#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__)