Leaked source code of windows server 2003
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.
 
 
 
 
 
 

508 lines
17 KiB

//
// marshal.h
//
#ifndef MARSHAL_H
#define MARSHAL_H
#include "private.h"
#include "globals.h"
#include "cicmutex.h"
#include "winuserp.h"
#include "systhrd.h"
#include "smblock.h"
#include "cregkey.h"
#define DEFAULTMARSHALTIMEOUT 30000
#define DEFAULTMARSHALCONNECTIONTIMEOUT 2000
#ifdef QS_RAWINPUT
#define QS_ALLINPUT400 (QS_ALLINPUT & ~QS_RAWINPUT)
#else
#define QS_ALLINPUT400 (QS_ALLINPUT)
#endif
#define QS_DEFAULTWAITFLAG (QS_ALLINPUT400 | QS_TRANSFER | QS_ALLPOSTMESSAGE)
#ifdef DEBUG
extern ULONG g_ulMarshalTimeOut;
#define MARSHALTIMEOUT g_ulMarshalTimeOut
const TCHAR c_szMarshal[] = TEXT("SOFTWARE\\Microsoft\\CTF\\Marshal\\");
const TCHAR c_szTimeOut[] = TEXT("TimeOut");
__inline void dbg_InitMarshalTimeOut()
{
CMyRegKey key;
DWORD dw;
if (key.Open(HKEY_CURRENT_USER, c_szMarshal, KEY_READ) != S_OK)
return;
if (key.QueryValue(dw, c_szTimeOut) != S_OK)
return;
g_ulMarshalTimeOut = (ULONG)dw;
}
#else
#define MARSHALTIMEOUT DEFAULTMARSHALTIMEOUT
#define dbg_InitMarshalTimeOut()
#endif
#define SZMARSHALINTERFACEFILEMAP __TEXT("MSCTF.MarshalInterface.FileMap.")
#define SZRPCSENDRECEIVEEVENT __TEXT("MSCTF.SendReceive.Event.")
#define SZRPCSENDRECEIVECONNECTIONEVENT __TEXT("MSCTF.SendReceiveConection.Event.")
HRESULT CicCoMarshalInterface(REFIID riid, IUnknown *punk, ULONG *pulStubId, DWORD *pdwStubTime, DWORD dwSrcThreadId);
HRESULT CicCoUnmarshalInterface(REFIID riid, DWORD dwStubThreadId, ULONG ulStubId, DWORD dwStubTIme, void **ppv);
void HandleSendReceiveMsg(DWORD dwSrcThreadId, ULONG ulCnt);
void FreeMarshaledStubs(SYSTHREAD *psfn);
void FreeMarshaledStubsForThread(SYSTHREAD *psfn, DWORD dwThread);
void StubCleanUp(ULONG ulStubId);
//////////////////////////////////////////////////////////////////////////////
//
// MARSHALINTERFACE structure
//
//////////////////////////////////////////////////////////////////////////////
typedef struct tag_MARSHALINTERFACE
{
IID iid;
DWORD dwStubTime;
} MARSHALINTERFACE;
//////////////////////////////////////////////////////////////////////////////
//
// MARSHALPARAM structure
//
//////////////////////////////////////////////////////////////////////////////
#define MPARAM_IN 0x000000001
#define MPARAM_OUT 0x000000002
#define MPARAM_INTERFACE 0x000010000
#define MPARAM_POINTER 0x000020000
#define MPARAM_ULONG 0x000040000
#define MPARAM_BSTR 0x000080000
#define MPARAM_STRUCT 0x000100000
#define MPARAM_HBITMAP 0x000200000
#define MPARAM_TF_LBBALLOONINFO 0x000400000
#define MPARAM_HICON 0x000800000
#define MPARAM_IN_POINTER (MPARAM_IN | MPARAM_POINTER)
#define MPARAM_IN_INTERFACE (MPARAM_IN | MPARAM_INTERFACE)
#define MPARAM_IN_ULONG (MPARAM_IN | MPARAM_ULONG)
#define MPARAM_IN_STRUCT (MPARAM_IN | MPARAM_STRUCT)
#define MPARAM_IN_HBITMAP (MPARAM_IN | MPARAM_HBITMAP)
#define MPARAM_IN_HICON (MPARAM_IN | MPARAM_HICON)
#define MPARAM_OUT_POINTER (MPARAM_OUT | MPARAM_POINTER)
#define MPARAM_OUT_INTERFACE (MPARAM_OUT | MPARAM_INTERFACE)
#define MPARAM_OUT_BSTR (MPARAM_OUT | MPARAM_BSTR)
#define MPARAM_OUT_HBITMAP (MPARAM_OUT | MPARAM_HBITMAP)
#define MPARAM_OUT_TF_LBBALLOONINFO (MPARAM_OUT | MPARAM_TF_LBBALLOONINFO)
#define MPARAM_OUT_HICON (MPARAM_OUT | MPARAM_HICON)
#define MPARAM_IN_OUT_INTERFACE (MPARAM_IN | MPARAM_OUT | MPARAM_INTERFACE)
typedef struct tag_MARSHALPARAM
{
ULONG cbBufSize;
DWORD dwFlags;
// DWORD buf[1];
} MARSHALPARAM;
typedef struct tag_MARSHALMSG
{
ULONG cbSize;
ULONG cbBufSize;
IID iid;
ULONG ulMethodId;
ULONG ulParamNum;
union {
HRESULT hrRet;
ULONG ulRet;
};
DWORD dwSrcThreadId;
DWORD dwSrcProcessId;
ULONG ulStubId;
DWORD dwStubTime;
HRESULT hrMarshalOutParam;
ULONG ulParamOffset[1];
} MARSHALMSG;
__inline MARSHALPARAM *GetMarshalParam(MARSHALMSG *pMsg, ULONG ulParam)
{
return (MARSHALPARAM *)(((BYTE *)pMsg) + pMsg->ulParamOffset[ulParam]);
}
//////////////////////////////////////////////////////////////////////////////
//
// ParamExtractor
//
//////////////////////////////////////////////////////////////////////////////
__inline void *ParamToBufferPointer(MARSHALPARAM *pParam)
{
return (void *)((BYTE *)pParam + sizeof(MARSHALPARAM));
}
__inline void *ParamToBufferPointer(MARSHALMSG *pMsg, ULONG ulParam)
{
MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
return (void *)((BYTE *)pParam + sizeof(MARSHALPARAM));
}
__inline void *ParamToPointer(MARSHALPARAM *pParam)
{
return *(void **)((BYTE *)pParam + sizeof(MARSHALPARAM));
}
__inline void *ParamToPointer(MARSHALMSG *pMsg , ULONG ulParam)
{
MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
return *(void **)((BYTE *)pParam + sizeof(MARSHALPARAM));
}
__inline ULONG ParamToULONG(MARSHALMSG *pMsg , ULONG ulParam)
{
MARSHALPARAM *pParam = GetMarshalParam(pMsg, ulParam);
return *(ULONG *)((BYTE *)pParam + sizeof(MARSHALPARAM));
}
HBITMAP ParamToHBITMAP(MARSHALMSG *pMsg , ULONG ulParam);
//////////////////////////////////////////////////////////////////////////////
//
// CModalLoop
//
//////////////////////////////////////////////////////////////////////////////
class CModalLoop : public CSysThreadRef
{
public:
CModalLoop(SYSTHREAD *psfn);
~CModalLoop();
HRESULT BlockFn(CCicEvent *pevent, DWORD dwWaitingThreadId, DWORD &dwWaitFlags);
private:
void WaitHandleWndMessages(DWORD dwQueueFlags);
BOOL WaitRemoveMessage(UINT uMsgFirst, UINT uMsgLast, DWORD dwFlags);
BOOL MyPeekMessage(MSG *pMsg, HWND hwnd, UINT min, UINT max, WORD wFlag);
ULONG _wQuitCode;
BOOL _fQuitReceived;
};
//////////////////////////////////////////////////////////////////////////////
//
// CThreadMarshalWnd
//
//////////////////////////////////////////////////////////////////////////////
class CThreadMarshalWnd
{
public:
CThreadMarshalWnd();
~CThreadMarshalWnd();
BOOL Init(DWORD dwThreadId);
BOOL PostMarshalThreadMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
static BOOL DestroyAll();
static BOOL DestroyThreadMarshalWnd(DWORD dwThread);
static HWND GetThreadMarshalWnd(DWORD dwThread);
static void ClearMarshalWndProc(DWORD dwProcessId);
BOOL IsWindow()
{
return ::IsWindow(_hwnd);
}
BOOL IsThreadWindow();
void SetMarshalWindow(HWND hwndMarshal)
{
_hwnd = hwndMarshal;
}
private:
static BOOL EnumThreadWndProc(HWND hwnd, LPARAM lParam);
DWORD _dwThreadId;
HWND _hwnd;
};
void RegisterMarshalWndClass();
HWND EnsureMarshalWnd();
//////////////////////////////////////////////////////////////////////////////
//
// CProxy
//
//////////////////////////////////////////////////////////////////////////////
#define CPROXY_PARAM_START() CPROXY_PARAM param[] = {
#define CPROXY_PARAM_ULONG_IN(ul) \
{MPARAM_IN_ULONG, NULL, ul, NULL, sizeof(ULONG), 1},
#define CPROXY_PARAM_WCHAR_IN(pch, cch) \
{MPARAM_IN_POINTER, (void *)(pch), 0, NULL, cch * sizeof(WCHAR), 1},
#define CPROXY_PARAM_POINTER_IN(p) \
{MPARAM_IN_POINTER, (void *)(p), 0, NULL, sizeof(*p), 1},
#define CPROXY_PARAM_POINTER_ARRAY_IN(p, nCnt) \
{MPARAM_IN_POINTER, (void *)(p), 0, NULL, sizeof(*p), nCnt},
#define CPROXY_PARAM_INTERFACE_IN(p, iid) \
{MPARAM_IN_INTERFACE, p, 0, &iid, sizeof(void *), 1},
#define CPROXY_PARAM_INTERFACE_ARRAY_IN(p, iid, nCnt) \
{MPARAM_IN_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
#define CPROXY_PARAM_POINTER_OUT(p) \
{MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), 1},
#define CPROXY_PARAM_POINTER_ARRAY_OUT(p, nCnt) \
{MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), nCnt},
#define CPROXY_PARAM_INTERFACE_OUT(p, iid) \
{MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
#define CPROXY_PARAM_INTERFACE_ARRAY_OUT(p, iid, nCnt) \
{MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
#define CPROXY_PARAM_INTERFACE_IN_OUT(p, iid) \
{MPARAM_IN_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
#define CPROXY_PARAM_INTERFACE_ARRAY_IN_OUT(p, iid, nCnt) \
{MPARAM_IN_OUT_INTERFACE, p, 0, &iid, sizeof(void *), nCnt},
#define CPROXY_PARAM_BSTR_OUT(p) \
{MPARAM_OUT_BSTR, p, 0, NULL, 0, 1},
#define CPROXY_PARAM_HBITMAP_OUT(p) \
{MPARAM_OUT_HBITMAP, p, 0, NULL, 0, 1},
#define CPROXY_PARAM_HICON_OUT(p) \
{MPARAM_OUT_HICON, p, 0, NULL, 0, 1},
#define CPROXY_PARAM_HBITMAP_IN(hbmp) \
{MPARAM_IN_HBITMAP, &hbmp, 0, NULL, 0, 1},
#define CPROXY_PARAM_HICON_IN(hicon) \
{MPARAM_IN_HICON, &hicon, 0, NULL, 0, 1},
#define CPROXY_PARAM_TF_LBBALLOONINFO_OUT(p) \
{MPARAM_OUT_TF_LBBALLOONINFO, (void *)p, 0, NULL, sizeof(*p), 1},
#define CPROXY_PARAM_STRUCT_IN(s) \
{MPARAM_IN_STRUCT, &s, 0, NULL, sizeof(s), 1},
#define CPROXY_PARAM_CALL(uMethodId) \
}; \
return proxy_Param(uMethodId, ARRAYSIZE(param), param);
#define CPROXY_PARAM_CALL_NOPARAM(x) return proxy_Param(x, 0, NULL);
typedef struct {
DWORD dwFlags;
void *pv;
ULONG ul;
const IID *piid;
ULONG cbUnitSize;
ULONG ulCount; // if this is array, the number of unit.
ULONG GetBufSize() {return cbUnitSize * ulCount;}
} CPROXY_PARAM;
class CProxy : public CSysThreadRef
{
public:
CProxy(SYSTHREAD *psfn);
virtual ~CProxy();
ULONG InternalAddRef();
ULONG InternalRelease();
void Init(REFIID riid,
ULONG ulProxyId,
ULONG ulIdStubId,
DWORD dwStubTime,
DWORD dwStubThreadId,
DWORD dwCurThreadId,
DWORD dwCurProcessId);
//
// IRpcChannelBuffer
//
HRESULT SendReceive( MARSHALMSG *pMsg , ULONG ulBlockId);
ULONG GetStubId() {return _ulStubId;}
DWORD GetStubThreadId() {return _dwStubThreadId;}
protected:
HRESULT proxy_Param(ULONG ulMethodId, ULONG ulParamNum, CPROXY_PARAM *pProsyParam);
protected:
IID _iid; // interface id for this proxy.
ULONG _cRef;
private:
CThreadMarshalWnd _tmw;
ULONG _ulProxyId; // unique proxy id in src thread.
ULONG _ulStubId; // unique stub id in stub thread.
DWORD _dwStubTime; // stub created time stamp.
DWORD _dwStubThreadId; // stub thread id.
DWORD _dwSrcThreadId; // src thread id.
DWORD _dwSrcProcessId; // src process id.
#ifdef DEBUG
BOOL _fInLoop;
#endif
};
//////////////////////////////////////////////////////////////////////////////
//
// CMarshalInterfaceFileMapping
//
//////////////////////////////////////////////////////////////////////////////
class CMarshalInterfaceFileMapping : public CCicFileMapping
{
public:
CMarshalInterfaceFileMapping(DWORD dwThreadId, ULONG ulStubId, ULONG ulStubTime) : CCicFileMapping()
{
if (SetName2(szFileMap, ARRAYSIZE(szFileMap), SZMARSHALINTERFACEFILEMAP, dwThreadId, ulStubId, ulStubTime))
_pszFile = szFileMap;
}
private:
char szFileMap[MAX_PATH];
};
//////////////////////////////////////////////////////////////////////////////
//
// CStub
//
//////////////////////////////////////////////////////////////////////////////
#define CSTUB_PARAM_START() CPROXY_PARAM param[] = {
#define CSTUB_PARAM_ULONG_IN(ul) \
{MPARAM_IN_ULONG, NULL, ul, NULL, 0 /*sizeof(ULONG)*/, 1},
#define CSTUB_PARAM_POINTER_IN(p) \
{MPARAM_IN_POINTER, (void *)(p), 0, NULL, 0 /*sizeof(*p)*/, 1},
#define CSTUB_PARAM_POINTER_ARRAY_IN(p, nCnt) \
{MPARAM_IN_POINTER, (void *)(p), 0, NULL, 0 /*sizeof(*p)*/, nCnt},
#define CSTUB_PARAM_INTERFACE_IN(p, iid) \
{MPARAM_IN_INTERFACE, p, 0, &iid, 0 /*sizeof(void *)*/, 1},
#define CSTUB_PARAM_INTERFACE_ARRAY_IN(p, iid, cnt) \
{MPARAM_IN_INTERFACE, p, 0, &iid, 0 /*sizeof(void *)*/, cnt},
#define CSTUB_PARAM_POINTER_OUT(p) \
{MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), 1},
#define CSTUB_PARAM_POINTER_ARRAY_OUT(p, nCnt) \
{MPARAM_OUT_POINTER, p, 0, NULL, sizeof(*p), nCnt},
#define CSTUB_PARAM_INTERFACE_OUT(p, iid) \
{MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), 1},
#define CSTUB_PARAM_INTERFACE_ARRAY_OUT(p, iid, cnt) \
{MPARAM_OUT_INTERFACE, p, 0, &iid, sizeof(void *), cnt},
#define CSTUB_PARAM_BSTR_OUT(p) \
{MPARAM_OUT_BSTR, p, 0, NULL, 0, 1},
#define CSTUB_PARAM_HBITMAP_OUT(p) \
{MPARAM_OUT_HBITMAP, p, 0, NULL, 0, 1},
#define CSTUB_PARAM_HICON_OUT(p) \
{MPARAM_OUT_HICON, p, 0, NULL, 0, 1},
#define CSTUB_PARAM_TF_LBBALLOONINFO_OUT(p) \
{MPARAM_OUT_TF_LBBALLOONINFO, (void *)p, 0, NULL, sizeof(*p), 1},
#define CSTUB_PARAM_HBITMAP_IN(hbmp) \
{MPARAM_IN_HBITMAP, &hbmp, 0, NULL, 0, 1},
#define CSTUB_PARAM_HICON_IN(hicon) \
{MPARAM_IN_HICON, &hicon, 0, NULL, 0, 1},
#define CSTUB_PARAM_END() \
};
#define CSTUB_PARAM_INTERFACE_OUT_RELEASE(p) \
if (p) ((IUnknown *)p)->Release();
#define CSTUB_PARAM_INTERFACE_ARRAY_OUT_RELEASE(p, ulCnt) \
for (ULONG __ul = 0; __ul < ulCnt; __ul++) \
if (p[__ul]) ((IUnknown *)p[__ul])->Release();
#define CSTUB_PARAM_CALL(pMsg, hrRet, psb) \
stub_OutParam(_this, pMsg, pMsg->ulMethodId, ARRAYSIZE(param), param, psb); \
pMsg->hrRet = hrRet;
#define CSTUB_PARAM_RETURN() \
return S_OK;
#define CSTUB_NOT_IMPL() \
Assert(0); \
return S_OK;
class CStub
{
public:
CStub();
virtual ~CStub();
ULONG _AddRef();
ULONG _Release();
ULONG GetStubId() {return _ulStubId;}
virtual HRESULT Invoke(MARSHALMSG *pMsg, CSharedBlock *psb) = 0;
void ClearFileMap()
{
if (_pfm)
{
_pfm->Close();
delete _pfm;
_pfm = NULL;
}
}
static HRESULT stub_OutParam(CStub *_this,
MARSHALMSG *pMsg,
ULONG ulMethodId,
ULONG ulParamNum,
CPROXY_PARAM *pProxyParam,
CSharedBlock *psb);
CMarshalInterfaceFileMapping *_pfm;
IID _iid; // interface id for this stub.
IUnknown *_punk; // actual object.
ULONG _ulStubId; // unique stubid of this thread.
DWORD _dwStubTime; // stub created time stamp.
DWORD _dwStubThreadId; // stub thread id.
DWORD _dwStubProcessId; // stub process id.
DWORD _dwSrcThreadId; // src thread id.
BOOL _fNoRemoveInDtor; // this stub has been removed from list.
// so don't try at dtor.
ULONG _cRef;
};
#endif // MARSHAL_H