home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / flatfile.ab / absearch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  15.8 KB  |  662 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.     Validate_IUnknown_Release(lpABSearch);
  308.  
  309.  
  310.     EnterCriticalSection(&lpABSearch->cs);
  311.     lcInit = --lpABSearch->lcInit;
  312.     LeaveCriticalSection(&lpABSearch->cs);
  313.  
  314.     if (lcInit == 0)
  315.     {
  316.  
  317.         /*
  318.          *  Get rid of the lpPropData
  319.          */
  320.         if (lpABSearch->lpPropData)
  321.             lpABSearch->lpPropData->lpVtbl->Release(lpABSearch->lpPropData);
  322.  
  323.         /*
  324.          *  Free up the restriction data
  325.          */
  326.         lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  327.  
  328.         /*  
  329.          *  Release our reference to the ABLogon object.
  330.          */
  331.         if (lpABSearch->lpABLogon)
  332.         {
  333.             lpABSearch->lpABLogon->lpVtbl->Release(lpABSearch->lpABLogon);
  334.             lpABSearch->lpABLogon = NULL;
  335.         }
  336.  
  337.         /*
  338.          *  Destroy the critical section for this object
  339.          */
  340.  
  341.         DeleteCriticalSection(&lpABSearch->cs);
  342.  
  343.         /*
  344.          *  Set the Jump table to NULL.  This way the client will find out
  345.          *  real fast if it's calling a method on a released object.  That is,
  346.          *  the client will crash.  Hopefully, this will happen during the
  347.          *  development stage of the client.
  348.          */
  349.         lpABSearch->lpVtbl = NULL;
  350.  
  351.         /*
  352.          *  Need to free the object
  353.          */
  354.  
  355.         lpABSearch->lpFreeBuff(lpABSearch);
  356.         return 0;
  357.     }
  358.  
  359.     return lpABSearch->lcInit;
  360.  
  361. }
  362.  
  363.  
  364. /*
  365.  -  ABSRCH_SaveChanges
  366.  -
  367.  *  This is used to save changes associated with the search dialog
  368.  *  in order to get the advanced search restriction and to save changes
  369.  *  associated with the container details dialog.
  370.  *
  371.  */
  372. SPropTagArray tagaANR_INT =
  373. {
  374.     1,
  375.     {
  376.         PR_ANR_STRING
  377.     }
  378. };
  379.  
  380. STDMETHODIMP
  381. ABSRCH_SaveChanges(LPABSRCH lpABSearch, ULONG ulFlags)
  382. {
  383.     HRESULT hResult;
  384.     ULONG ulCount;
  385.     LPSPropValue lpspv = NULL;
  386.     LPPROPDATA lpPropData = (LPPROPDATA) lpABSearch->lpPropData;
  387.  
  388.     
  389.     ABSRCH_ValidateObject(SaveChanges, lpABSearch);
  390.     
  391.     Validate_IMAPIProp_SaveChanges(lpABSearch, ulFlags);
  392.  
  393.  
  394.     EnterCriticalSection(&lpABSearch->cs);
  395.  
  396.     /*
  397.      *  Is there a PR_ANR_STRING??
  398.      */
  399.     hResult = lpPropData->lpVtbl->GetProps(lpPropData,
  400.         &tagaANR_INT,
  401.         0,      /* ansi */
  402.         &ulCount,
  403.         &lpspv);
  404.     if (HR_FAILED(hResult))
  405.     {
  406.         goto ret;
  407.     }
  408.  
  409.     if ((lpspv->ulPropTag == PR_ANR_STRING) && (lpspv->Value.lpszA[0] != '\0'))
  410.     {
  411.         /*
  412.          * save away the information to build up the new restriction
  413.          */
  414.  
  415.         /*  Free any existing data */
  416.         if (lpABSearch->lpRestrictData)
  417.         {
  418.             lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  419.         }
  420.  
  421.         lpABSearch->lpRestrictData = lpspv;
  422.         lpspv = NULL;
  423.     }
  424.  
  425. ret:
  426.  
  427.     LeaveCriticalSection(&lpABSearch->cs);
  428.  
  429.     lpABSearch->lpFreeBuff(lpspv);
  430.     DebugTraceResult(ABSRCH_SaveChanges, hResult);
  431.     return hResult;
  432. }
  433.  
  434. /*************************************************************************
  435.  *
  436.  -  ABSRCH_OpenProperty
  437.  -
  438.  *
  439.  *  This method allows the opening of the following object:
  440.  *
  441.  *  PR_DETAILS_TABLE        :-  Gets the display table associated with
  442.  *                              the advanced search dialog.
  443.  */
  444. STDMETHODIMP
  445. ABSRCH_OpenProperty(LPABSRCH lpABSearch,
  446.     ULONG ulPropTag,
  447.     LPCIID lpiid,
  448.     ULONG ulInterfaceOptions,
  449.     ULONG ulFlags,
  450.     LPUNKNOWN * lppUnk)
  451. {
  452.     HRESULT hResult;
  453.  
  454.     ABSRCH_ValidateObject(OpenProperty, lpABSearch);
  455.     
  456.     Validate_IMAPIProp_OpenProperty(lpABSearch, ulPropTag, lpiid,
  457.                             ulInterfaceOptions, ulFlags, lppUnk);
  458.  
  459.     /*
  460.      *  Check for flags we can't support
  461.      */
  462.  
  463.     if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
  464.     {
  465.         hResult = ResultFromScode(E_ACCESSDENIED);
  466.         goto out;
  467.     }
  468.         
  469.     if (ulInterfaceOptions & ~MAPI_UNICODE)
  470.     {
  471.         /*
  472.          *  Only UNICODE flag should be set for any of the objects that might
  473.          *  be returned from this object.
  474.          */
  475.         
  476.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  477.         goto out;
  478.     }
  479.     
  480.     if ( ulInterfaceOptions & MAPI_UNICODE )
  481.     {
  482.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  483.         DebugTraceArg( ABSRCH_OpenProperty, "bad character width" );
  484.         goto out;
  485.         
  486.     }
  487.  
  488.  
  489.     /*
  490.      *  Details for this Search object
  491.      */
  492.  
  493.     if (ulPropTag == PR_DETAILS_TABLE)
  494.     {
  495.         if (!memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  496.         {
  497.             hResult = HrGetSearchDialog(lpABSearch, (LPMAPITABLE *) lppUnk);
  498.  
  499.             goto out;
  500.         }
  501.  
  502.     } 
  503.  
  504.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  505.  
  506. out:
  507.  
  508.     DebugTraceResult(ABSRCH_OpenProperty, hResult);
  509.     return hResult;
  510.  
  511.  
  512. }
  513.  
  514. /*
  515.  -  ABSRCH_GetSearchCriteria
  516.  -
  517.  *  Generates the restriction associated with the data from
  518.  *  the advanced search dialog.  This restriction is subsequently
  519.  *  applied to the contents table retrieved from this container.
  520.  */
  521. STDMETHODIMP
  522. ABSRCH_GetSearchCriteria(   LPABSRCH lpABSearch,
  523.                         ULONG   ulFlags,
  524.                         LPSRestriction FAR * lppRestriction,
  525.                         LPENTRYLIST FAR * lppContainerList,
  526.                         ULONG FAR * lpulSearchState)
  527. {
  528.     HRESULT hResult = hrSuccess;
  529.     SCODE sc;
  530.     LPSRestriction lpRestriction = NULL;
  531.     LPSPropValue lpPropANR = NULL;
  532.     LPSTR lpszPartName;
  533.     LPSTR lpszRestrName;
  534.  
  535.     ABSRCH_ValidateObject(GetSearchCriteria, lpABSearch);
  536.     
  537.     Validate_IMAPIContainer_GetSearchCriteria(lpABSearch, ulFlags,
  538.                                 lppRestriction, lppContainerList, 
  539.                                 lpulSearchState);
  540.  
  541.     if (!lpABSearch->lpRestrictData)
  542.     {
  543.         hResult = ResultFromScode(MAPI_E_NOT_INITIALIZED);
  544.  
  545.         if (lppRestriction)
  546.             *lppRestriction = NULL;
  547.  
  548.         if (lppContainerList)
  549.             *lppContainerList = NULL;
  550.  
  551.         if (lpulSearchState)
  552.             *lpulSearchState = 0L;
  553.  
  554.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  555.         return hResult;
  556.     }
  557.  
  558.     if (ulFlags & MAPI_UNICODE)
  559.     {
  560.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  561.         
  562.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  563.         return hResult;
  564.     }
  565.  
  566.  
  567.     /*
  568.      *  Entering state dependant section
  569.      */
  570.     EnterCriticalSection(&lpABSearch->cs);
  571.  
  572.     /*
  573.      *  Ok, now build up a restriction using lpRestrictData (an LPSPropValue)
  574.      */
  575.  
  576.     sc = lpABSearch->lpAllocBuff(sizeof(SRestriction), &lpRestriction);
  577.     if (FAILED(sc))
  578.     {
  579.         hResult = ResultFromScode(sc);
  580.         goto err;
  581.     }
  582.  
  583.     sc = lpABSearch->lpAllocMore(sizeof(SPropValue), lpRestriction, &lpPropANR);
  584.     if (FAILED(sc))
  585.     {
  586.         hResult = ResultFromScode(sc);
  587.         goto err;
  588.  
  589.     }
  590.  
  591.     lpszRestrName = lpABSearch->lpRestrictData->Value.lpszA;
  592.  
  593.     sc = lpABSearch->lpAllocMore(lstrlenA(lpszRestrName)+1,
  594.         lpRestriction,
  595.         &lpszPartName);
  596.     if (FAILED(sc))
  597.     {
  598.         hResult = ResultFromScode(sc);
  599.         goto err;
  600.     }
  601.  
  602.     lstrcpyA(lpszPartName, lpszRestrName);
  603.  
  604.     lpPropANR->ulPropTag = PR_ANR;
  605.     lpPropANR->Value.LPSZ = lpszPartName;
  606.  
  607.     lpRestriction->rt = RES_PROPERTY;
  608.     lpRestriction->res.resProperty.relop = RELOP_EQ;
  609.     lpRestriction->res.resProperty.ulPropTag = PR_ANR;
  610.     lpRestriction->res.resProperty.lpProp = lpPropANR;
  611.  
  612.     *lppRestriction = lpRestriction;
  613.  
  614.     /*
  615.      *  The returned SearchState is set to 0 because none
  616.      *  of the defined states match what's going on.
  617.      */
  618.     if (lpulSearchState)
  619.         *lpulSearchState = 0;
  620.  
  621. out:
  622.     LeaveCriticalSection(&lpABSearch->cs);
  623.  
  624.     DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  625.     return hResult;
  626.  
  627. err:
  628.     lpABSearch->lpFreeBuff(lpRestriction);
  629.  
  630.     goto out;
  631. }
  632.  
  633. /*
  634.  -  HrGetSearchDialog
  635.  -
  636.  *
  637.  *  Builds a display table for the search dialog.
  638.  */
  639.  
  640. HRESULT
  641. HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable)
  642. {
  643.     HRESULT hResult;
  644.  
  645.     /* Create a display table */
  646.     hResult = BuildDisplayTable(
  647.             lpABSearch->lpAllocBuff,
  648.             lpABSearch->lpAllocMore,
  649.             lpABSearch->lpFreeBuff,
  650.             lpABSearch->lpMalloc,
  651.             lpABSearch->hLibrary,
  652.             sizeof(rgdtpageSearch) / sizeof(DTPAGE),
  653.             rgdtpageSearch,
  654.             0,
  655.             lppSearchTable,
  656.             NULL);
  657.  
  658.     DebugTraceResult(ABSRCH_GetSearchDialog, hResult);
  659.     return hResult;
  660. }
  661.  
  662.