Author: fireball
Date: Tue Mar 21 00:52:24 2006
New Revision: 21362
URL:
http://svn.reactos.ru/svn/reactos?rev=21362&view=rev
Log:
Sync to Wine-0_9_10:
Robert Shearman <rob(a)codeweavers.com>
- ndrtypes.h added into reactos/include
- too many changes to paste here. Look at the url below, checking all changes done after
Wine-0_9_5 tag (including Wine-0_9_10 as the last one)
-
http://cvs.winehq.com/cvsweb/wine/dlls/rpcrt4/?cvsroot=home/wine
Added:
trunk/reactos/include/ndrtypes.h
Modified:
trunk/reactos/dll/win32/rpcrt4/cproxy.c
trunk/reactos/dll/win32/rpcrt4/cpsf.c
trunk/reactos/dll/win32/rpcrt4/cpsf.h
trunk/reactos/dll/win32/rpcrt4/cstub.c
trunk/reactos/dll/win32/rpcrt4/ndr_marshall.c
trunk/reactos/dll/win32/rpcrt4/ndr_midl.c
trunk/reactos/dll/win32/rpcrt4/ndr_misc.h
trunk/reactos/dll/win32/rpcrt4/ndr_ole.c
trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c
trunk/reactos/dll/win32/rpcrt4/rpc_message.c
trunk/reactos/dll/win32/rpcrt4/rpcrt4.spec
trunk/reactos/include/rpcndr.h
trunk/reactos/include/rpcnterr.h
Modified: trunk/reactos/dll/win32/rpcrt4/cproxy.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/cproxy.c?r…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/cproxy.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/cproxy.c Tue Mar 21 00:52:24 2006
@@ -104,7 +104,7 @@
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 @@
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 @@
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; i<count; i++) {
@@ -162,7 +164,7 @@
if (vtbl->Vtbl[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 @@
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;
Modified: trunk/reactos/dll/win32/rpcrt4/cpsf.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/cpsf.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/cpsf.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/cpsf.c Tue Mar 21 00:52:24 2006
@@ -95,9 +95,7 @@
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 @@
*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);
Modified: trunk/reactos/dll/win32/rpcrt4/cpsf.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/cpsf.h?rev…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/cpsf.h (original)
+++ trunk/reactos/dll/win32/rpcrt4/cpsf.h Tue Mar 21 00:52:24 2006
@@ -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 @@
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
+const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
+
#endif /* __WINE_CPSF_H */
Modified: trunk/reactos/dll/win32/rpcrt4/cstub.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/cstub.c?re…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/cstub.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/cstub.c Tue Mar 21 00:52:24 2006
@@ -144,7 +144,10 @@
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 @@
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;
Modified: trunk/reactos/dll/win32/rpcrt4/ndr_marshall.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_marsha…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/ndr_marshall.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/ndr_marshall.c Tue Mar 21 00:52:24 2006
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
+#include <limits.h>
#include "windef.h"
#include "winbase.h"
@@ -300,20 +301,43 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 *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);
-
- if (*(const DWORD*)pFormat != 0xffffffff)
- FIXME("compute variance\n");
- pFormat += 4;
-
- NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
+ TRACE("conformance = %ld\n", pStubMsg->MaxCount);
+
+ variance_present = IsConformanceOrVariancePresent(pFormat);
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+ TRACE("variance = %ld\n", pStubMsg->ActualCount);
+
+ NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
pStubMsg->Buffer += 4;
-
- for (count=0; count<size; count++)
+ 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; count < pStubMsg->ActualCount; count++)
pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
STD_OVERFLOW_CHECK(pStubMsg);
@@ -2144,9 +2185,90 @@
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);
+ pFormat = ReadVariance(pStubMsg, pFormat);
+
+ esize = ComplexStructSize(pStubMsg, pFormat);
+
+ if (fMustAlloc || !*ppMemory)
+ {
+ *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
+ memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
+ }
+
+ pMemory = *ppMemory;
+ for (count = 0; count < pStubMsg->ActualCount; count++)
+ pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
+
+ return NULL;
+}
+
+/***********************************************************************
+ * NdrComplexArrayBufferSize [RPCRT4.@]
+ */
+void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
+ unsigned char *pMemory,
+ PFORMAT_STRING pFormat)
+{
+ 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);
+ TRACE("conformance = %ld\n", pStubMsg->MaxCount);
+ pStubMsg->BufferLength += sizeof(ULONG);
+
+ variance_present = IsConformanceOrVariancePresent(pFormat);
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+ TRACE("variance = %ld\n", pStubMsg->ActualCount);
+
+ if (variance_present)
+ pStubMsg->BufferLength += 2*sizeof(ULONG);
+
+ for (count=0; count < pStubMsg->ActualCount; count++)
+ pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
+}
+
+/***********************************************************************
+ * NdrComplexArrayMemorySize [RPCRT4.@]
+ */
+unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
+ PFORMAT_STRING pFormat)
+{
+ 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;
@@ -2156,85 +2278,37 @@
pFormat += 4;
- esize = ComplexStructSize(pStubMsg, pFormat);
-
- if (fMustAlloc || !*ppMemory)
- *ppMemory = NdrAllocate(pStubMsg, size*esize);
-
- pMemory = *ppMemory;
- for (count=0; count<size; count++)
- pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
-
- return NULL;
-}
-
-/***********************************************************************
- * NdrComplexArrayBufferSize [RPCRT4.@]
- */
-void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
- unsigned char *pMemory,
- PFORMAT_STRING pFormat)
-{
- DWORD size = 0, count, def;
+ return 0;
+}
+
+/***********************************************************************
+ * NdrComplexArrayFree [RPCRT4.@]
+ */
+void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
+ unsigned char *pMemory,
+ PFORMAT_STRING pFormat)
+{
+ 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);
-
- if (*(const DWORD*)pFormat != 0xffffffff)
- FIXME("compute variance\n");
- pFormat += 4;
-
- for (count=0; count<size; count++)
- pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
-}
-
-/***********************************************************************
- * NdrComplexArrayMemorySize [RPCRT4.@]
- */
-unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
- PFORMAT_STRING pFormat)
-{
- DWORD size = 0;
- FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
-
- pFormat += 4;
-
- pFormat = ReadConformance(pStubMsg, pFormat);
- size = pStubMsg->MaxCount;
- TRACE("conformance=%ld\n", size);
-
- pFormat += 4;
-
- return 0;
-}
-
-/***********************************************************************
- * NdrComplexArrayFree [RPCRT4.@]
- */
-void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
- unsigned char *pMemory,
- PFORMAT_STRING pFormat)
-{
- DWORD size = 0, count, def;
- TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
-
- def = *(const WORD*)&pFormat[2];
- pFormat += 4;
-
- pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
- size = pStubMsg->MaxCount;
- TRACE("conformance=%ld\n", size);
-
- if (*(const DWORD*)pFormat != 0xffffffff)
- FIXME("compute variance\n");
- pFormat += 4;
-
- for (count=0; count<size; count++)
+ TRACE("conformance = %ld\n", pStubMsg->MaxCount);
+
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+ TRACE("variance = %ld\n", pStubMsg->ActualCount);
+
+ for (count=0; count < pStubMsg->ActualCount; count++)
pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
}
@@ -2934,6 +3008,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
Modified: trunk/reactos/dll/win32/rpcrt4/ndr_midl.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_midl.c…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/ndr_midl.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/ndr_midl.c Tue Mar 21 00:52:24 2006
@@ -269,6 +269,8 @@
*/
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 @@
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;
Modified: trunk/reactos/dll/win32/rpcrt4/ndr_misc.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_misc.h…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/ndr_misc.h (original)
+++ trunk/reactos/dll/win32/rpcrt4/ndr_misc.h Tue Mar 21 00:52:24 2006
@@ -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(
Modified: trunk/reactos/dll/win32/rpcrt4/ndr_ole.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_ole.c?…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/ndr_ole.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/ndr_ole.c Tue Mar 21 00:52:24 2006
@@ -257,14 +257,16 @@
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 @@
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;
-}
Modified: trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_stuble…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c Tue Mar 21 00:52:24 2006
@@ -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,10 +19,12 @@
* 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 <stdarg.h>
#include <stdio.h>
@@ -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"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-/***********************************************************************
- * 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)
-{
-
- 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;
+#include "cpsf.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(rpc);
+
+#define NDR_TABLE_MASK 127
+
+static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
PFORMAT_STRING pFormat)
+{
+ 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, ...)
-{
- 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;
+static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char
*pMemory, PFORMAT_STRING pFormat)
+{
+ 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/pa…
*/
+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);
+}
Modified: trunk/reactos/dll/win32/rpcrt4/rpc_message.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpc_messag…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpc_message.c (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpc_message.c Tue Mar 21 00:52:24 2006
@@ -254,15 +254,13 @@
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 @@
return GetLastError();
}
+ buffer_pos += Header->common.frag_len - hdr_size;
+ BufferLength -= Header->common.frag_len - hdr_size;
Header->common.flags &= ~RPC_FLG_FIRST;
}
Modified: trunk/reactos/dll/win32/rpcrt4/rpcrt4.spec
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpcrt4.spe…
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpcrt4.spec (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpcrt4.spec Tue Mar 21 00:52:24 2006
@@ -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)
Added: trunk/reactos/include/ndrtypes.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ndrtypes.h?rev=2136…
==============================================================================
--- trunk/reactos/include/ndrtypes.h (added)
+++ trunk/reactos/include/ndrtypes.h Tue Mar 21 00:52:24 2006
@@ -1,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/pi…
+ * 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
Modified: trunk/reactos/include/rpcndr.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/rpcndr.h?rev=21362&…
==============================================================================
--- trunk/reactos/include/rpcndr.h (original)
+++ trunk/reactos/include/rpcndr.h Tue Mar 21 00:52:24 2006
@@ -164,67 +164,73 @@
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*);
Modified: trunk/reactos/include/rpcnterr.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/rpcnterr.h?rev=2136…
==============================================================================
--- trunk/reactos/include/rpcnterr.h (original)
+++ trunk/reactos/include/rpcnterr.h Tue Mar 21 00:52:24 2006
@@ -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__ */