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 / status.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  12.9 KB  |  545 lines

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