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

Windows编程

开发平台:

Visual C++

  1. /***********************************************************************
  2.  *
  3.  *  STATUS.C
  4.  *
  5.  *
  6.  *  The Sample Address Book Provider.
  7.  *  This file contains the methods that implement the status object.
  8.  *
  9.  *  The following routines are implemented in this file:
  10.  *
  11.  *      HrNewStatusObject()
  12.  *      ABS_QueryInterface()
  13.  *      ABS_Release()
  14.  *      ABS_ValidateState()
  15.  *      ABS_SettingsDialog()
  16.  *      ABS_ChangePassword()
  17.  *      ABS_FlushQueues()
  18.  *
  19.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  20.  *
  21.  ***********************************************************************/
  22. #include "abp.h"
  23. #include "sampabp.rh"
  24. /*
  25.  *  Declaration of IMAPIStatus object implementation
  26.  */
  27. #undef  INTERFACE
  28. #define INTERFACE   struct _ABSTATUS
  29. #undef  MAPIMETHOD_
  30. #define MAPIMETHOD_(type, method)   MAPIMETHOD_DECLARE(type, method, ABS_)
  31.         MAPI_IUNKNOWN_METHODS(IMPL)
  32.         MAPI_IMAPIPROP_METHODS(IMPL)
  33.         MAPI_IMAPISTATUS_METHODS(IMPL)
  34. #undef  MAPIMETHOD_
  35. #define MAPIMETHOD_(type, method)   MAPIMETHOD_TYPEDEF(type, method, ABS_)
  36.         MAPI_IUNKNOWN_METHODS(IMPL)
  37.         MAPI_IMAPIPROP_METHODS(IMPL)
  38.         MAPI_IMAPISTATUS_METHODS(IMPL)
  39. #undef  MAPIMETHOD_
  40. #define MAPIMETHOD_(type, method)   STDMETHOD_(type, method)
  41. DECLARE_MAPI_INTERFACE(ABS_)
  42. {
  43.     MAPI_IUNKNOWN_METHODS(IMPL)
  44.     MAPI_IMAPIPROP_METHODS(IMPL)
  45.     MAPI_IMAPISTATUS_METHODS(IMPL)
  46. };
  47. /*
  48.  *  The actual definition of the structure behind the 'this' pointer for this object
  49.  */
  50. typedef struct _ABSTATUS
  51. {
  52.     const ABS_Vtbl FAR * lpVtbl;
  53.     SAB_Wrapped;
  54.     
  55. } ABSTATUS, *LPABSTATUS;
  56. /*
  57.  *  AB Status vtbl filled in here
  58.  */
  59. static const ABS_Vtbl vtblABS =
  60. {
  61.     ABS_QueryInterface,
  62.     (ABS_AddRef_METHOD *)           ROOT_AddRef,
  63.     ABS_Release,
  64.     (ABS_GetLastError_METHOD *)     ROOT_GetLastError,
  65.     (ABS_SaveChanges_METHOD *)      WRAP_SaveChanges,
  66.     (ABS_GetProps_METHOD *)         WRAP_GetProps,
  67.     (ABS_GetPropList_METHOD *)      WRAP_GetPropList,
  68.     (ABS_OpenProperty_METHOD *)     WRAP_OpenProperty,
  69.     (ABS_SetProps_METHOD *)         WRAP_SetProps,
  70.     (ABS_DeleteProps_METHOD *)      WRAP_DeleteProps,
  71.     (ABS_CopyTo_METHOD *)           WRAP_CopyTo,
  72.     (ABS_CopyProps_METHOD *)        WRAP_CopyProps,
  73.     (ABS_GetNamesFromIDs_METHOD *)  WRAP_GetNamesFromIDs,
  74.     (ABS_GetIDsFromNames_METHOD *)  WRAP_GetIDsFromNames,
  75.     ABS_ValidateState,
  76.     ABS_SettingsDialog,
  77.     ABS_ChangePassword,
  78.     ABS_FlushQueues
  79. };
  80. /*************************************************************************
  81.  *
  82.  -  HrNewStatusObject
  83.  -
  84.  *  Creates the Status object associated with a particular SAB logon object
  85.  *
  86.  *
  87.  */
  88. HRESULT
  89. HrNewStatusObject(LPMAPISTATUS *    lppABS,
  90.                 ULONG *             lpulObjType,
  91.                 ULONG               ulFlags,
  92.                 LPABLOGON           lpABLogon,
  93.                 LPCIID              lpIID,
  94.                 HINSTANCE           hLibrary,
  95.                 LPALLOCATEBUFFER    lpAllocBuff,
  96.                 LPALLOCATEMORE      lpAllocMore,
  97.                 LPFREEBUFFER        lpFreeBuff,
  98.                 LPMALLOC            lpMalloc )
  99. {
  100.     LPABSTATUS lpABS = NULL;
  101.     SCODE sc;
  102.     HRESULT hr = hrSuccess;
  103.     LPPROPDATA lpPropData = NULL;
  104.     SPropValue spv[6];
  105.     LPSTR lpszFileName;
  106.     /*
  107.      *
  108.      */
  109.     if (lpIID &&
  110.         (memcmp(lpIID, &IID_IMAPIStatus, sizeof(IID)) &&
  111.          memcmp(lpIID, &IID_IMAPIProp, sizeof(IID)) &&
  112.          memcmp(lpIID, &IID_IUnknown, sizeof(IID))))
  113.     {
  114.         DebugTraceSc(HrNewStatusObject, E_NOINTERFACE);
  115.         return ResultFromScode(E_NOINTERFACE);
  116.     }
  117.     /*
  118.      *  Allocate space for the ABSTATUS structure
  119.      */
  120.     sc = lpAllocBuff( sizeof(ABSTATUS), (LPVOID *) &lpABS );
  121.     if (FAILED(sc))
  122.     {
  123.         hr = ResultFromScode(sc);
  124.         goto err;
  125.     }
  126.     lpABS->lpVtbl = &vtblABS;
  127.     lpABS->lcInit = 1;
  128.     lpABS->hResult = hrSuccess;
  129.     lpABS->idsLastError = 0;
  130.     lpABS->hLibrary = hLibrary;
  131.     lpABS->lpAllocBuff = lpAllocBuff;
  132.     lpABS->lpAllocMore = lpAllocMore;
  133.     lpABS->lpFreeBuff = lpFreeBuff;
  134.     lpABS->lpMalloc = lpMalloc;
  135.     lpABS->lpABLogon = lpABLogon;
  136.     /*
  137.      *  Create lpPropData
  138.      */
  139.     sc = CreateIProp((LPIID) &IID_IMAPIPropData,
  140.         lpAllocBuff,
  141.         lpAllocMore,
  142.         lpFreeBuff,
  143.         lpMalloc,
  144.         &lpPropData);
  145.     if (FAILED(sc))
  146.     {
  147.         hr = ResultFromScode(sc);
  148.         goto err;
  149.     }
  150.     /*
  151.      *  Set up initial set of properties associated with this
  152.      *  status object.
  153.      */
  154.     /*
  155.      *  Register my status row...
  156.      */
  157.     hr = HrLpszGetCurrentFileName(lpABLogon, &lpszFileName);
  158.     if (HR_FAILED(hr))
  159.     {
  160.         goto err;
  161.     }
  162.     
  163.     spv[0].ulPropTag = PR_DISPLAY_NAME_A;
  164.     spv[0].Value.lpszA = lpszFileName;
  165.     spv[1].ulPropTag = PR_RESOURCE_METHODS;
  166.     spv[1].Value.l = 0;
  167.     spv[2].ulPropTag = PR_RESOURCE_FLAGS;
  168.     spv[2].Value.l = 0;
  169.     spv[3].ulPropTag = PR_STATUS_CODE;
  170.     spv[3].Value.l = STATUS_AVAILABLE;
  171.     spv[4].ulPropTag = PR_STATUS_STRING_A;
  172.     spv[4].Value.lpszA = "Available";
  173.     spv[5].ulPropTag = PR_PROVIDER_DISPLAY_A;
  174.     spv[5].Value.lpszA = "Sample Address Book Provider";
  175.     /*
  176.      *   Set the default properties
  177.      */
  178.     hr = lpPropData->lpVtbl->SetProps(lpPropData,
  179.         6,
  180.         spv,
  181.         NULL);
  182.     /*
  183.      *  Done with the current file name
  184.      */
  185.     lpFreeBuff(lpszFileName);
  186.     if (HR_FAILED(hr))
  187.     {
  188.         goto err;
  189.     }
  190.     /*
  191.      *  The whole object is set READONLY thus eliminating the need to
  192.      *  set access rights for the individual properties.
  193.      */
  194.     (void) lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READONLY);
  195.     lpABS->lpPropData = (LPMAPIPROP) lpPropData;
  196.     InitializeCriticalSection(&lpABS->cs);
  197.     /*  We must AddRef the lpABLogon object since we will be using it
  198.      */
  199.     lpABLogon->lpVtbl->AddRef(lpABLogon);
  200.     *lpulObjType = MAPI_STATUS;
  201.     *lppABS = (LPMAPISTATUS) lpABS;
  202. out:
  203.     DebugTraceResult(HrNewStatusObject, hr);
  204.     return hr;
  205. err:
  206.     if (lpPropData)
  207.         lpPropData->lpVtbl->Release(lpPropData);
  208.     lpFreeBuff( lpABS );
  209.     goto out;
  210. }
  211. /*************************************************************************
  212.  *
  213.  *
  214.  -  ABS_QueryInterface
  215.  -
  216.  *  This method would allow this object to return a different interface than
  217.  *  the current one.  This object need only support IMAPIStatus and any interface
  218.  *  it derives from.
  219.  *
  220.  */
  221. STDMETHODIMP
  222. ABS_QueryInterface(LPABSTATUS lpABS,
  223.     REFIID lpiid, LPVOID FAR * lppNewObj)
  224. {
  225.     HRESULT hr = hrSuccess;
  226.     /*
  227.      *  Check to see if lpABS is what we expect
  228.      */
  229.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  230.         || lpABS->lpVtbl != &vtblABS )
  231.     {
  232.         hr = ResultFromScode(E_INVALIDARG);
  233.         goto out;
  234.     }
  235.     Validate_IUnknown_QueryInterface(lpABS, lpiid, lppNewObj);
  236.     /*  See if the requested interface is one of ours */
  237.     if (memcmp(lpiid, &IID_IUnknown, sizeof(IID)) &&
  238.         memcmp(lpiid, &IID_IMAPIProp, sizeof(IID)) &&
  239.         memcmp(lpiid, &IID_IMAPIStatus, sizeof(IID)))
  240.     {
  241.         *lppNewObj = NULL;      /* OLE requires zeroing [out] parameter */
  242.         hr = ResultFromScode(E_NOINTERFACE);
  243.         goto out;
  244.     }
  245.     /*  We'll do this one. Bump the usage count and return a new pointer. */
  246.     EnterCriticalSection(&lpABS->cs);
  247.     
  248.     ++lpABS->lcInit;
  249.     
  250.     LeaveCriticalSection(&lpABS->cs);
  251.     *lppNewObj = lpABS;
  252. out:
  253.     DebugTraceResult(ABS_QueryInterface, hr);
  254.     return hr;
  255. }
  256. /**************************************************
  257.  *
  258.  -  ABS_Release
  259.  -
  260.  *      Decrement lpInit.
  261.  *      When lcInit == 0, free up the lpABS structure
  262.  *
  263.  */
  264. STDMETHODIMP_(ULONG) ABS_Release(LPABSTATUS lpABS)
  265. {
  266.     LONG lcInit;
  267.     /*
  268.      *  Check to see if lpABS is what we expect
  269.      */
  270.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS)))
  271.     {
  272.         /*
  273.          *  No jump table found
  274.          */
  275.         return 1;
  276.     }
  277.     /*
  278.      *  Check to see that it's the correct jump table
  279.      */
  280.     if (lpABS->lpVtbl != &vtblABS)
  281.     {
  282.         /*
  283.          *  Not my jump table
  284.          */
  285.         return 1;
  286.     }
  287.     Validate_IUnknown_Release(lpABS);
  288.     EnterCriticalSection(&lpABS->cs);
  289.     lcInit = --lpABS->lcInit;
  290.     LeaveCriticalSection(&lpABS->cs);
  291.     if (lcInit == 0)
  292.     {
  293.         /*
  294.          *  Get rid of the lpPropData
  295.          */
  296.         lpABS->lpPropData->lpVtbl->Release(lpABS->lpPropData);
  297.         /*
  298.          *  Delete the critical section
  299.          */
  300.         DeleteCriticalSection(&lpABS->cs);
  301.         /*  
  302.          *  Release our reference to the ABLogon object.
  303.          */
  304.         if (lpABS->lpABLogon)
  305.         {
  306.             lpABS->lpABLogon->lpVtbl->Release(lpABS->lpABLogon);
  307.             lpABS->lpABLogon = NULL;
  308.         }
  309.         /*
  310.          *  Set the Jump table to NULL.  This way the client will find out
  311.          *  real fast if it's calling a method on a released object.  That is,
  312.          *  the client will crash.  Hopefully, this will happen during the
  313.          *  development stage of the client.
  314.          */
  315.         lpABS->lpVtbl = NULL;
  316.         /*
  317.          *  Need to free the object
  318.          */
  319.         lpABS->lpFreeBuff( lpABS );
  320.         return 0;
  321.     }
  322.     return lcInit;
  323. }
  324. /**********************************************************************
  325.  *
  326.  -  ABS_ValidateState
  327.  -
  328.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  329.  *  I don't have to support this method.
  330.  *
  331.  */
  332. STDMETHODIMP
  333. ABS_ValidateState(LPABSTATUS lpABS,
  334.                   ULONG ulUIParam,
  335.                   ULONG ulFlags)
  336. {
  337.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  338.     /*
  339.      *  Check to see if lpABS is what we expect
  340.      */
  341.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  342.         || lpABS->lpVtbl != &vtblABS )
  343.     {
  344.         hr = ResultFromScode(E_INVALIDARG);
  345.         goto out;
  346.     }
  347.     Validate_IMAPIStatus_ValidateState(lpABS, ulUIParam, ulFlags);
  348.     
  349. out:
  350.     DebugTraceResult(ABS_ValidateState, hr);
  351.     return hr;
  352. }
  353. /**********************************************************************
  354.  *
  355.  -  ABS_SettingsDialog
  356.  -
  357.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  358.  *  I don't have to support this method.
  359.  *
  360.  */
  361. STDMETHODIMP
  362. ABS_SettingsDialog( LPABSTATUS lpABS,
  363.                     ULONG ulUIParam,
  364.                     ULONG ulFlags)
  365. {
  366.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  367.     /*
  368.      *  Check to see if lpABS is what we expect
  369.      */
  370.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  371.         || lpABS->lpVtbl != &vtblABS )
  372.     {
  373.         hr = ResultFromScode(E_INVALIDARG);
  374.         goto out;
  375.     }
  376.     Validate_IMAPIStatus_SettingsDialog(lpABS, ulUIParam, ulFlags);
  377.     
  378. out:
  379.     DebugTraceResult(ABS_SettingsDialog, hr);
  380.     return hr;
  381. }
  382. /**********************************************************************
  383.  *
  384.  -  ABS_ChangePassword
  385.  -
  386.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  387.  *  I don't have to support this method.
  388.  *
  389.  *  Note:   in the parameter validation below I chose only check the first 15
  390.  *          characters of the passwords.  This was arbitrary.
  391.  */
  392. STDMETHODIMP
  393. ABS_ChangePassword(LPABSTATUS lpABS,
  394.     LPTSTR lpOldPass,
  395.     LPTSTR lpNewPass,
  396.     ULONG ulFlags)
  397. {
  398.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  399.     /*
  400.      *  Check to see if lpABS is what we expect
  401.      */
  402.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  403.         || lpABS->lpVtbl != &vtblABS )
  404.     {
  405.         hr = ResultFromScode(E_INVALIDARG);
  406.         goto out;
  407.     }
  408.     Validate_IMAPIStatus_ChangePassword(lpABS, lpOldPass, lpNewPass, ulFlags);
  409.     
  410.     if ( ulFlags & MAPI_UNICODE )
  411.     {
  412.         // UNICODE is currently not supported by the sample AB
  413.         
  414.         hr = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  415.         goto out;
  416.     }
  417.     
  418.         
  419. out:
  420.     DebugTraceResult(ABS_ChangePassword, hr);
  421.     return hr;
  422. }
  423. /**********************************************************************
  424.  *
  425.  -  ABS_FlushQueues
  426.  -
  427.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  428.  *  I don't have to support this method.
  429.  *
  430.  */
  431. STDMETHODIMP
  432. ABS_FlushQueues(LPABSTATUS lpABS,
  433.     ULONG ulUIParam,
  434.     ULONG cbTargetTransport,
  435.     LPENTRYID lpTargetTransport,
  436.     ULONG ulFlags)
  437. {
  438.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  439.     /*
  440.      *  Check to see if lpABS is what we expect
  441.      */
  442.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS)) || lpABS->lpVtbl != &vtblABS )
  443.     {
  444.         hr = ResultFromScode(E_INVALIDARG);
  445.         goto out;
  446.     }
  447.     Validate_IMAPIStatus_FlushQueues(lpABS, ulUIParam, cbTargetTransport,
  448.                                     lpTargetTransport, ulFlags);
  449. out:
  450.     DebugTraceResult(ABS_FlushQueues, hr);
  451.     return hr;
  452. }