747 lines
17 KiB
C
747 lines
17 KiB
C
/***********************************************************************
|
|
*
|
|
* 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;
|
|
}
|
|
|