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.srv / storage.cpp < prev    next >
C/C++ Source or Header  |  1996-04-11  |  86KB  |  2,311 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  File Name 
  4. //      STORAGE.CPP
  5. //
  6. //  Description
  7. //
  8. //  Author
  9. //      Irving De la Cruz
  10. //
  11. //  Revision: 1.7
  12. //
  13. // Written for Microsoft Windows Developer Support
  14. // Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
  15. //
  16. #include "_WINDS.H"
  17. #include "WDSADM.H"    // Header file generated by the MIDL compiler
  18. #include "COMMON.H"
  19. #include "STDIO.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. #define InfoTraceRaw(a)     TraceRaw(a)
  26. #define InfoTraceProp(a)    TraceProp(a)
  27. #else
  28. #define InfoTrace(a)        0
  29. #define InfoTraceRaw(a)     0
  30. #define InfoTraceProp(a)    0
  31. #endif // DO_INFO_TRACES
  32.  
  33. extern "C"
  34. {
  35.     HRESULT WINAPI LoadObjectProperties
  36.                         (LPSTORAGE                  pStorage,
  37.                          WINDS_AB_OBJTYPE           Type,
  38.                          LPTSTR                     pszObjectType,
  39.                          LPMALLOC                   pMalloc);
  40.     HRESULT WINAPI GetDLProperties
  41.                         (LPSTORAGE                  pStorage,
  42.                          LPOLESTR                   pwcsDLName,
  43.                          PDIST_LIST_INFO            pDLInfo,
  44.                          BOOL                       fGetMembers = FALSE);
  45.     HRESULT WINAPI SetDLProperties
  46.                         (LPSTORAGE                  pStorage,
  47.                          LPOLESTR                   pwcsDLName,
  48.                          PDIST_LIST_INFO            pDLInfo);
  49.     HRESULT WINAPI DLPropsAndMembers
  50.                         (LPSTORAGE                  pStorage,
  51.                          PDIST_LIST_INFO            pDLInfo,
  52.                          BOOL                       fGetProps);
  53.     HRESULT WINAPI CreateDistributionList
  54.                         (LPSTORAGE                  pStorage,
  55.                          PDIST_LIST_INFO            pDLInfo);
  56.     HRESULT WINAPI DeleteDistributionList
  57.                         (LPSTORAGE                  pStorage,
  58.                          PDIST_LIST_INFO            pDLInfo);
  59.     HRESULT WINAPI GetNextObjID
  60.                         (LPSTORAGE                  pStorage,
  61.                          DWORD &                    dwNextID);
  62.     HRESULT WINAPI ReadABContainerInfo
  63.                         (LPSTORAGE                  pStorage,
  64.                          LPMALLOC                   pMalloc,
  65.                          DWORD                      dwContainerID,
  66.                          HANDLE                     hPipe);
  67.     HRESULT WINAPI EnumContainerObjs
  68.                         (LPSTORAGE                  pDirectoryStg,
  69.                          HANDLE                     hPipe,
  70.                          WINDS_AB_OBJTYPE           Type,
  71.                          LPMALLOC                   pMalloc);
  72.     HRESULT WINAPI GetDLRecipientsInfo
  73.                         (LPSTORAGE                  pMBDirectory,
  74.                          LPSTORAGE                  pDLDirectory,
  75.                          HANDLE                     hPipe,
  76.                          LPOLESTR                   pwcsDLName);
  77.     HRESULT WINAPI CreateMailbox
  78.                         (LPSTORAGE                  pMBDirectory,
  79.                          PMAILBOX_INFO              pMBInfo);
  80.     HRESULT WINAPI MailboxProps
  81.                         (LPSTORAGE                  pMBDirectory,
  82.                          PMAILBOX_INFO              pMBInfo,
  83.                          BOOL                       fRetrieve);
  84.     HRESULT WINAPI GetGWContainerCount
  85.                         (LPSTORAGE                  pStorage,
  86.                          LPMALLOC                   pMalloc,
  87.                          DWORD                      dwContainerID,
  88.                          DWORD *                    pdwContainerCount);
  89.     HRESULT WINAPI CopyMsgFromFile
  90.                         (LPSTORAGE                  pStorage,
  91.                          HANDLE                     hFile,
  92.                          LPTSTR                     pszMailbox,
  93.                          LPTSTR                     pszHeader);
  94.     HRESULT WINAPI RemoveMessageFromMailbox
  95.                         (LPSTORAGE                  pStorage,
  96.                          LPTSTR                     pszMailbox,
  97.                          DWORD                      dwStreamID);
  98.     HRESULT WINAPI UpdateMailboxHeaders
  99.                         (LPSTORAGE                  pStorage,
  100.                          LPSTORAGE                  pMBStg,
  101.                          LPTSTR                     pszMailbox,
  102.                          DWORD                      dwStreamID,
  103.                          LPTSTR                     pszHeader,
  104.                          BOOL                       fAddMsgToHeadersList);
  105.     HRESULT WINAPI LoadServerObjects
  106.                         (LPSTORAGE                  pStorage,
  107.                          LPMALLOC                   pMalloc);
  108.     HRESULT WINAPI OpenMsgsDataFile
  109.                         (LPSTORAGE *                ppStorage);
  110.     HRESULT WINAPI GetMailBoxInfo
  111.                         (LPSTORAGE                  pStorage,
  112.                          LPOLESTR                   pwcsName,
  113.                          PMAILBOX_INFO              pInfo);
  114.     HRESULT WINAPI SetMailBoxInfo
  115.                         (LPSTORAGE                  pStorage,
  116.                          LPOLESTR                   pwcsName,
  117.                          PMAILBOX_INFO              pInfo);
  118.     HRESULT WINAPI DeleteMailbox
  119.                         (LPSTORAGE                  pStorage,
  120.                          PMAILBOX_INFO              pInfo);
  121.     HRESULT WINAPI EmptyMailBoxMsgs
  122.                         (LPSTORAGE                  pStorage,
  123.                          LPTSTR                     pszMailbox);
  124.     HRESULT WINAPI CopyHeadersToFile
  125.                         (LPSTORAGE                  pStorage,
  126.                          LPMALLOC                   pMalloc,
  127.                          HANDLE                     hFile,
  128.                          LPTSTR                     pszMailbox);
  129.     HRESULT WINAPI CopyMsgToFile
  130.                         (LPSTORAGE                  pStorage,
  131.                          LPTSTR                     pszMailbox,
  132.                          HANDLE                     hFile,
  133.                          ULONG *                    pulMsgLen,
  134.                          DWORD                      dwStreamID,
  135.                          BOOL                       fDeleteAfterCopy);
  136.     HRESULT WINAPI CopyStreamToFile
  137.                         (LPSTREAM                   pStream,
  138.                          HANDLE                     hFile,
  139.                          ULONG *                    pulWritten);
  140.     HRESULT WINAPI CheckForPendingMailboxMsgs
  141.                         (LPSTORAGE                  pStorage,
  142.                          LPMALLOC                   pMalloc,
  143.                          LPTSTR                     szMailbox,
  144.                          DWORD *                    pdwMsgCount);
  145.     HRESULT WINAPI GetNextMailboxMsg
  146.                         (LPSTORAGE                  pStorage,
  147.                          LPMALLOC                   pMalloc,
  148.                          LPTSTR                     szMailbox,
  149.                          DWORD *                    pdwMsgID,
  150.                          HANDLE                     hFile);
  151. };
  152.  
  153. ///////////////////////////////////////////////////////////////////////////////
  154. //    WorkingIOProc()
  155. //
  156. //    Parameters
  157. //
  158. //    Purpose
  159. //
  160. //    Return Value
  161. //
  162. DWORD WINAPI WorkingIOProc()
  163. {
  164.     //InfoTrace ("WorkingIOProc: Just starting up");
  165.     // Standard COM initialization so that we may use IStorage and IStream
  166.     LPMALLOC pMalloc;
  167.     HRESULT hResult = CoInitialize (NULL);
  168.     TraceResult ("WorkingIOProc: Failed to initialize the COM libraries", hResult);
  169.     if (!hResult)
  170.     {
  171.         hResult = CoGetMalloc (MEMCTX_TASK, &pMalloc);
  172.         TraceResult ("WorkingIOProc: Failed to get an IMalloc interface", hResult);
  173.     }
  174.     if (FAILED(hResult))
  175.     {
  176.         InfoTrace ("WorkingIOProc: Just bailing out now");
  177.         CoUninitialize();
  178.         g_hServerState = CO_E_NOTINITIALIZED;
  179.         return g_hServerState;
  180.     }
  181.     LPSTORAGE pStorage = NULL;
  182.     
  183.     DWORD dwException = 0;
  184.  
  185.     while (TRUE)
  186.     {
  187.         WaitForSingleObject (g_IOInfo.hResumeEvent, INFINITE);
  188.         //InfoTrace ("WorkingIOProc: Resumed. About to request the critical section...");
  189.         EnterCriticalSection (&g_csIOInfo);
  190.         //InfoTrace ("WorkingIOProc: ...Executing in critical section");
  191.         if (g_IOInfo.fAppIsTerminating)
  192.         {
  193.             InfoTrace ("WorkingIOProc: We are going down");
  194.             if (pStorage)
  195.             {
  196.                 pStorage->Release();
  197.                 pStorage = NULL;
  198.             }
  199.             break; // out of the WHILE() loop
  200.         }
  201. ProcessNextAction:
  202.         switch (g_IOInfo.Action)
  203.         {
  204.             case IO_OPEN_STORAGE_FILE :
  205.                 InfoTrace ("WorkingIOProc: Servicing IO_OPEN_STORAGE_FILE");
  206.                 __try
  207.                 {
  208.                     hResult = OpenMsgsDataFile (&pStorage);
  209.                     if (hResult)
  210.                     {
  211.                         g_hServerState = HRESULT_FROM_WIN32(ERROR_STATIC_INIT);
  212.                     }
  213.                     else
  214.                     {
  215.                         g_hServerState = S_OK; // Server is ready to accept requests
  216.                     }
  217.                 }
  218.                 __except (EXCEPTION_EXECUTE_HANDLER)
  219.                 {
  220.                     dwException = GetExceptionCode();
  221.                 }
  222.                 break;
  223.  
  224.             case IO_LOAD_MAILBOX_NAMES :
  225.                 InfoTrace ("WorkingIOProc: Servicing IO_LOAD_MAILBOX_NAMES");
  226.                 __try
  227.                 {
  228.                     hResult = LoadServerObjects (pStorage, pMalloc);
  229.                 }
  230.                 __except (EXCEPTION_EXECUTE_HANDLER)
  231.                 {
  232.                     dwException = GetExceptionCode();
  233.                 }
  234.                 // Restore notification links with the clients from a previous session
  235.                 g_IOInfo.Action = IO_RESTORE_CLIENT_NOTIFICATIONS;
  236.                 goto ProcessNextAction;
  237.                 break;
  238.  
  239.             case IO_GET_CONTAINER_RECIPIENTS :
  240.                 InfoTrace ("WorkingIOProc: Servicing IO_GET_CONTAINER_RECIPIENTS");
  241.                 __try
  242.                 {
  243.                     hResult = ReadABContainerInfo (pStorage,
  244.                                                    pMalloc,
  245.                                                    g_IOInfo.dwObjID,
  246.                                                    g_IOInfo.hTmpFile);
  247.                 }
  248.                 __except (EXCEPTION_EXECUTE_HANDLER)
  249.                 {
  250.                     dwException = GetExceptionCode();
  251.                 }
  252.                 break;
  253.  
  254.             case IO_CREATE_NEW_MAILBOX :
  255.                 InfoTrace ("WorkingIOProc: Servicing IO_CREATE_NEW_MAILBOX");
  256.                 __try
  257.                 {
  258.                     hResult = CreateMailbox (pStorage, g_IOInfo.pMBInfo);
  259.                 }
  260.                 __except (EXCEPTION_EXECUTE_HANDLER)
  261.                 {
  262.                     dwException = GetExceptionCode();
  263.                 }
  264.                 break;
  265.  
  266.             case IO_EMPTY_MAILBOX :
  267.                 InfoTrace ("WorkingIOProc: Servicing IO_EMPTY_MAILBOX");
  268.                 __try
  269.                 {
  270.                     hResult = EmptyMailBoxMsgs (pStorage, g_IOInfo.szObject);
  271.                 }
  272.                 __except (EXCEPTION_EXECUTE_HANDLER)
  273.                 {
  274.                     dwException = GetExceptionCode();
  275.                 }
  276.                 break;
  277.  
  278.             case IO_REMOVE_MAILBOX :
  279.                 InfoTrace ("WorkingIOProc: Servicing IO_REMOVE_MAILBOX");
  280.                 __try
  281.                 {
  282.                     hResult = DeleteMailbox (pStorage, g_IOInfo.pMBInfo);
  283.                 }
  284.                 __except (EXCEPTION_EXECUTE_HANDLER)
  285.                 {
  286.                     dwException = GetExceptionCode();
  287.                 }
  288.                 break;
  289.  
  290.             case IO_GET_MAILBOX_PROPERTIES :
  291.                 InfoTrace ("WorkingIOProc: Servicing IO_GET_MAILBOX_PROPERTIES");
  292.                 __try
  293.                 {
  294.                     hResult = MailboxProps (pStorage, g_IOInfo.pMBInfo, TRUE);
  295.                 }
  296.                 __except (EXCEPTION_EXECUTE_HANDLER)
  297.                 {
  298.                     dwException = GetExceptionCode();
  299.                 }
  300.                 break;
  301.  
  302.             case IO_SET_MAILBOX_PROPERTIES :
  303.                 InfoTrace ("WorkingIOProc: Servicing IO_SET_MAILBOX_PROPERTIES");
  304.                 __try
  305.                 {
  306.                     hResult = MailboxProps (pStorage, g_IOInfo.pMBInfo, FALSE);
  307.                 }
  308.                 __except (EXCEPTION_EXECUTE_HANDLER)
  309.                 {
  310.                     dwException = GetExceptionCode();
  311.                 }
  312.                 break;
  313.  
  314.             case IO_COPY_MSG_FROM_FILE :
  315.                 InfoTrace ("WorkingIOProc: Servicing IO_COPY_MSG_FROM_FILE");
  316.                 __try
  317.                 {
  318.                     hResult = CopyMsgFromFile (pStorage,
  319.                                                g_IOInfo.hTmpFile,
  320.                                                g_IOInfo.szObject,
  321.                                                g_IOInfo.szHeader);
  322.                     if (g_IOInfo.fCloseHandle)
  323.                     {
  324.                         CloseHandle (g_IOInfo.hTmpFile);
  325.                     }
  326.                 }
  327.                 __except (EXCEPTION_EXECUTE_HANDLER)
  328.                 {
  329.                     dwException = GetExceptionCode();
  330.                 }
  331.                 break;
  332.  
  333.             case IO_COPY_HEADERS_TO_FILE :
  334.                 InfoTrace ("WorkingIOProc: Servicing IO_COPY_HEADERS_TO_FILE");
  335.                 __try
  336.                 {
  337.                     hResult = CopyHeadersToFile (pStorage,  
  338.                                                  pMalloc,
  339.                                                  g_IOInfo.hTmpFile,
  340.                                                  g_IOInfo.szObject);
  341.                 }
  342.                 __except (EXCEPTION_EXECUTE_HANDLER)
  343.                 {
  344.                     dwException = GetExceptionCode();
  345.                 }
  346.                 break;
  347.  
  348.             case IO_CHECK_PENDING_MESSAGES :
  349.                 InfoTrace ("WorkingIOProc: Servicing IO_CHECK_PENDING_MESSAGES");
  350.                 __try
  351.                 {
  352.                     hResult = CheckForPendingMailboxMsgs (pStorage, 
  353.                                                           pMalloc,
  354.                                                           g_IOInfo.szObject,
  355.                                                           g_IOInfo.pdwData);
  356.                 }
  357.                 __except (EXCEPTION_EXECUTE_HANDLER)
  358.                 {
  359.                     dwException = GetExceptionCode();
  360.                 }
  361.                 break;
  362.  
  363.             case IO_COPY_MSG_TO_FILE :
  364.                 InfoTrace ("WorkingIOProc: Servicing IO_COPY_MSG_TO_FILE");
  365.                 __try
  366.                 {
  367.                     hResult = CopyMsgToFile (pStorage,
  368.                                              g_IOInfo.szObject,
  369.                                              g_IOInfo.hTmpFile,
  370.                                              g_IOInfo.pdwData,
  371.                                              g_IOInfo.dwObjID,
  372.                                              FALSE);
  373.                 }
  374.                 __except (EXCEPTION_EXECUTE_HANDLER)
  375.                 {
  376.                     dwException = GetExceptionCode();
  377.                 }
  378.                 break;
  379.  
  380.             case IO_MOVE_MSG_TO_FILE :
  381.                 InfoTrace ("WorkingIOProc: Servicing IO_MOVE_MSG_TO_FILE");
  382.                 __try
  383.                 {
  384.                     hResult = CopyMsgToFile (pStorage,
  385.                                              g_IOInfo.szObject,
  386.                                              g_IOInfo.hTmpFile,
  387.                                              g_IOInfo.pdwData,
  388.                                              g_IOInfo.dwObjID,
  389.                                              TRUE);
  390.                 }
  391.                 __except (EXCEPTION_EXECUTE_HANDLER)
  392.                 {
  393.                     dwException = GetExceptionCode();
  394.                 }
  395.                 break;
  396.  
  397.             case IO_MOVE_NEXT_MSG_TO_FILE :
  398.                 InfoTrace ("WorkingIOProc: Servicing IO_MOVE_NEXT_MSG_TO_FILE");
  399.                 __try
  400.                 {
  401.                     hResult = GetNextMailboxMsg (pStorage,
  402.                                                  pMalloc,
  403.                                                  g_IOInfo.szObject,
  404.                                                  g_IOInfo.pdwData,
  405.                                                  g_IOInfo.hTmpFile);
  406.                 }
  407.                 __except (EXCEPTION_EXECUTE_HANDLER)
  408.                 {
  409.                     dwException = GetExceptionCode();
  410.                 }
  411.                 break;
  412.             
  413.             case IO_DELETE_MSG_IN_MAILBOX :
  414.                 InfoTrace ("WorkingIOProc: Servicing IO_DELETE_MSG_IN_MAILBOX");
  415.                 __try
  416.                 {
  417.                     hResult = RemoveMessageFromMailbox (pStorage,
  418.                                                         g_IOInfo.szObject,
  419.                                                         g_IOInfo.dwObjID);
  420.                 }
  421.                 __except (EXCEPTION_EXECUTE_HANDLER)
  422.                 {
  423.                     dwException = GetExceptionCode();
  424.                 }
  425.                 break;
  426.  
  427.             case IO_CREATE_DISTRIBUTION_LIST :
  428.                 InfoTrace ("WorkingIOProc: Servicing IO_CREATE_DISTRIBUTION_LIST");
  429.                 __try
  430.                 {
  431.                     hResult = CreateDistributionList (pStorage, g_IOInfo.pDLInfo);
  432.                 }
  433.                 __except (EXCEPTION_EXECUTE_HANDLER)
  434.                 {
  435.                     dwException = GetExceptionCode();
  436.                 }
  437.                 break;
  438.  
  439.             case IO_DELETE_DISTRIBUTION_LIST :
  440.                 InfoTrace ("WorkingIOProc: Servicing IO_DELETE_DISTRIBUTION_LIST");
  441.                 __try
  442.                 {
  443.                     hResult = DeleteDistributionList (pStorage, g_IOInfo.pDLInfo);
  444.                 }
  445.                 __except (EXCEPTION_EXECUTE_HANDLER)
  446.                 {
  447.                     dwException = GetExceptionCode();
  448.                 }
  449.                 break;
  450.  
  451.             case IO_GET_DL_PROPERTIES :
  452.                 InfoTrace ("WorkingIOProc: Servicing IO_GET_DL_PROPERTIES");
  453.                 __try
  454.                 {
  455.                     hResult = DLPropsAndMembers (pStorage, g_IOInfo.pDLInfo, TRUE);
  456.                 }
  457.                 __except (EXCEPTION_EXECUTE_HANDLER)
  458.                 {
  459.                     dwException = GetExceptionCode();
  460.                 }
  461.                 break;
  462.  
  463.             case IO_SET_DL_PROPERTIES :
  464.                 InfoTrace ("WorkingIOProc: Servicing IO_SET_DL_PROPERTIES");
  465.                 __try
  466.                 {
  467.                     hResult = DLPropsAndMembers (pStorage, g_IOInfo.pDLInfo, FALSE);
  468.                 }
  469.                 __except (EXCEPTION_EXECUTE_HANDLER)
  470.                 {
  471.                     dwException = GetExceptionCode();
  472.                 }
  473.                 break;
  474.  
  475.             case IO_GET_GW_CONTAINER_COUNT :
  476.                 InfoTrace ("WorkingIOProc: Servicing IO_GET_GW_CONTAINER_COUNT");
  477.                 __try
  478.                 {
  479.                     hResult = GetGWContainerCount (pStorage,
  480.                                                    pMalloc,
  481.                                                    g_IOInfo.dwObjID,
  482.                                                    g_IOInfo.pdwData);
  483.                 }
  484.                 __except (EXCEPTION_EXECUTE_HANDLER)
  485.                 {
  486.                     dwException = GetExceptionCode();
  487.                 }
  488.                 break;
  489.  
  490.             case IO_SENT_SHUTDOWN_NOTIFICATION :
  491.                 InfoTrace ("WorkingIOProc: Servicing IO_SENT_SHUTDOWN_NOTIFICATION");
  492.                 __try
  493.                 {
  494.                     ClientNotifThreadProc (g_IOInfo.pNotif);
  495.                 }
  496.                 __except (EXCEPTION_EXECUTE_HANDLER)
  497.                 {
  498.                     dwException = GetExceptionCode();
  499.                 }
  500.                 break;
  501.  
  502.             case IO_RESTORE_CLIENT_NOTIFICATIONS :
  503.                 InfoTrace ("WorkingIOProc: Servicing IO_RESTORE_CLIENT_NOTIFICATIONS");
  504.                 __try
  505.                 {
  506.                     PWINDS_NOTIFICATION pNotif = (PWINDS_NOTIFICATION)HeapAlloc (ghHeap,
  507.                                                                                  HEAP_ZERO_MEMORY,
  508.                                                                                  sizeof(WINDS_NOTIFICATION));
  509.                     if (NULL == pNotif)
  510.                     {
  511.                         TraceMessage ("WorkingIOProc: Failed to allocate notification structure");
  512.                     }
  513.                     else
  514.                     {
  515.                         pNotif->Event = SERVER_HAS_RESTARTED;
  516.                         ClientNotifThreadProc (pNotif);
  517.                     }
  518.                 }
  519.                 __except (EXCEPTION_EXECUTE_HANDLER)
  520.                 {
  521.                     dwException = GetExceptionCode();
  522.                 }
  523.                 break;
  524.  
  525.             case IO_ADMIN_GET_SERVER_MAILBOXES :
  526.                 InfoTrace ("WorkingIOProc: Servicing IO_ADMIN_GET_SERVER_MAILBOXES");
  527.                 __try
  528.                 {
  529.                     hResult = WaitForClientConnection (g_IOInfo.hTmpFile, 15);
  530.                     if (S_OK == hResult)
  531.                     {
  532.                         hResult = EnumContainerObjs (pStorage, g_IOInfo.hTmpFile, SERVER_USER_MAILBOX, pMalloc);
  533.                     }
  534.                     CloseHandle (g_IOInfo.hTmpFile);
  535.                 }
  536.                 __except (EXCEPTION_EXECUTE_HANDLER)
  537.                 {
  538.                     dwException = GetExceptionCode();
  539.                 }
  540.                 break;
  541.             case IO_ADMIN_GET_SERVER_DISTLISTS :
  542.                 InfoTrace ("WorkingIOProc: Servicing IO_ADMIN_GET_SERVER_DISTLISTS");
  543.                 __try
  544.                 {
  545.                     LPSTORAGE pDirectoryStg;
  546.                     hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS,
  547.                                                      NULL,
  548.                                                      OPEN_FLAGS,
  549.                                                      NULL,
  550.                                                      0,
  551.                                                      &pDirectoryStg);
  552.                     if (S_OK == hResult)
  553.                     {
  554.                         hResult = WaitForClientConnection (g_IOInfo.hTmpFile, 15);
  555.                         if (S_OK == hResult)
  556.                         {
  557.                             hResult = EnumContainerObjs (pDirectoryStg,
  558.                                                          g_IOInfo.hTmpFile,
  559.                                                          SERVER_DISTRIBUTION_LIST,
  560.                                                          pMalloc);
  561.                         }
  562.                         CloseHandle (g_IOInfo.hTmpFile);
  563.                         pDirectoryStg->Release();
  564.                     }
  565.                 }
  566.                 __except (EXCEPTION_EXECUTE_HANDLER)
  567.                 {
  568.                     dwException = GetExceptionCode();
  569.                 }
  570.                 break;
  571.  
  572.             default :
  573.                 TraceString1 ("WorkingIOProc: Unknown action requested: %d", g_IOInfo.Action);
  574.                 hResult = (DWORD)HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
  575.                 break;
  576.         }
  577.         if (dwException)
  578.         {
  579.             TraceString2 ("WorkingIOProc: Exception %d occured processing action id %d", dwException, g_IOInfo.Action);
  580.             dwException = 0;
  581.             hResult = (DWORD)HRESULT_FROM_WIN32(ERROR_EXCEPTION_IN_SERVICE);
  582.         }
  583.  
  584.         __try
  585.         {
  586.             if (g_IOInfo.phLastError)
  587.             {
  588.                 *g_IOInfo.phLastError = hResult;
  589.             }
  590.         }
  591.         __except (EXCEPTION_EXECUTE_HANDLER)
  592.         {
  593.             dwException = GetExceptionCode();
  594.             TraceString2 ("WorkingIOProc: Exception %d occured setting return error code for action id %d", dwException, g_IOInfo.Action);
  595.             dwException = 0;
  596.         }
  597.  
  598.         if (g_IOInfo.hActionCompleted)
  599.         {
  600.             SetEvent (g_IOInfo.hActionCompleted);
  601.         }
  602.         g_IOInfo.Action = IO_IDLE;
  603.         g_IOInfo.phLastError = NULL;
  604.         g_IOInfo.hActionCompleted = NULL;
  605.         g_IOInfo.pdwData = NULL;
  606.  
  607.         //InfoTrace ("WorkingIOProc: About to leave critical section...");
  608.         LeaveCriticalSection (&g_csIOInfo);
  609.         //InfoTrace ("WorkingIOProc: ...Left critical section");
  610.     }
  611.     pMalloc->Release();
  612.  
  613.     CoUninitialize();
  614.  
  615.     //InfoTrace ("WorkingIOProc: Just closing down");
  616.     if (g_IOInfo.hActionCompleted)
  617.     {
  618.         SetEvent (g_IOInfo.hActionCompleted);
  619.     }
  620.     //InfoTrace ("WorkingIOProc: About to leave critical section...");
  621.     LeaveCriticalSection (&g_csIOInfo);
  622.     //InfoTrace ("WorkingIOProc: ...Left critical section");
  623.     return 0;
  624. }
  625.  
  626. ///////////////////////////////////////////////////////////////////////////////
  627. //    OpenMsgsDataFile()
  628. //
  629. //    Parameters
  630. //
  631. //    Purpose
  632. //
  633. //    Return Value
  634. //
  635. HRESULT WINAPI OpenMsgsDataFile (LPSTORAGE * ppStorage)
  636. {
  637.     DBINFO_DATA dbInfo = { 0 };
  638.     LPSTREAM pStream;
  639.     HRESULT hResult = S_OK;
  640.  
  641. #ifdef UNICODE
  642.     LPWSTR szFileName = g_szDataFile;
  643. #else
  644.     WCHAR wcsFileName[MAX_PATH];
  645.     LPWSTR szFileName = wcsFileName;
  646.     hResult = AnsiToUnicode (g_szDataFile, wcsFileName, MAX_PATH);
  647.     if (hResult)
  648.     {
  649.         TraceResult ("OpenMsgDataFile: Failed to convert file name to UNICODE", hResult);
  650.         return hResult;
  651.     }
  652. #endif // UNICODE
  653.     
  654.     hResult = StgIsStorageFile (szFileName);
  655.     if (S_OK != hResult)
  656.     {
  657.         if (S_FALSE == hResult)
  658.         {
  659.             hResult = S_OK;
  660.             goto CreateFileNow;
  661.         }
  662.         else
  663.         {
  664.             if (STG_E_FILENOTFOUND != hResult)
  665.             {
  666.                 // else, if any other error occurred
  667.                 TraceResult ("OpenMsgsDataFile: StgIsStorageFile failed", hResult);
  668.                 return hResult;
  669.             }
  670.             else
  671.             {
  672.                 goto CreateFileNow;
  673.             }
  674.         }
  675.     }
  676.  
  677.     hResult = StgOpenStorage (szFileName, NULL, OPEN_FLAGS, NULL, 0, ppStorage);
  678.     if (!hResult)
  679.     {
  680.         hResult = (*ppStorage)->OpenStream (DBINFO_STREAM, NULL, OPEN_FLAGS, 0, &pStream);
  681.         if (hResult)
  682.         {
  683.             TraceResult ("OpenMsgsDataFile: Failed to open DBINFO stream", hResult);
  684.             if (STG_E_FILENOTFOUND == hResult)
  685.             {
  686.                 hResult = STG_E_FILENOTFOUND;
  687.             }
  688.         }
  689.         else
  690.         {
  691.             hResult = pStream->Read (&dbInfo, sizeof(DBINFO_DATA), NULL);
  692.             TraceResult ("OpenMsgsDataFile: Failed to read from the DBINFO stream", hResult);
  693.             if (!hResult)
  694.             {
  695.                 // If the database version does not match, we will delete
  696.                 // it and create a new one.
  697.                 if (WINDS_DATABASE_VERSION != dbInfo.dwVersion)
  698.                 {
  699.                     hResult = STG_E_FILENOTFOUND;
  700.                 }
  701.             }
  702.             pStream->Release();
  703.         }
  704.         if (hResult)
  705.         {
  706.             (*ppStorage)->Release();
  707.             *ppStorage = NULL;
  708.         }
  709.     }
  710.     if (STG_E_FILENOTFOUND == hResult)
  711.     {
  712. CreateFileNow:
  713.         DeleteFile (g_szDataFile);
  714.         hResult = StgCreateDocfile (szFileName, CREATE_FLAGS, 0, ppStorage);
  715.         TraceResult ("OpenMsgsDataFile: failed to open or create storage object", hResult);
  716.         if (!hResult)
  717.         {
  718.             hResult = (*ppStorage)->CreateStream (DBINFO_STREAM, CREATE_FLAGS, 0, 0, &pStream);
  719.             TraceResult ("OpenMsgsDataFile: Failed to create DBINFO stream", hResult);
  720.             if (!hResult)
  721.             {
  722.                 dbInfo.dwVersion = WINDS_DATABASE_VERSION;
  723.                 hResult = pStream->Write (&dbInfo, sizeof(DBINFO_DATA), NULL);
  724.                 TraceResult ("OpenMsgsDataFile: Failed to write to the DBINFO stream", hResult);
  725.                 pStream->Release();
  726.                 if (!hResult)
  727.                 {
  728.                     hResult = (*ppStorage)->CreateStream (OBJ_ID_POOL_STREAM, CREATE_FLAGS, 0, 0, &pStream);
  729.                     TraceResult ("OpenMsgsDataFile: Failed to create Object ID Pool stream", hResult);
  730.                     if (!hResult)
  731.                     {
  732.                         DWORD dwZero = 0;
  733.                         hResult = pStream->Write (&dwZero, sizeof(DWORD), NULL);
  734.                         pStream->Release();
  735.                     }
  736.                 }
  737.             }
  738.         }
  739.         if (!hResult)
  740.         {
  741.             CreateDLsDirectory (*ppStorage);
  742.             CreateGatewayDirectories (*ppStorage);
  743.             CreatePublicFoldersDirectory (*ppStorage);
  744.         }
  745.         if (hResult)
  746.         {
  747.             DeleteFile (g_szDataFile);
  748.         }
  749.     }
  750.     TraceResult ("OpenMsgsDataFile", hResult);
  751.     return hResult;
  752. }
  753.  
  754. ///////////////////////////////////////////////////////////////////////////////
  755. //    ReadABContainerInfo()
  756. //
  757. //    Parameters
  758. //
  759. //    Purpose
  760. //
  761. //    Return Value
  762. //
  763. HRESULT WINAPI ReadABContainerInfo (LPSTORAGE pStorage,
  764.                                     LPMALLOC  pMalloc,
  765.                                     DWORD     dwContainerID,
  766.                                     HANDLE    hPipe)
  767. {
  768.     BOOL fGalContainer = FALSE;
  769.     DWORD dwLastContainerDone = 0;
  770.     LPSTORAGE pDirectoryStg;
  771.     HRESULT hResult = WaitForClientConnection (hPipe, 15); // 15 second timeout
  772.     if (hResult)
  773.     {
  774.         goto ErrorExit;
  775.     }
  776. DoNextContainer:
  777.     switch (dwContainerID)
  778.     {
  779.         case GAL_CONTAINER_ID :
  780.             fGalContainer = TRUE;
  781.             EnumContainerObjs (pStorage, hPipe, SERVER_USER_MAILBOX, pMalloc);
  782.             if (S_OK == pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg))
  783.             {
  784.                 EnumContainerObjs (pDirectoryStg, hPipe, SERVER_DISTRIBUTION_LIST, pMalloc);
  785.                 pDirectoryStg->Release();
  786.             }
  787.             dwLastContainerDone = GAL_CONTAINER_ID;
  788.             break;
  789.         case EXCHANGE_CONTAINER_ID :
  790.         case SMTP_CONTAINER_ID :
  791.         case FAX_CONTAINER_ID :
  792.             break;
  793.         default :
  794.             {
  795.                 TCHAR szDLAlias[MAX_ALIAS_SIZE+1] = { 0 };
  796.                 WINDS_AB_OBJTYPE Type = UNDEFINED_OBJECT_TYPE;
  797.                 WCHAR wcsDLalias[64] = { 0 };
  798.                 if (S_OK == GlobalObjectMap.FindObjFromID (dwContainerID, szDLAlias, &Type) &&
  799.                     SERVER_DISTRIBUTION_LIST == Type)
  800.                 {
  801.                     AnsiToUnicode (szDLAlias, wcsDLalias, 64);
  802.                     hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg);
  803.                     if (!hResult)
  804.                     {
  805.                         hResult = GetDLRecipientsInfo (pStorage, pDirectoryStg, hPipe, wcsDLalias);
  806.                         pDirectoryStg->Release();
  807.                     }
  808.                     TraceResult ("ReadABContainerInfo: Getting DL recipients", hResult);
  809.                     hResult = S_OK;                        
  810.                 }
  811.                 else
  812.                 {
  813.                     hResult = HRESULT_FROM_WIN32(ERROR_NO_SUCH_GROUP);
  814.                     TraceResult ("ReadABContainerInfo: Invalid container ID passed in", hResult);
  815.                 }
  816.             }
  817.             break;
  818.     }
  819.     if (fGalContainer)
  820.     {
  821.         dwContainerID++;
  822.         if (dwContainerID <= FAX_CONTAINER_ID)
  823.         {
  824.             goto DoNextContainer;
  825.         }
  826.     }
  827. ErrorExit:
  828.     TraceResult ("ReadABContainerInfo", hResult);
  829.     CloseHandle (hPipe);
  830.     return hResult;
  831. }
  832.  
  833. ///////////////////////////////////////////////////////////////////////////////
  834. //    EnumContainerObjs()
  835. //
  836. //    Parameters
  837. //
  838. //    Purpose
  839. //
  840. //    Return Value
  841. //
  842. HRESULT WINAPI EnumContainerObjs (LPSTORAGE             pDirectoryStg,
  843.                                   HANDLE                hPipe,
  844.                                   WINDS_AB_OBJTYPE      Type,
  845.                                   LPMALLOC              pMalloc)
  846. {
  847.     LPENUMSTATSTG pEnum;
  848.     STATSTG aStat[ELEMENTS_TO_FETCH];
  849.     AB_ENTRY_INFO abEntry = { 0 };
  850.     abEntry.Type = Type;
  851.     LPTSTR pszObjAlias = (SERVER_DISTRIBUTION_LIST == Type ? abEntry.Info.DL.szDLAlias : abEntry.Info.MB.szMailboxName);
  852.     ULONG ulMBoxFound = 1;
  853.     DWORD dwBytesWritten;
  854.     BOOL fFailure;
  855.     int nChars;
  856.     HRESULT hResult = pDirectoryStg->EnumElements (0, NULL, 0, &pEnum);
  857.     TraceResult ("EnumContainerObjs: Failed to get ENUM interface", hResult);
  858.     if (!hResult)
  859.     {
  860.         while (!hResult && ulMBoxFound)
  861.         {
  862.             hResult = pEnum->Next (ELEMENTS_TO_FETCH, aStat, &ulMBoxFound);
  863.             if (FAILED(hResult)) // We might get S_FALSE
  864.             {
  865.                 TraceResult ("EnumContainerObjs: Failed to ENUM streams", hResult);
  866.             }
  867.             else
  868.             {
  869.                 if (ulMBoxFound)
  870.                 {
  871.                     for (ULONG i=0; i<ulMBoxFound; i++)
  872.                     {
  873.                         if (STGTY_STORAGE == aStat[i].type && (L'_' != aStat[i].pwcsName[0]))
  874.                         {
  875.                             nChars = WideCharToMultiByte (CP_ACP,
  876.                                                           0,
  877.                                                           aStat[i].pwcsName,
  878.                                                           -1,
  879.                                                           pszObjAlias,
  880.                                                           MAX_ALIAS_SIZE+1,
  881.                                                           NULL,
  882.                                                           NULL);
  883.                             if (!nChars)
  884.                             {
  885.                                 TraceResult ("EnumContainerObjs: Failed to convert storage name", HRESULT_FROM_WIN32(GetLastError()));
  886.                             }
  887.                             else
  888.                             {
  889.                                 if (SERVER_DISTRIBUTION_LIST == Type)
  890.                                 {
  891.                                     fFailure = GetDLProperties (pDirectoryStg, aStat[i].pwcsName, &abEntry.Info.DL);
  892.                                 }
  893.                                 else
  894.                                 {
  895.                                     fFailure = GetMailBoxInfo (pDirectoryStg, aStat[i].pwcsName, &abEntry.Info.MB);
  896.                                 }
  897.                                 if (!fFailure)
  898.                                 {
  899.                                     WriteFile (hPipe, &abEntry, sizeof(AB_ENTRY_INFO), &dwBytesWritten, NULL);
  900.                                 }
  901.                             }
  902.                         }
  903.                         pMalloc->Free (aStat[i].pwcsName);
  904.                     }
  905.                 }
  906.             }
  907.         }
  908.         pEnum->Release();
  909.     }
  910.     if (S_FALSE == hResult)
  911.     {
  912.         hResult = S_OK;
  913.     }
  914.     return hResult;
  915. }
  916.  
  917. ///////////////////////////////////////////////////////////////////////////////
  918. //    LoadServerObjects()
  919. //
  920. //    Parameters
  921. //
  922. //    Purpose
  923. //
  924. //    Return Value
  925. //
  926. HRESULT WINAPI LoadServerObjects (LPSTORAGE pStorage, LPMALLOC pMalloc)
  927. {
  928.     LoadObjectProperties (pStorage, SERVER_USER_MAILBOX, TEXT("User Mailbox"), pMalloc);
  929.     LPSTORAGE pDirectoryStg;
  930.     HRESULT hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg);
  931. RestartDL:
  932.     if (!hResult)
  933.     {
  934.         LoadObjectProperties (pDirectoryStg, SERVER_DISTRIBUTION_LIST, TEXT("Distribution List"), pMalloc);
  935.         pDirectoryStg->Release();
  936.     }
  937.     else
  938.     {
  939.         if (STG_E_FILENOTFOUND == hResult)
  940.         {
  941.             hResult = pStorage->CreateStorage (DISTRIBUTION_LISTS, CREATE_FLAGS, 0, 0, &pDirectoryStg);
  942.             goto RestartDL;
  943.         }
  944.     }
  945.     LPSTORAGE pGatewaysStg;
  946.     hResult = pStorage->OpenStorage (FOREIGN_DIRECTORIES, NULL, OPEN_FLAGS, NULL, 0, &pGatewaysStg);
  947. RestartGateways:
  948.     if (!hResult)
  949.     {
  950.         if (!pGatewaysStg->OpenStorage (EXCHANGE_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg))
  951.         {
  952.             LoadObjectProperties (pDirectoryStg, GATEWAY_RECIPIENT, TEXT("Gateway Recipient"), pMalloc);
  953.             pDirectoryStg->Release();
  954.         }
  955.         if (!pGatewaysStg->OpenStorage (FAX_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg))
  956.         {
  957.             LoadObjectProperties (pDirectoryStg, GATEWAY_RECIPIENT, TEXT("Gateway Recipient"), pMalloc);
  958.             pDirectoryStg->Release();
  959.         }
  960.         if (!pGatewaysStg->OpenStorage (SMTP_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pDirectoryStg))
  961.         {
  962.             LoadObjectProperties (pDirectoryStg, GATEWAY_RECIPIENT, TEXT("Gateway Recipient"), pMalloc);
  963.             pDirectoryStg->Release();
  964.         }
  965.         pGatewaysStg->Release();
  966.     }
  967.     else
  968.     {
  969.         if (STG_E_FILENOTFOUND == hResult)
  970.         {
  971.             hResult = pStorage->CreateStorage (FOREIGN_DIRECTORIES, CREATE_FLAGS, 0, 0, &pGatewaysStg);
  972.             goto RestartGateways;
  973.         }
  974.     }
  975.     return S_OK;
  976. }
  977. ///////////////////////////////////////////////////////////////////////////////
  978. //    LoadObjectProperties()
  979. //
  980. //    Parameters
  981. //
  982. //    Purpose
  983. //
  984. //    Return Value
  985. //
  986. HRESULT WINAPI LoadObjectProperties (LPSTORAGE          pStorage,
  987.                                      WINDS_AB_OBJTYPE   Type,
  988.                                      LPTSTR             pszObjectType,
  989.                                      LPMALLOC           pMalloc)
  990. {
  991.     LPENUMSTATSTG pEnum;
  992.     STATSTG aStat[ELEMENTS_TO_FETCH];
  993.     MAILBOX_INFO MBInfo = { 0 };
  994.     DIST_LIST_INFO DLInfo = { 0 };
  995.     ULONG i, ulMBoxFound = 1;
  996.     HRESULT hResult = pStorage->EnumElements (0, NULL, 0, &pEnum);
  997.     TraceResult ("LoadObjectProperties: Failed to get ENUM interface", hResult);
  998.     if (!hResult)
  999.     {
  1000.         while (!hResult && ulMBoxFound)
  1001.         {
  1002.             hResult = pEnum->Next (ELEMENTS_TO_FETCH, aStat, &ulMBoxFound);
  1003.             if (FAILED(hResult)) // We might get S_FALSE
  1004.             {
  1005.                 TraceResult ("LoadObjectProperties: Failed to ENUM streams", hResult);
  1006.             }
  1007.             else
  1008.             {
  1009.                 if (ulMBoxFound)
  1010.                 {
  1011.                     for (i=0; i<ulMBoxFound; i++)
  1012.                     {
  1013.                         if (STGTY_STORAGE == aStat[i].type && (L'_' != aStat[i].pwcsName[0]))
  1014.                         {
  1015.                             int nChars = WideCharToMultiByte (CP_ACP,
  1016.                                                               0,
  1017.                                                               aStat[i].pwcsName,
  1018.                                                               -1,
  1019.                                                               (SERVER_DISTRIBUTION_LIST == Type ? DLInfo.szDLAlias : MBInfo.szMailboxName),
  1020.                                                               MAX_ALIAS_SIZE+1,
  1021.                                                               NULL,
  1022.                                                               NULL);
  1023.                             if (!nChars)
  1024.                             {
  1025.                                 TraceResult ("LoadObjectProperties: Failed to convert storage name", HRESULT_FROM_WIN32(GetLastError()));
  1026.                             }
  1027.                             else
  1028.                             {
  1029.                                 if (SERVER_DISTRIBUTION_LIST == Type)
  1030.                                 {                                
  1031.                                     if (S_OK == GetDLProperties (pStorage, aStat[i].pwcsName, &DLInfo))
  1032.                                     {
  1033.                                         GlobalObjectMap.Insert (DLInfo.dwObjID, DLInfo.szDLAlias, SERVER_DISTRIBUTION_LIST);
  1034.                                     }
  1035.                                 }
  1036.                                 else
  1037.                                 {
  1038.                                     if (S_OK == GetMailBoxInfo (pStorage, aStat[i].pwcsName, &MBInfo))
  1039.                                     {
  1040.                                         GlobalObjectMap.Insert (MBInfo.dwObjID, MBInfo.szMailboxName, SERVER_USER_MAILBOX);
  1041.                                     }
  1042.                                 }
  1043.                             }
  1044.                         }
  1045.                         pMalloc->Free (aStat[i].pwcsName);
  1046.                     }
  1047.                 }
  1048.             }
  1049.         }
  1050.         pEnum->Release();
  1051.     }
  1052.     if (S_FALSE == hResult)
  1053.     {
  1054.         hResult = S_OK;
  1055.     }
  1056.     return hResult;
  1057. }
  1058.  
  1059. ///////////////////////////////////////////////////////////////////////////////
  1060. //    MailboxProps()
  1061. //
  1062. //    Parameters
  1063. //
  1064. //    Purpose
  1065. //
  1066. //    Return Value
  1067. //
  1068. HRESULT WINAPI MailboxProps (LPSTORAGE pMBDirectory, PMAILBOX_INFO pMBInfo, BOOL fRetrieve)
  1069. {
  1070.     HRESULT hResult;
  1071.     WCHAR wcsMailbox[64] = { 0 };
  1072.     AnsiToUnicode (pMBInfo->szMailboxName, wcsMailbox, 64);
  1073.     if (fRetrieve)
  1074.     {
  1075.         hResult = GetMailBoxInfo (pMBDirectory, wcsMailbox, pMBInfo);
  1076.     }
  1077.     else
  1078.     {
  1079.         hResult = SetMailBoxInfo (pMBDirectory, wcsMailbox, pMBInfo);
  1080.     }
  1081.     TraceResult ("MailboxProps", hResult);
  1082.     return hResult;
  1083. }
  1084.  
  1085. ///////////////////////////////////////////////////////////////////////////////
  1086. //    GetMailBoxInfo()
  1087. //
  1088. //    Parameters
  1089. //
  1090. //    Purpose
  1091. //
  1092. //    Return Value
  1093. //
  1094. HRESULT WINAPI GetMailBoxInfo (LPSTORAGE pStorage, LPOLESTR pwcsName, PMAILBOX_INFO pInfo)
  1095. {
  1096.     LPSTREAM pStream;
  1097.     LPSTORAGE pSubStorage;
  1098.     HRESULT hResult = pStorage->OpenStorage (pwcsName, NULL, OPEN_FLAGS, NULL, 0, &pSubStorage);
  1099.     TraceResult ("GetMailBoxInfo: Failed to open mailbox storage", hResult);
  1100.     if (!hResult)
  1101.     {
  1102.         hResult = pSubStorage->OpenStream (USER_PROPERTIES, NULL, OPEN_FLAGS, 0, &pStream);
  1103.         TraceResult ("GetMailBoxInfo: Failed to open the properties stream", hResult);
  1104.         if (!hResult)
  1105.         {
  1106.             hResult = pStream->Read (pInfo, sizeof(MAILBOX_INFO), NULL);
  1107.             TraceResult ("GetMailBoxInfo: Failed to read the MBOX stream", hResult);
  1108.             pStream->Release();
  1109.         }
  1110.         pSubStorage->Release();
  1111.     }
  1112.     return hResult;
  1113. }
  1114.  
  1115. ///////////////////////////////////////////////////////////////////////////////
  1116. //    SetMailBoxInfo()
  1117. //
  1118. //    Parameters
  1119. //
  1120. //    Purpose
  1121. //
  1122. //    Return Value
  1123. //
  1124. HRESULT WINAPI SetMailBoxInfo (LPSTORAGE pStorage, LPOLESTR pwcsName, PMAILBOX_INFO pInfo)
  1125. {
  1126.     LPSTREAM pStream;
  1127.     LPSTORAGE pSubStorage;
  1128.     HRESULT hResult = pStorage->OpenStorage (pwcsName, NULL, OPEN_FLAGS, NULL, 0, &pSubStorage);
  1129.     TraceResult ("SetMailBoxInfo: Failed to open mailbox storage", hResult);
  1130.     if (!hResult)
  1131.     {
  1132.         hResult = pSubStorage->OpenStream (USER_PROPERTIES, NULL, OPEN_FLAGS, 0, &pStream);
  1133.         TraceResult ("SetMailBoxInfo: Failed to open the properties stream", hResult);
  1134.         if (!hResult)
  1135.         {
  1136.             hResult = pStream->Write (pInfo, sizeof(MAILBOX_INFO), NULL);
  1137.             TraceResult ("SetMailBoxInfo: Failed to write to the MBOX stream", hResult);
  1138.             pStream->Release();
  1139.         }
  1140.         pSubStorage->Release();
  1141.     }
  1142.     return hResult;
  1143. }
  1144.  
  1145. ///////////////////////////////////////////////////////////////////////////////
  1146. //    EmptyMailBoxMsgs()
  1147. //
  1148. //    Parameters
  1149. //
  1150. //    Purpose
  1151. //
  1152. //    Return Value
  1153. //
  1154. HRESULT WINAPI EmptyMailBoxMsgs (LPSTORAGE pStorage, LPTSTR pszMailbox)
  1155. {
  1156.     LPSTORAGE pMBStg, pSubStg;
  1157.     WCHAR wcsMailbox[64] = { 0 };
  1158.     AnsiToUnicode (pszMailbox, wcsMailbox, 64);
  1159.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1160.     if (!hResult)
  1161.     {
  1162.         hResult = pMBStg->DestroyElement (HEADERS_STORAGE);
  1163.         if (!hResult)
  1164.         {
  1165.             hResult = pMBStg->CreateStorage (HEADERS_STORAGE, CREATE_FLAGS, 0, 0, &pSubStg);
  1166.             if (!hResult)
  1167.             {
  1168.                 pSubStg->Release();
  1169.                 hResult = pMBStg->DestroyElement (MSGS_STORAGE);
  1170.                 if (!hResult)
  1171.                 {
  1172.                     hResult = pMBStg->CreateStorage (MSGS_STORAGE, CREATE_FLAGS, 0, 0, &pSubStg);
  1173.                     if (!hResult)
  1174.                     {
  1175.                         pSubStg->Release();
  1176.                     }
  1177.                 }
  1178.             }
  1179.         }
  1180.         pMBStg->Release();
  1181.     }
  1182.     TraceResult ("EmptyMailBoxMsgs", hResult);
  1183.     return hResult;
  1184. }
  1185.  
  1186. ///////////////////////////////////////////////////////////////////////////////
  1187. //    GetNextObjID()
  1188. //
  1189. //    Parameters
  1190. //
  1191. //    Purpose
  1192. //
  1193. //    Return Value
  1194. //
  1195. HRESULT WINAPI GetNextObjID (LPSTORAGE pStorage, DWORD & dwNextID)
  1196. {
  1197.     LPSTREAM pStream;
  1198.     LARGE_INTEGER liZero = { 0 };
  1199.     HRESULT hResult = pStorage->OpenStream (OBJ_ID_POOL_STREAM, NULL, OPEN_FLAGS, 0, &pStream);
  1200.     if (!hResult)
  1201.     {
  1202.         // From the opened stream, read the next available ID
  1203.         hResult = pStream->Read (&dwNextID, sizeof(DWORD), NULL);
  1204.         if (!hResult)
  1205.         {
  1206.             // Set the stream seek pointer back to the beginning and write the ID
  1207.             hResult = pStream->Seek (liZero, STREAM_SEEK_SET, NULL);
  1208.             if (!hResult)
  1209.             {
  1210.                 dwNextID++;
  1211.                 hResult = pStream->Write (&dwNextID, sizeof(DWORD), NULL);
  1212.             }
  1213.         }
  1214.         pStream->Release();
  1215.     }
  1216.     // If any, trace out the error code.
  1217.     TraceResult ("GetNextObjID", hResult);
  1218.     return hResult;
  1219. }
  1220.  
  1221. ///////////////////////////////////////////////////////////////////////////////
  1222. //    CreateMailbox()
  1223. //
  1224. //    Parameters
  1225. //
  1226. //    Purpose
  1227. //
  1228. //    Return Value
  1229. //
  1230. HRESULT WINAPI CreateMailbox (LPSTORAGE pMBDirectory, PMAILBOX_INFO pMBInfo)
  1231. {
  1232.     LPSTORAGE pMBStg, pSubStg;
  1233.     LPSTREAM pStream;
  1234.     DWORD dwZero = 0;
  1235.     HRESULT hResult = GetNextObjID (pMBDirectory, pMBInfo->dwObjID);
  1236.     if (hResult)
  1237.     {
  1238.         return hResult;
  1239.     }
  1240.     WCHAR wcsMailbox[64] = { 0 };
  1241.     AnsiToUnicode (pMBInfo->szMailboxName, wcsMailbox, 64);
  1242.     hResult = pMBDirectory->CreateStorage (wcsMailbox, CREATE_FLAGS, 0, 0, &pMBStg);
  1243.     if (!hResult)
  1244.     {
  1245.         hResult = pMBStg->CreateStream (USER_PROPERTIES, CREATE_FLAGS, 0, 0, &pStream);
  1246.         if (!hResult)
  1247.         {
  1248.             hResult = pStream->Write (pMBInfo, sizeof(MAILBOX_INFO), NULL);
  1249.             if (!hResult)
  1250.             {
  1251.                 hResult = pMBStg->CreateStorage (HEADERS_STORAGE, CREATE_FLAGS, 0, 0, &pSubStg);
  1252.                 if (!hResult)
  1253.                 {
  1254.                     pSubStg->Release();
  1255.                     hResult = pMBStg->CreateStream (OBJ_ID_POOL_STREAM, CREATE_FLAGS, 0, 0, &pStream);
  1256.                     if (!hResult)
  1257.                     {
  1258.                         hResult = pStream->Write (&dwZero, sizeof(DWORD), NULL);
  1259.                         pStream->Release();
  1260.                         if (!hResult)
  1261.                         {
  1262.                             hResult = pMBStg->CreateStorage (MSGS_STORAGE, CREATE_FLAGS, 0, 0, &pSubStg);
  1263.                             if (!hResult)
  1264.                             {
  1265.                                 pSubStg->Release();
  1266.                             }
  1267.                         }
  1268.                     }
  1269.                 }
  1270.             }
  1271.         }
  1272.         pMBStg->Release();
  1273.         if (hResult)
  1274.         {
  1275.             hResult = pMBDirectory->DestroyElement (wcsMailbox);
  1276.         }
  1277.     }
  1278.     TraceResult ("CreateMailbox", hResult);
  1279.     return hResult;
  1280. }
  1281.  
  1282. ///////////////////////////////////////////////////////////////////////////////
  1283. //    DeleteMailbox()
  1284. //
  1285. //    Parameters
  1286. //
  1287. //    Purpose
  1288. //
  1289. //    Return Value
  1290. //
  1291. HRESULT WINAPI DeleteMailbox (LPSTORAGE pStorage, PMAILBOX_INFO pMBInfo)
  1292. {
  1293.     WCHAR wcsMailbox[64] = { 0 };
  1294.     AnsiToUnicode (pMBInfo->szMailboxName, wcsMailbox, 64);
  1295.     GetMailBoxInfo (pStorage, wcsMailbox, pMBInfo);
  1296.     HRESULT hResult = pStorage->DestroyElement (wcsMailbox);
  1297.     TraceResult ("DeleteMailbox: Failed to delete storage of mailbox", hResult);
  1298.     return hResult;
  1299. }
  1300.  
  1301. ///////////////////////////////////////////////////////////////////////////////
  1302. //    CopyMsgFromFile()
  1303. //
  1304. //    Parameters
  1305. //
  1306. //    Purpose
  1307. //
  1308. //    Return Value
  1309. //
  1310. HRESULT WINAPI CopyMsgFromFile (LPSTORAGE      pStorage,
  1311.                                 HANDLE         hFile,
  1312.                                 LPTSTR         szMailbox,
  1313.                                 LPTSTR         szHeader)
  1314. {
  1315.     LPSTORAGE pMBStg, pMsgStg;
  1316.     LPSTREAM pStream;
  1317.     WCHAR wcsMailbox[64] = { 0 }, wcsStreamName[NAME_FORMAT_SIZE];
  1318.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  1319.     
  1320.     BYTE abBuffer[IO_BUFFERSIZE];
  1321.     DWORD dwBytesRead, dwLastError = 0, dwStreamID;
  1322.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1323.     if (!hResult)
  1324.     {
  1325.         hResult = pMBStg->OpenStorage (MSGS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pMsgStg);
  1326.         if (!hResult)
  1327.         {
  1328.             hResult = GetNextObjID (pMBStg, dwStreamID);
  1329.             if (!hResult)
  1330.             {
  1331.                 wsprintfW (wcsStreamName, MSG_STREAM_FORMAT, dwStreamID);
  1332.                 hResult = pMsgStg->CreateStream (wcsStreamName, CREATE_FLAGS, 0, 0, &pStream);
  1333.                 if (!hResult)
  1334.                 {
  1335.                     do
  1336.                     {
  1337.                         if (!ReadFile (hFile, abBuffer, IO_BUFFERSIZE, &dwBytesRead, NULL))
  1338.                         {
  1339.                             dwLastError = HRESULT_FROM_WIN32(GetLastError());
  1340.                             TraceResult ("CopyMsgFromFile: Failed to read from the tmp file", dwLastError);
  1341.                         }
  1342.                         if (dwBytesRead)
  1343.                         {
  1344.                             hResult = pStream->Write (abBuffer, dwBytesRead, NULL);
  1345.                             TraceResult ("CopyMsgFromFile: Failed to write into mb stream", hResult);
  1346.                         }
  1347.                     } while (dwBytesRead && !hResult && !dwLastError);
  1348.                     if (!hResult && !dwLastError)
  1349.                     {
  1350.                         hResult = UpdateMailboxHeaders (pStorage, pMBStg, NULL, dwStreamID, szHeader, TRUE);
  1351.                     }
  1352.                     pStream->Release();
  1353.                     if (hResult || dwLastError)
  1354.                     {
  1355.                         pMsgStg->DestroyElement (wcsStreamName);
  1356.                         if (dwLastError)
  1357.                         {
  1358.                             hResult = dwLastError;
  1359.                         }
  1360.                     }
  1361.                 }
  1362.             }
  1363.             pMsgStg->Release();
  1364.         }
  1365.         pMBStg->Release();
  1366.     }
  1367.     // If there were no error storing the message in the user mailbox, send a
  1368.     // notification to client transports indicating that a new message
  1369.     // is pending download.
  1370.     if (S_OK == hResult)
  1371.     {
  1372.         PWINDS_NOTIFICATION pNotif = (PWINDS_NOTIFICATION)HeapAlloc (ghHeap,
  1373.                                                                      HEAP_ZERO_MEMORY,
  1374.                                                                      sizeof(WINDS_NOTIFICATION));
  1375.         if (pNotif)
  1376.         {
  1377.             pNotif->Event = XP_NEW_MAIL_ARRIVED;
  1378.             lstrcpy (pNotif->Info.MB.szMailboxName, szMailbox);
  1379.             NotifyClients (pNotif); // This will take care of freeing the notification structure
  1380.         }
  1381.         else
  1382.         {
  1383.             TraceMessage ("CopyMsgFromFile: Failed to allocate memory for client notification");
  1384.         }
  1385.     }
  1386.     TraceResult ("CopyMsgFromFile", hResult);
  1387.     return hResult;
  1388. }
  1389.  
  1390. ///////////////////////////////////////////////////////////////////////////////
  1391. //    RemoveMessageFromMailbox()
  1392. //
  1393. //    Parameters
  1394. //
  1395. //    Purpose
  1396. //
  1397. //    Return Value
  1398. //
  1399. HRESULT WINAPI RemoveMessageFromMailbox (LPSTORAGE      pStorage,
  1400.                                          LPTSTR         szMailbox,
  1401.                                          DWORD          dwStreamID)
  1402. {
  1403.     LPSTORAGE pHeaders, pMBStg, pMsgStg;
  1404.     WCHAR wcsMailbox[64] = { 0 }, wcsStreamName[NAME_FORMAT_SIZE];
  1405.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  1406.  
  1407.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1408.     if (!hResult)
  1409.     {
  1410.         hResult = pMBStg->OpenStorage (MSGS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pMsgStg);
  1411.         if (!hResult)
  1412.         {
  1413.             wsprintfW (wcsStreamName, MSG_STREAM_FORMAT, dwStreamID);
  1414.             hResult = pMsgStg->DestroyElement (wcsStreamName);
  1415.             if (!hResult)
  1416.             {
  1417.                 hResult = pMBStg->OpenStorage (HEADERS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pHeaders);
  1418.                 if (!hResult)
  1419.                 {
  1420.                     wsprintfW (wcsStreamName, HEADER_STREAM_FORMAT, dwStreamID);
  1421.                     pHeaders->DestroyElement (wcsStreamName); // Drop the error code here
  1422.                     pHeaders->Release();
  1423.                 }
  1424.             }
  1425.             pMsgStg->Release();
  1426.         }
  1427.         pMBStg->Release();
  1428.     }
  1429.     TraceResult ("RemoveMessageFromMailbox", hResult);
  1430.     return hResult;
  1431. }
  1432.  
  1433. ///////////////////////////////////////////////////////////////////////////////
  1434. //    UpdateMailboxHeaders()
  1435. //
  1436. //    Parameters
  1437. //
  1438. //    Purpose
  1439. //
  1440. //    Return Value
  1441. //
  1442. long WINAPI UpdateMailboxHeaders (LPSTORAGE pStorage,
  1443.                                   LPSTORAGE pMBStg,
  1444.                                   LPTSTR    szMailbox,
  1445.                                   DWORD     dwStreamID,
  1446.                                   LPTSTR    pszHeader,
  1447.                                   BOOL      fAddMsgToHeadersList)
  1448. {
  1449.     WCHAR wcsMailbox[64] = { 0 }, wcsStreamName[NAME_FORMAT_SIZE];
  1450.     
  1451.     LPSTORAGE pHeadersStg;
  1452.     LPSTREAM pHeader;
  1453.     HRESULT hResult = S_OK;
  1454.     BOOL fReleaseLocalStorage = FALSE;
  1455.     if (!pMBStg)
  1456.     {
  1457.         fReleaseLocalStorage = TRUE;
  1458.         AnsiToUnicode (szMailbox, wcsMailbox, 64);
  1459.         hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1460.         TraceResult ("UpdateMailboxHeaders: Failed to open mailbox", hResult);
  1461.     }
  1462.     if (!hResult)
  1463.     {
  1464.         hResult = pMBStg->OpenStorage (HEADERS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pHeadersStg);
  1465.         TraceResult ("UpdateMailboxHeaders: Failed to open header storage", hResult);
  1466.         if (!hResult)
  1467.         {
  1468.             wsprintfW (wcsStreamName, HEADER_STREAM_FORMAT, dwStreamID);
  1469.             if (fAddMsgToHeadersList)
  1470.             {
  1471.                 hResult = pHeadersStg->CreateStream (wcsStreamName, CREATE_FLAGS, 0, 0, &pHeader);
  1472.                 TraceResult ("UpdateMailboxHeaders: Failed to create header stream", hResult);
  1473.                 if (!hResult)
  1474.                 {
  1475.                     BYTE abEntryID[16];
  1476.                     ZeroMemory (abEntryID, 16);
  1477.                     wsprintfA ((LPSTR)&abEntryID[4], "%d", dwStreamID);
  1478.  
  1479.                     ULONG cbSize = 16 + lstrlen(pszHeader) * sizeof(TCHAR);
  1480.                     hResult = pHeader->Write (&cbSize, sizeof(ULONG), NULL);
  1481.                     TraceResult ("UpdateMailboxHeaders: Failed to write header size", hResult);
  1482.                     if (!hResult)
  1483.                     {
  1484.                         hResult = pHeader->Write (abEntryID, 16, NULL);
  1485.                         TraceResult ("UpdateMailboxHeaders: Failed to write message EID", hResult);
  1486.                         if (!hResult)
  1487.                         {
  1488.                             hResult = pHeader->Write (pszHeader, cbSize - 16, NULL);
  1489.                             TraceResult ("UpdateMailboxHeaders: Failed to write header to stream", hResult);
  1490.                         }
  1491.                     }
  1492.                     pHeader->Release();
  1493.                     if (hResult)
  1494.                     {
  1495.                         TraceIO2 ("UpdateMailboxHeaders", pHeadersStg->DestroyElement(wcsStreamName));
  1496.                     }
  1497.                 }
  1498.             }
  1499.             else
  1500.             {
  1501.                 hResult = pMBStg->DestroyElement (wcsStreamName);
  1502.                 TraceResult ("UpdateMailboxHeaders: Failed to remove header stream", hResult);
  1503.             }
  1504.             pHeadersStg->Release();
  1505.         }
  1506.         if (fReleaseLocalStorage)
  1507.         {
  1508.             pMBStg->Release();
  1509.         }
  1510.     }
  1511.     return hResult;
  1512. }
  1513.  
  1514. ///////////////////////////////////////////////////////////////////////////////
  1515. //    CopyHeadersToFile()
  1516. //
  1517. //    Parameters
  1518. //
  1519. //    Purpose
  1520. //
  1521. //    Return Value
  1522. //
  1523. HRESULT WINAPI CopyHeadersToFile (LPSTORAGE     pStorage,
  1524.                                   LPMALLOC      pMalloc,
  1525.                                   HANDLE        hFile,
  1526.                                   LPTSTR        szMailbox)
  1527. {
  1528.     BOOL fAtLeastOneCopied = FALSE, fSubStreamFailed = FALSE;
  1529.     LPSTORAGE pMBStg, pHeadersStg;
  1530.     LPSTREAM pStream;
  1531.     LPENUMSTATSTG pEnum;
  1532.     BYTE abBuffer[IO_BUFFERSIZE];
  1533.     STATSTG aStat[ELEMENTS_TO_FETCH];
  1534.     ULONG ulStreamsFound, ulBytesRead;
  1535.     DWORD dwBytesWrite;
  1536.     
  1537.     WCHAR wcsMailbox[64] = { 0 };
  1538.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  1539.  
  1540.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1541.     TraceResult ("CopyHeadersToFile: Failed to mailbox storage", hResult);
  1542.     if (!hResult)
  1543.     {
  1544.         hResult = pMBStg->OpenStorage (HEADERS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pHeadersStg);
  1545.         TraceResult ("CopyHeadersToFile: Failed to open headers storage", hResult);
  1546.         if (!hResult)
  1547.         {
  1548.             hResult = pHeadersStg->EnumElements (0, NULL, 0, &pEnum);
  1549.             TraceResult ("CopyHeadersToFile: Failed to get ENUM interface", hResult);
  1550.             if (!hResult)
  1551.             {
  1552.                 hResult = 0;
  1553.                 ulStreamsFound = 1;
  1554.                 while (!hResult && ulStreamsFound)
  1555.                 {
  1556.                     hResult = pEnum->Next (ELEMENTS_TO_FETCH, aStat, &ulStreamsFound);
  1557.                     if (ulStreamsFound)
  1558.                     {
  1559.                         for (ULONG i=0; i<ulStreamsFound; i++)
  1560.                         {
  1561.                             hResult = pHeadersStg->OpenStream (aStat[i].pwcsName, NULL, OPEN_FLAGS, 0, &pStream);
  1562.                             TraceResult ("CopyHeadersToFile: Failed to open header stream", hResult);
  1563.                             if (!hResult)
  1564.                             {
  1565.                                 ASSERT (IO_BUFFERSIZE >= aStat[i].cbSize.LowPart);
  1566.                                 hResult = pStream->Read (abBuffer, aStat[i].cbSize.LowPart, &ulBytesRead);
  1567.                                 if (!hResult)
  1568.                                 {
  1569.                                     if (!WriteFile (hFile, abBuffer, ulBytesRead, &dwBytesWrite, NULL))
  1570.                                     {
  1571.                                         fSubStreamFailed = TRUE;
  1572.                                         TraceResult ("CopyHeadersToFile: Failed to write header to tmp file", HRESULT_FROM_WIN32(GetLastError()));
  1573.                                     }
  1574.                                     else
  1575.                                     {
  1576.                                         fAtLeastOneCopied = TRUE;
  1577.                                     }
  1578.                                 }
  1579.                                 pStream->Release();
  1580.                             }
  1581.                             pMalloc->Free (aStat[i].pwcsName);
  1582.                         }
  1583.                     }
  1584.                     else
  1585.                     {
  1586.                         if (FAILED(hResult)) // We might get S_FALSE
  1587.                         {
  1588.                             TraceResult ("CopyHeadersToFile: Failed to ENUM streams", hResult);
  1589.                         }
  1590.                     }
  1591.                 }
  1592.                 if (S_FALSE == hResult)
  1593.                 {
  1594.                     hResult = S_OK;
  1595.                 }
  1596.                 pEnum->Release();
  1597.             }
  1598.             pHeadersStg->Release();
  1599.         }
  1600.         pMBStg->Release();
  1601.     }
  1602.     if (hResult)
  1603.     {
  1604.         if (fSubStreamFailed)
  1605.         {
  1606.             if (fAtLeastOneCopied)
  1607.             {
  1608.                 hResult = MAKE_HRESULT(0, FACILITY_WIN32, ERROR_PARTIAL_COPY);
  1609.             }
  1610.         }
  1611.     }
  1612.     SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
  1613.     return hResult;
  1614. }
  1615.  
  1616. ///////////////////////////////////////////////////////////////////////////////
  1617. //    CopyStreamToFile()
  1618. //
  1619. //    Parameters                        
  1620. //
  1621. //    Purpose
  1622. //      
  1623. //    Return Value
  1624. //      
  1625. HRESULT WINAPI CopyStreamToFile (LPSTREAM   pStream,
  1626.                                  HANDLE     hFile,
  1627.                                  ULONG *    pulWritten)
  1628. {
  1629.     BYTE aBuffer[IO_BUFFERSIZE]; 
  1630.     ULONG ulRead, ulRemain, ulWritten;
  1631.     STATSTG StatInfo;
  1632.     *pulWritten = 0;
  1633.     HRESULT hResult = pStream->Stat (&StatInfo, STATFLAG_NONAME);
  1634.     if (!hResult)
  1635.     {
  1636.         ulRemain  = StatInfo.cbSize.LowPart;
  1637.         for (; ulRemain>0; ulRemain -= ulWritten)
  1638.         {
  1639.             hResult = pStream->Read (aBuffer, min(ulRemain, IO_BUFFERSIZE), &ulRead);
  1640.             if (hResult)
  1641.             {
  1642.                 break; // Out of the FOR() loop
  1643.             }
  1644.             else
  1645.             {
  1646.                 if (!WriteFile (hFile, aBuffer, ulRead, &ulWritten, NULL))
  1647.                 {            
  1648.                     hResult = HRESULT_FROM_WIN32(GetLastError());
  1649.                     break; // Out of the FOR() loop
  1650.                 }
  1651.             }
  1652.             *pulWritten += ulWritten;
  1653.         }
  1654.     }
  1655.     TraceResult ("CopyStreamToFile", hResult);
  1656.     return hResult;
  1657. }
  1658.  
  1659. ///////////////////////////////////////////////////////////////////////////////
  1660. //    CopyMsgToFile()
  1661. //
  1662. //    Parameters
  1663. //
  1664. //    Purpose
  1665. //
  1666. //    Return Value
  1667. //
  1668. HRESULT WINAPI CopyMsgToFile (LPSTORAGE    pStorage,
  1669.                               LPTSTR       szMailbox,
  1670.                               HANDLE       hFile,
  1671.                               ULONG *      pulMsgLen,
  1672.                               DWORD        dwStreamID,
  1673.                               BOOL         fDeleteAfterCopy)
  1674. {
  1675.     LPSTORAGE pMBStg, pMsgStg, pHeaders;
  1676.     LPSTREAM pStream;
  1677.     WCHAR wcsMailbox[64] = { 0 }, wcsStreamName[NAME_FORMAT_SIZE];
  1678.     wsprintfW (wcsStreamName, MSG_STREAM_FORMAT, dwStreamID);
  1679.  
  1680.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  1681.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMBStg);
  1682.     if (!hResult)
  1683.     {
  1684.         hResult = pMBStg->OpenStorage (MSGS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pMsgStg);
  1685.         if(!hResult)
  1686.         {
  1687.             hResult = pMsgStg->OpenStream (wcsStreamName, NULL, OPEN_FLAGS, 0, &pStream);
  1688.             if (!hResult)
  1689.             {
  1690.                 hResult = CopyStreamToFile (pStream, hFile, pulMsgLen);
  1691.                 pStream->Release();
  1692.                 if (!hResult && fDeleteAfterCopy)
  1693.                 {
  1694.                     hResult = pMsgStg->DestroyElement (wcsStreamName);
  1695.                     if (!hResult)
  1696.                     {
  1697.                         hResult = pMBStg->OpenStorage (HEADERS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pHeaders);
  1698.                         if (!hResult)
  1699.                         {
  1700.                             wsprintfW (wcsStreamName, HEADER_STREAM_FORMAT, dwStreamID);
  1701.                             hResult = pHeaders->DestroyElement (wcsStreamName);
  1702.                             pHeaders->Release();
  1703.                         }
  1704.                     }
  1705.                     hResult = S_OK; // We don't want to propagate errors at this level, since the message is already copied.
  1706.                 }
  1707.             }
  1708.             pMsgStg->Release();
  1709.         }
  1710.         pMBStg->Release();
  1711.     }
  1712.     TraceResult ("CopyMsgToFile", hResult);
  1713.     return hResult;
  1714. }
  1715.  
  1716. ///////////////////////////////////////////////////////////////////////////////
  1717. //    CreateDistributionList()
  1718. //
  1719. //    Parameters
  1720. //
  1721. //    Purpose
  1722. //
  1723. //    Return Value
  1724. //
  1725. HRESULT WINAPI CreateDistributionList (LPSTORAGE pStorage, PDIST_LIST_INFO pDLInfo)
  1726. {
  1727.     HRESULT hResult = GetNextObjID (pStorage, pDLInfo->dwObjID);
  1728.     if (hResult)
  1729.     {
  1730.         return hResult;
  1731.     }
  1732.     LPSTORAGE pDLDirectoryStg, pDLStg;
  1733.     LPSTREAM pStream;
  1734.     WCHAR wcsDLalias[64] = { 0 };
  1735.     AnsiToUnicode (pDLInfo->szDLAlias, wcsDLalias, 64);
  1736.  
  1737.     hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDLDirectoryStg);
  1738. Restart:
  1739.     if (!hResult)
  1740.     {
  1741.         hResult = pDLDirectoryStg->CreateStorage (wcsDLalias, CREATE_FLAGS, 0, 0, &pDLStg);
  1742.         if (!hResult)
  1743.         {
  1744.             hResult = pDLStg->CreateStream (DL_PROPS, CREATE_FLAGS, 0, 0, &pStream);
  1745.             if (!hResult)
  1746.             {
  1747.                 pStream->Release();
  1748.                 hResult = pDLStg->CreateStream (DL_MEMBERS, CREATE_FLAGS, 0, 0, &pStream);
  1749.                 if (!hResult)
  1750.                 {
  1751.                     pStream->Release();
  1752.                 }
  1753.             }
  1754.             pDLStg->Release();
  1755.             hResult = SetDLProperties (pDLDirectoryStg, wcsDLalias, pDLInfo);
  1756.         }
  1757.         if (hResult)
  1758.         {
  1759.             pDLDirectoryStg->DestroyElement (wcsDLalias);
  1760.         }
  1761.         pDLDirectoryStg->Release();
  1762.     }
  1763.     else
  1764.     {
  1765.         if (STG_E_FILENOTFOUND == hResult)
  1766.         {
  1767.             hResult = pStorage->CreateStorage (DISTRIBUTION_LISTS, CREATE_FLAGS, 0, 0, &pDLDirectoryStg);
  1768.             goto Restart;
  1769.         }
  1770.     }
  1771.     TraceResult ("CreateDistributionList", hResult);
  1772.     return hResult;
  1773. }
  1774.  
  1775. ///////////////////////////////////////////////////////////////////////////////
  1776. //    DLPropsAndMembers()
  1777. //
  1778. //    Parameters
  1779. //
  1780. //    Purpose
  1781. //
  1782. //    Return Value
  1783. //
  1784. HRESULT WINAPI DLPropsAndMembers (LPSTORAGE pStorage, PDIST_LIST_INFO pDLInfo, BOOL fGetProps)
  1785. {
  1786.     LPSTORAGE pDLDirectoryStg;
  1787.     WCHAR wcsDLalias[64] = { 0 };
  1788.     AnsiToUnicode (pDLInfo->szDLAlias, wcsDLalias, 64);
  1789.     HRESULT hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDLDirectoryStg);
  1790.     if (!hResult)
  1791.     {
  1792.         if (fGetProps)
  1793.         {
  1794.             hResult = GetDLProperties (pDLDirectoryStg, wcsDLalias, pDLInfo, TRUE);
  1795.         }
  1796.         else
  1797.         {
  1798.             hResult = SetDLProperties (pDLDirectoryStg, wcsDLalias, pDLInfo);
  1799.         }
  1800.         pDLDirectoryStg->Release();
  1801.     }
  1802.     TraceResult ("DLPropsAndMembers", hResult);
  1803.     return hResult;
  1804. }
  1805.  
  1806. ///////////////////////////////////////////////////////////////////////////////
  1807. //    GetDLProperties()
  1808. //
  1809. //    Parameters
  1810. //
  1811. //    Purpose
  1812. //
  1813. //    Return Value
  1814. //
  1815. HRESULT WINAPI GetDLProperties (LPSTORAGE           pStorage,
  1816.                                 LPOLESTR            pwcsDLName,
  1817.                                 PDIST_LIST_INFO     pDLInfo,
  1818.                                 BOOL                fGetMembers)
  1819. {
  1820.     LPSTREAM pStream;
  1821.     LPSTORAGE pDLStg;
  1822.     DWORD i;
  1823.     DLM_INFO_A Info = { 0 };
  1824.     DLM_LIST_A * pList = (DLM_LIST_A *)pDLInfo->pMembers;
  1825.  
  1826.     HRESULT hResult = pStorage->OpenStorage (pwcsDLName, NULL, OPEN_FLAGS, NULL, 0, &pDLStg);
  1827.     if (!hResult)
  1828.     {
  1829.         hResult = pDLStg->OpenStream (DL_PROPS, NULL, OPEN_FLAGS, 0, &pStream);
  1830.         if (!hResult)
  1831.         {
  1832.             hResult = pStream->Read (pDLInfo,
  1833.                                      sizeof(DIST_LIST_INFO) - 4, // Don't read the pMember pointer value
  1834.                                      NULL);
  1835.             pStream->Release();
  1836.         }
  1837.         if (!hResult && fGetMembers && pDLInfo->dwMemberCount && pList)
  1838.         {
  1839.             hResult = pDLStg->OpenStream (DL_MEMBERS, NULL, OPEN_FLAGS, 0, &pStream);
  1840.             if (!hResult)
  1841.             {
  1842.                 for (i=0; i<pDLInfo->dwMemberCount && !hResult; i++)
  1843.                 {
  1844.                     hResult = pStream->Read (&Info, sizeof(DLM_INFO_A), NULL);
  1845.                     if (!hResult)
  1846.                     {
  1847.                         if (i == 0)
  1848.                         {
  1849.                             pList->Info = Info;
  1850.                         }
  1851.                         else
  1852.                         {
  1853.                             InsertNewDLMNodeA (Info, pList);
  1854.                         }
  1855.                     }
  1856.                 }
  1857.                 pStream->Release();
  1858.             }
  1859.         }
  1860.         pDLStg->Release();
  1861.     }
  1862.     TraceResult ("GetDLProperties", hResult);
  1863.     return hResult;
  1864. }
  1865.  
  1866. ///////////////////////////////////////////////////////////////////////////////
  1867. //    SetDLProperties()
  1868. //
  1869. //    Parameters
  1870. //
  1871. //    Purpose
  1872. //
  1873. //    Return Value
  1874. //
  1875. HRESULT WINAPI SetDLProperties (LPSTORAGE           pStorage,
  1876.                                 LPOLESTR            pwcsDLName,
  1877.                                 PDIST_LIST_INFO     pDLInfo)
  1878. {
  1879.     LPSTREAM pStream;
  1880.     LPSTORAGE pDLStg;
  1881.     ULARGE_INTEGER uliTotalSize = { 0 };
  1882.     ULONG ulBytesWritten;
  1883.     DLM_LIST_A * pNode;
  1884.     HRESULT hResult = pStorage->OpenStorage (pwcsDLName, NULL, OPEN_FLAGS, NULL, 0, &pDLStg);
  1885.     if (!hResult)
  1886.     {
  1887.         pDLInfo->dwMemberCount = 0;
  1888.         hResult = pDLStg->OpenStream (DL_MEMBERS, NULL, OPEN_FLAGS, 0, &pStream);
  1889.         if (!hResult)
  1890.         {
  1891.             pNode = (DLM_LIST_A *)pDLInfo->pMembers;
  1892.             while (pNode && !hResult)
  1893.             {
  1894.                 hResult = pStream->Write (&(pNode->Info),
  1895.                                           sizeof(DLM_INFO_A),
  1896.                                           &ulBytesWritten);
  1897.                 uliTotalSize.LowPart += ulBytesWritten;
  1898.                 pDLInfo->dwMemberCount++;
  1899.                 pNode = pNode->pNext;
  1900.             }
  1901.             pStream->SetSize (uliTotalSize);
  1902.             pStream->Release();
  1903.         }
  1904.         if (!hResult)
  1905.         {
  1906.             hResult = pDLStg->OpenStream (DL_PROPS, NULL, OPEN_FLAGS, 0, &pStream);
  1907.             if (!hResult)
  1908.             {
  1909.                 hResult = pStream->Write (pDLInfo,
  1910.                                           sizeof(DIST_LIST_INFO) - 4, // Don't write the last 4 byte (pMembers)
  1911.                                           NULL);
  1912.                 pStream->Release();
  1913.             }
  1914.         }
  1915.         pDLStg->Release();
  1916.     }
  1917.     TraceResult ("SetDLProperties", hResult);
  1918.     return hResult;
  1919. }
  1920.  
  1921. ///////////////////////////////////////////////////////////////////////////////
  1922. //    DeleteDistributionList()
  1923. //
  1924. //    Parameters
  1925. //
  1926. //    Purpose
  1927. //
  1928. //    Return Value
  1929. //
  1930. HRESULT WINAPI DeleteDistributionList (LPSTORAGE pStorage, PDIST_LIST_INFO pDLInfo)
  1931. {
  1932.     LPSTORAGE pDLDirectoryStg;
  1933.     WCHAR wcsDLalias[64] = { 0 };
  1934.     AnsiToUnicode (pDLInfo->szDLAlias, wcsDLalias, 64);
  1935.     HRESULT hResult = pStorage->OpenStorage (DISTRIBUTION_LISTS, NULL, OPEN_FLAGS, NULL, 0, &pDLDirectoryStg);
  1936.     if (!hResult)
  1937.     {
  1938.         GetDLProperties (pDLDirectoryStg, wcsDLalias, pDLInfo, FALSE);
  1939.         hResult = pDLDirectoryStg->DestroyElement (wcsDLalias);
  1940.         pDLDirectoryStg->Release();
  1941.     }
  1942.     TraceResult ("DeleteDistributionList", hResult);
  1943.     return hResult;
  1944. }
  1945.  
  1946. ///////////////////////////////////////////////////////////////////////////////
  1947. //    GetDLRecipientsInfo()
  1948. //
  1949. //    Parameters
  1950. //
  1951. //    Purpose
  1952. //
  1953. //    Return Value
  1954. //
  1955. HRESULT WINAPI GetDLRecipientsInfo (LPSTORAGE   pMBDirectory,
  1956.                                     LPSTORAGE   pDLDirectory,
  1957.                                     HANDLE      hPipe,
  1958.                                     LPOLESTR    pwcsDLName)
  1959. {
  1960.     DLM_LIST_A Members = { 0 };
  1961.     DIST_LIST_INFO DLInfo = { 0 };
  1962.     DLInfo.pMembers = (LPVOID)&Members;
  1963.     AB_ENTRY_INFO abEntry = { 0 };
  1964.     OLECHAR wcsMemberAlias[MAX_ALIAS_SIZE+1];
  1965.     int nChars;
  1966.     DWORD dwBytesWritten;
  1967.     DLM_LIST_A * pNode;
  1968.     
  1969.     HRESULT hEntry, hResult = GetDLProperties (pDLDirectory, pwcsDLName, &DLInfo, TRUE);
  1970.     if (!hResult && (0 != Members.Info.dwMemberID))
  1971.     {
  1972.         pNode = (DLM_LIST_A *)DLInfo.pMembers;
  1973.         while (pNode)
  1974.         {
  1975.             nChars = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, (LPSTR)pNode->Info.szMemberAlias, -1, wcsMemberAlias, MAX_ALIAS_SIZE+1);
  1976.             if (!nChars)
  1977.             {
  1978.                 TraceResult ("GetDLRecipientsInfo: Failed to convert alias name", HRESULT_FROM_WIN32(GetLastError()));
  1979.             }
  1980.             else
  1981.             {
  1982.                 abEntry.Type = (WINDS_AB_OBJTYPE)pNode->Info.dwMemberType;
  1983.                 if (SERVER_DISTRIBUTION_LIST == abEntry.Type)
  1984.                 {
  1985.                     hEntry = GetDLProperties (pDLDirectory, wcsMemberAlias, &abEntry.Info.DL, FALSE);
  1986.                 }
  1987.                 else
  1988.                 {
  1989.                     if (SERVER_USER_MAILBOX == abEntry.Type)
  1990.                     {
  1991.                         hEntry = GetMailBoxInfo (pMBDirectory, wcsMemberAlias, &abEntry.Info.MB);
  1992.                     }
  1993.                     else
  1994.                     {
  1995.                         ASSERT (GATEWAY_RECIPIENT == abEntry.Type);
  1996.                         ASSERT (FALSE); // not implemented yet
  1997.                         hEntry = E_FAIL;
  1998.                     }
  1999.                 }
  2000.                 if (!hEntry)
  2001.                 {
  2002.                     if (!WriteFile (hPipe, &abEntry, sizeof(AB_ENTRY_INFO), &dwBytesWritten, NULL))
  2003.                     {
  2004.                         TraceResult ("GetDLRecipientsInfo: Failed to write to client pipe", HRESULT_FROM_WIN32(GetLastError()));
  2005.                     }
  2006.                 }
  2007.             }
  2008.             pNode = pNode->pNext;
  2009.         }
  2010.         FreeDLMList (&Members);
  2011.     }
  2012.     TraceResult ("GetDLRecipientsInfo", hResult);
  2013.     return hResult;
  2014. }
  2015.  
  2016. ///////////////////////////////////////////////////////////////////////////////
  2017. //    GetGWContainerCount()
  2018. //
  2019. //    Parameters
  2020. //
  2021. //    Purpose
  2022. //
  2023. //    Return Value
  2024. //
  2025. HRESULT WINAPI GetGWContainerCount (LPSTORAGE   pStorage,
  2026.                                     LPMALLOC    pMalloc,
  2027.                                     DWORD       dwContainerID,
  2028.                                     DWORD *     pdwContainerCount)
  2029. {
  2030.     LPENUMSTATSTG pEnum;
  2031.     STATSTG aStat[ELEMENTS_TO_FETCH];
  2032.     ULONG ulMBoxFound = 1;
  2033.     LPSTORAGE pDirectory, pGWContainer;
  2034.     HRESULT hResult = pStorage->OpenStorage (FOREIGN_DIRECTORIES, NULL, OPEN_FLAGS, NULL, 0, &pDirectory);
  2035.     if (!hResult)
  2036.     {
  2037.         switch (dwContainerID)
  2038.         {
  2039.             case FAX_CONTAINER_ID :
  2040.                 hResult = pStorage->OpenStorage (FAX_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pGWContainer);
  2041.                 break;
  2042.             case SMTP_CONTAINER_ID :
  2043.                 hResult = pStorage->OpenStorage (SMTP_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pGWContainer);
  2044.                 break;
  2045.             case EXCHANGE_CONTAINER_ID :
  2046.                 hResult = pStorage->OpenStorage (EXCHANGE_GATEWAY, NULL, OPEN_FLAGS, NULL, 0, &pGWContainer);
  2047.                 break;
  2048.         }
  2049.         if (!hResult)
  2050.         {
  2051.             hResult = pGWContainer->EnumElements (0, NULL, 0, &pEnum);
  2052.             if (!hResult)
  2053.             {
  2054.                 while (!hResult && ulMBoxFound)
  2055.                 {
  2056.                     hResult = pEnum->Next (ELEMENTS_TO_FETCH, aStat, &ulMBoxFound);
  2057.                     if (SUCCEEDED(hResult))
  2058.                     {
  2059.                         if (ulMBoxFound)
  2060.                         {
  2061.                             for (ULONG i=0; i<ulMBoxFound; i++)
  2062.                             {
  2063.                                 if (STGTY_STORAGE == aStat[i].type && (L'_' != aStat[i].pwcsName[0]))
  2064.                                 {
  2065.                                     (*pdwContainerCount)++;
  2066.                                 }
  2067.                                 pMalloc->Free (aStat[i].pwcsName);
  2068.                             }
  2069.                         }
  2070.                     }
  2071.                 }
  2072.                 pEnum->Release();
  2073.             }
  2074.             hResult = S_OK;
  2075.             pGWContainer->Release();
  2076.         }
  2077.         pDirectory->Release();
  2078.     }
  2079.     TraceResult ("GetGWContainerCount", hResult);
  2080.     return hResult;
  2081. }
  2082.  
  2083. ///////////////////////////////////////////////////////////////////////////////
  2084. //    CheckForPendingMailboxMsgs()
  2085. //
  2086. //    Parameters
  2087. //
  2088. //    Purpose
  2089. //
  2090. //    Return Value
  2091. //
  2092. HRESULT WINAPI CheckForPendingMailboxMsgs (LPSTORAGE pStorage,
  2093.                                            LPMALLOC  pMalloc,
  2094.                                            LPTSTR    szMailbox,
  2095.                                            DWORD *   pdwMsgCount)
  2096. {
  2097.     WCHAR wcsMailbox[64] = { 0 };
  2098.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  2099.  
  2100.     ULONG ulMsgsFound, dwTotal = 0;
  2101.     LPENUMSTATSTG pEnum;
  2102.     STATSTG aStat[ELEMENTS_TO_FETCH];
  2103.     LPSTORAGE pMailbox, pMessages;
  2104.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMailbox);
  2105.     if (!hResult)
  2106.     {
  2107.         hResult = pMailbox->OpenStorage (MSGS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pMessages);
  2108.         if (!hResult)
  2109.         {
  2110.             hResult = pMessages->EnumElements (0, NULL, 0, &pEnum);
  2111.             if (!hResult)
  2112.             {
  2113.                 while (!hResult)
  2114.                 {
  2115.                     hResult = pEnum->Next (ELEMENTS_TO_FETCH, aStat, &ulMsgsFound);
  2116.                     if (FAILED(hResult)) // We might get S_FALSE
  2117.                     {
  2118.                         TraceResult ("CheckForPendingMailboxMsgs: Failed to ENUM streams", hResult);
  2119.                     }
  2120.                     else
  2121.                     {
  2122.                         if (ulMsgsFound)
  2123.                         {
  2124.                             dwTotal += ulMsgsFound;
  2125.                         }
  2126.                         pMalloc->Free (aStat[0].pwcsName);
  2127.                     }
  2128.                 }
  2129.                 pEnum->Release();
  2130.                 if (S_FALSE == hResult)
  2131.                 {
  2132.                     hResult = S_OK;
  2133.                     *pdwMsgCount = dwTotal;
  2134.                 }
  2135.             }
  2136.             pMessages->Release();
  2137.         }
  2138.         pMailbox->Release();
  2139.     }
  2140.     TraceResult ("CheckForPendingMailboxMsgs", hResult);
  2141.     return hResult;
  2142. }
  2143.  
  2144. ///////////////////////////////////////////////////////////////////////////////
  2145. //    GetNextMailboxMsg()
  2146. //
  2147. //    Parameters
  2148. //
  2149. //    Purpose
  2150. //
  2151. //    Return Value
  2152. //
  2153. HRESULT WINAPI GetNextMailboxMsg (LPSTORAGE pStorage,
  2154.                                   LPMALLOC  pMalloc,
  2155.                                   LPTSTR    szMailbox,
  2156.                                   DWORD *   pdwMsgID,
  2157.                                   HANDLE    hFile)
  2158. {
  2159.     WCHAR wcsMailbox[64] = { 0 };
  2160.     AnsiToUnicode (szMailbox, wcsMailbox, 64);
  2161.  
  2162.     BYTE abBuffer[IO_BUFFERSIZE];
  2163.     int nChars;
  2164.     char szObjName[64];
  2165.     LPSTR pSubStr;
  2166.     DWORD dwBytesWritten;
  2167.     ULONG ulMsgsFound = 0, ulBytesRead;
  2168.     LPENUMSTATSTG pEnum;
  2169.     STATSTG aStat[1];
  2170.     LPSTORAGE pMailbox, pMessages;
  2171.     LPSTREAM pOneMsg;
  2172.     HRESULT hResult = pStorage->OpenStorage (wcsMailbox, NULL, OPEN_FLAGS, NULL, 0, &pMailbox);
  2173.     if (!hResult)
  2174.     {
  2175.         hResult = pMailbox->OpenStorage (MSGS_STORAGE, NULL, OPEN_FLAGS, NULL, 0, &pMessages);
  2176.         if (!hResult)
  2177.         {
  2178.             hResult = pMessages->EnumElements (0, NULL, 0, &pEnum);
  2179.             if (!hResult)
  2180.             {
  2181.                 hResult = pEnum->Next (1, aStat, &ulMsgsFound);
  2182.                 if (FAILED(hResult)) // We might get S_FALSE
  2183.                 {
  2184.                     TraceResult ("GetNextMailboxMsg: Failed to ENUM streams", hResult);
  2185.                 }
  2186.                 else
  2187.                 {
  2188.                     if (ulMsgsFound)
  2189.                     {
  2190.                         ASSERT (STGTY_STREAM == aStat[0].type)
  2191.                         nChars = WideCharToMultiByte (CP_ACP,
  2192.                                                       0,
  2193.                                                       aStat[0].pwcsName,
  2194.                                                       -1,
  2195.                                                       szObjName,
  2196.                                                       64,
  2197.                                                       NULL,
  2198.                                                       NULL);
  2199.                         if (!nChars)
  2200.                         {
  2201.                             TraceResult ("GetNextMailboxMsg: Failed to convert storage name", HRESULT_FROM_WIN32(GetLastError()));
  2202.                         }
  2203.                         hResult = pMessages->OpenStream (aStat[0].pwcsName,
  2204.                                                          NULL,
  2205.                                                          OPEN_FLAGS,
  2206.                                                          0,
  2207.                                                          &pOneMsg);
  2208.                         if (!hResult)
  2209.                         {
  2210.                             do
  2211.                             {
  2212.                                 hResult = pOneMsg->Read (abBuffer, IO_BUFFERSIZE, &ulBytesRead);
  2213.                                 if (!hResult && ulBytesRead)
  2214.                                 {
  2215.                                     if (!WriteFile (hFile, abBuffer, ulBytesRead, &dwBytesWritten, NULL))
  2216.                                     {
  2217.                                         hResult = HRESULT_FROM_WIN32(GetLastError());
  2218.                                     }
  2219.                                 }
  2220.                             } while (!hResult && ulBytesRead);
  2221.                             pOneMsg->Release();
  2222.                         }
  2223.                         if (!hResult && nChars)
  2224.                         {
  2225.                             pSubStr = &(szObjName[lstrlenA (szObjName)]);
  2226.                             while (' ' != *pSubStr)
  2227.                             {
  2228.                                 pSubStr--;
  2229.                             }
  2230.                             pSubStr++;
  2231.                             sscanf (pSubStr, "%X", pdwMsgID);
  2232.                         }
  2233.                         pMalloc->Free (aStat[0].pwcsName);
  2234.                     }
  2235.                 }
  2236.                 pEnum->Release();
  2237.             }
  2238.             pMessages->Release();
  2239.         }
  2240.         pMailbox->Release();
  2241.     }
  2242.     #ifdef _DEBUG
  2243.     if (hResult && S_FALSE != hResult)
  2244.     {
  2245.         TraceResult ("GetNextMailboxMsg", hResult);
  2246.     }
  2247.     #endif // _DEBUG
  2248.  
  2249.     return hResult;
  2250. }
  2251.  
  2252. ///////////////////////////////////////////////////////////////////////////////
  2253. //    CreateGatewayQueues()
  2254. //
  2255. //    Parameters
  2256. //
  2257. //    Purpose
  2258. //
  2259. //    Return Value
  2260. //
  2261. HRESULT WINAPI CreateGatewayQueues (LPSTORAGE pStorage)
  2262. {
  2263.     LPSTORAGE pQueueStg;
  2264.     if (!pStorage->CreateStorage (GW_OUTBOX, CREATE_FLAGS, 0, 0, &pQueueStg))
  2265.     {
  2266.         pQueueStg->Release();
  2267.     }
  2268.     if (!pStorage->CreateStorage (GW_INBOX, CREATE_FLAGS, 0, 0, &pQueueStg))
  2269.     {
  2270.         pQueueStg->Release();
  2271.     }
  2272.     return S_OK;
  2273. }
  2274.  
  2275. ///////////////////////////////////////////////////////////////////////////////
  2276. //    CreateGatewayDirectories()
  2277. //
  2278. //    Parameters
  2279. //
  2280. //    Purpose
  2281. //
  2282. //    Return Value
  2283. //
  2284. HRESULT WINAPI CreateGatewayDirectories (LPSTORAGE pStorage)
  2285. {
  2286.     LPSTORAGE pDirsStg, pGatewaysStg;
  2287.     HRESULT hResult = pStorage->CreateStorage (FOREIGN_DIRECTORIES, CREATE_FLAGS, 0, 0, &pDirsStg);
  2288.     if (!hResult)
  2289.     {
  2290.         if (!pDirsStg->CreateStorage (EXCHANGE_GATEWAY, CREATE_FLAGS, 0, 0, &pGatewaysStg))
  2291.         {
  2292.             CreateGatewayQueues (pGatewaysStg);
  2293.             pGatewaysStg->Release();
  2294.         }
  2295.         if (!pDirsStg->CreateStorage (FAX_GATEWAY, CREATE_FLAGS, 0, 0, &pGatewaysStg))
  2296.         {
  2297.             CreateGatewayQueues (pGatewaysStg);
  2298.             pGatewaysStg->Release();
  2299.         }
  2300.         if (!pDirsStg->CreateStorage (SMTP_GATEWAY, CREATE_FLAGS, 0, 0, &pGatewaysStg))
  2301.         {
  2302.             CreateGatewayQueues (pGatewaysStg);
  2303.             pGatewaysStg->Release();
  2304.         }
  2305.         pDirsStg->Release();
  2306.     }
  2307.     return hResult;
  2308. }
  2309.  
  2310. // End of file for STORAGE.CPP
  2311.