mirror of https://github.com/lianthony/NT4.0
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.
1375 lines
26 KiB
1375 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wmsgsvr.hxx
|
|
|
|
Abstract:
|
|
|
|
Class definition for the server side of the WMSG (RPC on LPC) protocol
|
|
engine.
|
|
|
|
Author:
|
|
|
|
Steven Zeck (stevez) 12/17/91 (spcsvr.hxx)
|
|
|
|
Revision History:
|
|
|
|
16-Dec-1992 mikemon
|
|
|
|
Rewrote the majority of the code and added comments.
|
|
|
|
-- mazharm code fork from spcsvr.hxx
|
|
|
|
05/13/96 mazharm merged WMSG/LRPC into a common protocol
|
|
|
|
--*/
|
|
|
|
#ifndef __WMSG_HXX__
|
|
#define __WMSG_HXX__
|
|
|
|
class WMSG_ASSOCIATION;
|
|
class WMSG_SASSOCIATION;
|
|
class WMSG_CASSOCIATION;
|
|
class WMSG_ADDRESS;
|
|
class WMSG_SERVER ;
|
|
class MSG_CACHE ;
|
|
class WMSG_ENDPOINT ;
|
|
extern WMSG_SERVER *GlobalWMsgServer;
|
|
extern MSG_CACHE *MessageCache ;
|
|
RPC_STATUS
|
|
InitializeWMsg(
|
|
) ;
|
|
|
|
NEW_SDICT(WMSG_ASSOCIATION);
|
|
NEW_SDICT(WMSG_SCALL) ;
|
|
|
|
#define SEQUENCE_NUMBER_MASK 0xFFFFL
|
|
#define DICTIONARY_KEY_MASK 0xFFFF0000L
|
|
#define DICTIONARY_KEY_SHIFT (sizeof(unsigned short) * 8)
|
|
#define MSGCACHE_SIZE 25
|
|
#define WM_MSG_REQUEST WM_USER+330
|
|
#define WM_MSG_CALL_COMPLETE WM_USER+331
|
|
#define RPC_S_CALL_PENDING 21
|
|
|
|
#define DISPATCHSTATEINIT 0
|
|
#define DISPATCHDENIED 1
|
|
#define DISPATCHALLOWED 2
|
|
|
|
|
|
typedef struct {
|
|
BOOL IsValid ;
|
|
int Index ;
|
|
void *Association ;
|
|
WMSG_ENDPOINT *Endpoint ;
|
|
RPC_MESSAGE RpcMessage ;
|
|
RPC_RUNTIME_INFO RuntimeInfo ;
|
|
BOOL fSyncDispatch ;
|
|
} INFO ;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
WMSG_MESSAGE WMSGMessage ;
|
|
INFO Info ;
|
|
} MSGMEM ;
|
|
|
|
|
|
typedef struct
|
|
/*++
|
|
Description:
|
|
Each entry in the table of WMSG message
|
|
--*/
|
|
{
|
|
MSGMEM WMSGMem ;
|
|
long InUse ;
|
|
} MSGTAB ;
|
|
|
|
#define VALID_MESSAGE(_x_) (((MSGMEM *) _x_)->Info.IsValid)
|
|
|
|
|
|
class MSG_CACHE
|
|
/*++
|
|
Class Description:
|
|
Keeps a cache of WMSG messages. The messages are allocated by
|
|
either GetBuffer of ReceiveLotsa calls and are freed after a send
|
|
of by free buffer.
|
|
|
|
Fields:
|
|
|
|
--*/
|
|
{
|
|
private:
|
|
int LastEntry ;
|
|
MSGTAB MessageTable[MSGCACHE_SIZE] ;
|
|
WMSG_MESSAGE *AllocateFromHeap() ;
|
|
long MessageCount ; // debug code
|
|
|
|
public:
|
|
MSG_CACHE(
|
|
) ;
|
|
|
|
~MSG_CACHE() ;
|
|
|
|
WMSG_MESSAGE *AllocateMessage(
|
|
) ;
|
|
|
|
void FreeMessage(
|
|
WMSG_MESSAGE *WMSGMessage
|
|
) ;
|
|
} ;
|
|
|
|
|
|
class WMSG_ENDPOINT
|
|
{
|
|
public:
|
|
WMSG_ENDPOINT(
|
|
IN THREAD_IDENTIFIER Thistid,
|
|
IN THREAD *Thisthread,
|
|
HWND ThishWnd
|
|
) ;
|
|
|
|
THREAD *
|
|
InqThread(
|
|
) ;
|
|
|
|
HWND
|
|
InqhWnd(
|
|
) ;
|
|
|
|
void
|
|
StartListening(
|
|
) ;
|
|
|
|
void
|
|
StopListening(
|
|
) ;
|
|
|
|
int
|
|
ThreadListening(
|
|
) ;
|
|
|
|
void
|
|
BeginCall(
|
|
) ;
|
|
|
|
void
|
|
EndCall(
|
|
) ;
|
|
|
|
long callcount ;
|
|
|
|
private:
|
|
THREAD_IDENTIFIER tid ; // useful only when we are walking the list
|
|
THREAD *thread ;
|
|
HWND hWnd ;
|
|
int ListeningFlag ;
|
|
} ;
|
|
|
|
inline void
|
|
WMSG_ENDPOINT::BeginCall(
|
|
)
|
|
{
|
|
InterlockedIncrement(&callcount) ;
|
|
}
|
|
|
|
inline void
|
|
WMSG_ENDPOINT::EndCall(
|
|
)
|
|
{
|
|
InterlockedDecrement(&callcount) ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_ENDPOINT::StartListening(
|
|
)
|
|
{
|
|
ListeningFlag = 1 ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_ENDPOINT::StopListening(
|
|
)
|
|
{
|
|
ListeningFlag = 0 ;
|
|
}
|
|
|
|
|
|
inline int
|
|
WMSG_ENDPOINT::ThreadListening(
|
|
)
|
|
{
|
|
return ListeningFlag ;
|
|
}
|
|
|
|
|
|
inline
|
|
WMSG_ENDPOINT::WMSG_ENDPOINT(
|
|
IN THREAD_IDENTIFIER Thistid,
|
|
IN THREAD *Thisthread,
|
|
HWND ThishWnd
|
|
)
|
|
{
|
|
tid = Thistid ;
|
|
thread = Thisthread ;
|
|
hWnd = ThishWnd ;
|
|
callcount = 0;
|
|
}
|
|
|
|
|
|
inline THREAD *
|
|
WMSG_ENDPOINT::InqThread(
|
|
)
|
|
{
|
|
return thread ;
|
|
}
|
|
|
|
|
|
inline HWND
|
|
WMSG_ENDPOINT::InqhWnd(
|
|
)
|
|
{
|
|
return hWnd ;
|
|
}
|
|
|
|
NEW_SDICT2(WMSG_ENDPOINT, THREAD_IDENTIFIER) ;
|
|
class WMSG_ADDRESS;
|
|
typedef THREAD_IDENTIFIER (*POLEGETTID) (IN UUID *pUUID) ;
|
|
typedef LRESULT
|
|
(WINAPI *PDEFWINDOWPROC) (
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
typedef BOOL
|
|
(WINAPI *PPOSTMESSAGE)(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
typedef BOOL
|
|
(WINAPI *PPEEKMESSAGE)(
|
|
LPMSG lpMsg,
|
|
HWND hWnd ,
|
|
UINT wMsgFilterMin,
|
|
UINT wMsgFilterMax,
|
|
UINT wRemoveMsg);
|
|
typedef BOOL
|
|
(WINAPI *PTRANSLATEMESSAGE)(
|
|
CONST MSG *lpMsg);
|
|
typedef DWORD
|
|
(WINAPI *PMSGWAIT)(
|
|
DWORD nCount,
|
|
LPHANDLE pHandles,
|
|
BOOL fWaitAll,
|
|
DWORD dwMilliseconds,
|
|
DWORD dwWakeMask);
|
|
typedef LRESULT
|
|
(WINAPI *PSENDMESSAGE)(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
typedef LONG
|
|
(WINAPI *PDISPATCHMESSAGE)(
|
|
CONST MSG *lpMsg);
|
|
|
|
|
|
class WMSG_SERVER
|
|
{
|
|
public:
|
|
WMSG_SERVER(
|
|
IN OUT RPC_STATUS *RpcStatus
|
|
) ;
|
|
|
|
~WMSG_SERVER(
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
ActuallyInitializeWMsgServer(
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
ServerStartingToListen(
|
|
HWND hWnd
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
ServerStoppedListening(
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
GetThreadWindowHandle (
|
|
OUT HWND *WindowHandle
|
|
) ;
|
|
|
|
THREAD_IDENTIFIER
|
|
OleGetTid (
|
|
IN UUID *pUUID
|
|
) ;
|
|
|
|
THREAD_IDENTIFIER tid ;
|
|
|
|
LRESULT
|
|
DefWindowProcW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
BOOL
|
|
PostMessageW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
BOOL
|
|
PeekMessageW(
|
|
LPMSG lpMsg,
|
|
HWND hWnd ,
|
|
UINT wMsgFilterMin,
|
|
UINT wMsgFilterMax,
|
|
UINT wRemoveMsg);
|
|
|
|
BOOL
|
|
TranslateMessage(
|
|
CONST MSG *lpMsg);
|
|
|
|
DWORD
|
|
MsgWaitForMultipleObjects(
|
|
DWORD nCount,
|
|
LPHANDLE pHandles,
|
|
BOOL fWaitAll,
|
|
DWORD dwMilliseconds,
|
|
DWORD dwWakeMask);
|
|
|
|
LRESULT
|
|
SendMessageW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
LONG
|
|
DispatchMessageW(
|
|
CONST MSG *lpMsg);
|
|
|
|
WMSG_ENDPOINT *GetEndpoint(
|
|
THREAD_IDENTIFIER tid
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
SetWMsgEndpoint(
|
|
IN RPC_CHAR *Endpoint
|
|
) ;
|
|
|
|
void
|
|
GetWMsgEndpoint(
|
|
IN RPC_CHAR *Endpoint
|
|
) ;
|
|
|
|
int
|
|
IsWMsgEndpointInitialized(
|
|
) ;
|
|
|
|
int ActuallyInitialized ;
|
|
|
|
void AcquireMutex(
|
|
) ;
|
|
|
|
void ReleaseMutex(
|
|
) ;
|
|
|
|
void
|
|
SetOleCallback(
|
|
IN POLEGETTID pfnCallback
|
|
) ;
|
|
|
|
private:
|
|
WMSG_ENDPOINT_DICT2 WMsgEndpointDict ;
|
|
WMSG_ADDRESS *Address ;
|
|
HINSTANCE hOle32 ;
|
|
POLEGETTID pOleGetTid ;
|
|
HINSTANCE hUser32 ;
|
|
RPC_CHAR PAPI * WMsgEndpoint;
|
|
BOOL wmsgEndpointInitialized ;
|
|
MUTEX ServerMutex ;
|
|
|
|
PDEFWINDOWPROC pDefWindowProc ;
|
|
PPOSTMESSAGE pPostMessage ;
|
|
PPEEKMESSAGE pPeekMessage ;
|
|
PTRANSLATEMESSAGE pTranslateMessage ;
|
|
PMSGWAIT pMsgWaitForMultipleObjects ;
|
|
PSENDMESSAGE pSendMessage ;
|
|
PDISPATCHMESSAGE pDispatchMessage ;
|
|
} ;
|
|
|
|
|
|
inline void
|
|
WMSG_SERVER::SetOleCallback (
|
|
IN POLEGETTID pfnCallback
|
|
)
|
|
{
|
|
pOleGetTid = pfnCallback ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_SERVER::AcquireMutex(
|
|
)
|
|
{
|
|
ServerMutex.Request() ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_SERVER::ReleaseMutex(
|
|
)
|
|
{
|
|
ServerMutex.Clear() ;
|
|
}
|
|
|
|
|
|
inline int
|
|
WMSG_SERVER::IsWMsgEndpointInitialized(
|
|
)
|
|
{
|
|
return wmsgEndpointInitialized ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_SERVER::GetWMsgEndpoint(
|
|
IN RPC_CHAR *Endpoint)
|
|
{
|
|
RpcpStringCopy(Endpoint, WMsgEndpoint) ;
|
|
}
|
|
|
|
inline RPC_STATUS
|
|
WMSG_SERVER::SetWMsgEndpoint(
|
|
IN RPC_CHAR *Endpoint
|
|
)
|
|
{
|
|
WMsgEndpoint = DuplicateString(Endpoint) ;
|
|
if (WMsgEndpoint == 0)
|
|
{
|
|
return RPC_S_OUT_OF_MEMORY ;
|
|
}
|
|
|
|
wmsgEndpointInitialized = 1 ;
|
|
return RPC_S_OK ;
|
|
}
|
|
|
|
inline THREAD_IDENTIFIER
|
|
WMSG_SERVER::OleGetTid (
|
|
IN UUID *pUUID
|
|
)
|
|
{
|
|
return (*pOleGetTid) (pUUID) ;
|
|
}
|
|
|
|
inline LRESULT
|
|
WMSG_SERVER::DefWindowProcW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return (*pDefWindowProc)(hWnd, Msg, wParam, lParam) ;
|
|
}
|
|
|
|
inline BOOL
|
|
WMSG_SERVER::PostMessageW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return (*pPostMessage)(hWnd, Msg, wParam, lParam) ;
|
|
}
|
|
|
|
inline BOOL
|
|
WMSG_SERVER::PeekMessageW(
|
|
LPMSG lpMsg,
|
|
HWND hWnd ,
|
|
UINT wMsgFilterMin,
|
|
UINT wMsgFilterMax,
|
|
UINT wRemoveMsg)
|
|
{
|
|
return (*pPeekMessage)(lpMsg, hWnd, wMsgFilterMin,
|
|
wMsgFilterMax, wRemoveMsg) ;
|
|
}
|
|
|
|
inline BOOL
|
|
WMSG_SERVER::TranslateMessage(
|
|
CONST MSG *lpMsg)
|
|
{
|
|
return (*pTranslateMessage)(lpMsg) ;
|
|
}
|
|
|
|
inline DWORD
|
|
WMSG_SERVER::MsgWaitForMultipleObjects(
|
|
DWORD nCount,
|
|
LPHANDLE pHandles,
|
|
BOOL fWaitAll,
|
|
DWORD dwMilliseconds,
|
|
DWORD dwWakeMask)
|
|
{
|
|
return (*pMsgWaitForMultipleObjects)(nCount, pHandles, fWaitAll,
|
|
dwMilliseconds, dwWakeMask) ;
|
|
}
|
|
|
|
inline LRESULT
|
|
WMSG_SERVER::SendMessageW(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return (*pSendMessage)(hWnd, Msg, wParam, lParam) ;
|
|
}
|
|
|
|
inline LONG
|
|
WMSG_SERVER::DispatchMessageW(
|
|
CONST MSG *lpMsg)
|
|
{
|
|
return (*pDispatchMessage)(lpMsg) ;
|
|
}
|
|
|
|
|
|
inline WMSG_ENDPOINT *
|
|
WMSG_SERVER::GetEndpoint(
|
|
THREAD_IDENTIFIER tid
|
|
)
|
|
{
|
|
return WMsgEndpointDict.Find(tid) ;
|
|
}
|
|
|
|
|
|
inline RPC_STATUS
|
|
WMSG_SERVER::GetThreadWindowHandle (
|
|
OUT HWND *WindowHandle
|
|
)
|
|
{
|
|
THREAD_IDENTIFIER tid ;
|
|
WMSG_ENDPOINT *Endpoint ;
|
|
|
|
// get thread id
|
|
tid = GetThreadIdentifier() ;
|
|
|
|
// lookup entry using threadid
|
|
Endpoint = WMsgEndpointDict.Find(tid) ;
|
|
if (Endpoint == 0)
|
|
{
|
|
return (RPC_S_OUT_OF_MEMORY) ;
|
|
}
|
|
|
|
*WindowHandle = Endpoint->InqhWnd() ;
|
|
|
|
return (RPC_S_OK) ;
|
|
}
|
|
|
|
|
|
class WMSG_ADDRESS : public RPC_ADDRESS
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Fields:
|
|
|
|
LpcAddressPort - Contains the connection port which this address will
|
|
use to wait for clients to connect.
|
|
|
|
CallThreadCount - Contains the number of call threads we have executing.
|
|
|
|
MinimumCallThreads - Contains the minimum number of call threads.
|
|
|
|
ServerListeningFlag - Contains a flag indicating whether or not the server
|
|
is listening for remote procedure calls. A non-zero value indicates
|
|
that it is listening.
|
|
|
|
ActiveCallCount - Contains the number of remote procedure calls active
|
|
on this address.
|
|
|
|
AssociationDictionary - Contains the dictionary of associations on this
|
|
address. We need this to map from an association key into the
|
|
correct association. This is necessary to prevent a race condition
|
|
between deleting an association and using it.
|
|
|
|
--*/
|
|
{
|
|
private:
|
|
|
|
HANDLE LpcAddressPort;
|
|
unsigned int CallThreadCount;
|
|
unsigned int MinimumCallThreads;
|
|
unsigned int ServerListeningFlag ;
|
|
WMSG_ASSOCIATION_DICT AssociationDictionary;
|
|
BOOL fSpareThread ;
|
|
int AssociationCount ;
|
|
int WMSGCallCount ;
|
|
|
|
public:
|
|
|
|
WMSG_ADDRESS (
|
|
OUT RPC_STATUS * RpcStatus
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
FireUpManager (
|
|
IN unsigned int MinimumConcurrentCalls
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
ServerStartingToListen (
|
|
IN unsigned int MinimumCallThreads,
|
|
IN unsigned int MaximumConcurrentCalls,
|
|
IN int ServerThreadsStarted
|
|
);
|
|
|
|
virtual void
|
|
ServerStoppedListening (
|
|
);
|
|
|
|
virtual unsigned int
|
|
InqNumberOfActiveCalls (
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
SetupAddressWithEndpoint (
|
|
IN RPC_CHAR PAPI * Endpoint,
|
|
OUT RPC_CHAR PAPI * PAPI * NetworkAddress,
|
|
OUT unsigned int PAPI * NumNetworkAddress,
|
|
IN void PAPI * SecurityDescriptor, OPTIONAL
|
|
IN unsigned int PendingQueueSize,
|
|
IN RPC_CHAR PAPI * RpcProtocolSequence,
|
|
IN unsigned long EndpointFlags,
|
|
IN unsigned long NICFlags
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
SetupAddressUnknownEndpoint (
|
|
OUT RPC_CHAR PAPI * PAPI * Endpoint,
|
|
OUT RPC_CHAR PAPI * PAPI * NetworkAddress,
|
|
OUT unsigned int PAPI * NumNetworkAddress,
|
|
IN void PAPI * SecurityDescriptor, OPTIONAL
|
|
IN unsigned int PendingQueueSize,
|
|
IN RPC_CHAR PAPI * RpcProtocolSequence,
|
|
IN unsigned long EndpointFlags,
|
|
IN unsigned long NICFlags
|
|
);
|
|
|
|
inline void
|
|
DereferenceAssociation (
|
|
IN WMSG_SASSOCIATION * Association
|
|
);
|
|
|
|
friend void
|
|
RecvLotsaCallsWrapper(
|
|
IN WMSG_ADDRESS PAPI * Address
|
|
);
|
|
|
|
int
|
|
InitializeWMsg(
|
|
) ;
|
|
|
|
void
|
|
HandleRequest (
|
|
IN WMSG_MESSAGE *WMSGMessage,
|
|
IN WMSG_SASSOCIATION * Association,
|
|
IN RPC_MESSAGE *RpcMessage,
|
|
IN WMSG_ENDPOINT *Endpoint,
|
|
IN BOOL fSyncDispatch
|
|
) ;
|
|
|
|
void
|
|
WaitForCalls(
|
|
) ;
|
|
|
|
void
|
|
DeleteCAssoc(
|
|
unsigned short DictionaryKey
|
|
) ;
|
|
|
|
private:
|
|
|
|
inline WMSG_ASSOCIATION *
|
|
ReferenceAssociation (
|
|
IN unsigned long AssociationKey,
|
|
OUT int *AssociationType
|
|
);
|
|
|
|
void
|
|
ReceiveLotsaCalls (
|
|
);
|
|
|
|
void
|
|
DealWithNewClient (
|
|
IN WMSG_MESSAGE * ConnectionRequest
|
|
);
|
|
|
|
void
|
|
DealWithConnectResponse (
|
|
IN WMSG_MESSAGE * ConnectResponse
|
|
) ;
|
|
|
|
void
|
|
RejectNewClient (
|
|
IN WMSG_MESSAGE * ConnectionRequest,
|
|
IN RPC_STATUS RpcStatus
|
|
);
|
|
|
|
BOOL
|
|
DealWithWMSGRequest (
|
|
IN WMSG_MESSAGE *WMSGMessage,
|
|
IN WMSG_ENDPOINT **Endpoint,
|
|
IN HWND *hWndEndpoint,
|
|
IN WMSG_ASSOCIATION *Association,
|
|
IN OUT WMSG_MESSAGE **WMSGReplyMessage
|
|
) ;
|
|
|
|
inline WMSG_MESSAGE *
|
|
DealWithLRPCRequest (
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
IN WMSG_MESSAGE * WMSGReplyMessage,
|
|
IN BOOL Partial,
|
|
IN WMSG_ASSOCIATION *Association
|
|
) ;
|
|
};
|
|
|
|
inline void
|
|
WMSG_ADDRESS::DeleteCAssoc(
|
|
unsigned short DictionaryKey
|
|
)
|
|
{
|
|
RequestGlobalMutex() ;
|
|
AssociationDictionary.Delete(DictionaryKey - 1) ;
|
|
ClearGlobalMutex() ;
|
|
}
|
|
|
|
|
|
class WMSG_SBINDING
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Each object of this class represents a binding to an interface by a
|
|
client.
|
|
|
|
Fields:
|
|
|
|
RpcInterface - Contains a pointer to the bound interface.
|
|
|
|
PresentationContext - Contains the key which the client will send when
|
|
it wants to use this binding.
|
|
|
|
--*/
|
|
{
|
|
friend class WMSG_SASSOCIATION;
|
|
friend class WMSG_SCALL;
|
|
friend class WMSG_ADDRESS;
|
|
|
|
private:
|
|
|
|
RPC_INTERFACE * RpcInterface;
|
|
unsigned char PresentationContext;
|
|
RPC_SYNTAX_IDENTIFIER TransferSyntax;
|
|
unsigned long SecurityCalloutState;
|
|
unsigned long SequenceNumber ;
|
|
|
|
public:
|
|
|
|
WMSG_SBINDING (
|
|
IN RPC_INTERFACE * RpcInterface,
|
|
IN RPC_SYNTAX_IDENTIFIER * TransferSyntax
|
|
);
|
|
|
|
inline RPC_STATUS
|
|
CheckSecurity (
|
|
SCONNECTION * Context
|
|
);
|
|
};
|
|
|
|
|
|
inline
|
|
WMSG_SBINDING::WMSG_SBINDING (
|
|
IN RPC_INTERFACE * RpcInterface,
|
|
IN RPC_SYNTAX_IDENTIFIER * TransferSyntax
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
We will construct a WMSG_SBINDING.
|
|
|
|
Arguments:
|
|
|
|
RpcInterface - Supplies the bound interface.
|
|
|
|
TransferSyntax - Supplies the transfer syntax which the client will use
|
|
over this binding.
|
|
|
|
--*/
|
|
{
|
|
this->RpcInterface = RpcInterface;
|
|
this->TransferSyntax = *TransferSyntax;
|
|
SecurityCalloutState = DISPATCHSTATEINIT;
|
|
SequenceNumber = 0;
|
|
}
|
|
|
|
inline RPC_STATUS
|
|
WMSG_SBINDING::CheckSecurity (
|
|
SCONNECTION * Context
|
|
)
|
|
{
|
|
if ( (RpcInterface->SequenceNumber == SequenceNumber)
|
|
|| (RpcInterface->IsSecurityCallbackReqd() == 0))
|
|
{
|
|
return (RPC_S_OK);
|
|
}
|
|
|
|
if (SecurityCalloutState == DISPATCHDENIED)
|
|
{
|
|
return (RPC_S_ACCESS_DENIED);
|
|
}
|
|
if (RpcInterface->CheckSecurityIfNecessary(Context) == RPC_S_OK)
|
|
{
|
|
// BUGBUG: race condition here...
|
|
SequenceNumber = RpcInterface->SequenceNumber ;
|
|
SecurityCalloutState = DISPATCHALLOWED;
|
|
return (RPC_S_OK);
|
|
}
|
|
else
|
|
{
|
|
SequenceNumber = 0;
|
|
SecurityCalloutState = DISPATCHDENIED;
|
|
}
|
|
return (RPC_S_ACCESS_DENIED);
|
|
}
|
|
|
|
typedef void * WMSG_BUFFER;
|
|
|
|
NEW_SDICT(WMSG_SBINDING);
|
|
NEW_SDICT(WMSG_CLIENT_BUFFER);
|
|
|
|
#define ASSOCIATION_TYPE_CLIENT 1
|
|
#define ASSOCIATION_TYPE_SERVER 2
|
|
|
|
// BUGBUG: changed from a virtual function to a public value for
|
|
// the association type. this was done to improve performance
|
|
// however, now we are very sensitive to memory layout of the object
|
|
// a the first sign of trouble, we'll revert.
|
|
|
|
class WMSG_ASSOCIATION
|
|
{
|
|
friend class WMSG_ADDRESS;
|
|
friend class WMSG_CASSOCIATION ;
|
|
public:
|
|
int AssociationType ;
|
|
|
|
private:
|
|
unsigned short DictionaryKey;
|
|
} ;
|
|
|
|
#define USER_NAME_LEN 256
|
|
#define DOMAIN_NAME_LEN 128
|
|
|
|
|
|
|
|
class WMSG_SASSOCIATION : public WMSG_ASSOCIATION, ASSOCIATION_HANDLE
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
|
|
Fields:
|
|
|
|
LpcServerPort - Contains the LPC server communication port.
|
|
|
|
Bindings - Contains the dictionary of bindings with the client. This
|
|
information is necessary to dispatch remote procedure calls to the
|
|
correct stub.
|
|
|
|
Address - Contains the address which this association is over.
|
|
|
|
AssociationReferenceCount - Contains a count of the number of objects
|
|
referencing this association. This will be the number of outstanding
|
|
remote procedure calls, and one for LPC (because of the context
|
|
pointer). We will protect this fielding using the global mutex.
|
|
|
|
Buffers - Contains the dictionary of buffers to be written into the
|
|
client's address space on demand.
|
|
|
|
AssociationKey - Contains the key for this association in the dictionary
|
|
of associations maintained by the address.
|
|
|
|
--*/
|
|
{
|
|
friend class WMSG_ADDRESS;
|
|
friend class WMSG_SCALL;
|
|
|
|
private:
|
|
|
|
HANDLE LpcServerPort;
|
|
HANDLE LpcClientPort ;
|
|
WMSG_SBINDING_DICT Bindings;
|
|
WMSG_ADDRESS * Address;
|
|
unsigned int AssociationReferenceCount;
|
|
unsigned short SequenceNumber;
|
|
int Aborted ;
|
|
long Deleted ;
|
|
HANDLE TokenHandle ;
|
|
RPC_CHAR *UserName ;
|
|
WMSG_CLIENT_BUFFER_DICT Buffers ;
|
|
BOOL OpenThreadTokenFailed ;
|
|
|
|
public:
|
|
WMSG_SCALL_DICT SCallDict ;
|
|
|
|
WMSG_SASSOCIATION (
|
|
IN WMSG_ADDRESS * Address,
|
|
IN RPC_STATUS *RpcStatus
|
|
);
|
|
|
|
~WMSG_SASSOCIATION (
|
|
);
|
|
|
|
RPC_STATUS
|
|
AddBinding (
|
|
IN OUT WMSG_BIND_EXCHANGE * BindExchange
|
|
);
|
|
|
|
void
|
|
DealWithBindMessage (
|
|
IN WMSG_MESSAGE * WMSGMessage
|
|
);
|
|
|
|
void
|
|
DealWithRequestMessage (
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
IN OUT WMSG_MESSAGE *WMSGReply,
|
|
IN RPC_MESSAGE *RpcMessage,
|
|
IN WMSG_SBINDING **SBinding,
|
|
IN unsigned int Flags,
|
|
IN BOOL IsWMsg,
|
|
IN BOOL fSyncClient
|
|
);
|
|
|
|
void
|
|
DealWithCloseMessage (
|
|
);
|
|
|
|
WMSG_MESSAGE *
|
|
DealWithCopyMessage (
|
|
IN WMSG_COPY_MESSAGE * WMSGMessage
|
|
) ;
|
|
|
|
inline RPC_STATUS
|
|
WMSGMessageToRpcMessage (
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
OUT RPC_MESSAGE * RpcMessage,
|
|
IN OUT int *size = 0,
|
|
IN unsigned long Extra = 0,
|
|
IN WMSG_SCALL *SCall = 0
|
|
) ;
|
|
|
|
NTSTATUS
|
|
ReplyMessage (
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
IN int Flags
|
|
) ;
|
|
|
|
WMSG_ADDRESS *
|
|
InqAddress(
|
|
) ;
|
|
|
|
inline void
|
|
AbortAssociation(
|
|
) ;
|
|
|
|
inline int
|
|
IsAborted(
|
|
) ;
|
|
|
|
inline HANDLE
|
|
GetToken (
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
SaveToken (
|
|
IN WMSG_MESSAGE *WMSGMessage
|
|
) ;
|
|
|
|
WMSG_MESSAGE *
|
|
DealWithBindBackMessage (
|
|
IN WMSG_MESSAGE *BindBack
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
BindBack (
|
|
IN RPC_CHAR *Endpoint,
|
|
IN PVOID pAssoc
|
|
) ;
|
|
|
|
WMSG_MESSAGE *
|
|
DealWithPipeRequest (
|
|
IN WMSG_MESSAGE *WMSGMessage
|
|
) ;
|
|
|
|
inline void
|
|
MaybeDereference (
|
|
) ;
|
|
|
|
void
|
|
Delete(
|
|
) ;
|
|
};
|
|
|
|
inline HANDLE
|
|
WMSG_SASSOCIATION::GetToken (
|
|
)
|
|
{
|
|
return TokenHandle ;
|
|
}
|
|
|
|
|
|
inline void
|
|
WMSG_SASSOCIATION::AbortAssociation (
|
|
)
|
|
{
|
|
Aborted = 1 ;
|
|
}
|
|
|
|
inline int
|
|
WMSG_SASSOCIATION::IsAborted(
|
|
)
|
|
{
|
|
return Aborted ;
|
|
}
|
|
|
|
inline void
|
|
WMSG_SASSOCIATION::MaybeDereference (
|
|
)
|
|
{
|
|
if (Aborted)
|
|
{
|
|
Delete() ;
|
|
}
|
|
}
|
|
|
|
|
|
inline WMSG_ADDRESS *
|
|
WMSG_SASSOCIATION::InqAddress(
|
|
)
|
|
{
|
|
return Address ;
|
|
}
|
|
|
|
|
|
class WMSG_SCALL : public SCONNECTION
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Fields:
|
|
|
|
Association - Contains the association over which the remote procedure
|
|
call was received. We need this information to make callbacks and
|
|
to send the reply.
|
|
|
|
WMSGMessage - Contains the request message. We need this to send callbacks
|
|
as well as the reply.
|
|
|
|
SBinding - Contains the binding being used for this remote procedure call.
|
|
|
|
ObjectUuidFlag - Contains a flag indicting whether or not an object
|
|
uuid was specified for this remote procedure call. A non-zero
|
|
value indicates that an object uuid was specified.
|
|
|
|
ObjectUuid - Optionally contains the object uuid for this call, if one
|
|
was specified.
|
|
|
|
ClientId - Contains the thread identifier of the thread which made the
|
|
remote procedure call.
|
|
|
|
MessageId - Contains an identifier used by LPC to identify the current
|
|
remote procedure call.
|
|
|
|
DataInfoOffset - Contains an identifier used by LPC to identify the offset
|
|
to PORT_DATA_INFORMATION in the current message if any.
|
|
|
|
PushedResponse - When the client needs to send a large response to the
|
|
server it must be transfered via a request. This holds the pushed
|
|
response until the request gets here.
|
|
|
|
--*/
|
|
{
|
|
friend class WMSG_SASSOCIATION;
|
|
private:
|
|
|
|
WMSG_SASSOCIATION * Association;
|
|
WMSG_MESSAGE * WMSGRequestMessage;
|
|
WMSG_MESSAGE * WMSGReplyMessage;
|
|
WMSG_SBINDING * SBinding;
|
|
unsigned int ObjectUuidFlag;
|
|
RPC_UUID ObjectUuid;
|
|
int SCallDictKey;
|
|
CLIENT_ID ClientId;
|
|
ULONG MessageId;
|
|
CSHORT DataInfoOffset;
|
|
ULONG CallbackId;
|
|
void * PushedResponse;
|
|
unsigned int CurrentBufferLength ;
|
|
int BufferComplete ;
|
|
unsigned int Flags ;
|
|
int fSyncClient ;
|
|
WMSG_MESSAGE *PipeMessage ;
|
|
HANDLE PipeEvent ;
|
|
int ConnectionKey ;
|
|
int FirstSend ;
|
|
int PipeSendCalled ;
|
|
int Deleted ;
|
|
|
|
public:
|
|
|
|
inline
|
|
WMSG_SCALL (
|
|
IN WMSG_SASSOCIATION * Association,
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
IN WMSG_MESSAGE * WMSGReplyMessage,
|
|
IN unsigned int Flags,
|
|
IN int fSyncClient
|
|
);
|
|
|
|
inline
|
|
~WMSG_SCALL (
|
|
) ;
|
|
|
|
virtual RPC_STATUS
|
|
GetBuffer (
|
|
IN OUT PRPC_MESSAGE Message
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
SendReceive (
|
|
IN OUT PRPC_MESSAGE Message
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
Send (
|
|
IN OUT PRPC_MESSAGE Messsage
|
|
) ;
|
|
|
|
virtual RPC_STATUS
|
|
Receive (
|
|
IN PRPC_MESSAGE Message,
|
|
IN unsigned int Size
|
|
) ;
|
|
|
|
virtual void
|
|
FreeBuffer (
|
|
IN PRPC_MESSAGE Message
|
|
);
|
|
|
|
virtual void
|
|
FreePipeBuffer (
|
|
IN PRPC_MESSAGE Message
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
ReallocPipeBuffer (
|
|
IN PRPC_MESSAGE Message,
|
|
IN unsigned int NewSize
|
|
) ;
|
|
|
|
virtual RPC_STATUS
|
|
ImpersonateClient (
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
RevertToSelf (
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
IsClientLocal (
|
|
OUT unsigned int * ClientLocalFlag
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
ConvertToServerBinding (
|
|
OUT RPC_BINDING_HANDLE __RPC_FAR * ServerBinding
|
|
);
|
|
|
|
virtual void
|
|
InquireObjectUuid (
|
|
OUT RPC_UUID * ObjectUuid
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
ToStringBinding (
|
|
OUT RPC_CHAR ** StringBinding
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
MonitorAssociation (
|
|
IN PRPC_RUNDOWN RundownRoutine,
|
|
IN void * Context
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
StopMonitorAssociation (
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
GetAssociationContext (
|
|
OUT void ** AssociationContext
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
SetAssociationContext (
|
|
IN void * Context
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
InquireAuthClient (
|
|
OUT RPC_AUTHZ_HANDLE PAPI * Privileges,
|
|
OUT RPC_CHAR PAPI * PAPI * ServerPrincipalName, OPTIONAL
|
|
OUT unsigned long PAPI * AuthenticationLevel,
|
|
OUT unsigned long PAPI * AuthenticationService,
|
|
OUT unsigned long PAPI * AuthorizationService
|
|
);
|
|
|
|
virtual RPC_STATUS
|
|
InqTransportType(
|
|
OUT unsigned int __RPC_FAR * Type
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
GetBufferDo(
|
|
IN OUT PRPC_MESSAGE Message,
|
|
IN int NewSize,
|
|
IN BOOL fDataValid
|
|
) ;
|
|
|
|
void
|
|
DealWithPipeRequest (
|
|
WMSG_MESSAGE *Message
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
SetupForPipes (
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
ReadData (
|
|
IN OUT PRPC_MESSAGE Message,
|
|
IN int Extra
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
WriteData (
|
|
IN void *Buffer,
|
|
IN int BufferLength,
|
|
IN OUT int *LengthWritten
|
|
) ;
|
|
|
|
RPC_STATUS
|
|
SendAck (
|
|
IN WMSG_MESSAGE *AckMessage,
|
|
IN BOOL fPipeMessage = 1,
|
|
IN int ValidDataSize = 0,
|
|
IN int Flags = 0,
|
|
IN RPC_STATUS Status = RPC_S_OK
|
|
) ;
|
|
|
|
void
|
|
DealWithPipeReply (
|
|
) ;
|
|
};
|
|
|
|
|
|
inline RPC_STATUS
|
|
WMSG_SCALL::InqTransportType(
|
|
OUT unsigned int __RPC_FAR * Type
|
|
)
|
|
{
|
|
*Type = TRANSPORT_TYPE_LPC ;
|
|
|
|
return (RPC_S_OK) ;
|
|
}
|
|
|
|
|
|
inline
|
|
WMSG_SCALL::WMSG_SCALL (
|
|
IN WMSG_SASSOCIATION * Association,
|
|
IN WMSG_MESSAGE * WMSGMessage,
|
|
IN WMSG_MESSAGE * WMSGReplyMessage,
|
|
IN unsigned int Flags,
|
|
IN BOOL fSyncClient
|
|
)
|
|
{
|
|
this->Association = Association;
|
|
this->WMSGRequestMessage = WMSGMessage;
|
|
this->WMSGReplyMessage = WMSGReplyMessage;
|
|
ObjectUuidFlag = 0;
|
|
PushedResponse = 0;
|
|
CurrentBufferLength = 0;
|
|
BufferComplete = 0;
|
|
this->Flags = Flags ;
|
|
this->fSyncClient = fSyncClient;
|
|
PipeEvent = 0;
|
|
ConnectionKey = 0;
|
|
FirstSend = 1;
|
|
PipeSendCalled = 0;
|
|
PipeMessage = 0;
|
|
Deleted = 0;
|
|
}
|
|
|
|
inline WMSG_SCALL::~WMSG_SCALL (
|
|
)
|
|
{
|
|
if (PipeEvent)
|
|
{
|
|
CloseHandle(PipeEvent) ;
|
|
|
|
GlobalMutexRequest() ;
|
|
Association->SCallDict.Delete(ConnectionKey - 1) ;
|
|
GlobalMutexClear() ;
|
|
}
|
|
|
|
if (PipeMessage)
|
|
{
|
|
MessageCache->FreeMessage(PipeMessage) ;
|
|
}
|
|
}
|
|
|
|
inline RPC_STATUS
|
|
InitializeWMsgIfNeccassary(
|
|
int ActuallyInitialize
|
|
)
|
|
{
|
|
int nIndex ;
|
|
RPC_STATUS RpcStatus ;
|
|
|
|
if (GlobalWMsgServer == 0 || MessageCache == 0)
|
|
{
|
|
if ((RpcStatus = InitializeWMsg()) != RPC_S_OK)
|
|
{
|
|
return RpcStatus ;
|
|
}
|
|
}
|
|
|
|
if (GlobalWMsgServer->ActuallyInitialized == 0 &&
|
|
ActuallyInitialize)
|
|
{
|
|
GlobalWMsgServer->ActuallyInitializeWMsgServer() ;
|
|
}
|
|
|
|
return (RPC_S_OK) ;
|
|
}
|
|
#endif
|