home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / sample.ab / status.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  14.5 KB  |  609 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 other parameters */
  284.  
  285.     if (IsBadReadPtr(lpiid, (UINT) sizeof(IID))
  286.         || IsBadWritePtr(lppNewObj, sizeof(LPVOID)))
  287.     {
  288.         hr = ResultFromScode(E_INVALIDARG);
  289.         goto out;
  290.     }
  291.  
  292.     /*  See if the requested interface is one of ours */
  293.  
  294.     if (memcmp(lpiid, &IID_IUnknown, sizeof(IID)) &&
  295.         memcmp(lpiid, &IID_IMAPIProp, sizeof(IID)) &&
  296.         memcmp(lpiid, &IID_IMAPIStatus, sizeof(IID)))
  297.     {
  298.         *lppNewObj = NULL;      /* OLE requires zeroing [out] parameter */
  299.         hr = ResultFromScode(E_NOINTERFACE);
  300.         goto out;
  301.     }
  302.  
  303.     /*  We'll do this one. Bump the usage count and return a new pointer. */
  304.  
  305.     EnterCriticalSection(&lpABS->cs);
  306.     
  307.     ++lpABS->lcInit;
  308.     
  309.     LeaveCriticalSection(&lpABS->cs);
  310.  
  311.     *lppNewObj = lpABS;
  312.  
  313. out:
  314.  
  315.     DebugTraceResult(ABS_QueryInterface, hr);
  316.     return hr;
  317. }
  318.  
  319. /**************************************************
  320.  *
  321.  -  ABS_Release
  322.  -
  323.  *      Decrement lpInit.
  324.  *      When lcInit == 0, free up the lpABS structure
  325.  *
  326.  */
  327. STDMETHODIMP_(ULONG) ABS_Release(LPABSTATUS lpABS)
  328. {
  329.     LONG lcInit;
  330.  
  331.     /*
  332.      *  Check to see if lpABS is what we expect
  333.      */
  334.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS)))
  335.     {
  336.         /*
  337.          *  No jump table found
  338.          */
  339.         return 1;
  340.     }
  341.  
  342.     /*
  343.      *  Check to see that it's the correct jump table
  344.      */
  345.     if (lpABS->lpVtbl != &vtblABS)
  346.     {
  347.         /*
  348.          *  Not my jump table
  349.          */
  350.         return 1;
  351.     }
  352.  
  353.     EnterCriticalSection(&lpABS->cs);
  354.  
  355.     lcInit = --lpABS->lcInit;
  356.  
  357.     LeaveCriticalSection(&lpABS->cs);
  358.  
  359.     if (lcInit == 0)
  360.     {
  361.  
  362.         /*
  363.          *  Get rid of the lpPropData
  364.          */
  365.  
  366.         lpABS->lpPropData->lpVtbl->Release(lpABS->lpPropData);
  367.  
  368.         /*
  369.          *  Delete the critical section
  370.          */
  371.  
  372.         DeleteCriticalSection(&lpABS->cs);
  373.  
  374.         /*  
  375.          *  Release our reference to the ABLogon object.
  376.          */
  377.         if (lpABS->lpABLogon)
  378.         {
  379.             lpABS->lpABLogon->lpVtbl->Release(lpABS->lpABLogon);
  380.             lpABS->lpABLogon = NULL;
  381.         }
  382.  
  383.         /*
  384.          *  Set the Jump table to NULL.  This way the client will find out
  385.          *  real fast if it's calling a method on a released object.  That is,
  386.          *  the client will crash.  Hopefully, this will happen during the
  387.          *  development stage of the client.
  388.          */
  389.  
  390.         lpABS->lpVtbl = NULL;
  391.  
  392.         /*
  393.          *  Need to free the object
  394.          */
  395.  
  396.         lpABS->lpFreeBuff( lpABS );
  397.         return 0;
  398.     }
  399.  
  400.     return lcInit;
  401.  
  402. }
  403.  
  404.  
  405. /**********************************************************************
  406.  *
  407.  -  ABS_ValidateState
  408.  -
  409.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  410.  *  I don't have to support this method.
  411.  *
  412.  */
  413.  
  414. STDMETHODIMP
  415. ABS_ValidateState(LPABSTATUS lpABS,
  416.                   ULONG ulUIParam,
  417.                   ULONG ulFlags)
  418. {
  419.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  420.     /*
  421.      *  Check to see if lpABS is what we expect
  422.      */
  423.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  424.         || lpABS->lpVtbl != &vtblABS )
  425.     {
  426.         hr = ResultFromScode(E_INVALIDARG);
  427.         goto out;
  428.     }
  429.  
  430.     /*  Validate other parameters */
  431.     if (ulFlags & ~(SUPPRESS_UI
  432.                     | REFRESH_XP_HEADER_CACHE
  433.                     | PROCESS_XP_HEADER_CACHE
  434.                     | FORCE_XP_CONNECT
  435.                     | FORCE_XP_DISCONNECT
  436.                     | CONFIG_CHANGED))
  437.     {
  438.         hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  439.         goto out;
  440.     }
  441.  
  442. out:
  443.     DebugTraceResult(ABS_ValidateState, hr);
  444.     return hr;
  445. }
  446.  
  447.  
  448. /**********************************************************************
  449.  *
  450.  -  ABS_SettingsDialog
  451.  -
  452.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  453.  *  I don't have to support this method.
  454.  *
  455.  */
  456. STDMETHODIMP
  457. ABS_SettingsDialog( LPABSTATUS lpABS,
  458.                     ULONG ulUIParam,
  459.                     ULONG ulFlags)
  460. {
  461.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  462.     /*
  463.      *  Check to see if lpABS is what we expect
  464.      */
  465.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  466.         || lpABS->lpVtbl != &vtblABS )
  467.     {
  468.         hr = ResultFromScode(E_INVALIDARG);
  469.         goto out;
  470.     }
  471.  
  472.     /*  Validate other parameters */
  473.     if (ulFlags & ~(UI_READONLY))
  474.     {
  475.         hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  476.         goto out;
  477.     }
  478.  
  479. out:
  480.     DebugTraceResult(ABS_SettingsDialog, hr);
  481.     return hr;
  482. }
  483.  
  484.  
  485. /**********************************************************************
  486.  *
  487.  -  ABS_ChangePassword
  488.  -
  489.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  490.  *  I don't have to support this method.
  491.  *
  492.  *  Note:   in the parameter validation below I chose only check the first 15
  493.  *          characters of the passwords.  This was arbitrary.
  494.  */
  495. STDMETHODIMP
  496. ABS_ChangePassword(LPABSTATUS lpABS,
  497.     LPTSTR lpOldPass,
  498.     LPTSTR lpNewPass,
  499.     ULONG ulFlags)
  500. {
  501.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  502.     /*
  503.      *  Check to see if lpABS is what we expect
  504.      */
  505.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS))
  506.         || lpABS->lpVtbl != &vtblABS )
  507.     {
  508.         hr = ResultFromScode(E_INVALIDARG);
  509.         goto out;
  510.     }
  511.  
  512.     /*  Validate other parameters */
  513.  
  514.     if (ulFlags & ~(MAPI_UNICODE))
  515.     {
  516.         hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  517.         goto out;
  518.     }
  519.  
  520.     if ( ulFlags & MAPI_UNICODE )
  521.     {
  522.         // UNICODE is currently not supported by the sample AB
  523.         
  524.         hr = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  525.         goto out;
  526.     }
  527.     
  528.     if (ulFlags)
  529.     {
  530.         /*
  531.          *  We're checking UNICODE strings
  532.          */
  533.         if (IsBadStringPtrW((LPWSTR) lpOldPass, (UINT) 15) ||
  534.             IsBadStringPtrW((LPWSTR) lpNewPass, (UINT) 15))
  535.         {
  536.             
  537.             hr = ResultFromScode(E_INVALIDARG);
  538.             goto out;
  539.         }
  540.     } else
  541.     {
  542.         /*
  543.          *  We're not checking UNICODE strings
  544.          */
  545.         if (IsBadStringPtrA((LPSTR) lpOldPass, (UINT) 15) ||
  546.             IsBadStringPtrA((LPSTR) lpNewPass, (UINT) 15))
  547.         {
  548.             
  549.             hr = ResultFromScode(E_INVALIDARG);
  550.             goto out;
  551.         }
  552.     }
  553.         
  554.  
  555. out:
  556.     DebugTraceResult(ABS_ChangePassword, hr);
  557.     return hr;
  558. }
  559.  
  560.  
  561. /**********************************************************************
  562.  *
  563.  -  ABS_FlushQueues
  564.  -
  565.  *  Since I did not set any flags for the property PR_RESOURCE_METHODS
  566.  *  I don't have to support this method.
  567.  *
  568.  */
  569. STDMETHODIMP
  570. ABS_FlushQueues(LPABSTATUS lpABS,
  571.     ULONG ulUIParam,
  572.     ULONG cbTargetTransport,
  573.     LPENTRYID lpTargetTransport,
  574.     ULONG ulFlags)
  575. {
  576.     HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  577.     /*
  578.      *  Check to see if lpABS is what we expect
  579.      */
  580.     if (IsBadReadPtr(lpABS, sizeof(ABSTATUS)) || lpABS->lpVtbl != &vtblABS )
  581.     {
  582.         hr = ResultFromScode(E_INVALIDARG);
  583.         goto out;
  584.     }
  585.  
  586.     /*  Validate other parameters */
  587.  
  588.     if (cbTargetTransport &&
  589.         ((cbTargetTransport < (ULONG) sizeof (ENTRYID)) ||
  590.           IsBadReadPtr(lpTargetTransport, (UINT) cbTargetTransport)))
  591.     {
  592.         hr = ResultFromScode(E_INVALIDARG);
  593.         goto out;
  594.     }
  595.     
  596.     if (ulFlags & ~(FLUSH_NO_UI
  597.                     | FLUSH_UPLOAD
  598.                     | FLUSH_DOWNLOAD
  599.                     | FLUSH_FORCE))
  600.     {
  601.         hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  602.         goto out;
  603.     }
  604.  
  605. out:
  606.     DebugTraceResult(ABS_FlushQueues, hr);
  607.     return hr;
  608. }
  609.