windows-nt/Source/XPSP1/NT/com/rpc/ndrmem/rpcproxy.c
2020-09-26 16:20:57 +08:00

953 lines
22 KiB
C

#if !defined(__RPC_DOS__) && !defined(__RPC_WIN16__)
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: rpcproxy.c
//
// Contents: Contains runtime functions for interface proxies and stubs.
//
// Functions:
// DllGetClassObject
// DllCanUnloadNow
// MIDL_user_allocate
// MIDL_user_free
// NdrGetProxyBuffer
// NdrGetProxyIID
// NdrProxyInitialize
// NdrProxyGetBuffer
// NdrProxySendReceive
// NdrProxyFreeBuffer
// NdrProxyErrorHandler
// NdrStubInitialize
// NdrStubGetBuffer
//
// Classes: CStdProxyBuffer
// CStdPSFactoryBuffer
// CStdStubBuffer
//
//
//
//--------------------------------------------------------------------------
#include <rpcproxy.h>
#include <assert.h>
//+-------------------------------------------------------------------------
//
// Global data
//
//--------------------------------------------------------------------------
long DllRefCount = 0;
IPSFactoryBufferVtbl CStdPSFactoryBufferVtbl = {
CStdPSFactoryBuffer_QueryInterface,
CStdPSFactoryBuffer_AddRef,
CStdPSFactoryBuffer_Release,
CStdPSFactoryBuffer_CreateProxy,
CStdPSFactoryBuffer_CreateStub };
CStdPSFactoryBuffer gPSFactoryBuffer = {
&CStdPSFactoryBufferVtbl,
0 };
IRpcProxyBufferVtbl CStdProxyBufferVtbl = {
CStdProxyBuffer_QueryInterface,
CStdProxyBuffer_AddRef,
CStdProxyBuffer_Release,
CStdProxyBuffer_Connect,
CStdProxyBuffer_Disconnect };
//+-------------------------------------------------------------------------
//
// Function: DllGetClassObject
//
// Synopsis: Standard implementation of entrypoint required by binder.
//
// Arguments: [rclsid] -- class id to find
// [riid] -- interface to return
// [ppv] -- output pointer
//
// Returns: E_UNEXPECTED if class not found
// Otherwise, whatever is returned by the class's QI
//
// Algorithm: Searches the linked list for the required class.
//
// Notes:
//
//--------------------------------------------------------------------------
HRESULT STDAPICALLTYPE DllGetClassObject (
REFCLSID rclsid,
REFIID riid,
LPVOID FAR* ppv )
{
HRESULT hr = E_UNEXPECTED;
assert(rclsid);
assert(riid);
assert(ppv);
*ppv = 0;
if(memcmp(rclsid, &CLSID_PSFactoryBuffer, sizeof(IID)) == 0)
hr = gPSFactoryBuffer.lpVtbl->QueryInterface((IPSFactoryBuffer *)&gPSFactoryBuffer, riid, ppv);
return hr;
}
//+-------------------------------------------------------------------------
//
// Function: DllCanUnloadNow
//
// Synopsis: Standard entrypoint required by binder
//
// Returns: S_OK if DLL reference count is zero
// S_FALSE otherwise
//
//--------------------------------------------------------------------------
HRESULT STDAPICALLTYPE DllCanUnloadNow ()
{
HRESULT hr;
if(DllRefCount == 0)
hr = S_OK;
else
hr = S_FALSE;
return hr;
}
//+-------------------------------------------------------------------------
//
// Method: CStdPSFactoryBuffer_QueryInterface, public
//
// Synopsis: Query for an interface on the class factory.
//
// Derivation: IUnknown
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdPSFactoryBuffer_QueryInterface (
IPSFactoryBuffer *pThis,
REFIID iid,
void **ppv )
{
HRESULT hr = E_NOINTERFACE;
assert(pThis);
assert(iid);
assert(ppv);
*ppv = 0;
if ((memcmp(iid, &IID_IUnknown, sizeof(IID)) == 0) ||
(memcmp(iid, &IID_IPSFactoryBuffer, sizeof(IID)) == 0))
{
*ppv = pThis;
pThis->lpVtbl->AddRef(pThis);
hr = S_OK;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Method: CStdPSFactoryBuffer_AddRef, public
//
// Synopsis: Increment DLL reference counts
//
// Derivation: IUnknown
//
// Notes: We have a single instance of the CStdPSFactoryBuffer.
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdPSFactoryBuffer_AddRef(
IPSFactoryBuffer *this)
{
assert(this);
InterlockedIncrement(&((CStdPSFactoryBuffer *)this)->RefCount);
InterlockedIncrement(&DllRefCount);
return (unsigned long) ((CStdPSFactoryBuffer *)this)->RefCount;
}
//+-------------------------------------------------------------------------
//
// Method: CStdPSFactoryBuffer_Release, public
//
// Synopsis: Decrement DLL reference count
//
// Derivation: IUnknown
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdPSFactoryBuffer_Release(
IPSFactoryBuffer *this)
{
long t;
unsigned long count;
assert(this);
t = InterlockedDecrement(&((CStdPSFactoryBuffer *)this)->RefCount);
InterlockedDecrement(&DllRefCount);
if(t == 0)
count = 0;
else
count = (unsigned long) ((CStdPSFactoryBuffer *)this)->RefCount;
return count;
}
//+-------------------------------------------------------------------------
//
// Method: CStdPSFactoryBuffer_CreateProxy, public
//
// Synopsis: Create a proxy for the specified interface.
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdPSFactoryBuffer_CreateProxy
(
IPSFactoryBuffer *this,
IUnknown *punkOuter,
REFIID riid,
IRpcProxyBuffer **ppProxy,
void **ppv
)
{
HRESULT hr = E_OUTOFMEMORY;
const IID *pIID;
CStdProxyBuffer *pProxyBuffer = 0;
int i, j;
assert(this);
assert(riid);
assert(ppProxy);
assert(ppv);
*ppProxy = 0;
*ppv = 0;
//Search the list of proxy files.
for(i = 0;
pProxyFileList[i] && !pProxyBuffer;
i++)
{
//Search the interface proxies in the proxy buffer
for(j = 0;
((CStdProxyBuffer *)pProxyFileList[i]->pProxyBuffer)->aProxyVtbl[j] && !pProxyBuffer;
j++)
{
pIID = NdrGetProxyIID(&((CStdProxyBuffer *)pProxyFileList[i]->pProxyBuffer)->aProxyVtbl[j]);
assert(pIID);
if(memcmp(riid, pIID, sizeof(IID)) == 0)
{
//We found the interface!
//Allocate memory for the new proxy buffer.
pProxyBuffer = (CStdProxyBuffer *) CoTaskMemAlloc(pProxyFileList[i]->ProxyBufferSize);
if(pProxyBuffer)
{
//Initialize the new proxy buffer.
memcpy(pProxyBuffer, pProxyFileList[i]->pProxyBuffer, pProxyFileList[i]->ProxyBufferSize);
pProxyBuffer->punkOuter = punkOuter;
//Increment the DLL reference count.
InterlockedIncrement(&DllRefCount);
*ppProxy = (IRpcProxyBuffer *) pProxyBuffer;
*ppv = &pProxyBuffer->aProxyVtbl[j];
hr = S_OK;
}
}
}
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Method: CStdPSFactoryBuffer_CreateStub, public
//
// Synopsis: Create a stub for the specified interface.
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdPSFactoryBuffer_CreateStub
(
IPSFactoryBuffer *this,
REFIID riid,
IUnknown *punkServer,
IRpcStubBuffer **ppStub
)
{
HRESULT hr = E_OUTOFMEMORY;
const IID *pIID;
CStdStubBuffer *pStubBuffer = 0;
int i, j;
assert(this);
assert(riid);
assert(ppStub);
*ppStub = 0;
//Search the list of proxy files.
for(i = 0;
pProxyFileList[i] && !pStubBuffer;
i++)
{
//Search the interface stubs in the stub buffer
for(j = 0;
((CStdStubBuffer *)pProxyFileList[i]->pStubBuffer)->aInterfaceStub[j].lpVtbl && !pStubBuffer;
j++)
{
pIID = NdrGetStubIID(&((CStdStubBuffer *)pProxyFileList[i]->pStubBuffer)->aInterfaceStub[j].lpVtbl);
assert(pIID);
if(memcmp(riid, pIID, sizeof(IID)) == 0)
{
//We found the interface!
//Allocate memory for the new proxy buffer.
pStubBuffer = (CStdStubBuffer *) CoTaskMemAlloc(pProxyFileList[i]->StubBufferSize);
if(pStubBuffer)
{
//Initialize the new stub buffer.
memcpy(pStubBuffer, pProxyFileList[i]->pStubBuffer, pProxyFileList[i]->StubBufferSize);
if(punkServer)
{
punkServer->lpVtbl->AddRef(punkServer);
pStubBuffer->punkObject = punkServer;
hr = punkServer->lpVtbl->QueryInterface(punkServer, riid, &pStubBuffer->aInterfaceStub[j].pvServerObject);
}
else
hr = S_OK;
if(FAILED(hr))
CoTaskMemFree(pStubBuffer);
else
{
*ppStub = (IRpcStubBuffer *) &pStubBuffer->aInterfaceStub[j].lpVtbl;
//Increment the DLL reference count.
InterlockedIncrement(&DllRefCount);
}
}
}
}
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Method: CStdProxyBuffer_QueryInterface, public
//
// Synopsis: Query for an interface on the proxy. This provides access
// to both internal and external interfaces.
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdProxyBuffer_QueryInterface(IRpcProxyBuffer *pThis, REFIID riid, void **ppv)
{
HRESULT hr = E_NOINTERFACE;
CStdProxyBuffer *pProxyBuffer = (CStdProxyBuffer *) pThis;
void *pInterfaceProxy = 0;
int j;
const IID *pIID;
assert(pThis);
assert(riid);
assert(ppv);
*ppv = 0;
if((memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0) ||
(memcmp(riid, &IID_IRpcProxyBuffer, sizeof(IID)) == 0))
{
//This is an internal interface. Increment the internal reference count.
InterlockedIncrement( &((CStdProxyBuffer *)pThis)->RefCount);
*ppv = pThis;
hr = S_OK;
}
//Search the interface proxies in the proxy buffer
for(j = 0;
pProxyBuffer->aProxyVtbl[j] && !pInterfaceProxy;
j++)
{
pIID = NdrGetProxyIID(&pProxyBuffer->aProxyVtbl[j]);
assert(pIID);
if(memcmp(riid, pIID, sizeof(IID)) == 0)
{
//We found the interface!
pInterfaceProxy = &pProxyBuffer->aProxyVtbl[j];
//Increment the reference count.
if(pProxyBuffer->punkOuter)
{
pProxyBuffer->punkOuter->lpVtbl->AddRef(pProxyBuffer->punkOuter);
}
else
{
InterlockedIncrement(&pProxyBuffer->RefCount);
}
*ppv = pInterfaceProxy;
hr = S_OK;
}
}
return hr;
};
//+-------------------------------------------------------------------------
//
// Method: CStdProxyBuffer_AddRef, public
//
// Synopsis: Increment reference count.
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdProxyBuffer_AddRef(IRpcProxyBuffer *pThis)
{
InterlockedIncrement(&((CStdProxyBuffer *)pThis)->RefCount);
return (ULONG) ((CStdProxyBuffer *)pThis)->RefCount;
};
//+-------------------------------------------------------------------------
//
// Method: CStdProxyBuffer_Release, public
//
// Synopsis: Decrement reference count.
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdProxyBuffer_Release(IRpcProxyBuffer *pThis)
{
long RefCount;
unsigned long count;
assert(pThis);
RefCount = InterlockedDecrement(&((CStdProxyBuffer *)pThis)->RefCount);
assert(RefCount >= 0);
if(RefCount == 0)
{
count = 0;
//Decrement the DLL reference count.
InterlockedDecrement(&DllRefCount);
//Free the memory
MIDL_user_free(pThis);
}
else
count = (unsigned long) ((CStdProxyBuffer *)pThis)->RefCount;
return count;
};
//+-------------------------------------------------------------------------
//
// Method: CStdProxyBuffer_Connect, public
//
// Synopsis: Connect the proxy to the channel.
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdProxyBuffer_Connect(IRpcProxyBuffer *pThis, IRpcChannelBuffer *pChannel)
{
HRESULT hr = E_UNEXPECTED;
assert(pThis);
pThis->lpVtbl->Disconnect(pThis);
if(pChannel)
hr = pChannel->lpVtbl->QueryInterface(pChannel, &IID_IRpcChannelBuffer, &((CStdProxyBuffer *)pThis)->pChannel);
return hr;
};
//+-------------------------------------------------------------------------
//
// Method: CStdProxyBuffer_Disconnect, public
//
// Synopsis: Disconnect the proxy from the channel.
//
// Derivation: IRpcProxyBuffer
//
//--------------------------------------------------------------------------
void STDMETHODCALLTYPE
CStdProxyBuffer_Disconnect(IRpcProxyBuffer *pThis)
{
assert(pThis);
if(((CStdProxyBuffer *)pThis)->pChannel)
{
((CStdProxyBuffer *)pThis)->pChannel->lpVtbl->Release(((CStdProxyBuffer *)pThis)->pChannel);
((CStdProxyBuffer *)pThis)->pChannel = 0;
}
};
//+-------------------------------------------------------------------------
//
// Method: CStdStubBuffer_QueryInterface, public
//
// Synopsis: Query for an interface on the stub buffer.
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_QueryInterface(IRpcStubBuffer *pThis, REFIID riid, void **ppvObject)
{
HRESULT hr = E_NOINTERFACE;
assert(pThis);
assert(riid);
assert(ppvObject);
*ppvObject = 0;
if ((memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0) ||
(memcmp(riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
{
*ppvObject = (IRpcStubBuffer *) pThis;
pThis->lpVtbl->AddRef(pThis);
hr = S_OK;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Method: CStdStubBuffer_AddRef, public
//
// Synopsis: Increment reference count.
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdStubBuffer_AddRef(IRpcStubBuffer *pThis)
{
CStdStubBuffer *pStubBuffer;
assert(pThis);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
InterlockedIncrement(&pStubBuffer->RefCount);
return (ULONG) pStubBuffer->RefCount;
}
//+-------------------------------------------------------------------------
//
// Method: CStdStubBuffer_Release, public
//
// Synopsis: Decrement reference count.
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE
CStdStubBuffer_Release(IRpcStubBuffer *pThis)
{
long RefCount;
unsigned long count;
CStdStubBuffer *pStubBuffer;
assert(pThis);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
RefCount = InterlockedDecrement(&pStubBuffer->RefCount);
assert(RefCount >= 0);
if(RefCount == 0)
{
count = 0;
//Decrement the DLL reference count.
InterlockedDecrement(&DllRefCount);
//Free the stub buffer
MIDL_user_free(pStubBuffer);
}
else
count = (unsigned long) pStubBuffer->RefCount;
return count;
}
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_Connect(IRpcStubBuffer *pThis, IUnknown *pUnkServer)
{
HRESULT hr = E_UNEXPECTED;
CStdStubBuffer *pStubBuffer;
assert(pThis);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
pThis->lpVtbl->Disconnect(pThis);
if(pUnkServer)
{
hr = pUnkServer->lpVtbl->QueryInterface(pUnkServer, &IID_IUnknown, &pStubBuffer->punkObject);
}
return hr;
}
void STDMETHODCALLTYPE
CStdStubBuffer_Disconnect(IRpcStubBuffer *pThis)
{
CStdStubBuffer *pStubBuffer;
long temp;
int j;
IUnknown *punkObject;
assert(pThis);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
punkObject = pStubBuffer->punkObject;
//Free the interface pointers held by the stub buffer
if(punkObject)
{
for(j = 0;
pStubBuffer->aInterfaceStub[j].lpVtbl;
j++)
{
temp = InterlockedExchange((long *) &pStubBuffer->aInterfaceStub[j].pvServerObject, 0);
if(temp)
punkObject->lpVtbl->Release(punkObject);
}
temp = InterlockedExchange((long *) &pStubBuffer->punkObject, 0);
if(temp)
punkObject->lpVtbl->Release(punkObject);
}
}
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_Invoke(
IRpcStubBuffer *pThis,
RPCOLEMESSAGE *prpcmsg,
IRpcChannelBuffer *pRpcChannelBuffer)
{
HRESULT hr = S_OK;
unsigned char **ppTemp;
unsigned char *pTemp;
CInterfaceStubVtbl *pStubVtbl;
CInterfaceStub *pInterfaceStub;
DWORD dwExceptionCode;
assert(pThis);
assert(prpcmsg);
assert(pRpcChannelBuffer);
pInterfaceStub = (CInterfaceStub *) pThis;
//Get a pointer to the stub vtbl.
ppTemp = (unsigned char **) pThis;
pTemp = *ppTemp;
pTemp -= sizeof(CInterfaceStubHeader);
pStubVtbl = (CInterfaceStubVtbl *) pTemp;
__try
{
//Check the data rep
//Check if we are connected to the server object.
if(pInterfaceStub->pvServerObject == 0)
{
CStdStubBuffer *pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
if(pStubBuffer->punkObject)
{
const IID *piid = NdrGetStubIID(pThis);
assert(piid);
hr = pStubBuffer->punkObject->lpVtbl->QueryInterface(pStubBuffer->punkObject, piid, &pInterfaceStub->pvServerObject);
if(FAILED(hr))
{
SetLastError(hr);
RpcRaiseException(RPC_E_FAULT);
}
}
else
{
//We are not connected to the server object.
SetLastError((unsigned long) CO_E_OBJNOTCONNECTED);
RpcRaiseException(RPC_E_FAULT);
}
}
//Check if procnum is valid.
if(prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount)
RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
(*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
pRpcChannelBuffer,
(PRPC_MESSAGE) prpcmsg,
pInterfaceStub->pvServerObject);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
dwExceptionCode = GetExceptionCode();
switch(dwExceptionCode)
{
case RPC_E_FAULT:
hr = GetLastError();
break;
case RPC_E_SERVERFAULT:
//Pass the server's exception to the channel.
dwExceptionCode = GetLastError();
RpcRaiseException(dwExceptionCode);
break;
default:
//Assume this is a win32 error code.
hr = HRESULT_FROM_WIN32(dwExceptionCode);
break;
}
}
return hr;
}
IRpcStubBuffer * STDMETHODCALLTYPE
CStdStubBuffer_IsIIDSupported(IRpcStubBuffer *pThis, REFIID riid)
{
int j;
CStdStubBuffer *pStubBuffer;
IRpcStubBuffer *pInterfaceStub = 0;
const IID *pIID;
assert(pThis);
assert(riid);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
//Search the interface stubs in the stub buffer
for(j = 0;
pStubBuffer->aInterfaceStub[j].lpVtbl && !pInterfaceStub;
j++)
{
pIID = NdrGetStubIID(&pStubBuffer->aInterfaceStub[j].lpVtbl);
assert(pIID);
if(memcmp(riid, pIID, sizeof(IID)) == 0)
{
//We found the interface!
if(pStubBuffer->aInterfaceStub[j].pvServerObject == 0)
{
//Check if the server object supports the interface.
if(pStubBuffer->punkObject)
{
pStubBuffer->punkObject->lpVtbl->QueryInterface(
pStubBuffer->punkObject,
riid,
&pStubBuffer->aInterfaceStub[j].pvServerObject);
}
}
if(pStubBuffer->aInterfaceStub[j].pvServerObject)
{
pInterfaceStub = (IRpcStubBuffer *)&pStubBuffer->aInterfaceStub[j].lpVtbl;
pInterfaceStub->lpVtbl->AddRef(pInterfaceStub);
}
}
}
return pInterfaceStub;
}
ULONG STDMETHODCALLTYPE
CStdStubBuffer_CountRefs(IRpcStubBuffer *pThis)
{
ULONG count = 0;
int j;
CStdStubBuffer *pStubBuffer;
assert(pThis);
pStubBuffer = NdrGetStubBuffer(pThis);
assert(pStubBuffer);
if(pStubBuffer->punkObject != 0)
count++;
//Search the interface stubs in the stub buffer
for(j = 0;
pStubBuffer->aInterfaceStub[j].lpVtbl;
j++)
{
//We found the interface!
if(pStubBuffer->aInterfaceStub[j].pvServerObject != 0)
count++;
}
return count;
}
HRESULT STDMETHODCALLTYPE
CStdStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *pThis, void **ppv)
{
HRESULT hr = E_UNEXPECTED;
assert(pThis);
assert(ppv);
*ppv = ((CInterfaceStub *)pThis)->pvServerObject;
if(*ppv)
hr = S_OK;
return hr;
}
void STDMETHODCALLTYPE
CStdStubBuffer_DebugServerRelease(IRpcStubBuffer *pthis, void *pv)
{
}
//+-------------------------------------------------------------------------
//
// Method: IUnknown_QueryInterface_Proxy
//
// Synopsis: Implementation of QueryInterface for interface proxy.
//
//--------------------------------------------------------------------------
HRESULT __stdcall
IUnknown_QueryInterface_Proxy(
IUnknown *pThis,
REFIID riid,
void **ppv)
{
HRESULT hr = E_NOINTERFACE;
CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
assert(pProxyBuffer);
hr = pProxyBuffer->punkOuter->lpVtbl->QueryInterface(pProxyBuffer->punkOuter, riid, ppv);
return hr;
};
//+-------------------------------------------------------------------------
//
// Method: IUnknown_AddRef_Proxy
//
// Synopsis: Implementation of AddRef for interface proxy.
//
//--------------------------------------------------------------------------
ULONG __stdcall
IUnknown_AddRef_Proxy(IUnknown *pThis)
{
CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
ULONG count;
count = pProxyBuffer->punkOuter->lpVtbl->AddRef(pProxyBuffer->punkOuter);
return count;
};
//+-------------------------------------------------------------------------
//
// Method: IUnknown_Release_Proxy
//
// Synopsis: Implementation of Release for interface proxy.
//
//--------------------------------------------------------------------------
ULONG __stdcall
IUnknown_Release_Proxy(IUnknown *pThis)
{
CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
ULONG count;
count = pProxyBuffer->punkOuter->lpVtbl->Release(pProxyBuffer->punkOuter);
return count;
};
void __RPC_STUB
IUnknown_QueryInterface_Stub(
IRpcChannelBuffer * _pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
void * _pvServerObject )
{
}
void __RPC_STUB
IUnknown_AddRef_Stub(
IRpcChannelBuffer * _pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
void * _pvServerObject )
{
}
void __RPC_STUB
IUnknown_Release_Stub(
IRpcChannelBuffer * _pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
void * _pvServerObject )
{
}
//+-------------------------------------------------------------------------
//
// Function: MIDL_user_allocate
//
// Synopsis: Allocate memory via OLE task allocator.
//
//--------------------------------------------------------------------------
void * __stdcall MIDL_user_allocate(size_t size)
{
void *pMemory;
pMemory = CoTaskMemAlloc(size);
if(0 == pMemory)
{
SetLastError((unsigned long) E_OUTOFMEMORY);
RpcRaiseException(RPC_E_FAULT);
}
return pMemory;
}
//+-------------------------------------------------------------------------
//
// Function: MIDL_user_free
//
// Synopsis: Free memory using OLE task allocator.
//
//--------------------------------------------------------------------------
void __stdcall MIDL_user_free(void *pMemory)
{
CoTaskMemFree(pMemory);
}
#endif // !defined(__RPC_DOS__) && !defined(__RPC_WIN16__)