ABSEARCH.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  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. #include "abp.h"
  28. #include "sampabp.rh"
  29. #include <smpab.h>
  30. /*
  31.  *  Proptags used only in this module
  32.  */
  33. #define PR_ANR_STRING               PROP_TAG(PT_STRING8,0x6602)
  34. /*
  35.  *  Structure for the 'this'
  36.  */
  37. typedef struct _ABSRCH
  38. {
  39.     const ABSRCH_Vtbl FAR * lpVtbl;
  40.     SAB_Wrapped;
  41.     /*  Private data */
  42.     LPSPropValue lpRestrictData;
  43.     
  44. } ABSRCH, *LPABSRCH;
  45. /* Display table control structures for the Search property sheet. */
  46. /*
  47.  *  The Sample AB exposes an 'advanced' search dialog.  The following
  48.  *  structures define it's layout.
  49.  */
  50. /*
  51.  *  The edit control that will have the name to be search for on it.
  52.  */
  53. #define MAX_SEARCH_NAME                 50
  54. DTBLEDIT editSearchName =
  55. {
  56.     sizeof(DTBLEDIT),
  57.     0,
  58.     MAX_SEARCH_NAME,
  59.     PR_ANR_STRING
  60. };
  61. /*
  62.  *  Display table pages for Search property sheet
  63.  */
  64. DTCTL rgdtctlSearchGeneral[] =
  65. {
  66.     /*
  67.      *  Defines the name of this Pane.
  68.      */
  69.     {DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
  70.     /* group box control */
  71.     {DTCT_GROUPBOX, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
  72.         &dtblgroupbox},
  73.     /* control and edit control */
  74.     {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
  75.         &dtbllabel},
  76.     {DTCT_EDIT, DT_EDITABLE, NULL, 0, szNoFilter, IDC_SEARCH_NAME,
  77.         &editSearchName},
  78. };
  79. /*
  80.  *  Actual definition of the set of pages that make up this advanced search
  81.  *  dialog.  Note that there's no limit to the number of pages that can be
  82.  *  displayed.  This sample AB, however, only exposes on page.
  83.  */
  84. DTPAGE rgdtpageSearch[] =
  85. {
  86.     {
  87.         sizeof(rgdtctlSearchGeneral) / sizeof(DTCTL),
  88.         (LPTSTR) MAKEINTRESOURCE(SearchGeneralPage),
  89.         "",
  90.         rgdtctlSearchGeneral
  91.     }
  92. };
  93. /*
  94.  *  ABSearch vtbl is filled in here.
  95.  */
  96. ABSRCH_Vtbl vtblABSRCH =
  97. {
  98.     (ABSRCH_QueryInterface_METHOD *)        ROOT_QueryInterface,
  99.     (ABSRCH_AddRef_METHOD *)                ROOT_AddRef,    
  100.     ABSRCH_Release,
  101.     (ABSRCH_GetLastError_METHOD *)          ROOT_GetLastError,
  102.     ABSRCH_SaveChanges,
  103.     (ABSRCH_GetProps_METHOD *)              WRAP_GetProps,
  104.     (ABSRCH_GetPropList_METHOD *)           WRAP_GetPropList,
  105.     ABSRCH_OpenProperty,
  106.     (ABSRCH_SetProps_METHOD *)              WRAP_SetProps,
  107.     (ABSRCH_DeleteProps_METHOD *)           WRAP_DeleteProps,
  108.     (ABSRCH_CopyTo_METHOD *)                WRAP_CopyTo,
  109.     (ABSRCH_CopyProps_METHOD *)             WRAP_CopyProps,
  110.     (ABSRCH_GetNamesFromIDs_METHOD *)       WRAP_GetNamesFromIDs,
  111.     (ABSRCH_GetIDsFromNames_METHOD *)       WRAP_GetIDsFromNames,
  112.     (ABSRCH_GetContentsTable_METHOD *)      ROOT_GetContentsTable,
  113.     (ABSRCH_GetHierarchyTable_METHOD *)     ABC_GetHierarchyTable,
  114.     (ABSRCH_OpenEntry_METHOD *)             ROOT_OpenEntry,
  115.     (ABSRCH_SetSearchCriteria_METHOD *)     ROOT_SetSearchCriteria,
  116.     ABSRCH_GetSearchCriteria,
  117. };
  118. HRESULT HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable);
  119. /*
  120.  -  HrNewSearch
  121.  -
  122.  *  Creates an advanced search object
  123.  *
  124.  *
  125.  */
  126. /*
  127.  *  Properties that are initially set on this object
  128.  */
  129. enum {  ivalabsrchPR_ANR_STRING = 0,
  130.         cvalabsrchMax };
  131. HRESULT
  132. HrNewSearch(LPMAPICONTAINER *   lppABSearch,
  133.             LPABLOGON           lpABLogon,
  134.             LPCIID              lpInterface,
  135.             HINSTANCE           hLibrary,
  136.             LPALLOCATEBUFFER    lpAllocBuff,
  137.             LPALLOCATEMORE      lpAllocMore,
  138.             LPFREEBUFFER        lpFreeBuff,
  139.             LPMALLOC            lpMalloc )
  140. {
  141.     HRESULT hResult = hrSuccess;
  142.     LPABSRCH lpABSearch = NULL;
  143.     SCODE sc;
  144.     LPPROPDATA lpPropData = NULL;
  145.     SPropValue spv[cvalabsrchMax];
  146.     
  147.     /*  Do I support this interface?? */
  148.     if (lpInterface)
  149.     {
  150.         if (memcmp(lpInterface, &IID_IMAPIContainer, sizeof(IID)) &&
  151.             memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
  152.             memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
  153.         {
  154.             DebugTraceSc(HrNewSearch, MAPI_E_INTERFACE_NOT_SUPPORTED);
  155.             return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
  156.         }
  157.     }
  158.     /*
  159.      *  Allocate space for the directory container structure
  160.      */
  161.     sc = lpAllocBuff( sizeof(ABSRCH), (LPVOID *) &lpABSearch );
  162.     if (FAILED(sc))
  163.     {
  164.         hResult = ResultFromScode(sc);
  165.         goto err;
  166.     }
  167.     lpABSearch->lpVtbl = &vtblABSRCH;
  168.     lpABSearch->lcInit = 1;
  169.     lpABSearch->hResult = hrSuccess;
  170.     lpABSearch->idsLastError = 0;
  171.     lpABSearch->hLibrary = hLibrary;
  172.     lpABSearch->lpAllocBuff = lpAllocBuff;
  173.     lpABSearch->lpAllocMore = lpAllocMore;
  174.     lpABSearch->lpFreeBuff = lpFreeBuff;
  175.     lpABSearch->lpMalloc = lpMalloc;
  176.     lpABSearch->lpABLogon = lpABLogon;
  177.     lpABSearch->lpRestrictData = NULL;
  178.     /*
  179.      *  Create property storage object
  180.      */
  181.     sc = CreateIProp((LPIID) &IID_IMAPIPropData,
  182.         lpAllocBuff,
  183.         lpAllocMore,
  184.         lpFreeBuff,
  185.         lpMalloc,
  186.         &lpPropData);
  187.     if (FAILED(sc))
  188.     {
  189.         hResult = ResultFromScode(sc);
  190.         goto err;
  191.     }
  192.     spv[ivalabsrchPR_ANR_STRING].ulPropTag = PR_ANR_STRING;
  193.     spv[ivalabsrchPR_ANR_STRING].Value.lpszA = "";
  194.     /*
  195.      *   Set the default properties
  196.      */
  197.     hResult = lpPropData->lpVtbl->SetProps(lpPropData,
  198.         cvalabsrchMax,
  199.         spv,
  200.         NULL);
  201.     InitializeCriticalSection(&lpABSearch->cs);
  202.     /*  We must AddRef the lpABLogon object since we will be using it
  203.      */
  204.     lpABLogon->lpVtbl->AddRef(lpABLogon);
  205.     lpABSearch->lpPropData = (LPMAPIPROP) lpPropData;
  206.     *lppABSearch = (LPMAPICONTAINER) lpABSearch;
  207. out:
  208.     DebugTraceResult(HrNewSearch, hResult);
  209.     return hResult;
  210. err:
  211.     /*
  212.      *  free the ABContainer object
  213.      */
  214.     lpFreeBuff( lpABSearch );
  215.     /*
  216.      *  free the property storage object
  217.      */
  218.     if (lpPropData)
  219.         lpPropData->lpVtbl->Release(lpPropData);
  220.     goto out;
  221. }
  222. /*
  223.  -  ABSRCH_Release
  224.  -
  225.  *  Decrement lcInit.
  226.  *      When lcInit == 0, free up the lpABSearch structure
  227.  *
  228.  */
  229. STDMETHODIMP_(ULONG)
  230. ABSRCH_Release(LPABSRCH lpABSearch)
  231. {
  232.     long lcInit;
  233.     
  234.     /*
  235.      *  Check to see if it has a jump table
  236.      */
  237.     if (IsBadReadPtr(lpABSearch, sizeof(ABSRCH)))
  238.     {
  239.         /*
  240.          *  No jump table found
  241.          */
  242.         return 1;
  243.     }
  244.     /*
  245.      *  Check to see that it's the correct jump table
  246.      */
  247.     if (lpABSearch->lpVtbl != &vtblABSRCH)
  248.     {
  249.         /*
  250.          *  Not my jump table
  251.          */
  252.         return 1;
  253.     }
  254.     Validate_IUnknown_Release(lpABSearch);
  255.     EnterCriticalSection(&lpABSearch->cs);
  256.     lcInit = --lpABSearch->lcInit;
  257.     LeaveCriticalSection(&lpABSearch->cs);
  258.     if (lcInit == 0)
  259.     {
  260.         /*
  261.          *  Get rid of the lpPropData
  262.          */
  263.         if (lpABSearch->lpPropData)
  264.             lpABSearch->lpPropData->lpVtbl->Release(lpABSearch->lpPropData);
  265.         /*
  266.          *  Free up the restriction data
  267.          */
  268.         lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  269.         /*  
  270.          *  Release our reference to the ABLogon object.
  271.          */
  272.         if (lpABSearch->lpABLogon)
  273.         {
  274.             lpABSearch->lpABLogon->lpVtbl->Release(lpABSearch->lpABLogon);
  275.             lpABSearch->lpABLogon = NULL;
  276.         }
  277.         /*
  278.          *  Destroy the critical section for this object
  279.          */
  280.         DeleteCriticalSection(&lpABSearch->cs);
  281.         /*
  282.          *  Set the Jump table to NULL.  This way the client will find out
  283.          *  real fast if it's calling a method on a released object.  That is,
  284.          *  the client will crash.  Hopefully, this will happen during the
  285.          *  development stage of the client.
  286.          */
  287.         lpABSearch->lpVtbl = NULL;
  288.         /*
  289.          *  Need to free the object
  290.          */
  291.         lpABSearch->lpFreeBuff(lpABSearch);
  292.         return 0;
  293.     }
  294.     return lpABSearch->lcInit;
  295. }
  296. /*
  297.  -  ABSRCH_SaveChanges
  298.  -
  299.  *  This is used to save changes associated with the search dialog
  300.  *  in order to get the advanced search restriction and to save changes
  301.  *  associated with the container details dialog.
  302.  *
  303.  */
  304. SPropTagArray tagaANR_INT =
  305. {
  306.     1,
  307.     {
  308.         PR_ANR_STRING
  309.     }
  310. };
  311. STDMETHODIMP
  312. ABSRCH_SaveChanges(LPABSRCH lpABSearch, ULONG ulFlags)
  313. {
  314.     HRESULT hResult;
  315.     ULONG ulCount;
  316.     LPSPropValue lpspv = NULL;
  317.     LPPROPDATA lpPropData = (LPPROPDATA) lpABSearch->lpPropData;
  318.     
  319.     ABSRCH_ValidateObject(SaveChanges, lpABSearch);
  320.     
  321.     Validate_IMAPIProp_SaveChanges(lpABSearch, ulFlags);
  322.     EnterCriticalSection(&lpABSearch->cs);
  323.     /*
  324.      *  Is there a PR_ANR_STRING??
  325.      */
  326.     hResult = lpPropData->lpVtbl->GetProps(lpPropData,
  327.         &tagaANR_INT,
  328.         0,      /* ansi */
  329.         &ulCount,
  330.         &lpspv);
  331.     if (HR_FAILED(hResult))
  332.     {
  333.         goto ret;
  334.     }
  335.     if ((lpspv->ulPropTag == PR_ANR_STRING) && (lpspv->Value.lpszA[0] != ''))
  336.     {
  337.         /*
  338.          * save away the information to build up the new restriction
  339.          */
  340.         /*  Free any existing data */
  341.         if (lpABSearch->lpRestrictData)
  342.         {
  343.             lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  344.         }
  345.         lpABSearch->lpRestrictData = lpspv;
  346.         lpspv = NULL;
  347.     }
  348. ret:
  349.     LeaveCriticalSection(&lpABSearch->cs);
  350.     lpABSearch->lpFreeBuff(lpspv);
  351.     DebugTraceResult(ABSRCH_SaveChanges, hResult);
  352.     return hResult;
  353. }
  354. /*************************************************************************
  355.  *
  356.  -  ABSRCH_OpenProperty
  357.  -
  358.  *
  359.  *  This method allows the opening of the following object:
  360.  *
  361.  *  PR_DETAILS_TABLE        :-  Gets the display table associated with
  362.  *                              the advanced search dialog.
  363.  */
  364. STDMETHODIMP
  365. ABSRCH_OpenProperty(LPABSRCH lpABSearch,
  366.     ULONG ulPropTag,
  367.     LPCIID lpiid,
  368.     ULONG ulInterfaceOptions,
  369.     ULONG ulFlags,
  370.     LPUNKNOWN * lppUnk)
  371. {
  372.     HRESULT hResult;
  373.     ABSRCH_ValidateObject(OpenProperty, lpABSearch);
  374.     
  375.     Validate_IMAPIProp_OpenProperty(lpABSearch, ulPropTag, lpiid,
  376.                             ulInterfaceOptions, ulFlags, lppUnk);
  377.     /*
  378.      *  Check for flags we can't support
  379.      */
  380.     if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
  381.     {
  382.         hResult = ResultFromScode(E_ACCESSDENIED);
  383.         goto out;
  384.     }
  385.         
  386.     if (ulInterfaceOptions & ~MAPI_UNICODE)
  387.     {
  388.         /*
  389.          *  Only UNICODE flag should be set for any of the objects that might
  390.          *  be returned from this object.
  391.          */
  392.         
  393.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  394.         goto out;
  395.     }
  396.     
  397.     if ( ulInterfaceOptions & MAPI_UNICODE )
  398.     {
  399.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  400.         DebugTraceArg( ABSRCH_OpenProperty, "bad character width" );
  401.         goto out;
  402.         
  403.     }
  404.     /*
  405.      *  Details for this Search object
  406.      */
  407.     if (ulPropTag == PR_DETAILS_TABLE)
  408.     {
  409.         if (!memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  410.         {
  411.             hResult = HrGetSearchDialog(lpABSearch, (LPMAPITABLE *) lppUnk);
  412.             goto out;
  413.         }
  414.     } 
  415.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  416. out:
  417.     DebugTraceResult(ABSRCH_OpenProperty, hResult);
  418.     return hResult;
  419. }
  420. /*
  421.  -  ABSRCH_GetSearchCriteria
  422.  -
  423.  *  Generates the restriction associated with the data from
  424.  *  the advanced search dialog.  This restriction is subsequently
  425.  *  applied to the contents table retrieved from this container.
  426.  */
  427. STDMETHODIMP
  428. ABSRCH_GetSearchCriteria(   LPABSRCH lpABSearch,
  429.                         ULONG   ulFlags,
  430.                         LPSRestriction FAR * lppRestriction,
  431.                         LPENTRYLIST FAR * lppContainerList,
  432.                         ULONG FAR * lpulSearchState)
  433. {
  434.     HRESULT hResult = hrSuccess;
  435.     SCODE sc;
  436.     LPSRestriction lpRestriction = NULL;
  437.     LPSPropValue lpPropANR = NULL;
  438.     LPSTR lpszPartName;
  439.     LPSTR lpszRestrName;
  440.     ABSRCH_ValidateObject(GetSearchCriteria, lpABSearch);
  441.     
  442.     Validate_IMAPIContainer_GetSearchCriteria(lpABSearch, ulFlags,
  443.                                 lppRestriction, lppContainerList, 
  444.                                 lpulSearchState);
  445.     if (!lpABSearch->lpRestrictData)
  446.     {
  447.         hResult = ResultFromScode(MAPI_E_NOT_INITIALIZED);
  448.         if (lppRestriction)
  449.             *lppRestriction = NULL;
  450.         if (lppContainerList)
  451.             *lppContainerList = NULL;
  452.         if (lpulSearchState)
  453.             *lpulSearchState = 0L;
  454.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  455.         return hResult;
  456.     }
  457.     if (ulFlags & MAPI_UNICODE)
  458.     {
  459.         hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  460.         
  461.         DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  462.         return hResult;
  463.     }
  464.     /*
  465.      *  Entering state dependant section
  466.      */
  467.     EnterCriticalSection(&lpABSearch->cs);
  468.     /*
  469.      *  Ok, now build up a restriction using lpRestrictData (an LPSPropValue)
  470.      */
  471.     sc = lpABSearch->lpAllocBuff(sizeof(SRestriction), &lpRestriction);
  472.     if (FAILED(sc))
  473.     {
  474.         hResult = ResultFromScode(sc);
  475.         goto err;
  476.     }
  477.     sc = lpABSearch->lpAllocMore(sizeof(SPropValue), lpRestriction, &lpPropANR);
  478.     if (FAILED(sc))
  479.     {
  480.         hResult = ResultFromScode(sc);
  481.         goto err;
  482.     }
  483.     lpszRestrName = lpABSearch->lpRestrictData->Value.lpszA;
  484.     sc = lpABSearch->lpAllocMore(lstrlenA(lpszRestrName)+1,
  485.         lpRestriction,
  486.         &lpszPartName);
  487.     if (FAILED(sc))
  488.     {
  489.         hResult = ResultFromScode(sc);
  490.         goto err;
  491.     }
  492.     lstrcpyA(lpszPartName, lpszRestrName);
  493.     lpPropANR->ulPropTag = PR_ANR;
  494.     lpPropANR->Value.LPSZ = lpszPartName;
  495.     lpRestriction->rt = RES_PROPERTY;
  496.     lpRestriction->res.resProperty.relop = RELOP_EQ;
  497.     lpRestriction->res.resProperty.ulPropTag = PR_ANR;
  498.     lpRestriction->res.resProperty.lpProp = lpPropANR;
  499.     *lppRestriction = lpRestriction;
  500.     /*
  501.      *  The returned SearchState is set to 0 because none
  502.      *  of the defined states match what's going on.
  503.      */
  504.     if (lpulSearchState)
  505.         *lpulSearchState = 0;
  506. out:
  507.     LeaveCriticalSection(&lpABSearch->cs);
  508.     DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  509.     return hResult;
  510. err:
  511.     lpABSearch->lpFreeBuff(lpRestriction);
  512.     goto out;
  513. }
  514. /*
  515.  -  HrGetSearchDialog
  516.  -
  517.  *
  518.  *  Builds a display table for the search dialog.
  519.  */
  520. HRESULT
  521. HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable)
  522. {
  523.     HRESULT hResult;
  524.     /* Create a display table */
  525.     hResult = BuildDisplayTable(
  526.             lpABSearch->lpAllocBuff,
  527.             lpABSearch->lpAllocMore,
  528.             lpABSearch->lpFreeBuff,
  529.             lpABSearch->lpMalloc,
  530.             lpABSearch->hLibrary,
  531.             sizeof(rgdtpageSearch) / sizeof(DTPAGE),
  532.             rgdtpageSearch,
  533.             0,
  534.             lppSearchTable,
  535.             NULL);
  536.     DebugTraceResult(ABSRCH_GetSearchDialog, hResult);
  537.     return hResult;
  538. }