Windows NT 4.0 source code leak
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.

1008 lines
27 KiB

4 years ago
  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. pickle.cxx
  5. Abstract:
  6. Generates stub routines to call the pickle engine.
  7. Notes:
  8. History:
  9. Mar-22-1994 VibhasC Created
  10. ----------------------------------------------------------------------------*/
  11. /****************************************************************************
  12. * include files
  13. ***************************************************************************/
  14. #include "becls.hxx"
  15. #pragma hdrstop
  16. #include "szbuffer.h"
  17. /****************************************************************************
  18. * local definitions
  19. ***************************************************************************/
  20. /****************************************************************************
  21. * local data
  22. ***************************************************************************/
  23. /****************************************************************************
  24. * externs
  25. ***************************************************************************/
  26. /****************************************************************************/
  27. CG_STATUS
  28. CG_ENCODE_PROC::GenClientStub(
  29. CCB * pCCB )
  30. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  31. Routine Description:
  32. Generate DCE style procedure pickling stub code.
  33. Arguments:
  34. pCCB - The code gen controller block.
  35. Return Value:
  36. CG_OK
  37. Notes:
  38. ----------------------------------------------------------------------------*/
  39. {
  40. expr_node * pExpr;
  41. CG_ITERATOR Iterator;
  42. ISTREAM * pStream = pCCB->GetStream();
  43. RESOURCE * pReturnResource = 0;
  44. CG_PARAM * pLastParam;
  45. // Register this procedure as a proc-encoding procedure.
  46. pCCB->RegisterEncodeDecodeProc( this );
  47. // Generate the format strings.
  48. GenNdrFormatV1( pCCB );
  49. // Print the prolog of procedure.
  50. Out_ClientProcedureProlog( pCCB, GetType() );
  51. // If there exists a return type, declare a local resource of that
  52. // type.
  53. if( GetReturnType() )
  54. {
  55. pReturnResource = new RESOURCE( RETURN_VALUE_VAR_NAME,
  56. GetReturnType()->GetType() );
  57. pStream->Write( " " );
  58. pReturnResource->GetType()->PrintType(
  59. (PRT_PARAM_WITH_TYPE | PRT_CSTUB_PREFIX),
  60. pStream,
  61. (node_skl *)0 );
  62. pStream->Write( " " RETURN_VALUE_VAR_NAME ";" );
  63. pStream->NewLine();
  64. }
  65. // For alpha, we may need to emit a va_list and va_start under an #ifdef
  66. //
  67. // Emit va_start and declaration only when there are some arguments.
  68. // If number of args is 0 then we don't have to emit that. The reason is
  69. // we need to emit this stuff to force the well defined stack layout
  70. // only for the optimized alpha code But when there is no arguments
  71. // we don't care about the original stack layout as the engine code
  72. // won't be accessing the original stack (this happens only for top
  73. // level parameters that have array attributes: size_is, length_is etc
  74. // or the switch_is attribute)
  75. //
  76. // See if there exists the last the last parameter.
  77. GetMembers(Iterator);
  78. pLastParam = 0;
  79. while ( ITERATOR_GETNEXT( Iterator, pLastParam ) )
  80. ;
  81. if ( pLastParam )
  82. {
  83. pStream->IndentDec();
  84. pStream->NewLine();
  85. pStream->Write( ALPHA_IFDEF );
  86. pStream->IndentInc();
  87. pStream->NewLine();
  88. pStream->Write( VA_LIST_TYPE_NAME" "VLIST_VAR_NAME";" );
  89. pStream->NewLine( 2 );
  90. //
  91. // Emit "va_start( vlist, last_param_name );
  92. expr_node * pVaExpr;
  93. pVaExpr = new expr_proc_call( VA_START_PROC_NAME );
  94. ((expr_proc_call *)pVaExpr)->SetParam( new expr_param(
  95. new expr_variable( VLIST_VAR_NAME,0)));
  96. pExpr = new expr_variable( pLastParam->GetType()->GetSymName(), 0 );
  97. ((expr_proc_call *)pVaExpr)->SetParam( new expr_param( pExpr ) );
  98. pVaExpr->PrintCall( pStream, 0, 0 );
  99. pStream->IndentDec();
  100. pStream->NewLine();
  101. pStream->Write( "#endif" );
  102. pStream->NewLine();
  103. }
  104. GenMesProcEncodeDecodeCall( pCCB, 0 );
  105. GenEpilog( pCCB );
  106. return CG_OK;
  107. }
  108. CG_STATUS
  109. CG_ENCODE_PROC::GenMesProcEncodeDecodeCall(
  110. CCB * pCCB,
  111. BOOL fAlpha )
  112. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  113. Routine Description:
  114. Generate DCE style procedure pickling stub code.
  115. Arguments:
  116. pCCB - The code gen controller block.
  117. pAlpha - The alpha version flag (with va-list argument).
  118. Return Value:
  119. CG_OK
  120. Notes:
  121. ----------------------------------------------------------------------------*/
  122. {
  123. expr_proc_call * pProc;
  124. node_skl * pType;
  125. expr_node * pExpr;
  126. CG_ITERATOR I;
  127. CG_PARAM * pCG;
  128. ISTREAM * pStream = pCCB->GetStream();
  129. PNAME pHandleName;
  130. RESOURCE * pReturnResource = 0;
  131. //
  132. // Generate a call to the single encode proc engine call.
  133. pProc = new expr_proc_call( PROC_ENCODE_DECODE_RTN_NAME );
  134. // Handle. If the handle is explicit, then it must be a MIDL_ES_HANDLE
  135. if( GetHandleUsage() == HU_EXPLICIT )
  136. {
  137. pHandleName = SearchForBindingParam()->GetName();
  138. pType = MakeIDNodeFromTypeName( pHandleName,
  139. MIDL_ES_HANDLE_TYPE_NAME );
  140. }
  141. else
  142. {
  143. assert( pCCB->GetInterfaceCG()->GetImplicitHandle() != 0 );
  144. pType = (node_id *)pCCB->GetInterfaceCG()->GetImplicitHandle()->
  145. GetHandleIDOrParam();
  146. pHandleName = pType->GetSymName();
  147. }
  148. pProc->SetParam( new expr_variable( pHandleName, pType ) );
  149. // Stub descriptor.
  150. pExpr = new RESOURCE( pCCB->GetInterfaceCG()->GetStubDescName(),
  151. (node_skl *)0 );
  152. pExpr = MakeAddressExpressionNoMatterWhat( pExpr );
  153. pExpr = MakeExpressionOfCastToTypeName( PSTUB_DESC_STRUCT_TYPE_NAME,
  154. pExpr );
  155. pProc->SetParam( pExpr );
  156. // Offset into the format string.
  157. pExpr = Make_1_ArrayExpressionFromVarName(
  158. PROC_FORMAT_STRING_STRING_FIELD,
  159. GetFormatStringOffset()
  160. );
  161. pExpr = MakeAddressExpressionNoMatterWhat( pExpr );
  162. pExpr = MakeExpressionOfCastToTypeName( PFORMAT_STRING_TYPE_NAME, pExpr );
  163. pProc->SetParam( pExpr );
  164. // Parameters to the engine are the address of each of the parameters to
  165. // this procedure. If there is no parameter AND no return type, push a
  166. // null (0).
  167. if( GetMembers( I ) )
  168. {
  169. while( ITERATOR_GETNEXT( I, pCG ) )
  170. {
  171. pExpr = new expr_variable( pCG->GetType()->GetSymName(),
  172. pCG->GetType());
  173. pExpr = MakeAddressExpressionNoMatterWhat( pExpr );
  174. pExpr = MakeCastExprPtrToUChar( pExpr );
  175. pProc->SetParam( pExpr );
  176. }
  177. }
  178. else if( !GetReturnType() )
  179. {
  180. pProc->SetParam( new expr_constant( 0L ) );
  181. }
  182. // If there is a return value, then set another parameter to the generated
  183. // procedure expression.
  184. if( GetReturnType() )
  185. {
  186. pReturnResource = new RESOURCE( RETURN_VALUE_VAR_NAME,
  187. GetReturnType()->GetType() );
  188. pExpr = MakeAddressExpressionNoMatterWhat( pReturnResource );
  189. pExpr = MakeCastExprPtrToUChar( pExpr );
  190. pProc->SetParam( pExpr );
  191. }
  192. if ( fAlpha )
  193. {
  194. // We wait for Bruce's comments to see if this is really necessary.
  195. // Right now it seems to work without this or something similar.
  196. pExpr = new expr_variable( VLIST_A0, 0 );
  197. pProc->SetParam( new expr_param( pExpr ));
  198. }
  199. // Now print the call out.
  200. pStream->IndentInc();
  201. pStream->NewLine();
  202. pProc->PrintCall( pStream, 0, 0 );
  203. pStream->NewLine();
  204. return CG_OK;
  205. }
  206. CG_STATUS
  207. CG_TYPE_ENCODE_PROC::GenClientStub(
  208. CCB * pCCB )
  209. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  210. Routine Description:
  211. Generate the client side type encoding stub for this proc.
  212. Arguments:
  213. pCCB - The code gen controller block.
  214. Return Value:
  215. CG_OK
  216. Notes:
  217. This proc node hanging under the encode interface node is really a dummy
  218. proc, put in so that the format string generator can have a placeholder
  219. node to look at.
  220. ----------------------------------------------------------------------------*/
  221. {
  222. return ((CG_PARAM *)GetChild())->GenTypeEncodingStub( pCCB );
  223. }
  224. CG_STATUS
  225. CG_PARAM::GenTypeEncodingStub(
  226. CCB * pCCB )
  227. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  228. Routine Description:
  229. Generate the client side type encoding stub for this param.
  230. Arguments:
  231. pCCB - The code gen controller block.
  232. Return Value:
  233. CG_OK
  234. Notes:
  235. This param is really a dummy param, put in so that the format string
  236. generator can have a placeholder node to look at.
  237. ----------------------------------------------------------------------------*/
  238. {
  239. CG_STATUS Status;
  240. CG_NDR * pLast = pCCB->SetLastPlaceholderClass( this );
  241. Status = ((CG_TYPE_ENCODE *)GetChild())->GenTypeEncodingStub( pCCB );
  242. pCCB->SetLastPlaceholderClass( pLast );
  243. return Status;
  244. }
  245. CG_STATUS
  246. CG_TYPE_ENCODE::GenTypeEncodingStub(
  247. CCB * pCCB )
  248. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  249. Routine Description:
  250. Generate the pickling stubs for a given type.
  251. Arguments:
  252. pCCB - A pointer to the code generator control block.
  253. Return Value:
  254. CG_OK
  255. Notes:
  256. Emit the Type_Encode(), Type_Size() and Type_Decode() routines.
  257. If the encode is needed, then sizing is needed too !.
  258. ----------------------------------------------------------------------------*/
  259. {
  260. CG_NDR * pChild = (CG_NDR *)GetChild();
  261. // Generate the ndr format for the types.
  262. if( ! pChild->IsSimpleType() )
  263. pChild->GenNdrFormat( pCCB );
  264. // Check if implicit binding exists.
  265. if( pCCB->GetInterfaceCG()->GetImplicitHandle() )
  266. {
  267. SetHasImplicitHandle();
  268. }
  269. // Create a resource dictionary database.
  270. pCCB->SetResDictDatabase( new RESOURCE_DICT_DATABASE );
  271. pCCB->ClearParamResourceDict();
  272. // If the type has [encode] on it, generate the sizing and encode routines.
  273. if( IsEncode() )
  274. {
  275. // Allocate standard resources for type encoding.
  276. AllocateEncodeResources( pCCB );
  277. // Generate the sizing and encode routines.
  278. GenTypeSize( pCCB );
  279. GenTypeEncode( pCCB );
  280. }
  281. pCCB->ClearParamResourceDict();
  282. // If the type has [decode] on it, generate the decode routine.
  283. if( IsDecode() )
  284. {
  285. // Allocate standard resources for type decoding.
  286. AllocateEncodeResources( pCCB );
  287. GenTypeDecode( pCCB );
  288. GenTypeFree( pCCB );
  289. }
  290. return CG_OK;
  291. }
  292. CG_STATUS
  293. CG_TYPE_ENCODE::GenTypeSize(
  294. CCB * pCCB )
  295. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  296. Routine Description:
  297. Generate the type sizing routine for the type.
  298. Arguments:
  299. pCCB - The code gen controller block.
  300. Return Value:
  301. CG_OK
  302. Notes:
  303. ----------------------------------------------------------------------------*/
  304. {
  305. ISTREAM * pStream = pCCB->GetStream();
  306. PNAME pName;
  307. TYPE_ENCODE_INFO * pTEInfo = new TYPE_ENCODE_INFO;
  308. // Generate the standard prototype. This really means emit the proto of
  309. // the proc in the stub file. Remember, a real proc node does not exist
  310. // for this pickling type. So we emit a prototype by hand (so to speak).
  311. // The body of the function is output later,
  312. GenStdMesPrototype( pCCB,
  313. (pName = GetType()->GetSymName()),
  314. TYPE_ALIGN_SIZE_CODE,
  315. HasImplicitHandle()
  316. );
  317. pStream->NewLine();
  318. pStream->Write( '{' );
  319. pStream->IndentInc();
  320. pStream->NewLine();
  321. // The procedure body consists of a single procedure call.
  322. expr_proc_call * pProc = CreateStdMesEngineProc( pCCB, TYPE_ALIGN_SIZE_CODE);
  323. pStream->Write( "return " );
  324. pProc->PrintCall( pStream, 0, 0 );
  325. // Terminate the procedure body.
  326. pStream->IndentDec();
  327. pStream->NewLine();
  328. pStream->Write( '}' );
  329. pStream->NewLine();
  330. // Register the routine with the ccb to enable emitting of prototypes.
  331. pTEInfo->pName = pName;
  332. pTEInfo->Flags = HasImplicitHandle() ? TYPE_ENCODE_WITH_IMPL_HANDLE : 0;
  333. pCCB->RegisterTypeAlignSize( pTEInfo );
  334. return CG_OK;
  335. }
  336. CG_STATUS
  337. CG_TYPE_ENCODE::GenTypeEncode(
  338. CCB * pCCB )
  339. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  340. Routine Description:
  341. Generate the type encoding routine for the type.
  342. Arguments:
  343. pCCB - The code gen controller block.
  344. Return Value:
  345. CG_OK
  346. Notes:
  347. ----------------------------------------------------------------------------*/
  348. {
  349. ISTREAM * pStream = pCCB->GetStream();
  350. PNAME pName;
  351. TYPE_ENCODE_INFO * pTEInfo = new TYPE_ENCODE_INFO;
  352. // Generate the standard prototype. This really means emit the proto of
  353. // the proc in the stub file. The body of the function output later,
  354. GenStdMesPrototype( pCCB,
  355. (pName = GetType()->GetSymName()),
  356. TYPE_ENCODE_CODE,
  357. HasImplicitHandle()
  358. );
  359. pStream->NewLine();
  360. pStream->Write( '{' );
  361. pStream->IndentInc();pStream->NewLine();
  362. // The procedure body consists of a single procedure call.
  363. expr_proc_call * pProc = CreateStdMesEngineProc( pCCB, TYPE_ENCODE_CODE);
  364. pProc->PrintCall( pCCB->GetStream(), 0, 0 );
  365. // Terminate the procedure body.
  366. pStream->IndentDec();
  367. pStream->NewLine();
  368. pStream->Write( '}' );
  369. pStream->NewLine();
  370. // Register the routine with the ccb to enable emitting of prototypes.
  371. pTEInfo->pName = pName;
  372. pTEInfo->Flags = HasImplicitHandle() ? TYPE_ENCODE_WITH_IMPL_HANDLE : 0;
  373. pCCB->RegisterTypeEncode( pTEInfo );
  374. return CG_OK;
  375. }
  376. CG_STATUS
  377. CG_TYPE_ENCODE::GenTypeDecode(
  378. CCB * pCCB )
  379. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  380. Routine Description:
  381. Generate the type sizing routine for the type.
  382. Arguments:
  383. pCCB - The code gen controller block.
  384. Return Value:
  385. CG_OK
  386. Notes:
  387. ----------------------------------------------------------------------------*/
  388. {
  389. ISTREAM * pStream = pCCB->GetStream();
  390. PNAME pName;
  391. TYPE_ENCODE_INFO * pTEInfo = new TYPE_ENCODE_INFO;
  392. // Generate the standard prototype. This really means emit the proto of
  393. // the proc in the stub file. The body of the function output later,
  394. GenStdMesPrototype( pCCB,
  395. ( pName = GetType()->GetSymName()),
  396. TYPE_DECODE_CODE,
  397. HasImplicitHandle()
  398. );
  399. pStream->NewLine();
  400. pStream->Write( '{' );
  401. pStream->IndentInc();pStream->NewLine();
  402. // The procedure body consists of a single procedure call.
  403. expr_proc_call * pProc = CreateStdMesEngineProc( pCCB, TYPE_DECODE_CODE);
  404. pProc->PrintCall( pCCB->GetStream(), 0, 0 );
  405. // Terminate the procedure body.
  406. pStream->IndentDec();
  407. pStream->NewLine();
  408. pStream->Write( '}' );
  409. pStream->NewLine();
  410. // Register the routine with the ccb to enable emitting of prototypes.
  411. pTEInfo->pName = pName;
  412. pTEInfo->Flags = HasImplicitHandle() ? TYPE_ENCODE_WITH_IMPL_HANDLE : 0;
  413. pCCB->RegisterTypeDecode( pTEInfo );
  414. return CG_OK;
  415. }
  416. CG_STATUS
  417. CG_TYPE_ENCODE::GenTypeFree(
  418. CCB * pCCB )
  419. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  420. Routine Description:
  421. Generate the type freeing routine for the type.
  422. Arguments:
  423. pCCB - The code gen controller block.
  424. Return Value:
  425. CG_OK
  426. Notes:
  427. ----------------------------------------------------------------------------*/
  428. {
  429. // Currently disabled. This was a code written for Dave Straube.
  430. // Still under evaluation.
  431. if ( NO_FREEING_FOR_PICKLING )
  432. return CG_OK;
  433. ISTREAM * pStream = pCCB->GetStream();
  434. PNAME pName;
  435. TYPE_ENCODE_INFO * pTEInfo = new TYPE_ENCODE_INFO;
  436. // Generate the standard prototype. This really means emit the proto of
  437. // the proc in the stub file. The body of the function output later,
  438. if ( ((CG_NDR *)GetChild())->IsSimpleType() )
  439. return CG_OK;
  440. GenStdMesPrototype( pCCB,
  441. ( pName = GetType()->GetSymName()),
  442. TYPE_FREE_CODE,
  443. HasImplicitHandle()
  444. );
  445. pStream->NewLine();
  446. pStream->Write( '{' );
  447. pStream->IndentInc();pStream->NewLine();
  448. // The procedure body consists of a single procedure call.
  449. expr_proc_call * pProc = CreateStdMesEngineProc( pCCB, TYPE_FREE_CODE);
  450. pProc->PrintCall( pCCB->GetStream(), 0, 0 );
  451. // Terminate the procedure body.
  452. pStream->IndentDec();
  453. pStream->NewLine();
  454. pStream->Write( '}' );
  455. pStream->NewLine();
  456. // Register the routine with the ccb to enable emitting of prototypes.
  457. pTEInfo->pName = pName;
  458. pTEInfo->Flags = HasImplicitHandle() ? TYPE_ENCODE_WITH_IMPL_HANDLE : 0;
  459. pCCB->RegisterTypeFree( pTEInfo );
  460. return CG_OK;
  461. }
  462. void
  463. CG_TYPE_ENCODE::AllocateEncodeResources(
  464. CCB * pCCB )
  465. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  466. Routine Description:
  467. Allocate predefined resources for type pickling.
  468. Arguments:
  469. pCCB - The code gen controller block.
  470. Return Value:
  471. CG_OK
  472. Notes:
  473. Resources are:
  474. 1. The MIDL_ES_HANDLE if explicit binding.
  475. 2. A pointer to the type.
  476. If there is no explicit binding set the implicit binding resource.
  477. ----------------------------------------------------------------------------*/
  478. {
  479. node_id * pMidlESHandle;
  480. RESOURCE * pBindingResource;
  481. node_id * pType = MakeIDNode( PTYPE_VAR_NAME,GetType());
  482. CG_INTERFACE * pInterfaceCG = pCCB->GetInterfaceCG();
  483. // If explicit binding, then a parameter of the type MIDL_ES_HANDLE will
  484. // be specified by the user. This must be added to the dictionary of
  485. // parameter resources.
  486. if( !HasImplicitHandle() )
  487. {
  488. pMidlESHandle = MakeIDNodeFromTypeName( MIDL_ES_HANDLE_VAR_NAME,
  489. MIDL_ES_HANDLE_TYPE_NAME
  490. );
  491. pBindingResource = pCCB->AddParamResource(
  492. MIDL_ES_HANDLE_VAR_NAME,
  493. pMidlESHandle
  494. );
  495. }
  496. else
  497. {
  498. PNAME pName;
  499. // If an implicit binding has been specified, a global variable of the
  500. // type MIDL_ES_HANDLE will have been specified by the user. Pick that
  501. // up and use as the binding resource.
  502. assert( pCCB->GetInterfaceCG()->GetImplicitHandle() != 0 );
  503. pMidlESHandle =
  504. (node_id *)pCCB->GetInterfaceCG()->
  505. GetImplicitHandle()->
  506. GetHandleIDOrParam();
  507. pName = pMidlESHandle->GetSymName();
  508. pBindingResource = new RESOURCE( pName,
  509. MakeIDNodeFromTypeName(
  510. pName,
  511. MIDL_ES_HANDLE_TYPE_NAME));
  512. }
  513. SetBindingResource( pBindingResource );
  514. // Add a param for the type being pickled.
  515. pCCB->AddParamResource( PTYPE_VAR_NAME, pType );
  516. }
  517. expr_proc_call *
  518. CG_TYPE_ENCODE::CreateStdMesEngineProc(
  519. CCB * pCCB,
  520. int Code )
  521. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  522. Routine Description:
  523. Create a standard proc expression for calls to the engine for encode/decode
  524. or size.
  525. Arguments:
  526. pCCB - The code gen controller block.
  527. Code - Which can be any standard encoding services code.
  528. Return Value:
  529. CG_OK
  530. Notes:
  531. If the child is a base type that is being pickled, make direct calls
  532. to the internal apis.
  533. ----------------------------------------------------------------------------*/
  534. {
  535. expr_node * pExpr;
  536. expr_proc_call * pProc;
  537. PNAME pProcName;
  538. CG_NDR * pChild = (CG_NDR *)GetChild();
  539. CSzBuffer ProcNameBuf;
  540. BOOL fIsBaseType;
  541. fIsBaseType = pChild->IsSimpleType();
  542. if( fIsBaseType )
  543. {
  544. assert( Code != TYPE_FREE_CODE );
  545. pProcName = "SimpleType";
  546. ProcNameBuf.Set("NdrMes");
  547. ProcNameBuf.Append(pProcName);
  548. ProcNameBuf.Append((Code == TYPE_ALIGN_SIZE_CODE) ? "AlignSize" :
  549. (Code == TYPE_ENCODE_CODE) ? "Encode" : "Decode");
  550. // sprintf( ProcNameBuf,
  551. // "NdrMes%s%s",
  552. // pProcName,
  553. // (Code == TYPE_ALIGN_SIZE_CODE) ? "AlignSize" :
  554. // (Code == TYPE_ENCODE_CODE) ? "Encode" : "Decode"
  555. // );
  556. pProcName = new char [strlen( ProcNameBuf) + 1];
  557. strcpy( pProcName, ProcNameBuf );
  558. }
  559. else
  560. {
  561. switch( Code )
  562. {
  563. case TYPE_ALIGN_SIZE_CODE : pProcName = NDR_MES_TYPE_ALIGN_SIZE;
  564. break;
  565. case TYPE_ENCODE_CODE : pProcName = NDR_MES_TYPE_ENCODE;
  566. break;
  567. case TYPE_DECODE_CODE : pProcName = NDR_MES_TYPE_DECODE;
  568. break;
  569. case TYPE_FREE_CODE : pProcName = NDR_MES_TYPE_FREE;
  570. break;
  571. default:
  572. assert( FALSE );
  573. }
  574. }
  575. pProc = new expr_proc_call( pProcName );
  576. // Set parameters. First the encoding handle.
  577. // The handle may be implicit or explicit as usual.
  578. pProc->SetParam( GetBindingResource() );
  579. if( !fIsBaseType || Code == TYPE_ENCODE_CODE )
  580. {
  581. // Create an expression of address to the stub descriptor. Set a param
  582. // of that name.
  583. // For base types, only encode needs that, as it may allocate memory.
  584. pExpr = new RESOURCE( pCCB->GetInterfaceCG()->GetStubDescName(),
  585. (node_skl *)0 );
  586. pExpr = MakeAddressExpressionNoMatterWhat( pExpr );
  587. pExpr = MakeExpressionOfCastToTypeName( PSTUB_DESC_STRUCT_TYPE_NAME,
  588. pExpr );
  589. pProc->SetParam( pExpr );
  590. }
  591. if( !fIsBaseType )
  592. {
  593. // Next parameter is the address of the format string indexed by the
  594. // correct offset i.e &__MIDLFormatString[ ? ].
  595. pExpr = Make_1_ArrayExpressionFromVarName(FORMAT_STRING_STRING_FIELD,
  596. pChild->GetFormatStringOffset());
  597. pExpr = MakeAddressExpressionNoMatterWhat( pExpr );
  598. pExpr = MakeExpressionOfCastToTypeName( PFORMAT_STRING_TYPE_NAME, pExpr );
  599. pProc->SetParam( pExpr );
  600. }
  601. // The type pointer variable.
  602. if ( ! (fIsBaseType && Code == TYPE_ALIGN_SIZE_CODE) )
  603. {
  604. pExpr = pCCB->GetParamResource( PTYPE_VAR_NAME );
  605. pProc->SetParam( pExpr );
  606. }
  607. // Data size for simple type encoding and decoding
  608. if ( fIsBaseType )
  609. {
  610. switch ( Code )
  611. {
  612. case TYPE_ALIGN_SIZE_CODE:
  613. break;
  614. case TYPE_ENCODE_CODE:
  615. {
  616. pExpr = new expr_constant( (short) pChild->GetMemorySize() );
  617. pProc->SetParam( pExpr );
  618. }
  619. break;
  620. case TYPE_DECODE_CODE:
  621. // We need format char because of conversion.
  622. pExpr = new expr_constant( (short)
  623. ((CG_BASETYPE *)pChild)->GetFormatChar() );
  624. pProc->SetParam( pExpr );
  625. break;
  626. default:
  627. assert( FALSE );
  628. break;
  629. }
  630. }
  631. return pProc;
  632. }
  633. void
  634. GenStdMesPrototype(
  635. CCB * pCCB,
  636. PNAME TypeName,
  637. int Code,
  638. BOOL fImplicitHandle )
  639. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  640. Routine Description:
  641. Generate a standard prototype for the type pickle routines.
  642. Arguments:
  643. pCCB - The code gen controller block.
  644. PNAME - Name of the type.
  645. Code - Size / Encode / Decode code.
  646. fImplicitImplicitHandle - TRUE if implicit binding handle used.
  647. Return Value:
  648. Notes:
  649. ----------------------------------------------------------------------------*/
  650. {
  651. CSzBuffer Buffer;
  652. char * p;
  653. switch( Code )
  654. {
  655. case TYPE_ALIGN_SIZE_CODE: p = "AlignSize"; break;
  656. case TYPE_ENCODE_CODE: p = "Encode"; break;
  657. case TYPE_DECODE_CODE: p = "Decode"; break;
  658. case TYPE_FREE_CODE: p = "Free"; break;
  659. default:
  660. assert( FALSE );
  661. }
  662. if( fImplicitHandle )
  663. {
  664. Buffer.Set("\n");
  665. Buffer.Append((Code == TYPE_ALIGN_SIZE_CODE) ? "size_t" : "void");
  666. Buffer.Append("\n");
  667. Buffer.Append(TypeName);
  668. Buffer.Append("_");
  669. Buffer.Append(p);
  670. Buffer.Append("(\n ");
  671. Buffer.Append(TypeName);
  672. Buffer.Append(" __RPC_FAR * ");
  673. Buffer.Append(PTYPE_VAR_NAME);
  674. Buffer.Append(")");
  675. // sprintf( Buffer,
  676. // "\n%s\n%s_%s(\n %s __RPC_FAR * %s)",
  677. // (Code == TYPE_ALIGN_SIZE_CODE) ? "size_t" : "void",
  678. // TypeName,
  679. // p,
  680. // TypeName,
  681. // PTYPE_VAR_NAME );
  682. }
  683. else
  684. {
  685. Buffer.Set("\n");
  686. Buffer.Append((Code == TYPE_ALIGN_SIZE_CODE) ? "size_t" : "void");
  687. Buffer.Append("\n");
  688. Buffer.Append(TypeName);
  689. Buffer.Append("_");
  690. Buffer.Append(p);
  691. Buffer.Append("(\n ");
  692. Buffer.Append(MIDL_ES_HANDLE_TYPE_NAME);
  693. Buffer.Append(" ");
  694. Buffer.Append(MIDL_ES_HANDLE_VAR_NAME);
  695. Buffer.Append(",\n ");
  696. Buffer.Append(TypeName);
  697. Buffer.Append(" __RPC_FAR * ");
  698. Buffer.Append(PTYPE_VAR_NAME);
  699. Buffer.Append(")");
  700. // sprintf( Buffer,
  701. // "\n%s\n%s_%s(\n %s %s,\n %s __RPC_FAR * %s)",
  702. // (Code == TYPE_ALIGN_SIZE_CODE) ? "size_t" : "void",
  703. // TypeName,
  704. // p,
  705. // MIDL_ES_HANDLE_TYPE_NAME,
  706. // MIDL_ES_HANDLE_VAR_NAME,
  707. // TypeName,
  708. // PTYPE_VAR_NAME );
  709. }
  710. pCCB->GetStream()->Write( Buffer );
  711. }