diff --git a/reactos/dll/win32/rpcrt4/cproxy.c b/reactos/dll/win32/rpcrt4/cproxy.c index c2d71f9fa07..f045e0c8e33 100644 --- a/reactos/dll/win32/rpcrt4/cproxy.c +++ b/reactos/dll/win32/rpcrt4/cproxy.c @@ -104,7 +104,7 @@ static HRESULT WINAPI ObjectStubless(DWORD index) unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; TRACE("(%p)->(%ld)([%d bytes]) ret=%08lx\n", iface, index, bytes, *(DWORD*)(args+bytes)); - return RPCRT4_NdrClientCall2(This->stubless->pStubDesc, fs, args); + return NdrClientCall2(This->stubless->pStubDesc, fs, args); } #else /* __i386__ */ @@ -119,20 +119,21 @@ struct StublessThunk { int dummy; }; HRESULT WINAPI StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, - PCInterfaceName name, - CInterfaceProxyVtbl *vtbl, - CInterfaceStubVtbl *svtbl, + const ProxyFileInfo *ProxyInfo, + int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppvObj) { StdProxyImpl *This; const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; + PCInterfaceName name = ProxyInfo->pNamesArray[Index]; + CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index]; TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name); - /* I can't find any other way to detect stubless proxies than this hack */ - if (!IsEqualGUID(vtbl->header.piid, riid)) { + /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */ + if (ProxyInfo->TableVersion > 1) { stubless = *(const void **)vtbl; vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1); TRACE("stubless=%p\n", stubless); @@ -150,11 +151,12 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, if (!This) return E_OUTOFMEMORY; if (stubless) { - unsigned i, count = svtbl->header.DispatchTableCount; + CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index]; + unsigned long i, count = svtbl->header.DispatchTableCount; /* Maybe the original vtbl is just modified directly to point at * ObjectStublessClientXXX thunks in real Windows, but I don't like it */ - TRACE("stubless thunks: count=%d\n", count); + TRACE("stubless thunks: count=%ld\n", count); This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); for (i=0; iVtbl[i] == (LPVOID)-1) { PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("method %d: stacksize=%d\n", i, bytes); + TRACE("method %ld: stacksize=%d\n", i, bytes); FILL_STUBLESS(thunk, i, bytes) This->PVtbl[i] = thunk; } @@ -186,7 +188,11 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, This->pChannel = NULL; *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; *ppvObj = &This->PVtbl; - IUnknown_AddRef((IUnknown *)*ppvObj); + /* if there is no outer unknown then the caller will control the lifetime + * of the proxy object through the proxy buffer, so no need to increment the + * ref count of the proxy object */ + if (pUnkOuter) + IUnknown_AddRef((IUnknown *)*ppvObj); IPSFactoryBuffer_AddRef(pPSFactory); return S_OK; diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index 3f0190c24aa..44bb5a99255 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -95,9 +95,7 @@ static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, debugstr_guid(riid),ppProxy,ppv); if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) return E_NOINTERFACE; - return StdProxy_Construct(riid, pUnkOuter, ProxyInfo->pNamesArray[Index], - ProxyInfo->pProxyVtblList[Index], - ProxyInfo->pStubVtblList[Index], iface, ppProxy, ppv); + return StdProxy_Construct(riid, pUnkOuter, ProxyInfo, Index, iface, ppProxy, ppv); } static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, @@ -139,9 +137,24 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, *ppv = NULL; if (!pPSFactoryBuffer->lpVtbl) { + const ProxyFileInfo **pProxyFileList2; pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; pPSFactoryBuffer->RefCount = 0; pPSFactoryBuffer->pProxyFileList = pProxyFileList; + for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) { + int i; + for (i = 0; i < (*pProxyFileList2)->TableSize; i++) { + /* FIXME: i think that different vtables should be copied for + * async interfaces */ + void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; + void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; + int j; + + for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) + if (!pRpcStubVtbl[j]) + pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; + } + } } if (IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); diff --git a/reactos/dll/win32/rpcrt4/cpsf.h b/reactos/dll/win32/rpcrt4/cpsf.h index 60364d39db2..cf1572b9ac6 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.h +++ b/reactos/dll/win32/rpcrt4/cpsf.h @@ -23,9 +23,8 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, - PCInterfaceName name, - CInterfaceProxyVtbl *vtbl, - CInterfaceStubVtbl *svtbl, + const ProxyFileInfo *ProxyInfo, + int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppvObj); @@ -43,4 +42,6 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); +const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; + #endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4/cstub.c b/reactos/dll/win32/rpcrt4/cstub.c index 2633298fe46..41c09437c3f 100644 --- a/reactos/dll/win32/rpcrt4/cstub.c +++ b/reactos/dll/win32/rpcrt4/cstub.c @@ -144,7 +144,10 @@ HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, DWORD dwPhase = STUB_UNMARSHAL; TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); - STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); + if (STUB_HEADER(This).pDispatchTable) + STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); + else /* pure interpreted */ + NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); return S_OK; } @@ -178,6 +181,20 @@ void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); } +const IRpcStubBufferVtbl CStdStubBuffer_Vtbl = +{ + CStdStubBuffer_QueryInterface, + CStdStubBuffer_AddRef, + NULL, + CStdStubBuffer_Connect, + CStdStubBuffer_Disconnect, + CStdStubBuffer_Invoke, + CStdStubBuffer_IsIIDSupported, + CStdStubBuffer_CountRefs, + CStdStubBuffer_DebugServerQueryInterface, + CStdStubBuffer_DebugServerRelease +}; + const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) { CStdStubBuffer *This = (CStdStubBuffer *)iface; diff --git a/reactos/dll/win32/rpcrt4/ndr_marshall.c b/reactos/dll/win32/rpcrt4/ndr_marshall.c index 4156a0e3421..47d78f574b3 100644 --- a/reactos/dll/win32/rpcrt4/ndr_marshall.c +++ b/reactos/dll/win32/rpcrt4/ndr_marshall.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "windef.h" #include "winbase.h" @@ -300,20 +301,43 @@ static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer) pStubMsg->pfnFree(Pointer); } +static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) +{ + return (*(const ULONG *)pFormat != -1); +} + PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); - return pFormat+4; + if (pStubMsg->fHasNewCorrDesc) + return pFormat+6; + else + return pFormat+4; } static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { + if (!IsConformanceOrVariancePresent(pFormat)) + { + pStubMsg->Offset = 0; + pStubMsg->ActualCount = pStubMsg->MaxCount; + goto done; + } + + pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); + pStubMsg->Buffer += 4; + TRACE("offset is %ld\n", pStubMsg->Offset); pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; - TRACE("unmarshalled variance is %ld\n", pStubMsg->ActualCount); - return pFormat+4; + TRACE("variance is %ld\n", pStubMsg->ActualCount); + +done: + if (pStubMsg->fHasNewCorrDesc) + return pFormat+6; + else + return pFormat+4; } PFORMAT_STRING ComputeConformanceOrVariance( @@ -325,8 +349,7 @@ PFORMAT_STRING ComputeConformanceOrVariance( LPVOID ptr = NULL; DWORD data = 0; - /* FIXME: is this correct? */ - if (pFormat[0] == 0xff) { + if (!IsConformanceOrVariancePresent(pFormat)) { /* null descriptor */ *pCount = def; goto finish_conf; @@ -428,7 +451,10 @@ done_conf_grab: finish_conf: TRACE("resulting conformance is %ld\n", *pCount); - return pFormat+4; + if (pStubMsg->fHasNewCorrDesc) + return pFormat+6; + else + return pFormat+4; } @@ -1773,7 +1799,10 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); if (fMustAlloc || !*ppMemory) + { *ppMemory = NdrAllocate(pStubMsg, size); + memset(*ppMemory, 0, size); + } pFormat += 4; if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; @@ -2026,7 +2055,6 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { - DWORD offset; DWORD esize = *(const WORD*)(pFormat+2); TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2038,13 +2066,11 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS return NULL; } pFormat = ReadConformance(pStubMsg, pFormat); - offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; pFormat = ReadVariance(pStubMsg, pFormat); if (!*ppMemory || fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize); - memcpy(*ppMemory + offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize); + memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize); pStubMsg->Buffer += pStubMsg->ActualCount * esize; EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2111,24 +2137,39 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size = 0, count, def; + ULONG count, def; + BOOL variance_present; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (pFormat[0] != RPC_FC_BOGUS_ARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + def = *(const WORD*)&pFormat[2]; pFormat += 4; pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - size = pStubMsg->MaxCount; - TRACE("conformance=%ld\n", size); + TRACE("conformance = %ld\n", pStubMsg->MaxCount); - if (*(const DWORD*)pFormat != 0xffffffff) - FIXME("compute variance\n"); - pFormat += 4; + variance_present = IsConformanceOrVariancePresent(pFormat); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); + TRACE("variance = %ld\n", pStubMsg->ActualCount); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size); + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); pStubMsg->Buffer += 4; + if (variance_present) + { + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); + pStubMsg->Buffer += 4; + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); + pStubMsg->Buffer += 4; + } - for (count=0; countActualCount; count++) pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL); STD_OVERFLOW_CHECK(pStubMsg); @@ -2144,25 +2185,33 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - DWORD size = 0, count, esize; + ULONG count, esize; unsigned char *pMemory; + TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + if (pFormat[0] != RPC_FC_BOGUS_ARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + pFormat += 4; pFormat = ReadConformance(pStubMsg, pFormat); - size = pStubMsg->MaxCount; - TRACE("conformance=%ld\n", size); - - pFormat += 4; + pFormat = ReadVariance(pStubMsg, pFormat); esize = ComplexStructSize(pStubMsg, pFormat); if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, size*esize); + { + *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize); + memset(*ppMemory, 0, pStubMsg->MaxCount * esize); + } pMemory = *ppMemory; - for (count=0; countActualCount; count++) pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc); return NULL; @@ -2175,21 +2224,33 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size = 0, count, def; + ULONG count, def; + BOOL variance_present; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (pFormat[0] != RPC_FC_BOGUS_ARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + def = *(const WORD*)&pFormat[2]; pFormat += 4; pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - size = pStubMsg->MaxCount; - TRACE("conformance=%ld\n", size); + TRACE("conformance = %ld\n", pStubMsg->MaxCount); + pStubMsg->BufferLength += sizeof(ULONG); - if (*(const DWORD*)pFormat != 0xffffffff) - FIXME("compute variance\n"); - pFormat += 4; + variance_present = IsConformanceOrVariancePresent(pFormat); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); + TRACE("variance = %ld\n", pStubMsg->ActualCount); - for (count=0; countBufferLength += 2*sizeof(ULONG); + + for (count=0; count < pStubMsg->ActualCount; count++) pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL); } @@ -2202,6 +2263,13 @@ unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, DWORD size = 0; FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + if (pFormat[0] != RPC_FC_BOGUS_ARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + pFormat += 4; pFormat = ReadConformance(pStubMsg, pFormat); @@ -2220,21 +2288,27 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size = 0, count, def; + ULONG count, def; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (pFormat[0] != RPC_FC_BOGUS_ARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + def = *(const WORD*)&pFormat[2]; pFormat += 4; pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - size = pStubMsg->MaxCount; - TRACE("conformance=%ld\n", size); + TRACE("conformance = %ld\n", pStubMsg->MaxCount); - if (*(const DWORD*)pFormat != 0xffffffff) - FIXME("compute variance\n"); - pFormat += 4; + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); + TRACE("variance = %ld\n", pStubMsg->ActualCount); - for (count=0; countActualCount; count++) pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); } @@ -2934,6 +3008,7 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ERROR_STATUS_T: + case RPC_FC_ENUM32: ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory; pStubMsg->Buffer += sizeof(ULONG); @@ -2956,7 +3031,14 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); break; case RPC_FC_ENUM16: - case RPC_FC_ENUM32: + /* only 16-bits on the wire, so do a sanity check */ + if (*(UINT *)pMemory > USHRT_MAX) + RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; + pStubMsg->Buffer += sizeof(USHORT); + TRACE("value: 0x%04x\n", *(UINT *)pMemory); + break; default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); } @@ -3004,6 +3086,7 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall( case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ERROR_STATUS_T: + case RPC_FC_ENUM32: ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer; pStubMsg->Buffer += sizeof(ULONG); @@ -3028,7 +3111,12 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall( TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); break; case RPC_FC_ENUM16: - case RPC_FC_ENUM32: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + /* 16-bits on the wire, but int in memory */ + **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(USHORT); + TRACE("value: 0x%08x\n", **(UINT **)ppMemory); + break; default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); } @@ -3059,11 +3147,13 @@ static void WINAPI NdrBaseTypeBufferSize( case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: + case RPC_FC_ENUM16: ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT) - 1); pStubMsg->BufferLength += sizeof(USHORT); break; case RPC_FC_LONG: case RPC_FC_ULONG: + case RPC_FC_ENUM32: ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG) - 1); pStubMsg->BufferLength += sizeof(ULONG); break; @@ -3083,8 +3173,6 @@ static void WINAPI NdrBaseTypeBufferSize( ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t) - 1); pStubMsg->BufferLength += sizeof(error_status_t); break; - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); } @@ -3121,6 +3209,7 @@ static unsigned long WINAPI NdrBaseTypeMemorySize( return sizeof(error_status_t); case RPC_FC_ENUM16: case RPC_FC_ENUM32: + return sizeof(INT); default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); return 0; diff --git a/reactos/dll/win32/rpcrt4/ndr_midl.c b/reactos/dll/win32/rpcrt4/ndr_midl.c index 723c3c11603..cc43817462e 100644 --- a/reactos/dll/win32/rpcrt4/ndr_midl.c +++ b/reactos/dll/win32/rpcrt4/ndr_midl.c @@ -269,6 +269,8 @@ void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg) */ unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer ) { + RPC_STATUS status; + TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer); /* FIXME: how to handle errors? (raise exception?) */ @@ -281,10 +283,9 @@ unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char return NULL; } - if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) { - WARN("I_RpcSendReceive did not return success.\n"); - /* FIXME: raise exception? */ - } + status = I_RpcSendReceive(stubmsg->RpcMsg); + if (status != RPC_S_OK) + RpcRaiseException(status); stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; stubmsg->BufferStart = stubmsg->RpcMsg->Buffer; diff --git a/reactos/dll/win32/rpcrt4/ndr_misc.h b/reactos/dll/win32/rpcrt4/ndr_misc.h index 32f835dfd1d..0abeaed5b04 100644 --- a/reactos/dll/win32/rpcrt4/ndr_misc.h +++ b/reactos/dll/win32/rpcrt4/ndr_misc.h @@ -30,11 +30,6 @@ struct IPSFactoryBuffer; -LONG_PTR RPCRT4_NdrClientCall2(PMIDL_STUB_DESC pStubDesc, - PFORMAT_STRING pFormat, va_list args ); - -HRESULT RPCRT4_GetPSFactory(REFIID riid, struct IPSFactoryBuffer **ppPS); - #define ComputeConformance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount) #define ComputeVariance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->ActualCount) PFORMAT_STRING ComputeConformanceOrVariance( diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index 0919f9fdd96..4bdeefe633d 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -257,14 +257,16 @@ unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { stream = RpcStream_Create(pStubMsg, TRUE); if (stream) { - hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, - pStubMsg->dwDestContext, pStubMsg->pvDestContext, - MSHLFLAGS_NORMAL); + if (pMemory) + hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, + pStubMsg->dwDestContext, pStubMsg->pvDestContext, + MSHLFLAGS_NORMAL); + else + hr = S_OK; + IStream_Release(stream); - if (FAILED(hr)) { - IUnknown_Release((LPUNKNOWN)pMemory); + if (FAILED(hr)) RpcRaiseException(hr); - } } } return NULL; @@ -355,17 +357,3 @@ void WINAPI NdrOleFree(void *NodeToFree) if (!LoadCOM()) return; COM_MemFree(NodeToFree); } - -/* internal */ -HRESULT RPCRT4_GetPSFactory(REFIID riid, LPPSFACTORYBUFFER *pPS) -{ - HRESULT hr; - CLSID clsid; - - if (!LoadCOM()) return RPC_E_UNEXPECTED; - hr = COM_GetPSClsid(riid, &clsid); - if (FAILED(hr)) return hr; - hr = COM_GetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, - &IID_IPSFactoryBuffer, (LPVOID *)pPS); - return hr; -} diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index 40f8dcc6d30..ec31fda0935 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -1,7 +1,8 @@ /* - * NDR client stuff + * NDR -Oi,-Oif,-Oicf Interpreter * * Copyright 2001 Ove Kåven, TransGaming Technologies + * Copyright 2003-5 Robert Shearman (for CodeWeavers) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +19,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * TODO: - * - Exception handling - * - Context stuff - * - Who knows + * - Pipes + * - Some types of binding handles */ +#include "config.h" +#include "wine/port.h" + #include #include #include @@ -32,75 +35,1444 @@ #include "winerror.h" #include "winreg.h" +#include "objbase.h" #include "rpc.h" -#include "rpcndr.h" +#include "rpcproxy.h" +#include "ndrtypes.h" #include "wine/debug.h" +#include "wine/rpcfc.h" #include "ndr_misc.h" +#include "cpsf.h" -WINE_DEFAULT_DEBUG_CHANNEL(ole); +WINE_DEFAULT_DEBUG_CHANNEL(rpc); -/*********************************************************************** - * Note: this should return a CLIENT_CALL_RETURN, but calling convention for - * returning structures/unions is different between Windows and gcc on i386. - */ -LONG_PTR RPCRT4_NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, va_list args) +#define NDR_TABLE_MASK 127 + +static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - - RPC_CLIENT_INTERFACE *rpc_cli_if = (RPC_CLIENT_INTERFACE *)(pStubDesc->RpcInterfaceInformation); - LONG_PTR ret = 0; -/* - RPC_BINDING_HANDLE handle = 0; - RPC_MESSAGE rpcmsg; - MIDL_STUB_MESSAGE stubmsg; -*/ - - FIXME("(pStubDec == ^%p,pFormat = ^%p,...): stub\n", pStubDesc, pFormat); - if (rpc_cli_if) /* NULL for objects */ { - TRACE(" *rpc_cli_if (== ^%p) == (RPC_CLIENT_INTERFACE):\n", pStubDesc); - TRACE(" Length == %d\n", rpc_cli_if->Length); - TRACE(" InterfaceID == %s (%d.%d)\n", debugstr_guid(&rpc_cli_if->InterfaceId.SyntaxGUID), - rpc_cli_if->InterfaceId.SyntaxVersion.MajorVersion, rpc_cli_if->InterfaceId.SyntaxVersion.MinorVersion); - TRACE(" TransferSyntax == %s (%d.%d)\n", debugstr_guid(&rpc_cli_if->TransferSyntax.SyntaxGUID), - rpc_cli_if->TransferSyntax.SyntaxVersion.MajorVersion, rpc_cli_if->TransferSyntax.SyntaxVersion.MinorVersion); - TRACE(" DispatchTable == ^%p\n", rpc_cli_if->DispatchTable); - TRACE(" RpcProtseqEndpointCount == ^%d\n", rpc_cli_if->RpcProtseqEndpointCount); - TRACE(" RpcProtseqEndpoint == ^%p\n", rpc_cli_if->RpcProtseqEndpoint); - TRACE(" Flags == ^%d\n", rpc_cli_if->Flags); - } - - /* for now, while these functons are under development, this is too sketchy. commented out. */ - /* - NdrClientInitializeNew( &rpcmsg, &stubmsg, pStubDesc, 0 ); - - handle = (RPC_BINDING_HANDLE)0xdeadbeef; */ /* FIXME */ - - /* stubmsg.BufferLength = 0;*/ /* FIXME */ - /* - NdrGetBuffer( &stubmsg, stubmsg.BufferLength, handle ); - NdrSendReceive( &stubmsg, stubmsg.Buffer ); - NdrFreeBuffer( &stubmsg ); - */ - return ret; + NDR_BUFFERSIZE m = NdrBufferSizer[pFormat[0] & NDR_TABLE_MASK]; + if (m) m(pStubMsg, pMemory, pFormat); + else + { + FIXME("format type 0x%x not implemented\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } } -/*********************************************************************** - * NdrClientCall2 [RPCRT4.@] - * - * Note: this should return a CLIENT_CALL_RETURN, but calling convention for - * returning structures/unions is different between Windows and gcc on i386. - */ -LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, - PFORMAT_STRING pFormat, ...) +static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - LONG_PTR ret; - va_list args; - - TRACE("(%p,%p,...)\n", pStubDesc, pFormat); - - va_start(args, pFormat); - ret = RPCRT4_NdrClientCall2(pStubDesc, pFormat, args); - va_end(args); - return ret; + NDR_MARSHALL m = NdrMarshaller[pFormat[0] & NDR_TABLE_MASK]; + if (m) return m(pStubMsg, pMemory, pFormat); + else + { + FIXME("format type 0x%x not implemented\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return NULL; + } +} + +static inline unsigned char *call_unmarshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc) +{ + NDR_UNMARSHALL m = NdrUnmarshaller[pFormat[0] & NDR_TABLE_MASK]; + if (m) return m(pStubMsg, ppMemory, pFormat, fMustAlloc); + else + { + FIXME("format type 0x%x not implemented\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return NULL; + } +} + +static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) +{ + NDR_FREE m = NdrFreer[pFormat[0] & NDR_TABLE_MASK]; + if (m) m(pStubMsg, pMemory, pFormat); + else + { + FIXME("format type 0x%x not implemented\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) +{ + NDR_MEMORYSIZE m = NdrMemorySizer[pFormat[0] & NDR_TABLE_MASK]; + if (m) return m(pStubMsg, pFormat); + else + { + FIXME("format type 0x%x not implemented\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return 0; + } +} + +/* there can't be any alignment with the structures in this file */ +#include "pshpack1.h" + +#define STUBLESS_UNMARSHAL 1 +#define STUBLESS_CALLSERVER 2 +#define STUBLESS_CALCSIZE 3 +#define STUBLESS_GETBUFFER 4 +#define STUBLESS_MARSHAL 5 + +/* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */ +typedef struct _NDR_PROC_HEADER +{ + /* type of handle to use: + * RPC_FC_BIND_EXPLICIT = 0 - Explicit handle. + * Handle is passed as a parameter to the function. + * Indicates that explicit handle information follows the header, + * which actually describes the handle. + * RPC_FC_BIND_GENERIC = 31 - Implicit handle with custom binding routines + * (MIDL_STUB_DESC::IMPLICIT_HANDLE_INFO::pGenericBindingInfo) + * RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by + * calling application + * RPC_FC_AUTO_HANDLE = 33 - Automatic handle + * RPC_FC_CALLBACK_HANDLE = 34 - undocmented + */ + unsigned char handle_type; + + /* procedure flags: + * Oi_FULL_PTR_USED = 0x01 - A full pointer can have the value NULL and can + * change during the call from NULL to non-NULL and supports aliasing + * and cycles. Indicates that the NdrFullPointerXlatInit function + * should be called. + * Oi_RPCSS_ALLOC_USED = 0x02 - Use RpcSS allocate/free routines instead of + * normal allocate/free routines + * Oi_OBJECT_PROC = 0x04 - Indicates a procedure that is part of an OLE + * interface, rather than a DCE RPC interface. + * Oi_HAS_RPCFLAGS = 0x08 - Indicates that the rpc_flags element is + * present in the header. + * Oi_HAS_COMM_OR_FAULT = 0x20 - If Oi_OBJECT_PROC not present only then + * indicates that the procedure has the comm_status or fault_status + * MIDL attribute. + * Oi_OBJ_USE_V2_INTERPRETER = 0x20 - If Oi_OBJECT_PROC present only + * then indicates that the format string is in -Oif or -Oicf format + * Oi_USE_NEW_INIT_ROUTINES = 0x40 - Use NdrXInitializeNew instead of + * NdrXInitialize? + */ + unsigned char Oi_flags; + + /* the zero-based index of the procedure */ + unsigned short proc_num; + + /* total size of all parameters on the stack, including any "this" + * pointer and/or return value */ + unsigned short stack_size; +} NDR_PROC_HEADER; + +/* same as above struct except additional element rpc_flags */ +typedef struct _NDR_PROC_HEADER_RPC +{ + unsigned char handle_type; + unsigned char Oi_flags; + + /* + * RPCF_Idempotent = 0x0001 - [idempotent] MIDL attribute + * RPCF_Broadcast = 0x0002 - [broadcast] MIDL attribute + * RPCF_Maybe = 0x0004 - [maybe] MIDL attribute + * Reserved = 0x0008 - 0x0080 + * RPCF_Message = 0x0100 - [message] MIDL attribute + * Reserved = 0x0200 - 0x1000 + * RPCF_InputSynchronous = 0x2000 - unknown + * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute + * Reserved = 0x8000 + */ + unsigned long rpc_flags; + unsigned short proc_num; + unsigned short stack_size; + +} NDR_PROC_HEADER_RPC; + +typedef struct _NDR_PROC_PARTIAL_OIF_HEADER +{ + /* the pre-computed client buffer size so that interpreter can skip all + * or some (if the flag RPC_FC_PROC_OI2F_CLTMUSTSIZE is specified) of the + * sizing pass */ + unsigned short constant_client_buffer_size; + + /* the pre-computed server buffer size so that interpreter can skip all + * or some (if the flag RPC_FC_PROC_OI2F_SRVMUSTSIZE is specified) of the + * sizing pass */ + unsigned short constant_server_buffer_size; + + /* -Oif flags: + * RPC_FC_PROC_OI2F_SRVMUSTSIZE = 0x01 - the server must perform a + * sizing pass. + * RPC_FC_PROC_OI2F_CLTMUSTSIZE = 0x02 - the client must perform a + * sizing pass. + * RPC_FC_PROC_OI2F_HASRETURN = 0x04 - procedure has a return value. + * RPC_FC_PROC_OI2F_HASPIPES = 0x08 - the pipe package should be used. + * RPC_FC_PROC_OI2F_HASASYNCUUID = 0x20 - indicates an asynchronous DCOM + * procedure. + * RPC_FC_PROC_OI2F_HASEXTS = 0x40 - indicates that Windows 2000 + * extensions are in use. + * RPC_FC_PROC_OI2F_HASASYNCHND = 0x80 - indicates an asynchronous RPC + * procedure. + */ + unsigned char Oif_flags; + + /* number of params */ + unsigned char number_of_params; +} NDR_PROC_PARTIAL_OIF_HEADER; + +/* Windows 2000 extensions */ +typedef struct _NDR_PROC_EXTENSION +{ + /* size in bytes of all following extensions */ + unsigned char extension_version; + + /* extension flags: + * HasNewCorrDesc = 0x01 - indicates new correlation descriptors in use + * ClientCorrCheck = 0x02 - client needs correlation check + * ServerCorrCheck = 0x04 - server needs correlation check + * HasNotify = 0x08 - should call MIDL [notify] routine @ NotifyIndex + * HasNotify2 = 0x10 - should call MIDL [notify_flag] routine @ + * NotifyIndex + */ + unsigned char ext_flags; + + /* client cache size hint */ + unsigned short ClientCorrHint; + + /* server cache size hint */ + unsigned short ServerCorrHint; + + /* index of routine in MIDL_STUB_DESC::NotifyRoutineTable to call if + * HasNotify or HasNotify2 flag set */ + unsigned short NotifyIndex; +} NDR_PROC_EXTENSION; + +/* usually generated only on IA64 */ +typedef struct _NDR_PROC_EXTENSION_64 +{ + NDR_PROC_EXTENSION ext; + + /* needed only on IA64 to cope with float/register loading */ + unsigned short FloatDoubleMask; +} NDR_PROC_EXTENSION_64; + + +typedef struct _NDR_PARAM_OI_BASETYPE +{ + /* parameter direction. One of: + * FC_IN_PARAM_BASETYPE = 0x4e - an in param + * FC_RETURN_PARAM_BASETYPE = 0x53 - a return param + */ + unsigned char param_direction; + + /* One of: FC_BYTE,FC_CHAR,FC_SMALL,FC_USMALL,FC_WCHAR,FC_SHORT,FC_USHORT, + * FC_LONG,FC_ULONG,FC_FLOAT,FC_HYPER,FC_DOUBLE,FC_ENUM16,FC_ENUM32, + * FC_ERROR_STATUS_T,FC_INT3264,FC_UINT3264 */ + unsigned char type_format_char; +} NDR_PARAM_OI_BASETYPE; + +typedef struct _NDR_PARAM_OI_OTHER +{ + /* One of: + * FC_IN_PARAM = 0x4d - An in param + * FC_IN_OUT_PARAM = 0x50 - An in/out param + * FC_OUT_PARAM = 0x51 - An out param + * FC_RETURN_PARAM = 0x52 - A return value + * FC_IN_PARAM_NO_FREE_INST = 0x4f - A param for which no freeing is done + */ + unsigned char param_direction; + + /* Size of param on stack in NUMBERS OF INTS */ + unsigned char stack_size; + + /* offset in the type format string table */ + unsigned short type_offset; +} NDR_PARAM_OI_OTHER; + +typedef struct _NDR_PARAM_OIF_BASETYPE +{ + PARAM_ATTRIBUTES param_attributes; + + /* the offset on the calling stack where the parameter is located */ + unsigned short stack_offset; + + /* see NDR_PARAM_OI_BASETYPE::type_format_char */ + unsigned char type_format_char; + + /* always FC_PAD */ + unsigned char unused; +} NDR_PARAM_OIF_BASETYPE; + +typedef struct _NDR_PARAM_OIF_OTHER +{ + PARAM_ATTRIBUTES param_attributes; + + /* see NDR_PARAM_OIF_BASETYPE::stack_offset */ + unsigned short stack_offset; + + /* offset into the provided type format string where the type for this + * parameter starts */ + unsigned short type_offset; +} NDR_PARAM_OIF_OTHER; + +/* explicit handle description for FC_BIND_PRIMITIVE type */ +typedef struct _NDR_EHD_PRIMITIVE +{ + /* FC_BIND_PRIMITIVE */ + unsigned char handle_type; + + /* is the handle passed in via a pointer? */ + unsigned char flag; + + /* offset from the beginning of the stack to the handle in bytes */ + unsigned short offset; +} NDR_EHD_PRIMITIVE; + +/* explicit handle description for FC_BIND_GENERIC type */ +typedef struct _NDR_EHD_GENERIC +{ + /* FC_BIND_GENERIC */ + unsigned char handle_type; + + /* upper 4bits is a flag indicating whether the handle is passed in + * via a pointer. lower 4bits is the size of the user defined generic + * handle type. the size must be less than or equal to the machine + * register size */ + unsigned char flag_and_size; + + /* offset from the beginning of the stack to the handle in bytes */ + unsigned short offset; + + /* the index into the aGenericBindingRoutinesPairs field of MIDL_STUB_DESC + * giving the bind and unbind routines for the handle */ + unsigned char binding_routine_pair_index; + + /* FC_PAD */ + unsigned char unused; +} NDR_EHD_GENERIC; + +/* explicit handle description for FC_BIND_CONTEXT type */ +typedef struct _NDR_EHD_CONTEXT +{ + /* FC_BIND_CONTEXT */ + unsigned char handle_type; + + /* Any of the following flags: + * NDR_CONTEXT_HANDLE_CANNOT_BE_NULL = 0x01 + * NDR_CONTEXT_HANDLE_SERIALIZE = 0x02 + * NDR_CONTEXT_HANDLE_NO_SERIALIZE = 0x04 + * NDR_STRICT_CONTEXT_HANDLE = 0x08 + * HANDLE_PARAM_IS_OUT = 0x20 + * HANDLE_PARAM_IS_RETURN = 0x21 + * HANDLE_PARAM_IS_IN = 0x40 + * HANDLE_PARAM_IS_VIA_PTR = 0x80 + */ + unsigned char flags; + + /* offset from the beginning of the stack to the handle in bytes */ + unsigned short offset; + + /* zero-based index on rundown routine in apfnNdrRundownRoutines field + * of MIDL_STUB_DESC */ + unsigned char context_rundown_routine_index; + + /* varies depending on NDR version used. + * V1: zero-based index into parameters + * V2: zero-based index into handles that are parameters */ + unsigned char param_num; +} NDR_EHD_CONTEXT; + +#include "poppack.h" + +void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage) +{ +#if 0 /* these functions are not defined yet */ + pMessage->pfnAllocate = NdrRpcSmClientAllocate; + pMessage->pfnFree = NdrRpcSmClientFree; +#endif +} + +static void WINAPI dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes) +{ + if (param_attributes.MustSize) TRACE(" MustSize"); + if (param_attributes.MustFree) TRACE(" MustFree"); + if (param_attributes.IsPipe) TRACE(" IsPipe"); + if (param_attributes.IsIn) TRACE(" IsIn"); + if (param_attributes.IsOut) TRACE(" IsOut"); + if (param_attributes.IsReturn) TRACE(" IsReturn"); + if (param_attributes.IsBasetype) TRACE(" IsBasetype"); + if (param_attributes.IsByValue) TRACE(" IsByValue"); + if (param_attributes.IsSimpleRef) TRACE(" IsSimpleRef"); + if (param_attributes.IsDontCallFreeInst) TRACE(" IsDontCallFreeInst"); + if (param_attributes.SaveForAsyncFinish) TRACE(" SaveForAsyncFinish"); + if (param_attributes.ServerAllocSize) TRACE(" ServerAllocSize = %d", param_attributes.ServerAllocSize * 8); +} + +/* FIXME: this will be different on other plaftorms than i386 */ +#define ARG_FROM_OFFSET(args, offset) (*(unsigned char **)args + offset) + +/* the return type should be CLIENT_CALL_RETURN, but this is incompatible + * with the way gcc returns structures. "void *" should be the largest type + * that MIDL should allow you to return anyway */ +LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...) +{ + /* pointer to start of stack where arguments start */ + /* FIXME: not portable */ + unsigned char *args = (unsigned char *)(&pFormat+1); + RPC_MESSAGE rpcMsg; + MIDL_STUB_MESSAGE stubMsg; + handle_t hBinding = NULL; + /* procedure number */ + unsigned short procedure_number; + /* size of stack */ + unsigned short stack_size; + /* current stack offset */ + unsigned short current_stack_offset; + /* number of parameters. optional for client to give it to us */ + unsigned char number_of_params = ~0; + /* counter */ + unsigned short i; + /* cache of Oif_flags from v2 procedure header */ + unsigned char Oif_flags = 0; + /* cache of extension flags from NDR_PROC_EXTENSION */ + unsigned char ext_flags = 0; + /* the type of pass we are currently doing */ + int phase; + /* header for procedure string */ + const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; + /* offset in format string for start of params */ + int parameter_start_offset; + /* current format string offset */ + int current_offset; + /* -Oif or -Oicf generated format */ + BOOL bV2Format = FALSE; + /* the value to return to the client from the remote procedure */ + LONG_PTR RetVal = 0; + /* the pointer to the object when in OLE mode */ + void * This = NULL; + + TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); + TRACE("&first_argument = %p -> %p\n", args, ARG_FROM_OFFSET(args, 0)); + + /* Later NDR language versions probably won't be backwards compatible */ + if (pStubDesc->Version > 0x50002) + { + FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); + } + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + { + NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0]; + stack_size = pProcHeader->stack_size; + procedure_number = pProcHeader->proc_num; + current_offset = sizeof(NDR_PROC_HEADER_RPC); + } + else + { + stack_size = pProcHeader->stack_size; + procedure_number = pProcHeader->proc_num; + TRACE("proc num: %d\n", procedure_number); + current_offset = sizeof(NDR_PROC_HEADER); + } + + TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); + TRACE("MIDL stub version = 0x%lx\n", pStubDesc->MIDLVersion); + + /* we only need a handle if this isn't an object method */ + if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)) + { + /* binding */ + switch (pProcHeader->handle_type) + { + /* explicit binding: parse additional section */ + case RPC_FC_BIND_EXPLICIT: + switch (pFormat[current_offset]) /* handle_type */ + { + case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ + { + NDR_EHD_PRIMITIVE * pDesc = (NDR_EHD_PRIMITIVE *)&pFormat[current_offset]; + + TRACE("Explicit primitive handle @ %d\n", pDesc->offset); + + if (pDesc->flag) /* pointer to binding */ + hBinding = **(handle_t **)ARG_FROM_OFFSET(args, pDesc->offset); + else + hBinding = *(handle_t *)ARG_FROM_OFFSET(args, pDesc->offset); + current_offset += sizeof(NDR_EHD_PRIMITIVE); + break; + } + case RPC_FC_BIND_GENERIC: /* explicit generic */ + FIXME("RPC_FC_BIND_GENERIC\n"); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ + current_offset += sizeof(NDR_EHD_GENERIC); + break; + case RPC_FC_BIND_CONTEXT: /* explicit context */ + { + NDR_EHD_CONTEXT * pDesc = (NDR_EHD_CONTEXT *)&pFormat[current_offset]; + TRACE("Explicit bind context\n"); + hBinding = NDRCContextBinding(*(NDR_CCONTEXT *)ARG_FROM_OFFSET(args, pDesc->offset)); + /* FIXME: should we store this structure in stubMsg.pContext? */ + current_offset += sizeof(NDR_EHD_CONTEXT); + break; + } + default: + ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + break; + case RPC_FC_BIND_GENERIC: /* implicit generic */ + FIXME("RPC_FC_BIND_GENERIC\n"); + RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ + break; + case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ + TRACE("Implicit primitive handle\n"); + hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle; + break; + case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ + FIXME("RPC_FC_CALLBACK_HANDLE\n"); + break; + case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ + /* strictly speaking, it isn't necessary to set hBinding here + * since it isn't actually used (hence the automatic in its name), + * but then why does MIDL generate a valid entry in the + * MIDL_STUB_DESC for it? */ + TRACE("Implicit auto handle\n"); + hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle; + break; + default: + ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + } + + bV2Format = (pStubDesc->Version >= 0x20000); + + if (bV2Format) + { + NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader = + (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset]; + + Oif_flags = pOIFHeader->Oif_flags; + number_of_params = pOIFHeader->number_of_params; + + current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); + } + + TRACE("Oif_flags = 0x%02x\n", Oif_flags); + + if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS) + { + NDR_PROC_EXTENSION * pExtensions = + (NDR_PROC_EXTENSION *)&pFormat[current_offset]; + ext_flags = pExtensions->ext_flags; + current_offset += pExtensions->extension_version; + } + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + { + /* object is always the first argument */ + This = *(void **)ARG_FROM_OFFSET(args, 0); + NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); + } + else + NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number); + + /* create the full pointer translation tables, if requested */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) +#if 0 + stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); +#else + FIXME("initialize full pointer translation tables\n"); +#endif + + stubMsg.BufferLength = 0; + + /* store the RPC flags away */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + rpcMsg.RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; + + /* use alternate memory allocation routines */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) + NdrRpcSmSetClientToOsf(&stubMsg); + + if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + { + FIXME("pipes not supported yet\n"); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ + /* init pipes package */ + /* NdrPipesInitialize(...) */ + } + if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + { + /* initialize extra correlation package */ + FIXME("new correlation description not implemented\n"); + stubMsg.fHasNewCorrDesc = TRUE; + } + + parameter_start_offset = current_offset; + + /* order of phases: + * 1. PROXY_CALCSIZE - calculate the buffer size + * 2. PROXY_GETBUFFER - allocate the buffer + * 3. PROXY_MARHSAL - marshal [in] params into the buffer + * 4. PROXY_SENDRECEIVE - send/receive buffer + * 5. PROXY_UNMARHSAL - unmarshal [out] params from buffer + */ + for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++) + { + TRACE("phase = %d\n", phase); + switch (phase) + { + case PROXY_GETBUFFER: + /* allocate the buffer */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + NdrProxyGetBuffer(This, &stubMsg); + else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + /* NdrGetPipeBuffer(...) */ + FIXME("pipes not supported yet\n"); + else + { + if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) +#if 0 + NdrNsGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding); +#else + FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n"); +#endif + else + NdrGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding); + } + break; + case PROXY_SENDRECEIVE: + /* send the [in] params and receive the [out] and [retval] + * params */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + NdrProxySendReceive(This, &stubMsg); + else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + /* NdrPipesSendReceive(...) */ + FIXME("pipes not supported yet\n"); + else + { + if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) +#if 0 + NdrNsSendReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); +#else + FIXME("using auto handle - call NdrNsSendReceive when it gets implemented\n"); +#endif + else + NdrSendReceive(&stubMsg, stubMsg.Buffer); + } + + /* convert strings, floating point values and endianess into our + * preferred format */ + if ((rpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) + NdrConvert(&stubMsg, pFormat); + + break; + case PROXY_CALCSIZE: + case PROXY_MARSHAL: + case PROXY_UNMARSHAL: + current_offset = parameter_start_offset; + current_stack_offset = 0; + + /* NOTE: V1 style format does't terminate on the number_of_params + * condition as it doesn't have this attribute. Instead it + * terminates when the stack size given in the header is exceeded. + */ + for (i = 0; i < number_of_params; i++) + { + if (bV2Format) /* new parameter format */ + { + NDR_PARAM_OIF_BASETYPE * pParam = + (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; + unsigned char * pArg; + + current_stack_offset = pParam->stack_offset; + pArg = ARG_FROM_OFFSET(args, current_stack_offset); + + TRACE("param[%d]: new format\n", i); + TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset); + TRACE("\tmemory addr (before): %p\n", pArg); + + if (pParam->param_attributes.IsBasetype) + { + const unsigned char * pTypeFormat = + &pParam->type_format_char; + + if (pParam->param_attributes.IsSimpleRef) + pArg = *(unsigned char **)pArg; + + TRACE("\tbase type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_attributes.IsIn) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_attributes.IsIn) + call_marshaller(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_attributes.IsOut) + { + unsigned char *pRetVal = (unsigned char *)&RetVal; + if (pParam->param_attributes.IsReturn) + call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0); + else + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + TRACE("pRetVal = %p\n", pRetVal); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); + } + else + { + NDR_PARAM_OIF_OTHER * pParamOther = + (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &(pStubDesc->pFormatTypes[pParamOther->type_offset]); + + /* if a simple ref pointer then we have to do the + * check for the pointer being non-NULL. */ + if (pParam->param_attributes.IsSimpleRef) + { + if (!*(unsigned char **)pArg) + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + + TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + else + call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + case PROXY_MARSHAL: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_marshaller(&stubMsg, pArg, pTypeFormat); + else + call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + case PROXY_UNMARSHAL: + if (pParam->param_attributes.IsOut) + { + unsigned char *pRetVal = (unsigned char *)&RetVal; + if (pParam->param_attributes.IsReturn) + call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0); + else if (pParam->param_attributes.IsByValue) + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + else + call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_OTHER); + } + TRACE("\tmemory addr (after): %p\n", pArg); + } + else /* old parameter format */ + { + NDR_PARAM_OI_BASETYPE * pParam = + (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; + unsigned char * pArg = ARG_FROM_OFFSET(args, current_stack_offset); + + /* no more parameters; exit loop */ + if (current_stack_offset > stack_size) + break; + + TRACE("param[%d]: old format\n", i); + TRACE("\tparam_direction: %x\n", pParam->param_direction); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset); + TRACE("\tmemory addr (before): %p\n", pArg); + + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || + pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + const unsigned char * pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_marshaller(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + if (pParam->param_direction & RPC_FC_RETURN_PARAM) + call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0); + else + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat); + current_offset += sizeof(NDR_PARAM_OI_BASETYPE); + } + else + { + NDR_PARAM_OI_OTHER * pParamOther = + (NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; + + const unsigned char *pTypeFormat = + &pStubDesc->pFormatTypes[pParamOther->type_offset]; + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_direction == RPC_FC_IN_PARAM || + pParam->param_direction & RPC_FC_IN_OUT_PARAM) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM || + pParam->param_direction & RPC_FC_IN_OUT_PARAM) + call_marshaller(&stubMsg, pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_OUT_PARAM) + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + else if (pParam->param_direction == RPC_FC_RETURN_PARAM) + call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0); + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += pParamOther->stack_size * sizeof(INT); + current_offset += sizeof(NDR_PARAM_OI_OTHER); + } + TRACE("\tmemory addr (after): %p\n", pArg); + } + } + + break; + default: + ERR("shouldn't reach here. phase %d\n", phase); + break; + } + } + + /* FIXME: unbind the binding handle */ + + if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + { + /* free extra correlation package */ + /* NdrCorrelationFree(&stubMsg); */ + } + + if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + { + /* NdrPipesDone(...) */ + } + +#if 0 + /* free the full pointer translation tables */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); +#endif + + /* free marshalling buffer */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + NdrProxyFreeBuffer(This, &stubMsg); + else + NdrFreeBuffer(&stubMsg); + + TRACE("RetVal = 0x%lx\n", RetVal); + + return RetVal; +} + +/* calls a function with the specificed arguments, restoring the stack + * properly afterwards as we don't know the calling convention of the + * function */ +#if defined __i386__ && defined _MSC_VER +__declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size) +{ + __asm + { + push ebp + push edi ; Save registers + push esi + mov ebp, esp + mov eax, [ebp+16] ; Get stack size + sub esp, eax ; Make room in stack for arguments + mov edi, esp + mov ecx, eax + mov esi, [ebp+12] + shr ecx, 2 + cld + rep movsd ; Copy dword blocks + call [ebp+8] ; Call function + lea esp, [ebp-8] ; Restore stack + pop ebp ; Restore registers + pop esi + pop edi + ret + } +} +#elif defined __i386__ && defined __GNUC__ +LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size); +__ASM_GLOBAL_FUNC(call_server_func, + "pushl %ebp\n\t" + "movl %esp, %ebp\n\t" + "pushl %edi\n\t" /* Save registers */ + "pushl %esi\n\t" + "movl 16(%ebp), %eax\n\t" /* Get stack size */ + "subl %eax, %esp\n\t" /* Make room in stack for arguments */ + "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for MacOS X */ + "movl %esp, %edi\n\t" + "movl %eax, %ecx\n\t" + "movl 12(%ebp), %esi\n\t" + "shrl $2, %ecx\n\t" /* divide by 4 */ + "cld\n\t" + "rep; movsl\n\t" /* Copy dword blocks */ + "call *8(%ebp)\n\t" /* Call function */ + "leal -8(%ebp), %esp\n\t" /* Restore stack */ + "popl %esi\n\t" /* Restore registers */ + "popl %edi\n\t" + "popl %ebp\n\t" + "ret\n" ); +#else +#warning call_server_func not implemented for your architecture +LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) +{ + FIXME("Not implemented for your architecture\n"); + return 0; +} +#endif + +/* FIXME: need to free some stuff in here too */ +long WINAPI NdrStubCall2( + struct IRpcStubBuffer * pThis, + struct IRpcChannelBuffer * pChannel, + PRPC_MESSAGE pRpcMsg, + unsigned long * pdwStubPhase) +{ + const MIDL_SERVER_INFO *pServerInfo; + const MIDL_STUB_DESC *pStubDesc; + PFORMAT_STRING pFormat; + MIDL_STUB_MESSAGE stubMsg; + /* pointer to start of stack to pass into stub implementation */ + unsigned char * args; + /* size of stack */ + unsigned short stack_size; + /* current stack offset */ + unsigned short current_stack_offset; + /* number of parameters. optional for client to give it to us */ + unsigned char number_of_params = ~0; + /* counter */ + unsigned short i; + /* cache of Oif_flags from v2 procedure header */ + unsigned char Oif_flags = 0; + /* cache of extension flags from NDR_PROC_EXTENSION */ + unsigned char ext_flags = 0; + /* the type of pass we are currently doing */ + int phase; + /* header for procedure string */ + const NDR_PROC_HEADER *pProcHeader; + /* offset in format string for start of params */ + int parameter_start_offset; + /* current format string offset */ + int current_offset; + /* -Oif or -Oicf generated format */ + BOOL bV2Format = FALSE; + /* the return value (not from this function, but to be put back onto + * the wire */ + LONG_PTR RetVal = 0; + + TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase); + + if (pThis) + pServerInfo = CStdStubBuffer_GetServerInfo(pThis); + else + pServerInfo = ((RPC_SERVER_INTERFACE *)pRpcMsg->RpcInterfaceInformation)->InterpreterInfo; + + pStubDesc = pServerInfo->pStubDesc; + pFormat = pServerInfo->ProcString + pServerInfo->FmtStringOffset[pRpcMsg->ProcNum]; + pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; + + /* Later NDR language versions probably won't be backwards compatible */ + if (pStubDesc->Version > 0x50002) + { + FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); + } + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + { + NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0]; + stack_size = pProcHeader->stack_size; + current_offset = sizeof(NDR_PROC_HEADER_RPC); + + } + else + { + stack_size = pProcHeader->stack_size; + current_offset = sizeof(NDR_PROC_HEADER); + } + + TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); + + /* binding */ + switch (pProcHeader->handle_type) + { + /* explicit binding: parse additional section */ + case RPC_FC_BIND_EXPLICIT: + switch (pFormat[current_offset]) /* handle_type */ + { + case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ + current_offset += sizeof(NDR_EHD_PRIMITIVE); + break; + case RPC_FC_BIND_GENERIC: /* explicit generic */ + current_offset += sizeof(NDR_EHD_GENERIC); + break; + case RPC_FC_BIND_CONTEXT: /* explicit context */ + current_offset += sizeof(NDR_EHD_CONTEXT); + break; + default: + ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + break; + case RPC_FC_BIND_GENERIC: /* implicit generic */ + case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ + case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ + case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ + break; + default: + ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + bV2Format = (pStubDesc->Version >= 0x20000); + + if (bV2Format) + { + NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader = + (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset]; + + Oif_flags = pOIFHeader->Oif_flags; + number_of_params = pOIFHeader->number_of_params; + + current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); + } + + TRACE("Oif_flags = 0x%02x\n", Oif_flags); + + if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS) + { + NDR_PROC_EXTENSION * pExtensions = + (NDR_PROC_EXTENSION *)&pFormat[current_offset]; + ext_flags = pExtensions->ext_flags; + current_offset += pExtensions->extension_version; + } + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + NdrStubInitialize(pRpcMsg, &stubMsg, pStubDesc, pChannel); + else + NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc); + + /* create the full pointer translation tables, if requested */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) +#if 0 + stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER); +#else + FIXME("initialize full pointer translation tables\n"); +#endif + + /* store the RPC flags away */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + pRpcMsg->RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; + + /* use alternate memory allocation routines */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) +#if 0 + NdrRpcSsEnableAllocate(&stubMsg); +#else + FIXME("Set RPCSS memory allocation routines\n"); +#endif + + if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + { + FIXME("pipes not supported yet\n"); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ + /* init pipes package */ + /* NdrPipesInitialize(...) */ + } + if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + { + /* initialize extra correlation package */ + FIXME("new correlation description not implemented\n"); + stubMsg.fHasNewCorrDesc = TRUE; + } + + + /* convert strings, floating point values and endianess into our + * preferred format */ + if ((pRpcMsg->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) + NdrConvert(&stubMsg, pFormat); + + parameter_start_offset = current_offset; + + TRACE("allocating memory for stack of size %x\n", stack_size); + + args = HeapAlloc(GetProcessHeap(), 0, stack_size); + ZeroMemory(args, stack_size); + + /* add the implicit This pointer as the first arg to the function if we + * are calling an object method */ + if (pThis) + *(void **)args = ((CStdStubBuffer *)pThis)->pvServerObject; + + /* order of phases: + * 1. STUBLESS_UNMARHSAL - unmarshal [in] params from buffer + * 2. STUBLESS_CALLSERVER - send/receive buffer + * 3. STUBLESS_CALCSIZE - get [out] buffer size + * 4. STUBLESS_GETBUFFER - allocate [out] buffer + * 5. STUBLESS_MARHSAL - marshal [out] params to buffer + */ + for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_MARSHAL; phase++) + { + TRACE("phase = %d\n", phase); + switch (phase) + { + case STUBLESS_CALLSERVER: + /* call the server function */ + if (pServerInfo->ThunkTable) + { + stubMsg.StackTop = args; + pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg); + /* FIXME: RetVal is stored as the last argument - retrieve it */ + } + else if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + { + SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject; + RetVal = call_server_func(vtbl[pRpcMsg->ProcNum], args, stack_size); + } + else + RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size); + + TRACE("stub implementation returned %p\n", (void *)RetVal); + + stubMsg.Buffer = NULL; + stubMsg.BufferLength = 0; + + break; + case STUBLESS_GETBUFFER: + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + NdrStubGetBuffer(pThis, pChannel, &stubMsg); + else + { + RPC_STATUS Status; + + pRpcMsg->BufferLength = stubMsg.BufferLength; + /* allocate buffer for [out] and [ret] params */ + Status = I_RpcGetBuffer(pRpcMsg); + if (Status) + RpcRaiseException(Status); + stubMsg.BufferStart = pRpcMsg->Buffer; + stubMsg.BufferEnd = stubMsg.BufferStart + stubMsg.BufferLength; + stubMsg.Buffer = stubMsg.BufferStart; + } + break; + case STUBLESS_MARSHAL: + case STUBLESS_UNMARSHAL: + case STUBLESS_CALCSIZE: + current_offset = parameter_start_offset; + current_stack_offset = 0; + + /* NOTE: V1 style format does't terminate on the number_of_params + * condition as it doesn't have this attribute. Instead it + * terminates when the stack size given in the header is exceeded. + */ + for (i = 0; i < number_of_params; i++) + { + if (bV2Format) /* new parameter format */ + { + const NDR_PARAM_OIF_BASETYPE *pParam = + (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; + unsigned char *pArg; + + current_stack_offset = pParam->stack_offset; + pArg = (unsigned char *)(args+current_stack_offset); + + TRACE("param[%d]: new format\n", i); + TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); + TRACE("\tstack_offset: %x\n", current_stack_offset); + TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg); + + if (pParam->param_attributes.ServerAllocSize) + FIXME("ServerAllocSize of %d ignored for parameter %d\n", + pParam->param_attributes.ServerAllocSize * 8, i); + + if (pParam->param_attributes.IsBasetype) + { + const unsigned char *pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_attributes.IsReturn) + call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); + else if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsSimpleRef) + call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + else + call_marshaller(&stubMsg, pArg, pTypeFormat); + } + /* FIXME: call call_freer here */ + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsSimpleRef) + call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); + else + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + } + break; + case STUBLESS_CALCSIZE: + if (pParam->param_attributes.IsReturn) + call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); + else if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsSimpleRef) + call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + else + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); + } + else + { + NDR_PARAM_OIF_OTHER * pParamOther = + (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &(pStubDesc->pFormatTypes[pParamOther->type_offset]); + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_attributes.IsReturn) + call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); + else if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsByValue) + call_marshaller(&stubMsg, pArg, pTypeFormat); + else + { + call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + stubMsg.pfnFree(*(void **)pArg); + } + } + /* FIXME: call call_freer here for IN types */ + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + else + call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); + } + else if ((pParam->param_attributes.IsOut) && + !(pParam->param_attributes.IsByValue)) + { + *(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *)); + **(void ***)pArg = 0; + } + break; + case STUBLESS_CALCSIZE: + if (pParam->param_attributes.IsReturn) + call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); + else if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsByValue) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + else + call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_OTHER); + } + TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg); + } + else /* old parameter format */ + { + NDR_PARAM_OI_BASETYPE *pParam = + (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; + unsigned char *pArg = (unsigned char *)(args+current_stack_offset); + + /* no more parameters; exit loop */ + if (current_stack_offset > stack_size) + break; + + TRACE("param[%d]: old format\n\tparam_direction: 0x%x\n", i, pParam->param_direction); + + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || + pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + const unsigned char *pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + unsigned char *pRetVal = (unsigned char *)&RetVal; + call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); + } + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + break; + case STUBLESS_CALCSIZE: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + unsigned char * pRetVal = (unsigned char *)&RetVal; + call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat); + current_offset += sizeof(NDR_PARAM_OI_BASETYPE); + } + else + { + NDR_PARAM_OI_OTHER * pParamOther = + (NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &pStubDesc->pFormatTypes[pParamOther->type_offset]; + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_direction == RPC_FC_RETURN_PARAM) + { + unsigned char *pRetVal = (unsigned char *)&RetVal; + call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); + } + else if (pParam->param_direction == RPC_FC_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_OUT_PARAM) + call_marshaller(&stubMsg, pArg, pTypeFormat); + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_PARAM) + call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); + break; + case STUBLESS_CALCSIZE: + if (pParam->param_direction == RPC_FC_RETURN_PARAM) + { + unsigned char * pRetVal = (unsigned char *)&RetVal; + call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); + } + else if (pParam->param_direction == RPC_FC_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_OUT_PARAM) + call_buffer_sizer(&stubMsg, pArg, pTypeFormat); + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += pParamOther->stack_size * sizeof(INT); + current_offset += sizeof(NDR_PARAM_OI_OTHER); + } + } + } + + break; + default: + ERR("shouldn't reach here. phase %d\n", phase); + break; + } + } + + pRpcMsg->BufferLength = (unsigned int)(stubMsg.Buffer - (unsigned char *)pRpcMsg->Buffer); + + if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + { + /* free extra correlation package */ + /* NdrCorrelationFree(&stubMsg); */ + } + + if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + { + /* NdrPipesDone(...) */ + } + +#if 0 + /* free the full pointer translation tables */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); +#endif + + /* free server function stack */ + HeapFree(GetProcessHeap(), 0, args); + + return S_OK; +} + +void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) +{ + DWORD dwPhase; + NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); } diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index dcd36700333..7c34719f55a 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -254,15 +254,13 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, hdr_size = Header->common.frag_len; Header->common.flags |= RPC_FLG_FIRST; Header->common.flags &= ~RPC_FLG_LAST; - while (!(Header->common.flags & RPC_FLG_LAST)) { + while (!(Header->common.flags & RPC_FLG_LAST)) { /* decide if we need to split the packet into fragments */ if ((BufferLength + hdr_size) <= Connection->MaxTransmissionSize) { Header->common.flags |= RPC_FLG_LAST; Header->common.frag_len = BufferLength + hdr_size; } else { Header->common.frag_len = Connection->MaxTransmissionSize; - buffer_pos += Header->common.frag_len - hdr_size; - BufferLength -= Header->common.frag_len - hdr_size; } /* transmit packet header */ @@ -293,6 +291,8 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, return GetLastError(); } + buffer_pos += Header->common.frag_len - hdr_size; + BufferLength -= Header->common.frag_len - hdr_size; Header->common.flags &= ~RPC_FLG_FIRST; } diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index b238b612e61..ad4e04f544a 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -303,7 +303,7 @@ @ stub NdrRpcSsDisableAllocate @ stub NdrRpcSsEnableAllocate @ stdcall NdrSendReceive(ptr ptr) -@ stub NdrServerCall2 +@ stdcall NdrServerCall2(ptr) @ stub NdrServerCall @ stdcall NdrServerContextMarshall(ptr ptr long) @ stdcall NdrServerContextNewMarshall(ptr ptr ptr ptr) # wxp @@ -323,7 +323,7 @@ @ stdcall NdrSimpleStructUnmarshall(ptr ptr ptr long) @ stdcall NdrSimpleTypeMarshall(ptr ptr long) @ stdcall NdrSimpleTypeUnmarshall(ptr ptr long) -@ stub NdrStubCall2 +@ stdcall NdrStubCall2(ptr ptr ptr ptr) @ stub NdrStubCall @ stdcall NdrStubForwardingFunction(ptr ptr ptr ptr) @ stdcall NdrStubGetBuffer(ptr ptr ptr) diff --git a/reactos/include/ndrtypes.h b/reactos/include/ndrtypes.h new file mode 100644 index 00000000000..aa47acf37b2 --- /dev/null +++ b/reactos/include/ndrtypes.h @@ -0,0 +1,57 @@ +/* + * NDR Types + * + * Copyright 2006 Robert Shearman (for CodeWeavers) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __NDRTYPES_H__ +#define __NDRTYPES_H__ + +typedef struct +{ + unsigned short MustSize : 1; /* 0x0001 - client interpreter MUST size this + * parameter, other parameters may be skipped, using the value in + * NDR_PROC_PARTIAL_OIF_HEADER::constant_client_buffer_size instead. */ + unsigned short MustFree : 1; /* 0x0002 - server interpreter MUST size this + * parameter, other parameters may be skipped, using the value in + * NDR_PROC_PARTIAL_OIF_HEADER::constant_server_buffer_size instead. */ + unsigned short IsPipe : 1; /* 0x0004 - The parameter is a pipe handle. See + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/pipes.asp + * for more information on pipes. */ + unsigned short IsIn : 1; /* 0x0008 - The parameter is an input */ + unsigned short IsOut : 1; /* 0x0010 - The parameter is an output */ + unsigned short IsReturn : 1; /* 0x0020 - The parameter is to be returned */ + unsigned short IsBasetype : 1; /* 0x0040 - The parameter is simple and has the + * format defined by NDR_PARAM_OIF_BASETYPE rather than by + * NDR_PARAM_OIF_OTHER. */ + unsigned short IsByValue : 1; /* 0x0080 - Set for compound types being sent by + * value. Can be of type: structure, union, transmit_as, represent_as, + * wire_marshal and SAFEARRAY. */ + unsigned short IsSimpleRef : 1; /* 0x0100 - parameter that is a reference + * pointer to anything other than another pointer, and which has no + * allocate attributes. */ + unsigned short IsDontCallFreeInst : 1; /* 0x0200 - Used for some represent_as types + * for when the free instance routine should not be called. */ + unsigned short SaveForAsyncFinish : 1; /* 0x0400 - Unknown */ + unsigned short Unused : 2; + unsigned short ServerAllocSize : 3; /* 0xe000 - If non-zero + * specifies the size of the object in numbers of 8byte blocks needed. + * It will be stored on the server's stack rather than using an allocate + * call. */ +} PARAM_ATTRIBUTES; + +#endif diff --git a/reactos/include/rpcndr.h b/reactos/include/rpcndr.h index d777e862548..99c16697751 100644 --- a/reactos/include/rpcndr.h +++ b/reactos/include/rpcndr.h @@ -164,67 +164,73 @@ typedef struct _NDR_ASYNC_MESSAGE *PNDR_ASYNC_MESSAGE; typedef struct _NDR_CORRELATION_INFO *PNDR_CORRELATION_INFO; #pragma pack(push,4) -typedef struct _MIDL_STUB_MESSAGE { - PRPC_MESSAGE RpcMsg; - unsigned char *Buffer; - unsigned char *BufferStart; - unsigned char *BufferEnd; - unsigned char *BufferMark; - unsigned long BufferLength; - unsigned long MemorySize; - unsigned char *Memory; - int IsClient; - int ReuseBuffer; - unsigned char *AllocAllNodesMemory; - unsigned char *AllocAllNodesMemoryEnd; - int IgnoreEmbeddedPointers; - unsigned char *PointerBufferMark; - unsigned char fBufferValid; - unsigned char uFlags; - unsigned long MaxCount; - unsigned long Offset; - unsigned long ActualCount; - void*(__RPC_API *pfnAllocate)(unsigned int); - void(__RPC_API *pfnFree)(void*); - unsigned char *StackTop; - unsigned char *pPresentedType; - unsigned char *pTransmitType; - handle_t SavedHandle; - const struct _MIDL_STUB_DESC *StubDesc; - struct _FULL_PTR_XLAT_TABLES *FullPtrXlatTables; - unsigned long FullPtrRefId; - int fCheckBounds; - int fInDontFree :1; - int fDontCallFreeInst :1; - int fInOnlyParam :1; - int fHasReturn :1; - unsigned long dwDestContext; - void*pvDestContext; - NDR_SCONTEXT *SavedContextHandles; - long ParamNumber; - struct IRpcChannelBuffer *pRpcChannelBuffer; - PARRAY_INFO pArrayInfo; - unsigned long *SizePtrCountArray; - unsigned long *SizePtrOffsetArray; - unsigned long *SizePtrLengthArray; - void*pArgQueue; - unsigned long dwStubPhase; - void *LowStackMark; - PNDR_ASYNC_MESSAGE pAsyncMsg; - PNDR_CORRELATION_INFO pCorrInfo; - unsigned char *pCorrMemory; - void *pMemoryList; - CS_STUB_INFO *pCSInfo; - unsigned char *ConformanceMark; - unsigned char *VarianceMark; - INT_PTR Unused; - struct _NDR_PROC_CONTEXT *pContext; - INT_PTR Reserved51_1; - INT_PTR Reserved51_2; - INT_PTR Reserved51_3; - INT_PTR Reserved51_4; - INT_PTR Reserved51_5; -} MIDL_STUB_MESSAGE,*PMIDL_STUB_MESSAGE; +typedef struct _MIDL_STUB_MESSAGE +{ + PRPC_MESSAGE RpcMsg; + unsigned char *Buffer; + unsigned char *BufferStart; + unsigned char *BufferEnd; + unsigned char *BufferMark; + unsigned long BufferLength; + unsigned long MemorySize; + unsigned char *Memory; + int IsClient; + int ReuseBuffer; + struct NDR_ALLOC_ALL_NODES_CONTEXT *pAllocAllNodesContext; + struct NDR_POINTER_QUEUE_STATE *pPointerQueueState; + int IgnoreEmbeddedPointers; + unsigned char *PointerBufferMark; + unsigned char fBufferValid; + unsigned char uFlags; + unsigned short UniquePtrCount; + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned long ActualCount; + void * (__RPC_API *pfnAllocate)(size_t); + void (__RPC_API *pfnFree)(void *); + unsigned char *StackTop; + unsigned char *pPresentedType; + unsigned char *pTransmitType; + handle_t SavedHandle; + const struct _MIDL_STUB_DESC *StubDesc; + struct _FULL_PTR_XLAT_TABLES *FullPtrXlatTables; + unsigned long FullPtrRefId; + unsigned long PointerLength; + int fInDontFree:1; + int fDontCallFreeInst:1; + int fInOnlyParam:1; + int fHasReturn:1; + int fHasExtensions:1; + int fHasNewCorrDesc:1; + int fUnused:10; + int fUnused2:16; + unsigned long dwDestContext; + void *pvDestContext; + NDR_SCONTEXT *SavedContextHandles; + long ParamNumber; + struct IRpcChannelBuffer *pRpcChannelBuffer; + PARRAY_INFO pArrayInfo; + unsigned long *SizePtrCountArray; + unsigned long *SizePtrOffsetArray; + unsigned long *SizePtrLengthArray; + void *pArgQueue; + unsigned long dwStubPhase; + void *LowStackMark; + PNDR_ASYNC_MESSAGE pAsyncMsg; + PNDR_CORRELATION_INFO pCorrInfo; + unsigned char *pCorrMemory; + void *pMemoryList; + CS_STUB_INFO *pCSInfo; + unsigned char *ConformanceMark; + unsigned char *VarianceMark; + INT_PTR Unused; + struct _NDR_PROC_CONTEXT *pContext; + INT_PTR Reserved51_1; + INT_PTR Reserved51_2; + INT_PTR Reserved51_3; + INT_PTR Reserved51_4; + INT_PTR Reserved51_5; +} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; #pragma pack(pop) typedef void*(__RPC_API *GENERIC_BINDING_ROUTINE)(void*); typedef void (__RPC_API *GENERIC_UNBIND_ROUTINE)(void*,unsigned char*); diff --git a/reactos/include/rpcnterr.h b/reactos/include/rpcnterr.h index b23c429c6e9..ad342ba7852 100644 --- a/reactos/include/rpcnterr.h +++ b/reactos/include/rpcnterr.h @@ -1,23 +1,44 @@ -#ifndef _RPCNTERR_H -#define _RPCNTERR_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/* + * Copyright (C) 2001 Peter Hunnisett + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ -#define RPC_S_OK ERROR_SUCCESS -#define RPC_S_INVALID_ARG ERROR_INVALID_PARAMETER -#define RPC_S_OUT_OF_MEMORY ERROR_OUTOFMEMORY -#define RPC_S_OUT_OF_THREADS ERROR_MAX_THRDS_REACHED -#define RPC_S_INVALID_LEVEL ERROR_INVALID_PARAMETER -#define RPC_S_BUFFER_TOO_SMALL ERROR_INSUFFICIENT_BUFFER -#define RPC_S_INVALID_SECURITY_DESC ERROR_INVALID_SECURITY_DESCR -#define RPC_S_ACCESS_DENIED ERROR_ACCESS_DENIED -#define RPC_S_SERVER_OUT_OF_MEMORY ERROR_NOT_ENOUGH_SERVER_MEMORY -#define RPC_X_NO_MEMORY RPC_S_OUT_OF_MEMORY -#define RPC_X_INVALID_BOUND RPC_S_INVALID_BOUND -#define RPC_X_INVALID_TAG RPC_S_INVALID_TAG -#define RPC_X_ENUM_VALUE_TOO_LARGE RPC_X_ENUM_VALUE_OUT_OF_RANGE -#define RPC_X_SS_CONTEXT_MISMATCH ERROR_INVALID_HANDLE -#define RPC_X_INVALID_BUFFER ERROR_INVALID_USER_BUFFER -#define RPC_X_INVALID_PIPE_OPERATION RPC_X_WRONG_PIPE_ORDER -#endif +#ifndef __RPCNTERR_H__ +#define __RPCNTERR_H__ + +#define RPC_S_OK ERROR_SUCCESS +#define RPC_S_INVALID_ARG ERROR_INVALID_PARAMETER +#define RPC_S_OUT_OF_MEMORY ERROR_OUTOFMEMORY +#define RPC_S_OUT_OF_THREADS ERROR_MAX_THRDS_REACHED +#define RPC_S_INVALID_LEVEL ERROR_INVALID_PARAMETER +#define RPC_S_BUFFER_TOO_SMALL ERROR_INSUFFICIENT_BUFFER +#define RPC_S_INVALID_SECURITY_DESC ERROR_INVALID_SECURITY_DESCR +#define RPC_S_ACCESS_DENIED ERROR_ACCESS_DENIED +#define RPC_S_SERVER_OUT_OF_MEMORY ERROR_NOT_ENOUGH_SERVER_MEMORY +#define RPC_S_ASYNC_CALL_PENDING ERROR_IO_PENDING +#define RPC_S_UNKNOWN_PRINCIPAL ERROR_NONE_MAPPED +#define RPC_S_TIMEOUT ERROR_TIMEOUT + +#define RPC_X_NO_MEMORY RPC_S_OUT_OF_MEMORY +#define RPC_X_INVALID_BOUND RPC_S_INVALID_BOUND +#define RPC_X_INVALID_TAG RPC_S_INVALID_TAG +#define RPC_X_ENUM_VALUE_TOO_LARGE RPC_X_ENUM_VALUE_OUT_OF_RANGE +#define RPC_X_SS_CONTEXT_MISMATCH ERROR_INVALID_HANDLE +#define RPC_X_INVALID_BUFFER ERROR_INVALID_USER_BUFFER +#define RPC_X_PIPE_APP_MEMORY ERROR_OUTOFMEMORY +#define RPC_X_INVALID_PIPE_OPERATION RPC_X_WRONG_PIPE_ORDER + +#endif /* __RPCNTERR_H__ */