home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //
- // File Name
- // NOTIFY.CPP
- //
- // Description
- //
- // Author
- // Irving De la Cruz
- //
- // Revision: 1.7
- //
- // Written for Microsoft Windows Developer Support
- // Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
- //
- #include "_WINDS.H"
- #include <RPC.H>
- #include "WINDS.H" // Header file generated by the MIDL compiler
-
- typedef struct _WINDS_NOTIF_CLIENT
- {
- struct _WINDS_NOTIF_CLIENT * pNext;
- TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
- TCHAR szObjectName[MAX_ALIAS_SIZE+1];
- DWORD dwFlags;
- DWORD dwNotifMask;
- } WINDS_NOTIF_CLIENT, *PWINDS_NOTIF_CLIENT;
-
- PWINDS_NOTIF_CLIENT gpNotifLinks = NULL;
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteLogonMailBoxAndSetNotifA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteLogonMailBoxAndSetNotifA (unsigned char * szMailbox,
- unsigned char * szPassword,
- unsigned char * szFullName,
- unsigned long * pdwMailboxID,
- unsigned char * szComputerName,
- unsigned long ulNotifMask,
- unsigned long * pulConnectionID)
- {
- long lResult = RemoteLogonMailBoxA (szMailbox, szPassword, szFullName, pdwMailboxID);
- if (lResult)
- {
- return lResult;
- }
- RemoteValidateNotifA (szComputerName, szMailbox, ulNotifMask, pulConnectionID);
- return S_OK;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteValidateNotifA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteValidateNotifA (unsigned char * szComputerName,
- unsigned char * szMailbox,
- unsigned long ulNotifMask,
- unsigned long * pulConnectionID)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
- PWINDS_NOTIF_CLIENT pNode, pNewNode = (PWINDS_NOTIF_CLIENT)HeapAlloc (ghHeap,
- HEAP_ZERO_MEMORY,
- sizeof(WINDS_NOTIF_CLIENT));
- if (pNewNode)
- {
- pNewNode->dwNotifMask = ulNotifMask;
- lstrcpy (pNewNode->szComputerName, (LPSTR)szComputerName);
- lstrcpy (pNewNode->szObjectName, (LPSTR)szMailbox);
-
- EnterCriticalSection (&g_csNotifLinks);
- if (gpNotifLinks)
- {
- pNode = gpNotifLinks;
- while (pNode)
- {
- if (NULL == pNode->pNext)
- {
- pNode->pNext = pNewNode;
- break; // Out of the WHILE() loop
- }
- pNode = pNode->pNext;
- }
- }
- else
- {
- gpNotifLinks = pNewNode;
- }
- LeaveCriticalSection (&g_csNotifLinks);
-
- *pulConnectionID = (unsigned long)pNewNode;
- }
- TraceMessageIf ("RemoteValidateNotifA: Failed to allocated new node", 0 == *pulConnectionID);
- return S_OK;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoteTerminateNotifA()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- //
- long RemoteTerminateNotifA (unsigned char * szComputerName,
- unsigned long ulConnectionID)
- {
- long lResult = GetServiceState();
- if (lResult)
- {
- return lResult;
- }
-
- long cbSize = lstrlen ((LPSTR)szComputerName);
- EnterCriticalSection (&g_csNotifLinks);
- PWINDS_NOTIF_CLIENT pNext, pPrev = NULL, pNode = gpNotifLinks;
- while (pNode)
- {
- if (ulConnectionID == (unsigned long)pNode && (0 == memcmp (pNode->szComputerName, szComputerName, cbSize)))
- {
- // If the node is the head of the list, make the head point to the next node
- if (gpNotifLinks == pNode)
- {
- gpNotifLinks = gpNotifLinks->pNext;
- }
- // Save the next pointer so that we may delete the current node
- pNext = pNode->pNext;
- HeapFree (ghHeap, 0, pNode);
- // If we have a previous node, we are doing a delete in the middle of a single link list
- if (pPrev)
- {
- pPrev->pNext = pNext;
- }
- break; // Out of the WHILE() loop
- }
- else
- {
- // Don't delete this node, save is as the "previous" node in the linear list
- pPrev = pNode;
- pNode = pNode->pNext;
- }
- }
- LeaveCriticalSection (&g_csNotifLinks);
- return S_OK;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // RemoveAllNotifLinks()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- // None.
- //
- void WINAPI RemoveAllNotifLinks()
- {
- EnterCriticalSection (&g_csNotifLinks);
- PWINDS_NOTIF_CLIENT pNode = gpNotifLinks;
- while (gpNotifLinks)
- {
- pNode = gpNotifLinks->pNext;
- HeapFree (ghHeap, 0, gpNotifLinks);
- gpNotifLinks = pNode;
- }
- gpNotifLinks = NULL;
- LeaveCriticalSection (&g_csNotifLinks);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // NotifyClients()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- // None.
- //
- void WINAPI NotifyClients (PWINDS_NOTIFICATION pNotif)
- {
- DWORD dwThreadID;
- HANDLE hThread = CreateThread (NULL,
- 0,
- (LPTHREAD_START_ROUTINE)ClientNotifThreadProc,
- (LPVOID)pNotif,
- CREATE_SUSPENDED,
- &dwThreadID);
- if (hThread)
- {
- TraceDebugger ("NotifyClients: Notif dispatcher thread spawned. ID: %X", dwThreadID);
- ResumeThread (hThread);
- CloseHandle (hThread);
- }
- else
- {
- TraceResult ("NotifyClients: Failed to create notification dispatching thread", HRESULT_FROM_WIN32(GetLastError()));
- HeapFree (ghHeap, 0, pNotif);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // ClientNotifThreadProc()
- //
- // Parameters
- //
- // Purpose
- //
- // Return Value
- // None.
- //
- DWORD WINAPI ClientNotifThreadProc (PWINDS_NOTIFICATION pNotif)
- {
- TCHAR szTargetMailslot[MAX_PATH] = { 0 };
- DWORD dwWritten, dwNotifEvent = 0;
- HANDLE hClientMailSlot;
- LPTSTR szMailSlotSink = NULL;
-
- SYSTEMTIME st;
- GetSystemTime (&st);
- SystemTimeToFileTime (&st, &(pNotif->ftEventTime));
-
- if (pNotif->Event >= AB_NOTIF_MIN && pNotif->Event <= AB_NOTIF_MAX)
- {
- dwNotifEvent = WINDS_NOTIF_ON_AB | WINDS_NOTIF_ON_USER;
- szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- if (pNotif->Event >= XP_NOTIF_MIN && pNotif->Event <= XP_NOTIF_MAX)
- {
- dwNotifEvent = WINDS_NOTIF_ON_XP;
- szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- if (pNotif->Event >= MS_NOTIF_MIN && pNotif->Event <= MS_NOTIF_MAX)
- {
- dwNotifEvent = WINDS_NOTIF_ON_MS;
- szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- if (pNotif->Event >= GENERAL_NOTIF_MIN && pNotif->Event <= GENERAL_NOTIF_MAX)
- {
- dwNotifEvent = WINDS_NOTIF_ON_USER;
- }
- }
- }
- }
-
- EnterCriticalSection (&g_csNotifLinks);
- PWINDS_NOTIF_CLIENT pNode = gpNotifLinks;
- while (pNode)
- {
- if (dwNotifEvent & pNode->dwNotifMask)
- {
- if (WINDS_NOTIF_ON_USER & dwNotifEvent)
- {
- if (WINDS_NOTIF_ON_AB & pNode->dwNotifMask)
- {
- szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- if (WINDS_NOTIF_ON_XP & pNode->dwNotifMask)
- {
- szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
- }
- }
- }
- if (WINDS_NOTIF_ON_XP == dwNotifEvent && XP_NEW_MAIL_ARRIVED == pNotif->Event)
- {
- if (lstrcmpi (pNode->szObjectName, pNotif->Info.MB.szMailboxName))
- {
- goto NextNode;
- }
- }
- if (WINDS_ADMINISTRATOR & pNode->dwNotifMask)
- {
- szMailSlotSink = ADMIN_WINDS_NOTIFICATION_MAILSLOT;
- }
- wsprintf (szTargetMailslot,
- SERVER_MAILSLOT_SINK_NAME_FORMAT,
- pNode->szComputerName,
- szMailSlotSink,
- pNode); // the connection number is the pointer address in the server side (this is unique within a given process)
-
- hClientMailSlot = CreateFile (szTargetMailslot,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (INVALID_HANDLE_VALUE == hClientMailSlot)
- {
- TraceResult ("ClientNotifThreadProc: Failed to open client mailslot", HRESULT_FROM_WIN32(GetLastError()));
- }
- else
- {
- if (!WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL))
- {
- TraceResult ("ClientNotifThreadProc: Failed to write to the client mailslot", HRESULT_FROM_WIN32(GetLastError()));
- }
- CloseHandle (hClientMailSlot);
- }
- }
- NextNode:
- pNode = pNode->pNext;
- }
-
- #define CLIENTS_NOTIF_CACHE_FILE TEXT("WINDS Service - Last Session Clients.WINDS")
- if (SERVER_IS_SHUTTING_DOWN == pNotif->Event && gpNotifLinks)
- {
- DWORD dwBytesWritten;
- WINDS_NOTIF_CLIENT tmpNode;
- HANDLE hFile = CreateFile (CLIENTS_NOTIF_CACHE_FILE,
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- {
- TraceResult ("ClientNotifThreadProc: Failed to create clients cache file", HRESULT_FROM_WIN32(GetLastError()));
- }
- else
- {
- pNode = gpNotifLinks;
- while (pNode)
- {
- tmpNode = *pNode;
- tmpNode.pNext = pNode;
- // This is so that the node address gets written to the disk. This is the
- // connection number and the name of the mailslot in the client side.
- WriteFile (hFile, &tmpNode, sizeof(WINDS_NOTIF_CLIENT), &dwBytesWritten, NULL);
- pNode = pNode->pNext;
- }
- }
- }
- if (SERVER_HAS_RESTARTED == pNotif->Event)
- {
- DWORD dwBytesRead;
- WINDS_NOTIF_CLIENT tmpNode = { 0 };
- HANDLE hFile = CreateFile (CLIENTS_NOTIF_CACHE_FILE,
- GENERIC_READ,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
- if (INVALID_HANDLE_VALUE != hFile)
- {
- do
- {
- if (TRUE == ReadFile (hFile, &tmpNode, sizeof(WINDS_NOTIF_CLIENT), &dwBytesRead, NULL))
- {
- if (WINDS_NOTIF_ON_AB & tmpNode.dwNotifMask)
- {
- szMailSlotSink = AB_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- if (WINDS_NOTIF_ON_XP & tmpNode.dwNotifMask)
- {
- szMailSlotSink = XP_WINDS_NOTIFICATION_MAILSLOT;
- }
- else
- {
- szMailSlotSink = MS_WINDS_NOTIFICATION_MAILSLOT;
- }
- }
- if (WINDS_ADMINISTRATOR & tmpNode.dwNotifMask)
- {
- szMailSlotSink = ADMIN_WINDS_NOTIFICATION_MAILSLOT;
- }
- wsprintf (szTargetMailslot,
- SERVER_MAILSLOT_SINK_NAME_FORMAT,
- tmpNode.szComputerName,
- szMailSlotSink,
- tmpNode.pNext); // The connection number is the pointer address in the server side (this is unique within a process address space)
- hClientMailSlot = CreateFile (szTargetMailslot,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (INVALID_HANDLE_VALUE != hClientMailSlot)
- {
- pNotif->Event = SERVER_HAS_RESTARTED;
- pNotif->ftEventTime.dwLowDateTime++;
- pNotif->ftEventTime.dwHighDateTime++;
- WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL);
- pNotif->Event = RESET_LINKS_WITH_SERVER;
- pNotif->ftEventTime.dwLowDateTime++;
- pNotif->ftEventTime.dwHighDateTime++;
- WriteFile (hClientMailSlot, pNotif, sizeof(WINDS_NOTIFICATION), &dwWritten, NULL);
- CloseHandle (hClientMailSlot);
- }
- }
- } while (dwBytesRead);
- CloseHandle (hFile);
- }
- }
-
- LeaveCriticalSection (&g_csNotifLinks);
- HeapFree (ghHeap, 0, pNotif);
- return S_OK;
- }
-
- // End of file for NOTIFY.CPP
-