You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
10 KiB
344 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Events.h
|
|
|
|
Abstract:
|
|
|
|
This file provides declaration of the service
|
|
notification mechanism.
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS) Jan, 2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _SERVER_EVENTS_H
|
|
#define _SERVER_EVENTS_H
|
|
|
|
#include <map>
|
|
#include <queue>
|
|
#include <algorithm>
|
|
#include <string>
|
|
|
|
#define STRSAFE_NO_DEPRECATE
|
|
#include <strsafe.h>
|
|
using namespace std;
|
|
#pragma hdrstop
|
|
|
|
#pragma warning (disable : 4786) // identifier was truncated to '255' characters in the debug information
|
|
// This pragma does not work KB ID: Q167355
|
|
|
|
#define MAX_EVENTS_THREADS 2
|
|
#define TOTAL_EVENTS_THREADS (MAX_EVENTS_THREADS * 2)
|
|
#define EVENT_COMPLETION_KEY 0x00000001
|
|
#define CLIENT_COMPLETION_KEY 0x00000002
|
|
#define CLIENT_OPEN_CONN_COMPLETION_KEY 0x00000003
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* CFaxEvent *
|
|
* *
|
|
************************************/
|
|
|
|
class CFaxEvent
|
|
{
|
|
public:
|
|
|
|
CFaxEvent() {}
|
|
virtual ~CFaxEvent() {}
|
|
virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const = 0;
|
|
virtual CFaxEvent* Clone() const = 0;
|
|
virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEventType, BOOL , BOOL bAllOutArchiveMessages) const = 0;
|
|
void RemoveOffendingExtendedJobStatus() {}
|
|
|
|
}; // CFaxEvent
|
|
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* CFaxEventExtended *
|
|
* *
|
|
************************************/
|
|
|
|
class CFaxEventExtended : public CFaxEvent
|
|
{
|
|
public:
|
|
|
|
CFaxEventExtended(const FAX_EVENT_EX* pEvent, DWORD dwEventSize, PSID pSid);
|
|
|
|
virtual ~CFaxEventExtended ()
|
|
{
|
|
MemFree ((void*)m_pEvent);
|
|
m_pEvent = NULL;
|
|
MemFree (m_pSid);
|
|
m_pSid = NULL;
|
|
m_dwEventSize = 0;
|
|
}
|
|
|
|
virtual CFaxEvent* Clone() const
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("CFaxEventExtended::Clone"));
|
|
CFaxEventExtended* pFaxExtendedEvent = NULL;
|
|
|
|
try
|
|
{
|
|
pFaxExtendedEvent = new (std::nothrow) CFaxEventExtended (m_pEvent, m_dwEventSize, m_pSid);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("Exception: %S"),
|
|
ex.what()
|
|
);
|
|
}
|
|
return pFaxExtendedEvent;
|
|
}
|
|
|
|
virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const;
|
|
|
|
void RemoveOffendingExtendedJobStatus();
|
|
|
|
virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEventType, BOOL bAllQueueMessages, BOOL bAllOutArchiveMessages) const;
|
|
|
|
|
|
private:
|
|
const FAX_EVENT_EX* m_pEvent;
|
|
DWORD m_dwEventSize;
|
|
PSID m_pSid; // Pointer to the SID associated with the event
|
|
}; // CFaxEventExtended
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* CFaxEventLegacy *
|
|
* *
|
|
************************************/
|
|
|
|
class CFaxEventLegacy : public CFaxEvent
|
|
{
|
|
public:
|
|
|
|
CFaxEventLegacy(const FAX_EVENT* pEvent);
|
|
|
|
virtual ~CFaxEventLegacy ()
|
|
{
|
|
MemFree ((void*)m_pEvent);
|
|
m_pEvent = NULL;
|
|
}
|
|
|
|
virtual CFaxEvent* Clone() const
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("CFaxEventLegacy::Clone"));
|
|
|
|
CFaxEventLegacy* pFaxLegacyEvent = NULL;
|
|
|
|
try
|
|
{
|
|
pFaxLegacyEvent = new (std::nothrow) CFaxEventLegacy (m_pEvent);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("Exception: %S"),
|
|
ex.what()
|
|
);
|
|
}
|
|
return pFaxLegacyEvent;
|
|
}
|
|
|
|
virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const;
|
|
|
|
virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEvenTtype, BOOL bAllQueueMessages, BOOL bAllOutArchiveMessages) const;
|
|
|
|
private:
|
|
const FAX_EVENT* m_pEvent;
|
|
}; // CFaxEventExtended
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* CClientID *
|
|
* *
|
|
************************************/
|
|
class CClientID
|
|
{
|
|
public:
|
|
CClientID (DWORDLONG dwlClientID, LPCWSTR lpcwstrMachineName, LPCWSTR lpcwstrEndPoint, ULONG64 Context)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert (lpcwstrMachineName && lpcwstrEndPoint && Context);
|
|
|
|
m_dwlClientID = dwlClientID;
|
|
hr = StringCchCopy (m_wstrMachineName, ARR_SIZE(m_wstrMachineName), lpcwstrMachineName);
|
|
if (FAILED(hr))
|
|
{
|
|
ASSERT_FALSE;
|
|
}
|
|
|
|
hr = StringCchCopy (m_wstrEndPoint, ARR_SIZE(m_wstrEndPoint), lpcwstrEndPoint);
|
|
if (FAILED(hr))
|
|
{
|
|
ASSERT_FALSE;
|
|
}
|
|
m_Context = Context;
|
|
}
|
|
|
|
CClientID (const CClientID& rhs)
|
|
{
|
|
m_dwlClientID = rhs.m_dwlClientID;
|
|
wcscpy (m_wstrMachineName, rhs.m_wstrMachineName);
|
|
wcscpy (m_wstrEndPoint, rhs.m_wstrEndPoint);
|
|
m_Context = rhs.m_Context;
|
|
}
|
|
|
|
~CClientID ()
|
|
{
|
|
ZeroMemory (this, sizeof(CClientID));
|
|
}
|
|
|
|
bool operator < ( const CClientID &other ) const;
|
|
|
|
CClientID& operator= (const CClientID& rhs)
|
|
{
|
|
if (this == &rhs)
|
|
{
|
|
return *this;
|
|
}
|
|
m_dwlClientID = rhs.m_dwlClientID;
|
|
wcscpy (m_wstrMachineName, rhs.m_wstrMachineName);
|
|
wcscpy (m_wstrEndPoint, rhs.m_wstrEndPoint);
|
|
m_Context = rhs.m_Context;
|
|
return *this;
|
|
}
|
|
|
|
ULONG64 GetContext() const { return m_Context; }
|
|
DWORDLONG GetID() const { return m_dwlClientID; }
|
|
|
|
private:
|
|
DWORDLONG m_dwlClientID;
|
|
WCHAR m_wstrMachineName[MAX_COMPUTERNAME_LENGTH + 1]; // Machine name
|
|
WCHAR m_wstrEndPoint[MAX_ENDPOINT_LEN]; // End point used for RPC connection
|
|
ULONG64 m_Context; // context (Client assync info)
|
|
|
|
}; // CClientID
|
|
|
|
|
|
|
|
typedef queue<CFaxEvent*> CLIENT_EVENTS, *PCLIENT_EVENTS;
|
|
|
|
/************************************
|
|
* *
|
|
* CClient *
|
|
* *
|
|
************************************/
|
|
class CClient
|
|
{
|
|
public:
|
|
CClient (CClientID ClientID,
|
|
PSID pUserSid,
|
|
DWORD dwEventTypes,
|
|
HANDLE hFaxHandle,
|
|
BOOL bAllQueueMessages,
|
|
BOOL bAllOutArchiveMessages,
|
|
DWORD dwAPIVersion);
|
|
|
|
CClient (const CClient& rhs);
|
|
|
|
~CClient ();
|
|
|
|
|
|
CClient& operator= (const CClient& rhs);
|
|
const CClientID& GetClientID () const { return m_ClientID; }
|
|
DWORD AddEvent (CFaxEvent* pFaxEvent);
|
|
DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize, PHANDLE phClientContext) const;
|
|
DWORD DelEvent ();
|
|
BOOL IsConnectionOpened() const { return (m_hFaxClientContext != NULL); }
|
|
VOID SetContextHandle(HANDLE hContextHandle) { m_hFaxClientContext = hContextHandle; }
|
|
HANDLE GetContextHandle () const { return m_hFaxClientContext; }
|
|
HANDLE GetFaxHandle() const { return m_FaxHandle; }
|
|
DWORD GetAPIVersion() const { return m_dwAPIVersion; }
|
|
BOOL IsLegacyClient() const { return (FAX_EVENT_TYPE_LEGACY == m_dwEventTypes); }
|
|
DWORD Release() { return (m_dwRefCount ? --m_dwRefCount : 1); } // There might be race between 2 or more threads trying to destroy the same client
|
|
VOID Lock() { m_dwRefCount++; }
|
|
DWORD GetRefCount()const { return m_dwRefCount; }
|
|
|
|
private:
|
|
HANDLE m_FaxHandle; // binding handle FaxBindToFaxClient
|
|
DWORD m_dwEventTypes; // Bit wise combination of FAX_ENUM_EVENT_TYPE
|
|
PSID m_pUserSid; // Pointer to the user SID
|
|
CLIENT_EVENTS m_Events;
|
|
HANDLE m_hFaxClientContext; // Client context handle
|
|
CClientID m_ClientID;
|
|
BOOL m_bPostClientID; // Flag that indicates whether to notify the service (using the events
|
|
// completion port) that this client has events.
|
|
BOOL m_bAllQueueMessages; // flag that indicates Outbox view rights.
|
|
BOOL m_bAllOutArchiveMessages; // flag that indicates Sent items view rights.
|
|
DWORD m_dwAPIVersion; // API version of the client
|
|
DWORD m_dwRefCount; // Handles the object refernce count
|
|
}; // CClient
|
|
|
|
typedef CClient *PCCLIENT;
|
|
|
|
|
|
/***********************************\
|
|
* *
|
|
* CClientsMap *
|
|
* *
|
|
\***********************************/
|
|
|
|
typedef map<CClientID, CClient> CLIENTS_MAP, *PCLIENTS_MAP;
|
|
|
|
//
|
|
// The CClientsMap class maps between client ID and a specific client
|
|
//
|
|
class CClientsMap
|
|
{
|
|
public:
|
|
CClientsMap () {}
|
|
~CClientsMap () {}
|
|
|
|
DWORD AddClient (const CClient& Client);
|
|
DWORD ReleaseClient (const CClientID& ClientID, BOOL fRunDown = FALSE);
|
|
PCCLIENT FindClient (const CClientID& ClientID) const;
|
|
DWORD AddEvent (CFaxEvent* pFaxEvent);
|
|
DWORD Notify (const CClientID& ClientID);
|
|
DWORD OpenClientConnection (const CClientID& ClientID);
|
|
|
|
private:
|
|
CLIENTS_MAP m_ClientsMap;
|
|
}; // CClientsMap
|
|
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* Externes *
|
|
* *
|
|
************************************/
|
|
|
|
extern CClientsMap* g_pClientsMap; // Map of clients ID to client.
|
|
extern HANDLE g_hDispatchEventsCompPort; // Events completion port. The events are dispatched to the client in the client map.
|
|
extern HANDLE g_hSendEventsCompPort; // Completion port of client IDs that have events in their queue.
|
|
//The events mechanism uses 2 completion ports.
|
|
// 1. g_hDispatchEventsCompPort, is monitored by 1 thread only!!!, and is responsible for dispatching the events to each one of the registered clients events queue. It is important that only 1 thread will dispatch the events, so the order of the events will be retained.
|
|
// 2. g_hSendEventsCompPort is monitored by TOTAL_EVENTS_THREADS, and is responsible for sending the events to the remote clients over RPC.
|
|
|
|
extern DWORDLONG g_dwlClientID; // Client ID
|
|
|
|
|
|
//
|
|
// IMPORTANT - No locking mechanism - USE g_CsClients to serialize calls to g_pClientsMap
|
|
//
|
|
|
|
#endif
|
|
|