|
|
/***********************************************************************
* * 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; }
|