Leaked source code of windows server 2003
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.

2149 lines
56 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name :
  4. auxilary.c
  5. Abstract :
  6. This file contains auxilary routines used for initialization of the
  7. RPC and stub messages and the offline batching of common code sequences
  8. needed by the stubs.
  9. Author :
  10. David Kays dkays September 1993.
  11. Revision History :
  12. ---------------------------------------------------------------------*/
  13. #define _OLE32_
  14. #include "ndrp.h"
  15. #include "ndrole.h"
  16. #include "ndrtypes.h"
  17. #include "limits.h"
  18. #include "interp.h"
  19. #include "mulsyntx.h"
  20. #include "pipendr.h"
  21. #include "asyncndr.h"
  22. #include "auxilary.h"
  23. #include "pointerq.h"
  24. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  25. Static data for NS library operations
  26. ---------------------------------------------------------------------*/
  27. int NsDllLoaded = 0;
  28. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  29. OLE routines for interface pointer marshalling
  30. ---------------------------------------------------------------------*/
  31. STDAPI NdrpCoCreateInstance(
  32. REFCLSID rclsid,
  33. LPUNKNOWN pUnkOuter,
  34. DWORD dwClsContext,
  35. REFIID riid,
  36. LPVOID * ppv);
  37. STDAPI NdrpCoReleaseMarshalData(
  38. IStream *pStm);
  39. STDAPI NdrpDcomChannelSetHResult(
  40. PRPC_MESSAGE pmsg,
  41. ULONG * pulReserved,
  42. HRESULT appsHR );
  43. STDAPI NdrCoGetPSClsid(
  44. REFIID iid,
  45. LPCLSID lpclsid);
  46. HINSTANCE hOle32 = 0;
  47. RPC_GET_CLASS_OBJECT_ROUTINE NdrCoGetClassObject;
  48. RPC_GET_CLASS_OBJECT_ROUTINE * pfnCoGetClassObject = &NdrCoGetClassObject;
  49. RPC_GET_MARSHAL_SIZE_MAX_ROUTINE NdrCoGetMarshalSizeMax;
  50. RPC_GET_MARSHAL_SIZE_MAX_ROUTINE * pfnCoGetMarshalSizeMax = &NdrCoGetMarshalSizeMax;
  51. RPC_MARSHAL_INTERFACE_ROUTINE NdrCoMarshalInterface;
  52. RPC_MARSHAL_INTERFACE_ROUTINE * pfnCoMarshalInterface = &NdrCoMarshalInterface;
  53. RPC_UNMARSHAL_INTERFACE_ROUTINE NdrCoUnmarshalInterface;
  54. RPC_UNMARSHAL_INTERFACE_ROUTINE * pfnCoUnmarshalInterface = &NdrCoUnmarshalInterface;
  55. RPC_STRING_FROM_IID OleStringFromIID;
  56. RPC_STRING_FROM_IID * pfnStringFromIID = &OleStringFromIID;
  57. RPC_GET_PS_CLSID NdrCoGetPSClsid;
  58. RPC_GET_PS_CLSID * pfnCoGetPSClsid = &NdrCoGetPSClsid;
  59. RPC_CO_CREATE_INSTANCE NdrpCoCreateInstance;
  60. RPC_CO_CREATE_INSTANCE * pfnCoCreateInstance = &NdrpCoCreateInstance;
  61. RPC_CLIENT_ALLOC NdrCoTaskMemAlloc;
  62. RPC_CLIENT_ALLOC * pfnCoTaskMemAlloc = &NdrCoTaskMemAlloc;
  63. RPC_CLIENT_FREE NdrCoTaskMemFree;
  64. RPC_CLIENT_FREE * pfnCoTaskMemFree = &NdrCoTaskMemFree;
  65. RPC_CO_RELEASEMARSHALDATA NdrpCoReleaseMarshalData;
  66. RPC_CO_RELEASEMARSHALDATA * pfnCoReleaseMarshalData = &NdrpCoReleaseMarshalData;
  67. RPC_DCOMCHANNELSETHRESULT NdrpDcomChannelSetHResult;
  68. RPC_DCOMCHANNELSETHRESULT * pfnDcomChannelSetHResult = &NdrpDcomChannelSetHResult;
  69. RPC_NS_GET_BUFFER_ROUTINE pRpcNsGetBuffer;
  70. RPC_NS_SEND_RECEIVE_ROUTINE pRpcNsSendReceive;
  71. RPC_NS_NEGOTIATETRANSFERSYNTAX_ROUTINE pRpcNsNegotiateTransferSyntax;
  72. HRESULT NdrLoadOleRoutines()
  73. {
  74. void * pTempRoutine;
  75. //Load ole32.dll
  76. if(hOle32 == 0)
  77. {
  78. #ifdef DOSWIN32RPC
  79. hOle32 = LoadLibraryA("OLE32");
  80. #else
  81. hOle32 = LoadLibraryW(L"OLE32");
  82. #endif // DOSWIN32C
  83. if(hOle32 == 0)
  84. return HRESULT_FROM_WIN32(GetLastError());
  85. }
  86. pTempRoutine = GetProcAddress(hOle32, "CoGetClassObject");
  87. if(pTempRoutine == 0)
  88. return HRESULT_FROM_WIN32(GetLastError());
  89. else
  90. pfnCoGetClassObject = (RPC_GET_CLASS_OBJECT_ROUTINE*) pTempRoutine;
  91. pTempRoutine = GetProcAddress(hOle32, "CoGetMarshalSizeMax");
  92. if(pTempRoutine == 0)
  93. return HRESULT_FROM_WIN32(GetLastError());
  94. else
  95. pfnCoGetMarshalSizeMax = (RPC_GET_MARSHAL_SIZE_MAX_ROUTINE*) pTempRoutine;
  96. pTempRoutine = GetProcAddress(hOle32, "CoMarshalInterface");
  97. if(pTempRoutine == 0)
  98. return HRESULT_FROM_WIN32(GetLastError());
  99. else
  100. pfnCoMarshalInterface = (RPC_MARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
  101. pTempRoutine = GetProcAddress(hOle32, "CoUnmarshalInterface");
  102. if(pTempRoutine == 0)
  103. return HRESULT_FROM_WIN32(GetLastError());
  104. else
  105. pfnCoUnmarshalInterface = (RPC_UNMARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
  106. pTempRoutine = GetProcAddress(hOle32, "StringFromIID");
  107. if(pTempRoutine == 0)
  108. return HRESULT_FROM_WIN32(GetLastError());
  109. else
  110. pfnStringFromIID = (RPC_STRING_FROM_IID*) pTempRoutine;
  111. pTempRoutine = GetProcAddress(hOle32, "CoGetPSClsid");
  112. if(pTempRoutine == 0)
  113. return HRESULT_FROM_WIN32(GetLastError());
  114. else
  115. pfnCoGetPSClsid = (RPC_GET_PS_CLSID*) pTempRoutine;
  116. pTempRoutine = GetProcAddress(hOle32, "CoTaskMemAlloc");
  117. if(pTempRoutine == 0)
  118. return HRESULT_FROM_WIN32(GetLastError());
  119. else
  120. pfnCoTaskMemAlloc = (RPC_CLIENT_ALLOC*) pTempRoutine;
  121. pTempRoutine = GetProcAddress(hOle32, "CoTaskMemFree");
  122. if(pTempRoutine == 0)
  123. return HRESULT_FROM_WIN32(GetLastError());
  124. else
  125. pfnCoTaskMemFree = (RPC_CLIENT_FREE*) pTempRoutine;
  126. pTempRoutine = GetProcAddress(hOle32, "CoCreateInstance");
  127. if(pTempRoutine == 0)
  128. return HRESULT_FROM_WIN32(GetLastError());
  129. else
  130. pfnCoCreateInstance = (RPC_CO_CREATE_INSTANCE*) pTempRoutine;
  131. pTempRoutine = GetProcAddress(hOle32, "CoReleaseMarshalData");
  132. if(pTempRoutine == 0)
  133. return HRESULT_FROM_WIN32(GetLastError());
  134. else
  135. pfnCoReleaseMarshalData = (RPC_CO_RELEASEMARSHALDATA*) pTempRoutine;
  136. pTempRoutine = GetProcAddress(hOle32, "DcomChannelSetHResult");
  137. if(pTempRoutine == 0)
  138. return HRESULT_FROM_WIN32(GetLastError());
  139. else
  140. pfnDcomChannelSetHResult = (RPC_DCOMCHANNELSETHRESULT*) pTempRoutine;
  141. return( (HRESULT)0 );
  142. }
  143. HRESULT STDAPICALLTYPE
  144. NdrCoGetClassObject(
  145. REFCLSID rclsid,
  146. DWORD dwClsContext,
  147. void *pvReserved,
  148. REFIID riid,
  149. void **ppv)
  150. /*++
  151. Routine Description:
  152. Loads a class factory. This function forwards the call to ole32.dll.
  153. Arguments:
  154. rclsid - Supplies the CLSID of the class to be loaded.
  155. dwClsContext - Supplies the context in which to load the code.
  156. pvReserved - Must be NULL.
  157. riid - Supplies the IID of the desired interface.
  158. ppv - Returns a pointer to the class factory.
  159. Return Value:
  160. S_OK
  161. --*/
  162. {
  163. HRESULT hr;
  164. if ( FAILED(hr = NdrLoadOleRoutines()) )
  165. return hr;
  166. return (*pfnCoGetClassObject)(rclsid, dwClsContext, pvReserved, riid, ppv);
  167. }
  168. HRESULT STDAPICALLTYPE
  169. NdrCoGetMarshalSizeMax(
  170. ULONG * pulSize,
  171. REFIID riid,
  172. LPUNKNOWN pUnk,
  173. DWORD dwDestContext,
  174. LPVOID pvDestContext,
  175. DWORD mshlflags)
  176. /*++
  177. Routine Description:
  178. Calculates the maximum size of a marshalled interface pointer.
  179. This function forwards the call to ole32.dll.
  180. Arguments:
  181. pulSize - Returns an upper bound for the size of a marshalled interface pointer.
  182. riid - Supplies the IID of the interface to be marshalled.
  183. pUnk - Supplies a pointer to the object to be marshalled.
  184. dwDestContext - Supplies the destination of the marshalled interface pointer.
  185. pvDestContext
  186. mshlflags - Flags. See the MSHFLAGS enumeration.
  187. Return Value:
  188. S_OK
  189. --*/
  190. {
  191. HRESULT hr;
  192. if ( FAILED(hr = NdrLoadOleRoutines()) )
  193. return hr;
  194. return (*pfnCoGetMarshalSizeMax)(pulSize, riid, pUnk, dwDestContext, pvDestContext, mshlflags);
  195. }
  196. RPC_STATUS
  197. RPC_ENTRY
  198. NdrGetDcomProtocolVersion(
  199. PMIDL_STUB_MESSAGE pStubMsg,
  200. RPC_VERSION * pVersion )
  201. /*
  202. This is a helper routine for OLEAUT guys.
  203. It returns the actually negotiated protocol version for the connection,
  204. i.e. a "common denominator" - lower of the two.
  205. */
  206. {
  207. HRESULT Hr = E_FAIL;
  208. if ( pStubMsg->pRpcChannelBuffer )
  209. {
  210. IRpcChannelBuffer2 * pBuffer2 = 0;
  211. Hr = ((IRpcChannelBuffer*)pStubMsg->pRpcChannelBuffer)->
  212. QueryInterface( IID_IRpcChannelBuffer2,
  213. (void**) & pBuffer2 );
  214. if ( Hr == S_OK )
  215. {
  216. Hr = pBuffer2->GetProtocolVersion( (DWORD *) pVersion );
  217. pBuffer2->Release( );
  218. }
  219. }
  220. return Hr;
  221. }
  222. unsigned long
  223. FixWireRepForDComVerGTE54(
  224. PMIDL_STUB_MESSAGE pStubMsg )
  225. /*
  226. Compares the current DCOM protocol version with the desired version ( 5.4 )
  227. Specific to interface pointer array and embedded conf struct wire rep fix.
  228. */
  229. {
  230. if ( pStubMsg->pRpcChannelBuffer )
  231. {
  232. RPC_VERSION currRpcVersion = { 0, 0 };
  233. if ( SUCCEEDED ( NdrGetDcomProtocolVersion( pStubMsg, &currRpcVersion ) ) )
  234. {
  235. if ( currRpcVersion.MajorVersion > 5 )
  236. {
  237. return TRUE;
  238. }
  239. else
  240. {
  241. return currRpcVersion.MinorVersion >= 4;
  242. }
  243. }
  244. }
  245. return TRUE;
  246. }
  247. HRESULT STDAPICALLTYPE
  248. NdrCoMarshalInterface(
  249. LPSTREAM pStm,
  250. REFIID riid,
  251. LPUNKNOWN pUnk,
  252. DWORD dwDestContext,
  253. LPVOID pvDestContext,
  254. DWORD mshlflags)
  255. /*++
  256. Routine Description:
  257. Marshals an interface pointer.
  258. This function forwards the call to ole32.dll.
  259. Arguments:
  260. pStm - Supplies the target stream.
  261. riid - Supplies the IID of the interface to be marshalled.
  262. pUnk - Supplies a pointer to the object to be marshalled.
  263. dwDestContext - Specifies the destination context
  264. pvDestContext
  265. mshlflags - Flags. See the MSHFLAGS enumeration.
  266. Return Value:
  267. S_OK
  268. --*/
  269. {
  270. HRESULT hr;
  271. if ( FAILED(hr = NdrLoadOleRoutines()) )
  272. return hr;
  273. return (*pfnCoMarshalInterface)(pStm, riid, pUnk, dwDestContext, pvDestContext, mshlflags);
  274. }
  275. HRESULT STDAPICALLTYPE
  276. NdrCoUnmarshalInterface(
  277. LPSTREAM pStm,
  278. REFIID riid,
  279. void ** ppv)
  280. /*++
  281. Routine Description:
  282. Unmarshals an interface pointer from a stream.
  283. This function forwards the call to ole32.dll.
  284. Arguments:
  285. pStm - Supplies the stream containing the marshalled interface pointer.
  286. riid - Supplies the IID of the interface pointer to be unmarshalled.
  287. ppv - Returns the unmarshalled interface pointer.
  288. Return Value:
  289. S_OK
  290. --*/
  291. {
  292. HRESULT hr;
  293. if ( FAILED(hr = NdrLoadOleRoutines()) )
  294. return hr;
  295. return (*pfnCoUnmarshalInterface)(pStm, riid, ppv);
  296. }
  297. STDAPI NdrpCoCreateInstance(
  298. REFCLSID rclsid,
  299. LPUNKNOWN pUnkOuter,
  300. DWORD dwClsContext,
  301. REFIID riid,
  302. LPVOID * ppv)
  303. {
  304. HRESULT hr;
  305. if ( FAILED(hr = NdrLoadOleRoutines()) )
  306. return hr;
  307. return (*pfnCoCreateInstance) (rclsid, pUnkOuter, dwClsContext, riid, ppv );
  308. }
  309. STDAPI NdrpCoReleaseMarshalData(
  310. IStream *pStm)
  311. {
  312. HRESULT hr;
  313. if ( FAILED(hr = NdrLoadOleRoutines()) )
  314. return hr;
  315. return (*pfnCoReleaseMarshalData) (pStm );
  316. }
  317. STDAPI NdrpDcomChannelSetHResult(
  318. PRPC_MESSAGE pmsg,
  319. ULONG * pulReserved,
  320. HRESULT appsHR )
  321. {
  322. HRESULT hr;
  323. if ( FAILED(hr = NdrLoadOleRoutines()) )
  324. return hr;
  325. return (*pfnDcomChannelSetHResult)( pmsg, pulReserved, appsHR );
  326. }
  327. HRESULT STDAPICALLTYPE OleStringFromIID(
  328. REFIID rclsid,
  329. LPOLESTR FAR* lplpsz)
  330. /*++
  331. Routine Description:
  332. Converts an IID into a string.
  333. This function forwards the call to ole32.dll.
  334. Arguments:
  335. rclsid - Supplies the clsid to convert to string form.
  336. lplpsz - Returns the string form of the clsid (with "{}" around it).
  337. Return Value:
  338. S_OK
  339. --*/
  340. {
  341. HRESULT hr;
  342. if ( FAILED(hr = NdrLoadOleRoutines()) )
  343. return hr;
  344. return (*pfnStringFromIID)(rclsid, lplpsz);
  345. }
  346. STDAPI NdrCoGetPSClsid(
  347. REFIID iid,
  348. LPCLSID lpclsid)
  349. /*++
  350. Routine Description:
  351. Converts an IID into a string.
  352. This function forwards the call to ole32.dll.
  353. Arguments:
  354. rclsid - Supplies the clsid to convert to string form.
  355. lplpsz - Returns the string form of the clsid (with "{}" around it).
  356. Return Value:
  357. S_OK
  358. --*/
  359. {
  360. HRESULT hr;
  361. if ( FAILED(hr = NdrLoadOleRoutines()) )
  362. return hr;
  363. return (*pfnCoGetPSClsid)(iid, lpclsid);
  364. }
  365. void * STDAPICALLTYPE
  366. NdrCoTaskMemAlloc(
  367. size_t cb)
  368. /*++
  369. Routine Description:
  370. Allocate memory using OLE task memory allocator.
  371. This function forwards the call to ole32.dll.
  372. Arguments:
  373. cb - Specifies the amount of memory to be allocated.
  374. Return Value:
  375. This function returns a pointer to the allocated memory.
  376. If an error occurs, this function returns zero.
  377. --*/
  378. {
  379. if ( FAILED(NdrLoadOleRoutines()) )
  380. return 0;
  381. return (*pfnCoTaskMemAlloc)(cb);
  382. }
  383. void STDAPICALLTYPE
  384. NdrCoTaskMemFree(
  385. void * pMemory)
  386. /*++
  387. Routine Description:
  388. Free memory using OLE task memory allocator.
  389. This function forwards the call to ole32.dll.
  390. Arguments:
  391. pMemory - Supplies a pointer to the memory to be freed.
  392. Return Value:
  393. None.
  394. --*/
  395. {
  396. if ( FAILED(NdrLoadOleRoutines()) )
  397. return;
  398. (*pfnCoTaskMemFree)(pMemory);
  399. }
  400. void * RPC_ENTRY NdrOleAllocate(size_t size)
  401. /*++
  402. Routine Description:
  403. Allocate memory via OLE task allocator.
  404. Arguments:
  405. size - Specifies the amount of memory to be allocated.
  406. Return Value:
  407. This function returns a pointer to the allocated memory.
  408. If an error occurs, this function raises an exception.
  409. --*/
  410. {
  411. void *pMemory;
  412. pMemory = (*pfnCoTaskMemAlloc)(size);
  413. if(pMemory == 0)
  414. RpcRaiseException(E_OUTOFMEMORY);
  415. return pMemory;
  416. }
  417. void RPC_ENTRY NdrOleFree(void *pMemory)
  418. /*++
  419. Routine Description:
  420. Free memory using OLE task allocator.
  421. Arguments:
  422. None.
  423. Return Value:
  424. None.
  425. --*/
  426. {
  427. (*pfnCoTaskMemFree)(pMemory);
  428. }
  429. HRESULT STDAPICALLTYPE NdrStringFromIID(
  430. REFIID rclsid,
  431. char * lpsz)
  432. /*++
  433. Routine Description:
  434. Converts an IID into a string.
  435. This function forwards the call to ole32.dll.
  436. Arguments:
  437. rclsid - Supplies the clsid to convert to string form.
  438. lplpsz - Returns the string form of the clsid (with "{}" around it).
  439. Return Value:
  440. S_OK
  441. --*/
  442. {
  443. HRESULT hr;
  444. wchar_t * olestr;
  445. hr = (*pfnStringFromIID)(rclsid, &olestr);
  446. if(SUCCEEDED(hr))
  447. {
  448. WideCharToMultiByte(CP_ACP,
  449. 0,
  450. (LPCWSTR)olestr,
  451. -1,
  452. (LPSTR)lpsz,
  453. 50,
  454. NULL,
  455. NULL);
  456. NdrOleFree(olestr);
  457. }
  458. return hr;
  459. }
  460. void RPC_ENTRY
  461. NdrClientInitializeNew(
  462. PRPC_MESSAGE pRpcMsg,
  463. PMIDL_STUB_MESSAGE pStubMsg,
  464. PMIDL_STUB_DESC pStubDescriptor,
  465. unsigned int ProcNum
  466. )
  467. /*++
  468. Routine Description :
  469. This routine is called by client side stubs to initialize the RPC message
  470. and stub message, and to get the RPC buffer.
  471. Arguments :
  472. pRpcMsg - pointer to RPC message structure
  473. pStubMsg - pointer to stub message structure
  474. pStubDescriptor - pointer to stub descriptor structure
  475. HandleType - type of binding handle
  476. ProcNum - remote procedure number
  477. --*/
  478. {
  479. NdrClientInitialize( pRpcMsg,
  480. pStubMsg,
  481. pStubDescriptor,
  482. ProcNum );
  483. if ( pStubDescriptor->pMallocFreeStruct )
  484. {
  485. MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
  486. NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
  487. }
  488. // This exception should be raised after initializing StubMsg.
  489. if ( pStubDescriptor->Version > NDR_VERSION )
  490. {
  491. NDR_ASSERT( 0, "ClientInitialize : Bad version number" );
  492. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  493. }
  494. //
  495. // This is where we initialize fields behind the NT3.5 - NT5.0 field set.
  496. //
  497. #ifdef _CS_CHAR_
  498. if ( NDR_VERSION_6_0 <= pStubDescriptor->Version )
  499. {
  500. pStubMsg->pCSInfo = 0;
  501. }
  502. #endif // _CS_CHAR_
  503. }
  504. void RPC_ENTRY
  505. NdrClientInitialize(
  506. PRPC_MESSAGE pRpcMsg,
  507. PMIDL_STUB_MESSAGE pStubMsg,
  508. PMIDL_STUB_DESC pStubDescriptor,
  509. unsigned int ProcNum )
  510. /*++
  511. Routine Description :
  512. This routine is called by client side stubs to initialize the RPC message
  513. and stub message, and to get the RPC buffer.
  514. Arguments :
  515. pRpcMsg - pointer to RPC message structure
  516. pStubMsg - pointer to stub message structure
  517. pStubDescriptor - pointer to stub descriptor structure
  518. ProcNum - remote procedure number
  519. Notes:
  520. This routine has to be backward compatible with the old binaries built from
  521. -Os stubs. In particular, it cannot touch StubMsg fields outside of
  522. the NT3.5 - NT5.0 field set, i.e. set of fields present since NT3.5 release.
  523. --*/
  524. {
  525. //
  526. // Initialize RPC message fields.
  527. //
  528. // The leftmost bit of the procnum field is supposed to be set to 1 inr
  529. // order for the runtime to know if it is talking to the older stubs or
  530. // not.
  531. //
  532. pRpcMsg->RpcInterfaceInformation = pStubDescriptor->RpcInterfaceInformation;
  533. //#if !defined(__RPC_WIN64__)
  534. pRpcMsg->ProcNum = ProcNum | RPC_FLAGS_VALID_BIT;
  535. //#endif
  536. pRpcMsg->RpcFlags = 0;
  537. pRpcMsg->Handle = 0;
  538. //
  539. // Initialize the Stub messsage fields.
  540. //
  541. pStubMsg->RpcMsg = pRpcMsg;
  542. pStubMsg->StubDesc = pStubDescriptor;
  543. pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
  544. pStubMsg->pfnFree = pStubDescriptor->pfnFree;
  545. pStubMsg->fInDontFree = 0;
  546. pStubMsg->fDontCallFreeInst = 0;
  547. pStubMsg->fInOnlyParam = 0;
  548. pStubMsg->fHasReturn = 0;
  549. pStubMsg->fHasExtensions = 0;
  550. pStubMsg->fHasNewCorrDesc = 0;
  551. pStubMsg->UniquePtrCount= 0;
  552. pStubMsg->IsClient = TRUE;
  553. pStubMsg->BufferLength = 0;
  554. pStubMsg->BufferStart = 0;
  555. pStubMsg->BufferEnd = 0;
  556. pStubMsg->uFlags = 0;
  557. pStubMsg->fBufferValid = FALSE;
  558. pStubMsg->ReuseBuffer = FALSE;
  559. pStubMsg->StackTop = 0;
  560. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  561. pStubMsg->PointerBufferMark = 0;
  562. pStubMsg->pAllocAllNodesContext = 0;
  563. pStubMsg->pPointerQueueState = 0;
  564. pStubMsg->FullPtrRefId = 0;
  565. pStubMsg->PointerLength = 0;
  566. pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
  567. pStubMsg->pvDestContext = 0;
  568. pStubMsg->pRpcChannelBuffer = 0;
  569. pStubMsg->pArrayInfo = 0;
  570. pStubMsg->dwStubPhase = 0;
  571. NdrSetupLowStackMark( pStubMsg );
  572. pStubMsg->pAsyncMsg = 0;
  573. pStubMsg->pCorrInfo = 0;
  574. pStubMsg->pCorrMemory = 0;
  575. pStubMsg->pMemoryList = 0;
  576. }
  577. void
  578. MakeSureWeHaveNonPipeArgs(
  579. PMIDL_STUB_MESSAGE pStubMsg,
  580. unsigned long BufferSize )
  581. /*
  582. Routine description:
  583. This routine is called for pipe calls at the server.
  584. After the runtime dispatched to the stub with the first packet,
  585. it makes sure that we have a portion of the buffer big enough
  586. to keep all the non-pipe args.
  587. Arguments:
  588. BufferSize - a pipe call: addtional number of bytes over what we have.
  589. Note:
  590. The buffer location may change from before to after the call.
  591. */
  592. {
  593. RPC_STATUS Status;
  594. PRPC_MESSAGE pRpcMsg = pStubMsg->RpcMsg;
  595. if ( !(pRpcMsg->RpcFlags & RPC_BUFFER_COMPLETE ) )
  596. {
  597. // May be the args fit into the first packet.
  598. if ( BufferSize <= pRpcMsg->BufferLength )
  599. return;
  600. // Set the partial flag to get the non-pipe args.
  601. // For a partial call with the "extra", the meaning of the size
  602. // arg is the addition required above what we have already.
  603. pRpcMsg->RpcFlags |= (RPC_BUFFER_PARTIAL | RPC_BUFFER_EXTRA);
  604. // We will receive at least BufferSize.
  605. // (buffer location may change)
  606. BufferSize -= pRpcMsg->BufferLength;
  607. Status = I_RpcReceive( pRpcMsg, (unsigned int) BufferSize );
  608. if ( Status != RPC_S_OK )
  609. {
  610. // Note, that for this particular error case, i.e. non-pipe
  611. // data receive failing, we don't want to restore the
  612. // original dispatch buffer into the rpc message.
  613. // In case of an error the buffer coming back here would be 0.
  614. //
  615. RpcRaiseException( Status );
  616. }
  617. NDR_ASSERT( 0 == BufferSize ||
  618. NULL != pRpcMsg->Buffer,
  619. "Rpc runtime returned an invalid buffer.");
  620. // In case this is a new buffer
  621. pStubMsg->Buffer = (uchar*)pRpcMsg->Buffer;
  622. pStubMsg->BufferStart = (uchar*)pRpcMsg->Buffer;
  623. pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
  624. }
  625. }
  626. unsigned char * RPC_ENTRY
  627. NdrServerInitializeNew(
  628. PRPC_MESSAGE pRpcMsg,
  629. PMIDL_STUB_MESSAGE pStubMsg,
  630. PMIDL_STUB_DESC pStubDescriptor
  631. )
  632. /*++
  633. Routine Description :
  634. This routine is called by the server stubs before unmarshalling.
  635. It initializes the stub message fields.
  636. Aruguments :
  637. pStubMsg - pointer to the stub message structure
  638. pStubDescriptor - pointer to the stub descriptor structure
  639. Note.
  640. NdrServerInitializeNew is almost identical to NdrServerInitializePartial.
  641. NdrServerInitializeNew is generated for non-pipes and is backward comp.
  642. NdrServerInitializePartial is generated for routines with pipes args.
  643. --*/
  644. {
  645. NdrServerInitialize( pRpcMsg,
  646. pStubMsg,
  647. pStubDescriptor );
  648. if ( pStubDescriptor->pMallocFreeStruct )
  649. {
  650. MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
  651. NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
  652. }
  653. // This exception should be raised after initializing StubMsg.
  654. if ( pStubDescriptor->Version > NDR_VERSION )
  655. {
  656. NDR_ASSERT( 0, "ServerInitializeNew : bad version number" );
  657. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  658. }
  659. //
  660. // This is where we initialize fields behind the NT3.5 - NT5.0 field set.
  661. //
  662. #ifdef _CS_CHAR_
  663. if ( NDR_VERSION_6_0 <= pStubDescriptor->Version )
  664. {
  665. pStubMsg->pCSInfo = 0;
  666. }
  667. #endif // _CS_CHAR_
  668. if ( !(pRpcMsg->RpcFlags & RPC_BUFFER_COMPLETE ) )
  669. {
  670. // A non-pipe call with an incomplete buffer.
  671. // This can happen only for non-pipe calls in an interface that
  672. // has some pipe calls.
  673. RPC_STATUS Status;
  674. pRpcMsg->RpcFlags = RPC_BUFFER_EXTRA;
  675. // The size argument is ignored, we will get everything.
  676. Status = I_RpcReceive( pRpcMsg, 0 );
  677. if ( Status != RPC_S_OK )
  678. {
  679. // This is the same behavior (and comment) as in MakeSure..
  680. // routine above for non-pipe data case in a pipe call.
  681. // For this particular error case, i.e. a call to Receive to get
  682. // all (non-pipe) data failing, we don't want to restore the
  683. // original dispatch buffer into the rpc message.
  684. // In case of an error the buffer coming back here would be 0.
  685. //
  686. RpcRaiseException( Status );
  687. }
  688. NDR_ASSERT( 0 == pRpcMsg->BufferLength ||
  689. NULL != pRpcMsg->Buffer,
  690. "Rpc runtime returned an invalid buffer.");
  691. // In case this is a new buffer
  692. pStubMsg->Buffer = (uchar*)pRpcMsg->Buffer;
  693. pStubMsg->BufferStart = (uchar*)pRpcMsg->Buffer;
  694. pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
  695. }
  696. return 0;
  697. }
  698. unsigned char * RPC_ENTRY
  699. NdrServerInitialize(
  700. PRPC_MESSAGE pRpcMsg,
  701. PMIDL_STUB_MESSAGE pStubMsg,
  702. PMIDL_STUB_DESC pStubDescriptor )
  703. /*++
  704. Routine Description :
  705. This routine is called by the server stubs before unmarshalling.
  706. It initializes the stub message fields.
  707. Aruguments :
  708. pStubMsg - pointer to the stub message structure
  709. pStubDescriptor - pointer to the stub descriptor structure
  710. Note :
  711. This is a core server-side initializer, called by everybody.
  712. This routine has to be backward compatible with the old binaries built from
  713. -Os stubs. In particular, it cannot touch StubMsg fields outside of
  714. the NT3.5 - NT5.0 field set, i.e. set of fields present since NT3.5 release.
  715. --*/
  716. {
  717. pStubMsg->IsClient = FALSE;
  718. pStubMsg->pAllocAllNodesContext = 0;
  719. pStubMsg->pPointerQueueState = 0;
  720. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  721. pStubMsg->PointerBufferMark = 0;
  722. pStubMsg->BufferLength = 0;
  723. pStubMsg->StackTop = 0;
  724. pStubMsg->FullPtrXlatTables = 0;
  725. pStubMsg->FullPtrRefId = 0;
  726. pStubMsg->PointerLength = 0;
  727. pStubMsg->fDontCallFreeInst = 0;
  728. pStubMsg->fInDontFree = 0;
  729. pStubMsg->fInOnlyParam = 0;
  730. pStubMsg->fHasReturn = 0;
  731. pStubMsg->fHasExtensions = 0;
  732. pStubMsg->fHasNewCorrDesc = 0;
  733. pStubMsg->UniquePtrCount = 0;
  734. pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
  735. pStubMsg->pvDestContext = 0;
  736. pStubMsg->pRpcChannelBuffer = 0;
  737. pStubMsg->pArrayInfo = 0;
  738. pStubMsg->RpcMsg = pRpcMsg;
  739. pStubMsg->Buffer = (uchar*)pRpcMsg->Buffer;
  740. //
  741. // Set BufferStart and BufferEnd before unmarshalling.
  742. // NdrPointerFree uses these values to detect pointers into the
  743. // rpc message buffer.
  744. //
  745. pStubMsg->BufferStart = (uchar*)pRpcMsg->Buffer;
  746. pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
  747. pStubMsg->uFlags = 0;
  748. pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
  749. pStubMsg->pfnFree = pStubDescriptor->pfnFree;
  750. pStubMsg->StubDesc = pStubDescriptor;
  751. pStubMsg->ReuseBuffer = FALSE;
  752. pStubMsg->dwStubPhase = 0;
  753. NdrSetupLowStackMark( pStubMsg );
  754. pStubMsg->pAsyncMsg = 0;
  755. pStubMsg->pCorrInfo = 0;
  756. pStubMsg->pCorrMemory = 0;
  757. pStubMsg->pMemoryList = 0;
  758. NdrRpcSetNDRSlot( pStubMsg );
  759. return(0);
  760. }
  761. void RPC_ENTRY
  762. NdrServerInitializePartial(
  763. PRPC_MESSAGE pRpcMsg,
  764. PMIDL_STUB_MESSAGE pStubMsg,
  765. PMIDL_STUB_DESC pStubDescriptor,
  766. unsigned long RequestedBufferSize )
  767. /*++
  768. Routine Description :
  769. This routine is called by the server stubs for pipes.
  770. It is almost identical to NdrServerInitializeNew, except that
  771. it calls NdrpServerInitialize.
  772. Aruguments :
  773. pStubMsg - pointer to the stub message structure
  774. pStubDescriptor - pointer to the stub descriptor structure
  775. pBuffer - pointer to the beginning of the RPC message buffer
  776. --*/
  777. {
  778. NdrServerInitialize( pRpcMsg,
  779. pStubMsg,
  780. pStubDescriptor );
  781. if ( pStubDescriptor->pMallocFreeStruct )
  782. {
  783. MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
  784. NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
  785. }
  786. // This exception should be raised after initializing StubMsg.
  787. if ( pStubDescriptor->Version > NDR_VERSION )
  788. {
  789. NDR_ASSERT( 0, "ServerInitializePartial : bad version number" );
  790. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  791. }
  792. //
  793. // This is where we initialize fields behind the NT3.5 - NT5.0 field set.
  794. //
  795. #ifdef _CS_CHAR_
  796. if ( NDR_VERSION_6_0 <= pStubDescriptor->Version )
  797. {
  798. pStubMsg->pCSInfo = 0;
  799. }
  800. #endif _CS_CHAR_
  801. // Last but not least...
  802. MakeSureWeHaveNonPipeArgs( pStubMsg, RequestedBufferSize );
  803. }
  804. unsigned char * RPC_ENTRY
  805. NdrGetBuffer(
  806. PMIDL_STUB_MESSAGE pStubMsg,
  807. unsigned long BufferLength,
  808. RPC_BINDING_HANDLE Handle )
  809. /*++
  810. Routine Description :
  811. Performs an RpcGetBuffer.
  812. Arguments :
  813. pStubMsg - Pointer to stub message structure.
  814. BufferLength - Length of requested rpc message buffer.
  815. Handle - Bound handle.
  816. --*/
  817. {
  818. RPC_STATUS Status;
  819. if ( pStubMsg->IsClient )
  820. pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
  821. LENGTH_ALIGN(BufferLength, 3);
  822. pStubMsg->RpcMsg->BufferLength = BufferLength;
  823. Status = I_RpcGetBuffer( pStubMsg->RpcMsg );
  824. if ( Status )
  825. {
  826. // For raw rpc, if async, don't call abort later.
  827. if ( pStubMsg->pAsyncMsg )
  828. pStubMsg->pAsyncMsg->Flags.RuntimeCleanedUp = 1;
  829. RpcRaiseException( Status );
  830. }
  831. NDR_ASSERT( 0 == BufferLength ||
  832. NULL != pStubMsg->RpcMsg->Buffer,
  833. "Rpc runtime returned an invalid buffer.");
  834. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  835. "marshaling buffer misaligned" );
  836. pStubMsg->Buffer = (uchar *) pStubMsg->RpcMsg->Buffer;
  837. pStubMsg->fBufferValid = TRUE;
  838. return pStubMsg->Buffer;
  839. }
  840. void
  841. EnsureNSLoaded()
  842. /*++
  843. Routine Description :
  844. Guarantee that the RpcNs4 DLL is loaded. Throw exception if unable
  845. to load it.
  846. Will load the RpcNs4 DLL if not already loaded
  847. Arguments :
  848. --*/
  849. {
  850. HINSTANCE DllHandle;
  851. LPSTR EntryName;
  852. if ( NsDllLoaded )
  853. return;
  854. #ifdef DOSWIN32RPC
  855. DllHandle = LoadLibraryA( "RPCNS4" );
  856. #else
  857. DllHandle = LoadLibraryW( L"RPCNS4" );
  858. #endif // DOSWIN32RPC
  859. if ( DllHandle == 0 )
  860. {
  861. RpcRaiseException (RPC_S_INVALID_BINDING);
  862. }
  863. EntryName = "I_RpcNsGetBuffer";
  864. pRpcNsGetBuffer = (RPC_NS_GET_BUFFER_ROUTINE)
  865. GetProcAddress( DllHandle,
  866. EntryName);
  867. if ( pRpcNsGetBuffer == 0 )
  868. {
  869. RpcRaiseException (RPC_S_INVALID_BINDING);
  870. }
  871. EntryName = "I_RpcNsSendReceive";
  872. pRpcNsSendReceive = (RPC_NS_SEND_RECEIVE_ROUTINE)
  873. GetProcAddress( DllHandle,
  874. EntryName);
  875. if ( pRpcNsSendReceive == 0 )
  876. {
  877. RpcRaiseException (RPC_S_INVALID_BINDING);
  878. }
  879. EntryName = "I_RpcNsNegotiateTransferSyntax";
  880. pRpcNsNegotiateTransferSyntax = ( RPC_NS_NEGOTIATETRANSFERSYNTAX_ROUTINE )
  881. GetProcAddress( DllHandle,
  882. EntryName );
  883. if ( pRpcNsNegotiateTransferSyntax == 0 )
  884. {
  885. RpcRaiseException (RPC_S_INVALID_BINDING);
  886. }
  887. NsDllLoaded = 1;
  888. }
  889. unsigned char * RPC_ENTRY
  890. NdrNsGetBuffer( PMIDL_STUB_MESSAGE pStubMsg,
  891. unsigned long BufferLength,
  892. RPC_BINDING_HANDLE Handle )
  893. /*++
  894. Routine Description :
  895. Performs an RpcNsGetBuffer.
  896. Will load the RpcNs4 DLL if not already loaded
  897. Arguments :
  898. pStubMsg - Pointer to stub message structure.
  899. BufferLength - Length of requested rpc message buffer.
  900. Handle - Bound handle
  901. --*/
  902. {
  903. RPC_STATUS Status;
  904. if( pStubMsg->IsClient == TRUE )
  905. pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
  906. EnsureNSLoaded();
  907. LENGTH_ALIGN(BufferLength, 3);
  908. pStubMsg->RpcMsg->BufferLength = BufferLength;
  909. Status = (*pRpcNsGetBuffer)( pStubMsg->RpcMsg );
  910. if ( Status )
  911. RpcRaiseException( Status );
  912. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  913. "marshaling buffer misaligned" );
  914. pStubMsg->Buffer = (uchar *) pStubMsg->RpcMsg->Buffer;
  915. pStubMsg->fBufferValid = TRUE;
  916. return pStubMsg->Buffer;
  917. }
  918. unsigned char * RPC_ENTRY
  919. NdrSendReceive(
  920. PMIDL_STUB_MESSAGE pStubMsg,
  921. uchar * pBufferEnd )
  922. /*++
  923. Routine Description :
  924. Performs an RpcSendRecieve.
  925. This routine is executed for the non-pipe calls only.
  926. It returns a whole marshaling buffer.
  927. Arguments :
  928. pStubMsg - Pointer to stub message structure.
  929. pBufferEnd - End of the rpc message buffer being sent.
  930. Return :
  931. The new message buffer pointer returned from the runtime after the
  932. SendReceive call to the server.
  933. --*/
  934. {
  935. RPC_STATUS Status;
  936. PRPC_MESSAGE pRpcMsg;
  937. pRpcMsg = pStubMsg->RpcMsg;
  938. if ( pRpcMsg->BufferLength <
  939. (uint)(pBufferEnd - (uchar *)pRpcMsg->Buffer))
  940. {
  941. NDR_ASSERT( 0, "NdrSendReceive : buffer overflow" );
  942. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  943. }
  944. pRpcMsg->BufferLength = (ulong)(pBufferEnd - (uchar *)pRpcMsg->Buffer);
  945. pStubMsg->fBufferValid = FALSE;
  946. Status = I_RpcSendReceive( pRpcMsg );
  947. if ( Status )
  948. RpcRaiseException(Status);
  949. NDR_ASSERT( 0 == pRpcMsg->BufferLength ||
  950. NULL != pRpcMsg->Buffer,
  951. "Rpc runtime returned an invalid buffer.");
  952. NDR_ASSERT( ! ((ULONG_PTR)pRpcMsg->Buffer & 0x7),
  953. "marshaling buffer misaligned" );
  954. pStubMsg->Buffer = (uchar*)pRpcMsg->Buffer;
  955. pStubMsg->BufferStart = pStubMsg->Buffer;
  956. pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
  957. pStubMsg->fBufferValid = TRUE;
  958. return 0;
  959. }
  960. unsigned char * RPC_ENTRY
  961. NdrNsSendReceive(
  962. PMIDL_STUB_MESSAGE pStubMsg,
  963. uchar * pBufferEnd,
  964. RPC_BINDING_HANDLE * pAutoHandle )
  965. /*++
  966. Routine Description :
  967. Performs an RpcNsSendRecieve for a procedure which uses an auto handle.
  968. Will load the RpcNs4 DLL if not already loaded
  969. Arguments :
  970. pStubMsg - Pointer to stub message structure.
  971. pBufferEnd - End of the rpc message buffer being sent.
  972. pAutoHandle - Pointer to the auto handle used in the call.
  973. Return :
  974. The new message buffer pointer returned from the runtime after the
  975. SendReceive call to the server.
  976. --*/
  977. {
  978. RPC_STATUS Status;
  979. PRPC_MESSAGE pRpcMsg;
  980. EnsureNSLoaded();
  981. pRpcMsg = pStubMsg->RpcMsg;
  982. if ( pRpcMsg->BufferLength <
  983. (uint)(pBufferEnd - (uchar *)pRpcMsg->Buffer) )
  984. {
  985. NDR_ASSERT( 0, "NdrNsSendReceive : buffer overflow" );
  986. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  987. }
  988. pRpcMsg->BufferLength = (ulong)(pBufferEnd - (uchar *)pRpcMsg->Buffer);
  989. pStubMsg->fBufferValid = FALSE;
  990. Status = (*pRpcNsSendReceive)( pRpcMsg, pAutoHandle );
  991. if ( Status )
  992. RpcRaiseException(Status);
  993. pStubMsg->SavedHandle = *pAutoHandle;
  994. pStubMsg->Buffer = (uchar*)pRpcMsg->Buffer;
  995. pStubMsg->BufferStart = pStubMsg->Buffer;
  996. pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
  997. pStubMsg->fBufferValid = TRUE;
  998. return pStubMsg->Buffer;
  999. }
  1000. void RPC_ENTRY
  1001. NdrFreeBuffer(
  1002. PMIDL_STUB_MESSAGE pStubMsg )
  1003. /*++
  1004. Routine Description :
  1005. Performs an RpcFreeBuffer.
  1006. Arguments :
  1007. pStubMsg - pointer to stub message structure
  1008. Return :
  1009. None.
  1010. --*/
  1011. {
  1012. RPC_STATUS Status;
  1013. if ( ! pStubMsg->fBufferValid )
  1014. return;
  1015. if( ! pStubMsg->RpcMsg->Handle )
  1016. return;
  1017. Status = I_RpcFreeBuffer( pStubMsg->RpcMsg );
  1018. pStubMsg->fBufferValid = FALSE;
  1019. if ( Status )
  1020. RpcRaiseException(Status);
  1021. }
  1022. void * RPC_ENTRY
  1023. NdrAllocate(
  1024. PMIDL_STUB_MESSAGE pStubMsg,
  1025. size_t Len )
  1026. /*++
  1027. Routine Description :
  1028. Private allocator. Handles allocate all nodes cases.
  1029. Arguments :
  1030. pStubMsg - Pointer to stub message structure.
  1031. Len - Number of bytes to allocate.
  1032. Return :
  1033. Valid memory pointer.
  1034. --*/
  1035. {
  1036. void * pMemory;
  1037. if ( pStubMsg->pAllocAllNodesContext )
  1038. {
  1039. //
  1040. // We must guarantee 4 byte alignment on NT and MAC.
  1041. //
  1042. #if defined(__RPC_WIN64__)
  1043. ALIGN(pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory,7);
  1044. #else
  1045. ALIGN(pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory,3);
  1046. #endif
  1047. // Get the pointer.
  1048. pMemory = pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory;
  1049. // Increment the block pointer.
  1050. pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory += Len;
  1051. //
  1052. // Check for memory allocs past the end of our allocated buffer.
  1053. //
  1054. if ( pStubMsg->pAllocAllNodesContext->AllocAllNodesMemoryEnd <
  1055. pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory )
  1056. {
  1057. NDR_ASSERT( pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory <=
  1058. pStubMsg->pAllocAllNodesContext->AllocAllNodesMemoryEnd,
  1059. "Not enough alloc all nodes memory!" );
  1060. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1061. }
  1062. return pMemory;
  1063. }
  1064. else
  1065. {
  1066. size_t NodeOffset, FullSize;
  1067. PNDR_MEMORY_LIST_TAIL_NODE pMemoryList;
  1068. // Add linked list node to tail of allocation. Ensure that the tail
  1069. // is at a 8 byte alignment so that the same code will work in 64bits.
  1070. NodeOffset = Len;
  1071. LENGTH_ALIGN(NodeOffset, 7);
  1072. FullSize = NodeOffset + sizeof(NDR_MEMORY_LIST_TAIL_NODE);
  1073. // prevent arithmetic overflow
  1074. if ( FullSize < Len )
  1075. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  1076. if ( ! (pMemory = (*pStubMsg->pfnAllocate)( FullSize )) )
  1077. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  1078. pMemoryList = (PNDR_MEMORY_LIST_TAIL_NODE)((char *)pMemory + NodeOffset);
  1079. pMemoryList->Signature = NDR_MEMORY_LIST_SIGNATURE;
  1080. pMemoryList->pMemoryHead = pMemory;
  1081. pMemoryList->pNextNode = (PNDR_MEMORY_LIST_TAIL_NODE)pStubMsg->pMemoryList;
  1082. pStubMsg->pMemoryList = pMemoryList;
  1083. return pMemory;
  1084. }
  1085. }
  1086. void
  1087. NdrpFreeMemoryList(
  1088. MIDL_STUB_MESSAGE * pStubMsg)
  1089. /*++
  1090. Routine Description :
  1091. Freeing the list of memory allocated by NdrAllocate.
  1092. Arguments :
  1093. pStubMsg - Pointer to stub message structure.
  1094. Return :
  1095. None.
  1096. --*/
  1097. {
  1098. // if the server memory is corrupted, it's probably better to let it die
  1099. while(pStubMsg->pMemoryList)
  1100. {
  1101. PNDR_MEMORY_LIST_TAIL_NODE pMemoryList =
  1102. (PNDR_MEMORY_LIST_TAIL_NODE)pStubMsg->pMemoryList;
  1103. if (pMemoryList->Signature != NDR_MEMORY_LIST_SIGNATURE)
  1104. {
  1105. NDR_ASSERT( 0 , "bad rpc allocated memory signature" );
  1106. return;
  1107. }
  1108. pStubMsg->pMemoryList = pMemoryList->pNextNode;
  1109. (*pStubMsg->pfnFree)(pMemoryList->pMemoryHead);
  1110. }
  1111. }
  1112. unsigned char * RPC_ENTRY
  1113. NdrServerInitializeUnmarshall (
  1114. PMIDL_STUB_MESSAGE pStubMsg,
  1115. PMIDL_STUB_DESC pStubDescriptor,
  1116. PRPC_MESSAGE pRpcMsg )
  1117. /*++
  1118. Routine Description :
  1119. Old NT Beta2 (build 683) server stub initialization routine. Used for
  1120. backward compatability only.
  1121. Aruguments :
  1122. pStubMsg - Pointer to the stub message structure.
  1123. pStubDescriptor - Pointer to the stub descriptor structure.
  1124. pBuffer - Pointer to the beginning of the RPC message buffer.
  1125. --*/
  1126. {
  1127. return NdrServerInitialize( pRpcMsg,
  1128. pStubMsg,
  1129. pStubDescriptor );
  1130. }
  1131. void RPC_ENTRY
  1132. NdrServerInitializeMarshall (
  1133. PRPC_MESSAGE pRpcMsg,
  1134. PMIDL_STUB_MESSAGE pStubMsg )
  1135. /*++
  1136. Routine Description :
  1137. Old NT Beta2 (build 683) server stub initialization routine. Used for
  1138. backward compatability only.
  1139. Arguments :
  1140. pRpcMsg - Pointer to the RPC message structure.
  1141. pStubMsg - Pointer to the stub message structure.
  1142. --*/
  1143. {
  1144. }
  1145. //
  1146. // Functions to simulate a alloca across a function call.
  1147. // Note that this code is optimized for simplicity and speed. It does
  1148. // not attempt to search a list on each allocation to reuse partially full
  1149. // blocks as much as it could. This gives max speed, but hurts space
  1150. // utilization when allocations of significantly different sizes are requested.
  1151. //
  1152. // This code can easily be optimized more in the future.
  1153. #if defined(NDR_PROFILE_ALLOCA)
  1154. VOID
  1155. NdrpAllocaWriteLog( CHAR *pChar, DWORD Size )
  1156. {
  1157. HANDLE hMutex = NULL;
  1158. HANDLE hLogFile = INVALID_HANDLE_VALUE;
  1159. BOOL bHasMutex = FALSE;
  1160. RpcTryFinally
  1161. {
  1162. // Open and acquire the log mutex
  1163. hMutex = CreateMutex( NULL, FALSE, "NDR_ALLOCA_LOG_MUTEX");
  1164. if ( !hMutex) return;
  1165. DWORD dwWaitResult = WaitForSingleObject( hMutex, INFINITE );
  1166. if ( WAIT_FAILED == dwWaitResult ) return;
  1167. bHasMutex = TRUE;
  1168. CHAR LogFile[MAX_PATH];
  1169. UINT DirResult =
  1170. GetSystemDirectoryA( LogFile, sizeof(LogFile) );
  1171. if ( !DirResult) return;
  1172. strcat( LogFile, "\\ndralloca.log" );
  1173. hLogFile = CreateFileA( LogFile,
  1174. GENERIC_WRITE,
  1175. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1176. NULL,
  1177. OPEN_ALWAYS,
  1178. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
  1179. NULL );
  1180. SetFilePointer( hLogFile, 0, NULL, FILE_END );
  1181. DWORD dwBytesWritten;
  1182. WriteFile( hLogFile, pChar, Size, &dwBytesWritten, NULL );
  1183. }
  1184. RpcFinally
  1185. {
  1186. if ( bHasMutex ) ReleaseMutex( hMutex );
  1187. if ( NULL != hMutex) CloseHandle( hMutex );
  1188. if ( INVALID_HANDLE_VALUE != hLogFile ) CloseHandle( hLogFile );
  1189. }
  1190. RpcEndFinally
  1191. }
  1192. VOID
  1193. NdrpAllocaDumpStatistics(
  1194. PNDR_ALLOCA_CONTEXT pAllocaContext
  1195. )
  1196. {
  1197. // Produce a record suitable for entry into Excel.
  1198. CHAR DataBuffer[4048];
  1199. CHAR AppName[MAX_PATH];
  1200. memset(AppName, 0, sizeof(AppName ) );
  1201. GetModuleFileNameA( NULL, AppName, sizeof(AppName ) );
  1202. sprintf( DataBuffer, "EXE,%s,PID,0x%X,TID,0x%x,CS,%d,AB,%d,AA,%d,MB,%d,MA,%d\r\n",
  1203. AppName,
  1204. GetCurrentProcessId(),
  1205. GetCurrentThreadId(),
  1206. (long)NDR_ALLOCA_PREALLOCED_BLOCK_SIZE,
  1207. pAllocaContext->AllocaBytes,
  1208. pAllocaContext->AllocaAllocations,
  1209. pAllocaContext->MemoryBytes,
  1210. pAllocaContext->MemoryAllocations );
  1211. NdrpAllocaWriteLog( DataBuffer, strlen( DataBuffer ) );
  1212. }
  1213. #endif
  1214. VOID
  1215. NdrpAllocaInit(
  1216. PNDR_ALLOCA_CONTEXT pAllocaContext
  1217. )
  1218. /*++
  1219. Routine Description :
  1220. Initiaizes the alloca context.
  1221. Arguments :
  1222. pAllocaContext - Pointer to the Alloca context..
  1223. Return :
  1224. None.
  1225. --*/
  1226. {
  1227. pAllocaContext->pBlockPointer = pAllocaContext->PreAllocatedBlock;
  1228. pAllocaContext->BytesRemaining = NDR_ALLOCA_PREALLOCED_BLOCK_SIZE;
  1229. #if defined(NDR_PROFILE_ALLOCA)
  1230. pAllocaContext->AllocaBytes = 0;
  1231. pAllocaContext->AllocaAllocations = 0;
  1232. pAllocaContext->MemoryBytes = 0;
  1233. pAllocaContext->MemoryAllocations = 0;
  1234. #endif
  1235. InitializeListHead( &pAllocaContext->MemoryList );
  1236. }
  1237. VOID
  1238. NdrpAllocaDestroy(
  1239. PNDR_ALLOCA_CONTEXT pAllocaContext
  1240. )
  1241. /*++
  1242. Routine Description :
  1243. Deinitializes this Alloca context and frees all memory
  1244. from the allocation calls that were associated with this context.
  1245. Arguments :
  1246. pAllocaContext - Pointer to the Alloca context.
  1247. Return :
  1248. None.
  1249. --*/
  1250. {
  1251. #if defined(NDR_PROFILE_ALLOCA)
  1252. NdrpAllocaDumpStatistics( pAllocaContext );
  1253. #endif
  1254. PLIST_ENTRY pMemoryList = pAllocaContext->MemoryList.Flink;
  1255. while( pMemoryList != &pAllocaContext->MemoryList )
  1256. {
  1257. PLIST_ENTRY pMemoryListNext = pMemoryList->Flink;
  1258. I_RpcFree( pMemoryList );
  1259. pMemoryList = pMemoryListNext;
  1260. }
  1261. InitializeListHead( &pAllocaContext->MemoryList );
  1262. }
  1263. PVOID
  1264. NdrpAlloca(
  1265. PNDR_ALLOCA_CONTEXT pAllocaContext,
  1266. UINT Size
  1267. )
  1268. /*++
  1269. Routine Description :
  1270. Allocates memory from the allocation context. If no memory is available
  1271. in the cache, more memory is added. If more memory can not be
  1272. added, a RPC_S_NO_MEMORY exception is raised.
  1273. Arguments :
  1274. pAllocaContext - Pointer to the Alloca context.
  1275. Size - Size of the memory to allocate.
  1276. Return :
  1277. Newly allocated memory.
  1278. --*/
  1279. {
  1280. PVOID pReturnedBlock;
  1281. LENGTH_ALIGN( Size, 15 );
  1282. #if defined(NDR_PROFILE_ALLOCA)
  1283. pAllocaContext->AllocaAllocations++;
  1284. pAllocaContext->AllocaBytes += Size;
  1285. #endif
  1286. // Check if the current block has enough memory to handle the request.
  1287. if (Size > pAllocaContext->BytesRemaining)
  1288. {
  1289. // Allocate a new block
  1290. ULONG NewBlockSize = max( Size + sizeof(LIST_ENTRY),
  1291. NDR_ALLOCA_MIN_BLOCK_SIZE );
  1292. #if defined(NDR_PROFILE_ALLOCA)
  1293. pAllocaContext->MemoryAllocations++;
  1294. pAllocaContext->MemoryBytes += NewBlockSize;
  1295. #endif
  1296. PBYTE pNewBlock = (PBYTE)I_RpcAllocate( NewBlockSize );
  1297. if ( !pNewBlock )
  1298. {
  1299. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  1300. return NULL; // keep the compiler happy
  1301. }
  1302. InsertHeadList( &pAllocaContext->MemoryList, (PLIST_ENTRY) pNewBlock);
  1303. pAllocaContext->pBlockPointer = pNewBlock + sizeof(LIST_ENTRY);
  1304. pAllocaContext->BytesRemaining = NewBlockSize - sizeof(LIST_ENTRY);
  1305. }
  1306. // alloc memory from an existing block.
  1307. pReturnedBlock = pAllocaContext->pBlockPointer;
  1308. pAllocaContext->pBlockPointer += Size;
  1309. pAllocaContext->BytesRemaining -= Size;
  1310. return pReturnedBlock;
  1311. }
  1312. PVOID
  1313. NdrpPrivateAllocate(
  1314. PNDR_ALLOCA_CONTEXT pAllocaContext,
  1315. UINT Size
  1316. )
  1317. /*++
  1318. Routine Description :
  1319. Allocates memory using I_RpcAllocate and adds the memory to the
  1320. memory list block. If no memory is available, and RPC_S_OUT_OF_MEMORY exception
  1321. is thrown.
  1322. Arguments :
  1323. pAllocaContext - Pointer to the Alloca context.
  1324. Size - Size of the memory to allocate.
  1325. Return :
  1326. Newly allocated memory.
  1327. --*/
  1328. {
  1329. PBYTE pNewBlock = (PBYTE)NdrpAlloca( pAllocaContext, Size );
  1330. if ( !pNewBlock )
  1331. {
  1332. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  1333. return NULL; // keep the compiler happy
  1334. }
  1335. return (uchar *)pNewBlock ;
  1336. }
  1337. void
  1338. NdrpPrivateFree(
  1339. PNDR_ALLOCA_CONTEXT pAllocaContext,
  1340. void *pMemory
  1341. )
  1342. /*++
  1343. Routine Description :
  1344. Frees memory allocated with NdrpPrivateAllocate
  1345. Arguments :
  1346. pAllocaContext - Pointer to the Alloca context.
  1347. pMemory - Memory allocated with NdrpPrivateAllocate.
  1348. Return :
  1349. None.
  1350. --*/
  1351. {
  1352. return;
  1353. }
  1354. void
  1355. NdrpInitUserMarshalCB(
  1356. MIDL_STUB_MESSAGE * pStubMsg,
  1357. PFORMAT_STRING pFormat,
  1358. USER_MARSHAL_CB_TYPE CBType,
  1359. USER_MARSHAL_CB * pUserMarshalCB
  1360. )
  1361. /*++
  1362. Routine Description :
  1363. Initialize a user marshall callback structure.
  1364. Arguments :
  1365. pStubMsg - Supplies the stub message for the call.
  1366. pFormat - Supplies the format string for the type(FC_USER_MARSHAL).
  1367. CBType - Supplies the callback type.
  1368. pUserMarshalCB - Pointer to the callback to be initialized.
  1369. Return :
  1370. None.
  1371. --*/
  1372. {
  1373. pUserMarshalCB->Flags = USER_CALL_CTXT_MASK( pStubMsg->dwDestContext );
  1374. if ( USER_MARSHAL_CB_UNMARSHALL == CBType )
  1375. {
  1376. pUserMarshalCB->Flags |=
  1377. (((pStubMsg->RpcMsg->DataRepresentation & (ulong)0x0000FFFF)) << 16 );
  1378. }
  1379. if ( pStubMsg->pAsyncMsg )
  1380. pUserMarshalCB->Flags |= USER_CALL_IS_ASYNC;
  1381. if ( pStubMsg->fHasNewCorrDesc )
  1382. pUserMarshalCB->Flags |= USER_CALL_NEW_CORRELATION_DESC;
  1383. pUserMarshalCB->pStubMsg = pStubMsg;
  1384. pUserMarshalCB->pReserve = (pFormat[1] & USER_MARSHAL_IID) ? pFormat + 10
  1385. : 0;
  1386. pUserMarshalCB->Signature = USER_MARSHAL_CB_SIGNATURE;
  1387. pUserMarshalCB->CBType = CBType;
  1388. pUserMarshalCB->pFormat = pFormat;
  1389. pUserMarshalCB->pTypeFormat = pFormat + 8;
  1390. pUserMarshalCB->pTypeFormat = pUserMarshalCB->pTypeFormat +
  1391. *(short *)pUserMarshalCB->pTypeFormat;
  1392. }
  1393. RPC_STATUS
  1394. RPC_ENTRY
  1395. NdrGetUserMarshalInfo (
  1396. IN unsigned long * pFlags,
  1397. IN unsigned long InformationLevel,
  1398. OUT NDR_USER_MARSHAL_INFO * pMarshalInfo
  1399. )
  1400. /*++
  1401. Routine Description :
  1402. The NdrGetUserMarshalInfo function is called by a application provided
  1403. wire_marshal or user_marshal helper function to receive extra information
  1404. in addition to the pFlags parameter.
  1405. Arguments :
  1406. pFlags - Supplies the pFlags pointer that rpc passed to the helper function.
  1407. InformationLevel - Supplies the desired level of detail to be received. The amount of
  1408. information increases as the level increases.
  1409. pMarshalInfo - Points to the buffer that is to receive the extra information.
  1410. Return :
  1411. On sucesss - RPC_S_OK.
  1412. --*/
  1413. {
  1414. MIDL_STUB_MESSAGE *pStubMsg;
  1415. USER_MARSHAL_CB * pCBInfo = (USER_MARSHAL_CB *)pFlags;
  1416. if ( InformationLevel != 1)
  1417. {
  1418. return RPC_S_INVALID_ARG;
  1419. }
  1420. RpcTryExcept
  1421. {
  1422. if ( USER_MARSHAL_CB_SIGNATURE != pCBInfo->Signature )
  1423. {
  1424. return RPC_S_INVALID_ARG;
  1425. }
  1426. MIDL_memset( pMarshalInfo, 0, sizeof(NDR_USER_MARSHAL_INFO) );
  1427. }
  1428. RpcExcept(1)
  1429. {
  1430. return RPC_S_INVALID_ARG;
  1431. }
  1432. RpcEndExcept
  1433. pMarshalInfo->InformationLevel = InformationLevel;
  1434. pStubMsg = pCBInfo->pStubMsg;
  1435. // The buffer pointer and the buffer length only
  1436. // make sense if the callback is for marshalling
  1437. // and unmarshalling.
  1438. if ( USER_MARSHAL_CB_MARSHALL == pCBInfo->CBType ||
  1439. USER_MARSHAL_CB_UNMARSHALL == pCBInfo->CBType )
  1440. {
  1441. char *CurrentBuffer = (char *)pStubMsg->Buffer;
  1442. char *BufferStart = (char *)pStubMsg->RpcMsg->Buffer;
  1443. unsigned long BufferUsed = (unsigned long)(ULONG_PTR)(CurrentBuffer
  1444. - BufferStart);
  1445. unsigned long BufferLength = pStubMsg->RpcMsg->BufferLength - BufferUsed;
  1446. if ( CurrentBuffer < BufferStart ||
  1447. CurrentBuffer > (BufferStart + pStubMsg->RpcMsg->BufferLength ) )
  1448. {
  1449. return RPC_X_INVALID_BUFFER;
  1450. }
  1451. pMarshalInfo->Level1.Buffer = pStubMsg->Buffer;
  1452. pMarshalInfo->Level1.BufferSize = BufferLength;
  1453. }
  1454. pMarshalInfo->Level1.pfnAllocate = pStubMsg->pfnAllocate;
  1455. pMarshalInfo->Level1.pfnFree = pStubMsg->pfnFree;
  1456. pMarshalInfo->Level1.pRpcChannelBuffer = pStubMsg->pRpcChannelBuffer;
  1457. pMarshalInfo->Level1.Reserved[0] = (ULONG_PTR)pCBInfo->pFormat;
  1458. pMarshalInfo->Level1.Reserved[1] = (ULONG_PTR)pCBInfo->pTypeFormat;
  1459. return RPC_S_OK;
  1460. }
  1461. void RPC_ENTRY
  1462. RpcUserFree( HANDLE AsyncHandle, void * pBuffer )
  1463. {
  1464. PMIDL_STUB_MESSAGE pStubMsg;
  1465. RPC_STATUS Status;
  1466. PRPC_ASYNC_STATE pHandle = ( PRPC_ASYNC_STATE) AsyncHandle;
  1467. // User passes in NULL in sync case.
  1468. if ( NULL == pHandle )
  1469. {
  1470. pStubMsg = (PMIDL_STUB_MESSAGE )I_RpcGetNDRSlot();
  1471. Status = S_OK;
  1472. }
  1473. else
  1474. {
  1475. Status = NdrValidateBothAndLockAsyncHandle( pHandle);
  1476. if ( Status == RPC_S_OK )
  1477. {
  1478. PNDR_ASYNC_MESSAGE pAsyncMsg = (PNDR_ASYNC_MESSAGE) pHandle->StubInfo;
  1479. pStubMsg = &pAsyncMsg->StubMsg;
  1480. }
  1481. }
  1482. // REVIEW: default behavior is not to raise exception?
  1483. if ( Status != RPC_S_OK )
  1484. {
  1485. NDR_ASSERT( 0, "invalid rpc handle" );
  1486. return ;
  1487. }
  1488. // validate the stubmsg.
  1489. NDR_ASSERT( pStubMsg, "invalid stub message" );
  1490. // We'll call into user's free routine to free the buffer if it's not
  1491. // part of dispatch buffer.
  1492. // We don't care about allocate_on_stack: it can only happen on top level
  1493. // out ref pointer or ref pointer to pointer case, and freeing that is
  1494. // very much shooting self on the foot.
  1495. if ( (pBuffer < pStubMsg->BufferStart) || (pBuffer > pStubMsg->BufferEnd))
  1496. {
  1497. pStubMsg->pfnFree( pBuffer );
  1498. }
  1499. else
  1500. return;
  1501. }
  1502. BOOL
  1503. IsWriteAV (
  1504. IN struct _EXCEPTION_POINTERS *ExceptionPointers
  1505. )
  1506. {
  1507. EXCEPTION_RECORD *ExceptionRecord;
  1508. ExceptionRecord = ExceptionPointers->ExceptionRecord;
  1509. if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION)
  1510. && (ExceptionRecord->ExceptionInformation[0]))
  1511. {
  1512. return TRUE;
  1513. }
  1514. else
  1515. return FALSE;
  1516. }
  1517. int RPC_ENTRY
  1518. NdrServerUnmarshallExceptionFlag(
  1519. IN struct _EXCEPTION_POINTERS *ExceptionPointers
  1520. )
  1521. {
  1522. RPC_STATUS ExceptCode = ExceptionPointers->ExceptionRecord->ExceptionCode;
  1523. if ( ( ExceptCode != STATUS_POSSIBLE_DEADLOCK ) &&
  1524. ( ExceptCode != STATUS_INSTRUCTION_MISALIGNMENT ) &&
  1525. ( ExceptCode != STATUS_DATATYPE_MISALIGNMENT ) &&
  1526. ( ExceptCode != STATUS_PRIVILEGED_INSTRUCTION ) &&
  1527. ( ExceptCode != STATUS_ILLEGAL_INSTRUCTION ) &&
  1528. ( ExceptCode != STATUS_BREAKPOINT ) &&
  1529. ( ExceptCode != STATUS_STACK_OVERFLOW ) &&
  1530. !IsWriteAV(ExceptionPointers) )
  1531. return EXCEPTION_EXECUTE_HANDLER;
  1532. else
  1533. return EXCEPTION_CONTINUE_SEARCH;
  1534. }
  1535. // check for overflow when calculating the total size.
  1536. #if defined(_X86_)
  1537. ULONG MultiplyWithOverflowCheck( ULONG_PTR Count, ULONG_PTR ELemSize )
  1538. {
  1539. register UINT32 IsOverFlowed = 0;
  1540. NDR_CORRUPTION_ASSERT( Count < 0x80000000, "invalid count" );
  1541. NDR_CORRUPTION_ASSERT( ELemSize < 0x80000000 , "invalid element size" );
  1542. ULONG res = Count * ELemSize;
  1543. __asm
  1544. {
  1545. jno skip;
  1546. mov IsOverFlowed, 1;
  1547. skip:
  1548. }
  1549. if ( IsOverFlowed || res > 0x7fffffff )
  1550. RpcRaiseException( RPC_X_INVALID_BOUND );
  1551. return res;
  1552. }
  1553. #else // we only have ia64 & amd64 here.
  1554. ULONG MultiplyWithOverflowCheck( ULONG_PTR Count, ULONG_PTR ElemSize )
  1555. {
  1556. NDR_CORRUPTION_ASSERT( Count < 0x80000000, "invalid count" );
  1557. NDR_CORRUPTION_ASSERT( ElemSize < 0x80000000 , "invalid element size" );
  1558. UINT64 res = (UINT64)Count * ElemSize;
  1559. if ( res > 0x7fffffff )
  1560. RpcRaiseException( RPC_X_INVALID_BOUND );
  1561. return (ULONG) res ;
  1562. }
  1563. #endif
  1564. void
  1565. NdrpInitArrayInfo( PMIDL_STUB_MESSAGE pStubMsg, ARRAY_INFO * pArrayInfo )
  1566. {
  1567. // we cannot use pArrayInfo from stack if we are in pointer queue; also, pPointerQueueState
  1568. // could be NULL if we have top level multiD array and pointer queue is on always. We have
  1569. // to use stack in that case too.
  1570. if ( !NdrIsLowStack(pStubMsg) || (pStubMsg->pPointerQueueState == NULL ) )
  1571. {
  1572. pStubMsg->pArrayInfo = pArrayInfo;
  1573. }
  1574. else
  1575. {
  1576. NDR_POINTER_QUEUE_STATE *pActiveState = pStubMsg->pPointerQueueState;
  1577. NDR_ASSERT( pActiveState != NULL, "invaild pointer queue");
  1578. if ( pActiveState )
  1579. pStubMsg->pArrayInfo = pActiveState->GetArrayInfo();
  1580. else
  1581. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1582. }
  1583. pStubMsg->pArrayInfo->Dimension = 0;
  1584. pStubMsg->pArrayInfo->BufferConformanceMark = (unsigned long *)pStubMsg->BufferMark;
  1585. pStubMsg->pArrayInfo->BufferVarianceMark = 0;
  1586. pStubMsg->pArrayInfo->MaxCountArray = (unsigned long *) pStubMsg->MaxCount;
  1587. pStubMsg->pArrayInfo->OffsetArray = (ulong *) UlongToPtr( pStubMsg->Offset );
  1588. pStubMsg->pArrayInfo->ActualCountArray = (ulong *) UlongToPtr( pStubMsg->ActualCount );
  1589. }