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 / remote.xp / xpfolder.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  53.7 KB  |  1,472 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  File Name 
  4. //      XPFOLDER.CPP
  5. //
  6. //  Description
  7. //      This file implements the IMAPIFolder interface with the methods 
  8. //      specified in the MAPI SPI 1.0.
  9. //
  10. //  Authors
  11. //      Irving De la Cruz
  12. //      Les Thaler
  13. //
  14. //  Revision: 1.7
  15. //
  16. // Written for Microsoft Windows Developer Support
  17. // Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
  18. //
  19. #include "XPWDSR.H"
  20.  
  21. // Remark this line to turn verbose tracing OFF
  22. #define DO_INFO_TRACES
  23. #ifdef DO_INFO_TRACES
  24. #define InfoTrace(a)   TraceInfoMessage(a)
  25. #else
  26. #define InfoTrace(a)   
  27. #endif // DO_INFO_TRACES
  28.  
  29. ///////////////////////////////////////////////////////////////////////////////
  30. //    CMAPIFolder::CMAPIFolder()
  31. //
  32. //    Parameters
  33. //      pStatusObj      Pointer to parent status object
  34. //      pLogonObj       Pointer to logon session
  35. //
  36. //    Purpose
  37. //      Constructor of the object. Parameters are passed to initialize the
  38. //      data members with the appropiate values.
  39. //
  40. //    Return Value
  41. //      None
  42. //
  43. CMAPIFolder::CMAPIFolder (CMAPIStatus * pStatusObj,
  44.                           CXPLogon *    pLogonObj)
  45. {
  46.     InfoTrace ("CMAPIFolder: Constructor called");
  47.     m_cRef = 1;
  48.     m_pTableData = NULL;
  49.     m_pLogon = pLogonObj;
  50.     m_pLogon->AddRef();
  51.     m_pStatusObj = pStatusObj;
  52. //    m_pStatusObj->AddRef(); the status object holds a reference to us, so
  53. //  addref will result in circular reference.
  54.     m_fNoHeadersFile = FALSE;
  55. }
  56.  
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //    CMAPIFolder::~CMAPIFolder()
  59. //
  60. //    Parameters
  61. //      None
  62. //
  63. //    Purpose
  64. //      Destructor of CMAPIFolder. Releases memory allocated for internal 
  65. //      properties during the life of this transport logon object.
  66. //
  67. //    Return Value
  68. //      None
  69. //
  70. CMAPIFolder::~CMAPIFolder ()
  71. {
  72.     InfoTrace ("CMAPIFolder: Destructor called");
  73.     if (m_pTableData)
  74.     {
  75.         m_pTableData->Release();
  76.         m_pTableData = NULL;
  77.     }
  78. //    m_pStatusObj->Release(); we didn't addref it in the constructor.
  79.     m_pStatusObj = NULL;
  80.     m_pLogon->Release();
  81.     m_pLogon = NULL;
  82.     m_fNoHeadersFile = FALSE;
  83. }
  84.  
  85. ///////////////////////////////////////////////////////////////////////////////
  86. //    CMAPIFolder::QueryInterface()
  87. //
  88. //    Parameters
  89. //      { Refer to OLE Documentation on this method }
  90. //
  91. //    Purpose
  92. //      Returns a pointer to a interface requested if the interface is 
  93. //      supported and implemented by this object. If it is not supported, it
  94. //      returns NULL
  95. //
  96. //    Return Value
  97. //      An HRESULT
  98. //
  99. STDMETHODIMP CMAPIFolder::QueryInterface (REFIID riid, LPVOID * ppvObj)
  100. {
  101.     // OLE requires NULLing parameter
  102.     *ppvObj = NULL;
  103.     // If this is one of the two IID return an interface pointer to it
  104.     if (riid == IID_IMAPIFolder || riid == IID_IMAPIContainer || riid == IID_IMAPIProp)
  105.     {
  106.         *ppvObj = (LPVOID)this;
  107.         // Increase usage count of this object
  108.         AddRef();
  109.         return S_OK;
  110.     }
  111.     // OLE's COM rules for IUnknown establish that if an interface B
  112.     // was obtained using QueryInterface() on interface A, querying B for
  113.     // its IUnknown IID, should return a pointer to the A interface.
  114.     // Since this IMAPIFolder interface was obtained from IMAPIStatus::QueryInterface,
  115.     // when requested for IUnknown, return the contained pointer to the parent status
  116.     // object
  117.     if (riid == IID_IUnknown)
  118.     {
  119.         *ppvObj = (LPVOID)m_pStatusObj;
  120.         // Increase usage count of this object
  121.         m_pStatusObj->AddRef();
  122.         return S_OK;
  123.     }
  124.     // This object does not support the interface requested
  125.     return E_NOINTERFACE;
  126. }
  127.  
  128. ///////////////////////////////////////////////////////////////////////////////
  129. //    CMAPIFolder::Release()
  130. //
  131. //    Parameters
  132. //      None
  133. //
  134. //    Purpose
  135. //      Decrements the usage count of the Folder object.
  136. //
  137. //    Return Value
  138. //      Usage count of this object.
  139. //
  140. STDMETHODIMP_(ULONG) CMAPIFolder::Release()
  141. {
  142.     ULONG ulCount = --m_cRef;
  143.     if (!ulCount)
  144.     {
  145.         delete this;
  146.     }
  147.     // If the count is 1, is only the internal reference kept in the parent
  148.     // status object. This is the time to flush the contents table to
  149.     // the headers file.
  150.     if (1 == ulCount)
  151.     {
  152.         CopyTableToFile();
  153.     }
  154.     return ulCount;
  155. }
  156.  
  157. ///////////////////////////////////////////////////////////////////////////////
  158. // IMAPIProp virtual member functions implementation
  159. //
  160.  
  161. ///////////////////////////////////////////////////////////////////////////////
  162. //    CMAPIFolder::GetLastError()
  163. //
  164. //    Parameters
  165. //      { Refer to MAPI Documentation on this method }
  166. //
  167. //    Purpose
  168. //      This function finds a string for the hError passed. The hError is the
  169. //      last error that occurred in one of our methods. Here we call a
  170. //      function to allocate a MAPIERROR structure and passed the information
  171. //      to the caller.
  172. //
  173. //    Return Value
  174. //      An HRESULT
  175. //
  176. STDMETHODIMP CMAPIFolder::GetLastError (HRESULT        hError,
  177.                                         ULONG          ulFlags,
  178.                                         LPMAPIERROR *  ppMAPIError)
  179. {
  180.     InfoTrace ("CMAPIFolder::GetLastError method called");
  181.     Validate_IMAPIProp_GetLastError (this, hError, ulFlags, ppMAPIError);
  182.  
  183.     // Allocate and fill a MAPIERROR structure with the error passed in.
  184.     // Use the common helper function GetMAPIError
  185.     return GetMAPIError (ppMAPIError, ulFlags, hError, m_pLogon->GetInstance());
  186. }
  187.  
  188. ///////////////////////////////////////////////////////////////////////////////
  189. //    CMAPIFolder::SaveChanges()
  190. //
  191. //    Parameters
  192. //      { Refer to MAPI Documentation on this method }
  193. //
  194. //    Purpose
  195. //      We don't implement this. Besides, folder objects are not transacted.
  196. //
  197. //    Return Value
  198. //      S_OK always.
  199. //
  200. STDMETHODIMP CMAPIFolder::SaveChanges (ULONG ulFlags)
  201. {
  202.     InfoTrace ("CMAPIFolder::SaveChanges method called");
  203.     Validate_IMAPIProp_SaveChanges (this, ulFlags);
  204.     return S_OK;
  205. }
  206.  
  207. ///////////////////////////////////////////////////////////////////////////////
  208. //    CMAPIFolder::GetProps()
  209. //
  210. //    Parameters
  211. //      { Refer to MAPI Documentation on this method }
  212. //
  213. //    Purpose
  214. //      Gets the properties of the remote message folder container. A client
  215. //      requests the properties it needs by passing an array of property tags
  216. //      in pTags. If the array pointer is NULL, we return ALL the properties
  217. //      we have.
  218. //
  219. //    Return Value
  220. //      An HRESULT
  221. //
  222. STDMETHODIMP CMAPIFolder::GetProps (LPSPropTagArray pTags,
  223.                                     ULONG           ulFlags,
  224.                                     ULONG *         pcValues,
  225.                                     LPSPropValue *  ppPropArray)
  226. {
  227.     InfoTrace ("CMAPIFolder::GetProps method called");
  228.     Validate_IMAPIProp_GetProps (this, pTags, ulFlags, pcValues, ppPropArray);
  229.  
  230.     #ifdef DO_INFO_TRACES
  231.     if (!pTags)
  232.     {
  233.         TraceInfoMessage ("CMAPIFolder::GetProps: All properties requested");
  234.     }
  235.     else
  236.     {
  237.         TraceMessage ("CMAPIFolder::GetProps Properties requested..."); for (ULONG j=0; j<pTags->cValues; j++) { TraceProp (pTags->aulPropTag[j]); }
  238.     }
  239.     #endif // DO_INFO_TRACES
  240.  
  241.     BOOL fGetAllProps = pTags ? FALSE : TRUE;
  242.     if (!pTags)
  243.     {
  244.         pTags = (LPSPropTagArray)&sptFolderProps;
  245.     }
  246.     *pcValues = pTags->cValues;
  247.     HRESULT hResult = gpfnAllocateBuffer (sizeof(SPropValue)*(*pcValues), (LPVOID *)ppPropArray);
  248.     if (hResult)
  249.     {
  250.         TraceResult ("CMAPIFolder::GetProps: Memory allocation failed", hResult);
  251.         return hResult;
  252.     }
  253.     if (fGetAllProps)
  254.     {
  255.         for (ULONG i=0; i<sptFolderProps.cValues; i++)
  256.         {
  257.             (*ppPropArray)[i].ulPropTag = sptFolderProps.aulPropTag[i];
  258.         }
  259.     }
  260.     else
  261.     {
  262.         // A client of the IMAPIProp::GetProps() method can pass PT_UNSPECIFIED in the
  263.         // tag of a property. Is the provider's responsiblity to return
  264.         // the proper type of the property.
  265.         for (ULONG k=0; k<pTags->cValues; k++)
  266.         {
  267.             for (ULONG i=0; i<sptFolderProps.cValues; i++)
  268.             {
  269.                 if (PROP_ID(pTags->aulPropTag[k]) == PROP_ID(sptFolderProps.aulPropTag[i]))
  270.                 {
  271.                     (*ppPropArray)[k].ulPropTag = sptFolderProps.aulPropTag[i];
  272.                 }
  273.                 else
  274.                 {
  275.                     (*ppPropArray)[k].ulPropTag = pTags->aulPropTag[k];
  276.                 }
  277.             }
  278.         }
  279.     }
  280.     TCHAR szBuffer[64];
  281.     BOOL fGotErrors = FALSE;    
  282.     LPVOID pSrc, pDst;
  283.     ULONG cbSize;
  284.     for (ULONG i=0; i<*pcValues; i++)
  285.     {
  286.         hResult = S_OK;
  287.         switch ((*ppPropArray)[i].ulPropTag)
  288.         {
  289.             case PR_NULL :
  290.                 (*ppPropArray)[i].Value.err = S_OK;
  291.                 break;
  292.             case PR_CREATION_TIME :
  293.                 if (m_fNoHeadersFile)
  294.                 {
  295.                     hResult = MAPI_E_NOT_FOUND;
  296.                 }
  297.                 else
  298.                 {
  299.                     (*ppPropArray)[i].Value.ft = m_ftLastUpdate;
  300.                 }
  301.                 break;
  302.             case PR_CONTENT_COUNT :
  303.                 hResult = MAPI_E_NOT_FOUND;
  304.                 if (m_pTableData)
  305.                 {
  306.                     LPMAPITABLE pTable;
  307.                     if (!m_pTableData->HrGetView (NULL, NULL, 0, &pTable))
  308.                     {
  309.                         if (!pTable->GetRowCount (0, &(*ppPropArray)[i].Value.ul))
  310.                         {
  311.                             hResult = S_OK;
  312.                         }
  313.                         pTable->Release();
  314.                     }
  315.                 }
  316.                 break;
  317.             case PR_ASSOC_CONTENT_COUNT :
  318.                 (*ppPropArray)[i].Value.l = 0;
  319.                 break;
  320.             case PR_ACCESS :
  321.                 (*ppPropArray)[i].Value.l = MAPI_ACCESS_READ;
  322.                 break;
  323.             case PR_ACCESS_LEVEL :
  324.                 (*ppPropArray)[i].Value.l = 0;
  325.                 break;
  326.             case PR_FOLDER_TYPE :
  327.                 (*ppPropArray)[i].Value.l = FOLDER_GENERIC;
  328.                 break;
  329.             case PR_OBJECT_TYPE :
  330.                 (*ppPropArray)[i].Value.l = MAPI_FOLDER;
  331.                 break;
  332.             case PR_DISPLAY_TYPE :
  333.                 (*ppPropArray)[i].Value.l = DT_FOLDER;
  334.                 break;
  335.             case PR_SUBFOLDERS :
  336.                 (*ppPropArray)[i].Value.b = FALSE;
  337.                 break;
  338.             case PR_CREATION_VERSION :
  339.                 (*ppPropArray)[i].Value.li.LowPart = TRANSPORT_VERSION_MAJOR;
  340.                 (*ppPropArray)[i].Value.li.HighPart = TRANSPORT_VERSION_MINOR;
  341.                 break;
  342.             case PR_CURRENT_VERSION :
  343.                 (*ppPropArray)[i].Value.li.LowPart = TRANSPORT_VERSION_MAJOR;
  344.                 (*ppPropArray)[i].Value.li.HighPart = TRANSPORT_VERSION_MINOR;
  345.                 break;
  346.             case PR_DISPLAY_NAME :
  347.                 szBuffer[0] = 0;
  348.                 LoadString (m_pLogon->GetInstance(), IDS_MSG_REMOTE_FOLDER_VIEW_NAME, szBuffer, 64);
  349.                 pSrc = (LPVOID)szBuffer;
  350.                 break;
  351.             default:
  352.                 hResult = MAPI_E_NOT_FOUND;
  353.                 #ifdef DO_INFO_TRACES
  354.                 TraceRaw ("CMAPIFolder::GetProps: Not Found - "); TraceProp ((*ppPropArray)[i].ulPropTag);
  355.                 #endif // #DO_INFO_TRACES
  356.                 break;
  357.         }
  358.         if (!hResult && 
  359.             (PROP_TYPE((*ppPropArray)[i].ulPropTag) == PT_BINARY ||
  360.              PROP_TYPE((*ppPropArray)[i].ulPropTag) == PT_TSTRING))
  361.         {
  362.             if (PROP_TYPE((*ppPropArray)[i].ulPropTag) == PT_TSTRING)
  363.             {
  364.                 cbSize = Cbtszsize ((LPTSTR)pSrc);
  365.             }
  366.             hResult = gpfnAllocateMore (cbSize, *ppPropArray, &pDst);
  367.             if (!hResult)
  368.             {
  369.                 CopyMemory (pDst, pSrc, cbSize);
  370.                 if (PROP_TYPE((*ppPropArray)[i].ulPropTag) == PT_BINARY)
  371.                 {
  372.                     (*ppPropArray)[i].Value.bin.cb  = cbSize;
  373.                     (*ppPropArray)[i].Value.bin.lpb = (LPBYTE)pDst;
  374.                 }
  375.                 else
  376.                 {
  377.                     (*ppPropArray)[i].Value.LPSZ = (LPTSTR)pDst;
  378.                 }
  379.             }
  380.         }
  381.         if (hResult)
  382.         {
  383.             (*ppPropArray)[i].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID((*ppPropArray)[i].ulPropTag));
  384.             (*ppPropArray)[i].Value.err = hResult;
  385.             fGotErrors = TRUE;
  386.         }
  387.     }
  388.     if (fGotErrors)
  389.     {
  390.         hResult = MAPI_W_ERRORS_RETURNED;
  391.     }
  392.     return hResult;
  393. }
  394.  
  395. ///////////////////////////////////////////////////////////////////////////////
  396. //    CMAPIFolder::GetPropList()
  397. //
  398. //    Parameters
  399. //      { Refer to MAPI Documentation on this method }
  400. //
  401. //    Purpose
  402. //      Returns an array with all the property tags that we support in
  403. //      this folder
  404. //
  405. //    Return Value
  406. //      An HRESULT
  407. //
  408. STDMETHODIMP CMAPIFolder::GetPropList (ULONG ulFlags, LPSPropTagArray * ppTags)
  409. {
  410.     InfoTrace ("CMAPIFolder::GetPropList method called");
  411.     Validate_IMAPIProp_GetPropList (this, ulFlags, ppTags);
  412.  
  413.     ULONG cbTagsArraySize = CbNewSPropTagArray(NUM_FOLDER_PROPS);
  414.     // Allocate the required amount of memory
  415.     HRESULT hResult = gpfnAllocateBuffer (cbTagsArraySize, (LPVOID *)ppTags);
  416.     TraceResult ("CMAPIFolder::GetPropList: Memory allocation failed", hResult);
  417.     if (!hResult)
  418.     {
  419.         // Copy the contents of our property tag array into the buffer
  420.         CopyMemory (*ppTags, &sptFolderProps, cbTagsArraySize);
  421.     }
  422.     return hResult;
  423. }
  424.  
  425. ///////////////////////////////////////////////////////////////////////////////
  426. //    CMAPIFolder::OpenProperty()
  427. //
  428. //    Parameters
  429. //      { Refer to MAPI Documentation on this method }
  430. //
  431. //    Purpose
  432. //      Stub method.
  433. //
  434. //    Return Value
  435. //      MAPI_E_NO_SUPPORT always.
  436. //
  437. STDMETHODIMP CMAPIFolder::OpenProperty (ULONG       ulPropTag,
  438.                                         LPCIID      piid,
  439.                                         ULONG       ulInterfaceOptions,
  440.                                         ULONG       ulFlags,
  441.                                         LPUNKNOWN * ppUnk)
  442. {
  443.     InfoTrace ("CMAPIFolder::OpenProperty method called");
  444.     Validate_IMAPIProp_OpenProperty (this, ulPropTag,  piid, ulInterfaceOptions, ulFlags, ppUnk);
  445.     return MAPI_E_NO_SUPPORT;
  446. }
  447.  
  448. ///////////////////////////////////////////////////////////////////////////////
  449. //    CMAPIFolder::SetProps()
  450. //
  451. //    Parameters
  452. //      { Refer to MAPI Documentation on this method }
  453. //
  454. //    Purpose
  455. //      Stub method.
  456. //
  457. //    Return Value
  458. //      MAPI_E_NO_SUPPORT always.
  459. //
  460. STDMETHODIMP CMAPIFolder::SetProps (ULONG                   cValues,
  461.                                     LPSPropValue            pPropArray,
  462.                                     LPSPropProblemArray *   ppProblems)
  463. {
  464.     InfoTrace ("CMAPIFolder::SetProps method called");
  465.     Validate_IMAPIProp_SetProps (this, cValues, pPropArray, ppProblems);
  466.     return MAPI_E_NO_SUPPORT;
  467. }
  468.  
  469. ///////////////////////////////////////////////////////////////////////////////
  470. //    CMAPIFolder::DeleteProps()
  471. //
  472. //    Parameters
  473. //      { Refer to MAPI Documentation on this method }
  474. //
  475. //    Purpose
  476. //      Stub method.
  477. //
  478. //    Return Value
  479. //      MAPI_E_NO_SUPPORT always.
  480. //
  481. STDMETHODIMP CMAPIFolder::DeleteProps (LPSPropTagArray       pPropTagArray,
  482.                                        LPSPropProblemArray * ppProblems)
  483. {
  484.     InfoTrace ("CMAPIFolder::DeleteProps method called");
  485.     Validate_IMAPIProp_DeleteProps (this, pPropTagArray, ppProblems);
  486.     return MAPI_E_NO_SUPPORT;
  487. }
  488.  
  489. ///////////////////////////////////////////////////////////////////////////////
  490. //    CMAPIFolder::CopyTo()
  491. //
  492. //    Parameters
  493. //      { Refer to MAPI Documentation on this method }
  494. //
  495. //    Purpose
  496. //      Stub method.
  497. //
  498. //    Return Value
  499. //      MAPI_E_NO_SUPPORT always.
  500. //
  501. STDMETHODIMP CMAPIFolder::CopyTo (ULONG                 ciidExclude,
  502.                                   LPCIID                rgiidExclude,
  503.                                   LPSPropTagArray       pExcludeProps,
  504.                                   ULONG                 ulUIParam,
  505.                                   LPMAPIPROGRESS        pProgress,
  506.                                   LPCIID                pInterface,
  507.                                   LPVOID                pDestObj,
  508.                                   ULONG                 ulFlags,
  509.                                   LPSPropProblemArray * ppProblems)
  510. {
  511.     InfoTrace ("CMAPIFolder::CopyTo method called");
  512.     Validate_IMAPIProp_CopyTo (this,
  513.                                ciidExclude,
  514.                                rgiidExclude,
  515.                                pExcludeProps,
  516.                                ulUIParam,
  517.                                pProgress,
  518.                                pInterface,
  519.                                pDestObj,
  520.                                ulFlags,
  521.                                ppProblems);
  522.     return MAPI_E_NO_SUPPORT;
  523. }
  524.  
  525. ///////////////////////////////////////////////////////////////////////////////
  526. //    CMAPIFolder::CopyProps()
  527. //
  528. //    Parameters
  529. //      { Refer to MAPI Documentation on this method }
  530. //
  531. //    Purpose
  532. //      Stub method.
  533. //
  534. //    Return Value
  535. //      MAPI_E_NO_SUPPORT always.
  536. //
  537. STDMETHODIMP CMAPIFolder::CopyProps (LPSPropTagArray        pIncludeProps,
  538.                                      ULONG                  ulUIParam,
  539.                                      LPMAPIPROGRESS         pProgress,
  540.                                      LPCIID                 pInterface,
  541.                                      LPVOID                 pDestObj,
  542.                                      ULONG                  ulFlags,
  543.                                      LPSPropProblemArray *  ppProblems)
  544. {
  545.     InfoTrace ("CMAPIFolder::CopyProps method called");
  546.     Validate_IMAPIProp_CopyProps (this,
  547.                                   pIncludeProps,
  548.                                   ulUIParam,
  549.                                   pProgress,
  550.                                   pInterface,
  551.                                   pDestObj,
  552.                                   ulFlags,
  553.                                   ppProblems);
  554.     return MAPI_E_NO_SUPPORT;
  555. }
  556.  
  557. ///////////////////////////////////////////////////////////////////////////////
  558. //    CMAPIFolder::GetNamesFromIDs()
  559. //
  560. //    Parameters
  561. //      { Refer to MAPI Documentation on this method }
  562. //
  563. //    Purpose
  564. //      Stub method.
  565. //
  566. //    Return Value
  567. //      MAPI_E_NO_SUPPORT always.
  568. //
  569. STDMETHODIMP CMAPIFolder::GetNamesFromIDs (LPSPropTagArray *    ppPropTags,
  570.                                            LPGUID               pPropSetGuid,
  571.                                            ULONG                ulFlags,
  572.                                            ULONG *              pcPropNames,
  573.                                            LPMAPINAMEID **      pppPropNames)
  574. {
  575.     InfoTrace ("CMAPIFolder::GetNamesFromIDs method called");
  576.     Validate_IMAPIProp_GetNamesFromIDs (this,
  577.                                         ppPropTags,
  578.                                         pPropSetGuid,
  579.                                         ulFlags,
  580.                                         pcPropNames,
  581.                                         pppPropNames);
  582.     return MAPI_E_NO_SUPPORT;
  583. }
  584.  
  585. ///////////////////////////////////////////////////////////////////////////////
  586. //    CMAPIFolder::GetIDsFromNames()
  587. //
  588. //    Parameters
  589. //      { Refer to MAPI Documentation on this method }
  590. //
  591. //    Purpose
  592. //      Stub method.
  593. //
  594. //    Return Value
  595. //      MAPI_E_NO_SUPPORT always.
  596. //
  597. STDMETHODIMP CMAPIFolder::GetIDsFromNames (ULONG                cPropNames,
  598.                                            LPMAPINAMEID *       ppPropNames,
  599.                                            ULONG                ulFlags,
  600.                                            LPSPropTagArray *    ppPropTags)
  601. {
  602.     InfoTrace ("CMAPIFolder::GetIDsFromNames method called");
  603.     Validate_IMAPIProp_GetIDsFromNames (this,
  604.                                         cPropNames,
  605.                                         ppPropNames,
  606.                                         ulFlags,
  607.                                         ppPropTags);
  608.     return MAPI_E_NO_SUPPORT;
  609. }
  610.  
  611. ///////////////////////////////////////////////////////////////////////////////
  612. // IMAPIContainer virtual member functions implementation
  613. //
  614.  
  615. ///////////////////////////////////////////////////////////////////////////////
  616. //    CMAPIFolder::GetContentsTable()
  617. //
  618. //    Parameters
  619. //      { Refer to MAPI Documentation on this method }
  620. //
  621. //    Purpose
  622. //
  623. //    Return Value
  624. //      An HRESULT
  625. //
  626. STDMETHODIMP CMAPIFolder::GetContentsTable (ULONG ulFlags, LPMAPITABLE * ppTable)
  627. {
  628.     InfoTrace ("CMAPIFolder::GetContentsTable method called");
  629.     Validate_IMAPIContainer_GetContentsTable (this, ulFlags, ppTable);
  630.  
  631.     if (MAPI_ASSOCIATED & ulFlags)
  632.     {
  633.         TraceMessage ("CMAPIFolder::GetContentsTable: We don't have associated messages");
  634.         return MAPI_E_NO_SUPPORT;
  635.     }
  636.     HRESULT hResult;
  637.     // If we don't have an ITableData interface pointer instantiated, create one.
  638.     if (!m_pTableData)
  639.     {
  640.         hResult = CreateTable (&IID_IMAPITableData,
  641.                                gpfnAllocateBuffer,
  642.                                gpfnAllocateMore,
  643.                                gpfnFreeBuffer,
  644.                                NULL,
  645.                                TBLTYPE_DYNAMIC,
  646.                                PR_ENTRYID,
  647.                                (LPSPropTagArray)&sptFldContents,
  648.                                &m_pTableData);
  649.         if (hResult)
  650.         {
  651.             TraceResult ("CMAPIFolder::GetContentsTable: Failed to create an ITableData object", hResult);
  652.             return hResult;
  653.         }
  654.  
  655.         // Populate the data for the table here
  656.         hResult = FillContentsTable (m_pLogon->GetLocalHeadersCache());
  657.         if (hResult)
  658.         {
  659.             TraceResult ("CMAPIFolder::GetContentsTable: Failed to populate table data", hResult);
  660.             return hResult;
  661.         }
  662.     }
  663.     hResult = m_pTableData->HrGetView (NULL, NULL, 0, ppTable);
  664.     // If any, trace out the error code.
  665.     TraceResult ("CMAPIFolder::GetContentsTable: Failed to create a view of the table data", hResult);
  666.     return hResult;
  667. }
  668.  
  669. ///////////////////////////////////////////////////////////////////////////////
  670. //    CMAPIFolder::GetHierarchyTable()
  671. //
  672. //    Parameters
  673. //      { Refer to MAPI Documentation on this method }
  674. //
  675. //    Purpose
  676. //      Stub method.
  677. //
  678. //    Return Value
  679. //      MAPI_E_NO_SUPPORT always.
  680. //
  681. STDMETHODIMP CMAPIFolder::GetHierarchyTable (ULONG          ulFlags,
  682.                                              LPMAPITABLE *  ppTable)
  683. {
  684.     InfoTrace ("CMAPIFolder::GetHierarchyTable method called");
  685.     Validate_IMAPIContainer_GetHierarchyTable (this, ulFlags, ppTable);
  686.     return MAPI_E_NO_SUPPORT;
  687. }
  688.  
  689. ///////////////////////////////////////////////////////////////////////////////
  690. //    CMAPIFolder::OpenEntry()
  691. //
  692. //    Parameters
  693. //      { Refer to MAPI Documentation on this method }
  694. //
  695. //    Purpose
  696. //      Stub method.
  697. //
  698. //    Return Value
  699. //      MAPI_E_NO_SUPPORT always.
  700. //
  701. STDMETHODIMP CMAPIFolder::OpenEntry (ULONG          cbEntryID,
  702.                                      LPENTRYID      pEntryID,
  703.                                      LPCIID         pInterface,
  704.                                      ULONG          ulFlags,
  705.                                      ULONG *        pulObjType,
  706.                                      LPUNKNOWN *    ppUnk)
  707. {
  708.     InfoTrace ("CMAPIFolder::OpenEntry method called");
  709.     Validate_IMAPIContainer_OpenEntry (this,
  710.                                        cbEntryID,
  711.                                        pEntryID,
  712.                                        pInterface,
  713.                                        ulFlags,
  714.                                        pulObjType,
  715.                                        ppUnk);
  716.     return MAPI_E_NO_SUPPORT;
  717. }
  718.  
  719. ///////////////////////////////////////////////////////////////////////////////
  720. //    CMAPIFolder::SetSearchCriteria()
  721. //
  722. //    Parameters
  723. //      { Refer to MAPI Documentation on this method }
  724. //
  725. //    Purpose
  726. //      Stub method.
  727. //
  728. //    Return Value
  729. //      MAPI_E_NO_SUPPORT always.
  730. //
  731. STDMETHODIMP CMAPIFolder::SetSearchCriteria (LPSRestriction pRestriction,
  732.                                              LPENTRYLIST    pContainerList,
  733.                                              ULONG          ulSearchFlags)
  734. {
  735.     InfoTrace ("CMAPIFolder::SetSearchCriteria method called");
  736.     Validate_IMAPIContainer_SetSearchCriteria (this, pRestriction, pContainerList, ulSearchFlags);
  737.     return MAPI_E_NO_SUPPORT;
  738. }
  739.  
  740. ///////////////////////////////////////////////////////////////////////////////
  741. //    CMAPIFolder::GetSearchCriteria()
  742. //
  743. //    Parameters
  744. //      { Refer to MAPI Documentation on this method }
  745. //
  746. //    Purpose
  747. //      Stub method.
  748. //
  749. //    Return Value
  750. //      MAPI_E_NO_SUPPORT always.
  751. //
  752. STDMETHODIMP CMAPIFolder::GetSearchCriteria (ULONG             ulFlags,
  753.                                              LPSRestriction *  ppRestriction,
  754.                                              LPENTRYLIST *     ppContainerList,
  755.                                              ULONG *           pulSearchState)
  756. {
  757.     InfoTrace ("CMAPIFolder::GetSearchCriteria method called");
  758.     Validate_IMAPIContainer_GetSearchCriteria (this, ulFlags, ppRestriction, ppContainerList, pulSearchState);
  759.     return MAPI_E_NO_SUPPORT;
  760. }
  761.  
  762. ///////////////////////////////////////////////////////////////////////////////
  763. // IMAPIFolder virtual member functions implementation
  764. //
  765.  
  766. ///////////////////////////////////////////////////////////////////////////////
  767. //    CMAPIFolder::CreateMessage()
  768. //
  769. //    Parameters
  770. //      { Refer to MAPI Documentation on this method }
  771. //
  772. //    Purpose
  773. //      Stub method.
  774. //
  775. //    Return Value
  776. //      MAPI_E_NO_SUPPORT always.
  777. //
  778. STDMETHODIMP CMAPIFolder::CreateMessage (LPCIID         pInterface,
  779.                                          ULONG          ulFlags,
  780.                                          LPMESSAGE *    ppMessage)
  781. {
  782.     InfoTrace ("CMAPIFolder::CreateMessage method called");
  783.     Validate_IMAPIFolder_CreateMessage (this, pInterface, ulFlags, ppMessage);
  784.     return MAPI_E_NO_SUPPORT;
  785. }
  786.  
  787. ///////////////////////////////////////////////////////////////////////////////
  788. //    CMAPIFolder::CopyMessages()
  789. //
  790. //    Parameters
  791. //      { Refer to MAPI Documentation on this method }
  792. //
  793. //    Purpose
  794. //      Stub method.
  795. //
  796. //    Return Value
  797. //      MAPI_E_NO_SUPPORT always.
  798. //
  799. STDMETHODIMP CMAPIFolder::CopyMessages (LPENTRYLIST     pMsgList,
  800.                                         LPCIID          pInterface,
  801.                                         LPVOID          pDestFolder,
  802.                                         ULONG           ulUIParam,
  803.                                         LPMAPIPROGRESS  pProgress,
  804.                                         ULONG           ulFlags)
  805. {
  806.     InfoTrace ("CMAPIFolder::CopyMessages method called");
  807.     Validate_IMAPIFolder_CopyMessages (this,
  808.                                        pMsgList,
  809.                                        pInterface,
  810.                                        pDestFolder,
  811.                                        ulUIParam,
  812.                                        pProgress,
  813.                                        ulFlags);
  814.     return MAPI_E_NO_SUPPORT;
  815. }
  816.  
  817. ///////////////////////////////////////////////////////////////////////////////
  818. //    CMAPIFolder::DeleteMessages()
  819. //
  820. //    Parameters
  821. //      { Refer to MAPI Documentation on this method }
  822. //
  823. //    Purpose
  824. //      Stub method.
  825. //
  826. //    Return Value
  827. //      MAPI_E_NO_SUPPORT always.
  828. //
  829. STDMETHODIMP CMAPIFolder::DeleteMessages (LPENTRYLIST       pMsgList,
  830.                                           ULONG             ulUIParam,
  831.                                           LPMAPIPROGRESS    pProgress,
  832.                                           ULONG             ulFlags)
  833. {
  834.     InfoTrace ("CMAPIFolder::DeleteMessages method called");
  835.     Validate_IMAPIFolder_DeleteMessages (this,
  836.                                          pMsgList,
  837.                                          ulUIParam,
  838.                                          pProgress,
  839.                                          ulFlags);
  840.     return MAPI_E_NO_SUPPORT;
  841. }
  842.  
  843. ///////////////////////////////////////////////////////////////////////////////
  844. //    CMAPIFolder::CreateFolder()
  845. //
  846. //    Parameters
  847. //      { Refer to MAPI Documentation on this method }
  848. //
  849. //    Purpose
  850. //      Stub method.
  851. //
  852. //    Return Value
  853. //      MAPI_E_NO_SUPPORT always.
  854. //
  855. STDMETHODIMP CMAPIFolder::CreateFolder (ULONG           ulFolderType,
  856.                                         LPTSTR          pszFolderName,
  857.                                         LPTSTR          pszFolderComment,
  858.                                         LPCIID          pInterface,
  859.                                         ULONG           ulFlags,
  860.                                         LPMAPIFOLDER *  ppFolder)
  861. {
  862.     InfoTrace ("CMAPIFolder::CreateFolder method called");
  863.     Validate_IMAPIFolder_CreateFolder (this,
  864.                                        ulFolderType,
  865.                                        pszFolderName,
  866.                                        pszFolderComment,
  867.                                        pInterface,
  868.                                        ulFlags,
  869.                                        ppFolder);
  870.     return MAPI_E_NO_SUPPORT;
  871. }
  872.  
  873. ///////////////////////////////////////////////////////////////////////////////
  874. //    CMAPIFolder::CopyFolder()
  875. //
  876. //    Parameters
  877. //      { Refer to MAPI Documentation on this method }
  878. //
  879. //    Purpose
  880. //      Stub method.
  881. //
  882. //    Return Value
  883. //      MAPI_E_NO_SUPPORT always.
  884. //
  885. STDMETHODIMP CMAPIFolder::CopyFolder (ULONG             cbEntryID,
  886.                                       LPENTRYID         pEntryID,
  887.                                       LPCIID            pInterface,
  888.                                       LPVOID            pDestFolder,
  889.                                       LPTSTR            pszNewFolderName,
  890.                                       ULONG             ulUIParam,
  891.                                       LPMAPIPROGRESS    pProgress,
  892.                                       ULONG             ulFlags)
  893. {
  894.     InfoTrace ("CMAPIFolder::CopyFolder method called");
  895.     Validate_IMAPIFolder_CopyFolder (this,
  896.                                      cbEntryID,
  897.                                      pEntryID,
  898.                                      pInterface,
  899.                                      pDestFolder,
  900.                                      pszNewFolderName,
  901.                                      ulUIParam,
  902.                                      pProgress,
  903.                                      ulFlags);
  904.     return MAPI_E_NO_SUPPORT;
  905. }
  906.  
  907. ///////////////////////////////////////////////////////////////////////////////
  908. //    CMAPIFolder::DeleteFolder()
  909. //
  910. //    Parameters
  911. //      { Refer to MAPI Documentation on this method }
  912. //
  913. //    Purpose
  914. //      Stub method.
  915. //
  916. //    Return Value
  917. //      MAPI_E_NO_SUPPORT always.
  918. //
  919. STDMETHODIMP CMAPIFolder::DeleteFolder (ULONG           cbEntryID,
  920.                                         LPENTRYID       pEntryID,
  921.                                         ULONG           ulUIParam,
  922.                                         LPMAPIPROGRESS  pProgress,
  923.                                         ULONG           ulFlags)
  924. {
  925.     InfoTrace ("CMAPIFolder::DeleteFolder method called");
  926.     Validate_IMAPIFolder_DeleteFolder (this,
  927.                                        cbEntryID,
  928.                                        pEntryID,
  929.                                        ulUIParam,
  930.                                        pProgress,
  931.                                        ulFlags);
  932.     return MAPI_E_NO_SUPPORT;
  933. }
  934.  
  935. ///////////////////////////////////////////////////////////////////////////////
  936. //    CMAPIFolder::SetReadFlags()
  937. //
  938. //    Parameters
  939. //      { Refer to MAPI Documentation on this method }
  940. //
  941. //    Purpose
  942. //      Stub method.
  943. //
  944. //    Return Value
  945. //      MAPI_E_NO_SUPPORT always.
  946. //
  947. STDMETHODIMP CMAPIFolder::SetReadFlags (LPENTRYLIST     pMsgList,
  948.                                         ULONG           ulUIParam,
  949.                                         LPMAPIPROGRESS  pProgress,
  950.                                         ULONG           ulFlags)
  951. {
  952.     InfoTrace ("CMAPIFolder::SetReadFlags method called");
  953.     Validate_IMAPIFolder_SetReadFlags (this,
  954.                                        pMsgList,
  955.                                        ulUIParam,
  956.                                        pProgress,
  957.                                        ulFlags);
  958.     return MAPI_E_NO_SUPPORT;
  959. }
  960.  
  961. ///////////////////////////////////////////////////////////////////////////////
  962. //    CMAPIFolder::GetMessageStatus()
  963. //
  964. //    Parameters
  965. //      { Refer to MAPI Documentation on this method }
  966. //
  967. //    Purpose
  968. //      Stub method.
  969. //
  970. //    Return Value
  971. //      MAPI_E_NO_SUPPORT always.
  972. //
  973. STDMETHODIMP CMAPIFolder::GetMessageStatus (ULONG       cbEntryID,
  974.                                             LPENTRYID   pEntryID,
  975.                                             ULONG       ulFlags,
  976.                                             ULONG *     pulMessageStatus)
  977. {
  978.     InfoTrace ("CMAPIFolder::GetMessageStatus method called");
  979.     Validate_IMAPIFolder_GetMessageStatus (this,
  980.                                            cbEntryID,
  981.                                            pEntryID,
  982.                                            ulFlags,
  983.                                            pulMessageStatus);
  984.     return MAPI_E_NO_SUPPORT;
  985. }
  986.  
  987. ///////////////////////////////////////////////////////////////////////////////
  988. //    CMAPIFolder::SetMessageStatus()
  989. //
  990. //    Parameters
  991. //      { Refer to MAPI Documentation on this method }
  992. //
  993. //    Purpose
  994. //
  995. //    Return Value
  996. //      An HRESULT
  997. //
  998. STDMETHODIMP CMAPIFolder::SetMessageStatus (ULONG       cbEntryID,
  999.                                             LPENTRYID   pEntryID,
  1000.                                             ULONG       ulNewStatus,
  1001.                                             ULONG       ulNewStatusMask,
  1002.                                             ULONG *     pulOldStatus)
  1003. {
  1004.     InfoTrace ("CMAPIFolder::SetMessageStatus method called");
  1005.     Validate_IMAPIFolder_SetMessageStatus (this,
  1006.                                            cbEntryID,
  1007.                                            pEntryID,
  1008.                                            ulNewStatus,
  1009.                                            ulNewStatusMask,
  1010.                                            pulOldStatus);
  1011.  
  1012.     ASSERT (TRANSPORT_MESSAGE_EID_SIZE == cbEntryID);
  1013.     SPropValue spvSearchProp;
  1014.     spvSearchProp.ulPropTag     = PR_ENTRYID;
  1015.     spvSearchProp.Value.bin.cb  = cbEntryID;
  1016.     spvSearchProp.Value.bin.lpb = (LPBYTE)pEntryID;
  1017.  
  1018.     LPSRow psrTargetRow;
  1019.     HRESULT hResult = m_pTableData->HrQueryRow (&spvSearchProp, &psrTargetRow, NULL);
  1020.     if (hResult)
  1021.     {
  1022.         TraceResult ("CMAPIFolder::SetMessageStatus: Failed to query row from internal table", hResult);
  1023.         return hResult;
  1024.     }
  1025.  
  1026.     BOOL bFound = FALSE;
  1027.     ULONG ulOldStatus;
  1028.     for (ULONG i=0; i<psrTargetRow->cValues; i++)
  1029.     {
  1030.         if (PR_MSG_STATUS == psrTargetRow->lpProps[i].ulPropTag)
  1031.         {
  1032.             bFound = TRUE;
  1033.             ulOldStatus = psrTargetRow->lpProps[i].Value.l;
  1034.             if (pulOldStatus)
  1035.             {
  1036.                 *pulOldStatus = ulOldStatus;
  1037.             }
  1038.             ulOldStatus &= ulNewStatusMask;
  1039.             ulNewStatus &= ulNewStatusMask;
  1040.             if (ulNewStatus != ulOldStatus)
  1041.             {
  1042.                 psrTargetRow->lpProps[i].Value.l &= ~ulNewStatusMask;
  1043.                 psrTargetRow->lpProps[i].Value.l |= ulNewStatus;
  1044.                 hResult= m_pTableData->HrModifyRow (psrTargetRow);
  1045.                 // If any, trace out the error code.
  1046.                 TraceResult ("CMAPIFolder::SetMessageStatus: Failed to modify row in the internal table", hResult);
  1047.             }
  1048.             break; // Out of the FOR() loop
  1049.         }
  1050.     }
  1051.     if (!hResult && !bFound)
  1052.     {
  1053.         TraceMessage ("CMAPIFolder::SetMessageStatus: Could not find property in table row");
  1054.         hResult = MAPI_E_NOT_FOUND;
  1055.     }
  1056.     gpfnFreeBuffer (psrTargetRow);
  1057.     return hResult;
  1058. }
  1059.  
  1060. ///////////////////////////////////////////////////////////////////////////////
  1061. //    CMAPIFolder::SaveContentsSort()
  1062. //
  1063. //    Parameters
  1064. //      { Refer to MAPI Documentation on this method }
  1065. //
  1066. //    Purpose
  1067. //      Stub method.
  1068. //
  1069. //    Return Value
  1070. //      MAPI_E_NO_SUPPORT always.
  1071. //
  1072. STDMETHODIMP CMAPIFolder::SaveContentsSort (LPSSortOrderSet pSortCriteria,
  1073.                                             ULONG           ulFlags)
  1074. {
  1075.     InfoTrace ("CMAPIFolder::SaveContentsSort method called");
  1076.     Validate_IMAPIFolder_SaveContentsSort (this, pSortCriteria, ulFlags);
  1077.     return MAPI_E_NO_SUPPORT;
  1078. }
  1079.  
  1080. ///////////////////////////////////////////////////////////////////////////////
  1081. //    CMAPIFolder::EmptyFolder()
  1082. //
  1083. //    Parameters
  1084. //      { Refer to MAPI Documentation on this method }
  1085. //
  1086. //    Purpose
  1087. //      Stub method.
  1088. //
  1089. //    Return Value
  1090. //      MAPI_E_NO_SUPPORT always.
  1091. //
  1092. STDMETHODIMP CMAPIFolder::EmptyFolder (ULONG            ulUIParam,
  1093.                                        LPMAPIPROGRESS   pProgress,
  1094.                                        ULONG            ulFlags)
  1095. {
  1096.     InfoTrace ("CMAPIFolder::EmptyFolder method called");
  1097.     Validate_IMAPIFolder_EmptyFolder (this, ulUIParam, pProgress, ulFlags);
  1098.     return MAPI_E_NO_SUPPORT;
  1099. }
  1100.  
  1101. ///////////////////////////////////////////////////////////////////////////////
  1102. // Other member functions specific to this class
  1103. //
  1104.  
  1105. ///////////////////////////////////////////////////////////////////////////////
  1106. //    CMAPIFolder::FillContentsTable()
  1107. //
  1108. //    Parameters
  1109. //      pszHeaderFileName       String with a fully qualified path to the
  1110. //                              headers data file
  1111. //    Purpose
  1112. //      This function reads the file with the headers information to
  1113. ///     populate the table of contents of the remote mail bag folder.
  1114. //      The data is store in a file whose path is given in the
  1115. //      pszHeaderFileName parameter.
  1116. //
  1117. //    Return Value
  1118. //      S_OK  If the function is successful or an hResult with the
  1119. //      error that occurr
  1120. //
  1121. STDMETHODIMP CMAPIFolder::FillContentsTable (LPTSTR pszHeaderFileName)
  1122. {
  1123.     ASSERT(pszHeaderFileName);
  1124.     if (NULL == m_pTableData)
  1125.     {
  1126.         // Nothing to do
  1127.         return S_OK;
  1128.     }
  1129.  
  1130.     HRESULT hResult = m_pTableData->HrDeleteRows (TAD_ALL_ROWS, NULL, NULL);
  1131.     TraceResult ("CMAPIFolder::FillContentsTable: Failed to delete all rows in internal table", hResult);
  1132.  
  1133.     // Check that the file exists. If it doesn't exist, then there is no headers file.
  1134.     HANDLE hFile = CreateFile (pszHeaderFileName,
  1135.                                GENERIC_READ,
  1136.                                0,
  1137.                                NULL,
  1138.                                OPEN_EXISTING,
  1139.                                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  1140.                                NULL);
  1141.     if (INVALID_HANDLE_VALUE == hFile)
  1142.     {
  1143.         // Set the internal flag that the user HAS NOT downloaded headers from the server
  1144.         m_fNoHeadersFile = TRUE;
  1145.         return S_OK;
  1146.     }
  1147.     else
  1148.     {
  1149.         // The time the headers file was last updated, is the last time the file was written to
  1150.         if (GetFileTime (hFile, NULL, NULL, &m_ftLastUpdate))
  1151.         {
  1152.             // Set the internal flag that the user HAS downloaded headers from the server
  1153.             m_fNoHeadersFile = FALSE;
  1154.         }
  1155.         TraceResult ("CMAPIFolder::FillContentsTable: Failed to get info about the headers file", ::GetLastError()); // Call the Win32 API
  1156.     }
  1157.     if (!GetFileSize (hFile, NULL))
  1158.     {
  1159.         CloseHandle(hFile);
  1160.         return S_OK;
  1161.     }
  1162.  
  1163.     SRow srTblRow;
  1164.     // Allocate an array of properties for the colums in the contents
  1165.     // tables of the folder
  1166.     hResult = gpfnAllocateBuffer (NUM_HDR_PROPS*sizeof(SPropValue), (LPVOID *)&(srTblRow.lpProps));
  1167.     if (hResult)
  1168.     {
  1169.         TraceResult ("CMAPIFolder::FillContentsTable: Failed to allocate memory for properties", hResult);
  1170.         CloseHandle (hFile);
  1171.         return hResult;
  1172.     }
  1173.  
  1174.     // Initialize the property tags in the row set
  1175.     srTblRow.cValues = NUM_HDR_PROPS;
  1176.     for (UINT i=0; i<NUM_HDR_PROPS; i++)    
  1177.     {
  1178.         srTblRow.lpProps[i].ulPropTag = sptFldContents.aulPropTag[i];
  1179.     }
  1180.     // The MS Exchange remote viewer wants PR_MESSAGE_DOWNLOAD_TIME in the rows of the contents table.
  1181.     // However in our transport we compute it. This property gets set when we download the message.
  1182.     // This property is listed and shown here for information purposes only.
  1183.     srTblRow.lpProps[HDR_DOWNLOAD_TIME].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(PR_MESSAGE_DOWNLOAD_TIME));
  1184.     srTblRow.lpProps[HDR_DOWNLOAD_TIME].Value.err = S_OK;
  1185.     srTblRow.lpProps[HDR_OBJ_TYPE].Value.l = MAPI_MESSAGE;
  1186.     
  1187.     DWORD dwBytesRead, dwInstanceKey = 1;
  1188.     srTblRow.lpProps[HDR_INST_KEY].Value.bin.cb  = sizeof (DWORD); // This is a fixed size.
  1189.     srTblRow.lpProps[HDR_INST_KEY].Value.bin.lpb = (LPBYTE)&dwInstanceKey;
  1190.     ULONG ulHeaderSize, iNextField;
  1191.     LONG lFieldSize, lValue = 0;
  1192.     LPTSTR pStr, pszMsgClass;
  1193.     TCHAR szDisplayTo[256], szSubject[256], szSender[256];
  1194.     BYTE abBuffer[IO_BUFFERSIZE];
  1195.     __try
  1196.     {
  1197.         do
  1198.         {
  1199.             ZeroMemory (szDisplayTo, 256);
  1200.             ZeroMemory (szSubject, 256);
  1201.             ZeroMemory (szSender, 256);
  1202.             if (ReadFile (hFile, &ulHeaderSize, sizeof(ULONG), &dwBytesRead, NULL))
  1203.             {
  1204.                 if (ReadFile (hFile, abBuffer, ulHeaderSize, &dwBytesRead, NULL))
  1205.                 {
  1206.                     if (dwBytesRead)
  1207.                     {
  1208.                         // Put the data into the property value members
  1209.                         srTblRow.lpProps[HDR_EID].Value.bin.cb  = TRANSPORT_MESSAGE_EID_SIZE; // This is a fixed size.
  1210.                         srTblRow.lpProps[HDR_EID].Value.bin.lpb = abBuffer;                   // It will only read the first 16 bytes
  1211.                         iNextField = TRANSPORT_MESSAGE_EID_SIZE;                              // Skip the entry ID
  1212.  
  1213.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1214.                         lFieldSize = atol (pStr);
  1215.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1216.                         CopyMemory (szSender, &abBuffer[iNextField], lFieldSize);
  1217.                         iNextField += lstrlen (szSender) + 1;   // +1 to skip the comma
  1218.                         srTblRow.lpProps[HDR_SNDR].Value.LPSZ = szSender;
  1219.                         srTblRow.lpProps[HDR_REPR].Value.LPSZ = szSender;
  1220.  
  1221.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1222.                         lFieldSize = atol (pStr);
  1223.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1224.                         CopyMemory (szDisplayTo, &abBuffer[iNextField], lFieldSize);
  1225.                         srTblRow.lpProps[HDR_DISP_TO].Value.LPSZ = szDisplayTo;
  1226.                     
  1227.                         iNextField += lFieldSize + 1;       // +1 to skip the comma
  1228.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1229.                         lFieldSize = atol (pStr);
  1230.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1231.                         CopyMemory (szSubject, &abBuffer[iNextField], lFieldSize);
  1232.                         srTblRow.lpProps[HDR_SUBJ].Value.LPSZ = szSubject;
  1233.                         srTblRow.lpProps[HDR_NORM_SUBJ].Value.LPSZ = szSubject;
  1234.  
  1235.                         iNextField += lFieldSize + 1;       // +1 to skip the comma
  1236.                         pszMsgClass = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1237.                         srTblRow.lpProps[HDR_CLASS].Value.LPSZ = pszMsgClass;
  1238.                     
  1239.                         iNextField += lstrlen (pszMsgClass) + 1;       // +1 to skip the comma
  1240.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1241.                         lValue = atol (pStr);
  1242.                         srTblRow.lpProps[HDR_FLAGS].Value.l = lValue;
  1243.  
  1244.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1245.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1246.                         lValue = atol (pStr);
  1247.                         srTblRow.lpProps[HDR_SIZE].Value.l = lValue;
  1248.  
  1249.                     
  1250.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1251.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1252.                         lValue = atol (pStr);
  1253.                         srTblRow.lpProps[HDR_PRIOR].Value.l = lValue;
  1254.                     
  1255.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1256.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1257.                         lValue = atol (pStr);
  1258.                         srTblRow.lpProps[HDR_IMPORTANCE].Value.l = lValue;
  1259.  
  1260.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1261.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1262.                         lValue = atol (pStr);
  1263.                         srTblRow.lpProps[HDR_SENS].Value.l = lValue;
  1264.  
  1265.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1266.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1267.                         lValue = atol (pStr);
  1268.                         srTblRow.lpProps[HDR_TIME].Value.ft.dwLowDateTime = lValue;
  1269.                     
  1270.                         iNextField += lstrlen (pStr) + 1;   // +1 to skip the comma
  1271.                         pStr = strtok ((LPTSTR)&abBuffer[iNextField], ",");
  1272.                         lValue = atol (pStr);
  1273.                         srTblRow.lpProps[HDR_TIME].Value.ft.dwHighDateTime = lValue;
  1274.  
  1275.                         srTblRow.lpProps[HDR_STAT].Value.l = 0;
  1276.  
  1277.                         srTblRow.lpProps[HDR_HASATTACH].Value.l = (BOOL)!!(srTblRow.lpProps[HDR_FLAGS].Value.l & MSGFLAG_HASATTACH);
  1278.                     
  1279.                         hResult = m_pTableData->HrModifyRow (&srTblRow);
  1280.                         if (hResult)
  1281.                         {
  1282.                             TraceResult ("CMAPIFolder::FillContentsTable: Failed to add row to table data", hResult);
  1283.                         }
  1284.                         dwInstanceKey++;
  1285.                     }
  1286.                 }
  1287.                 else
  1288.                 {
  1289.                     hResult = ::GetLastError(); // Call the Win32 API
  1290.                     TraceResult ("CMAPIFolder::FillContentsTable: Failed to read header data", hResult);
  1291.                     hResult = HRESULT_FROM_WIN32 (hResult);
  1292.                 }
  1293.             }
  1294.             else
  1295.             {
  1296.                 hResult = ::GetLastError(); // Call the Win32 API
  1297.                 TraceResult ("CMAPIFolder::FillContentsTable: Failed to read header size", hResult);
  1298.                 hResult = HRESULT_FROM_WIN32 (hResult);
  1299.             }
  1300.         } while (dwBytesRead && !hResult);
  1301.     }
  1302.     __except (EXCEPTION_EXECUTE_HANDLER)
  1303.     {
  1304.         TraceString1 ("CMAPIFolder::FillContentsTable: An exception occured. Exception code: %d", GetExceptionCode());
  1305.         hResult = MAPI_E_CORRUPT_DATA;
  1306.     }
  1307.  
  1308.     // Free the array and close the file
  1309.     gpfnFreeBuffer (srTblRow.lpProps);
  1310.     CloseHandle (hFile);
  1311.     return hResult;
  1312. }
  1313.  
  1314. ///////////////////////////////////////////////////////////////////////////////
  1315. //    CMAPIFolder::CopyTableToFile()
  1316. //
  1317. //    Parameters
  1318. //      None.
  1319. //
  1320. //    Purpose
  1321. //      This function copies the data from the in-memory contents table into
  1322. //      the headers file. If the user selected any action on the messages in
  1323. //      the contents table, those changes will be reflected in the headers
  1324. //      file and restored the next time the remote viewer is brought up.
  1325. //
  1326. //    Return Value
  1327. //      An HRESULT
  1328. //
  1329. STDMETHODIMP CMAPIFolder::CopyTableToFile()
  1330. {
  1331.     if (!m_pTableData)
  1332.     {
  1333.         return S_OK;
  1334.     }
  1335.     HRESULT hResult;
  1336.     HANDLE hFile = CreateFile (m_pLogon->GetLocalHeadersCache(),
  1337.                                GENERIC_WRITE,
  1338.                                0,
  1339.                                NULL,
  1340.                                CREATE_ALWAYS,
  1341.                                FILE_FLAG_SEQUENTIAL_SCAN,
  1342.                                NULL);
  1343.     if (INVALID_HANDLE_VALUE == hFile)
  1344.     {
  1345.         hResult = ::GetLastError();
  1346.         TraceResult ("CMAPIFolder::CopyTableToFile: Failed to open local headers file", hResult);
  1347.         return HRESULT_FROM_WIN32(hResult);
  1348.     }
  1349.     BOOL fDeleteFile = TRUE;
  1350.     LPMAPITABLE pTable = NULL;
  1351.     hResult = m_pTableData->HrGetView (NULL, NULL, 0, &pTable);
  1352.     if (hResult)
  1353.     {
  1354.         TraceResult ("CMAPIFolder::CopyTableToFile: Failed to get a view of the table data", hResult);
  1355.         goto ErrorExit;
  1356.     }
  1357.     
  1358.     hResult = pTable->SetColumns ((LPSPropTagArray)&sptFldContents, 0);
  1359.     if (hResult)
  1360.     {
  1361.         TraceResult ("CMAPIFolder::CopyTableToFile: Failed to set the columns", hResult);
  1362.         goto ErrorExit;
  1363.     }
  1364.     
  1365.     LPSPropValue pProps;
  1366.     BYTE abBuffer[IO_BUFFERSIZE];
  1367.     LPSRowSet pRows;
  1368.     LPVOID pVoid;
  1369.     DWORD i, cbSize, dwBytesWrittem;
  1370.     BOOL fSuccess;
  1371.     while (TRUE)
  1372.     {
  1373.         #define QUERY_SIZE  10
  1374.         hResult = pTable->QueryRows (QUERY_SIZE, 0, &pRows);
  1375.         if (hResult)
  1376.         {
  1377.             TraceResult ("CMAPIFolder::CopyTableToFile: Failed to query the rows in the table", hResult);
  1378.             goto ErrorExit;
  1379.         }
  1380.         // Did we finish reading all the rows?
  1381.         if (!pRows->cRows)
  1382.         {
  1383.             FreeProws (pRows);
  1384.             break; // Out of the WHILE() loop
  1385.         }
  1386.         for (i=0; i<pRows->cRows; i++)
  1387.         {
  1388.             pProps = pRows->aRow[i].lpProps;
  1389.             if (pProps[HDR_EID].ulPropTag != PR_ENTRYID ||
  1390.                 pProps[HDR_SNDR].ulPropTag != PR_SENDER_NAME ||
  1391.                 pProps[HDR_DISP_TO].ulPropTag != PR_DISPLAY_TO ||
  1392.                 pProps[HDR_SUBJ].ulPropTag != PR_SUBJECT ||
  1393.                 pProps[HDR_CLASS].ulPropTag != PR_MESSAGE_CLASS ||
  1394.                 pProps[HDR_FLAGS].ulPropTag != PR_MESSAGE_FLAGS ||
  1395.                 pProps[HDR_SIZE].ulPropTag != PR_MESSAGE_SIZE ||
  1396.                 pProps[HDR_PRIOR].ulPropTag != PR_PRIORITY ||
  1397.                 pProps[HDR_IMPORTANCE].ulPropTag != PR_IMPORTANCE ||
  1398.                 pProps[HDR_SENS].ulPropTag != PR_SENSITIVITY ||
  1399.                 pProps[HDR_TIME].ulPropTag != PR_MESSAGE_DELIVERY_TIME ||
  1400.                 pProps[HDR_STAT].ulPropTag != PR_MSG_STATUS)
  1401.             {
  1402.                 TraceMessage ("CMAPIFolder::CopyTableToFile: Missing property in a row. Skipping it");
  1403.                 continue; // The FOR() loop
  1404.             }
  1405.             
  1406.             ZeroMemory (abBuffer, IO_BUFFERSIZE);
  1407.         
  1408.             // Put the properties' data into the buffer.
  1409.             pVoid = (LPVOID)abBuffer;
  1410.             CopyMemory (pVoid, pProps[HDR_EID].Value.bin.lpb, TRANSPORT_MESSAGE_EID_SIZE);
  1411.             cbSize = (DWORD)pVoid + TRANSPORT_MESSAGE_EID_SIZE;
  1412.             pVoid = (LPVOID)cbSize;
  1413.  
  1414.             wsprintf ((LPTSTR)pVoid,
  1415.                       TEXT("%d,%s,%d,%s,%d,%s,%s,%d,%d,%d,%d,%d,%d,%d,"),
  1416.                       lstrlen (pProps[HDR_SNDR].Value.LPSZ),
  1417.                       pProps[HDR_SNDR].Value.LPSZ,
  1418.                       lstrlen (pProps[HDR_DISP_TO].Value.LPSZ),
  1419.                       pProps[HDR_DISP_TO].Value.LPSZ,
  1420.                       lstrlen (pProps[HDR_SUBJ].Value.LPSZ),
  1421.                       pProps[HDR_SUBJ].Value.LPSZ,
  1422.                       pProps[HDR_CLASS].Value.LPSZ,
  1423.                       pProps[HDR_FLAGS].Value.l,
  1424.                       pProps[HDR_SIZE].Value.l,
  1425.                       pProps[HDR_PRIOR].Value.l,
  1426.                       pProps[HDR_IMPORTANCE].Value.l,
  1427.                       pProps[HDR_SENS].Value.l,
  1428.                       pProps[HDR_TIME].Value.ft.dwLowDateTime,
  1429.                       pProps[HDR_TIME].Value.ft.dwHighDateTime);
  1430.  
  1431.             cbSize = TRANSPORT_MESSAGE_EID_SIZE + lstrlen ((LPTSTR)pVoid);
  1432.             fSuccess = WriteFile (hFile, &cbSize, sizeof(DWORD), &dwBytesWrittem, NULL);
  1433.             if (fSuccess)
  1434.             {
  1435.                 fSuccess = WriteFile (hFile, abBuffer, cbSize, &dwBytesWrittem, NULL);
  1436.                 if (fSuccess)
  1437.                 {
  1438.                     fDeleteFile = FALSE;
  1439.                 }
  1440.             }
  1441.             if (!fSuccess)
  1442.             {
  1443.                 hResult = ::GetLastError();
  1444.                 TraceResult ("CMAPIFolder::CopyTableToFile: Write header data to file", hResult);
  1445.                 hResult = HRESULT_FROM_WIN32(hResult);
  1446.                 break; // Ouf of the FOR() loop
  1447.             }
  1448.         }
  1449.         FreeProws (pRows);
  1450.         if (hResult)
  1451.         {
  1452.             goto ErrorExit;
  1453.         }
  1454.     }
  1455.  
  1456. ErrorExit:
  1457.     if (pTable)
  1458.     {
  1459.         pTable->Release();
  1460.     }
  1461.     CloseHandle (hFile);
  1462.     if (hResult && fDeleteFile)
  1463.     {
  1464.         DeleteFile (m_pLogon->GetLocalHeadersCache());
  1465.     }
  1466.     m_pTableData->Release();
  1467.     m_pTableData = NULL;
  1468.     return hResult;
  1469. }
  1470.  
  1471. // End of file for XPFOLDER.CPP
  1472.