home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / sample.ab / absearch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  19.1 KB  |  811 lines

  1. /***********************************************************************
  2.  *
  3.  *  ABSEARCH.C
  4.  *
  5.  *  Sample AB directory container Search object
  6.  *
  7.  *  This file contains the code for implementing the Sample AB
  8.  *  directory container search object.  Also known as advanced
  9.  *  search.
  10.  *
  11.  *  This search object was retrieved by OpenProperty on PR_SEARCH on the
  12.  *  AB directory found in ABCONT.C.
  13.  *
  14.  *  The following routines are implemented in this file:
  15.  *
  16.  *      HrNewSearch
  17.  *      ABSRCH_Release
  18.  *      ABSRCH_SaveChanges
  19.  *      ABSRCH_OpenProperty
  20.  *      ABSRCH_GetSearchCriteria
  21.  *
  22.  *      HrGetSearchDialog
  23.  *
  24.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  25.  *
  26.  ***********************************************************************/
  27.  
  28. #include "abp.h"
  29. #include "sampabp.rh"
  30. #include <smpab.h>
  31.  
  32.  
  33. /*
  34.  *  Proptags used only in this module
  35.  */
  36. #define PR_ANR_STRING               PROP_TAG(PT_STRING8,0x6602)
  37.  
  38.  
  39. /*
  40.  *  Structure for the 'this'
  41.  */
  42.  
  43. typedef struct _ABSRCH
  44. {
  45.     const ABSRCH_Vtbl FAR * lpVtbl;
  46.  
  47.     SAB_Wrapped;
  48.  
  49.     /*  Private data */
  50.  
  51.     LPSPropValue lpRestrictData;
  52.     
  53. } ABSRCH, *LPABSRCH;
  54.  
  55.  
  56.  
  57. /* Display table control structures for the Search property sheet. */
  58.  
  59. /*
  60.  *  The Sample AB exposes an 'advanced' search dialog.  The following
  61.  *  structures define it's layout.
  62.  */
  63.  
  64. /*
  65.  *  The edit control that will have the name to be search for on it.
  66.  */
  67. #define MAX_SEARCH_NAME                 50
  68.  
  69. DTBLEDIT editSearchName =
  70. {
  71.     sizeof(DTBLEDIT),
  72.     0,
  73.     MAX_SEARCH_NAME,
  74.     PR_ANR_STRING
  75. };
  76.  
  77. /*
  78.  *  Display table pages for Search property sheet
  79.  */
  80. DTCTL rgdtctlSearchGeneral[] =
  81. {
  82.  
  83.     /*
  84.      *  Defines the name of this Pane.
  85.      */
  86.     {DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
  87.  
  88.     /* group box control */
  89.     {DTCT_GROUPBOX, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
  90.         &dtblgroupbox},
  91.  
  92.     /* control and edit control */
  93.     {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
  94.         &dtbllabel},
  95.     {DTCT_EDIT, DT_EDITABLE, NULL, 0, szNoFilter, IDC_SEARCH_NAME,
  96.         &editSearchName},
  97. };
  98.  
  99. /*
  100.  *  Actual definition of the set of pages that make up this advanced search
  101.  *  dialog.  Note that there's no limit to the number of pages that can be
  102.  *  displayed.  This sample AB, however, only exposes on page.
  103.  */
  104. DTPAGE rgdtpageSearch[] =
  105. {
  106.     {
  107.         sizeof(rgdtctlSearchGeneral) / sizeof(DTCTL),
  108.         (LPTSTR) MAKEINTRESOURCE(SearchGeneralPage),
  109.         "",
  110.         rgdtctlSearchGeneral
  111.     }
  112. };
  113.  
  114. /*
  115.  *  ABSearch vtbl is filled in here.
  116.  */
  117. ABSRCH_Vtbl vtblABSRCH =
  118. {
  119.     (ABSRCH_QueryInterface_METHOD *)        ROOT_QueryInterface,
  120.     (ABSRCH_AddRef_METHOD *)                ROOT_AddRef,    
  121.     ABSRCH_Release,
  122.     (ABSRCH_GetLastError_METHOD *)          ROOT_GetLastError,
  123.     ABSRCH_SaveChanges,
  124.     (ABSRCH_GetProps_METHOD *)              WRAP_GetProps,
  125.     (ABSRCH_GetPropList_METHOD *)           WRAP_GetPropList,
  126.     ABSRCH_OpenProperty,
  127.     (ABSRCH_SetProps_METHOD *)              WRAP_SetProps,
  128.     (ABSRCH_DeleteProps_METHOD *)           WRAP_DeleteProps,
  129.     (ABSRCH_CopyTo_METHOD *)                WRAP_CopyTo,
  130.     (ABSRCH_CopyProps_METHOD *)             WRAP_CopyProps,
  131.     (ABSRCH_GetNamesFromIDs_METHOD *)       WRAP_GetNamesFromIDs,
  132.     (ABSRCH_GetIDsFromNames_METHOD *)       WRAP_GetIDsFromNames,
  133.     (ABSRCH_GetContentsTable_METHOD *)      ROOT_GetContentsTable,
  134.     (ABSRCH_GetHierarchyTable_METHOD *)     ABC_GetHierarchyTable,
  135.     (ABSRCH_OpenEntry_METHOD *)             ROOT_OpenEntry,
  136.     (ABSRCH_SetSearchCriteria_METHOD *)     ROOT_SetSearchCriteria,
  137.     ABSRCH_GetSearchCriteria,
  138. };
  139.  
  140.  
  141.  
  142. HRESULT HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable);
  143.  
  144. /*
  145.  -  HrNewSearch
  146.  -
  147.  *  Creates an advanced search object
  148.  *
  149.  *
  150.  */
  151.  
  152.  
  153. /*
  154.  *  Properties that are initially set on this object
  155.  */
  156. enum {  ivalabsrchPR_ANR_STRING = 0,
  157.         cvalabsrchMax };
  158.  
  159. HRESULT
  160. HrNewSearch(LPMAPICONTAINER *   lppABSearch,
  161.             LPABLOGON           lpABLogon,
  162.             LPCIID              lpInterface,
  163.             HINSTANCE           hLibrary,
  164.             LPALLOCATEBUFFER    lpAllocBuff,
  165.             LPALLOCATEMORE      lpAllocMore,
  166.             LPFREEBUFFER        lpFreeBuff,
  167.             LPMALLOC            lpMalloc )
  168. {
  169.     HRESULT hResult = hrSuccess;
  170.     LPABSRCH lpABSearch = NULL;
  171.     SCODE sc;
  172.     LPPROPDATA lpPropData = NULL;
  173.     SPropValue spv[cvalabsrchMax];
  174.     
  175.     /*  Do I support this interface?? */
  176.     if (lpInterface)
  177.     {
  178.         if (memcmp(lpInterface, &IID_IMAPIContainer, sizeof(IID)) &&
  179.             memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
  180.             memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
  181.         {
  182.             DebugTraceSc(HrNewSearch, MAPI_E_INTERFACE_NOT_SUPPORTED);
  183.             return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
  184.         }
  185.     }
  186.  
  187.     /*
  188.      *  Allocate space for the directory container structure
  189.      */
  190.  
  191.     sc = lpAllocBuff( sizeof(ABSRCH), (LPVOID *) &lpABSearch );
  192.  
  193.     if (FAILED(sc))
  194.     {
  195.         hResult = ResultFromScode(sc);
  196.         goto err;
  197.     }
  198.  
  199.     lpABSearch->lpVtbl = &vtblABSRCH;
  200.     lpABSearch->lcInit = 1;
  201.     lpABSearch->hResult = hrSuccess;
  202.     lpABSearch->idsLastError = 0;
  203.  
  204.     lpABSearch->hLibrary = hLibrary;
  205.     lpABSearch->lpAllocBuff = lpAllocBuff;
  206.     lpABSearch->lpAllocMore = lpAllocMore;
  207.     lpABSearch->lpFreeBuff = lpFreeBuff;
  208.     lpABSearch->lpMalloc = lpMalloc;
  209.  
  210.     lpABSearch->lpABLogon = lpABLogon;
  211.     lpABSearch->lpRestrictData = NULL;
  212.  
  213.     /*
  214.      *  Create property storage object
  215.      */
  216.  
  217.     sc = CreateIProp((LPIID) &IID_IMAPIPropData,
  218.         lpAllocBuff,
  219.         lpAllocMore,
  220.         lpFreeBuff,
  221.         lpMalloc,
  222.         &lpPropData);
  223.  
  224.     if (FAILED(sc))
  225.     {
  226.         hResult = ResultFromScode(sc);
  227.         goto err;
  228.     }
  229.  
  230.     spv[ivalabsrchPR_ANR_STRING].ulPropTag = PR_ANR_STRING;
  231.     spv[ivalabsrchPR_ANR_STRING].Value.lpszA = "";
  232.  
  233.     /*
  234.      *   Set the default properties
  235.      */
  236.     hResult = lpPropData->lpVtbl->SetProps(lpPropData,
  237.         cvalabsrchMax,
  238.         spv,
  239.         NULL);
  240.  
  241.     InitializeCriticalSection(&lpABSearch->cs);
  242.  
  243.     /*  We must AddRef the lpABLogon object since we will be using it
  244.      */
  245.     lpABLogon->lpVtbl->AddRef(lpABLogon);
  246.  
  247.     lpABSearch->lpPropData = (LPMAPIPROP) lpPropData;
  248.     *lppABSearch = (LPMAPICONTAINER) lpABSearch;
  249.  
  250. out:
  251.  
  252.     DebugTraceResult(HrNewSearch, hResult);
  253.     return hResult;
  254.  
  255. err:
  256.     /*
  257.      *  free the ABContainer object
  258.      */
  259.     lpFreeBuff( lpABSearch );
  260.  
  261.     /*
  262.      *  free the property storage object
  263.      */
  264.     if (lpPropData)
  265.         lpPropData->lpVtbl->Release(lpPropData);
  266.  
  267.     goto out;
  268. }
  269.  
  270.  
  271. /*
  272.  -  ABSRCH_Release
  273.  -
  274.  *  Decrement lcInit.
  275.  *      When lcInit == 0, free up the lpABSearch structure
  276.  *
  277.  */
  278.  
  279. STDMETHODIMP_(ULONG)
  280. ABSRCH_Release(LPABSRCH lpABSearch)
  281. {
  282.  
  283.     long lcInit;
  284.     
  285.     /*
  286.      *  Check to see if it has a jump table
  287.      */
  288.     if (IsBadReadPtr(lpABSearch, sizeof(ABSRCH)))
  289.     {
  290.         /*
  291.          *  No jump table found
  292.          */
  293.         return 1;
  294.     }
  295.  
  296.     /*
  297.      *  Check to see that it's the correct jump table
  298.      */
  299.     if (lpABSearch->lpVtbl != &vtblABSRCH)
  300.     {
  301.         /*
  302.          *  Not my jump table
  303.          */
  304.         return 1;
  305.     }
  306.  
  307.     EnterCriticalSection(&lpABSearch->cs);
  308.     lcInit = --lpABSearch->lcInit;
  309.     LeaveCriticalSection(&lpABSearch->cs);
  310.  
  311.     if (lcInit == 0)
  312.     {
  313.  
  314.         /*
  315.          *  Get rid of the lpPropData
  316.          */
  317.         if (lpABSearch->lpPropData)
  318.             lpABSearch->lpPropData->lpVtbl->Release(lpABSearch->lpPropData);
  319.  
  320.         /*
  321.          *  Free up the restriction data
  322.          */
  323.         lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  324.  
  325.         /*  
  326.          *  Release our reference to the ABLogon object.
  327.          */
  328.         if (lpABSearch->lpABLogon)
  329.         {
  330.             lpABSearch->lpABLogon->lpVtbl->Release(lpABSearch->lpABLogon);
  331.             lpABSearch->lpABLogon = NULL;
  332.         }
  333.  
  334.         /*
  335.          *  Destroy the critical section for this object
  336.          */
  337.  
  338.         DeleteCriticalSection(&lpABSearch->cs);
  339.  
  340.         /*
  341.          *  Set the Jump table to NULL.  This way the client will find out
  342.          *  real fast if it's calling a method on a released object.  That is,
  343.          *  the client will crash.  Hopefully, this will happen during the
  344.          *  development stage of the client.
  345.          */
  346.         lpABSearch->lpVtbl = NULL;
  347.  
  348.         /*
  349.          *  Need to free the object
  350.          */
  351.  
  352.         lpABSearch->lpFreeBuff(lpABSearch);
  353.         return 0;
  354.     }
  355.  
  356.     return lpABSearch->lcInit;
  357.  
  358. }
  359.  
  360.  
  361. /*
  362.  -  ABSRCH_SaveChanges
  363.  -
  364.  *  This is used to save changes associated with the search dialog
  365.  *  in order to get the advanced search restriction and to save changes
  366.  *  associated with the container details dialog.
  367.  *
  368.  */
  369. SPropTagArray tagaANR_INT =
  370. {
  371.     1,
  372.     {
  373.         PR_ANR_STRING
  374.     }
  375. };
  376.  
  377. STDMETHODIMP
  378. ABSRCH_SaveChanges(LPABSRCH lpABSearch, ULONG ulFlags)
  379. {
  380.     HRESULT hResult;
  381.     ULONG ulCount;
  382.     LPSPropValue lpspv = NULL;
  383.     LPPROPDATA lpPropData = (LPPROPDATA) lpABSearch->lpPropData;
  384.  
  385.     /*
  386.      *  Check to see if it has a jump table
  387.      */
  388.     if (IsBadReadPtr(lpABSearch, sizeof(ABSRCH)))
  389.     {
  390.         /*
  391.          *  No jump table found
  392.          */
  393.         hResult = ResultFromScode(E_INVALIDARG);
  394.         return hResult;
  395.     }
  396.  
  397.     /*
  398.      *  Check to see that it's the correct jump table
  399.      */
  400.     if (lpABSearch->lpVtbl != &vtblABSRCH)
  401.     {
  402.         /*
  403.          *  Not my jump table
  404.          */
  405.         hResult = ResultFromScode(E_INVALIDARG);
  406.         return hResult;
  407.     }
  408.  
  409.  
  410.     EnterCriticalSection(&lpABSearch->cs);
  411.  
  412.     /*
  413.      *  Is there a PR_ANR_STRING??
  414.      */
  415.     hResult = lpPropData->lpVtbl->GetProps(lpPropData,
  416.         &tagaANR_INT,
  417.         0,      /* ansi */
  418.         &ulCount,
  419.         &lpspv);
  420.     if (HR_FAILED(hResult))
  421.     {
  422.         goto ret;
  423.     }
  424.  
  425.     if ((lpspv->ulPropTag == PR_ANR_STRING) && (lpspv->Value.lpszA[0] != '\0'))
  426.     {
  427.         /*
  428.          * save away the information to build up the new restriction
  429.          */
  430.  
  431.         /*  Free any existing data */
  432.         if (lpABSearch->lpRestrictData)
  433.         {
  434.             lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  435.         }
  436.  
  437.         lpABSearch->lpRestrictData = lpspv;
  438.         lpspv = NULL;
  439.     }
  440.  
  441. ret:
  442.  
  443.     LeaveCriticalSection(&lpABSearch->cs);
  444.  
  445.     lpABSearch->lpFreeBuff(lpspv);
  446.     DebugTraceResult(ABSRCH_SaveChanges, hResult);
  447.     return hResult;
  448. }
  449.  
  450. /*************************************************************************
  451.  *
  452.  -  ABSRCH_OpenProperty
  453.  -
  454.  *
  455.  *  This method allows the opening of the following object:
  456.  *
  457.  *  PR_DETAILS_TABLE        :-  Gets the display table associated with
  458.  *                              the advanced search dialog.
  459.  */
  460. STDMETHODIMP
  461. ABSRCH_OpenProperty(LPABSRCH lpABSearch,
  462.     ULONG ulPropTag,
  463.     LPCIID lpiid,
  464.     ULONG ulInterfaceOptions,
  465.     ULONG ulFlags,
  466.     LPUNKNOWN * lppUnk)
  467. {
  468.     HRESULT hResult;
  469.  
  470.     /*
  471.      *  Check to see if it's big enough to be this object
  472.      */
  473.     if (IsBadReadPtr(lpABSearch, sizeof(ABSRCH)))
  474.     {
  475.         /*
  476.          *  Not big enough to be this object
  477.          */
  478.         hResult = ResultFromScode(E_INVALIDARG);
  479.         goto out;
  480.     }
  481.  
  482.     /*
  483.      *  Check to see that it's the correct vtbl
  484.      */
  485.     if (lpABSearch->lpVtbl != &vtblABSRCH)
  486.     {
  487.         /*
  488.          *  Not my vtbl
  489.          */
  490.         hResult = ResultFromScode(E_INVALIDARG);
  491.         goto out;
  492.     }
  493.  
  494.  
  495.     if (IsBadWritePtr(lppUnk, sizeof(LPUNKNOWN)))
  496.     {
  497.         /*
  498.          *  Got to be able to return an object
  499.          */
  500.         hResult = ResultFromScode(E_INVALIDARG);
  501.         goto out;
  502.     }
  503.  
  504.     if (IsBadReadPtr(lpiid, (UINT) sizeof(IID)))
  505.     {
  506.         /*
  507.          *  An interface ID is required for this call.
  508.          */
  509.  
  510.         hResult = ResultFromScode(E_INVALIDARG);
  511.         goto out;
  512.     }
  513.  
  514.     /*
  515.      *  Make sure we are getting a valid PropTag.
  516.      */
  517.     if (FBadPropTag(ulPropTag))
  518.     {
  519.         hResult = ResultFromScode(E_INVALIDARG);
  520.         goto out;
  521.     }
  522.  
  523.     /*
  524.      *  check for unknown flags
  525.      */
  526.     if (ulFlags & ~(  MAPI_DEFERRED_ERRORS | STREAM_APPEND
  527.                     | MAPI_CREATE | MAPI_MODIFY))
  528.     {
  529.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  530.         goto out;
  531.     }
  532.  
  533.     /*
  534.      *  STREAM_APPEND is only valid on a stream interface.
  535.      */
  536.     if (   (ulFlags & STREAM_APPEND)
  537.         && memcmp(lpiid, &IID_IStream, sizeof(IID)) )
  538.     {
  539.         hResult = ResultFromScode(MAPI_E_INVALID_PARAMETER);
  540.         goto out;
  541.     }
  542.  
  543.     /*
  544.      *  Check for flags we can't support
  545.      */
  546.  
  547.     if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
  548.     {
  549.         hResult = ResultFromScode(E_ACCESSDENIED);
  550.         goto out;
  551.     }
  552.         
  553.     if (ulInterfaceOptions & ~MAPI_UNICODE)
  554.     {
  555.         /*
  556.          *  Only UNICODE flag should be set for any of the objects that might
  557.          *  be returned from this object.
  558.          */
  559.         
  560.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  561.         goto out;
  562.     }
  563.     
  564.     if ( ulInterfaceOptions & MAPI_UNICODE )
  565.     {
  566.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  567.         DebugTraceArg( ABSRCH_OpenProperty, "bad character width" );
  568.         goto out;
  569.         
  570.     }
  571.  
  572.  
  573.     /*
  574.      *  Details for this Search object
  575.      */
  576.  
  577.     if (ulPropTag == PR_DETAILS_TABLE)
  578.     {
  579.         if (!memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  580.         {
  581.             hResult = HrGetSearchDialog(lpABSearch, (LPMAPITABLE *) lppUnk);
  582.  
  583.             goto out;
  584.         }
  585.  
  586.     } 
  587.  
  588.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  589.  
  590. out:
  591.  
  592.     DebugTraceResult(ABSRCH_OpenProperty, hResult);
  593.     return hResult;
  594.  
  595.  
  596. }
  597.  
  598. /*
  599.  -  ABSRCH_GetSearchCriteria
  600.  -
  601.  *  Generates the restriction associated with the data from
  602.  *  the advanced search dialog.  This restriction is subsequently
  603.  *  applied to the contents table retrieved from this container.
  604.  */
  605. STDMETHODIMP
  606. ABSRCH_GetSearchCriteria(   LPABSRCH lpABSearch,
  607.                         ULONG   ulFlags,
  608.                         LPSRestriction FAR * lppRestriction,
  609.                         LPENTRYLIST FAR * lppContainerList,
  610.                         ULONG FAR * lpulSearchState)
  611. {
  612.     HRESULT hResult = hrSuccess;
  613.     SCODE sc;
  614.     LPSRestriction lpRestriction = NULL;
  615.     LPSPropValue lpPropANR = NULL;
  616.     LPSTR lpszPartName;
  617.     LPSTR lpszRestrName;
  618.  
  619.     /*
  620.      *  Check to see if it's large enough to be my object
  621.      */
  622.     if (IsBadReadPtr(lpABSearch, sizeof(ABSRCH)))
  623.     {
  624.         /*
  625.          *  Not large enough
  626.          */
  627.         hResult = ResultFromScode(E_INVALIDARG);
  628.  
  629.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  630.         return hResult;
  631.     }
  632.  
  633.     /*
  634.      *  Check to see that it's the correct vtbl
  635.      */
  636.     if (lpABSearch->lpVtbl != &vtblABSRCH)
  637.     {
  638.         /*
  639.          *  Not my vtbl
  640.          */
  641.         hResult = ResultFromScode(E_INVALIDARG);
  642.  
  643.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  644.         return hResult;
  645.     }
  646.  
  647.     /*
  648.      *  Check out parameters
  649.      */
  650.      
  651.     if ( ulFlags & ~(MAPI_UNICODE) )
  652.     {
  653.         hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
  654.         
  655.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  656.         return hResult;
  657.     }
  658.     
  659.     if ( ulFlags & MAPI_UNICODE )
  660.     {
  661.         DebugTraceArg( ABSRCH_GetSearchCriteria, "bad character width" );
  662.         return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  663.     }
  664.     
  665.     if (IsBadWritePtr(lppRestriction, sizeof(LPSRestriction)))
  666.     {
  667.         hResult = ResultFromScode(E_INVALIDARG);
  668.  
  669.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  670.         return hResult;
  671.     }
  672.  
  673.     if (lpulSearchState && IsBadWritePtr(lpulSearchState, sizeof(ULONG)))
  674.     {
  675.         hResult = ResultFromScode(E_INVALIDARG);
  676.  
  677.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  678.         return hResult;
  679.     }
  680.  
  681.     if (lppContainerList && IsBadWritePtr(lppContainerList, sizeof(LPENTRYLIST)))
  682.     {
  683.         hResult = ResultFromScode(E_INVALIDARG);
  684.  
  685.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  686.         return hResult;
  687.     }
  688.         
  689.  
  690.     if (!lpABSearch->lpRestrictData)
  691.     {
  692.         hResult = ResultFromScode(MAPI_E_NOT_INITIALIZED);
  693.  
  694.         if (lppRestriction)
  695.             *lppRestriction = NULL;
  696.  
  697.         if (lppContainerList)
  698.             *lppContainerList = NULL;
  699.  
  700.         if (lpulSearchState)
  701.             *lpulSearchState = 0L;
  702.  
  703.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  704.         return hResult;
  705.     }
  706.  
  707.     if (ulFlags & MAPI_UNICODE)
  708.     {
  709.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  710.         
  711.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  712.         return hResult;
  713.     }
  714.  
  715.  
  716.     /*
  717.      *  Entering state dependant section
  718.      */
  719.     EnterCriticalSection(&lpABSearch->cs);
  720.  
  721.     /*
  722.      *  Ok, now build up a restriction using lpRestrictData (an LPSPropValue)
  723.      */
  724.  
  725.     sc = lpABSearch->lpAllocBuff(sizeof(SRestriction), &lpRestriction);
  726.     if (FAILED(sc))
  727.     {
  728.         hResult = ResultFromScode(sc);
  729.         goto err;
  730.     }
  731.  
  732.     sc = lpABSearch->lpAllocMore(sizeof(SPropValue), lpRestriction, &lpPropANR);
  733.     if (FAILED(sc))
  734.     {
  735.         hResult = ResultFromScode(sc);
  736.         goto err;
  737.  
  738.     }
  739.  
  740.     lpszRestrName = lpABSearch->lpRestrictData->Value.lpszA;
  741.  
  742.     sc = lpABSearch->lpAllocMore(lstrlenA(lpszRestrName)+1,
  743.         lpRestriction,
  744.         &lpszPartName);
  745.     if (FAILED(sc))
  746.     {
  747.         hResult = ResultFromScode(sc);
  748.         goto err;
  749.     }
  750.  
  751.     lstrcpyA(lpszPartName, lpszRestrName);
  752.  
  753.     lpPropANR->ulPropTag = PR_ANR;
  754.     lpPropANR->Value.LPSZ = lpszPartName;
  755.  
  756.     lpRestriction->rt = RES_PROPERTY;
  757.     lpRestriction->res.resProperty.relop = RELOP_EQ;
  758.     lpRestriction->res.resProperty.ulPropTag = PR_ANR;
  759.     lpRestriction->res.resProperty.lpProp = lpPropANR;
  760.  
  761.     *lppRestriction = lpRestriction;
  762.  
  763.     /*
  764.      *  The returned SearchState is set to 0 because none
  765.      *  of the defined states match what's going on.
  766.      */
  767.     if (lpulSearchState)
  768.         *lpulSearchState = 0;
  769.  
  770. out:
  771.     LeaveCriticalSection(&lpABSearch->cs);
  772.  
  773.     DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  774.     return hResult;
  775.  
  776. err:
  777.     lpABSearch->lpFreeBuff(lpRestriction);
  778.  
  779.     goto out;
  780. }
  781.  
  782. /*
  783.  -  HrGetSearchDialog
  784.  -
  785.  *
  786.  *  Builds a display table for the search dialog.
  787.  */
  788.  
  789. HRESULT
  790. HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable)
  791. {
  792.     HRESULT hResult;
  793.  
  794.     /* Create a display table */
  795.     hResult = BuildDisplayTable(
  796.             lpABSearch->lpAllocBuff,
  797.             lpABSearch->lpAllocMore,
  798.             lpABSearch->lpFreeBuff,
  799.             lpABSearch->lpMalloc,
  800.             lpABSearch->hLibrary,
  801.             sizeof(rgdtpageSearch) / sizeof(DTPAGE),
  802.             rgdtpageSearch,
  803.             0,
  804.             lppSearchTable,
  805.             NULL);
  806.  
  807.     DebugTraceResult(ABSRCH_GetSearchDialog, hResult);
  808.     return hResult;
  809. }
  810.  
  811.