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 / notify.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  15.1 KB  |  435 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  File Name 
  4. //      NOTIFY.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 <RPC.H>
  18. #include "WINDS.H"     // Header file generated by the MIDL compiler
  19.  
  20. typedef struct _WINDS_NOTIF_CLIENT
  21. {
  22.     struct _WINDS_NOTIF_CLIENT *    pNext;
  23.     TCHAR                           szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  24.     TCHAR                           szObjectName[MAX_ALIAS_SIZE+1];
  25.     DWORD                           dwFlags;
  26.     DWORD                           dwNotifMask;
  27. } WINDS_NOTIF_CLIENT, *PWINDS_NOTIF_CLIENT;
  28.  
  29. PWINDS_NOTIF_CLIENT gpNotifLinks = NULL;
  30.  
  31. ///////////////////////////////////////////////////////////////////////////////
  32. //    RemoteLogonMailBoxAndSetNotifA()
  33. //
  34. //    Parameters
  35. //
  36. //    Purpose
  37. //
  38. //    Return Value
  39. //
  40. long RemoteLogonMailBoxAndSetNotifA (unsigned char *    szMailbox,
  41.                                      unsigned char *    szPassword,
  42.                                      unsigned char *    szFullName,
  43.                                      unsigned long *    pdwMailboxID,
  44.                                      unsigned char *    szComputerName,
  45.                                      unsigned long      ulNotifMask,
  46.                                      unsigned long *    pulConnectionID)
  47. {
  48.     long lResult = RemoteLogonMailBoxA (szMailbox, szPassword, szFullName, pdwMailboxID);
  49.     if (lResult)
  50.     {
  51.         return lResult;
  52.     }
  53.     RemoteValidateNotifA (szComputerName, szMailbox, ulNotifMask, pulConnectionID);
  54.     return S_OK;
  55. }
  56.  
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //    RemoteValidateNotifA()
  59. //
  60. //    Parameters
  61. //
  62. //    Purpose
  63. //
  64. //    Return Value
  65. //
  66. long RemoteValidateNotifA (unsigned char *  szComputerName,
  67.                            unsigned char *  szMailbox,
  68.                            unsigned long    ulNotifMask,
  69.                            unsigned long *  pulConnectionID)
  70. {
  71.     long lResult = GetServiceState();
  72.     if (lResult)
  73.     {
  74.         return lResult;
  75.     }
  76.     PWINDS_NOTIF_CLIENT pNode, pNewNode = (PWINDS_NOTIF_CLIENT)HeapAlloc (ghHeap,
  77.                                                                           HEAP_ZERO_MEMORY,
  78.                                                                           sizeof(WINDS_NOTIF_CLIENT));
  79.     if (pNewNode)
  80.     {
  81.         pNewNode->dwNotifMask = ulNotifMask;
  82.         lstrcpy (pNewNode->szComputerName, (LPSTR)szComputerName);
  83.         lstrcpy (pNewNode->szObjectName, (LPSTR)szMailbox);
  84.         
  85.         EnterCriticalSection (&g_csNotifLinks);
  86.         if (gpNotifLinks)
  87.         {
  88.             pNode = gpNotifLinks;
  89.             while (pNode)
  90.             {
  91.                 if (NULL == pNode->pNext)
  92.                 {
  93.                     pNode->pNext = pNewNode;
  94.                     break; // Out of the WHILE() loop
  95.                 }
  96.                 pNode = pNode->pNext;
  97.             }
  98.         }
  99.         else
  100.         {
  101.             gpNotifLinks = pNewNode;
  102.         }
  103.         LeaveCriticalSection (&g_csNotifLinks);
  104.  
  105.         *pulConnectionID = (unsigned long)pNewNode;
  106.     }
  107.     TraceMessageIf ("RemoteValidateNotifA: Failed to allocated new node", 0 == *pulConnectionID);
  108.     return S_OK;
  109. }
  110.  
  111. ///////////////////////////////////////////////////////////////////////////////
  112. //    RemoteTerminateNotifA()
  113. //
  114. //    Parameters
  115. //
  116. //    Purpose
  117. //
  118. //    Return Value
  119. //
  120. long RemoteTerminateNotifA (unsigned char * szComputerName,
  121.                             unsigned long ulConnectionID)
  122. {
  123.     long lResult = GetServiceState();
  124.     if (lResult)
  125.     {
  126.         return lResult;
  127.     }
  128.  
  129.     long cbSize = lstrlen ((LPSTR)szComputerName);
  130.     EnterCriticalSection (&g_csNotifLinks);
  131.     PWINDS_NOTIF_CLIENT pNext, pPrev = NULL, pNode = gpNotifLinks;
  132.     while (pNode)
  133.     {
  134.         if (ulConnectionID == (unsigned long)pNode && (0 == memcmp (pNode->szComputerName, szComputerName, cbSize)))
  135.         {
  136.             // If the node is the head of the list, make the head point to the next node
  137.             if (gpNotifLinks == pNode)
  138.             {
  139.                 gpNotifLinks = gpNotifLinks->pNext;
  140.             }
  141.             // Save the next pointer so that we may delete the current node
  142.             pNext = pNode->pNext;
  143.             HeapFree (ghHeap, 0, pNode);
  144.             // If we have a previous node, we are doing a delete in the middle of a single link list
  145.             if (pPrev)
  146.             {
  147.                 pPrev->pNext = pNext;
  148.             }
  149.             break; // Out of the WHILE() loop
  150.         }
  151.         else
  152.         {
  153.             // Don't delete this node, save is as the "previous" node in the linear list
  154.             pPrev = pNode;
  155.             pNode = pNode->pNext;
  156.         }
  157.     }
  158.     LeaveCriticalSection (&g_csNotifLinks);
  159.     return S_OK;
  160. }
  161.  
  162. ///////////////////////////////////////////////////////////////////////////////
  163. //    RemoveAllNotifLinks()
  164. //
  165. //    Parameters
  166. //
  167. //    Purpose
  168. //
  169. //    Return Value
  170. //      None.
  171. //
  172. void WINAPI RemoveAllNotifLinks()
  173. {
  174.     EnterCriticalSection (&g_csNotifLinks);
  175.     PWINDS_NOTIF_CLIENT pNode = gpNotifLinks;
  176.     while (gpNotifLinks)
  177.     {
  178.         pNode = gpNotifLinks->pNext;
  179.         HeapFree (ghHeap, 0, gpNotifLinks);
  180.         gpNotifLinks = pNode;
  181.     }
  182.     gpNotifLinks = NULL;
  183.     LeaveCriticalSection (&g_csNotifLinks);
  184. }
  185.  
  186. ///////////////////////////////////////////////////////////////////////////////
  187. //    NotifyClients()
  188. //
  189. //    Parameters
  190. //
  191. //    Purpose
  192. //
  193. //    Return Value
  194. //      None.
  195. //
  196. void WINAPI NotifyClients (PWINDS_NOTIFICATION pNotif)
  197. {
  198.     DWORD dwThreadID;
  199.     HANDLE hThread = CreateThread (NULL,
  200.                                    0,
  201.                                    (LPTHREAD_START_ROUTINE)ClientNotifThreadProc,
  202.                                    (LPVOID)pNotif,
  203.                                    CREATE_SUSPENDED,
  204.                                    &dwThreadID);
  205.     if (hThread)
  206.     {
  207.         TraceDebugger ("NotifyClients: Notif dispatcher thread spawned. ID: %X", dwThreadID);
  208.         ResumeThread (hThread);
  209.         CloseHandle (hThread);
  210.     }
  211.     else
  212.     {
  213.         TraceResult ("NotifyClients: Failed to create notification dispatching thread", HRESULT_FROM_WIN32(GetLastError()));
  214.         HeapFree (ghHeap, 0, pNotif);
  215.     }
  216. }
  217.  
  218. ///////////////////////////////////////////////////////////////////////////////
  219. //    ClientNotifThreadProc()
  220. //
  221. //    Parameters
  222. //
  223. //    Purpose
  224. //
  225. //    Return Value
  226. //      None.
  227. //
  228. DWORD WINAPI ClientNotifThreadProc (PWINDS_NOTIFICATION pNotif)
  229. {
  230.     TCHAR szTargetMailslot[MAX_PATH] = { 0 };
  231.     DWORD dwWritten, dwNotifEvent = 0;
  232.     HANDLE hClientMailSlot;
  233.     LPTSTR szMailSlotSink = NULL;
  234.  
  235.     SYSTEMTIME st;
  236.     GetSystemTime (&st);
  237.     SystemTimeToFileTime (&st, &(pNotif->ftEventTime));
  238.  
  239.     if (pNotif->Event >= AB_NOTIF_MIN  && pNotif->Event <= AB_NOTIF_MAX)
  240.     {
  241.         dwNotifEvent = WINDS_NOTIF_ON_AB | WINDS_NOTIF_ON_USER;
  242.         szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
  243.     }
  244.     else
  245.     {
  246.         if (pNotif->Event >= XP_NOTIF_MIN  && pNotif->Event <= XP_NOTIF_MAX)
  247.         {
  248.             dwNotifEvent = WINDS_NOTIF_ON_XP;
  249.             szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
  250.         }
  251.         else
  252.         {
  253.             if (pNotif->Event >= MS_NOTIF_MIN  && pNotif->Event <= MS_NOTIF_MAX)
  254.             {
  255.                 dwNotifEvent = WINDS_NOTIF_ON_MS;
  256.                 szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
  257.             }
  258.             else
  259.             {
  260.                 if (pNotif->Event >= GENERAL_NOTIF_MIN  && pNotif->Event <= GENERAL_NOTIF_MAX)
  261.                 {
  262.                     dwNotifEvent = WINDS_NOTIF_ON_USER;
  263.                 }
  264.             }
  265.         }
  266.     }
  267.  
  268.     EnterCriticalSection (&g_csNotifLinks);
  269.     PWINDS_NOTIF_CLIENT pNode = gpNotifLinks;
  270.     while (pNode)
  271.     {
  272.         if (dwNotifEvent & pNode->dwNotifMask)
  273.         {
  274.             if (WINDS_NOTIF_ON_USER & dwNotifEvent)
  275.             {
  276.                 if (WINDS_NOTIF_ON_AB & pNode->dwNotifMask)
  277.                 {
  278.                     szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
  279.                 }
  280.                 else
  281.                 {
  282.                     if (WINDS_NOTIF_ON_XP & pNode->dwNotifMask)
  283.                     {
  284.                         szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
  285.                     }
  286.                     else
  287.                     {
  288.                         szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
  289.                     }
  290.                 }
  291.             }
  292.             if (WINDS_NOTIF_ON_XP == dwNotifEvent && XP_NEW_MAIL_ARRIVED == pNotif->Event)
  293.             {
  294.                 if (lstrcmpi (pNode->szObjectName, pNotif->Info.MB.szMailboxName))
  295.                 {
  296.                     goto NextNode;
  297.                 }
  298.             }
  299.             if (WINDS_ADMINISTRATOR & pNode->dwNotifMask)
  300.             {
  301.                 szMailSlotSink = ADMIN_WINDS_NOTIFICATION_MAILSLOT;
  302.             }
  303.             wsprintf (szTargetMailslot,
  304.                       SERVER_MAILSLOT_SINK_NAME_FORMAT,
  305.                       pNode->szComputerName,
  306.                       szMailSlotSink,
  307.                       pNode); // the connection number is the pointer address in the server side (this is unique within a given process)
  308.  
  309.             hClientMailSlot = CreateFile (szTargetMailslot,
  310.                                           GENERIC_WRITE,
  311.                                           FILE_SHARE_READ,
  312.                                           NULL,
  313.                                           OPEN_EXISTING,
  314.                                           FILE_ATTRIBUTE_NORMAL,
  315.                                           NULL); 
  316.             if (INVALID_HANDLE_VALUE == hClientMailSlot)
  317.             {
  318.                 TraceResult ("ClientNotifThreadProc: Failed to open client mailslot", HRESULT_FROM_WIN32(GetLastError()));
  319.             }
  320.             else
  321.             {
  322.                 if (!WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL))
  323.                 {
  324.                     TraceResult ("ClientNotifThreadProc: Failed to write to the client mailslot", HRESULT_FROM_WIN32(GetLastError()));
  325.                 }
  326.                 CloseHandle (hClientMailSlot); 
  327.             }
  328.         }
  329. NextNode:
  330.         pNode = pNode->pNext;
  331.     }
  332.  
  333. #define CLIENTS_NOTIF_CACHE_FILE    TEXT("WINDS Service - Last Session Clients.WINDS")
  334.     if (SERVER_IS_SHUTTING_DOWN == pNotif->Event && gpNotifLinks)
  335.     {
  336.         DWORD dwBytesWritten;
  337.         WINDS_NOTIF_CLIENT tmpNode;
  338.         HANDLE hFile = CreateFile (CLIENTS_NOTIF_CACHE_FILE,
  339.                                    GENERIC_WRITE,
  340.                                    0,
  341.                                    NULL,
  342.                                    CREATE_ALWAYS,
  343.                                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  344.                                    NULL);
  345.         if (INVALID_HANDLE_VALUE == hFile)
  346.         {
  347.             TraceResult ("ClientNotifThreadProc: Failed to create clients cache file", HRESULT_FROM_WIN32(GetLastError()));
  348.         }
  349.         else
  350.         {
  351.             pNode = gpNotifLinks;
  352.             while (pNode)
  353.             {
  354.                 tmpNode = *pNode;
  355.                 tmpNode.pNext = pNode;
  356.                 // This is so that the node address gets written to the disk. This is the
  357.                 // connection number and the name of the mailslot in the client side.
  358.                 WriteFile (hFile, &tmpNode, sizeof(WINDS_NOTIF_CLIENT), &dwBytesWritten, NULL);
  359.                 pNode = pNode->pNext;
  360.             }
  361.         }
  362.     }
  363.     if (SERVER_HAS_RESTARTED == pNotif->Event)
  364.     {
  365.         DWORD dwBytesRead;
  366.         WINDS_NOTIF_CLIENT tmpNode = { 0 };
  367.         HANDLE hFile = CreateFile (CLIENTS_NOTIF_CACHE_FILE,
  368.                                    GENERIC_READ,
  369.                                    0,
  370.                                    NULL,
  371.                                    OPEN_EXISTING,
  372.                                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_DELETE_ON_CLOSE,
  373.                                    NULL);
  374.         if (INVALID_HANDLE_VALUE != hFile)
  375.         {
  376.             do
  377.             {
  378.                 if (TRUE == ReadFile (hFile, &tmpNode, sizeof(WINDS_NOTIF_CLIENT), &dwBytesRead, NULL))
  379.                 {
  380.                     if (WINDS_NOTIF_ON_AB & tmpNode.dwNotifMask)
  381.                     {
  382.                         szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
  383.                     }
  384.                     else
  385.                     {
  386.                         if (WINDS_NOTIF_ON_XP & tmpNode.dwNotifMask)
  387.                         {
  388.                             szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
  389.                         }
  390.                         else
  391.                         {
  392.                             szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
  393.                         }
  394.                     }
  395.                     if (WINDS_ADMINISTRATOR & tmpNode.dwNotifMask)
  396.                     {
  397.                         szMailSlotSink = ADMIN_WINDS_NOTIFICATION_MAILSLOT;
  398.                     }
  399.                     wsprintf (szTargetMailslot,
  400.                               SERVER_MAILSLOT_SINK_NAME_FORMAT,
  401.                               tmpNode.szComputerName,
  402.                               szMailSlotSink,
  403.                               tmpNode.pNext); // The connection number is the pointer address in the server side (this is unique within a process address space)
  404.                     hClientMailSlot = CreateFile (szTargetMailslot,
  405.                                                   GENERIC_WRITE,
  406.                                                   FILE_SHARE_READ,
  407.                                                   NULL,
  408.                                                   OPEN_EXISTING,
  409.                                                   FILE_ATTRIBUTE_NORMAL,
  410.                                                   NULL); 
  411.                     if (INVALID_HANDLE_VALUE != hClientMailSlot)
  412.                     {
  413.                         pNotif->Event = SERVER_HAS_RESTARTED;
  414.                         pNotif->ftEventTime.dwLowDateTime++;
  415.                         pNotif->ftEventTime.dwHighDateTime++;
  416.                         WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL);
  417.                         pNotif->Event = RESET_LINKS_WITH_SERVER;
  418.                         pNotif->ftEventTime.dwLowDateTime++;
  419.                         pNotif->ftEventTime.dwHighDateTime++;
  420.                         WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL);
  421.                         CloseHandle (hClientMailSlot);
  422.                     }
  423.                 }
  424.             } while (dwBytesRead);
  425.             CloseHandle (hFile);
  426.         }
  427.     }
  428.  
  429.     LeaveCriticalSection (&g_csNotifLinks);
  430.     HeapFree (ghHeap, 0, pNotif);
  431.     return S_OK;
  432. }
  433.  
  434. // End of file for NOTIFY.CPP
  435.