📄 oleproxy.c
字号:
{
RemUnkStub *This = (RemUnkStub *)iface;
TRACE("(%p)->Connect(%p)\n",This,lpUnkServer);
This->iface = (IRemUnknown*)lpUnkServer;
IRemUnknown_AddRef(This->iface);
return S_OK;
}
static void WINAPI RemUnkStub_Disconnect(LPRPCSTUBBUFFER iface)
{
RemUnkStub *This = (RemUnkStub *)iface;
TRACE("(%p)->Disconnect()\n",This);
IUnknown_Release(This->iface);
This->iface = NULL;
}
static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
PRPCOLEMESSAGE pMsg,
LPRPCCHANNELBUFFER pChannel)
{
RemUnkStub *This = (RemUnkStub *)iface;
ULONG iMethod = pMsg->iMethod;
LPBYTE buf = pMsg->Buffer;
HRESULT hr = RPC_E_INVALIDMETHOD;
TRACE("(%p)->Invoke(%p,%p) method %d\n", This, pMsg, pChannel, iMethod);
switch (iMethod)
{
case 3: /* RemQueryInterface */
{
IPID ipid;
ULONG cRefs;
USHORT cIids;
IID *iids;
REMQIRESULT *pQIResults = NULL;
/* in */
memcpy(&ipid, buf, sizeof(ipid));
buf += sizeof(ipid);
memcpy(&cRefs, buf, sizeof(cRefs));
buf += sizeof(cRefs);
memcpy(&cIids, buf, sizeof(cIids));
buf += sizeof(cIids);
iids = (IID *)buf;
hr = IRemUnknown_RemQueryInterface(This->iface, &ipid, cRefs, cIids, iids, &pQIResults);
/* out */
pMsg->cbBuffer = cIids * sizeof(REMQIRESULT) + sizeof(HRESULT);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
buf = pMsg->Buffer;
*(HRESULT *)buf = hr;
buf += sizeof(HRESULT);
if (hr) return hr;
/* FIXME: pQIResults is a unique pointer so pQIResults can be NULL! */
memcpy(buf, pQIResults, cIids * sizeof(REMQIRESULT));
break;
}
case 4: /* RemAddRef */
{
USHORT cIids;
REMINTERFACEREF *ir;
HRESULT *pResults;
/* in */
memcpy(&cIids, buf, sizeof(USHORT));
buf += sizeof(USHORT);
ir = (REMINTERFACEREF*)buf;
pResults = CoTaskMemAlloc(cIids * sizeof(HRESULT));
if (!pResults) return E_OUTOFMEMORY;
hr = IRemUnknown_RemAddRef(This->iface, cIids, ir, pResults);
/* out */
pMsg->cbBuffer = cIids * sizeof(HRESULT);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
if (!hr)
{
buf = pMsg->Buffer;
memcpy(buf, pResults, cIids * sizeof(HRESULT));
}
CoTaskMemFree(pResults);
break;
}
case 5: /* RemRelease */
{
USHORT cIids;
REMINTERFACEREF *ir;
/* in */
memcpy(&cIids, buf, sizeof(USHORT));
buf += sizeof(USHORT);
ir = (REMINTERFACEREF*)buf;
hr = IRemUnknown_RemRelease(This->iface, cIids, ir);
/* out */
pMsg->cbBuffer = 0;
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
break;
}
}
return hr;
}
static LPRPCSTUBBUFFER WINAPI RemUnkStub_IsIIDSupported(LPRPCSTUBBUFFER iface,
REFIID riid)
{
RemUnkStub *This = (RemUnkStub *)iface;
TRACE("(%p)->IsIIDSupported(%s)\n", This, debugstr_guid(riid));
return IsEqualGUID(&IID_IRemUnknown, riid) ? iface : NULL;
}
static ULONG WINAPI RemUnkStub_CountRefs(LPRPCSTUBBUFFER iface)
{
RemUnkStub *This = (RemUnkStub *)iface;
FIXME("(%p)->CountRefs()\n", This);
return 1;
}
static HRESULT WINAPI RemUnkStub_DebugServerQueryInterface(LPRPCSTUBBUFFER iface,
LPVOID *ppv)
{
RemUnkStub *This = (RemUnkStub *)iface;
FIXME("(%p)->DebugServerQueryInterface(%p)\n",This,ppv);
return E_NOINTERFACE;
}
static void WINAPI RemUnkStub_DebugServerRelease(LPRPCSTUBBUFFER iface,
LPVOID pv)
{
RemUnkStub *This = (RemUnkStub *)iface;
FIXME("(%p)->DebugServerRelease(%p)\n", This, pv);
}
static const IRpcStubBufferVtbl RemUnkStub_VTable =
{
RemUnkStub_QueryInterface,
RemUnkStub_AddRef,
RemUnkStub_Release,
RemUnkStub_Connect,
RemUnkStub_Disconnect,
RemUnkStub_Invoke,
RemUnkStub_IsIIDSupported,
RemUnkStub_CountRefs,
RemUnkStub_DebugServerQueryInterface,
RemUnkStub_DebugServerRelease
};
static HRESULT RemUnkStub_Construct(IRpcStubBuffer **ppStub)
{
RemUnkStub *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &RemUnkStub_VTable;
This->refs = 1;
This->iface = NULL;
*ppStub = (IRpcStubBuffer*)This;
return S_OK;
}
typedef struct _RemUnkProxy {
const IRemUnknownVtbl *lpvtbl_remunk;
const IRpcProxyBufferVtbl *lpvtbl_proxy;
LONG refs;
IRpcChannelBuffer *chan;
IUnknown *outer_unknown;
} RemUnkProxy;
static HRESULT WINAPI RemUnkProxy_QueryInterface(LPREMUNKNOWN iface, REFIID riid, void **ppv)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
if (This->outer_unknown)
return IUnknown_QueryInterface(This->outer_unknown, riid, ppv);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IRemUnknown))
{
IRemUnknown_AddRef(iface);
*ppv = (LPVOID)iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI RemUnkProxy_AddRef(LPREMUNKNOWN iface)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
ULONG refs;
TRACE("(%p)->AddRef()\n",This);
if (This->outer_unknown)
refs = IUnknown_AddRef(This->outer_unknown);
else
refs = InterlockedIncrement(&This->refs);
return refs;
}
static ULONG WINAPI RemUnkProxy_Release(LPREMUNKNOWN iface)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
TRACE("(%p)->Release()\n",This);
if (This->outer_unknown)
return IUnknown_Release(This->outer_unknown);
else
return IRpcProxyBufferImpl_Release((IRpcProxyBuffer *)&This->lpvtbl_proxy);
}
static HRESULT WINAPI RemUnkProxy_RemQueryInterface(LPREMUNKNOWN iface,
REFIPID ripid,
ULONG cRefs,
USHORT cIids,
IID* iids,
REMQIRESULT** ppQIResults)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
RPCOLEMESSAGE msg;
HRESULT hr = S_OK;
ULONG status;
TRACE("(%p)->(%s,%d,%d,%p,%p)\n",This,
debugstr_guid(ripid),cRefs,cIids,iids,ppQIResults);
*ppQIResults = NULL;
memset(&msg, 0, sizeof(msg));
msg.iMethod = 3;
msg.cbBuffer = sizeof(IPID) + sizeof(ULONG) +
sizeof(USHORT) + cIids*sizeof(IID);
hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown);
if (SUCCEEDED(hr)) {
LPBYTE buf = msg.Buffer;
memcpy(buf, ripid, sizeof(IPID));
buf += sizeof(IPID);
memcpy(buf, &cRefs, sizeof(ULONG));
buf += sizeof(ULONG);
memcpy(buf, &cIids, sizeof(USHORT));
buf += sizeof(USHORT);
memcpy(buf, iids, cIids*sizeof(IID));
hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status);
buf = msg.Buffer;
if (SUCCEEDED(hr)) {
hr = *(HRESULT *)buf;
buf += sizeof(HRESULT);
}
if (SUCCEEDED(hr)) {
*ppQIResults = CoTaskMemAlloc(cIids*sizeof(REMQIRESULT));
memcpy(*ppQIResults, buf, cIids*sizeof(REMQIRESULT));
}
IRpcChannelBuffer_FreeBuffer(This->chan, &msg);
}
return hr;
}
static HRESULT WINAPI RemUnkProxy_RemAddRef(LPREMUNKNOWN iface,
USHORT cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs,
HRESULT* pResults)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
RPCOLEMESSAGE msg;
HRESULT hr = S_OK;
ULONG status;
TRACE("(%p)->(%d,%p,%p)\n",This,
cInterfaceRefs,InterfaceRefs,pResults);
memset(&msg, 0, sizeof(msg));
msg.iMethod = 4;
msg.cbBuffer = sizeof(USHORT) + cInterfaceRefs*sizeof(REMINTERFACEREF);
hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown);
if (SUCCEEDED(hr)) {
LPBYTE buf = msg.Buffer;
memcpy(buf, &cInterfaceRefs, sizeof(USHORT));
buf += sizeof(USHORT);
memcpy(buf, InterfaceRefs, cInterfaceRefs*sizeof(REMINTERFACEREF));
hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status);
if (SUCCEEDED(hr)) {
buf = msg.Buffer;
memcpy(pResults, buf, cInterfaceRefs*sizeof(HRESULT));
}
IRpcChannelBuffer_FreeBuffer(This->chan, &msg);
}
return hr;
}
static HRESULT WINAPI RemUnkProxy_RemRelease(LPREMUNKNOWN iface,
USHORT cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
RPCOLEMESSAGE msg;
HRESULT hr = S_OK;
ULONG status;
TRACE("(%p)->(%d,%p)\n",This,
cInterfaceRefs,InterfaceRefs);
memset(&msg, 0, sizeof(msg));
msg.iMethod = 5;
msg.cbBuffer = sizeof(USHORT) + cInterfaceRefs*sizeof(REMINTERFACEREF);
hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown);
if (SUCCEEDED(hr)) {
LPBYTE buf = msg.Buffer;
memcpy(buf, &cInterfaceRefs, sizeof(USHORT));
buf += sizeof(USHORT);
memcpy(buf, InterfaceRefs, cInterfaceRefs*sizeof(REMINTERFACEREF));
hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status);
IRpcChannelBuffer_FreeBuffer(This->chan, &msg);
}
return hr;
}
static const IRemUnknownVtbl RemUnkProxy_VTable =
{
RemUnkProxy_QueryInterface,
RemUnkProxy_AddRef,
RemUnkProxy_Release,
RemUnkProxy_RemQueryInterface,
RemUnkProxy_RemAddRef,
RemUnkProxy_RemRelease
};
static HRESULT WINAPI RURpcProxyBufferImpl_QueryInterface(LPRPCPROXYBUFFER iface,REFIID riid,LPVOID *ppv) {
*ppv = NULL;
if (IsEqualIID(riid,&IID_IRpcProxyBuffer)||IsEqualIID(riid,&IID_IUnknown)) {
IRpcProxyBuffer_AddRef(iface);
*ppv = (LPVOID)iface;
return S_OK;
}
FIXME("(%s), no interface.\n",debugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI RURpcProxyBufferImpl_AddRef(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
TRACE("%p, %d\n", iface, This->refs + 1);
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
ULONG ref = InterlockedDecrement(&This->refs);
TRACE("%p, %d\n", iface, ref);
if (!ref) {
IRpcProxyBuffer_Disconnect(iface);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
}
static HRESULT WINAPI RURpcProxyBufferImpl_Connect(LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
TRACE("%p, %p\n", iface, pRpcChannelBuffer);
This->chan = pRpcChannelBuffer;
IRpcChannelBuffer_AddRef(This->chan);
return S_OK;
}
static void WINAPI RURpcProxyBufferImpl_Disconnect(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
TRACE("%p, %p\n", iface, This->chan);
if (This->chan) {
IRpcChannelBuffer_Release(This->chan);
This->chan = NULL;
}
}
static const IRpcProxyBufferVtbl RURpcProxyBuffer_VTable = {
RURpcProxyBufferImpl_QueryInterface,
RURpcProxyBufferImpl_AddRef,
RURpcProxyBufferImpl_Release,
RURpcProxyBufferImpl_Connect,
RURpcProxyBufferImpl_Disconnect
};
static HRESULT
RemUnkProxy_Construct(IUnknown *pUnkOuter, LPVOID *ppv,LPVOID *ppProxy) {
RemUnkProxy *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
This->lpvtbl_remunk = &RemUnkProxy_VTable;
This->lpvtbl_proxy = &RURpcProxyBuffer_VTable;
/* only one reference for the proxy buffer */
This->refs = 1;
This->outer_unknown = pUnkOuter;
*ppv = &(This->lpvtbl_remunk);
*ppProxy = &(This->lpvtbl_proxy);
/* and one reference for the object */
IUnknown_AddRef((IUnknown *)*ppv);
return S_OK;
}
/********************* OLE Proxy/Stub Factory ********************************/
static HRESULT WINAPI
PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
*ppv = (LPVOID)iface;
/* No ref counting, static class */
return S_OK;
}
FIXME("(%s) unknown IID?\n",debugstr_guid(iid));
return E_NOINTERFACE;
}
static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }
static HRESULT WINAPI
PSFacBuf_CreateProxy(
LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
IRpcProxyBuffer **ppProxy, LPVOID *ppv
) {
if (IsEqualIID(&IID_IClassFactory,riid))
return CFProxy_Construct(pUnkOuter, ppv,(LPVOID*)ppProxy);
else if (IsEqualIID(&IID_IRemUnknown,riid))
return RemUnkProxy_Construct(pUnkOuter, ppv,(LPVOID*)ppProxy);
FIXME("proxying not implemented for (%s) yet!\n",debugstr_guid(riid));
return E_FAIL;
}
static HRESULT WINAPI
PSFacBuf_CreateStub(
LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer,
IRpcStubBuffer** ppStub
) {
HRESULT hres;
TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
if (IsEqualIID(&IID_IClassFactory, riid) ||
IsEqualIID(&IID_IUnknown, riid) /* FIXME: fixup stub manager and remove this*/) {
hres = CFStub_Construct(ppStub);
if (!hres)
IRpcStubBuffer_Connect((*ppStub),pUnkServer);
return hres;
} else if (IsEqualIID(&IID_IRemUnknown,riid)) {
hres = RemUnkStub_Construct(ppStub);
if (!hres)
IRpcStubBuffer_Connect((*ppStub),pUnkServer);
return hres;
}
FIXME("stubbing not implemented for (%s) yet!\n",debugstr_guid(riid));
return E_FAIL;
}
static const IPSFactoryBufferVtbl psfacbufvtbl = {
PSFacBuf_QueryInterface,
PSFacBuf_AddRef,
PSFacBuf_Release,
PSFacBuf_CreateProxy,
PSFacBuf_CreateStub
};
/* This is the whole PSFactoryBuffer object, just the vtableptr */
static const IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;
/***********************************************************************
* DllGetClassObject [OLE32.@]
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(rclsid, &CLSID_PSFactoryBuffer))
return IPSFactoryBuffer_QueryInterface((IPSFactoryBuffer *)&lppsfac, iid, ppv);
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
IsEqualIID(iid,&IID_IClassFactory) ||
IsEqualIID(iid,&IID_IUnknown)
)
)
return MARSHAL_GetStandardMarshalCF(ppv);
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
return StdGlobalInterfaceTable_GetFactory(ppv);
if (IsEqualCLSID(rclsid, &CLSID_FileMoniker))
return FileMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
return ItemMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_AntiMoniker))
return AntiMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_CompositeMoniker))
return CompositeMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ClassMoniker))
return ClassMonikerCF_Create(iid, ppv);
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -