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.

2376 lines
70 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name:
  4. pickle.cxx
  5. Abstract:
  6. This module contains pickling related ndr library routines.
  7. Notes:
  8. Author:
  9. Ryszard K. Kott (ryszardk) Oct 10, 1993
  10. Revision History:
  11. ryszardk Mar 17, 1994 Reworked for midl20
  12. ------------------------------------------------------------------------*/
  13. #include <ndrp.h>
  14. #include <rpcdcep.h>
  15. #include "ndrtypes.h"
  16. #include <midles.h>
  17. #include <stdarg.h>
  18. #include <malloc.h>
  19. #include "interp2.h"
  20. #include "mulsyntx.h"
  21. #include "picklep.hxx"
  22. #include "util.hxx" // PerformRpcInitialization
  23. extern const MIDL_FORMAT_STRING __MIDLFormatString;
  24. // DCE puts endianness on the low nibble in the pickling header.
  25. #define NDR_LOCAL_ENDIAN_LOW (NDR_LOCAL_ENDIAN >> 4)
  26. RPC_STATUS
  27. NdrpPerformRpcInitialization (
  28. void
  29. )
  30. {
  31. return PerformRpcInitialization();
  32. }
  33. // =======================================================================
  34. // Handle validation
  35. // =======================================================================
  36. void
  37. NdrpValidateMesHandle(
  38. PMIDL_ES_MESSAGE_EX pMesMsgEx )
  39. {
  40. RpcTryExcept
  41. {
  42. if ( pMesMsgEx == 0 || pMesMsgEx->Signature != MIDL_ES_SIGNATURE ||
  43. pMesMsgEx->MesMsg.MesVersion != MIDL_ES_VERSION )
  44. RpcRaiseException( RPC_S_INVALID_ARG );
  45. }
  46. RpcExcept( 1 )
  47. {
  48. RpcRaiseException( RPC_S_INVALID_ARG );
  49. }
  50. RpcEndExcept
  51. }
  52. RPC_STATUS
  53. NdrpValidateMesHandleReturnStatus(
  54. PMIDL_ES_MESSAGE_EX pMesMsgEx )
  55. {
  56. RPC_STATUS Status = RPC_S_OK;
  57. RpcTryExcept
  58. {
  59. if ( pMesMsgEx == 0 || pMesMsgEx->Signature != MIDL_ES_SIGNATURE ||
  60. ( pMesMsgEx->MesMsg.MesVersion != MIDL_ES_VERSION &&
  61. pMesMsgEx->MesMsg.MesVersion != MIDL_NDR64_ES_VERSION ) )
  62. Status = RPC_S_INVALID_ARG;
  63. }
  64. RpcExcept( 1 )
  65. {
  66. Status = RPC_S_INVALID_ARG;
  67. }
  68. RpcEndExcept
  69. return Status;
  70. }
  71. // =======================================================================
  72. // Handle allocation and freeing.
  73. // =======================================================================
  74. RPC_STATUS
  75. NdrpHandleAllocate(
  76. handle_t * pHandle )
  77. /*++
  78. The reason for having this function here is that
  79. handle_t is a near pointer on win16 (but not on Dos),
  80. and we still compile the whole rpcndr20 large for that platform.
  81. So we need near malloc to be within the default segment.
  82. --*/
  83. {
  84. RPC_STATUS RpcStatus;
  85. if ( pHandle == NULL )
  86. return( RPC_S_INVALID_ARG );
  87. // Rpc mtrt heap allocation initialization (any platform).
  88. // This is a macro that returns from NdrpHandleAllocate with
  89. // out of memory error when it fails.
  90. // It's under an if only to facilitate testing.
  91. RpcStatus = NdrpPerformRpcInitialization();
  92. if ( RpcStatus != RPC_S_OK )
  93. return(RpcStatus);
  94. // Now allocate.
  95. // Mes handle includes stubmsg but we need to add rpcmsg to it.
  96. *pHandle = new char[ sizeof(MIDL_ES_MESSAGE_EX) ];
  97. if ( *pHandle == NULL )
  98. return( RPC_S_OUT_OF_MEMORY );
  99. return( RPC_S_OK );
  100. }
  101. RPC_STATUS RPC_ENTRY
  102. MesHandleFree( handle_t Handle )
  103. /*++
  104. This routine frees a pickling handle.
  105. --*/
  106. {
  107. if ( Handle)
  108. {
  109. delete Handle;
  110. }
  111. return( RPC_S_OK );
  112. }
  113. void RPC_ENTRY
  114. I_NdrMesMessageInit(
  115. PMIDL_ES_MESSAGE_EX pMesMsgEx )
  116. {
  117. PMIDL_STUB_MESSAGE pStubMsg = & pMesMsgEx->MesMsg.StubMsg;
  118. PRPC_MESSAGE pRpcMsg = & pMesMsgEx->RpcMsg;
  119. MIDL_memset( pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE) );
  120. MIDL_memset( pRpcMsg, 0, sizeof(RPC_MESSAGE) );
  121. pRpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  122. pStubMsg->RpcMsg = pRpcMsg;
  123. pStubMsg->IsClient = 1;
  124. NdrSetupLowStackMark( pStubMsg );
  125. }
  126. // =======================================================================
  127. RPC_STATUS RPC_ENTRY
  128. MesEncodeIncrementalHandleCreate(
  129. void * UserState,
  130. MIDL_ES_ALLOC Alloc,
  131. MIDL_ES_WRITE Write,
  132. handle_t * pHandle )
  133. /*++
  134. This routine creates an encoding incremental pickling handle.
  135. --*/
  136. {
  137. RPC_STATUS Status;
  138. if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
  139. {
  140. ((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_INCREMENTAL_HANDLE;
  141. ((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
  142. ((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
  143. if ( (Status = MesIncrementalHandleReset( *pHandle,
  144. UserState,
  145. Alloc,
  146. Write,
  147. 0,
  148. MES_ENCODE )) != RPC_S_OK )
  149. {
  150. MesHandleFree( *pHandle );
  151. *pHandle = NULL;
  152. }
  153. }
  154. return( Status );
  155. }
  156. RPC_STATUS RPC_ENTRY
  157. MesDecodeIncrementalHandleCreate(
  158. void * UserState,
  159. MIDL_ES_READ Read,
  160. handle_t * pHandle )
  161. /*++
  162. This routine creates a descoding incrementsl pickling handle.
  163. --*/
  164. {
  165. RPC_STATUS Status;
  166. if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
  167. {
  168. ((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_INCREMENTAL_HANDLE;
  169. ((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
  170. ((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
  171. if ( (Status = MesIncrementalHandleReset( *pHandle,
  172. UserState,
  173. 0,
  174. 0,
  175. Read,
  176. MES_DECODE )) != RPC_S_OK )
  177. {
  178. MesHandleFree( *pHandle );
  179. *pHandle = NULL;
  180. }
  181. }
  182. return( Status );
  183. }
  184. RPC_STATUS RPC_ENTRY
  185. MesIncrementalHandleReset(
  186. handle_t Handle,
  187. void * UserState,
  188. MIDL_ES_ALLOC Alloc,
  189. MIDL_ES_WRITE Write,
  190. MIDL_ES_READ Read,
  191. MIDL_ES_CODE Operation )
  192. /*++
  193. This routine initializes a pickling handle with supplied arguments.
  194. --*/
  195. {
  196. RPC_STATUS Status;
  197. Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
  198. if ( Status != RPC_S_OK )
  199. return Status;
  200. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  201. // we support ndr64 pickling now.
  202. if ( Handle == NULL ||
  203. pMesMsg->HandleStyle != MES_INCREMENTAL_HANDLE ||
  204. ( Operation != MES_ENCODE &&
  205. Operation != MES_DECODE &&
  206. Operation != MES_ENCODE_NDR64 &&
  207. Operation != MES_DECODE_NDR64 ) )
  208. return( RPC_S_INVALID_ARG );
  209. I_NdrMesMessageInit( (PMIDL_ES_MESSAGE_EX) Handle );
  210. pMesMsg->Operation = Operation;
  211. pMesMsg->HandleFlags = 0;
  212. pMesMsg->ByteCount = 0;
  213. if ( Operation == MES_ENCODE_NDR64 ||
  214. Operation == MES_DECODE_NDR64 )
  215. {
  216. pMesMsg->MesVersion = MIDL_NDR64_ES_VERSION;
  217. }
  218. else
  219. {
  220. pMesMsg->MesVersion = MIDL_ES_VERSION;
  221. }
  222. if ( UserState )
  223. pMesMsg->UserState = UserState;
  224. if ( Alloc )
  225. pMesMsg->Alloc = Alloc;
  226. if ( Write )
  227. pMesMsg->Write = Write;
  228. if ( Read )
  229. pMesMsg->Read = Read;
  230. if ( ( (Operation == MES_ENCODE || Operation == MES_ENCODE_NDR64 ) &&
  231. (pMesMsg->Alloc == NULL || pMesMsg->Write == NULL) ) ||
  232. ( (Operation == MES_DECODE || Operation == MES_DECODE_NDR64 ) &&
  233. (pMesMsg->Read == NULL)) )
  234. return( RPC_S_INVALID_ARG );
  235. return( RPC_S_OK );
  236. }
  237. RPC_STATUS RPC_ENTRY
  238. MesEncodeFixedBufferHandleCreate(
  239. char * Buffer,
  240. unsigned long BufferSize,
  241. unsigned long * pEncodedSize,
  242. handle_t * pHandle )
  243. {
  244. RPC_STATUS Status;
  245. if( (LONG_PTR)Buffer & 0x7 )
  246. return( RPC_X_INVALID_BUFFER );
  247. if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
  248. {
  249. ((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_FIXED_BUFFER_HANDLE;
  250. ((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
  251. ((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
  252. if ( (Status = MesBufferHandleReset( *pHandle,
  253. MES_FIXED_BUFFER_HANDLE,
  254. MES_ENCODE,
  255. & Buffer,
  256. BufferSize,
  257. pEncodedSize )) != RPC_S_OK )
  258. {
  259. MesHandleFree( *pHandle );
  260. *pHandle = NULL;
  261. }
  262. }
  263. return( Status );
  264. }
  265. RPC_STATUS RPC_ENTRY
  266. MesEncodeDynBufferHandleCreate(
  267. char ** pBuffer,
  268. unsigned long * pEncodedSize,
  269. handle_t * pHandle )
  270. {
  271. RPC_STATUS Status;
  272. if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
  273. {
  274. ((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_DYNAMIC_BUFFER_HANDLE;
  275. ((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
  276. ((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
  277. if ( (Status = MesBufferHandleReset( *pHandle,
  278. MES_DYNAMIC_BUFFER_HANDLE,
  279. MES_ENCODE,
  280. pBuffer,
  281. 0,
  282. pEncodedSize )) != RPC_S_OK )
  283. {
  284. MesHandleFree( *pHandle );
  285. *pHandle = NULL;
  286. }
  287. }
  288. return( Status );
  289. }
  290. RPC_STATUS RPC_ENTRY
  291. MesDecodeBufferHandleCreate(
  292. char * Buffer,
  293. unsigned long BufferSize,
  294. handle_t * pHandle )
  295. {
  296. if ( Buffer == NULL ||
  297. BufferSize < MES_CTYPE_HEADER_SIZE + 8 )
  298. return( RPC_S_INVALID_ARG );
  299. if( (LONG_PTR)Buffer & 0x7 )
  300. return( RPC_X_INVALID_BUFFER );
  301. RPC_STATUS Status;
  302. if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
  303. {
  304. ((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_FIXED_BUFFER_HANDLE;
  305. ((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
  306. ((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
  307. if ( (Status = MesBufferHandleReset( *pHandle,
  308. MES_FIXED_BUFFER_HANDLE,
  309. MES_DECODE,
  310. & Buffer,
  311. BufferSize,
  312. 0 )) != RPC_S_OK )
  313. {
  314. MesHandleFree( *pHandle );
  315. *pHandle = NULL;
  316. }
  317. }
  318. return( Status );
  319. }
  320. // reset a pickling handle.
  321. RPC_STATUS RPC_ENTRY
  322. MesBufferHandleReset(
  323. handle_t Handle,
  324. unsigned long HandleStyle,
  325. MIDL_ES_CODE Operation,
  326. char * * pBuffer,
  327. unsigned long BufferSize,
  328. unsigned long * pEncodedSize )
  329. {
  330. RPC_STATUS Status;
  331. Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
  332. if ( Status != RPC_S_OK )
  333. return Status;
  334. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  335. if ( Handle == NULL || pBuffer == NULL ||
  336. ( HandleStyle != MES_FIXED_BUFFER_HANDLE &&
  337. HandleStyle != MES_DYNAMIC_BUFFER_HANDLE ) ||
  338. (HandleStyle == MES_FIXED_BUFFER_HANDLE &&
  339. (*pBuffer == NULL || BufferSize < MES_MINIMAL_BUFFER_SIZE)) ||
  340. (Operation == MES_ENCODE && pEncodedSize == NULL) ||
  341. (Operation == MES_DECODE &&
  342. (*pBuffer == NULL || BufferSize < MES_MINIMAL_BUFFER_SIZE))
  343. )
  344. return( RPC_S_INVALID_ARG );
  345. if ( (Operation == MES_ENCODE_NDR64 && pEncodedSize == NULL) ||
  346. (Operation == MES_DECODE_NDR64 &&
  347. (*pBuffer == NULL || BufferSize < MES_MINIMAL_NDR64_BUFFER_SIZE ) ) )
  348. return( RPC_S_INVALID_ARG );
  349. I_NdrMesMessageInit( (PMIDL_ES_MESSAGE_EX) Handle );
  350. pMesMsg->Operation = Operation;
  351. pMesMsg->HandleFlags = 0;
  352. pMesMsg->HandleStyle = HandleStyle;
  353. pMesMsg->ByteCount = 0;
  354. if ( Operation == MES_ENCODE_NDR64 ||
  355. Operation == MES_DECODE_NDR64 )
  356. {
  357. pMesMsg->MesVersion = MIDL_NDR64_ES_VERSION;
  358. }
  359. else
  360. {
  361. pMesMsg->MesVersion = MIDL_ES_VERSION;
  362. }
  363. PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
  364. PRPC_MESSAGE pRpcMsg = pMesMsg->StubMsg.RpcMsg;
  365. if ( HandleStyle == MES_FIXED_BUFFER_HANDLE)
  366. {
  367. pMesMsg->Buffer = (uchar *)*pBuffer;
  368. pRpcMsg->BufferLength = BufferSize;
  369. pRpcMsg->Buffer = *pBuffer;
  370. pStubMsg->Buffer = (uchar *)*pBuffer;
  371. pStubMsg->BufferStart = (uchar *)*pBuffer;
  372. pStubMsg->BufferEnd = (uchar *)*pBuffer + BufferSize;
  373. }
  374. if ( HandleStyle == MES_DYNAMIC_BUFFER_HANDLE)
  375. {
  376. pMesMsg->pDynBuffer = (uchar **)pBuffer;
  377. if (Operation == MES_DECODE || Operation == MES_DECODE_NDR64 )
  378. {
  379. pMesMsg->Buffer = (uchar *)*pBuffer;
  380. pRpcMsg->BufferLength = BufferSize;
  381. pRpcMsg->Buffer = *pBuffer;
  382. pStubMsg->Buffer = (uchar *)*pBuffer;
  383. pStubMsg->BufferStart = (uchar *)*pBuffer;
  384. pStubMsg->BufferEnd = (uchar *)*pBuffer + BufferSize;
  385. }
  386. else
  387. {
  388. *pBuffer = NULL;
  389. pRpcMsg->BufferLength = 0;
  390. pRpcMsg->Buffer = 0;
  391. pStubMsg->Buffer = 0;
  392. pStubMsg->BufferStart = 0;
  393. pStubMsg->BufferEnd = 0;
  394. }
  395. }
  396. pMesMsg->BufferSize = BufferSize;
  397. pMesMsg->pEncodedSize = pEncodedSize;
  398. return( RPC_S_OK );
  399. }
  400. RPC_STATUS RPC_ENTRY
  401. MesInqProcEncodingId(
  402. handle_t Handle,
  403. PRPC_SYNTAX_IDENTIFIER pInterfaceId,
  404. unsigned long * pProcNumber )
  405. /*++
  406. The routine returns an informantion about the last proc encoding.
  407. Called before an encode, it should return RPC_X_INVALID_ES_ACTION.
  408. Called after an encode, it should return the last encoding info.
  409. Called before a decode, it should return the same encoding info.
  410. Called after a decode, it should return the just decoded encode info.
  411. --*/
  412. {
  413. RPC_STATUS Status;
  414. Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
  415. if ( Status != RPC_S_OK )
  416. return Status;
  417. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  418. Status = RPC_X_INVALID_ES_ACTION;
  419. if ( Handle == NULL || pInterfaceId == NULL || pProcNumber == NULL )
  420. return( RPC_S_INVALID_ARG );
  421. RpcTryExcept
  422. {
  423. // Note: because we allow to pickle several procs into the same buffer
  424. // (using the same handle without resetting), the PEEKED bit may be
  425. // cleared and the info may still be available.
  426. // On the other hand, the info bit is always set if we unmarshaled
  427. // a header. So check the info bit first.
  428. if ( pMesMsg->Operation == MES_DECODE &&
  429. ! GET_MES_INFO_AVAILABLE( pMesMsg ) &&
  430. ! GET_MES_HEADER_PEEKED( pMesMsg ) )
  431. {
  432. NdrpProcHeaderUnmarshallAll( pMesMsg );
  433. SET_MES_HEADER_PEEKED( pMesMsg );
  434. }
  435. if ( GET_MES_INFO_AVAILABLE( pMesMsg ) )
  436. {
  437. RpcpMemoryCopy( pInterfaceId,
  438. & pMesMsg->InterfaceId,
  439. sizeof( RPC_SYNTAX_IDENTIFIER ) );
  440. *pProcNumber = pMesMsg->ProcNumber;
  441. Status = RPC_S_OK;
  442. }
  443. // else Status = RPC_X_INVALID_ES_ACTION;
  444. }
  445. RpcExcept(1)
  446. {
  447. Status = RpcExceptionCode();
  448. }
  449. RpcEndExcept
  450. return( Status );
  451. }
  452. // =======================================================================
  453. //
  454. // Private Alloc, Read, Write helper routines
  455. //
  456. // =======================================================================
  457. void
  458. NdrpAllocPicklingBuffer(
  459. PMIDL_ES_MESSAGE pMesMsg,
  460. unsigned int RequiredLen
  461. )
  462. {
  463. unsigned int ActualLen;
  464. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  465. // Get the marshalling buffer.
  466. // alert: assuming the return buffer is aligned at 16 in 64bit platform.
  467. // ndr64 buffer needs to be aligned at 16.
  468. switch ( pMesMsg->HandleStyle )
  469. {
  470. case MES_INCREMENTAL_HANDLE:
  471. // Allocating the pickling buffer.
  472. ActualLen = RequiredLen;
  473. (pMesMsg->Alloc)( pMesMsg->UserState,
  474. (char * *) & pStubMsg->Buffer,
  475. & ActualLen );
  476. if ( ActualLen < RequiredLen )
  477. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  478. pStubMsg->RpcMsg->BufferLength = ActualLen;
  479. pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
  480. pStubMsg->BufferStart = pStubMsg->Buffer;
  481. pStubMsg->BufferEnd = pStubMsg->Buffer + ActualLen;
  482. break;
  483. case MES_FIXED_BUFFER_HANDLE:
  484. break;
  485. case MES_DYNAMIC_BUFFER_HANDLE:
  486. {
  487. // We have to return one buffer for multiple encodings,
  488. // and a cumulative size along with it.
  489. // So, we check if we have to copy data to a new buffer.
  490. uchar * pOldBufferToCopy = NULL;
  491. if ( pMesMsg->ByteCount )
  492. {
  493. RequiredLen += pMesMsg->ByteCount;
  494. pOldBufferToCopy = *pMesMsg->pDynBuffer;
  495. }
  496. pStubMsg->Buffer = (uchar *) pStubMsg->pfnAllocate( RequiredLen );
  497. if ( pStubMsg->Buffer == NULL )
  498. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  499. if ( pOldBufferToCopy )
  500. {
  501. RpcpMemoryCopy( pStubMsg->Buffer,
  502. pOldBufferToCopy,
  503. pMesMsg->ByteCount );
  504. pStubMsg->pfnFree( pOldBufferToCopy );
  505. }
  506. pStubMsg->RpcMsg->BufferLength = RequiredLen;
  507. pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
  508. pStubMsg->BufferStart = pStubMsg->Buffer;
  509. pStubMsg->BufferEnd = pStubMsg->Buffer + RequiredLen;
  510. * pMesMsg->pDynBuffer = pStubMsg->Buffer;
  511. pMesMsg->BufferSize = RequiredLen;
  512. // We write after the previously written buffer.
  513. pStubMsg->Buffer += pMesMsg->ByteCount;
  514. break;
  515. }
  516. }
  517. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  518. RpcRaiseException( RPC_X_INVALID_BUFFER );
  519. }
  520. void
  521. NdrpReadPicklingBuffer(
  522. PMIDL_ES_MESSAGE pMesMsg,
  523. unsigned int RequiredLen
  524. )
  525. {
  526. unsigned int ActualLen;
  527. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  528. // Read the marshalling buffer.
  529. if ( pMesMsg->HandleStyle == MES_INCREMENTAL_HANDLE )
  530. {
  531. // Allocating the pickling buffer.
  532. ActualLen = RequiredLen;
  533. (pMesMsg->Read)( pMesMsg->UserState,
  534. (char **) & pStubMsg->Buffer,
  535. & ActualLen );
  536. if ( ActualLen < RequiredLen )
  537. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  538. pStubMsg->RpcMsg->BufferLength = ActualLen;
  539. pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
  540. pStubMsg->BufferStart = pStubMsg->Buffer;
  541. pStubMsg->BufferEnd = pStubMsg->Buffer + ActualLen;
  542. }
  543. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  544. RpcRaiseException( RPC_X_INVALID_BUFFER );
  545. }
  546. void
  547. NdrpWritePicklingBuffer(
  548. PMIDL_ES_MESSAGE pMesMsg,
  549. uchar * pBuffer,
  550. size_t WriteLength
  551. )
  552. {
  553. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  554. NDR_ASSERT( ! ((LONG_PTR)pStubMsg->Buffer & 0x7), "Misaligned buffer" );
  555. NDR_ASSERT( ! (WriteLength & 0x7 ), "Length should be multiple of 8" );
  556. // Write the marshalling buffer.
  557. if ( pMesMsg->HandleStyle == MES_INCREMENTAL_HANDLE )
  558. {
  559. (pMesMsg->Write)( pMesMsg->UserState,
  560. (char * ) pBuffer,
  561. WriteLength );
  562. }
  563. else
  564. {
  565. // We return the cumulative length both for the fixed buffer
  566. // and for the dynamic buffer style.
  567. pMesMsg->ByteCount += WriteLength;
  568. * pMesMsg->pEncodedSize = pMesMsg->ByteCount;
  569. }
  570. }
  571. // =======================================================================
  572. //
  573. // One call generic routine pickling.
  574. //
  575. // =======================================================================
  576. void
  577. NdrpProcHeaderMarshall(
  578. PMIDL_ES_MESSAGE pMesMsg
  579. )
  580. {
  581. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  582. // Marshall DCE pickle header.
  583. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  584. RpcRaiseException( RPC_X_INVALID_BUFFER );
  585. * pStubMsg->Buffer++ = MIDL_ES_VERSION;
  586. * pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
  587. *( PSHORT_LV_CAST pStubMsg->Buffer)++ = (short)0xcccc; // filler
  588. // Marshall transfer syntax from the stub.
  589. RpcpMemoryCopy( pStubMsg->Buffer,
  590. & ((PRPC_CLIENT_INTERFACE)(pStubMsg->
  591. StubDesc->RpcInterfaceInformation))->TransferSyntax,
  592. sizeof(RPC_SYNTAX_IDENTIFIER) );
  593. // We need to remember InterfaceId for inquiries.
  594. RpcpMemoryCopy( & pMesMsg->InterfaceId,
  595. & ((PRPC_CLIENT_INTERFACE)(pStubMsg->
  596. StubDesc->RpcInterfaceInformation))->InterfaceId,
  597. sizeof(RPC_SYNTAX_IDENTIFIER) );
  598. // Marshall InterfaceId and ProcNumber from the handle.
  599. RpcpMemoryCopy( pStubMsg->Buffer + sizeof(RPC_SYNTAX_IDENTIFIER),
  600. & pMesMsg->InterfaceId,
  601. sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
  602. SET_MES_INFO_AVAILABLE( pMesMsg );
  603. pStubMsg->Buffer += 2 * sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
  604. * pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
  605. * pStubMsg->Buffer++ = NDR_ASCII_CHAR;
  606. * pStubMsg->Buffer++ = (char) (NDR_IEEE_FLOAT >> 8);
  607. * pStubMsg->Buffer++ = 0; // filler
  608. // This is non-DCE element as they have just 4 more bytes of filler here.
  609. // This field is used only when unmarshalling in our incremental style.
  610. *( PLONG_LV_CAST pStubMsg->Buffer)++ = pStubMsg->BufferLength -
  611. MES_PROC_HEADER_SIZE;
  612. }
  613. void
  614. NdrpProcHeaderUnmarshall(
  615. PMIDL_ES_MESSAGE pMesMsg
  616. )
  617. {
  618. unsigned char * BufferToRestore;
  619. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  620. if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
  621. return;
  622. NdrpReadPicklingBuffer( pMesMsg, MES_PROC_HEADER_SIZE );
  623. // Unmarshalling the header
  624. if ( *pStubMsg->Buffer != MIDL_ES_VERSION )
  625. RpcRaiseException( RPC_X_WRONG_ES_VERSION );
  626. BufferToRestore = pStubMsg->Buffer + 4;
  627. if ( pStubMsg->Buffer[1] != NDR_LOCAL_ENDIAN_LOW )
  628. {
  629. // The DCE header has the endianness on the low nibble, while
  630. // our DataRep has it on the high nibble.
  631. // We need only endianess to convert the proc header.
  632. byte Endianness = (pStubMsg->Buffer[1] << 4 );
  633. pStubMsg->RpcMsg->DataRepresentation = Endianness;
  634. pStubMsg->Buffer += 4;
  635. NdrSimpleStructConvert( pStubMsg,
  636. &__MIDLFormatString.Format[32],
  637. FALSE );
  638. }
  639. pStubMsg->Buffer = BufferToRestore;
  640. // Verify the transfer syntax
  641. if ( NULL != pStubMsg->StubDesc )
  642. {
  643. if (0 != RpcpMemoryCompare(
  644. pStubMsg->Buffer,
  645. & ((PRPC_CLIENT_INTERFACE)(pStubMsg->
  646. StubDesc->RpcInterfaceInformation))->
  647. TransferSyntax,
  648. sizeof(RPC_SYNTAX_IDENTIFIER) ) )
  649. {
  650. RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
  651. }
  652. }
  653. RpcpMemoryCopy( &((PMIDL_ES_MESSAGE_EX)pMesMsg)->TransferSyntax,
  654. pStubMsg->Buffer,
  655. sizeof( RPC_SYNTAX_IDENTIFIER ) );
  656. pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
  657. // We need to remember the last InterfaceId and ProcNumber for inquiries.
  658. RpcpMemoryCopy( & pMesMsg->InterfaceId,
  659. pStubMsg->Buffer,
  660. sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
  661. pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
  662. SET_MES_INFO_AVAILABLE( pMesMsg );
  663. unsigned long AlienDataRepresentation =
  664. ( (pStubMsg->Buffer[0] << 4) | // endianness
  665. pStubMsg->Buffer[1] | // chars
  666. ((unsigned long)(pStubMsg->Buffer[2]) << 8) ); // float
  667. pMesMsg->AlienDataRep = AlienDataRepresentation;
  668. pMesMsg->IncrDataSize = (size_t) *(unsigned long *)
  669. (pStubMsg->Buffer + 4);
  670. pStubMsg->Buffer += 8;
  671. }
  672. void
  673. NdrpDataBufferInit(
  674. PMIDL_ES_MESSAGE pMesMsg,
  675. PFORMAT_STRING pProcFormat
  676. )
  677. {
  678. size_t RequiredLen;
  679. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  680. if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
  681. {
  682. pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
  683. NdrConvert( pStubMsg, pProcFormat );
  684. }
  685. // When incremental, this is the non-DCE buffer size.
  686. // For non incremental RequiredLen will be ignored.
  687. RequiredLen = pMesMsg->IncrDataSize;
  688. NdrpReadPicklingBuffer( pMesMsg, RequiredLen );
  689. pStubMsg->pfnAllocate = pStubMsg->StubDesc->pfnAllocate;
  690. pStubMsg->pfnFree = pStubMsg->StubDesc->pfnFree;
  691. }
  692. void RPC_VAR_ENTRY
  693. NdrMesProcEncodeDecode(
  694. handle_t Handle,
  695. const MIDL_STUB_DESC * pStubDesc,
  696. PFORMAT_STRING pFormat,
  697. ...
  698. )
  699. /*++
  700. Routine description:
  701. Sizes and marshalls [in] arguments, unmarshalls [out] arguments.
  702. Includes a routine header.
  703. Arguments:
  704. Handle - a pickling handle
  705. pStubDesc - a pointer to the stub descriptor,
  706. pFormat - a pointer to the format code describing the object type.
  707. Note:
  708. Please note that all the ... arguments here are pointers.
  709. We will handle them appropriately to access the original arguments.
  710. The pickling header for the routine is included in the sizing.
  711. --*/
  712. {
  713. BOOL fMoreParams;
  714. PFORMAT_STRING pProcFormat;
  715. void * pArg;
  716. va_list ArgList;
  717. unsigned char * BufferSaved;
  718. size_t WriteLength;
  719. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  720. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  721. PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
  722. NDR_ASSERT( *pFormat == FC_BIND_PRIMITIVE || *pFormat == 0,
  723. "Pickling handle expected" );
  724. pStubMsg->StubDesc = pStubDesc;
  725. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  726. pStubMsg->pfnFree = pStubDesc->pfnFree;
  727. BOOL fEncodeUsed = (pFormat[1] & ENCODE_IS_USED) &&
  728. pMesMsg->Operation == MES_ENCODE;
  729. BOOL fDecodeUsed = (pFormat[1] & DECODE_IS_USED) &&
  730. pMesMsg->Operation == MES_DECODE;
  731. NDR_ASSERT( !( fEncodeUsed && fDecodeUsed ),
  732. "Both encode & decode at the same time" );
  733. if ( !fEncodeUsed && !fDecodeUsed )
  734. RpcRaiseException( RPC_X_INVALID_ES_ACTION );
  735. pStubMsg->FullPtrXlatTables = ( (pFormat[1] & Oi_FULL_PTR_USED)
  736. ? NdrFullPointerXlatInit( 0, XLAT_CLIENT )
  737. : 0 );
  738. pFormat += HAS_RPCFLAGS(pFormat[1]) ? 6
  739. : 2;
  740. // We use the proc number only to support MesInqEncodingId. So, set it for
  741. // encoding only. When decoding it will get picked up from the header.
  742. //
  743. if ( fEncodeUsed )
  744. pMesMsg->ProcNumber = * (unsigned short *) pFormat;
  745. pFormat +=4;
  746. if ( *pFormat == FC_BIND_PRIMITIVE )
  747. pFormat += 4;
  748. if ( fEncodeUsed )
  749. {
  750. //
  751. // The sizing walk.
  752. //
  753. pStubMsg->BufferLength = MES_PROC_HEADER_SIZE;
  754. // We will be walking this routine's stack.
  755. // However, for the engine to be able to calculate conformant arrays
  756. // and such, top of the original routine's stack has to be available
  757. // via the stub message.
  758. INIT_ARG( ArgList, pFormat );
  759. GET_FIRST_ARG( pArg, ArgList );
  760. pStubMsg->StackTop = *(uchar * *)pArg;
  761. pProcFormat = pFormat;
  762. fMoreParams = TRUE;
  763. for ( ; fMoreParams ; pProcFormat += 2 )
  764. {
  765. switch ( *pProcFormat )
  766. {
  767. case FC_OUT_PARAM:
  768. break;
  769. case FC_RETURN_PARAM:
  770. fMoreParams = FALSE;
  771. break;
  772. default:
  773. fMoreParams = FALSE;
  774. break;
  775. case FC_IN_PARAM_BASETYPE :
  776. LENGTH_ALIGN( pStubMsg->BufferLength,
  777. SIMPLE_TYPE_ALIGNMENT( pProcFormat[1] ));
  778. pStubMsg->BufferLength +=
  779. SIMPLE_TYPE_BUFSIZE( pProcFormat[1] );
  780. break;
  781. case FC_IN_PARAM:
  782. case FC_IN_PARAM_NO_FREE_INST:
  783. // Other [in] types than simple or ignore
  784. // fall through to [in,out].
  785. case FC_IN_OUT_PARAM:
  786. {
  787. uchar * pOrigArg = *(uchar * *)pArg;
  788. PFORMAT_STRING pTypeFormat;
  789. unsigned char FcType;
  790. pProcFormat += 2;
  791. pTypeFormat = pStubDesc->pFormatTypes +
  792. *(signed short *) pProcFormat;
  793. FcType = *pTypeFormat;
  794. if ( ! IS_BY_VALUE( FcType ) )
  795. pOrigArg = *(uchar * *)pOrigArg;
  796. (*pfnSizeRoutines[ ROUTINE_INDEX( FcType ) ])( pStubMsg,
  797. pOrigArg,
  798. pTypeFormat );
  799. }
  800. break;
  801. }
  802. GET_NEXT_ARG( pArg, ArgList );
  803. } // for
  804. LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
  805. size_t LengthSaved;
  806. NdrpAllocPicklingBuffer( pMesMsg, pStubMsg->BufferLength );
  807. BufferSaved = pStubMsg->Buffer;
  808. LengthSaved = pStubMsg->BufferLength;
  809. //
  810. // Marshalling.
  811. //
  812. NdrpProcHeaderMarshall( pMesMsg );
  813. INIT_ARG( ArgList, pFormat );
  814. GET_FIRST_ARG( pArg, ArgList );
  815. pProcFormat = pFormat;
  816. fMoreParams = TRUE;
  817. for ( ; fMoreParams ; pProcFormat += 2 )
  818. {
  819. switch ( *pProcFormat )
  820. {
  821. case FC_OUT_PARAM:
  822. break;
  823. case FC_RETURN_PARAM:
  824. default:
  825. fMoreParams = FALSE;
  826. break;
  827. case FC_IN_PARAM_BASETYPE :
  828. NdrSimpleTypeMarshall( pStubMsg,
  829. *(uchar * *)pArg,
  830. pProcFormat[1] );
  831. break;
  832. case FC_IN_PARAM:
  833. case FC_IN_PARAM_NO_FREE_INST:
  834. case FC_IN_OUT_PARAM:
  835. {
  836. uchar * pOrigArg = *(uchar * *)pArg;
  837. PFORMAT_STRING pTypeFormat;
  838. unsigned char FcType;
  839. pProcFormat += 2;
  840. pTypeFormat = pStubDesc->pFormatTypes +
  841. *(signed short *) pProcFormat;
  842. FcType = *pTypeFormat;
  843. if ( ! IS_BY_VALUE( FcType ) )
  844. pOrigArg = *(uchar * *)pOrigArg;
  845. (*pfnMarshallRoutines[ ROUTINE_INDEX( FcType )])( pStubMsg,
  846. pOrigArg,
  847. pTypeFormat );
  848. }
  849. break;
  850. }
  851. GET_NEXT_ARG( pArg, ArgList );
  852. }
  853. // Next encoding (if any) starts at aligned to 8.
  854. ALIGN( pStubMsg->Buffer, 7 );
  855. // Now manage the actual size of encoded data.
  856. WriteLength = (size_t)(pStubMsg->Buffer - BufferSaved);
  857. * (unsigned long *)
  858. ( BufferSaved + MES_PROC_HEADER_SIZE - 4) =
  859. WriteLength - MES_PROC_HEADER_SIZE;
  860. if ( LengthSaved < WriteLength )
  861. {
  862. NDR_ASSERT( 0, "NdrMesProcEncodeDecode: encode buffer overflow" );
  863. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  864. }
  865. NdrpWritePicklingBuffer( pMesMsg, BufferSaved, WriteLength );
  866. }
  867. if ( fDecodeUsed )
  868. {
  869. //
  870. // Unmarshalling.
  871. //
  872. if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
  873. {
  874. // This makes it possible to encode/decode several procs one after
  875. // another with the same pickling handle (using the same buffer).
  876. CLEAR_MES_HEADER_PEEKED( pMesMsg );
  877. }
  878. else
  879. NdrpProcHeaderUnmarshall( pMesMsg );
  880. NdrpDataBufferInit( pMesMsg, pFormat );
  881. INIT_ARG( ArgList, pFormat );
  882. GET_FIRST_ARG( pArg, ArgList );
  883. pStubMsg->StackTop = *(uchar * *)pArg;
  884. pProcFormat = pFormat;
  885. fMoreParams = TRUE;
  886. for ( ; fMoreParams ; pProcFormat += 2 )
  887. {
  888. switch ( *pProcFormat )
  889. {
  890. case FC_IN_PARAM_BASETYPE :
  891. case FC_IN_PARAM:
  892. case FC_IN_PARAM_NO_FREE_INST:
  893. break;
  894. default:
  895. fMoreParams = FALSE;
  896. break;
  897. case FC_RETURN_PARAM_BASETYPE :
  898. NdrSimpleTypeUnmarshall( pStubMsg,
  899. *(uchar * *)pArg,
  900. pProcFormat[1] );
  901. fMoreParams = FALSE;
  902. break;
  903. case FC_RETURN_PARAM:
  904. fMoreParams = FALSE;
  905. // fall through to out params.
  906. case FC_IN_OUT_PARAM:
  907. case FC_OUT_PARAM:
  908. {
  909. uchar * pOrigArg = *(uchar * *)pArg;
  910. PFORMAT_STRING pTypeFormat;
  911. unsigned char FcType;
  912. pProcFormat += 2;
  913. pTypeFormat = pStubDesc->pFormatTypes +
  914. *(signed short *) pProcFormat;
  915. FcType = *pTypeFormat;
  916. if ( IS_STRUCT( FcType ) || IS_UNION( FcType) ||
  917. IS_XMIT_AS( FcType ) )
  918. {
  919. // All these are possible only as a return value.
  920. pOrigArg = (uchar *) &pOrigArg;
  921. }
  922. else
  923. pOrigArg = (uchar *)pOrigArg;
  924. (*pfnUnmarshallRoutines[ ROUTINE_INDEX( FcType )])(
  925. pStubMsg,
  926. (uchar * *)pOrigArg,
  927. pTypeFormat,
  928. FALSE );
  929. }
  930. break;
  931. }
  932. GET_NEXT_ARG( pArg, ArgList );
  933. } // for
  934. // Next decoding (if any) starts at aligned to 8.
  935. ALIGN( pStubMsg->Buffer, 7 );
  936. } // if decode
  937. NdrFullPointerXlatFree( pStubMsg->FullPtrXlatTables );
  938. }
  939. CLIENT_CALL_RETURN RPC_VAR_ENTRY
  940. NdrMesProcEncodeDecode2(
  941. handle_t Handle,
  942. const MIDL_STUB_DESC * pStubDescriptor,
  943. PFORMAT_STRING pFormat,
  944. ...
  945. )
  946. {
  947. va_list ArgList;
  948. uchar * StartofStack;
  949. PFORMAT_STRING pFormatParam;
  950. CLIENT_CALL_RETURN ReturnValue;
  951. ulong ProcNum;
  952. uchar * pArg;
  953. void * pThis;
  954. PFORMAT_STRING pProcFormat = pFormat;
  955. unsigned char * BufferSaved;
  956. size_t WriteLength;
  957. NDR_PROC_CONTEXT ProcContext;
  958. PNDR_PROC_HEADER_EXTS pHeaderExts = 0;
  959. ReturnValue.Pointer = 0;
  960. //
  961. // Get address of argument to this function following pFormat. This
  962. // is the address of the address of the first argument of the function
  963. // calling this function.
  964. //
  965. INIT_ARG( ArgList, pFormat);
  966. //
  967. // Get the address of the stack where the parameters are.
  968. //
  969. GET_FIRST_IN_ARG(ArgList);
  970. StartofStack = (uchar *) GET_STACK_START(ArgList);
  971. // StartofStack points to the virtual stack at this point.
  972. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  973. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  974. PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
  975. NDR_ASSERT( *pFormat == FC_BIND_PRIMITIVE || *pFormat == 0,
  976. "Pickling handle expected" );
  977. pStubMsg->StubDesc = pStubDescriptor;
  978. pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
  979. pStubMsg->pfnFree = pStubDescriptor->pfnFree;
  980. ProcNum = MulNdrpInitializeContextFromProc( XFER_SYNTAX_DCE, pFormat, &ProcContext, StartofStack );
  981. BOOL fEncodeUsed = ( * ( ( uchar *)&ProcContext.NdrInfo.InterpreterFlags ) & ENCODE_IS_USED ) &&
  982. pMesMsg->Operation == MES_ENCODE;
  983. BOOL fDecodeUsed = ( * ( ( uchar *)&ProcContext.NdrInfo.InterpreterFlags ) & DECODE_IS_USED ) &&
  984. pMesMsg->Operation == MES_DECODE;
  985. NDR_ASSERT( !( fEncodeUsed && fDecodeUsed ),
  986. "Both encode & decode at the same time" );
  987. if ( !fEncodeUsed && !fDecodeUsed )
  988. RpcRaiseException( RPC_X_INVALID_ES_ACTION );
  989. if ( fEncodeUsed )
  990. pMesMsg->ProcNumber = ProcNum;
  991. // Must do this before the sizing pass!
  992. pStubMsg->StackTop = StartofStack;
  993. pStubMsg->pContext = &ProcContext;
  994. RpcTryFinally
  995. {
  996. // We don't really need to zeroout here, but code is much more cleaner this way,
  997. // and ObjectProc is the first check anyhow.
  998. NdrpClientInit( pStubMsg, &ReturnValue );
  999. if (fEncodeUsed)
  1000. {
  1001. //
  1002. // ----------------------------------------------------------------
  1003. // Sizing Pass.
  1004. // ----------------------------------------------------------------
  1005. //
  1006. pStubMsg->BufferLength += MES_PROC_HEADER_SIZE;
  1007. //
  1008. // Skip buffer size pass if possible.
  1009. //
  1010. if ( ProcContext.NdrInfo.pProcDesc->Oi2Flags.ClientMustSize )
  1011. {
  1012. NdrpSizing( pStubMsg,
  1013. TRUE ); // IsClient
  1014. }
  1015. LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
  1016. size_t LengthSaved;
  1017. NdrpAllocPicklingBuffer( pMesMsg, pStubMsg->BufferLength );
  1018. BufferSaved = pStubMsg->Buffer;
  1019. LengthSaved = pStubMsg->BufferLength;
  1020. NdrpProcHeaderMarshall( pMesMsg );
  1021. //
  1022. // ----------------------------------------------------------
  1023. // Marshall Pass.
  1024. // ----------------------------------------------------------
  1025. //
  1026. NdrpClientMarshal( pStubMsg,
  1027. FALSE ); // IsObject
  1028. // Next encoding (if any) starts at aligned to 8.
  1029. ALIGN( pStubMsg->Buffer, 7 );
  1030. // Now manage the actual size of encoded data.
  1031. WriteLength = (size_t)(pStubMsg->Buffer - BufferSaved);
  1032. * (unsigned long *) ( BufferSaved + MES_PROC_HEADER_SIZE - 4) =
  1033. WriteLength - MES_PROC_HEADER_SIZE;
  1034. if ( LengthSaved < WriteLength )
  1035. {
  1036. NDR_ASSERT( 0, "NdrMesProcEncodeDecode: encode buffer overflow" );
  1037. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1038. }
  1039. NdrpWritePicklingBuffer( pMesMsg, BufferSaved, WriteLength );
  1040. }
  1041. if (fDecodeUsed)
  1042. {
  1043. //
  1044. // ----------------------------------------------------------
  1045. // Unmarshall Pass.
  1046. // ----------------------------------------------------------
  1047. //
  1048. if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
  1049. {
  1050. // This makes it possible to encode/decode several procs one after
  1051. // another with the same pickling handle (using the same buffer).
  1052. CLEAR_MES_HEADER_PEEKED( pMesMsg );
  1053. }
  1054. else
  1055. NdrpProcHeaderUnmarshall( pMesMsg );
  1056. NdrpDataBufferInit( pMesMsg, pFormat );
  1057. NdrpClientUnMarshal( pStubMsg,
  1058. &ReturnValue );
  1059. // Next decoding (if any) starts at aligned to 8.
  1060. ALIGN( pStubMsg->Buffer, 7 );
  1061. } // if decode
  1062. }
  1063. RpcFinally
  1064. {
  1065. NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
  1066. NdrCorrelationFree( pStubMsg );
  1067. }
  1068. RpcEndFinally
  1069. return ReturnValue;
  1070. }
  1071. // =======================================================================
  1072. //
  1073. // Generic type pickling routines (for non-simple types).
  1074. //
  1075. // =======================================================================
  1076. void
  1077. NdrpCommonTypeHeaderSize(
  1078. PMIDL_ES_MESSAGE pMesMsg
  1079. )
  1080. {
  1081. // This check is to prevent a decoding handle from being used
  1082. // for both encoding and sizing of types.
  1083. if ( pMesMsg->Operation != MES_ENCODE )
  1084. RpcRaiseException( RPC_X_INVALID_ES_ACTION );
  1085. if ( ! GET_COMMON_TYPE_HEADER_SIZED( pMesMsg ) )
  1086. {
  1087. pMesMsg->StubMsg.BufferLength += MES_CTYPE_HEADER_SIZE;
  1088. SET_COMMON_TYPE_HEADER_SIZED( pMesMsg );
  1089. }
  1090. }
  1091. size_t RPC_ENTRY
  1092. NdrMesTypeAlignSize2(
  1093. handle_t Handle,
  1094. const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
  1095. const MIDL_STUB_DESC * pStubDesc,
  1096. PFORMAT_STRING pFormat,
  1097. const void * pObject
  1098. )
  1099. {
  1100. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1101. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1102. PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
  1103. pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
  1104. NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
  1105. pStubMsg->fHasExtensions = 1;
  1106. if ( pPicklingInfo->Flags.HasNewCorrDesc )
  1107. {
  1108. void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
  1109. NdrCorrelationInitialize( pStubMsg,
  1110. (unsigned long *) pCorrInfo,
  1111. NDR_DEFAULT_CORR_CACHE_SIZE,
  1112. 0 /* flags */ );
  1113. }
  1114. return NdrMesTypeAlignSize(Handle, pStubDesc, pFormat, pObject);
  1115. }
  1116. size_t RPC_ENTRY
  1117. NdrMesTypeAlignSize(
  1118. handle_t Handle,
  1119. const MIDL_STUB_DESC * pStubDesc,
  1120. PFORMAT_STRING pFormat,
  1121. const void * pObject
  1122. )
  1123. /*++
  1124. Routine description:
  1125. Calculates the buffer size of the object relative to the current state
  1126. of the pickling handle.
  1127. Arguments:
  1128. Handle - a pickling handle,
  1129. pStubDesc - a pointer to the stub descriptor,
  1130. pFormat - a pointer to the format code describing the object type
  1131. pObject - a pointer to the object being sized.
  1132. Returns:
  1133. The size.
  1134. Note:
  1135. The pickling header is included in the sizing.
  1136. --*/
  1137. {
  1138. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1139. PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
  1140. size_t OldLength = pStubMsg->BufferLength;
  1141. if ( ! pObject )
  1142. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  1143. if( (long)pStubMsg->BufferLength & 0x7 )
  1144. RpcRaiseException( RPC_X_INVALID_BUFFER );
  1145. pStubMsg->StubDesc = pStubDesc;
  1146. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1147. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1148. // See if we need to size the common type header.
  1149. NdrpCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
  1150. // Now the individual type object.
  1151. pStubMsg->BufferLength += MES_HEADER_SIZE;
  1152. if ( IS_POINTER_TYPE(*pFormat) )
  1153. {
  1154. // We have to dereference the pointer once.
  1155. pObject = *(void * *)pObject;
  1156. }
  1157. (*pfnSizeRoutines[ ROUTINE_INDEX(*pFormat) ])
  1158. ( pStubMsg,
  1159. (uchar *)pObject,
  1160. pFormat );
  1161. LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
  1162. return( pStubMsg->BufferLength - OldLength );
  1163. }
  1164. size_t
  1165. NdrpCommonTypeHeaderMarshall(
  1166. PMIDL_ES_MESSAGE pMesMsg
  1167. )
  1168. /*++
  1169. Returns the space used by the common header.
  1170. --*/
  1171. {
  1172. if ( ! GET_COMMON_TYPE_HEADER_IN( pMesMsg ) )
  1173. {
  1174. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1175. MIDL_memset( pStubMsg->Buffer, 0xcc, MES_CTYPE_HEADER_SIZE );
  1176. *pStubMsg->Buffer++ = MIDL_ES_VERSION;
  1177. *pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN;
  1178. * PSHORT_CAST pStubMsg->Buffer = MES_CTYPE_HEADER_SIZE;
  1179. pStubMsg->Buffer += MES_CTYPE_HEADER_SIZE - 2;
  1180. SET_COMMON_TYPE_HEADER_IN( pMesMsg );
  1181. return( MES_CTYPE_HEADER_SIZE );
  1182. }
  1183. return( 0 );
  1184. }
  1185. void RPC_ENTRY
  1186. NdrMesTypeEncode2(
  1187. handle_t Handle,
  1188. const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
  1189. const MIDL_STUB_DESC * pStubDesc,
  1190. PFORMAT_STRING pFormat,
  1191. const void * pObject
  1192. )
  1193. {
  1194. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1195. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1196. PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
  1197. pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
  1198. NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
  1199. pStubMsg->fHasExtensions = 1;
  1200. if ( pPicklingInfo->Flags.HasNewCorrDesc )
  1201. {
  1202. void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
  1203. NdrCorrelationInitialize( pStubMsg,
  1204. (unsigned long *) pCorrInfo,
  1205. NDR_DEFAULT_CORR_CACHE_SIZE,
  1206. 0 /* flags */ );
  1207. }
  1208. RpcTryFinally
  1209. {
  1210. NdrMesTypeEncode(Handle, pStubDesc, pFormat, pObject);
  1211. if ( pStubMsg->pCorrInfo )
  1212. NdrCorrelationPass( pStubMsg );
  1213. }
  1214. RpcFinally
  1215. {
  1216. // while currently we are not using corrinfo in marshalling pass, we need this
  1217. // in case we are using corrinfo later (like info for free)
  1218. NdrCorrelationFree( pStubMsg );
  1219. }
  1220. RpcEndFinally
  1221. }
  1222. void RPC_ENTRY
  1223. NdrMesTypeEncode(
  1224. handle_t Handle,
  1225. const MIDL_STUB_DESC * pStubDesc,
  1226. PFORMAT_STRING pFormat,
  1227. const void * pObject
  1228. )
  1229. /*++
  1230. Routine description:
  1231. Encodes the object to the buffer depending on the state of the handle.
  1232. This means: sizing, allocating buffer, marshalling, writing buffer.
  1233. Arguments:
  1234. Handle - a pickling handle
  1235. pStubDesc - a pointer to the stub descriptor,
  1236. pFormat - a pointer to the format code describing the object type,
  1237. pObject - a pointer to the object being sized.
  1238. Returns:
  1239. The size.
  1240. Note:
  1241. The pickling header is included in the sizing.
  1242. --*/
  1243. {
  1244. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1245. uchar * pBufferSaved;
  1246. size_t RequiredLen, CommonHeaderSize, LengthSaved;
  1247. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1248. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1249. if ( ! pObject )
  1250. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  1251. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  1252. RpcRaiseException( RPC_X_INVALID_BUFFER );
  1253. pStubMsg->StubDesc = pStubDesc;
  1254. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1255. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1256. // Size and allocate the buffer.
  1257. // The req len includes: (the common header), the header and the data
  1258. // Take the pointer alignment to come up with the right size.
  1259. pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
  1260. RequiredLen = NdrMesTypeAlignSize( Handle,
  1261. pStubDesc,
  1262. pFormat,
  1263. pObject );
  1264. NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
  1265. pBufferSaved = pStubMsg->Buffer;
  1266. LengthSaved = RequiredLen;
  1267. // See if we need to marshall the common type header
  1268. CommonHeaderSize = NdrpCommonTypeHeaderMarshall( pMesMsg );
  1269. // Marshall the header and the object.
  1270. // zero out the type header (will contain type buffer length after
  1271. // encoding is done )
  1272. memset( pStubMsg->Buffer, 0, MES_HEADER_SIZE );
  1273. pStubMsg->Buffer += MES_HEADER_SIZE;
  1274. if ( IS_POINTER_TYPE(*pFormat) )
  1275. {
  1276. // We have to dereference the pointer once.
  1277. pObject = *(void * *)pObject;
  1278. }
  1279. (*pfnMarshallRoutines[ ROUTINE_INDEX(*pFormat) ])
  1280. ( pStubMsg,
  1281. (uchar *)pObject,
  1282. pFormat );
  1283. // We adjust the buffer to the next align by 8 and
  1284. // so, we tell the user that we've written out till next mod 8.
  1285. ALIGN( pStubMsg->Buffer, 7 );
  1286. size_t WriteLength = (size_t)(pStubMsg->Buffer - pBufferSaved);
  1287. // We always save the rounded up object length in the type header.
  1288. *(unsigned long *)(pBufferSaved + CommonHeaderSize) =
  1289. WriteLength - CommonHeaderSize - MES_HEADER_SIZE;
  1290. if ( LengthSaved < WriteLength )
  1291. {
  1292. NDR_ASSERT( 0, "NdrMesTypeEncode: encode buffer overflow" );
  1293. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1294. }
  1295. NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, WriteLength );
  1296. }
  1297. void
  1298. NdrpCommonTypeHeaderUnmarshall(
  1299. PMIDL_ES_MESSAGE pMesMsg
  1300. )
  1301. {
  1302. if ( pMesMsg->Operation != MES_DECODE )
  1303. RpcRaiseException( RPC_X_INVALID_ES_ACTION );
  1304. if ( ! GET_COMMON_TYPE_HEADER_IN( pMesMsg ) )
  1305. {
  1306. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1307. NdrpReadPicklingBuffer( pMesMsg, MES_CTYPE_HEADER_SIZE );
  1308. // Check the version number, endianness.
  1309. if ( *pStubMsg->Buffer != MIDL_ES_VERSION )
  1310. RpcRaiseException( RPC_X_WRONG_ES_VERSION );
  1311. if ( pStubMsg->Buffer[1] == NDR_LOCAL_ENDIAN )
  1312. {
  1313. // Read the note about endianess at NdrMesTypeDecode.
  1314. //
  1315. pMesMsg->AlienDataRep = NDR_LOCAL_DATA_REPRESENTATION;
  1316. }
  1317. else
  1318. {
  1319. unsigned char temp = pStubMsg->Buffer[2];
  1320. pStubMsg->Buffer[2] = pStubMsg->Buffer[3];
  1321. pStubMsg->Buffer[3] = temp;
  1322. pMesMsg->AlienDataRep = ( NDR_ASCII_CHAR | // chars
  1323. pStubMsg->Buffer[1] | // endianness
  1324. NDR_IEEE_FLOAT ); // float
  1325. }
  1326. pStubMsg->Buffer += MES_CTYPE_HEADER_SIZE;
  1327. SET_COMMON_TYPE_HEADER_IN( pMesMsg );
  1328. }
  1329. }
  1330. void RPC_ENTRY
  1331. NdrMesTypeDecode2(
  1332. handle_t Handle,
  1333. const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
  1334. const MIDL_STUB_DESC * pStubDesc,
  1335. PFORMAT_STRING pFormat,
  1336. void * pObject
  1337. )
  1338. {
  1339. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1340. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1341. PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
  1342. pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
  1343. NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
  1344. pStubMsg->fHasExtensions = 1;
  1345. RpcTryFinally
  1346. {
  1347. if ( pPicklingInfo->Flags.HasNewCorrDesc )
  1348. {
  1349. void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
  1350. NdrCorrelationInitialize( pStubMsg,
  1351. (unsigned long *) pCorrInfo,
  1352. NDR_DEFAULT_CORR_CACHE_SIZE,
  1353. 0 /* flags */ );
  1354. }
  1355. NdrMesTypeDecode(Handle, pStubDesc, pFormat, pObject);
  1356. if ( pStubMsg->pCorrInfo )
  1357. NdrCorrelationPass( pStubMsg );
  1358. }
  1359. RpcFinally
  1360. {
  1361. NdrCorrelationFree( pStubMsg );
  1362. }
  1363. RpcEndFinally
  1364. }
  1365. void RPC_ENTRY
  1366. NdrMesTypeDecode(
  1367. handle_t Handle,
  1368. const MIDL_STUB_DESC * pStubDesc,
  1369. PFORMAT_STRING pFormat,
  1370. void * pObject
  1371. )
  1372. /*++
  1373. Routine description:
  1374. Decodes the object to the buffer depending on the state of the handle.
  1375. This means: reads the header, reads the buffer, unmarshalls.
  1376. Arguments:
  1377. Handle - a pickling handle
  1378. pStubDesc - a pointer to the stub descriptor,
  1379. pFormat - a pointer to the format code describing the object type,
  1380. pObject - a pointer to the object being sized.
  1381. Returns:
  1382. The size.
  1383. Note:
  1384. Endianness and other conversions when decoding *types*.
  1385. Starting with Mac implementation, types have a conversion that
  1386. takes care of different endianness. ASCII and VAX_FLOAT are still
  1387. assummed for types.
  1388. Common header conveys the endianness information. The handle gets the
  1389. endian info from the common header and so when decoding types, the
  1390. handle is used to check if the conversion is needed.
  1391. We cannot convert the whole buffer at the time of processing the common
  1392. header as the buffer may not be there yet (for incremental handle).
  1393. --*/
  1394. {
  1395. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1396. size_t RequiredLen;
  1397. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1398. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1399. uchar * BufferSaved;
  1400. if ( ! pObject )
  1401. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  1402. pStubMsg->StubDesc = pStubDesc;
  1403. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1404. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1405. // See if we need to unmarshall the common type header.
  1406. NdrpCommonTypeHeaderUnmarshall( pMesMsg );
  1407. // Now the individual data object.
  1408. NdrpReadPicklingBuffer( pMesMsg, MES_HEADER_SIZE );
  1409. // Reading the object. Get the length of the buffer first.
  1410. if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
  1411. {
  1412. pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
  1413. BufferSaved = pStubMsg->Buffer;
  1414. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  1415. pStubMsg->Buffer = BufferSaved;
  1416. }
  1417. RequiredLen = (size_t) *(unsigned long *)pStubMsg->Buffer;
  1418. pStubMsg->Buffer += MES_HEADER_SIZE;
  1419. NdrpReadPicklingBuffer( pMesMsg, RequiredLen );
  1420. // Now the conversion of the object, if needed.
  1421. if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
  1422. {
  1423. BufferSaved = pStubMsg->Buffer;
  1424. (*pfnConvertRoutines[ ROUTINE_INDEX( *pFormat) ])
  1425. ( pStubMsg,
  1426. pFormat,
  1427. FALSE );
  1428. pStubMsg->Buffer = BufferSaved;
  1429. }
  1430. // Unmarshalling.
  1431. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1432. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1433. void * pArg = pObject;
  1434. if ( IS_POINTER_TYPE(*pFormat) )
  1435. {
  1436. // We have to dereference the pointer once.
  1437. //
  1438. pArg = *(void **)pArg;
  1439. }
  1440. (*pfnUnmarshallRoutines[ ROUTINE_INDEX( *pFormat )])
  1441. ( pStubMsg,
  1442. (uchar * *)&pArg,
  1443. pFormat,
  1444. FALSE );
  1445. if ( IS_POINTER_TYPE(*pFormat) )
  1446. {
  1447. // Don't drop the pointee, if it was allocated.
  1448. *(void **)pObject = pArg;
  1449. }
  1450. // Next decoding needs to start at aligned to 8.
  1451. ALIGN( pStubMsg->Buffer, 7 );
  1452. }
  1453. void RPC_ENTRY
  1454. NdrMesTypeFree(
  1455. handle_t Handle,
  1456. const MIDL_STUB_DESC * pStubDesc,
  1457. PFORMAT_STRING pFormat,
  1458. void * pObject
  1459. )
  1460. /*++
  1461. Routine description:
  1462. Free the object.
  1463. Arguments:
  1464. Handle - a pickling handle,
  1465. pStubDesc - a pointer to the stub descriptor,
  1466. pFormat - a pointer to the format code describing the object type
  1467. pObject - a pointer to the object being freed.
  1468. Returns:
  1469. Note:
  1470. The pickling header is included in the sizing.
  1471. --*/
  1472. {
  1473. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1474. PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
  1475. if ( ! pObject )
  1476. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  1477. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  1478. RpcRaiseException( RPC_X_INVALID_BUFFER );
  1479. pStubMsg->StubDesc = pStubDesc;
  1480. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1481. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1482. // Now the individual type object.
  1483. if ( IS_POINTER_TYPE(*pFormat) )
  1484. {
  1485. // We have to dereference the pointer once.
  1486. pObject = *(void * *)pObject;
  1487. }
  1488. (*pfnFreeRoutines[ ROUTINE_INDEX(*pFormat) ])
  1489. ( pStubMsg,
  1490. (uchar *)pObject,
  1491. pFormat );
  1492. }
  1493. void RPC_ENTRY
  1494. NdrMesTypeFree2(
  1495. handle_t Handle,
  1496. const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
  1497. const MIDL_STUB_DESC * pStubDesc,
  1498. PFORMAT_STRING pFormat,
  1499. void * pObject
  1500. )
  1501. {
  1502. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1503. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1504. PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
  1505. pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
  1506. NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
  1507. pStubMsg->fHasExtensions = 1;
  1508. if ( pPicklingInfo->Flags.HasNewCorrDesc )
  1509. {
  1510. void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
  1511. NdrCorrelationInitialize( pStubMsg,
  1512. (unsigned long *) pCorrInfo,
  1513. NDR_DEFAULT_CORR_CACHE_SIZE,
  1514. 0 /* flags */ );
  1515. }
  1516. NdrMesTypeFree(Handle, pStubDesc, pFormat, pObject);
  1517. }
  1518. // =======================================================================
  1519. //
  1520. // Ready to use AlignSize routines for simple types
  1521. //
  1522. // =======================================================================
  1523. size_t RPC_ENTRY
  1524. NdrMesSimpleTypeAlignSize(
  1525. handle_t Handle )
  1526. /*++
  1527. Size is always 8 bytes for data and there is no header here per data.
  1528. However, the common header gets included for the first object.
  1529. --*/
  1530. {
  1531. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1532. PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE) Handle)->StubMsg;
  1533. if( (long)( pStubMsg->BufferLength & 0x7 ) )
  1534. RpcRaiseException( RPC_X_INVALID_BUFFER );
  1535. unsigned long OldLength = pStubMsg->BufferLength;
  1536. NdrpCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
  1537. pStubMsg->BufferLength += 8;
  1538. return( (size_t)(pStubMsg->BufferLength - OldLength) );
  1539. }
  1540. // =======================================================================
  1541. //
  1542. // Ready to use Encode routines for simple types
  1543. //
  1544. // =======================================================================
  1545. void RPC_ENTRY
  1546. NdrMesSimpleTypeEncode(
  1547. handle_t Handle,
  1548. const MIDL_STUB_DESC * pStubDesc,
  1549. const void * pData,
  1550. short Size )
  1551. /*++
  1552. Marshall a simple type entity. There is no header here per data.
  1553. However, the common header gets included for the first object.
  1554. --*/
  1555. {
  1556. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1557. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1558. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1559. pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
  1560. pStubMsg->pfnFree = pStubDesc->pfnFree;
  1561. size_t RequiredLen;
  1562. // Size and allocate the buffer.
  1563. // The req len includes: (the common header) and the data
  1564. // Take the pointer alignment to come up with the right size.
  1565. pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
  1566. RequiredLen = NdrMesSimpleTypeAlignSize( Handle );
  1567. NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
  1568. // See if we need to marshall the common type header
  1569. uchar * pBufferSaved = pStubMsg->Buffer;
  1570. NdrpCommonTypeHeaderMarshall( pMesMsg );
  1571. switch ( Size )
  1572. {
  1573. case 1:
  1574. * PCHAR_CAST pStubMsg->Buffer = * PCHAR_CAST pData;
  1575. break;
  1576. case 2:
  1577. * PSHORT_CAST pStubMsg->Buffer = * PSHORT_CAST pData;
  1578. break;
  1579. case 4:
  1580. * PLONG_CAST pStubMsg->Buffer = * PLONG_CAST pData;
  1581. break;
  1582. case 8:
  1583. * PHYPER_CAST pStubMsg->Buffer = * PHYPER_CAST pData;
  1584. break;
  1585. default:
  1586. NDR_ASSERT( 0, " Size generation problem" );
  1587. }
  1588. pStubMsg->Buffer += 8;
  1589. NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, RequiredLen );
  1590. }
  1591. // =======================================================================
  1592. //
  1593. // Ready to use Decode routines for simple types
  1594. //
  1595. // =======================================================================
  1596. void RPC_ENTRY
  1597. NdrMesSimpleTypeDecode(
  1598. handle_t Handle,
  1599. void * pData,
  1600. short FormatChar )
  1601. /*++
  1602. Does not include the header for the data.
  1603. However, the common header gets included for the first object.
  1604. Note. Endianness and other conversions for decode.
  1605. This has been deemed as not worthy doing in the Daytona time frame.
  1606. However, to be able to add it in future without backward compatibility
  1607. problems, we have the last argument to be the format character as
  1608. opposed to the size.
  1609. This makes it possible to call NdrSimpleTypeConvert, if needed.
  1610. --*/
  1611. {
  1612. NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
  1613. PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
  1614. PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
  1615. uchar * BufferSaved;
  1616. // See if we need to unmarshall the common type header.
  1617. NdrpCommonTypeHeaderUnmarshall( (PMIDL_ES_MESSAGE) Handle );
  1618. // Now the data.
  1619. NdrpReadPicklingBuffer( (PMIDL_ES_MESSAGE) Handle, 8);
  1620. if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
  1621. {
  1622. pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
  1623. BufferSaved = pStubMsg->Buffer;
  1624. NdrSimpleTypeConvert( pStubMsg, (unsigned char)FormatChar );
  1625. pStubMsg->Buffer = BufferSaved;
  1626. }
  1627. switch ( FormatChar )
  1628. {
  1629. case FC_BYTE:
  1630. case FC_CHAR:
  1631. case FC_SMALL:
  1632. case FC_USMALL:
  1633. * PCHAR_CAST pData = * PCHAR_CAST pStubMsg->Buffer;
  1634. break;
  1635. case FC_WCHAR:
  1636. case FC_SHORT:
  1637. case FC_USHORT:
  1638. case FC_ENUM16:
  1639. * PSHORT_CAST pData = * PSHORT_CAST pStubMsg->Buffer;
  1640. break;
  1641. case FC_LONG:
  1642. case FC_ULONG:
  1643. case FC_FLOAT:
  1644. case FC_ENUM32:
  1645. case FC_ERROR_STATUS_T:
  1646. * PLONG_CAST pData = * PLONG_CAST pStubMsg->Buffer;
  1647. break;
  1648. case FC_HYPER:
  1649. case FC_DOUBLE:
  1650. * PHYPER_CAST pData = * PHYPER_CAST pStubMsg->Buffer;
  1651. break;
  1652. #if defined(__RPC_WIN64__)
  1653. case FC_INT3264:
  1654. *((INT64 *)pData) = *((long *) pStubMsg->Buffer);
  1655. break;
  1656. case FC_UINT3264:
  1657. *((UINT64 *)pData) = *((ulong *)pStubMsg->Buffer);
  1658. break;
  1659. #endif
  1660. default:
  1661. NDR_ASSERT( 0, " Size generation problem for simple types" );
  1662. }
  1663. pStubMsg->Buffer += 8;
  1664. }
  1665. void
  1666. NdrpProcHeaderMarshallAll(
  1667. PMIDL_ES_MESSAGE pMesMsg
  1668. )
  1669. {
  1670. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1671. // Marshall DCE pickle header.
  1672. if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
  1673. RpcRaiseException( RPC_X_INVALID_BUFFER );
  1674. if ( pMesMsg->Operation == MES_ENCODE )
  1675. * pStubMsg->Buffer++ = MIDL_ES_VERSION;
  1676. else
  1677. * pStubMsg->Buffer++ = MIDL_NDR64_ES_VERSION;
  1678. * pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
  1679. *( PSHORT_LV_CAST pStubMsg->Buffer)++ = (short)0xcccc; // filler
  1680. // Marshall transfer syntax from the stub.
  1681. RpcpMemoryCopy( pStubMsg->Buffer,
  1682. &( ( PMIDL_ES_MESSAGE_EX)pMesMsg )->TransferSyntax,
  1683. sizeof(RPC_SYNTAX_IDENTIFIER) );
  1684. // We need to remember InterfaceId for inquiries.
  1685. RpcpMemoryCopy( & pMesMsg->InterfaceId,
  1686. & ((PRPC_CLIENT_INTERFACE)(pStubMsg->
  1687. StubDesc->RpcInterfaceInformation))->InterfaceId,
  1688. sizeof(RPC_SYNTAX_IDENTIFIER) );
  1689. // Marshall InterfaceId and ProcNumber from the handle.
  1690. RpcpMemoryCopy( pStubMsg->Buffer + sizeof(RPC_SYNTAX_IDENTIFIER),
  1691. & pMesMsg->InterfaceId,
  1692. sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
  1693. SET_MES_INFO_AVAILABLE( pMesMsg );
  1694. pStubMsg->Buffer += 2 * sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
  1695. * pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
  1696. * pStubMsg->Buffer++ = NDR_ASCII_CHAR;
  1697. * pStubMsg->Buffer++ = (char) (NDR_IEEE_FLOAT >> 8);
  1698. * pStubMsg->Buffer++ = 0; // filler
  1699. // This is non-DCE element as they have just 4 more bytes of filler here.
  1700. // This field is used only when unmarshalling in our incremental style.
  1701. *( PLONG_LV_CAST pStubMsg->Buffer)++ = pStubMsg->BufferLength -
  1702. MES_PROC_HEADER_SIZE;
  1703. }
  1704. void
  1705. NdrpProcHeaderUnmarshallAll(
  1706. PMIDL_ES_MESSAGE pMesMsg
  1707. )
  1708. {
  1709. unsigned char * BufferToRestore;
  1710. PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
  1711. if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
  1712. return;
  1713. NdrpReadPicklingBuffer( pMesMsg, MES_PROC_HEADER_SIZE );
  1714. // Unmarshalling the header
  1715. if ( *pStubMsg->Buffer != MIDL_ES_VERSION &&
  1716. *pStubMsg->Buffer != MIDL_NDR64_ES_VERSION)
  1717. RpcRaiseException( RPC_X_WRONG_ES_VERSION );
  1718. BufferToRestore = pStubMsg->Buffer + 4;
  1719. if ( pStubMsg->Buffer[1] != NDR_LOCAL_ENDIAN_LOW )
  1720. {
  1721. // The DCE header has the endianness on the low nibble, while
  1722. // our DataRep has it on the high nibble.
  1723. // We need only endianess to convert the proc header.
  1724. byte Endianness = (pStubMsg->Buffer[1] << 4 );
  1725. pStubMsg->RpcMsg->DataRepresentation = Endianness;
  1726. pStubMsg->Buffer += 4;
  1727. NdrSimpleStructConvert( pStubMsg,
  1728. &__MIDLFormatString.Format[32],
  1729. FALSE );
  1730. }
  1731. pStubMsg->Buffer = BufferToRestore;
  1732. // Verify the transfer syntax
  1733. RpcpMemoryCopy( &((PMIDL_ES_MESSAGE_EX)pMesMsg)->TransferSyntax,
  1734. pStubMsg->Buffer,
  1735. sizeof( RPC_SYNTAX_IDENTIFIER ) );
  1736. pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
  1737. // We need to remember the last InterfaceId and ProcNumber for inquiries.
  1738. RpcpMemoryCopy( & pMesMsg->InterfaceId,
  1739. pStubMsg->Buffer,
  1740. sizeof(RPC_SYNTAX_IDENTIFIER) );
  1741. pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
  1742. pMesMsg->ProcNumber = *(ulong *)pStubMsg->Buffer;
  1743. pStubMsg->Buffer += 4;
  1744. SET_MES_INFO_AVAILABLE( pMesMsg );
  1745. unsigned long AlienDataRepresentation =
  1746. ( (pStubMsg->Buffer[0] << 4) | // endianness
  1747. pStubMsg->Buffer[1] | // chars
  1748. ((unsigned long)(pStubMsg->Buffer[2]) << 8) ); // float
  1749. pMesMsg->AlienDataRep = AlienDataRepresentation;
  1750. pMesMsg->IncrDataSize = (size_t) *(unsigned long __RPC_FAR *)
  1751. (pStubMsg->Buffer + 4);
  1752. pStubMsg->Buffer += 8;
  1753. }
  1754. extern const MIDL_FORMAT_STRING __MIDLFormatString =
  1755. {
  1756. 0,
  1757. {
  1758. 0x1d, /* FC_SMFARRAY */
  1759. 0x0, /* 0 */
  1760. /* 2 */ 0x6, 0x0, /* 6 */
  1761. /* 4 */ 0x1, /* FC_BYTE */
  1762. 0x5b, /* FC_END */
  1763. /* 6 */
  1764. 0x15, /* FC_STRUCT */
  1765. 0x3, /* 3 */
  1766. /* 8 */ 0x10, 0x0, /* 16 */
  1767. /* 10 */ 0x8, /* FC_LONG */
  1768. 0x6, /* FC_SHORT */
  1769. /* 12 */ 0x6, /* FC_SHORT */
  1770. 0x3, /* FC_SMALL */
  1771. /* 14 */ 0x3, /* FC_SMALL */
  1772. 0x4c, /* FC_EMBEDDED_COMPLEX */
  1773. /* 16 */ 0x0, /* 0 */
  1774. 0xef, 0xff, /* Offset= -17 (0) */
  1775. 0x5b, /* FC_END */
  1776. /* 20 */
  1777. 0x15, /* FC_STRUCT */
  1778. 0x3, /* 3 */
  1779. /* 22 */ 0x14, 0x0, /* 20 */
  1780. /* 24 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
  1781. 0x0, /* 0 */
  1782. /* 26 */ 0xec, 0xff, /* Offset= -20 (6) */
  1783. /* 28 */ 0x6, /* FC_SHORT */
  1784. 0x6, /* FC_SHORT */
  1785. /* 30 */ 0x5c, /* FC_PAD */
  1786. 0x5b, /* FC_END */
  1787. /* 32 */
  1788. 0x15, /* FC_STRUCT */
  1789. 0x3, /* 3 */
  1790. /* 34 */ 0x34, 0x0, /* 52 */
  1791. /* 36 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
  1792. 0x0, /* 0 */
  1793. /* 38 */ 0xee, 0xff, /* Offset= -18 (20) */
  1794. /* 40 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
  1795. 0x0, /* 0 */
  1796. /* 42 */ 0xea, 0xff, /* Offset= -22 (20) */
  1797. /* 44 */ 0x8, /* FC_LONG */
  1798. 0x1, /* FC_BYTE */
  1799. /* 46 */ 0x1, /* FC_BYTE */
  1800. 0x1, /* FC_BYTE */
  1801. /* 48 */ 0x1, /* FC_BYTE */
  1802. 0x38, /* FC_ALIGNM4 */
  1803. /* 50 */ 0x8, /* FC_LONG */
  1804. 0x5b, /* FC_END */
  1805. 0x0
  1806. }
  1807. };