windows-nt/Source/XPSP1/NT/printscan/fax/exchange/ab/absearch.c

747 lines
17 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/***********************************************************************
*
* ABSEARCH.C
*
* Sample AB directory container Search object
*
* This file contains the code for implementing the Sample AB
* directory container search object. Also known as advanced
* search.
*
* This search object was retrieved by OpenProperty on PR_SEARCH on the
* AB directory found in ABCONT.C.
*
* The following routines are implemented in this file:
*
* HrNewSearch
* ABSRCH_Release
* ABSRCH_SaveChanges
* ABSRCH_OpenProperty
* ABSRCH_GetSearchCriteria
*
* HrGetSearchDialog
*
* Copyright 1992, 1993, 1994 Microsoft Corporation. All Rights Reserved.
*
***********************************************************************/
#include "faxab.h"
/*
* Proptags used only in this module
*/
#define PR_ANR_STRING_A PROP_TAG(PT_STRING8,0x6602)
/* Display table control structures for the Search property sheet. */
/*
* The Sample AB exposes an 'advanced' search dialog. The following
* structures define it's layout.
*/
/*
* The edit control that will have the name to be search for on it.
*/
#define MAX_SEARCH_NAME 50
DTBLEDIT editSearchName =
{
SIZEOF(DTBLEDIT),
0,
MAX_SEARCH_NAME,
PR_ANR_STRING_A
};
/*
* Display table pages for Search property sheet
*/
DTCTL rgdtctlSearchGeneral[] =
{
/*
* Defines the name of this Pane.
*/
{DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
/* group box control */
{DTCT_GROUPBOX, 0, NULL, 0, NULL, IDC_STATIC_CONTROL, &dtblgroupbox},
/* control and edit control */
{DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL, &dtbllabel},
{DTCT_EDIT, DT_EDITABLE, NULL, 0, (LPTSTR)szNoFilter, IDC_SEARCH_NAME, &editSearchName},
};
/*
* Actual definition of the set of pages that make up this advanced search
* dialog.
*/
DTPAGE rgdtpageSearch[] =
{
{
ARRAYSIZE(rgdtctlSearchGeneral),
(LPTSTR) MAKEINTRESOURCE(SearchGeneralPage),
TEXT(""),
rgdtctlSearchGeneral
}
};
/*
* ABSearch vtbl is filled in here.
*/
ABSRCH_Vtbl vtblABSRCH =
{
(ABSRCH_QueryInterface_METHOD *) ROOT_QueryInterface,
(ABSRCH_AddRef_METHOD *) ROOT_AddRef,
ABSRCH_Release,
(ABSRCH_GetLastError_METHOD *) ROOT_GetLastError,
ABSRCH_SaveChanges,
(ABSRCH_GetProps_METHOD *) WRAP_GetProps,
(ABSRCH_GetPropList_METHOD *) WRAP_GetPropList,
ABSRCH_OpenProperty,
(ABSRCH_SetProps_METHOD *) WRAP_SetProps,
(ABSRCH_DeleteProps_METHOD *) WRAP_DeleteProps,
(ABSRCH_CopyTo_METHOD *) WRAP_CopyTo,
(ABSRCH_CopyProps_METHOD *) WRAP_CopyProps,
(ABSRCH_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
(ABSRCH_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
(ABSRCH_GetContentsTable_METHOD *) ROOT_GetContentsTable,
(ABSRCH_GetHierarchyTable_METHOD *) ABC_GetHierarchyTable,
(ABSRCH_OpenEntry_METHOD *) ROOT_OpenEntry,
(ABSRCH_SetSearchCriteria_METHOD *) ROOT_SetSearchCriteria,
ABSRCH_GetSearchCriteria,
};
HRESULT HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable);
/*
- HrNewSearch
-
* Creates an advanced search object
*
*
*/
/*
* Properties that are initially set on this object
*/
enum { ivalabsrchPR_ANR_STRING = 0,
cvalabsrchMax };
HRESULT
HrNewSearch( LPMAPICONTAINER * lppABSearch,
LPABLOGON lpABLogon,
LPCIID lpInterface,
HINSTANCE hLibrary,
LPALLOCATEBUFFER lpAllocBuff,
LPALLOCATEMORE lpAllocMore,
LPFREEBUFFER lpFreeBuff,
LPMALLOC lpMalloc
)
{
HRESULT hResult = hrSuccess;
LPABSRCH lpABSearch = NULL;
SCODE sc;
LPPROPDATA lpPropData = NULL;
SPropValue spv[cvalabsrchMax];
/* Do I support this interface?? */
if (lpInterface)
{
if ( memcmp(lpInterface, &IID_IMAPIContainer, SIZEOF(IID)) &&
memcmp(lpInterface, &IID_IMAPIProp, SIZEOF(IID)) &&
memcmp(lpInterface, &IID_IUnknown, SIZEOF(IID))
)
{
DebugTraceSc(HrNewSearch, MAPI_E_INTERFACE_NOT_SUPPORTED);
return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
}
}
/*
* Allocate space for the directory container structure
*/
sc = lpAllocBuff( SIZEOF(ABSRCH), (LPVOID *) &lpABSearch );
if (FAILED(sc))
{
hResult = ResultFromScode(sc);
goto err;
}
lpABSearch->lpVtbl = &vtblABSRCH;
lpABSearch->lcInit = 1;
lpABSearch->hResult = hrSuccess;
lpABSearch->idsLastError = 0;
lpABSearch->hLibrary = hLibrary;
lpABSearch->lpAllocBuff = lpAllocBuff;
lpABSearch->lpAllocMore = lpAllocMore;
lpABSearch->lpFreeBuff = lpFreeBuff;
lpABSearch->lpMalloc = lpMalloc;
lpABSearch->lpABLogon = lpABLogon;
lpABSearch->lpRestrictData = NULL;
/*
* Create property storage object
*/
sc = CreateIProp((LPIID) &IID_IMAPIPropData,
lpAllocBuff,
lpAllocMore,
lpFreeBuff,
lpMalloc,
&lpPropData);
if (FAILED(sc))
{
hResult = ResultFromScode(sc);
goto err;
}
spv[ivalabsrchPR_ANR_STRING].ulPropTag = PR_ANR_STRING_A;
spv[ivalabsrchPR_ANR_STRING].Value.lpszA = "";
/*
* Set the default properties
*/
hResult = lpPropData->lpVtbl->SetProps(lpPropData,
cvalabsrchMax,
spv,
NULL);
InitializeCriticalSection(&lpABSearch->cs);
lpABSearch->lpPropData = (LPMAPIPROP) lpPropData;
*lppABSearch = (LPMAPICONTAINER) lpABSearch;
out:
DebugTraceResult(HrNewSearch, hResult);
return hResult;
err:
/*
* free the ABContainer object
*/
lpFreeBuff( lpABSearch );
/*
* free the property storage object
*/
if (lpPropData)
lpPropData->lpVtbl->Release(lpPropData);
goto out;
}
/*
- ABSRCH_Release
-
* Decrement lcInit.
* When lcInit == 0, free up the lpABSearch structure
*
*/
STDMETHODIMP_(ULONG)
ABSRCH_Release(LPABSRCH lpABSearch)
{
long lcInit;
/*
* Check to see if it has a jump table
*/
if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
{
/*
* No jump table found
*/
return 1;
}
/*
* Check to see that it's the correct jump table
*/
if (lpABSearch->lpVtbl != &vtblABSRCH)
{
/*
* Not my jump table
*/
return 1;
}
EnterCriticalSection(&lpABSearch->cs);
lcInit = --lpABSearch->lcInit;
LeaveCriticalSection(&lpABSearch->cs);
if (lcInit == 0)
{
/*
* Get rid of the lpPropData
*/
if (lpABSearch->lpPropData)
lpABSearch->lpPropData->lpVtbl->Release(lpABSearch->lpPropData);
/*
* Free up the restriction data
*/
lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
/*
* Destroy the critical section for this object
*/
DeleteCriticalSection(&lpABSearch->cs);
/*
* Set the Jump table to NULL. This way the client will find out
* real fast if it's calling a method on a released object. That is,
* the client will crash. Hopefully, this will happen during the
* development stage of the client.
*/
lpABSearch->lpVtbl = NULL;
/*
* Need to free the object
*/
lpABSearch->lpFreeBuff(lpABSearch);
return 0;
}
return lpABSearch->lcInit;
}
/*
- ABSRCH_SaveChanges
-
* This is used to save changes associated with the search dialog
* in order to get the advanced search restriction and to save changes
* associated with the container details dialog.
*
*/
SPropTagArray tagaANR_INT =
{
1,
{
PR_ANR_STRING_A
}
};
STDMETHODIMP
ABSRCH_SaveChanges(LPABSRCH lpABSearch, ULONG ulFlags)
{
HRESULT hResult;
ULONG ulCount;
LPSPropValue lpspv = NULL;
LPPROPDATA lpPropData = (LPPROPDATA) lpABSearch->lpPropData;
/*
* Check to see if it has a jump table
*/
if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that it's the correct jump table
*/
if (lpABSearch->lpVtbl != &vtblABSRCH)
{
/*
* Not my jump table
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
EnterCriticalSection(&lpABSearch->cs);
/*
* Is there a PR_ANR_STRING??
*/
hResult = lpPropData->lpVtbl->GetProps(lpPropData,
&tagaANR_INT,
0, /* ansi */
&ulCount,
&lpspv);
if (HR_FAILED(hResult))
{
goto ret;
}
if ((lpspv->ulPropTag == PR_ANR_STRING_A) && (lpspv->Value.lpszA != '\0'))
{
/*
* save away the information to build up the new restriction
*/
/* Free any existing data */
if (lpABSearch->lpRestrictData)
{
lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
}
lpABSearch->lpRestrictData = lpspv;
lpspv = NULL;
}
ret:
LeaveCriticalSection(&lpABSearch->cs);
lpABSearch->lpFreeBuff(lpspv);
DebugTraceResult(ABSRCH_SaveChanges, hResult);
return hResult;
}
/*************************************************************************
*
- ABSRCH_OpenProperty
-
*
* This method allows the opening of the following object:
*
* PR_DETAILS_TABLE :- Gets the display table associated with
* the advanced search dialog.
*/
STDMETHODIMP
ABSRCH_OpenProperty( LPABSRCH lpABSearch,
ULONG ulPropTag,
LPCIID lpiid,
ULONG ulInterfaceOptions,
ULONG ulFlags,
LPUNKNOWN * lppUnk
)
{
HRESULT hResult;
/*
* Check to see if it's big enough to be this object
*/
if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
{
/*
* Not big enough to be this object
*/
hResult = ResultFromScode(E_INVALIDARG);
goto out;
}
/*
* Check to see that it's the correct vtbl
*/
if (lpABSearch->lpVtbl != &vtblABSRCH)
{
/*
* Not my vtbl
*/
hResult = ResultFromScode(E_INVALIDARG);
goto out;
}
if (IsBadWritePtr(lppUnk, SIZEOF(LPUNKNOWN)))
{
/*
* Got to be able to return an object
*/
hResult = ResultFromScode(E_INVALIDARG);
goto out;
}
if (IsBadReadPtr(lpiid, (UINT) SIZEOF(IID)))
{
/*
* An interface ID is required for this call.
*/
hResult = ResultFromScode(E_INVALIDARG);
goto out;
}
/*
* check for unknown flags
*/
if (ulFlags & ~(MAPI_DEFERRED_ERRORS | MAPI_CREATE | MAPI_MODIFY))
{
hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
goto out;
}
/*
* Check for flags we can't support
*/
if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
{
hResult = ResultFromScode(E_ACCESSDENIED);
goto out;
}
if (ulInterfaceOptions & ~MAPI_UNICODE)
{
/*
* Only UNICODE flag should be set for any of the objects that might
* be returned from this object.
*/
hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
goto out;
}
if ( ulInterfaceOptions & MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
DebugTraceArg( ABSRCH_OpenProperty, "bad character width" );
goto out;
}
/*
* Details for this Search object
*/
if (ulPropTag == PR_DETAILS_TABLE)
{
if (!memcmp(lpiid, &IID_IMAPITable, SIZEOF(IID)))
{
hResult = HrGetSearchDialog(lpABSearch, (LPMAPITABLE *) lppUnk);
goto out;
}
}
hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
out:
DebugTraceResult(ABSRCH_OpenProperty, hResult);
return hResult;
}
/*
- ABSRCH_GetSearchCriteria
-
* Generates the restriction associated with the data from
* the advanced search dialog. This restriction is subsequently
* applied to the contents table retrieved from this container.
*/
STDMETHODIMP
ABSRCH_GetSearchCriteria( LPABSRCH lpABSearch,
ULONG ulFlags,
LPSRestriction FAR * lppRestriction,
LPENTRYLIST FAR * lppContainerList,
ULONG FAR * lpulSearchState
)
{
HRESULT hResult = hrSuccess;
SCODE sc;
LPSRestriction lpRestriction = NULL;
LPSPropValue lpPropANR = NULL;
LPSTR lpszPartNameA;
LPSTR lpszRestrNameA;
/*
* Check to see if it's large enough to be my object
*/
if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
{
/*
* Not large enough
*/
hResult = ResultFromScode(E_INVALIDARG);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
/*
* Check to see that it's the correct vtbl
*/
if (lpABSearch->lpVtbl != &vtblABSRCH)
{
/*
* Not my vtbl
*/
hResult = ResultFromScode(E_INVALIDARG);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
/*
* Check out parameters
*/
if ( ulFlags & ~(MAPI_UNICODE) )
{
hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
if ( ulFlags & MAPI_UNICODE )
{
DebugTraceArg( ABSRCH_GetSearchCriteria, "bad character width" );
return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
}
if (IsBadWritePtr(lppRestriction, SIZEOF(LPSRestriction)))
{
hResult = ResultFromScode(E_INVALIDARG);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
if (lpulSearchState && IsBadWritePtr(lpulSearchState, SIZEOF(ULONG)))
{
hResult = ResultFromScode(E_INVALIDARG);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
if (lppContainerList && IsBadWritePtr(lppContainerList, SIZEOF(LPENTRYLIST)))
{
hResult = ResultFromScode(E_INVALIDARG);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
if (!lpABSearch->lpRestrictData)
{
hResult = ResultFromScode(MAPI_E_NOT_INITIALIZED);
if (lppRestriction)
*lppRestriction = NULL;
if (lppContainerList)
*lppContainerList = NULL;
if (lpulSearchState)
*lpulSearchState = 0L;
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
}
/*
* Entering state dependant section
*/
EnterCriticalSection(&lpABSearch->cs);
/*
* Ok, now build up a restriction using lpRestrictData (an LPSPropValue)
*/
sc = lpABSearch->lpAllocBuff(SIZEOF(SRestriction), &lpRestriction);
if (FAILED(sc))
{
hResult = ResultFromScode(sc);
goto err;
}
sc = lpABSearch->lpAllocMore(SIZEOF(SPropValue), lpRestriction, &lpPropANR);
if (FAILED(sc))
{
hResult = ResultFromScode(sc);
goto err;
}
lpszRestrNameA = lpABSearch->lpRestrictData->Value.lpszA;
sc = lpABSearch->lpAllocMore( lstrlenA(lpszRestrNameA)+1,
lpRestriction,
&lpszPartNameA
);
if (FAILED(sc))
{
hResult = ResultFromScode(sc);
goto err;
}
lstrcpyA(lpszPartNameA, lpszRestrNameA);
lpPropANR->ulPropTag = PR_ANR_A;
lpPropANR->Value.lpszA = lpszPartNameA;
lpRestriction->rt = RES_PROPERTY;
lpRestriction->res.resProperty.relop = RELOP_EQ;
lpRestriction->res.resProperty.ulPropTag = PR_ANR_A;
lpRestriction->res.resProperty.lpProp = lpPropANR;
*lppRestriction = lpRestriction;
/*
* The returned SearchState is set to 0 because none
* of the defined states match what's going on.
*/
if (lpulSearchState)
*lpulSearchState = 0;
out:
LeaveCriticalSection(&lpABSearch->cs);
DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
return hResult;
err:
lpABSearch->lpFreeBuff(lpRestriction);
goto out;
}
/*
- HrGetSearchDialog
-
*
* Builds a display table for the search dialog.
*/
HRESULT
HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable)
{
HRESULT hResult;
/* Create a display table */
hResult = BuildDisplayTable(
lpABSearch->lpAllocBuff,
lpABSearch->lpAllocMore,
lpABSearch->lpFreeBuff,
lpABSearch->lpMalloc,
lpABSearch->hLibrary,
ARRAYSIZE(rgdtpageSearch),
rgdtpageSearch,
0,
lppSearchTable,
NULL);
DebugTraceResult(ABSRCH_GetSearchDialog, hResult);
return hResult;
}