Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 lines
11 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1998 - 1999 Microsoft Corporation
  3. Module Name :
  4. relmrl.c
  5. Abstract :
  6. This file contains release of Marshaled Data (called before unmarshal).
  7. Author :
  8. Yong Qu (yongqu@microsoft.com) Nov 1998
  9. Revision History :
  10. ---------------------------------------------------------------------*/
  11. #define USE_STUBLESS_PROXY
  12. #define CINTERFACE
  13. #include "ndrp.h"
  14. #include "ndrole.h"
  15. #include "rpcproxy.h"
  16. #include "hndl.h"
  17. #include "interp2.h"
  18. #include "pipendr.h"
  19. #include "attack.h"
  20. #include "mulsyntx.h"
  21. #include <stddef.h>
  22. #include <stdarg.h>
  23. /* client side: we only care about the [in] part.
  24. it's basically like unmarshal on the server side, just that
  25. we immediately free the buffer (virtual stack) after unmarshalling.
  26. The call it not necessary always OLE call: one side raw RPC and
  27. the other side OLE call is possible: do we support this?
  28. mostly code from NdrStubCall2, remove irrelavant code.
  29. */
  30. #define IN_BUFFER 0
  31. #define OUT_BUFFER 1
  32. #define IsSameDir(dwFlags,param) ((dwFlags == IN_BUFFER)? param.IsIn :param.IsOut)
  33. HRESULT NdrpReleaseMarshalBuffer(
  34. RPC_MESSAGE *pRpcMsg,
  35. PFORMAT_STRING pFormat,
  36. PMIDL_STUB_DESC pStubDesc,
  37. DWORD dwFlags,
  38. BOOLEAN fServer)
  39. {
  40. ushort StackSize;
  41. MIDL_STUB_MESSAGE StubMsg;
  42. PPARAM_DESCRIPTION Params;
  43. INTERPRETER_FLAGS InterpreterFlags;
  44. INTERPRETER_OPT_FLAGS OptFlags;
  45. long NumberParams;
  46. long n;
  47. PNDR_PROC_HEADER_EXTS pHeaderExts = 0;
  48. HRESULT hr = S_OK;
  49. uchar * pBuffer;
  50. PFORMAT_STRING pFormatComplex;
  51. PFORMAT_STRING pFormatTypes;
  52. NDR_ASSERT( ! ((ULONG_PTR)pRpcMsg->Buffer & 0x7),
  53. "marshaling buffer misaligned at server" );
  54. // must be auto handle.
  55. if (FC_AUTO_HANDLE != pFormat[0])
  56. return E_NOTIMPL;
  57. InterpreterFlags = *((PINTERPRETER_FLAGS)&pFormat[1]);
  58. pFormat += InterpreterFlags.HasRpcFlags ? 8 : 4;
  59. StackSize = *((ushort * &)pFormat)++;
  60. memset(&StubMsg,0,sizeof(MIDL_STUB_MESSAGE));
  61. StubMsg.FullPtrXlatTables = 0;
  62. //
  63. // Get new interpreter info.
  64. //
  65. NdrServerInitialize(pRpcMsg,&StubMsg,pStubDesc);
  66. SET_WALKIP( StubMsg.uFlags );
  67. OptFlags = *((PINTERPRETER_OPT_FLAGS)&pFormat[4]);
  68. NumberParams = (long) pFormat[5];
  69. Params = (PPARAM_DESCRIPTION) &pFormat[6];
  70. // Proc header extentions, from NDR ver. 5.2.
  71. // Params must be set correctly here because of exceptions.
  72. // need to setup correlation information.
  73. if ( OptFlags.HasExtensions )
  74. {
  75. pHeaderExts = (NDR_PROC_HEADER_EXTS *)Params;
  76. Params = (PPARAM_DESCRIPTION)((uchar*)Params + pHeaderExts->Size);
  77. StubMsg.fHasExtensions = 1;
  78. StubMsg.fHasNewCorrDesc = pHeaderExts->Flags2.HasNewCorrDesc;
  79. }
  80. if ( InterpreterFlags.FullPtrUsed )
  81. StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_SERVER );
  82. //
  83. // context handle is not supported in object
  84. //
  85. pFormatTypes = pStubDesc->pFormatTypes;
  86. // Save the original buffer pointer to restore later.
  87. pBuffer = StubMsg.Buffer;
  88. // Get the type format string.
  89. RpcTryFinally
  90. {
  91. RpcTryExcept
  92. {
  93. //
  94. // Check if we need to do any walking .
  95. //
  96. if ( (fServer && dwFlags == OUT_BUFFER)
  97. &&
  98. (pRpcMsg->DataRepresentation & 0X0000FFFFUL) !=
  99. NDR_LOCAL_DATA_REPRESENTATION )
  100. {
  101. NdrConvert2( &StubMsg,
  102. (PFORMAT_STRING) Params,
  103. NumberParams );
  104. }
  105. for ( n = 0; n < NumberParams; n++ )
  106. {
  107. if ( (dwFlags == IN_BUFFER ) &&
  108. Params[n].ParamAttr.IsPartialIgnore )
  109. {
  110. PMIDL_STUB_MESSAGE pStubMsg = &StubMsg;
  111. ALIGN( StubMsg.Buffer, 0x3 );
  112. StubMsg.Buffer += PTR_WIRE_SIZE;
  113. CHECK_EOB_RAISE_BSD( StubMsg.Buffer );
  114. continue;
  115. }
  116. if ( ! IsSameDir(dwFlags,Params[n].ParamAttr) ||
  117. Params[n].ParamAttr.IsPipe)
  118. continue;
  119. if ( Params[n].ParamAttr.IsBasetype )
  120. {
  121. ALIGN(StubMsg.Buffer, SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ));
  122. StubMsg.Buffer += SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
  123. }
  124. else
  125. {
  126. //
  127. // Complex type or pointer to complex type.
  128. //
  129. pFormatComplex = pFormatTypes + Params[n].TypeOffset;
  130. (*pfnMemSizeRoutines[ROUTINE_INDEX(*pFormatComplex)])
  131. ( &StubMsg,
  132. pFormatComplex);
  133. };
  134. }
  135. }
  136. RpcExcept( EXCEPTION_EXECUTE_HANDLER )
  137. {
  138. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  139. }
  140. RpcEndExcept
  141. }
  142. RpcFinally
  143. {
  144. NdrFullPointerXlatFree( StubMsg.FullPtrXlatTables );
  145. StubMsg.Buffer = pBuffer;
  146. }
  147. RpcEndFinally
  148. return hr;
  149. }
  150. HRESULT NdrpClientReleaseMarshalBuffer(
  151. IReleaseMarshalBuffers *pRMB,
  152. RPC_MESSAGE *pRpcMsg,
  153. DWORD dwIOFlags,
  154. BOOLEAN fAsync )
  155. {
  156. CStdProxyBuffer * pProxyBuffer;
  157. PMIDL_STUBLESS_PROXY_INFO pProxyInfo;
  158. CInterfaceProxyHeader * ProxyHeader;
  159. long ParamSize;
  160. ushort ProcNum;
  161. ushort FormatOffset;
  162. PFORMAT_STRING pFormat;
  163. PMIDL_STUB_DESC pStubDesc;
  164. void * This;
  165. HRESULT hr;
  166. pProxyBuffer = (CStdProxyBuffer *)
  167. (((uchar *)pRMB) - offsetof( CStdProxyBuffer, pRMBVtbl ));
  168. // The channel queries for IReleaseMarshalBuffers interface and gets the interface pointer
  169. // only when proxy is the new proxy with bigger header, with ProxyInfo.
  170. // Just in case, check this condition again.
  171. if ( pRMB == 0 )
  172. return E_NOTIMPL;
  173. // quite often OLE pass in NULL buffer. Do an additional check here.
  174. if ( NULL == pRpcMsg->Buffer )
  175. return E_INVALIDARG;
  176. This = (void *)pProxyBuffer->pProxyVtbl;
  177. ProxyHeader = (CInterfaceProxyHeader *)
  178. ( (char *)This - sizeof(CInterfaceProxyHeader));
  179. pProxyInfo = (PMIDL_STUBLESS_PROXY_INFO) (ProxyHeader->pStublessProxyInfo);
  180. // Hack just in case, the bit should not be set up, actually.
  181. ProcNum = pRpcMsg->ProcNum & ~RPC_FLAGS_VALID_BIT;
  182. // RPCMSG always has the synchronous proc number;
  183. if ( fAsync )
  184. ProcNum = 2 * ProcNum - 3; // Begin method #
  185. if ( dwIOFlags != IN_BUFFER )
  186. return E_NOTIMPL;
  187. pStubDesc = pProxyInfo->pStubDesc;
  188. #if defined(BUILD_NDR64)
  189. // check out ndr64
  190. if ( pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  191. {
  192. SYNTAX_TYPE SyntaxType;
  193. long i;
  194. MIDL_SYNTAX_INFO * pSyntaxInfo;
  195. SyntaxType = NdrpGetSyntaxType( pRpcMsg->TransferSyntax );
  196. // branch into ndr64 if SyntaxType is NDR64. fall through otherwise
  197. if ( XFER_SYNTAX_NDR64 == SyntaxType )
  198. {
  199. for ( i = 0; i < (long)pProxyInfo->nCount; i++ )
  200. {
  201. if ( SyntaxType == NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) )
  202. {
  203. pSyntaxInfo = &pProxyInfo->pSyntaxInfo[i];
  204. break;
  205. }
  206. }
  207. return Ndr64pReleaseMarshalBuffer( pRpcMsg, pSyntaxInfo, ProcNum, pStubDesc, dwIOFlags, FALSE );
  208. }
  209. }
  210. #endif
  211. FormatOffset = pProxyInfo->FormatStringOffset[ProcNum];
  212. pFormat = &((pProxyInfo->ProcFormatString)[FormatOffset]);
  213. // only support Oicf mode
  214. if ( (MIDL_VERSION_3_0_39 > pStubDesc->MIDLVersion ) ||
  215. !(pFormat[1] & Oi_OBJ_USE_V2_INTERPRETER ))
  216. return E_NOTIMPL;
  217. hr = NdrpReleaseMarshalBuffer( pRpcMsg,
  218. pFormat,
  219. pStubDesc,
  220. dwIOFlags,
  221. FALSE ); // client
  222. return hr;
  223. }
  224. HRESULT NdrpServerReleaseMarshalBuffer(
  225. IReleaseMarshalBuffers *pRMB,
  226. RPC_MESSAGE *pRpcMsg,
  227. DWORD dwIOFlags,
  228. BOOLEAN fAsync)
  229. {
  230. CStdStubBuffer * pStubBuffer ;
  231. PRPC_SERVER_INTERFACE pServerIfInfo;
  232. PMIDL_SERVER_INFO pServerInfo;
  233. ushort ProcNum;
  234. IUnknown * pSrvObj;
  235. CInterfaceStubVtbl * pStubVTable;
  236. ushort FormatOffset;
  237. PFORMAT_STRING pFormat;
  238. PMIDL_STUB_DESC pStubDesc;
  239. HRESULT hr;
  240. pStubBuffer = (CStdStubBuffer *) (((uchar *)pRMB) -
  241. offsetof(CStdStubBuffer, pRMBVtbl));
  242. // The channel queries for IReleaseMarshalBuffers interface and gets the interface pointer
  243. // only when proxy is the new proxy with bigger header, with ProxyInfo.
  244. // Just in case, check this condition again.
  245. if ( pRMB == 0 )
  246. return E_NOTIMPL;
  247. if ( NULL == pRpcMsg->Buffer )
  248. return E_INVALIDARG;
  249. pSrvObj = (IUnknown * )((CStdStubBuffer *)pStubBuffer)->pvServerObject;
  250. pStubVTable = (CInterfaceStubVtbl *)
  251. ((uchar *)pStubBuffer->lpVtbl - sizeof(CInterfaceStubHeader));
  252. pServerInfo = (PMIDL_SERVER_INFO) pStubVTable->header.pServerInfo;
  253. // Hack just in case, this should not be set up, actually.
  254. ProcNum = pRpcMsg->ProcNum & ~RPC_FLAGS_VALID_BIT;
  255. // RPCMSG always has the synchronous proc number;
  256. if ( fAsync )
  257. {
  258. ProcNum = 2 * ProcNum - 3; // Begin method #
  259. if ( dwIOFlags != IN_BUFFER )
  260. ProcNum++; // Finish method
  261. }
  262. pStubDesc = pServerInfo->pStubDesc;
  263. #if defined(BUILD_NDR64)
  264. if ( pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  265. {
  266. SYNTAX_TYPE SyntaxType;
  267. long i;
  268. MIDL_SYNTAX_INFO * pSyntaxInfo;
  269. SyntaxType = NdrpGetSyntaxType( pRpcMsg->TransferSyntax );
  270. if ( XFER_SYNTAX_NDR64 == SyntaxType )
  271. {
  272. for ( i = 0; i < (long)pServerInfo->nCount; i++ )
  273. {
  274. if ( SyntaxType == NdrpGetSyntaxType( &pServerInfo->pSyntaxInfo[i].TransferSyntax ) )
  275. {
  276. pSyntaxInfo = &pServerInfo->pSyntaxInfo[i];
  277. break;
  278. }
  279. }
  280. return Ndr64pReleaseMarshalBuffer( pRpcMsg, pSyntaxInfo, ProcNum, pStubDesc, dwIOFlags, TRUE );
  281. }
  282. }
  283. #endif
  284. FormatOffset = pServerInfo->FmtStringOffset[ProcNum];
  285. pFormat = &((pServerInfo->ProcString)[FormatOffset]);
  286. // only support Oicf mode
  287. if ( (MIDL_VERSION_3_0_39 > pStubDesc->MIDLVersion ) ||
  288. !(pFormat[1] & Oi_OBJ_USE_V2_INTERPRETER ))
  289. return E_NOTIMPL;
  290. hr = NdrpReleaseMarshalBuffer(pRpcMsg,pFormat,pStubDesc,dwIOFlags,TRUE);
  291. return hr;
  292. }