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.

5403 lines
143 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. output.cxx
  5. Abstract:
  6. Low level output routines for midl.
  7. Notes:
  8. History:
  9. Sep-18-1993 VibhasC Created.
  10. ----------------------------------------------------------------------------*/
  11. /****************************************************************************
  12. * include files
  13. ***************************************************************************/
  14. #include "becls.hxx"
  15. #pragma hdrstop
  16. #include "buffer.hxx"
  17. #include "midlvers.h"
  18. #include "ndrtypes.h"
  19. #include "rpc.h"
  20. static BOOL HasExprRoutines = FALSE;
  21. #if 0
  22. Notes
  23. A few general rules followed throughout the file.
  24. 1. Never emit tab other than thru the stream.
  25. 2. Never emit a new line other than thru the stream.
  26. 3. Emitting a new line is the responsibility of the entity that wants
  27. itself to be emitted on a new line. Therefore, say each local
  28. variable in the stub needs to be on a new line, then the routine
  29. responsible for emitting the local variable will be responsible
  30. for setting the new line.
  31. #endif // 0
  32. /****************************************************************************
  33. * local definitions
  34. ***************************************************************************/
  35. /****************************************************************************
  36. * local data
  37. ***************************************************************************/
  38. /****************************************************************************
  39. * externs
  40. ***************************************************************************/
  41. extern CMD_ARG * pCommand;
  42. void
  43. Out_ServerProcedureProlog(
  44. CCB * pCCB,
  45. node_skl* pNode,
  46. ITERATOR& LocalsList,
  47. ITERATOR& ParamsList,
  48. ITERATOR& TransientList )
  49. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  50. Routine Description:
  51. Generate the server side procedure prolog.
  52. Arguments:
  53. pCCB - A pointer to the code generation controller block.
  54. pNode - A pointer to the actual procedure node.
  55. LocalsList - A list of local resources.
  56. ParamsList - A list of param resources.
  57. TransientList- A list of temp variables.
  58. Return Value:
  59. Notes:
  60. The server side procedure prolog generation cannot use the normal
  61. printtype method on the procedure node, since the server stub signature
  62. looks different.
  63. Also the name of the server side stub is mangled with the interface name.
  64. All server side procs are void returns.
  65. ----------------------------------------------------------------------------*/
  66. {
  67. CSzBuffer TempBuffer( "void __RPC_STUB\n" );
  68. TempBuffer.Append( pCCB->GetInterfaceName() );
  69. TempBuffer.Append( "_" );
  70. TempBuffer.Append( pNode->GetSymName() );
  71. TempBuffer.Append( "(" );
  72. Out_ProcedureProlog( pCCB,
  73. TempBuffer,
  74. pNode,
  75. LocalsList,
  76. ParamsList,
  77. TransientList
  78. );
  79. }
  80. void
  81. Out_ProcedureProlog(
  82. CCB * pCCB,
  83. PNAME pProcName,
  84. node_skl* ,
  85. ITERATOR& LocalsList,
  86. ITERATOR& ParamsList,
  87. ITERATOR& TransientList )
  88. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89. Routine Description:
  90. Generate the server side procedure prolog.
  91. Arguments:
  92. pCCB - A pointer to the code generation controller block.
  93. pName - A pointer to the procs name string.
  94. pNode - A pointer to the actual procedure node.
  95. LocalsList - A list of local resources.
  96. ParamsList - A list of param resources.
  97. Return Value:
  98. Notes:
  99. Any name mangling is the responsibility of the caller.
  100. ----------------------------------------------------------------------------*/
  101. {
  102. ISTREAM * pStream = pCCB->GetStream();
  103. RESOURCE* pRes;
  104. BOOL fFirst = TRUE;
  105. pStream->NewLine();
  106. pStream->Write( pProcName );
  107. pStream->IndentInc();
  108. //
  109. // Emit the list of parameters.
  110. //
  111. if( ITERATOR_GETCOUNT( ParamsList ) )
  112. {
  113. ITERATOR_INIT( ParamsList );
  114. while( ITERATOR_GETNEXT( ParamsList, pRes ) )
  115. {
  116. if(fFirst != TRUE)
  117. pStream->Write(',');
  118. pRes->GetType()->PrintType(
  119. (PRT_PARAM_WITH_TYPE | PRT_CSTUB_PREFIX),
  120. pStream, // into stream
  121. (node_skl *)0 // no parent.
  122. );
  123. fFirst = FALSE;
  124. }
  125. }
  126. pStream->IndentDec();
  127. //
  128. // Write out the opening brace for the server proc and all that.
  129. //
  130. pStream->Write(" )");
  131. pStream->NewLine();
  132. pStream->Write( '{' );
  133. pStream->IndentInc();
  134. pStream->NewLine();
  135. //
  136. // This is where we get off for /Oi. We have a special routine
  137. // for local variable declaration for /Oi.
  138. //
  139. if ( pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER )
  140. return;
  141. //
  142. // Print out declarations for the locals.
  143. //
  144. if( ITERATOR_GETCOUNT( LocalsList ) )
  145. {
  146. ITERATOR_INIT( LocalsList );
  147. while( ITERATOR_GETNEXT( LocalsList, pRes ) )
  148. {
  149. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  150. pStream, // into stream
  151. (node_skl *)0 // no parent.
  152. );
  153. }
  154. }
  155. if( ITERATOR_GETCOUNT( TransientList ) )
  156. {
  157. ITERATOR_INIT( TransientList );
  158. while( ITERATOR_GETNEXT( TransientList, pRes ) )
  159. {
  160. pStream->IndentInc();
  161. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  162. pStream, // into stream
  163. (node_skl *)0 // no parent.
  164. );
  165. pStream->IndentDec();
  166. }
  167. }
  168. pStream->Write( RPC_STATUS_TYPE_NAME" "RPC_STATUS_VAR_NAME";" );
  169. pStream->NewLine();
  170. //
  171. // Done.
  172. //
  173. }
  174. void
  175. Out_ClientProcedureProlog(
  176. CCB * pCCB,
  177. node_skl* pNode )
  178. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  179. Routine Description:
  180. Generate the procedure prolog for the client side.
  181. Arguments:
  182. pCCB - A pointer to the code generation controller block.
  183. pNode - A pointer to the procedure node.
  184. Return Value:
  185. None.
  186. Notes:
  187. The procedure prolog consists of the return type, the proc name and the
  188. parameters along with the open brace.
  189. ----------------------------------------------------------------------------*/
  190. {
  191. ISTREAM * pStream = pCCB->GetStream();
  192. PRTFLAGS flags;
  193. MIDL_ASSERT( NODE_PROC == pNode->NodeKind() );
  194. flags = PRT_PROC_PROTOTYPE | PRT_CSTUB_PREFIX;
  195. if ( NULL != ( ( node_proc * ) pNode )->GetCSTagRoutine() )
  196. flags |= PRT_OMIT_CS_TAG_PARAMS;
  197. pStream->NewLine();
  198. pStream->NewLine(); // extra new line.
  199. pNode->PrintType(
  200. flags, // print the declaration only.
  201. pStream, // into this stream.
  202. (node_skl *)0 // parent pointer not applicable.
  203. );
  204. //
  205. // Write the opening brace on a new line.
  206. //
  207. pStream->WriteOnNewLine( "{" );
  208. pStream->NewLine();
  209. }
  210. void
  211. Out_ClientLocalVariables(
  212. CCB * pCCB,
  213. ITERATOR& LocalVarList )
  214. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  215. Routine Description:
  216. Output the list of client side local variables.
  217. Arguments:
  218. pCCB - A pointer to the code generation controller block.
  219. LocalVarList - An iterator containing the list of local variables.
  220. Return Value:
  221. None.
  222. Notes:
  223. ----------------------------------------------------------------------------*/
  224. {
  225. ISTREAM * pStream = pCCB->GetStream();
  226. RESOURCE * pResTemp;
  227. ITERATOR_INIT( LocalVarList );
  228. while( ITERATOR_GETNEXT( LocalVarList, pResTemp ) )
  229. {
  230. pStream->IndentInc();
  231. pStream->NewLine();
  232. pResTemp->GetType()->PrintType( PRT_ID_DECLARATION,
  233. // print top level decl
  234. pStream, // into stream with
  235. (node_skl *)0 // parent not applicable
  236. );
  237. pStream->IndentDec();
  238. }
  239. }
  240. void
  241. Out_AllocAndFreeFields(
  242. CCB * pCCB )
  243. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  244. Routine Description:
  245. Outputs the alloc and free fields of the stub descriptor.
  246. Arguments:
  247. pCCB - A pointer to the code generation controller block.
  248. ----------------------------------------------------------------------------*/
  249. {
  250. ISTREAM * pStream;
  251. CG_INTERFACE * pIntfCG = pCCB->GetInterfaceCG();
  252. pStream = pCCB->GetStream();
  253. if ( pIntfCG->IsObject() )
  254. {
  255. pStream->Write( OLE_ALLOC_RTN_NAME );
  256. }
  257. else if ( pCCB->GetMode() )
  258. {
  259. // non-osf modes
  260. if ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  261. {
  262. pStream->Write( pIntfCG->IsAllRpcSS()
  263. ? RPC_SM_CLIENT_ALLOCATE_RTN_NAME
  264. : DEFAULT_ALLOC_RTN_NAME );
  265. }
  266. else
  267. pStream->Write( pIntfCG->IsAllRpcSS()
  268. ? DEFAULT_ALLOC_OSF_RTN_NAME
  269. : DEFAULT_ALLOC_RTN_NAME );
  270. }
  271. else
  272. {
  273. // osf mode
  274. pStream->Write( (pCCB->GetCodeGenSide() == CGSIDE_CLIENT)
  275. ? RPC_SM_CLIENT_ALLOCATE_RTN_NAME
  276. : DEFAULT_ALLOC_OSF_RTN_NAME );
  277. }
  278. pStream->Write(',');
  279. pStream->NewLine();
  280. if ( pIntfCG->IsObject() )
  281. {
  282. pStream->Write( OLE_FREE_RTN_NAME );
  283. }
  284. else if ( pCCB->GetMode() )
  285. {
  286. if ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  287. {
  288. pStream->Write( pIntfCG->IsAllRpcSS()
  289. ? RPC_SM_CLIENT_FREE_RTN_NAME
  290. : DEFAULT_FREE_RTN_NAME );
  291. }
  292. else
  293. pStream->Write( pIntfCG->IsAllRpcSS()
  294. ? DEFAULT_FREE_OSF_RTN_NAME
  295. : DEFAULT_FREE_RTN_NAME );
  296. }
  297. else
  298. {
  299. pStream->Write( (pCCB->GetCodeGenSide() == CGSIDE_CLIENT)
  300. ? RPC_SM_CLIENT_FREE_RTN_NAME
  301. : DEFAULT_FREE_OSF_RTN_NAME );
  302. }
  303. pStream->Write(',');
  304. pStream->NewLine();
  305. }
  306. void
  307. Out_NotifyTable (
  308. CCB* pCCB
  309. )
  310. {
  311. CGSIDE Side = pCCB->GetCodeGenSide();
  312. ITERATOR NotifyProcList;
  313. pCCB->GetListOfNotifyTableEntries( NotifyProcList );
  314. ITERATOR_INIT( NotifyProcList );
  315. if ( Side == CGSIDE_SERVER && pCommand->GetNdrVersionControl().HasInterpretedNotify() )
  316. {
  317. ISTREAM* pStream = pCCB->GetStream();
  318. CG_PROC* pProc = 0;
  319. pStream->NewLine();
  320. pStream->Write( "static const NDR_NOTIFY_ROUTINE " );
  321. pStream->Write( "_NotifyRoutineTable[] = {" );
  322. pStream->IndentInc();
  323. pStream->NewLine();
  324. while ( ITERATOR_GETNEXT( NotifyProcList, pProc ) )
  325. {
  326. pStream->Write( "(NDR_NOTIFY_ROUTINE) " );
  327. pStream->Write( pProc->GetSymName() );
  328. pStream->Write( "_notify" );
  329. if ( pProc->HasNotifyFlag() )
  330. {
  331. pStream->Write( "_flag" );
  332. }
  333. pStream->Write( "," );
  334. pStream->NewLine();
  335. }
  336. pStream->Write( "0" );
  337. pStream->NewLine();
  338. pStream->Write( "};" );
  339. pStream->IndentDec();
  340. pStream->NewLine();
  341. }
  342. }
  343. void
  344. Out_NotifyTableExtern (
  345. CCB* pCCB
  346. )
  347. {
  348. if ( pCommand->GetNdrVersionControl().HasInterpretedNotify() )
  349. {
  350. ISTREAM* pStream = pCCB->GetStream();
  351. pStream->NewLine();
  352. pStream->Write( "extern const NDR_NOTIFY_ROUTINE _NotifyRoutineTable[];" );
  353. pStream->NewLine();
  354. }
  355. }
  356. void
  357. Out_StubDescriptor(
  358. CG_HANDLE * pImplicitHandle,
  359. CCB * pCCB )
  360. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  361. Routine Description:
  362. Generate the stub descriptor structure in the client or server stub.
  363. Arguments:
  364. pImplicitHandle - A pointer to the implicit CG_HANDLE used in the
  365. interface. Every interface has one of these even if
  366. it is not used.
  367. pCCB - A pointer to the code gen controller block.
  368. Return Value:
  369. None.
  370. Notes:
  371. ----------------------------------------------------------------------------*/
  372. {
  373. if ( !pCommand->IsFinalProtocolRun() )
  374. {
  375. // Expression routines are generated in dce run, but we are generating stubdesc in
  376. // ndr64 run. So we need to save the state for second run.
  377. // better solution would be using expression evaluator for dce.
  378. MIDL_ASSERT( pCommand->IsNDRRun() );
  379. if ( pCommand->NeedsNDR64Run() && pCCB->GetExprEvalIndexMgr()->Lookup(1) )
  380. {
  381. HasExprRoutines = TRUE;
  382. }
  383. return;
  384. }
  385. ISTREAM * pStream;
  386. CG_INTERFACE * pInterface;
  387. CSzBuffer Buffer;
  388. CGSIDE Side;
  389. BOOL fObjectInterface;
  390. ULONG_PTR ulMidlFlag = 0;
  391. pStream = pCCB->GetStream();
  392. Side = pCCB->GetCodeGenSide();
  393. pInterface = pCCB->GetInterfaceCG();
  394. fObjectInterface = pInterface->IsObject();
  395. if ( pInterface->HasClientInterpretedCommOrFaultProc( pCCB ) )
  396. {
  397. CG_ITERATOR Iterator;
  398. CG_PROC * pProc;
  399. pStream->NewLine();
  400. pStream->Write( "static const COMM_FAULT_OFFSETS " );
  401. pStream->Write( pCCB->GetInterfaceName() );
  402. pStream->Write( '_' );
  403. pStream->Write( "CommFaultOffsets[]" );
  404. pStream->Write( " = " );
  405. pStream->NewLine();
  406. pStream->Write( '{' );
  407. pStream->NewLine();
  408. pInterface->GetMembers( Iterator );
  409. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  410. {
  411. long CommOffset, FaultOffset;
  412. if ( ((Side == CGSIDE_CLIENT) &&
  413. (pProc->GetCGID() != ID_CG_PROC)) ||
  414. ((Side == CGSIDE_SERVER) &&
  415. (pProc->GetCGID() != ID_CG_CALLBACK_PROC)) )
  416. continue;
  417. if ( pProc->HasStatuses() )
  418. {
  419. pProc->GetCommAndFaultOffset( pCCB, CommOffset, FaultOffset );
  420. Buffer.Set( "\t{ " );
  421. Buffer.Append( CommOffset );
  422. Buffer.Append( ", " );
  423. Buffer.Append( FaultOffset );
  424. Buffer.Append( " }" );
  425. Buffer.Append( pProc->GetSibling() ? "," : " " );
  426. if ( ! pCommand->Is32BitEnv() )
  427. {
  428. Buffer.Append( "\t/* ia64 Offsets for " );
  429. }
  430. else
  431. {
  432. Buffer.Append( "\t/* x86 Offsets for " );
  433. }
  434. Buffer.Append( pProc->GetSymName() );
  435. Buffer.Append( " */" );
  436. pStream->Write( Buffer );
  437. }
  438. else
  439. {
  440. pStream->Write( "\t{ -2, -2 }" );
  441. if ( pProc->GetSibling() )
  442. pStream->Write( ',' );
  443. }
  444. pStream->NewLine();
  445. }
  446. pStream->Write( "};" );
  447. pStream->NewLine();
  448. pStream->NewLine();
  449. }
  450. //
  451. // If we have an implicit generic handle then output the generic info
  452. // structure which will be placed in the IMPLICIT_HANDLE_INFO union.
  453. //
  454. if ( (Side == CGSIDE_CLIENT) &&
  455. pImplicitHandle && pImplicitHandle->IsGenericHandle() )
  456. {
  457. pStream->NewLine();
  458. pStream->Write( "static " GENERIC_BINDING_INFO_TYPE );
  459. pStream->Write( ' ' );
  460. pStream->Write( pCCB->GetInterfaceName() );
  461. pStream->Write( '_' );
  462. pStream->Write( GENERIC_BINDING_INFO_VAR );
  463. pStream->Write( " = " );
  464. pStream->IndentInc();
  465. pStream->NewLine();
  466. pStream->Write( '{' );
  467. pStream->NewLine();
  468. pStream->Write( '&' );
  469. pStream->Write( pImplicitHandle->GetHandleIDOrParam()->GetSymName() );
  470. pStream->Write( ',' );
  471. pStream->NewLine();
  472. char Buffer[80];
  473. sprintf( Buffer, "%d,",
  474. ((CG_GENERIC_HANDLE *)pImplicitHandle)->GetImplicitSize() );
  475. pStream->Write( Buffer );
  476. pStream->NewLine();
  477. pStream->Write( "(" GENERIC_BINDING_ROUTINE_TYPE ")" );
  478. pStream->Write( pImplicitHandle->GetHandleType()->GetSymName() );
  479. pStream->Write( "_bind," );
  480. pStream->NewLine();
  481. pStream->Write( "(" GENERIC_UNBINDING_ROUTINE_TYPE ")" );
  482. pStream->Write( pImplicitHandle->GetHandleType()->GetSymName() );
  483. pStream->Write( "_unbind" );
  484. pStream->NewLine();
  485. pStream->Write( "};" );
  486. pStream->IndentDec();
  487. pStream->NewLine();
  488. }
  489. //
  490. // Emit the stub descriptor structure itself.
  491. //
  492. pStream->NewLine();
  493. pStream->Write( "static const " STUB_DESC_STRUCT_TYPE_NAME );
  494. pStream->Write( ' ' );
  495. pStream->Write( pCCB->GetInterfaceCG()->GetStubDescName() );
  496. pStream->Write( " = " );
  497. pStream->IndentInc();
  498. pStream->NewLine();
  499. pStream->Write('{' );
  500. pStream->NewLine();
  501. if( (fObjectInterface == TRUE) )
  502. pStream->Write( "0," );
  503. else
  504. {
  505. pStream->Write( "(void *)& " );
  506. pStream->Write( pCCB->GetInterfaceName() );
  507. if( Side == CGSIDE_SERVER )
  508. pStream->Write( RPC_S_INT_INFO_STRUCT_NAME"," );
  509. else
  510. pStream->Write( RPC_C_INT_INFO_STRUCT_NAME"," );
  511. }
  512. pStream->NewLine();
  513. Out_AllocAndFreeFields( pCCB );
  514. //
  515. // Output the implicit handle information on the client side.
  516. //
  517. if ( (Side == CGSIDE_CLIENT) && (fObjectInterface != TRUE) )
  518. {
  519. if ( ! pImplicitHandle )
  520. {
  521. pStream->Write( '&' );
  522. pStream->Write( pCCB->GetInterfaceName() );
  523. pStream->Write( AUTO_BH_VAR_NAME );
  524. }
  525. else
  526. {
  527. if ( pImplicitHandle->IsPrimitiveHandle() )
  528. {
  529. pStream->Write( '&' );
  530. pStream->Write(
  531. pImplicitHandle->GetHandleIDOrParam()->GetSymName() );
  532. }
  533. else // has to be implicit generic
  534. {
  535. MIDL_ASSERT( pImplicitHandle->IsGenericHandle() );
  536. pStream->Write( "(handle_t *)& " );
  537. pStream->Write( pCCB->GetInterfaceName() );
  538. pStream->Write( '_' );
  539. pStream->Write( GENERIC_BINDING_INFO_VAR );
  540. }
  541. }
  542. }
  543. else
  544. pStream->Write( '0' );
  545. pStream->Write( ',' );
  546. pStream->NewLine();
  547. //
  548. // Output the rundown routine table on the server side interpreted stub
  549. // if needed.
  550. //
  551. if ( (Side == CGSIDE_SERVER) &&
  552. (pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER) &&
  553. pCCB->HasRundownRoutines()
  554. )
  555. {
  556. pStream->Write( RUNDOWN_ROUTINE_TABLE_VAR );
  557. }
  558. else
  559. {
  560. pStream->Write( '0' );
  561. }
  562. pStream->Write( ',' );
  563. pStream->NewLine();
  564. //
  565. // Output the generic bind/unbind routine pair table on the client side
  566. // interpreted stub if needed.
  567. //
  568. if ( (Side == CGSIDE_CLIENT) &&
  569. pCCB->GetInterpretedRoutinesUseGenHandle()
  570. )
  571. {
  572. pStream->Write( BINDING_ROUTINE_TABLE_VAR );
  573. }
  574. else
  575. {
  576. pStream->Write( '0' );
  577. }
  578. pStream->Write( ',' );
  579. pStream->NewLine();
  580. //
  581. // Output the expression evaluation routine table.
  582. //
  583. pStream->Write( pCCB->GetExprEvalIndexMgr()->Lookup(1) || HasExprRoutines
  584. ? EXPR_EVAL_ROUTINE_TABLE_VAR","
  585. : "0," );
  586. pStream->NewLine();
  587. //
  588. // Output the transmit as routine table.
  589. //
  590. pStream->Write( pCCB->GetQuintupleDictionary()->GetCount()
  591. ? XMIT_AS_ROUTINE_TABLE_VAR ","
  592. : "0," );
  593. pStream->NewLine();
  594. //
  595. // Output the type format string.
  596. //
  597. if ( SYNTAX_DCE == pCommand->GetDefaultSyntax() )
  598. pStream->Write( FORMAT_STRING_STRING_FIELD );
  599. else
  600. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  601. pStream->Write( ',' );
  602. pStream->NewLine();
  603. //
  604. // -error bounds_check flag.
  605. //
  606. pStream->Write( pCCB->MustCheckBounds() ? "1" : "0" );
  607. pStream->Write( ',' );
  608. pStream->Write( " /* -error bounds_check flag */" );
  609. pStream->NewLine();
  610. //
  611. // Ndr library version.
  612. //
  613. unsigned long ulNdrLibVer = NDR_VERSION_1_1;
  614. if ( pCommand->GetNdrVersionControl().HasNdr60Feature() )
  615. {
  616. ulNdrLibVer = NDR_VERSION_6_0;
  617. }
  618. else if ( pCommand->GetNdrVersionControl().HasNdr50Feature() )
  619. {
  620. if ( pCommand->GetNdrVersionControl().HasOicfPickling() )
  621. {
  622. ulNdrLibVer = NDR_VERSION_5_4;
  623. }
  624. else if ( pCommand->GetNdrVersionControl().HasNT5VTableSize() )
  625. {
  626. ulNdrLibVer = NDR_VERSION_5_3;
  627. }
  628. else if (pCommand->GetNdrVersionControl().HasAsyncUUID() ||
  629. pCommand->GetNdrVersionControl().HasDOA() ||
  630. pCommand->GetNdrVersionControl().HasContextSerialization() ||
  631. pCommand->GetNdrVersionControl().HasInterpretedNotify() )
  632. {
  633. ulNdrLibVer = NDR_VERSION_5_2;
  634. }
  635. else
  636. {
  637. ulNdrLibVer = NDR_VERSION_5_0;
  638. }
  639. }
  640. else if ( (pCommand->GetOptimizationFlags() & OPTIMIZE_NON_NT351) ||
  641. pCommand->GetNdrVersionControl().HasNdr20Feature() )
  642. {
  643. ulNdrLibVer = NDR_VERSION_2_0;
  644. }
  645. sprintf( Buffer, "0x%x", ulNdrLibVer );
  646. pStream->Write( Buffer );
  647. pStream->Write( ',' );
  648. pStream->Write( " /* Ndr library version */" );
  649. pStream->NewLine();
  650. if ( fObjectInterface &&
  651. pCommand->GetNdrVersionControl().HasUserMarshal() &&
  652. (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER) &&
  653. ! (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2)
  654. )
  655. {
  656. pStream->NewLine(2);
  657. pStream->Write( "#error [user_marshal] and [wire_marshal] not supported with -Oi and -Oic" );
  658. pStream->NewLine();
  659. pStream->Write( "/* use -Os or -Oicf compiler flag */" );
  660. pStream->NewLine();
  661. RpcError( NULL, 0, USER_MARSHAL_IN_OI, "" );
  662. exit( USER_MARSHAL_IN_OI );
  663. }
  664. // Used one reserved field for RpcSs.
  665. // In ms_ext when explicit, in osf always, to cover some weird cases.
  666. if ( ( pCCB->GetInterfaceCG()->GetUsesRpcSS() || (pCCB->GetMode() == 0) )
  667. &&
  668. ( (Side == CGSIDE_CLIENT) ||
  669. ((Side == CGSIDE_SERVER) && pCCB->GetMode()) )// because of callbacks
  670. )
  671. {
  672. pStream->Write( "&" MALLOC_FREE_STRUCT_VAR_NAME "," );
  673. }
  674. else
  675. pStream->Write( "0," );
  676. pStream->NewLine();
  677. // MIDL version number.
  678. sprintf( Buffer,
  679. "0x%x, /* MIDL Version %d.%d.%d */",
  680. (rmj << 24) | (rmm << 16) | rup,
  681. rmj,
  682. rmm,
  683. rup );
  684. pStream->Write( Buffer );
  685. pStream->NewLine();
  686. // Interpreter comm/fault status info.
  687. if ( pInterface->HasClientInterpretedCommOrFaultProc( pCCB ) )
  688. {
  689. pStream->Write( pCCB->GetInterfaceName() );
  690. pStream->Write( '_' );
  691. pStream->Write( "CommFaultOffsets," );
  692. }
  693. else
  694. {
  695. pStream->Write( "0," );
  696. }
  697. pStream->NewLine();
  698. // Fields for the compiler version 3.0+
  699. //
  700. // Output the usr_marshal routine table.
  701. //
  702. if ( pCCB->HasQuadrupleRoutines() )
  703. {
  704. if ( SYNTAX_DCE == pCommand->GetDefaultSyntax() )
  705. pStream->Write( USER_MARSHAL_ROUTINE_TABLE_VAR );
  706. else
  707. pStream->Write( NDR64_USER_MARSHAL_ROUTINE_TABLE_VAR );
  708. }
  709. else
  710. pStream->Write( "0" );
  711. pStream->Write( "," );
  712. pStream->NewLine();
  713. // notify & notify_flag routine table
  714. if ( Side == CGSIDE_SERVER && pCommand->GetNdrVersionControl().HasInterpretedNotify() )
  715. {
  716. pStream->Write( "_NotifyRoutineTable" );
  717. }
  718. else
  719. {
  720. pStream->Write( "0" );
  721. }
  722. pStream->Write( ", /* notify & notify_flag routine table */" );
  723. pStream->NewLine();
  724. if ( ! pInterface->GetHasMSConfStructAttr() )
  725. {
  726. ulMidlFlag |= 1;
  727. }
  728. if ( pCommand->IsSwitchDefined(SWITCH_NOREUSE_BUFFER))
  729. ulMidlFlag |= 2;
  730. if ( pCommand->NeedsNDR64Run() )
  731. ulMidlFlag |= RPCFLG_HAS_MULTI_SYNTAXES;
  732. sprintf( Buffer,
  733. "0x%x, /* MIDL flag */",
  734. ulMidlFlag);
  735. pStream->Write( Buffer );
  736. if ( pCCB->HasCsTypes() )
  737. {
  738. pStream->WriteOnNewLine( '&' );
  739. pStream->Write( CS_ROUTINE_TABLES_VAR );
  740. pStream->Write( ',' );
  741. }
  742. else
  743. {
  744. pStream->WriteOnNewLine( "0, /* cs routines */" );
  745. }
  746. if ( !fObjectInterface && pCommand->NeedsNDR64Run() )
  747. {
  748. if ( Side == CGSIDE_SERVER )
  749. {
  750. pStream->WriteOnNewLine( "(void *)& " );
  751. pStream->Write( pCCB->GetInterfaceName() );
  752. pStream->Write( "_ServerInfo," );
  753. }
  754. else
  755. {
  756. pStream->WriteOnNewLine( "(void *)& " );
  757. pStream->Write( pCCB->GetInterfaceName() );
  758. pStream->Write( "_ProxyInfo," );
  759. }
  760. }
  761. else
  762. {
  763. pStream->WriteOnNewLine( "0," );
  764. }
  765. pStream->Write( " /* proxy/server info */" );
  766. //
  767. // The reserved fields for future use.
  768. //
  769. // 1 reserved fields
  770. pStream->WriteOnNewLine( "0 /* Reserved5 */" );
  771. // No reserved fields left.
  772. // Check the compiler version and or lib version if you need to access
  773. // newer fields.
  774. pStream->WriteOnNewLine( "};" );
  775. pStream->IndentDec();
  776. pStream->NewLine();
  777. }
  778. void CG_INTERFACE::Out_ProxyInfo( CCB * pCCB,
  779. BOOL IsForCallback )
  780. {
  781. if ( pCommand->IsNDR64Run() )
  782. {
  783. GenSyntaxInfo( pCCB, IsForCallback );
  784. GenProxyInfo( pCCB, IsForCallback );
  785. }
  786. }
  787. void CG_INTERFACE::Out_ServerInfo(CCB *pCCB,
  788. BOOL fHasThunk,
  789. BOOL IsForCallback )
  790. {
  791. if ( !pCommand->IsFinalProtocolRun() )
  792. return;
  793. ISTREAM * pStream = pCCB->GetStream();
  794. CG_INTERFACE * pInterface = pCCB->GetInterfaceCG();
  795. char * pItfName = pInterface->GetSymName();
  796. BOOL fObject = pCCB->GetInterfaceCG()->IsObject();
  797. pStream->Write( "static const " SERVER_INFO_TYPE_NAME " " );
  798. pStream->Write( pItfName );
  799. pStream->Write( SERVER_INFO_VAR_NAME );
  800. pStream->Write( " = " );
  801. pStream->IndentInc();
  802. pStream->NewLine();
  803. pStream->Write( '{' );
  804. pStream->NewLine();
  805. //
  806. // Stub descriptor.
  807. //
  808. pStream->Write( '&' );
  809. pStream->Write( pInterface->GetStubDescName() );
  810. pStream->Write( ',' );
  811. pStream->NewLine();
  812. //
  813. // Dispatch table to server routines.
  814. //
  815. if ( !pCCB->GetInterfaceCG()->IsObject() )
  816. {
  817. pStream->Write( pItfName );
  818. pStream->Write( SERVER_ROUTINE_TABLE_NAME );
  819. }
  820. else
  821. {
  822. pStream->Write( '0' );
  823. }
  824. pStream->Write( ',' );
  825. pStream->NewLine();
  826. //
  827. // Procedure format string.
  828. //
  829. if (pCommand->GetDefaultSyntax() == SYNTAX_NDR64 )
  830. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  831. else
  832. pStream->Write( PROC_FORMAT_STRING_STRING_FIELD );
  833. pStream->Write( ',' );
  834. pStream->NewLine();
  835. //
  836. // Array of proc format string offsets.
  837. //
  838. if ( pCommand->IsNDR64Run() )
  839. pStream->Write( "(unsigned short *) " );
  840. if ( fObject )
  841. pStream->Write( '&' );
  842. if ( IsForCallback )
  843. pStream->Write( MIDL_CALLBACK_VAR_NAME );
  844. pStream->Write( pItfName );
  845. if ( pCommand->GetDefaultSyntax() == SYNTAX_DCE )
  846. {
  847. pStream->Write( FORMAT_STRING_OFFSET_TABLE_NAME );
  848. }
  849. else
  850. {
  851. pStream->Write( "_Ndr64ProcTable" );
  852. }
  853. if ( fObject )
  854. pStream->Write( "[-3]" );
  855. pStream->Write( ',' );
  856. pStream->NewLine();
  857. //
  858. // Thunk table.
  859. //
  860. if ( fHasThunk )
  861. {
  862. if ( fObject )
  863. pStream->Write( '&' );
  864. pStream->Write( pItfName );
  865. pStream->Write( STUB_THUNK_TABLE_NAME );
  866. if ( fObject )
  867. pStream->Write( "[-3]" );
  868. }
  869. else
  870. pStream->Write( '0' );
  871. pStream->Write( ',' );
  872. pStream->NewLine();
  873. // old inteface supporting one transfer syntax.
  874. // old interfaces.
  875. if ( !pCommand->NeedsNDR64Run() )
  876. {
  877. pStream->Write( "0,");
  878. pStream->NewLine();
  879. pStream->Write( "0,");
  880. pStream->NewLine();
  881. pStream->Write( "0");
  882. }
  883. else
  884. {
  885. // default transfer syntax is NDR
  886. pStream->Write( '&' );
  887. if ( pCommand->IsNDRRun() )
  888. pStream->Write( NDR_TRANSFER_SYNTAX_VAR_NAME );
  889. else
  890. pStream->Write( NDR64_TRANSFER_SYNTAX_VAR_NAME );
  891. pStream->Write( ',' );
  892. pStream->NewLine();
  893. // we only support one additional transfer syntax
  894. if ( pCommand->NeedsNDRRun() )
  895. pStream->Write( "2," );
  896. else
  897. pStream->Write( "1," );
  898. pStream->NewLine();
  899. if ( IsForCallback )
  900. pStream->Write( MIDL_CALLBACK_VAR_NAME );
  901. pStream->Write( GetMulSyntaxInfoName() );
  902. pStream->NewLine();
  903. }
  904. pStream->Write( "};" );
  905. pStream->IndentDec();
  906. pStream->NewLine();
  907. }
  908. /*
  909. * Generates MIDL_SERVER_INFO. It'll be generated in:
  910. . object interface
  911. . raw RPC server side
  912. . raw RPC client side, if callback is presented (client side means for callback)
  913. regardless of transfer syntax.
  914. *
  915. */
  916. void
  917. CG_INTERFACE::Out_InterpreterServerInfo( CCB * pCCB,
  918. CGSIDE Side )
  919. {
  920. if ( !pCommand->IsFinalProtocolRun() )
  921. return;
  922. ISTREAM * pStream = pCCB->GetStream();
  923. CG_PROC * pProc;
  924. BOOL fHasThunk;
  925. char * pSStubPrefix;
  926. CSzBuffer Buffer;
  927. BOOL fObject = pCCB->GetInterfaceCG()->IsObject();
  928. char * pItfName = GetSymName();
  929. pStream->NewLine();
  930. fHasThunk = FALSE;
  931. if ( (pSStubPrefix = pCommand->GetUserPrefix( PREFIX_SERVER_MGR ) ) == 0 )
  932. {
  933. pSStubPrefix = "";
  934. }
  935. //
  936. // Server routine dispatch table.
  937. //
  938. if ( !fObject )
  939. {
  940. CG_ITERATOR Iterator;
  941. pStream->Write( "static const " SERVER_ROUTINE_TYPE_NAME " " );
  942. pStream->Write( pItfName );
  943. pStream->Write( SERVER_ROUTINE_TABLE_NAME "[]" );
  944. pStream->Write( " = " );
  945. pStream->IndentInc();
  946. pStream->NewLine();
  947. pStream->Write( '{' );
  948. pStream->NewLine();
  949. GetMembers( Iterator );
  950. BOOL fNoProcsEmitted = TRUE;
  951. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  952. {
  953. if ( (Side == CGSIDE_CLIENT) &&
  954. (pProc->GetCGID() != ID_CG_CALLBACK_PROC) )
  955. continue;
  956. if ( (Side == CGSIDE_SERVER) &&
  957. ( (pProc->GetCGID() == ID_CG_CALLBACK_PROC)
  958. || ( pProc->GetCGID() == ID_CG_TYPE_ENCODE_PROC ) ) )
  959. continue;
  960. fNoProcsEmitted = FALSE;
  961. if ( pProc->NeedsServerThunk( pCCB, Side ) )
  962. {
  963. fHasThunk = TRUE;
  964. }
  965. pStream->Write( "(" SERVER_ROUTINE_TYPE_NAME ")" );
  966. if ( pProc->GetCallAsName() )
  967. {
  968. pStream->Write( pProc->GenMangledCallAsName( pCCB ) );
  969. }
  970. else
  971. {
  972. if ( pProc->GetCGID() == ID_CG_ENCODE_PROC ||
  973. pProc->GetCGID() == ID_CG_TYPE_ENCODE_PROC )
  974. pStream->Write( '0' );
  975. else
  976. {
  977. Buffer.Set( pSStubPrefix );
  978. Buffer.Append( pProc->GetType()->GetSymName() );
  979. if ( pProc->HasComplexReturnType() && !pProc->HasAsyncHandle() )
  980. Buffer.Append( "_ComplexThunk" );
  981. pStream->Write( Buffer );
  982. }
  983. }
  984. if ( pProc->GetSibling() )
  985. pStream->Write( ',' );
  986. pStream->NewLine();
  987. }
  988. if ( fNoProcsEmitted )
  989. {
  990. pStream->Write( '0' );
  991. pStream->NewLine();
  992. }
  993. pStream->Write( "};" );
  994. pStream->IndentDec();
  995. pStream->NewLine( 2 );
  996. }
  997. else // object interfaces only need to know about thunks
  998. {
  999. ITERATOR Iterator;
  1000. CG_OBJECT_PROC * pObjProc;
  1001. GetAllMemberFunctions( Iterator );
  1002. while ( ITERATOR_GETNEXT( Iterator, pObjProc ) )
  1003. {
  1004. if ( pObjProc->NeedsServerThunk( pCCB, Side ) && !pObjProc->IsDelegated() )
  1005. fHasThunk = TRUE;
  1006. }
  1007. }
  1008. //
  1009. // Thunk table.
  1010. //
  1011. if ( fHasThunk )
  1012. {
  1013. pStream->Write( "static const " STUB_THUNK_TYPE_NAME " " );
  1014. pStream->Write( pItfName );
  1015. pStream->Write( STUB_THUNK_TABLE_NAME "[]" );
  1016. pStream->Write( " = " );
  1017. pStream->IndentInc();
  1018. pStream->NewLine();
  1019. pStream->Write( '{' );
  1020. pStream->NewLine();
  1021. OutputThunkTableEntries( pCCB, TRUE );
  1022. pStream->Write( "};" );
  1023. pStream->IndentDec();
  1024. pStream->NewLine( 2 );
  1025. }
  1026. // ---------------------------
  1027. //
  1028. // Emit the Server Info struct.
  1029. //
  1030. // ---------------------------
  1031. Out_ServerInfo( pCCB , fHasThunk, Side == CGSIDE_CLIENT );
  1032. }
  1033. void
  1034. Out_EP_Info(
  1035. CCB * pCCB,
  1036. ITERATOR * I )
  1037. {
  1038. ISTREAM * pStream = pCCB->GetStream();
  1039. int Count = ITERATOR_GETCOUNT( *I );
  1040. int i;
  1041. CSzBuffer Buffer;
  1042. ENDPT_PAIR * pPair;
  1043. pStream->NewLine();
  1044. pStream->Write( "static RPC_PROTSEQ_ENDPOINT __RpcProtseqEndpoint[] = " );
  1045. pStream->IndentInc();
  1046. pStream->NewLine();
  1047. pStream->Write( '{' );
  1048. for( i = 0, ITERATOR_INIT( *I );
  1049. i < Count;
  1050. i++ )
  1051. {
  1052. ITERATOR_GETNEXT( *I, pPair );
  1053. pStream->NewLine();
  1054. pStream->Write( '{' );
  1055. Buffer.Set( "(unsigned char *) \"" );
  1056. Buffer.Append( pPair->pString1 );
  1057. Buffer.Append( "\", (unsigned char *) \"" );
  1058. Buffer.Append( pPair->pString2 );
  1059. Buffer.Append( "\"" );
  1060. pStream->Write( Buffer );
  1061. pStream->Write( '}' );
  1062. if( ITERATOR_PEEKTHIS( *I ) )
  1063. {
  1064. pStream->Write( ',' );
  1065. }
  1066. }
  1067. pStream->NewLine();
  1068. pStream->Write( "};" );
  1069. pStream->IndentDec();
  1070. pStream->NewLine();
  1071. }
  1072. void
  1073. Out_SetOperationBits(
  1074. CCB * pCCB,
  1075. unsigned int OpBits )
  1076. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1077. Routine Description:
  1078. Set the RPC operation flags.
  1079. Arguments:
  1080. pCCB - A pointer to the code generation controller block.
  1081. OpBits - Operation bits. These contain datagram related flags.
  1082. Return Value:
  1083. None.
  1084. Notes:
  1085. ----------------------------------------------------------------------------*/
  1086. {
  1087. ISTREAM * pStream = pCCB->GetStream();
  1088. pStream->NewLine();
  1089. if( OpBits != 0 )
  1090. {
  1091. char Buffer[ 512 ];
  1092. sprintf( Buffer, RPC_MESSAGE_VAR_NAME".RpcFlags = ( RPC_NCA_FLAGS_DEFAULT " );
  1093. if( OpBits & OPERATION_MAYBE )
  1094. {
  1095. strcat( Buffer, "| RPC_NCA_FLAGS_MAYBE" );
  1096. }
  1097. if( OpBits & OPERATION_BROADCAST )
  1098. {
  1099. strcat( Buffer, "| RPC_NCA_FLAGS_BROADCAST" );
  1100. }
  1101. if( OpBits & OPERATION_IDEMPOTENT )
  1102. {
  1103. strcat( Buffer, "| RPC_NCA_FLAGS_IDEMPOTENT" );
  1104. }
  1105. if( OpBits & OPERATION_INPUT_SYNC )
  1106. {
  1107. strcat( Buffer, "| RPCFLG_INPUT_SYNCHRONOUS" );
  1108. }
  1109. if( OpBits & OPERATION_MESSAGE )
  1110. {
  1111. strcat( Buffer, "| RPCFLG_MESSAGE" );
  1112. pCommand->GetNdrVersionControl().SetHasMessageAttr();
  1113. }
  1114. strcat( Buffer, " );" );
  1115. pStream->Write( Buffer );
  1116. }
  1117. }
  1118. void
  1119. Out_HandleInitialize(
  1120. CCB * pCCB,
  1121. ITERATOR& BindingParamList,
  1122. expr_node * ,
  1123. BOOL ,
  1124. unsigned short OpBits )
  1125. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1126. Routine Description:
  1127. Generate the call for initializing the stub message for a auto_handle
  1128. case.
  1129. Arguments:
  1130. pCCB - A pointer to the code generation controller block.
  1131. BindingParamList - List of params to the call.
  1132. pAssignExpr - if this param is non-null, assign the value of the
  1133. call to this.
  1134. fAuto - is this an auto handle call ?
  1135. OpBits - Operation bits. These contain datagram related flags.
  1136. Return Value:
  1137. None.
  1138. Notes:
  1139. ----------------------------------------------------------------------------*/
  1140. {
  1141. ISTREAM * pStream = pCCB->GetStream();
  1142. PNAME pName = CSTUB_INIT_RTN_NAME;
  1143. expr_proc_call * pProcCall = MakeProcCallOutOfParamExprList(
  1144. pName,
  1145. (node_skl *)0,
  1146. BindingParamList
  1147. );
  1148. pStream->NewLine();
  1149. pProcCall->PrintCall( pStream, 0, 0 );
  1150. pStream->NewLine();
  1151. Out_SetOperationBits(pCCB, OpBits);
  1152. }
  1153. void
  1154. Out_AutoHandleSendReceive(
  1155. CCB * pCCB,
  1156. expr_node * pDest,
  1157. expr_node * pProc )
  1158. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1159. Routine Description:
  1160. Emit code for an auto handle base send receive call.
  1161. Arguments:
  1162. pCCB - A pointer to the code gen controller block.
  1163. pDest - Optional destination for the result of the procedure call.
  1164. pProc - The procedure to call.
  1165. Return Value:
  1166. Notes:
  1167. If there are no output parameters, we wont pick up the returned
  1168. value of the send receive calls into the local variable for the
  1169. buffer length. In that case the pDest pointer will be null.
  1170. ----------------------------------------------------------------------------*/
  1171. {
  1172. ISTREAM * pStream = pCCB->GetStream();
  1173. expr_node * pExpr = pProc;
  1174. pStream->NewLine();
  1175. if( pDest )
  1176. {
  1177. pExpr = new expr_assign( pDest, pProc );
  1178. }
  1179. pExpr->PrintCall( pStream, 0, 0 );
  1180. }
  1181. void
  1182. Out_NormalSendReceive(
  1183. CCB * pCCB,
  1184. BOOL )
  1185. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1186. Routine Description:
  1187. Emit code for an auto handle base send receive call.
  1188. Arguments:
  1189. pCCB - A pointer to the code gen controller block.
  1190. fAnyOuts- Are there any out parameters at all ?
  1191. Return Value:
  1192. Notes:
  1193. If there are no output parameters, we wont pick up the returned
  1194. value of the send receive calls into the local variable for the
  1195. buffer length.
  1196. ----------------------------------------------------------------------------*/
  1197. {
  1198. ISTREAM * pStream = pCCB->GetStream();
  1199. CSzBuffer TempBuf;
  1200. pStream->NewLine();
  1201. //
  1202. // Call the send receive routine.
  1203. //
  1204. TempBuf.Set( NORMAL_SR_NDR_RTN_NAME );
  1205. TempBuf.Append( "( (PMIDL_STUB_MESSAGE) &" );
  1206. TempBuf.Append( STUB_MESSAGE_VAR_NAME );
  1207. TempBuf.Append( ", (unsigned char *)" );
  1208. TempBuf.Append( STUB_MSG_BUFFER_VAR_NAME );
  1209. TempBuf.Append( " );" );
  1210. pStream->Write( TempBuf );
  1211. }
  1212. void
  1213. Out_NormalFreeBuffer(
  1214. CCB * pCCB )
  1215. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1216. Routine Description:
  1217. Generate the free buffer with check for status.
  1218. Arguments:
  1219. Return Value:
  1220. Notes:
  1221. ----------------------------------------------------------------------------*/
  1222. {
  1223. ISTREAM * pStream = pCCB->GetStream();
  1224. expr_node * pExpr = pCCB->GetStandardResource(
  1225. ST_RES_STUB_MESSAGE_VARIABLE );
  1226. ITERATOR ParamList;
  1227. pStream->NewLine();
  1228. ITERATOR_INSERT( ParamList,
  1229. MakeAddressExpressionNoMatterWhat( pExpr )
  1230. );
  1231. pExpr = MakeProcCallOutOfParamExprList(
  1232. NORMAL_FB_NDR_RTN_NAME, // rtn name
  1233. (node_skl *)0, // type - dont care
  1234. ParamList // param list
  1235. );
  1236. // generate the procedure call.
  1237. pExpr->PrintCall( pStream, 0, 0 );
  1238. }
  1239. void
  1240. Out_IncludeOfFile(
  1241. CCB * pCCB,
  1242. PFILENAME p,
  1243. BOOL fAngleBrackets )
  1244. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1245. Routine Description:
  1246. Output a hash include of the given file.
  1247. Arguments:
  1248. pCCB - A pointer to the code generation controller block.
  1249. p - The ready to emit file name string.
  1250. fAngleBrackets - Do we want angle brackets or quotes (TRUE if anglebrackets)
  1251. Return Value:
  1252. None.
  1253. Notes:
  1254. ----------------------------------------------------------------------------*/
  1255. {
  1256. ISTREAM * pStream = pCCB->GetStream();
  1257. CSzBuffer TempBuf;
  1258. pStream->NewLine();
  1259. TempBuf.Set( "#include " );
  1260. TempBuf.Append( fAngleBrackets ? "<" : "\"" );
  1261. TempBuf.Append( p );
  1262. TempBuf.Append( fAngleBrackets ? ">" : "\"" );
  1263. pStream->Write( TempBuf );
  1264. }
  1265. void
  1266. Out_MKTYPLIB_Guid(
  1267. CCB * pCCB,
  1268. GUID_STRS & GStrs,
  1269. char * szPrefix,
  1270. char * szName )
  1271. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1272. Routine Description:
  1273. Output a MKTYPLIB style guid structure.
  1274. Arguments:
  1275. pCCB - A pointer to the code generation controller block.
  1276. pGString1 - Partial guid strings.
  1277. char * szName - name for the GUID
  1278. Return Value:
  1279. Notes:
  1280. No checks are made for the validity of the string. The front-end has done
  1281. that.
  1282. All strings are emitted with a leading 0x.
  1283. The 5 strings are treated this way:
  1284. 1 - 3. Emitted as such
  1285. 4 - 5. Broken into and emitted as byte hex values, without
  1286. transformation, so they are just picked up and written out.
  1287. ----------------------------------------------------------------------------*/
  1288. {
  1289. char TempBuf[256];
  1290. ISTREAM * pStream = pCCB->GetStream();
  1291. if ( !GStrs.str1 )
  1292. GStrs.str1 = "00000000";
  1293. if ( !GStrs.str2 )
  1294. GStrs.str2 = "0000";
  1295. if ( !GStrs.str3 )
  1296. GStrs.str3 = "0000";
  1297. if ( !GStrs.str4 )
  1298. GStrs.str4 = "00000000";
  1299. if ( !GStrs.str5 )
  1300. GStrs.str5 = "00000000";
  1301. pStream->Write( "DEFINE_GUID(" );
  1302. pStream->Write( szPrefix );
  1303. pStream->Write( szName );
  1304. pStream->Write( ',' );
  1305. sprintf( TempBuf, "0x%s,0x%s,0x%s", GStrs.str1, GStrs.str2, GStrs.str3 );
  1306. pStream->Write( TempBuf );
  1307. //
  1308. // Each of the above strings are just broken down into six 2 byte
  1309. // characters with 0x preceding them.
  1310. //
  1311. strcpy( TempBuf, GStrs.str4 );
  1312. strcat( TempBuf, GStrs.str5 );
  1313. pStream->Write( "," );
  1314. //
  1315. // We will use the iteration counter to index into the string. Since we
  1316. // need 2 per iteration, double the counter. Also pGString4 is actually
  1317. // a 16 bit qty.
  1318. //
  1319. for( int i = 0; i < (6+2)*2 ; i += 2 )
  1320. {
  1321. pStream->Write( "0x");
  1322. pStream->Write( TempBuf[ i ] );
  1323. pStream->Write( TempBuf[ i+1 ] );
  1324. if( i < (6+2)*2-2 )
  1325. pStream->Write( ',' );
  1326. }
  1327. pStream->Write( ");" );
  1328. pStream->NewLine();
  1329. }
  1330. void
  1331. Out_Guid(
  1332. CCB * pCCB,
  1333. GUID_STRS & GStrs,
  1334. GUIDFORMAT format)
  1335. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1336. Routine Description:
  1337. Output a guid structure.
  1338. Arguments:
  1339. pCCB - A pointer to the code generation controller block.
  1340. pGString1 - Partial guid strings.
  1341. format - Output format ( MIDL_DEFINE_GUID or const IID = )
  1342. Return Value:
  1343. Notes:
  1344. This routine emits a guid as a inited structure along with the proper
  1345. matched bracing.
  1346. No checks are made for the validity of the string. The front-end has done
  1347. that.
  1348. All strings are emitted with a leading 0x.
  1349. The 5 strings are treated this way:
  1350. 1 - 3. Emitted as such
  1351. 4 - 5. Broken into and emitted as byte hex values, without
  1352. transformation, so they are just picked up and written out.
  1353. ----------------------------------------------------------------------------*/
  1354. {
  1355. char TempBuf[ 256 ];
  1356. ISTREAM * pStream = pCCB->GetStream();
  1357. if ( !GStrs.str1 )
  1358. GStrs.str1 = "00000000";
  1359. if ( !GStrs.str2 )
  1360. GStrs.str2 = "0000";
  1361. if ( !GStrs.str3 )
  1362. GStrs.str3 = "0000";
  1363. if ( !GStrs.str4 )
  1364. GStrs.str4 = "00000000";
  1365. if ( !GStrs.str5 )
  1366. GStrs.str5 = "00000000";
  1367. if (GUIDFORMAT_RAW != format)
  1368. pStream->Write( '{' );
  1369. sprintf( TempBuf, "0x%s,0x%s,0x%s", GStrs.str1, GStrs.str2, GStrs.str3 );
  1370. pStream->Write( TempBuf );
  1371. //
  1372. // Each of the above strings are just broken down into six 2 byte
  1373. // characters with 0x preceding them.
  1374. //
  1375. strcpy( TempBuf, GStrs.str4 );
  1376. strcat( TempBuf, GStrs.str5 );
  1377. pStream->Write( "," );
  1378. if (GUIDFORMAT_RAW != format)
  1379. pStream->Write( "{" );
  1380. //
  1381. // We will use the iteration counter to index into the string. Since we
  1382. // need 2 per iteration, double the counter. Also pGString4 is actually
  1383. // a 16 bit qty.
  1384. //
  1385. for( int i = 0; i < (6+2)*2 ; i += 2 )
  1386. {
  1387. pStream->Write( "0x");
  1388. pStream->Write( TempBuf[ i ] );
  1389. pStream->Write( TempBuf[ i+1 ] );
  1390. if( i < (6+2)*2-2 )
  1391. pStream->Write( ',' );
  1392. }
  1393. if (GUIDFORMAT_RAW != format)
  1394. pStream->Write( "}}" );
  1395. }
  1396. void
  1397. Out_IFInfo(
  1398. CCB * pCCB,
  1399. char * pIntInfoTypeName,
  1400. char * pIntInfoVarName,
  1401. char * pIntInfoSizeOfString,
  1402. GUID_STRS & UserGuidStr,
  1403. unsigned short UserMajor,
  1404. unsigned short UserMinor,
  1405. // GUID_STRS & XferGuidStr,
  1406. // unsigned short XferSynMajor,
  1407. // unsigned short XferSynMinor,
  1408. char * pCallbackDispatchTable,
  1409. int ProtSeqEPCount,
  1410. char * ,
  1411. char * ,
  1412. BOOL fNoDefaultEpv,
  1413. BOOL fSide,
  1414. BOOL fHasPipes
  1415. )
  1416. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1417. Routine Description:
  1418. Arguments:
  1419. pCCB - Ptr to code gen controller block.
  1420. pIntInfoTypeName - Client InterfaceInfo type name string.
  1421. pIntInfoVarName - Client InterfaceInfo variable name string.
  1422. pIntInfoSizeOfString - string sizeof interface.
  1423. UserGuidStr - User specified Guid string components.
  1424. UserMajor - User specified major interface version
  1425. UserMinor - User specified minor interface version
  1426. XferGuidStr - Xfer syntax identifying Guid string components.
  1427. XferSynMajor - Transfre syntax major version
  1428. XferSynMinor - Transfre syntax minor version
  1429. pCallbackDispatchTable - A pointer to the call back dispatch table name.
  1430. ProtSeqEPCount - ProtSeq endpoint count.
  1431. ProtSeqEPTypeName - Protseq endpoint Type name.
  1432. ProtSeqEPVarName - Protseq endpoint variable name.
  1433. fNoDefaultEpv - No default epv switch specicied.
  1434. fSide - The server side (1) or client side(0)
  1435. fHasPipes - TRUE if any proc in the Interface has pipes
  1436. Return Value:
  1437. None.
  1438. Notes:
  1439. I'm tired already specifying so many params !
  1440. ----------------------------------------------------------------------------*/
  1441. {
  1442. CSzBuffer TempBuf;
  1443. ISTREAM * pStream = pCCB->GetStream();
  1444. unsigned int RpcIntfFlag = 0;
  1445. pStream->NewLine( 2 );
  1446. TempBuf.Set( "static const " );
  1447. TempBuf.Append( pIntInfoTypeName );
  1448. TempBuf.Append( " " );
  1449. TempBuf.Append( pCCB->GetInterfaceName() );
  1450. TempBuf.Append( pIntInfoVarName );
  1451. TempBuf.Append( " =" );
  1452. pStream->Write( TempBuf );
  1453. pStream->IndentInc();
  1454. pStream->NewLine();
  1455. pStream->Write( '{' );
  1456. pStream->NewLine();
  1457. TempBuf.Set( pIntInfoSizeOfString );
  1458. TempBuf.Append( "," );
  1459. pStream->Write( TempBuf );
  1460. //
  1461. // Emit the guid.
  1462. //
  1463. pStream->NewLine();
  1464. pStream->Write( '{' );
  1465. Out_Guid( pCCB,
  1466. UserGuidStr
  1467. );
  1468. //
  1469. // Emit the interface version specified by the user.
  1470. //
  1471. TempBuf.Set( ",{" );
  1472. TempBuf.Append( UserMajor );
  1473. TempBuf.Append( "," );
  1474. TempBuf.Append( UserMinor );
  1475. TempBuf.Append( "}" );
  1476. pStream->Write( TempBuf );
  1477. pStream->Write( "}," );
  1478. //
  1479. // Emit the xfer syntax guid.
  1480. //
  1481. pStream->NewLine();
  1482. if ( pCommand->GetDefaultSyntax() == SYNTAX_DCE )
  1483. Out_TransferSyntax( pCCB,
  1484. TransferSyntaxGuidStrs, // ndr identifying guid.
  1485. NDR_UUID_MAJOR_VERSION, // ndr's version
  1486. NDR_UUID_MINOR_VERSION );
  1487. else
  1488. {
  1489. if ( pCommand->IsSwitchDefined( SWITCH_INTERNAL ) &&
  1490. pCommand->GetEnv() == ENV_WIN32 )
  1491. Out_TransferSyntax( pCCB,
  1492. FakeNDR64TransferSyntaxGuidStrs,
  1493. NDR64_UUID_MAJOR_VERSION,
  1494. NDR64_UUID_MINOR_VERSION );
  1495. else
  1496. Out_TransferSyntax( pCCB,
  1497. NDR64TransferSyntaxGuidStrs, // ndr identifying guid.
  1498. NDR64_UUID_MAJOR_VERSION, // ndr's version
  1499. NDR64_UUID_MINOR_VERSION );
  1500. }
  1501. pStream->Write( ',' );
  1502. //
  1503. // Emit the callback dispatch table address, if none, emit a NULL
  1504. //
  1505. pStream->NewLine();
  1506. if( pCallbackDispatchTable )
  1507. {
  1508. pStream->Write( pCallbackDispatchTable );
  1509. }
  1510. else
  1511. {
  1512. pStream->Write( '0' );
  1513. }
  1514. pStream->Write( ',' );
  1515. //
  1516. // If there is a protseq ep count, emit a pointer to the ep table
  1517. // else emit a null.
  1518. //
  1519. pStream->NewLine();
  1520. if( ProtSeqEPCount )
  1521. {
  1522. TempBuf.Set(",");
  1523. TempBuf.Prepend(ProtSeqEPCount);
  1524. // sprintf( TempBuf, "%d,", ProtSeqEPCount );
  1525. pStream->Write( TempBuf );
  1526. pStream->NewLine();
  1527. pStream->Write( "__RpcProtseqEndpoint," );
  1528. }
  1529. else
  1530. {
  1531. pStream->Write( "0," );
  1532. pStream->NewLine();
  1533. pStream->Write( "0," );
  1534. }
  1535. pStream->NewLine();
  1536. if( fNoDefaultEpv )
  1537. {
  1538. if( fSide == 1 )
  1539. {
  1540. TempBuf.Set( "(" );
  1541. TempBuf.Append( pCCB->GetInterfaceName() );
  1542. TempBuf.Append( pCCB->GenMangledName() );
  1543. TempBuf.Append( "_" );
  1544. TempBuf.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  1545. TempBuf.Append( " *) " );
  1546. TempBuf.Append( "0xffffffff" );
  1547. pStream->Write( TempBuf );
  1548. }
  1549. else
  1550. {
  1551. pStream->Write( '0' );
  1552. }
  1553. }
  1554. else if( pCCB->IsMEpV() )
  1555. {
  1556. if( fSide == 1)
  1557. pStream->Write( "&DEFAULT_EPV" );
  1558. else
  1559. pStream->Write( '0' );
  1560. }
  1561. else
  1562. {
  1563. pStream->Write('0');
  1564. }
  1565. //
  1566. // Intepreter info.
  1567. //
  1568. pStream->Write( ',' );
  1569. pStream->NewLine();
  1570. if ( ( pCCB->GetCodeGenSide() == CGSIDE_SERVER &&
  1571. pCCB->GetInterfaceCG()->HasInterpretedProc() ) ||
  1572. ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT &&
  1573. pCCB->GetInterfaceCG()->HasInterpretedCallbackProc() ) )
  1574. {
  1575. RpcIntfFlag |= RPCFLG_HAS_CALLBACK;
  1576. pStream->Write( '&' );
  1577. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  1578. pStream->Write( SERVER_INFO_VAR_NAME );
  1579. }
  1580. else if ( pCommand->NeedsNDR64Run() )
  1581. {
  1582. pStream->Write( '&' );
  1583. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  1584. pStream->Write( MIDL_PROXY_INFO_VAR_NAME );
  1585. }
  1586. else
  1587. {
  1588. pStream->Write( '0' );
  1589. }
  1590. //
  1591. // Emit flags
  1592. //
  1593. pStream->Write( ',' );
  1594. pStream->NewLine();
  1595. if (fHasPipes)
  1596. {
  1597. RpcIntfFlag |= RPC_INTERFACE_HAS_PIPES;
  1598. }
  1599. if ( pCommand->NeedsBothSyntaxes() )
  1600. {
  1601. RpcIntfFlag |= RPCFLG_HAS_MULTI_SYNTAXES;
  1602. }
  1603. pStream->WriteNumber( "0x%08x",(unsigned long )RpcIntfFlag );
  1604. //
  1605. // All Done. Phew !!
  1606. //
  1607. pStream->NewLine();
  1608. pStream->Write( "};" );
  1609. pStream->IndentDec();
  1610. }
  1611. void Out_OneSyntaxInfo( CCB * pCCB,
  1612. BOOL IsForCallback,
  1613. SYNTAX_ENUM syntaxType )
  1614. {
  1615. ISTREAM *pStream = pCCB->GetStream();
  1616. char Buffer[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT+1];
  1617. pStream->Write( "{" );
  1618. pStream->NewLine();
  1619. if ( syntaxType == SYNTAX_NDR64 )
  1620. {
  1621. if ( pCommand->IsSwitchDefined( SWITCH_INTERNAL ) &&
  1622. pCommand->GetEnv() == ENV_WIN32 )
  1623. Out_TransferSyntax( pCCB,
  1624. FakeNDR64TransferSyntaxGuidStrs,
  1625. NDR64_UUID_MAJOR_VERSION,
  1626. NDR64_UUID_MINOR_VERSION );
  1627. else
  1628. Out_TransferSyntax( pCCB,
  1629. NDR64TransferSyntaxGuidStrs,
  1630. NDR64_UUID_MAJOR_VERSION,
  1631. NDR64_UUID_MINOR_VERSION );
  1632. }
  1633. if ( syntaxType == SYNTAX_DCE )
  1634. Out_TransferSyntax( pCCB,
  1635. TransferSyntaxGuidStrs,
  1636. NDR_UUID_MAJOR_VERSION,
  1637. NDR_UUID_MINOR_VERSION );
  1638. pStream->Write( ',' );
  1639. // yongqu: DispatchTable: we need only one dispatch table for now.
  1640. // we need to generate dispatch table for syntax_info in MIDL_SERVER_INFO, where
  1641. // runtime will use it to dispatch call. This include regular server side syntaxinfo
  1642. // and client side callback syntax info.
  1643. if ( ! pCCB->GetInterfaceCG()->IsObject() &&
  1644. ( ( ( pCCB->GetCodeGenSide() == CGSIDE_SERVER ) && !IsForCallback ) ||
  1645. ( ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT ) && IsForCallback ) ) )
  1646. {
  1647. pStream->WriteOnNewLine( "&" );
  1648. sprintf( Buffer,
  1649. "%s%s%s%_DispatchTable,",
  1650. pCCB->GetInterfaceName(),
  1651. ( syntaxType == SYNTAX_NDR64 )?"_NDR64_":"",
  1652. pCCB->GenMangledName() );
  1653. pStream->Write(Buffer );
  1654. }
  1655. else
  1656. pStream->WriteOnNewLine( "0," );
  1657. pStream->NewLine();
  1658. // proc format string.
  1659. if ( syntaxType == SYNTAX_DCE )
  1660. {
  1661. pStream->Write( PROC_FORMAT_STRING_STRING_FIELD );
  1662. }
  1663. else
  1664. {
  1665. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  1666. }
  1667. pStream->Write( ',' );
  1668. pStream->NewLine();
  1669. // The reference to the proc offset table
  1670. if ( SYNTAX_NDR64 == syntaxType)
  1671. pStream->Write( "(unsigned short *) " );
  1672. if ( pCCB->GetInterfaceCG()->IsObject() )
  1673. pStream->Write( '&' );
  1674. if ( IsForCallback )
  1675. pStream->Write( MIDL_CALLBACK_VAR_NAME );
  1676. pStream->Write( pCCB->GetInterfaceCG()->GetSymName() );
  1677. if ( syntaxType == SYNTAX_DCE )
  1678. pStream->Write( FORMAT_STRING_OFFSET_TABLE_NAME );
  1679. else
  1680. pStream->Write( "_Ndr64ProcTable" );
  1681. if ( pCCB->GetInterfaceCG()->IsObject() )
  1682. pStream->Write( "[-3]," );
  1683. else
  1684. pStream->Write( ',' );
  1685. pStream->NewLine();
  1686. //
  1687. if ( syntaxType == SYNTAX_DCE )
  1688. {
  1689. pStream->Write( FORMAT_STRING_STRING_FIELD );
  1690. }
  1691. else
  1692. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  1693. pStream->Write( ',' );
  1694. // TODO: Usermarshal routines?
  1695. pStream->NewLine();
  1696. if ( pCCB->HasQuadrupleRoutines() )
  1697. {
  1698. if ( syntaxType == SYNTAX_DCE )
  1699. pStream->Write( USER_MARSHAL_ROUTINE_TABLE_VAR );
  1700. else
  1701. pStream->Write( NDR64_USER_MARSHAL_ROUTINE_TABLE_VAR );
  1702. pStream->Write( "," );
  1703. }
  1704. else
  1705. pStream->Write( "0," );
  1706. pStream->WriteOnNewLine( "0," );
  1707. pStream->WriteOnNewLine( "0" );
  1708. pStream->NewLine();
  1709. pStream->Write( "}" );
  1710. pStream->NewLine();
  1711. }
  1712. // separate out because this is being called from multiple places.
  1713. void
  1714. Out_TransferSyntax(
  1715. CCB * pCCB,
  1716. GUID_STRS & XferGuidStr,
  1717. unsigned short XferSynMajor,
  1718. unsigned short XferSynMinor )
  1719. {
  1720. CSzBuffer TempBuf;
  1721. ISTREAM *pStream = pCCB->GetStream();
  1722. pStream->Write( '{' );
  1723. Out_Guid( pCCB,
  1724. XferGuidStr
  1725. );
  1726. //
  1727. // Emit the interface version specified by the user.
  1728. //
  1729. TempBuf.Set( ",{" );
  1730. TempBuf.Append( XferSynMajor );
  1731. TempBuf.Append( "," );
  1732. TempBuf.Append( XferSynMinor );
  1733. TempBuf.Append( "}" );
  1734. pStream->Write( TempBuf );
  1735. pStream->Write( "}" );
  1736. }
  1737. void
  1738. Out_MarshallSimple(
  1739. CCB * pCCB,
  1740. RESOURCE * pResource,
  1741. node_skl * pType,
  1742. expr_node * pSource,
  1743. BOOL fIncr,
  1744. unsigned short Size )
  1745. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1746. Routine Description:
  1747. Generate marshalling for a type of a given alignment.
  1748. Arguments:
  1749. pCCB - A pointer to the code generation controller block.
  1750. pResource - The marshalling buffer pointer resource.
  1751. pType - A pointer to the type of the entity being marshalled.
  1752. pSource - A pointer to the expression representing the source of
  1753. the marshalling.
  1754. fIncr - Output pointer increment code.
  1755. Size - The target alignment.
  1756. Return Value:
  1757. Notes:
  1758. ----------------------------------------------------------------------------*/
  1759. {
  1760. BOOL fUnsigned = pType->FInSummary( ATTR_UNSIGNED );
  1761. CSzBuffer TempBuf;
  1762. ISTREAM * pStream = pCCB->GetStream();
  1763. char * pRtn;
  1764. switch( Size )
  1765. {
  1766. case 1: pRtn = "char"; break;
  1767. case 2: pRtn = "short"; break;
  1768. case 4: pRtn = "long"; break;
  1769. case 8: pRtn = "hyper";break;
  1770. default: break;
  1771. }
  1772. pStream->NewLine();
  1773. TempBuf.Set( "*((" );
  1774. if (fUnsigned)
  1775. TempBuf.Append( "unsigned " );
  1776. TempBuf.Append( pRtn );
  1777. TempBuf.Append( "*)" );
  1778. TempBuf.Append( pResource->GetResourceName() );
  1779. TempBuf.Append( ")" );
  1780. if (fIncr)
  1781. TempBuf.Append( "++" );
  1782. TempBuf.Append( " = " );
  1783. pStream->Write( TempBuf );
  1784. pSource->Print( pStream );
  1785. pStream->Write(';');
  1786. }
  1787. void
  1788. Out_AddToBufferPointer(
  1789. CCB * pCCB,
  1790. expr_node * pSource,
  1791. expr_node * pExprAmount )
  1792. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1793. Routine Description:
  1794. Generate a force alignment by the specified alignment.
  1795. Arguments:
  1796. pCCB - A pointer to the code generation controller block.
  1797. pSource - A source pointer
  1798. pExprAmount - The amount to add
  1799. Return Value:
  1800. Notes:
  1801. ----------------------------------------------------------------------------*/
  1802. {
  1803. ISTREAM * pStream = pCCB->GetStream();
  1804. expr_node * pExpr;
  1805. pStream->NewLine();
  1806. pExpr = new expr_b_arithmetic( OP_PLUS,
  1807. pSource,
  1808. pExprAmount
  1809. );
  1810. pExpr = new expr_assign( pSource, pExpr );
  1811. pExpr->Print( pStream );
  1812. pStream->Write(';');
  1813. }
  1814. void
  1815. Out_DispatchTableStuff(
  1816. CCB * pCCB,
  1817. ITERATOR& ProcList,
  1818. short CountOfProcs)
  1819. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1820. Routine Description:
  1821. Generate the dispatch table and related data structures.
  1822. Arguments:
  1823. pCCB - A pointer to the code generation controller block.
  1824. ProcList - A list of all the procedure names in the dispatch table.
  1825. CountOfProcs- The number of procedures in the list.
  1826. Return Value:
  1827. None.
  1828. Notes:
  1829. Generate the dispatch table entries and then the dispatch table stuff.
  1830. ----------------------------------------------------------------------------*/
  1831. {
  1832. // if ( !pCommand->IsFinalProtocolRun() )
  1833. // return;
  1834. ISTREAM * pStream = pCCB->GetStream();
  1835. CSzBuffer TempBuf;
  1836. unsigned short M, m;
  1837. pStream->NewLine();
  1838. //
  1839. // Generate the dispatch table structure name. Currently we just do
  1840. // simple name mangling. This needs to be changed for dce stuff.
  1841. //
  1842. TempBuf.Set( "static " );
  1843. TempBuf.Append( RPC_DISPATCH_FUNCTION_TYPE_NAME );
  1844. TempBuf.Append( " " );
  1845. TempBuf.Append( pCCB->GetInterfaceName() );
  1846. if ( pCommand->IsNDR64Run() )
  1847. TempBuf.Append( "_NDR64_" );
  1848. TempBuf.Append( "_table[] =" );
  1849. pStream->Write( TempBuf );
  1850. pStream->IndentInc();
  1851. pStream->NewLine();
  1852. pStream->Write('{');
  1853. pStream->NewLine();
  1854. //
  1855. // Now print out the names of all the procedures.
  1856. //
  1857. ITERATOR_INIT( ProcList );
  1858. for( int i = 0; i < CountOfProcs; ++i )
  1859. {
  1860. DISPATCH_TABLE_ENTRY * p;
  1861. node_skl * pNode;
  1862. ITERATOR_GETNEXT( ProcList, p );
  1863. if ( p->Flags & DTF_PICKLING_PROC )
  1864. pStream->Write( '0' );
  1865. // BUGBUG: yongqu: code cleanup needed.
  1866. // -----------------------------------------------------------------
  1867. // Server dispatch routine names:
  1868. // raw rpc:
  1869. // sync interface
  1870. // ndr64 only: NdrServerCallNdr64
  1871. // ndr20 only: NdrServerCall2
  1872. // both syntaxes: NdrServerCallAll
  1873. // async interface
  1874. // ndr64 only: Ndr64AsyncServerCall64
  1875. // ndr20 only: NdrAsyncServerCall
  1876. // both syntaxes: Ndr64AsyncServerCallAll
  1877. // ORPC:
  1878. // sync interface
  1879. // ndr64 only: NdrStubCall3
  1880. // both syntaxes: NdrStubCall3
  1881. // ndr20 only: NdrStubCall2
  1882. // async interface
  1883. // ndr64 only: NdrDcomAsyncStubCall
  1884. // ndr20 only: NdrDcomAsyncStubCall
  1885. // both syntaxes: NdrDcomAsyncStubCall
  1886. //
  1887. // reason for so many different entries:
  1888. // In raw RPC, there is one dispatch table for each transfer syntax. RPC runtime
  1889. // will call into the right dispatch table according to the syntax being used.
  1890. // for raw rpc interface, we want to improvement server performance.
  1891. // after runtime select the right transfer syntax and called into
  1892. // right dispatch table, we know where MIDL_SYNTAX_INFO is and we can
  1893. // pickup the right format string etc. directly.
  1894. //
  1895. // In ORPC, all calls will be forwarded to the stub's Invoke, so we don't know
  1896. // which transfer syntax is being used when ole dispatch the call to engine.
  1897. // we need to find out the selected syntax anyway.
  1898. //
  1899. // ------------------------------------------------------------------
  1900. #ifndef TEMPORARY_OI_SERVER_STUBS
  1901. else if ( p->Flags & DTF_INTERPRETER )
  1902. {
  1903. if ( ((node_proc *)p->pNode)->HasAsyncUUID() )
  1904. {
  1905. if ( pCommand->IsNDR64Run() )
  1906. pStream->Write( S_NDR64_CALL_RTN_NAME_DCOM_ASYNC );
  1907. else
  1908. pStream->Write( S_NDR_CALL_RTN_NAME_DCOM_ASYNC );
  1909. }
  1910. else if ( ((node_proc *)p->pNode)->HasAsyncHandle() )
  1911. {
  1912. if ( pCommand->IsNDR64Run() )
  1913. {
  1914. if ( pCommand->NeedsBothSyntaxes() )
  1915. pStream->Write( S_ALL_CALL_RTN_NAME_ASYNC );
  1916. else
  1917. pStream->Write( S_NDR64_CALL_RTN_NAME_ASYNC );
  1918. }
  1919. else
  1920. pStream->Write( S_NDR_CALL_RTN_NAME_ASYNC );
  1921. }
  1922. else if ( ((node_proc *)p->pNode)->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
  1923. {
  1924. if ( pCommand->IsNDR64Run() )
  1925. {
  1926. if ( pCommand->NeedsBothSyntaxes() )
  1927. pStream->Write( S_ALL_CALL_RTN_NAME );
  1928. else
  1929. pStream->Write( S_NDR64_CALL_RTN_NAME );
  1930. }
  1931. else
  1932. pStream->Write( S_NDR_CALL_RTN_NAME_V2 );
  1933. }
  1934. else
  1935. pStream->Write( S_NDR_CALL_RTN_NAME );
  1936. }
  1937. #endif // TEMPORARY_OI_SERVER_STUBS
  1938. else
  1939. {
  1940. pNode = p->pNode;
  1941. TempBuf.Set( pCCB->GetInterfaceName() );
  1942. TempBuf.Append( "_" );
  1943. TempBuf.Append( pNode->GetSymName() );
  1944. pStream->Write( TempBuf );
  1945. }
  1946. pStream->Write( ',' );
  1947. pStream->NewLine();
  1948. }
  1949. //
  1950. // Write out a null and the closing brace.
  1951. //
  1952. pStream->Write( '0' ); pStream->NewLine();
  1953. pStream->Write( "};" );
  1954. pStream->IndentDec();
  1955. //
  1956. // Write out the dispatch table.
  1957. //
  1958. pCCB->GetVersion( &M, &m );
  1959. pStream->NewLine();
  1960. TempBuf.Set( RPC_DISPATCH_TABLE_TYPE_NAME );
  1961. TempBuf.Append( " " );
  1962. TempBuf.Append( pCCB->GetInterfaceName() );
  1963. if ( pCommand->IsNDR64Run() )
  1964. TempBuf.Append( "_NDR64_" );
  1965. TempBuf.Append( pCCB->GenMangledName() );
  1966. TempBuf.Append( "_DispatchTable = " );
  1967. pStream->Write( TempBuf );
  1968. pStream->IndentInc();
  1969. pStream->NewLine();
  1970. pStream->Write( '{' );
  1971. pStream->NewLine();
  1972. TempBuf.Set( "" );
  1973. TempBuf.Append( CountOfProcs );
  1974. TempBuf.Append( "," );
  1975. pStream->Write( TempBuf );
  1976. pStream->NewLine();
  1977. TempBuf.Set( pCCB->GetInterfaceName() );
  1978. if ( pCommand->IsNDR64Run() )
  1979. TempBuf.Append( "_NDR64_" );
  1980. TempBuf.Append( "_table" );
  1981. pStream->Write( TempBuf ); pStream->NewLine(); pStream->Write( "};" );
  1982. pStream->IndentDec();
  1983. pStream->NewLine();
  1984. }
  1985. void
  1986. Out_CallManager(
  1987. CCB * pCCB,
  1988. expr_proc_call * pProcExpr,
  1989. expr_node * pRet,
  1990. BOOL fIsCallback )
  1991. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1992. Routine Description:
  1993. Generate a call to the manager routine.
  1994. Arguments:
  1995. pCCB - A pointer to the code generation controller block.
  1996. pProcExpr - A pointer to the complete procedure expression.
  1997. pRet - An optional pointer to ther return variable.
  1998. fIsCallback - Is this a callback proc ?
  1999. Return Value:
  2000. None.
  2001. Notes:
  2002. Emit code to check for the manager epv also.
  2003. ----------------------------------------------------------------------------*/
  2004. {
  2005. expr_node * pAss = pProcExpr;
  2006. expr_node * pExpr;
  2007. CSzBuffer Buffer;
  2008. ISTREAM * pStream = pCCB->GetStream();
  2009. unsigned short M, m;
  2010. char * pTemp;
  2011. short Indent = 0;
  2012. pCCB->GetStream()->NewLine();
  2013. // If he specified the -epv flag, then dont generate the call to the
  2014. // static procedure. This is the opposite of the dce functionality.
  2015. //
  2016. // In case of -epv:
  2017. // ((interface_...) -> proc( ... );
  2018. // else
  2019. // proc ( ... );
  2020. //
  2021. if( pCCB->IsMEpV() && !fIsCallback )
  2022. {
  2023. pCCB->GetVersion( &M, &m );
  2024. Buffer.Set( "((" );
  2025. Buffer.Append( pCCB->GetInterfaceName() );
  2026. Buffer.Append( pCCB->GenMangledName() );
  2027. Buffer.Append( "_" );
  2028. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2029. Buffer.Append( " *)(" );
  2030. Buffer.Append( PRPC_MESSAGE_MANAGER_EPV_NAME );
  2031. Buffer.Append( "))" );
  2032. pTemp = new char [ strlen( Buffer ) + 1 ];
  2033. strcpy( pTemp, Buffer );
  2034. pExpr = new expr_variable( pTemp );//this has the rhs expr for the
  2035. // manager epv call. Sneaky !
  2036. pExpr = new expr_pointsto( pExpr, pProcExpr );
  2037. pAss = pExpr;
  2038. if( pRet )
  2039. {
  2040. pAss = new expr_assign( pRet, pExpr );
  2041. Indent = 7; // sizeof "_RetVal"
  2042. }
  2043. pStream->NewLine();
  2044. }
  2045. else
  2046. {
  2047. pAss = pProcExpr;
  2048. if( pRet )
  2049. {
  2050. pAss = new expr_assign( pRet, pProcExpr );
  2051. Indent = 7; // sizeof "_RetVal"
  2052. }
  2053. pStream->NewLine();
  2054. }
  2055. pAss->PrintCall( pStream, Indent, 0 );
  2056. }
  2057. void
  2058. Out_FormatInfoExtern( CCB * pCCB )
  2059. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2060. Routine Description:
  2061. Generates the forward extern declaration for the FormatInfo.
  2062. (64bit format string)
  2063. Arguments:
  2064. pCCB - A pointer to the code generation controller block.
  2065. Return Value:
  2066. None.
  2067. Notes:
  2068. ----------------------------------------------------------------------------*/
  2069. {
  2070. ISTREAM * pStream = pCCB->GetStream();
  2071. if ( pCommand->NeedsNDR64Run() )
  2072. {
  2073. pStream->NewLine();
  2074. // BUGBUG: We really don't need this anymore.
  2075. pStream->WriteOnNewLine(
  2076. "static const int NDR64_MIDL_FORMATINFO = 0;" );
  2077. }
  2078. }
  2079. void
  2080. Out_TypeFormatStringExtern( CCB * pCCB )
  2081. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2082. Routine Description:
  2083. Generates the forward extern declaration of the global type format string.
  2084. Arguments:
  2085. pCCB - A pointer to the code generation controller block.
  2086. Return Value:
  2087. None.
  2088. Notes:
  2089. ----------------------------------------------------------------------------*/
  2090. {
  2091. ISTREAM * pStream = pCCB->GetStream();
  2092. if ( pCommand->NeedsNDRRun() )
  2093. {
  2094. pStream->NewLine( 1 );
  2095. pStream->Write( "extern const " FORMAT_STRING_TYPE_NAME " " );
  2096. pStream->Write( FORMAT_STRING_STRUCT_NAME ";" );
  2097. }
  2098. }
  2099. void
  2100. Out_ProcFormatStringExtern( CCB * pCCB )
  2101. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2102. Routine Description:
  2103. Generates the forward extern declaration of the interface-wide
  2104. procedure/parameter format string.
  2105. Arguments:
  2106. pCCB - A pointer to the code generation controller block.
  2107. Return Value:
  2108. None.
  2109. Notes:
  2110. ----------------------------------------------------------------------------*/
  2111. {
  2112. ISTREAM * pStream = pCCB->GetStream();
  2113. if ( pCommand->NeedsNDRRun() )
  2114. {
  2115. pStream->NewLine( 1 );
  2116. pStream->Write( "extern const " PROC_FORMAT_STRING_TYPE_NAME " " );
  2117. pStream->Write( PROC_FORMAT_STRING_STRUCT_NAME ";" );
  2118. }
  2119. }
  2120. void
  2121. Out_StubDescriptorExtern(
  2122. CCB * pCCB )
  2123. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2124. Routine Description:
  2125. Generates the forward extern declaration of the global stub descriptor
  2126. variable.
  2127. Arguments:
  2128. pCCB - A pointer to the code generation controller block.
  2129. Return Value:
  2130. None.
  2131. Notes:
  2132. ----------------------------------------------------------------------------*/
  2133. {
  2134. ISTREAM * pStream = pCCB->GetStream();
  2135. pStream->NewLine( 2 );
  2136. pStream->Write( "extern const " STUB_DESC_STRUCT_TYPE_NAME );
  2137. pStream->Write( ' ' );
  2138. pStream->Write( pCCB->GetInterfaceCG()->GetStubDescName() );
  2139. pStream->Write( ';' );
  2140. pStream->NewLine();
  2141. }
  2142. void
  2143. Out_ProxyInfoExtern( CCB * pCCB )
  2144. {
  2145. ISTREAM * pStream = pCCB->GetStream();
  2146. pStream->NewLine();
  2147. pStream->Write( " extern const " MIDL_PROXY_INFO_TYPE_NAME );
  2148. pStream->Write( ' ' );
  2149. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  2150. pStream->Write( MIDL_PROXY_INFO_VAR_NAME );
  2151. pStream->Write( ';' );
  2152. }
  2153. void
  2154. Out_InterpreterServerInfoExtern( CCB * pCCB )
  2155. {
  2156. ISTREAM * pStream;
  2157. pStream = pCCB->GetStream();
  2158. pStream->NewLine( 2 );
  2159. pStream->Write( "extern const " SERVER_INFO_TYPE_NAME );
  2160. pStream->Write( ' ' );
  2161. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  2162. pStream->Write( SERVER_INFO_VAR_NAME );
  2163. pStream->Write( ';' );
  2164. }
  2165. void
  2166. Out_NdrMarshallCall( CCB * pCCB,
  2167. char * pRoutineName,
  2168. char * pParamName,
  2169. long FormatStringOffset,
  2170. BOOL fTakeAddress,
  2171. BOOL fDereference )
  2172. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2173. Routine Description:
  2174. Ouputs a call to an Ndr marshalling routine.
  2175. Arguments:
  2176. pStream - the stream to write the output to
  2177. pRoutineName - the routine name (without the trailing "Marshall")
  2178. pParamName - the name of the parameter/variable being marshalled
  2179. FormatStringOffset - the offset into the format string where this
  2180. parameter's/variable's description begins
  2181. Return Value:
  2182. None.
  2183. Notes:
  2184. ----------------------------------------------------------------------------*/
  2185. {
  2186. ISTREAM * pStream = pCCB->GetStream();
  2187. unsigned short Spaces;
  2188. char Buf[80];
  2189. pStream->NewLine();
  2190. Spaces = (unsigned short)(strlen(pRoutineName) + 10); // strlen("Marshall( ");
  2191. pStream->Write( pRoutineName );
  2192. pStream->Write( "Marshall( (PMIDL_STUB_MESSAGE)& "STUB_MESSAGE_VAR_NAME"," );
  2193. pStream->NewLine();
  2194. pStream->Spaces( Spaces );
  2195. pStream->Write( "(unsigned char *)" );
  2196. if ( fTakeAddress )
  2197. pStream->Write( '&' );
  2198. if ( fDereference )
  2199. pStream->Write( '*' );
  2200. pStream->Write( pParamName );
  2201. pStream->Write( ',' );
  2202. pStream->NewLine();
  2203. pStream->Spaces( Spaces );
  2204. pStream->Write( "(PFORMAT_STRING) &" );
  2205. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2206. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2207. pStream->Write( Buf );
  2208. pStream->NewLine();
  2209. }
  2210. void
  2211. Out_NdrUnmarshallCall( CCB * pCCB,
  2212. char * pRoutineName,
  2213. char * pParamName,
  2214. long FormatStringOffset,
  2215. BOOL fTakeAddress,
  2216. BOOL fMustAllocFlag )
  2217. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2218. Routine Description:
  2219. Outputs a call to an Ndr unmarshalling routine.
  2220. Arguments:
  2221. pStream - the stream to write the output to
  2222. pRoutineName - the routine name (without the trailing "Unmarshall")
  2223. pParamName - the name of the parameter/variable being unmarshalled
  2224. FormatStringOffset - the offset into the format string where this
  2225. parameter's/variable's description begins
  2226. Return Value:
  2227. None.
  2228. Notes:
  2229. ----------------------------------------------------------------------------*/
  2230. {
  2231. ISTREAM * pStream = pCCB->GetStream();
  2232. unsigned short Spaces = 0;
  2233. char Buf[80];
  2234. pStream->NewLine();
  2235. Spaces = (unsigned short)(strlen(pRoutineName) + 12); // strlen("Unmarshall( ");
  2236. pStream->Write( pRoutineName );
  2237. pStream->Write( "Unmarshall( (PMIDL_STUB_MESSAGE) &"STUB_MESSAGE_VAR_NAME"," );
  2238. pStream->NewLine();
  2239. pStream->Spaces( Spaces );
  2240. pStream->Write( "(unsigned char * *)" );
  2241. if ( fTakeAddress )
  2242. pStream->Write( '&' );
  2243. pStream->Write( pParamName );
  2244. pStream->Write( ',' );
  2245. pStream->NewLine();
  2246. pStream->Spaces( Spaces );
  2247. pStream->Write( "(PFORMAT_STRING) &" );
  2248. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2249. sprintf( Buf, ".Format[%d],", FormatStringOffset );
  2250. pStream->Write( Buf );
  2251. pStream->NewLine();
  2252. pStream->Spaces( Spaces );
  2253. pStream->Write( "(unsigned char)" );
  2254. pStream->Write( fMustAllocFlag ? "1" : "0" );
  2255. pStream->Write( " );" );
  2256. pStream->NewLine();
  2257. }
  2258. void
  2259. Out_NdrBufferSizeCall( CCB * pCCB,
  2260. char * pRoutineName,
  2261. char * pParamName,
  2262. long FormatStringOffset,
  2263. BOOL fTakeAddress,
  2264. BOOL fDereference,
  2265. BOOL fPtrToStubMsg )
  2266. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2267. Routine Description:
  2268. Outputs a call to an Ndr buffer sizing routine.
  2269. Arguments:
  2270. pStream - the stream to write the output to
  2271. pRoutineName - the routine name (without the trailing "BufferSize")
  2272. pParamName - the name of the parameter/variable being sized
  2273. FormatStringOffset - the offset into the format string where this
  2274. parameter's/variable's description begins
  2275. fPtrToStubMsg - defines how the StubMsg should be referenced to
  2276. FALSE: &_StubMsg
  2277. TRUE : pStupMsg
  2278. Return Value:
  2279. None.
  2280. Notes:
  2281. ----------------------------------------------------------------------------*/
  2282. {
  2283. ISTREAM * pStream = pCCB->GetStream();
  2284. unsigned short Spaces;
  2285. char Buf[80];
  2286. pStream->NewLine();
  2287. Spaces = (unsigned short)(strlen(pRoutineName) + 12); // strlen("BufferSize( ");
  2288. // Stub message
  2289. pStream->Write( pRoutineName );
  2290. pStream->Write( fPtrToStubMsg ? "BufferSize( (PMIDL_STUB_MESSAGE) "PSTUB_MESSAGE_PAR_NAME","
  2291. : "BufferSize( (PMIDL_STUB_MESSAGE) &"STUB_MESSAGE_VAR_NAME"," );
  2292. pStream->NewLine();
  2293. // Param
  2294. pStream->Spaces( Spaces );
  2295. pStream->Write( "(unsigned char *)" );
  2296. if ( fTakeAddress )
  2297. pStream->Write( '&' );
  2298. if ( fDereference )
  2299. pStream->Write( '*' );
  2300. pStream->Write( pParamName );
  2301. pStream->Write( ',' );
  2302. pStream->NewLine();
  2303. // Format string
  2304. pStream->Spaces( Spaces );
  2305. pStream->Write( "(PFORMAT_STRING) &" );
  2306. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2307. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2308. pStream->Write( Buf );
  2309. pStream->NewLine();
  2310. }
  2311. void
  2312. Out_NdrFreeCall( CCB * pCCB,
  2313. char * pRoutineName,
  2314. char * pParamName,
  2315. long FormatStringOffset,
  2316. BOOL fTakeAddress,
  2317. BOOL fDereference )
  2318. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2319. Routine Description:
  2320. Outputs a call to an Ndr unmarshalling routine.
  2321. Arguments:
  2322. pStream - the stream to write the output to
  2323. pRoutineName - the routine name (without the trailing "Free")
  2324. pParamName - the name of the parameter/variable being freed
  2325. FormatStringOffset - the offset into the format string where this
  2326. parameter's/variable's description begins
  2327. Return Value:
  2328. None.
  2329. Notes:
  2330. ----------------------------------------------------------------------------*/
  2331. {
  2332. ISTREAM * pStream = pCCB->GetStream();
  2333. unsigned short Spaces;
  2334. char Buf[80];
  2335. pStream->NewLine();
  2336. Spaces = (unsigned short)(strlen(pRoutineName) + 6); // strlen("Free( ");
  2337. pStream->Write( pRoutineName );
  2338. pStream->Write( "Free( &"STUB_MESSAGE_VAR_NAME"," );
  2339. pStream->NewLine();
  2340. pStream->Spaces( Spaces );
  2341. pStream->Write( "(unsigned char *)" );
  2342. if ( fTakeAddress )
  2343. pStream->Write( '&' );
  2344. if ( fDereference )
  2345. pStream->Write( '*' );
  2346. pStream->Write( pParamName );
  2347. pStream->Write( ',' );
  2348. pStream->NewLine();
  2349. pStream->Spaces( Spaces );
  2350. pStream->Write( '&' );
  2351. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2352. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2353. pStream->Write( Buf );
  2354. pStream->NewLine();
  2355. }
  2356. void
  2357. Out_NdrConvert( CCB * pCCB,
  2358. long FormatStringOffset,
  2359. long ParamTotal,
  2360. unsigned short ProcOptimFlags )
  2361. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2362. Routine Description:
  2363. Outputs a call to NdrConvert().
  2364. Arguments:
  2365. None.
  2366. ----------------------------------------------------------------------------*/
  2367. {
  2368. ISTREAM * pStream = pCCB->GetStream();
  2369. char Buf[80];
  2370. pStream->NewLine();
  2371. pStream->Write( "if ( (" );
  2372. pStream->Write( (pCCB->GetCodeGenSide() == CGSIDE_CLIENT) ?
  2373. RPC_MESSAGE_VAR_NAME"." : PRPC_MESSAGE_VAR_NAME"->" );
  2374. pStream->Write( "DataRepresentation & 0X0000FFFFUL) != "
  2375. "NDR_LOCAL_DATA_REPRESENTATION )" );
  2376. pStream->IndentInc();
  2377. pStream->NewLine();
  2378. if ( ProcOptimFlags & OPTIMIZE_NON_NT351 )
  2379. pStream->Write( NDR_CONVERT_RTN_NAME_V2 );
  2380. else
  2381. pStream->Write( NDR_CONVERT_RTN_NAME );
  2382. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2383. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2384. pStream->Write( "(PFORMAT_STRING) &" );
  2385. pStream->Write( PROC_FORMAT_STRING_STRING_FIELD );
  2386. sprintf( Buf, "[%d]", FormatStringOffset );
  2387. pStream->Write( Buf );
  2388. //
  2389. // NdrConvert2 takes a third parameter.
  2390. //
  2391. if ( ProcOptimFlags & OPTIMIZE_NON_NT351 )
  2392. {
  2393. sprintf( Buf, ", %d", ParamTotal );
  2394. pStream->Write( Buf );
  2395. }
  2396. pStream->Write( " );" );
  2397. pStream->IndentDec();
  2398. pStream->NewLine();
  2399. }
  2400. void
  2401. Out_NdrNsGetBuffer( CCB * pCCB )
  2402. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2403. Routine Description:
  2404. Outputs a call to NdrNsGetBuffer().
  2405. Arguments:
  2406. None.
  2407. ----------------------------------------------------------------------------*/
  2408. {
  2409. ISTREAM * pStream = pCCB->GetStream();
  2410. pStream->NewLine();
  2411. pStream->Write( AUTO_NDR_GB_RTN_NAME );
  2412. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2413. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2414. pStream->Write( STUB_MSG_LENGTH_VAR_NAME ", " );
  2415. if( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  2416. {
  2417. pStream->Write( pCCB->GetInterfaceName() );
  2418. pStream->Write( AUTO_BH_VAR_NAME );
  2419. }
  2420. else
  2421. pStream->Write( '0' );
  2422. pStream->Write( " );" );
  2423. pStream->NewLine();
  2424. }
  2425. void
  2426. Out_NdrGetBuffer( CCB * pCCB )
  2427. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2428. Routine Description:
  2429. Outputs a call to NdrGetBuffer().
  2430. Arguments:
  2431. None.
  2432. ----------------------------------------------------------------------------*/
  2433. {
  2434. ISTREAM * pStream = pCCB->GetStream();
  2435. unsigned short Env;
  2436. Env = pCommand->GetEnv();
  2437. if (pCCB->GetCodeGenSide() == CGSIDE_CLIENT)
  2438. {
  2439. pStream->NewLine();
  2440. pStream->Write( DEFAULT_NDR_GB_RTN_NAME );
  2441. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2442. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2443. pStream->Write( STUB_MSG_LENGTH_VAR_NAME ", " );
  2444. if( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  2445. pStream->Write( BH_LOCAL_VAR_NAME );
  2446. else
  2447. pStream->Write( '0' );
  2448. pStream->Write( " );" );
  2449. pStream->NewLine();
  2450. }
  2451. else
  2452. {
  2453. //
  2454. // This saves us at least 15 instructions on an x86 server.
  2455. //
  2456. pStream->NewLine();
  2457. pStream->Write( PRPC_MESSAGE_VAR_NAME "->BufferLength = "
  2458. STUB_MSG_LENGTH_VAR_NAME ";" );
  2459. pStream->NewLine();
  2460. pStream->NewLine();
  2461. pStream->Write( RPC_STATUS_VAR_NAME" = I_RpcGetBuffer( "
  2462. PRPC_MESSAGE_VAR_NAME " ); ");
  2463. pStream->NewLine();
  2464. pStream->Write( "if ( "RPC_STATUS_VAR_NAME" )" );
  2465. pStream->IndentInc();
  2466. pStream->NewLine();
  2467. pStream->Write( "RpcRaiseException( "RPC_STATUS_VAR_NAME" );" );
  2468. pStream->IndentDec();
  2469. pStream->NewLine();
  2470. pStream->NewLine();
  2471. pStream->Write( STUB_MSG_BUFFER_VAR_NAME
  2472. " = (unsigned char *) "
  2473. PRPC_MESSAGE_VAR_NAME "->Buffer;" );
  2474. pStream->NewLine();
  2475. }
  2476. }
  2477. void
  2478. Out_NdrNsSendReceive( CCB * pCCB )
  2479. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2480. Routine Description:
  2481. Outputs a call to NdrNsSendReceive().
  2482. Arguments:
  2483. None.
  2484. ----------------------------------------------------------------------------*/
  2485. {
  2486. ISTREAM * pStream = pCCB->GetStream();
  2487. pStream->NewLine();
  2488. pStream->Write( AUTO_NDR_SR_RTN_NAME );
  2489. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2490. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2491. pStream->Write( "(unsigned char *) "STUB_MESSAGE_VAR_NAME ".Buffer, " );
  2492. pStream->Write( "(RPC_BINDING_HANDLE *) ""&" );
  2493. pStream->Write( pCCB->GetInterfaceName() );
  2494. pStream->Write( AUTO_BH_VAR_NAME );
  2495. pStream->Write( " );" );
  2496. pStream->NewLine();
  2497. }
  2498. void
  2499. Out_NdrSendReceive( CCB * pCCB )
  2500. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2501. Routine Description:
  2502. Outputs a call to NdrSendReceive().
  2503. Arguments:
  2504. None.
  2505. ----------------------------------------------------------------------------*/
  2506. {
  2507. ISTREAM * pStream = pCCB->GetStream();
  2508. pStream->NewLine();
  2509. pStream->Write( DEFAULT_NDR_SR_RTN_NAME );
  2510. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2511. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2512. pStream->Write( "(unsigned char *) "STUB_MESSAGE_VAR_NAME ".Buffer" );
  2513. pStream->Write( " );" );
  2514. pStream->NewLine();
  2515. }
  2516. void
  2517. Out_FreeParamInline( CCB * pCCB )
  2518. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2519. Routine Description:
  2520. Frees a top level param using the current stub message deallocator.
  2521. Arguments:
  2522. pCCB - Code control block.
  2523. ----------------------------------------------------------------------------*/
  2524. {
  2525. CG_PARAM * pParam;
  2526. ISTREAM * pStream;
  2527. pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  2528. pStream = pCCB->GetStream();
  2529. pStream->NewLine();
  2530. pStream->Write( "if ( " );
  2531. pStream->Write( pParam->GetResource()->GetResourceName() );
  2532. pStream->Write( " )" );
  2533. pStream->IndentInc();
  2534. pStream->NewLine();
  2535. pStream->Write( STUB_MESSAGE_VAR_NAME ".pfnFree( " );
  2536. pStream->Write( pParam->GetResource()->GetResourceName() );
  2537. pStream->Write( " );" );
  2538. pStream->IndentDec();
  2539. pStream->NewLine();
  2540. }
  2541. void
  2542. Out_CContextHandleMarshall( CCB * pCCB,
  2543. char * pName,
  2544. BOOL IsPointer )
  2545. {
  2546. ISTREAM * pStream;
  2547. expr_proc_call * pCall;
  2548. expr_node * pHandle;
  2549. expr_node * pExpr;
  2550. pStream = pCCB->GetStream();
  2551. pStream->NewLine();
  2552. pCall = new expr_proc_call( "NdrClientContextMarshall" );
  2553. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2554. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2555. pCall->SetParam( new expr_param( pExpr ) );
  2556. pHandle = new expr_variable( pName );
  2557. if ( IsPointer )
  2558. pHandle = new expr_u_deref( pHandle );
  2559. pHandle = MakeExpressionOfCastToTypeName( CTXT_HDL_C_CONTEXT_TYPE_NAME,
  2560. pHandle );
  2561. pCall->SetParam( new expr_param( pHandle ) );
  2562. pCall->SetParam( new expr_param(
  2563. new expr_variable( IsPointer ? "0" : "1" ) ) );
  2564. pCall->PrintCall( pStream, 0, 0 );
  2565. }
  2566. void
  2567. Out_SContextHandleMarshall( CCB * pCCB,
  2568. char * pName,
  2569. char * pRundownRoutineName )
  2570. {
  2571. ISTREAM * pStream;
  2572. expr_proc_call * pCall;
  2573. expr_node * pHandle;
  2574. expr_node * pRoutine;
  2575. expr_node * pExpr;
  2576. pStream = pCCB->GetStream();
  2577. pStream->NewLine();
  2578. pCall = new expr_proc_call( "NdrServerContextMarshall" );
  2579. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2580. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2581. pCall->SetParam( new expr_param( pExpr ) );
  2582. pHandle = new expr_variable( pName );
  2583. pHandle = MakeExpressionOfCastToTypeName( CTXT_HDL_S_CONTEXT_TYPE_NAME,
  2584. pHandle );
  2585. pCall->SetParam( new expr_param( pHandle ) );
  2586. pRoutine = new expr_variable( pRundownRoutineName );
  2587. pRoutine = MakeExpressionOfCastToTypeName( CTXT_HDL_RUNDOWN_TYPE_NAME,
  2588. pRoutine );
  2589. pCall->SetParam( new expr_param( pRoutine ) );
  2590. pCall->PrintCall( pStream, 0, 0 );
  2591. pStream->NewLine();
  2592. }
  2593. void
  2594. Out_SContextHandleNewMarshall( CCB * pCCB,
  2595. char * pName,
  2596. char * pRundownRoutineName,
  2597. long TypeOffset )
  2598. {
  2599. ISTREAM * pStream;
  2600. unsigned short Spaces;
  2601. char Buf[80];
  2602. pStream = pCCB->GetStream();
  2603. pStream->NewLine();
  2604. pStream->Write( "NdrServerContextNewMarshall(" );
  2605. pStream->NewLine();
  2606. Spaces = 20;
  2607. pStream->Spaces( Spaces );
  2608. pStream->Write( "( PMIDL_STUB_MESSAGE )& "STUB_MESSAGE_VAR_NAME"," );
  2609. pStream->NewLine();
  2610. pStream->Spaces( Spaces );
  2611. pStream->Write( "( " CTXT_HDL_S_CONTEXT_TYPE_NAME " ) " );
  2612. pStream->Write( pName );
  2613. pStream->Write( "," );
  2614. pStream->NewLine();
  2615. pStream->Spaces( Spaces );
  2616. pStream->Write( "( " CTXT_HDL_RUNDOWN_TYPE_NAME " ) " );
  2617. pStream->Write( pRundownRoutineName );
  2618. pStream->Write( "," );
  2619. pStream->NewLine();
  2620. pStream->Spaces( Spaces );
  2621. pStream->Write( "(PFORMAT_STRING) &" );
  2622. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2623. sprintf( Buf, ".Format[%d] );", TypeOffset );
  2624. pStream->Write( Buf );
  2625. pStream->NewLine();
  2626. }
  2627. void
  2628. Out_CContextHandleUnmarshall( CCB * pCCB,
  2629. char * pName,
  2630. BOOL IsPointer,
  2631. BOOL IsReturn )
  2632. {
  2633. ISTREAM * pStream;
  2634. expr_proc_call * pCall;
  2635. expr_node * pHandle;
  2636. expr_node * pExpr;
  2637. pStream = pCCB->GetStream();
  2638. pStream->NewLine();
  2639. if ( IsPointer )
  2640. {
  2641. pStream->Write( '*' );
  2642. pStream->Write( pName );
  2643. pStream->Write( " = (void *)0;" );
  2644. pStream->NewLine();
  2645. }
  2646. else if ( IsReturn )
  2647. {
  2648. pStream->Write( pName );
  2649. pStream->Write( " = 0;" );
  2650. pStream->NewLine();
  2651. }
  2652. pCall = new expr_proc_call( "NdrClientContextUnmarshall" );
  2653. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2654. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2655. pCall->SetParam( new expr_param( pExpr ) );
  2656. pHandle = new expr_variable( pName );
  2657. if ( ! IsPointer && IsReturn )
  2658. pHandle = new expr_u_address( pHandle );
  2659. pHandle = MakeExpressionOfCastPtrToType(
  2660. (node_skl *) new node_def(CTXT_HDL_C_CONTEXT_TYPE_NAME),
  2661. pHandle );
  2662. pCall->SetParam( new expr_param( pHandle ) );
  2663. CG_PROC * pProc;
  2664. pProc = (CG_PROC *)pCCB->GetCGNodeContext();
  2665. char * FullAutoHandleName = NULL;
  2666. if ( pProc->IsAutoHandle() )
  2667. {
  2668. FullAutoHandleName = new char[ strlen( pCCB->GetInterfaceName()) +
  2669. strlen( AUTO_BH_VAR_NAME ) + 1 ];
  2670. strcpy( FullAutoHandleName, pCCB->GetInterfaceName() );
  2671. strcat( FullAutoHandleName, AUTO_BH_VAR_NAME );
  2672. }
  2673. pCall->SetParam( new expr_param(
  2674. new expr_variable( pProc->IsAutoHandle()
  2675. ? FullAutoHandleName
  2676. : BH_LOCAL_VAR_NAME ) ) );
  2677. pCall->PrintCall( pStream, 0, 0 );
  2678. pStream->NewLine();
  2679. }
  2680. void
  2681. Out_SContextHandleUnmarshall( CCB * pCCB,
  2682. char * pName,
  2683. BOOL IsOutOnly )
  2684. {
  2685. ISTREAM * pStream;
  2686. expr_proc_call * pCall;
  2687. expr_node * pExpr;
  2688. pStream = pCCB->GetStream();
  2689. pStream->NewLine();
  2690. if ( IsOutOnly )
  2691. {
  2692. CSzBuffer Buffer;
  2693. Buffer.Set( pName );
  2694. Buffer.Append( " = NDRSContextUnmarshall( (uchar *)0, " );
  2695. Buffer.Append( PRPC_MESSAGE_VAR_NAME "->DataRepresentation" );
  2696. Buffer.Append( " );" );
  2697. pStream->Write(Buffer);
  2698. pStream->NewLine();
  2699. return;
  2700. }
  2701. pCall = new expr_proc_call( "NdrServerContextUnmarshall" );
  2702. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2703. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2704. pCall->SetParam( new expr_param( pExpr ) );
  2705. pExpr = new expr_variable( pName );
  2706. pExpr = new expr_assign( pExpr, pCall );
  2707. pExpr->PrintCall( pStream, 0, 0 );
  2708. pStream->NewLine();
  2709. }
  2710. void
  2711. Out_SContextHandleNewUnmarshall( CCB * pCCB,
  2712. char * pName,
  2713. BOOL IsOutOnly,
  2714. long TypeOffset )
  2715. {
  2716. ISTREAM * pStream;
  2717. unsigned short Spaces;
  2718. char Buf[80];
  2719. if ( IsOutOnly )
  2720. return;
  2721. pStream = pCCB->GetStream();
  2722. pStream->NewLine();
  2723. pStream->Write( pName );
  2724. pStream->Write( " = " );
  2725. pStream->Write( "NdrServerContextNewUnmarshall(" );
  2726. pStream->NewLine();
  2727. Spaces = (unsigned short)(strlen( pName ) + 7);
  2728. pStream->Spaces( Spaces );
  2729. pStream->Write( "( PMIDL_STUB_MESSAGE )& "STUB_MESSAGE_VAR_NAME"," );
  2730. pStream->NewLine();
  2731. pStream->Spaces( Spaces );
  2732. pStream->Write( "( PFORMAT_STRING )& " );
  2733. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2734. sprintf( Buf, ".Format[%d] );", TypeOffset );
  2735. pStream->Write( Buf );
  2736. pStream->NewLine();
  2737. }
  2738. void
  2739. Out_NdrFreeBuffer( CCB * pCCB )
  2740. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2741. Routine Description:
  2742. Outputs a call to NdrFreeBuffer().
  2743. Arguments:
  2744. None.
  2745. ----------------------------------------------------------------------------*/
  2746. {
  2747. ISTREAM * pStream = pCCB->GetStream();
  2748. pStream->NewLine();
  2749. pStream->Write( DEFAULT_NDR_FB_RTN_NAME );
  2750. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2751. pStream->Write( STUB_MESSAGE_VAR_NAME );
  2752. pStream->Write( " );" );
  2753. pStream->NewLine();
  2754. }
  2755. void
  2756. Out_FullPointerInit( CCB * pCCB )
  2757. {
  2758. ISTREAM * pStream = pCCB->GetStream();
  2759. expr_proc_call * pProc;
  2760. expr_node * pExpr;
  2761. pProc = new expr_proc_call( FULL_POINTER_INIT_RTN_NAME );
  2762. pProc->SetParam( new expr_param(
  2763. new expr_constant( (long) 0 ) ) );
  2764. pProc->SetParam( new expr_param(
  2765. new expr_variable(
  2766. (pCCB->GetCodeGenSide() == CGSIDE_SERVER)
  2767. ? "XLAT_SERVER" : "XLAT_CLIENT" ) ) );
  2768. pExpr = new expr_variable( STUB_MESSAGE_VAR_NAME ".FullPtrXlatTables" );
  2769. pExpr = new expr_assign( pExpr, pProc );
  2770. pStream->NewLine();
  2771. pExpr->PrintCall( pStream, 0, 0 );
  2772. pStream->NewLine();
  2773. }
  2774. void
  2775. Out_FullPointerFree( CCB * pCCB )
  2776. {
  2777. ISTREAM * pStream = pCCB->GetStream();
  2778. expr_proc_call * pProc;
  2779. pProc = new expr_proc_call( FULL_POINTER_FREE_RTN_NAME );
  2780. pProc->SetParam( new expr_param(
  2781. new expr_variable(
  2782. STUB_MESSAGE_VAR_NAME ".FullPtrXlatTables" ) ) );
  2783. pStream->NewLine();
  2784. pProc->PrintCall( pStream, 0, 0 );
  2785. pStream->NewLine();
  2786. }
  2787. void
  2788. Out_NdrInitStackTop( CCB * pCCB )
  2789. {
  2790. ISTREAM * pStream;
  2791. pStream = pCCB->GetStream();
  2792. pStream->NewLine();
  2793. pStream->Write( STUB_MESSAGE_VAR_NAME ".StackTop = 0;" );
  2794. pStream->NewLine();
  2795. }
  2796. void
  2797. Out_DispatchTableTypedef(
  2798. CCB * pCCB,
  2799. PNAME pInterfaceName,
  2800. ITERATOR& ProcNodeList,
  2801. int flag )
  2802. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2803. Routine Description:
  2804. Output the dispatch table typedef.
  2805. Arguments:
  2806. pCCB - A pointer to the code gen controller block.
  2807. pInterfacename - The base interface name.
  2808. ProcNodeList - The list of procedure node_proc nodes.
  2809. flag - 0 : normal, 1 : callback
  2810. Return Value:
  2811. None.
  2812. Notes:
  2813. ----------------------------------------------------------------------------*/
  2814. {
  2815. ISTREAM * pStream = pCCB->GetStream();
  2816. CSzBuffer Buffer;
  2817. node_skl * pNode;
  2818. node_pointer * pPtr;
  2819. node_id * pID;
  2820. unsigned short M, m;
  2821. DISPATCH_TABLE_ENTRY * pDEntry;
  2822. if( flag == 1 )
  2823. return;
  2824. pCCB->GetVersion( &M, &m );
  2825. pStream->NewLine();
  2826. if( flag == 0 )
  2827. {
  2828. Buffer.Set( "typedef struct _" );
  2829. Buffer.Append( pInterfaceName );
  2830. Buffer.Append( pCCB->GenMangledName() );
  2831. Buffer.Append( "_" );
  2832. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2833. pStream->Write( Buffer );
  2834. pStream->NewLine();
  2835. pStream->IndentInc();
  2836. pStream->Write('{');
  2837. pStream->NewLine();
  2838. }
  2839. #if 0
  2840. else
  2841. {
  2842. Buffer.Set( "typedef struct _" );
  2843. Buffer.Append( pInterfaceName );
  2844. Buffer.Append( pCCB->GenMangledName() );
  2845. Buffer.Append( "_CLIENT_EPV" );
  2846. }
  2847. #endif // 0
  2848. ITERATOR_INIT( ProcNodeList );
  2849. while( ITERATOR_GETNEXT( ProcNodeList, pDEntry ) )
  2850. {
  2851. pNode = pDEntry->pNode;
  2852. pID = new node_id( pNode->GetSymName() );
  2853. pPtr = new node_pointer( pNode );
  2854. pID->SetBasicType( pPtr );
  2855. pPtr->SetBasicType( pNode );
  2856. pID->SetEdgeType( EDGE_DEF );
  2857. pPtr->SetEdgeType( EDGE_USE );
  2858. pID->PrintType( PRT_PROC_PTR_PROTOTYPE, pStream, (node_skl *)0 );
  2859. }
  2860. pStream->NewLine();
  2861. pStream->IndentDec();
  2862. if( flag == 0 )
  2863. {
  2864. Buffer.Set( "} " );
  2865. Buffer.Append( pInterfaceName );
  2866. Buffer.Append( pCCB->GenMangledName() );
  2867. Buffer.Append( "_" );
  2868. Buffer.Append( pCCB->IsOldNames() ?"SERVER_EPV" : "epv_t" );
  2869. Buffer.Append( ";" );
  2870. }
  2871. else
  2872. {
  2873. Buffer.Set( "} " );
  2874. Buffer.Append( pInterfaceName );
  2875. Buffer.Append( pCCB->GenMangledName() );
  2876. Buffer.Append( "_" );
  2877. Buffer.Append( (flag == 0) ?"SERVER" : "CLIENT" );
  2878. Buffer.Append( "_EPV;" );
  2879. }
  2880. pStream->Write( Buffer );
  2881. pStream->NewLine();
  2882. }
  2883. void
  2884. Out_ManagerEpv(
  2885. CCB * pCCB,
  2886. PNAME pInterfaceName,
  2887. ITERATOR& ProcNodeList,
  2888. short Count )
  2889. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2890. Routine Description:
  2891. Output the manager epv table.
  2892. Arguments:
  2893. pCCB - A pointer to the code gen controller block.
  2894. pInterfacename - The base interface name.
  2895. ProcNodeList - The list of procedure node_proc nodes.
  2896. Count - Count of procs.
  2897. Return Value:
  2898. None.
  2899. Notes:
  2900. ----------------------------------------------------------------------------*/
  2901. {
  2902. if ( !pCommand->IsFinalProtocolRun() )
  2903. return;
  2904. ISTREAM * pStream = pCCB->GetStream();
  2905. CSzBuffer Buffer;
  2906. unsigned short M, m;
  2907. DISPATCH_TABLE_ENTRY * pDEntry;
  2908. pCCB->GetVersion( &M, &m );
  2909. pStream->NewLine();
  2910. Buffer.Set( "static " );
  2911. Buffer.Append( pInterfaceName );
  2912. Buffer.Append( pCCB->GenMangledName() );
  2913. Buffer.Append( "_" );
  2914. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2915. Buffer.Append( " DEFAULT_EPV = " );
  2916. pStream->Write( Buffer );
  2917. pStream->IndentInc();
  2918. pStream->NewLine();
  2919. pStream->Write('{');
  2920. pStream->NewLine();
  2921. ITERATOR_INIT( ProcNodeList );
  2922. while( ITERATOR_GETNEXT( ProcNodeList, pDEntry ) )
  2923. {
  2924. char * pPrefix = pCommand->GetUserPrefix( PREFIX_SERVER_MGR );
  2925. if ( pPrefix )
  2926. pStream->Write( pPrefix );
  2927. pStream->Write( pDEntry->pNode->GetSymName() );
  2928. if( --Count != 0 )
  2929. {
  2930. pStream->Write( ',' );
  2931. pStream->NewLine();
  2932. }
  2933. }
  2934. pStream->IndentDec();
  2935. pStream->NewLine();
  2936. pStream->Write( "};" );
  2937. pStream->NewLine();
  2938. }
  2939. void
  2940. Out_GenHdlPrototypes(
  2941. CCB * pCCB,
  2942. ITERATOR& List )
  2943. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2944. Routine Description:
  2945. Output a list of generic handle prototypes.
  2946. Arguments:
  2947. pCCB - A pointer to the code gen controller block.
  2948. List - List of type nodes.
  2949. Return Value:
  2950. Notes:
  2951. ----------------------------------------------------------------------------*/
  2952. {
  2953. ISTREAM * pStream = pCCB->GetStream();
  2954. CSzBuffer Buffer;
  2955. node_skl* pN;
  2956. pStream->NewLine();
  2957. while( ITERATOR_GETNEXT( List, pN ) )
  2958. {
  2959. PNAME pName = pN->GetSymName();
  2960. Buffer.Set( "handle_t __RPC_USER " );
  2961. Buffer.Append( pName );
  2962. Buffer.Append( "_bind ( " );
  2963. Buffer.Append( pName );
  2964. Buffer.Append( " );" );
  2965. pStream->Write( Buffer );
  2966. pStream->NewLine();
  2967. Buffer.Set( "void __RPC_USER " );
  2968. Buffer.Append( pName );
  2969. Buffer.Append( "_unbind( " );
  2970. Buffer.Append( pName );
  2971. Buffer.Append( ", handle_t );" );
  2972. pStream->Write( Buffer );
  2973. pStream->NewLine();
  2974. }
  2975. }
  2976. void
  2977. Out_CtxtHdlPrototypes(
  2978. CCB * pCCB,
  2979. ITERATOR& List )
  2980. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2981. Routine Description:
  2982. Output a list of context handle prototypes.
  2983. Arguments:
  2984. pCCB - A pointer to the code gen controller block.
  2985. List - List of type nodes.
  2986. Return Value:
  2987. Notes:
  2988. ----------------------------------------------------------------------------*/
  2989. {
  2990. ISTREAM * pStream = pCCB->GetStream();
  2991. CSzBuffer Buffer;
  2992. node_skl* pN;
  2993. pStream->NewLine();
  2994. while( ITERATOR_GETNEXT( List, pN ) )
  2995. {
  2996. PNAME pName = pN->GetSymName();
  2997. // A name can be a "" (an empty string).
  2998. if ( strlen(pName) )
  2999. {
  3000. Buffer.Set( "void __RPC_USER " );
  3001. Buffer.Append( pName );
  3002. Buffer.Append( "_rundown( " );
  3003. Buffer.Append( pName );
  3004. Buffer.Append( " );" );
  3005. pStream->Write( Buffer );
  3006. pStream->NewLine();
  3007. }
  3008. }
  3009. }
  3010. void
  3011. Out_TransmitAsPrototypes(
  3012. CCB * pCCB,
  3013. ITERATOR& ListOfPresentedTypes )
  3014. {
  3015. ISTREAM * pStream = pCCB->GetStream();
  3016. ISTREAM * pMemoryStream = new ISTREAM;
  3017. CSzBuffer Buffer;
  3018. node_skl * pXmittedType;
  3019. node_skl * pPresentedType;
  3020. char * pMemBufferStart = pMemoryStream->GetCurrentPtr();
  3021. pStream->NewLine();
  3022. while( ITERATOR_GETNEXT( ListOfPresentedTypes, pPresentedType ) )
  3023. {
  3024. // we reuse the same memory stream.
  3025. pMemoryStream->SetCurrentPtr( pMemBufferStart );
  3026. pXmittedType = ((node_def *)pPresentedType)->GetTransmittedType();
  3027. PNAME pPresentedTypeName = pPresentedType->GetSymName();
  3028. PNAME pTransmittedTypeName= pXmittedType->GetSymName();
  3029. pXmittedType->PrintType( PRT_TYPE_SPECIFIER,
  3030. pMemoryStream, // into stream
  3031. (node_skl *)0 // no parent.
  3032. );
  3033. //
  3034. // The type spec is in the stream, except that it needs a terminating
  3035. // null to use it as a string.
  3036. //
  3037. pTransmittedTypeName = pMemBufferStart;
  3038. *(pMemoryStream->GetCurrentPtr()) = 0;
  3039. pStream->NewLine();
  3040. Buffer.Set( "void __RPC_USER " );
  3041. Buffer.Append( pPresentedTypeName );
  3042. Buffer.Append( "_to_xmit( " );
  3043. Buffer.Append( pPresentedTypeName );
  3044. Buffer.Append( " *, " );
  3045. Buffer.Append( pTransmittedTypeName );
  3046. Buffer.Append( " * * );" );
  3047. pStream->Write( Buffer );
  3048. pStream->NewLine();
  3049. Buffer.Set( "void __RPC_USER " );
  3050. Buffer.Append( pPresentedTypeName );
  3051. Buffer.Append( "_from_xmit( " );
  3052. Buffer.Append( pTransmittedTypeName );
  3053. Buffer.Append( " *, " );
  3054. Buffer.Append( pPresentedTypeName );
  3055. Buffer.Append( " * );" );
  3056. pStream->Write( Buffer );
  3057. pStream->NewLine();
  3058. Buffer.Set( "void __RPC_USER " );
  3059. Buffer.Append( pPresentedTypeName );
  3060. Buffer.Append( "_free_inst( " );
  3061. Buffer.Append( pPresentedTypeName );
  3062. Buffer.Append( " * );" );
  3063. pStream->Write( Buffer );
  3064. pStream->NewLine();
  3065. Buffer.Set( "void __RPC_USER " );
  3066. Buffer.Append( pPresentedTypeName );
  3067. Buffer.Append( "_free_xmit( " );
  3068. Buffer.Append( pTransmittedTypeName );
  3069. Buffer.Append( " * );" );
  3070. pStream->Write( Buffer );
  3071. pStream->NewLine();
  3072. }
  3073. delete pMemoryStream;
  3074. }
  3075. void
  3076. Out_RepAsPrototypes(
  3077. CCB * pCCB,
  3078. ITERATOR& ListOfRepAsWireTypes )
  3079. {
  3080. ISTREAM * pStream = pCCB->GetStream();
  3081. CSzBuffer Buffer;
  3082. node_skl * pWireType;
  3083. pStream->NewLine();
  3084. while( ITERATOR_GETNEXT( ListOfRepAsWireTypes, pWireType ) )
  3085. {
  3086. PNAME pRepAsTypeName = ((node_def *)pWireType)->GetRepresentationName();
  3087. PNAME pTransmittedTypeName= pWireType->GetSymName();
  3088. pStream->NewLine();
  3089. Buffer.Set( "void __RPC_USER " );
  3090. Buffer.Append( pTransmittedTypeName );
  3091. Buffer.Append( "_from_local( " );
  3092. Buffer.Append( pRepAsTypeName );
  3093. Buffer.Append( " *, " );
  3094. Buffer.Append( pTransmittedTypeName );
  3095. Buffer.Append( " * * );" );
  3096. pStream->Write( Buffer );
  3097. pStream->NewLine();
  3098. Buffer.Set( "void __RPC_USER ");
  3099. Buffer.Append( pTransmittedTypeName );
  3100. Buffer.Append( "_to_local( " );
  3101. Buffer.Append( pTransmittedTypeName );
  3102. Buffer.Append( " *, " );
  3103. Buffer.Append( pRepAsTypeName );
  3104. Buffer.Append( " * );" );
  3105. pStream->Write( Buffer );
  3106. pStream->NewLine();
  3107. Buffer.Set(" void __RPC_USER " );
  3108. Buffer.Append( pTransmittedTypeName );
  3109. Buffer.Append( "_free_inst( " );
  3110. Buffer.Append( pTransmittedTypeName );
  3111. Buffer.Append( " * );" );
  3112. pStream->Write( Buffer );
  3113. pStream->NewLine();
  3114. Buffer.Set( "void __RPC_USER " );
  3115. Buffer.Append( pTransmittedTypeName );
  3116. Buffer.Append( "_free_local( " );
  3117. Buffer.Append( pRepAsTypeName );
  3118. Buffer.Append( " * );" );
  3119. pStream->Write( Buffer );
  3120. pStream->NewLine();
  3121. }
  3122. }
  3123. #define USRM_SIZE 0
  3124. #define USRM_FREE 3
  3125. char * UserMProtoName[ 4 ] =
  3126. {
  3127. USER_MARSHAL_SIZE "( ",
  3128. USER_MARSHAL_MARSHALL "( ",
  3129. USER_MARSHAL_UNMARSHALL "(",
  3130. USER_MARSHAL_FREE "( "
  3131. };
  3132. char * NDR64_UserMProtoName[ 4 ] =
  3133. {
  3134. NDR64_USER_MARSHAL_SIZE "( ",
  3135. NDR64_USER_MARSHAL_MARSHALL "( ",
  3136. NDR64_USER_MARSHAL_UNMARSHALL "(",
  3137. NDR64_USER_MARSHAL_FREE "( "
  3138. };
  3139. void
  3140. Out_UserMarshalSingleProto(
  3141. ISTREAM * pStream,
  3142. char * pTypeName,
  3143. int fProto,
  3144. SYNTAX_ENUM SyntaxType )
  3145. {
  3146. switch ( fProto )
  3147. {
  3148. case USRM_SIZE:
  3149. pStream->Write( "unsigned long __RPC_USER " );
  3150. break;
  3151. case USRM_FREE:
  3152. pStream->Write( "void __RPC_USER " );
  3153. break;
  3154. default:
  3155. pStream->Write( "unsigned char * __RPC_USER " );
  3156. break;
  3157. }
  3158. pStream->Write( pTypeName );
  3159. if ( SyntaxType == SYNTAX_NDR64 )
  3160. pStream->Write( NDR64_UserMProtoName[ fProto ] );
  3161. else
  3162. pStream->Write( UserMProtoName[ fProto ] );
  3163. pStream->Write( "unsigned long *, " ); // flags
  3164. switch ( fProto )
  3165. {
  3166. case USRM_SIZE:
  3167. pStream->Write( "unsigned long , " );
  3168. break;
  3169. case USRM_FREE:
  3170. break;
  3171. default:
  3172. pStream->Write( "unsigned char *, " );
  3173. break;
  3174. }
  3175. pStream->Write( pTypeName );
  3176. pStream->Write( " * ); " );
  3177. pStream->NewLine();
  3178. }
  3179. void
  3180. Out_OneUserMarshalProtoTypes(
  3181. CCB * pCCB,
  3182. ITERATOR& ListOfPresentedTypes,
  3183. SYNTAX_ENUM SyntaxType )
  3184. {
  3185. USER_MARSHAL_CONTEXT * pUsrContext;
  3186. ISTREAM * pStream = pCCB->GetStream();
  3187. ITERATOR_INIT( ListOfPresentedTypes );
  3188. while( ITERATOR_GETNEXT( ListOfPresentedTypes, pUsrContext ) )
  3189. {
  3190. pStream->NewLine();
  3191. for (int i=0; i < 4; i++)
  3192. Out_UserMarshalSingleProto( pStream,
  3193. pUsrContext->pTypeName,
  3194. i,
  3195. SyntaxType );
  3196. }
  3197. }
  3198. void
  3199. Out_UserMarshalPrototypes(
  3200. CCB * pCCB,
  3201. ITERATOR& ListOfPresentedTypes )
  3202. {
  3203. if ( pCommand->NeedsNDRRun() )
  3204. Out_OneUserMarshalProtoTypes( pCCB, ListOfPresentedTypes, SYNTAX_DCE );
  3205. if ( pCommand->NeedsNDR64Run() ||
  3206. pCommand->NeedsNDR64Header() )
  3207. Out_OneUserMarshalProtoTypes( pCCB, ListOfPresentedTypes, SYNTAX_NDR64 );
  3208. }
  3209. char CsNetSizePrototype[] =
  3210. "_net_size(\n"
  3211. " RPC_BINDING_HANDLE hBinding,\n"
  3212. " unsigned long ulNetworkCodeSet,\n"
  3213. " unsigned long ulLocalBufferSize,\n"
  3214. " IDL_CS_CONVERT * conversionType,\n"
  3215. " unsigned long * pulNetworkBufferSize,\n"
  3216. " error_status_t * pStatus);\n\n";
  3217. char CsLocalSizePrototype[] =
  3218. "_local_size(\n"
  3219. " RPC_BINDING_HANDLE hBinding,\n"
  3220. " unsigned long ulNetworkCodeSet,\n"
  3221. " unsigned long ulNetworkBufferSize,\n"
  3222. " IDL_CS_CONVERT * conversionType,\n"
  3223. " unsigned long * pulLocalBufferSize,\n"
  3224. " error_status_t * pStatus);\n\n";
  3225. char CsToNetCsPrototype[] =
  3226. "_to_netcs(\n"
  3227. " RPC_BINDING_HANDLE hBinding,\n"
  3228. " unsigned long ulNetworkCodeSet,\n"
  3229. " void * pLocalData,\n"
  3230. " unsigned long ulLocalDataLength,\n"
  3231. " byte * pNetworkData,\n"
  3232. " unsigned long * pulNetworkDataLength,\n"
  3233. " error_status_t * pStatus);\n\n";
  3234. char CsFromNetCsPrototype[] =
  3235. "_from_netcs(\n"
  3236. " RPC_BINDING_HANDLE hBinding,\n"
  3237. " unsigned long ulNetworkCodeSet,\n"
  3238. " byte * pNetworkData,\n"
  3239. " unsigned long ulNetworkDataLength,\n"
  3240. " unsigned long ulLocalBufferSize,\n"
  3241. " void * pLocalData,\n"
  3242. " unsigned long * pulLocalDataLength,\n"
  3243. " error_status_t * pStatus);\n\n";
  3244. void
  3245. Out_CSSizingAndConversionPrototypes(
  3246. CCB * pCCB,
  3247. ITERATOR & types )
  3248. {
  3249. PNAME pTypeName;
  3250. ISTREAM * pStream = pCCB->GetStream();
  3251. ITERATOR_INIT( types );
  3252. while ( ITERATOR_GETNEXT( types, pTypeName ) )
  3253. {
  3254. pStream->Write( "void __RPC_USER " );
  3255. pStream->Write( pTypeName );
  3256. pStream->Write( CsNetSizePrototype );
  3257. pStream->Write( "void __RPC_USER " );
  3258. pStream->Write( pTypeName );
  3259. pStream->Write( CsLocalSizePrototype );
  3260. pStream->Write( "void __RPC_USER " );
  3261. pStream->Write( pTypeName );
  3262. pStream->Write( CsToNetCsPrototype );
  3263. pStream->Write( "void __RPC_USER " );
  3264. pStream->Write( pTypeName );
  3265. pStream->Write( CsFromNetCsPrototype );
  3266. }
  3267. }
  3268. void
  3269. Out_CallAsServerPrototypes(
  3270. CCB * pCCB,
  3271. ITERATOR& ListOfCallAsRoutines )
  3272. {
  3273. ISTREAM * pStream = pCCB->GetStream();
  3274. node_proc * pProc;
  3275. pStream->NewLine();
  3276. while( ITERATOR_GETNEXT( ListOfCallAsRoutines, pProc ) )
  3277. {
  3278. // keep these on the stack...
  3279. CSzBuffer NewName;
  3280. char TempBuf[40];
  3281. node_call_as * pCallAs = (node_call_as *)
  3282. pProc->GetAttribute( ATTR_CALL_AS );
  3283. unsigned short M, m;
  3284. node_interface * pIntf = pProc->GetMyInterfaceNode();
  3285. // don't emit the server prototype for object routines
  3286. if ( pIntf->FInSummary( ATTR_OBJECT ) )
  3287. continue;
  3288. // local stub routine, with remote param list
  3289. node_proc NewStubProc( pProc );
  3290. pIntf->GetVersionDetails( &M, &m );
  3291. sprintf( TempBuf,
  3292. "_v%d_%d",
  3293. M,
  3294. m );
  3295. NewName.Set( pIntf->GetSymName() );
  3296. NewName.Append( TempBuf );
  3297. NewName.Append( "_" );
  3298. NewName.Append( pCallAs->GetCallAsName() );
  3299. NewStubProc.SetSymName( NewName );
  3300. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI,
  3301. pCCB->GetStream(),
  3302. NULL ,
  3303. pIntf );
  3304. pCCB->GetStream()->NewLine();
  3305. }
  3306. }
  3307. void
  3308. Out_NotifyPrototypes(
  3309. CCB * pCCB,
  3310. ITERATOR& ListOfNotifyProcedures)
  3311. /*
  3312. We generate
  3313. void <proc_name>_notify( void );
  3314. void <proc_name>_notify_flag( boolean );
  3315. */
  3316. {
  3317. ISTREAM * pStream = pCCB->GetStream();
  3318. CG_PROC * pProcCG;
  3319. node_proc * pProc;
  3320. node_skl * pRet;
  3321. BOOL fHasFlag;
  3322. GetBaseTypeNode( &pRet, SIGN_UNDEF, SIZE_UNDEF, TYPE_VOID );
  3323. pStream->NewLine();
  3324. while( ITERATOR_GETNEXT( ListOfNotifyProcedures, pProcCG ) )
  3325. {
  3326. // keep these on the stack...
  3327. CSzBuffer NewName;
  3328. node_proc NewStubProc( 0, 0 );
  3329. node_param FlagParam;
  3330. fHasFlag = pProcCG->HasNotifyFlag();
  3331. pProc = (node_proc *) pProcCG->GetType();
  3332. NewStubProc.SetChild( pRet );
  3333. if ( fHasFlag )
  3334. {
  3335. node_skl * pParamType;
  3336. GetBaseTypeNode( &pParamType, SIGN_UNDEF, SIZE_UNDEF, TYPE_BOOLEAN );
  3337. FlagParam.SetChild( pParamType );
  3338. FlagParam.SetSymName( NOTIFY_FLAG_VAR_NAME );
  3339. NewStubProc.SetFirstMember( & FlagParam );
  3340. }
  3341. NewName.Set( pProc->GetSymName() );
  3342. NewName.Append( (fHasFlag ? NOTIFY_FLAG_SUFFIX
  3343. : NOTIFY_SUFFIX ) );
  3344. NewStubProc.SetSymName( NewName );
  3345. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI,
  3346. pStream,
  3347. NULL );
  3348. pCCB->GetStream()->NewLine();
  3349. }
  3350. }
  3351. void
  3352. Out_PatchReference(
  3353. CCB * pCCB,
  3354. expr_node * pDest,
  3355. expr_node * pSrc,
  3356. BOOL fIncr )
  3357. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3358. Routine Description:
  3359. Output a patch of a pointer to the source pointer.
  3360. Arguments:
  3361. pCCB - The cg cont. block.
  3362. pDest - The destination expression
  3363. pSrc - The source expression.
  3364. fIncr - Should we increment the ptr ?
  3365. Return Value:
  3366. None.
  3367. Notes:
  3368. Both the expressions must be pointers.
  3369. Cast the source expression to the destination.
  3370. ----------------------------------------------------------------------------*/
  3371. {
  3372. ISTREAM * pStream = pCCB->GetStream();
  3373. node_skl * pType = pDest->GetType();
  3374. NODE_T NT = pType->NodeKind();
  3375. expr_node * pCast;
  3376. expr_node * pAss;
  3377. if( (NT == NODE_ID) || (NT == NODE_PARAM) || (NT == NODE_FIELD) )
  3378. {
  3379. pType = pType->GetBasicType();
  3380. }
  3381. pCast = (expr_node *) new expr_cast( pType, pSrc );
  3382. if( fIncr )
  3383. pCast = (expr_node *) new expr_post_incr( pCast );
  3384. pAss = (expr_node *) new expr_assign( pDest, pCast );
  3385. pStream->NewLine();
  3386. pAss->Print( pStream );
  3387. pStream->Write(';');
  3388. }
  3389. void
  3390. Out_Endif( CCB * pCCB )
  3391. {
  3392. pCCB->GetStream()->NewLine();
  3393. pCCB->GetStream()->Write( '}' );
  3394. Out_IndentDec( pCCB );
  3395. }
  3396. void
  3397. Out_If(
  3398. CCB * pCCB,
  3399. expr_node * pExpr )
  3400. {
  3401. ISTREAM * pStream = pCCB->GetStream();
  3402. pStream->NewLine();
  3403. pStream->Write( "if(" );
  3404. pExpr->Print( pStream );
  3405. pStream->Write( ')' );
  3406. Out_IndentInc( pCCB );
  3407. pStream->NewLine();
  3408. pStream->Write( '{' );
  3409. }
  3410. void
  3411. Out_Else(
  3412. CCB * pCCB )
  3413. {
  3414. ISTREAM * pStream = pCCB->GetStream();
  3415. pStream->NewLine();
  3416. pStream->Write( "else" );
  3417. Out_IndentInc( pCCB );
  3418. pStream->NewLine();
  3419. pStream->Write( '{' );
  3420. }
  3421. void
  3422. Out_UniquePtrMarshall(
  3423. CCB * pCCB,
  3424. expr_node * pDestExpr,
  3425. expr_node * pSrcExpr )
  3426. {
  3427. ISTREAM * pStream = pCCB->GetStream();
  3428. expr_proc_call * pProc;
  3429. pStream->NewLine();
  3430. pProc = new expr_proc_call( MARSHALL_UNIQUE_PTR_RTN_NAME );
  3431. pProc->SetParam(new expr_param( pDestExpr ));
  3432. pProc->SetParam(new expr_param( pSrcExpr ));
  3433. pProc->PrintCall( pStream, 0, 0 );
  3434. }
  3435. void
  3436. Out_IfUniquePtrInBuffer(
  3437. CCB * pCCB,
  3438. expr_node * pSrc )
  3439. //
  3440. // This appears to be a fossil. Ryszard 3/30/98.
  3441. // However, the routine above appears to be used.
  3442. //
  3443. {
  3444. expr_proc_call * pProc = new expr_proc_call( CHECK_UNIQUE_PTR_IN_BUFFER );
  3445. ISTREAM * pStream = pCCB->GetStream();
  3446. pProc->SetParam( new expr_param( pSrc ) );
  3447. pStream->NewLine();
  3448. pStream->Write( "if(" );
  3449. pProc->Print( pStream );
  3450. pStream->Write( ')' );
  3451. Out_IndentInc( pCCB );
  3452. pStream->NewLine();
  3453. pStream->Write( '{' );
  3454. }
  3455. void
  3456. Out_Assign( CCB * pCCB,
  3457. expr_node * pDest,
  3458. expr_node * pSrc )
  3459. {
  3460. ISTREAM * pStream = pCCB->GetStream();
  3461. pStream->NewLine();
  3462. pDest->Print( pStream );
  3463. pStream->Write( " = " );
  3464. pSrc->Print( pStream );
  3465. pStream->Write( ';' );
  3466. }
  3467. void
  3468. Out_Memcopy(
  3469. CCB * pCCB,
  3470. expr_node * pDest,
  3471. expr_node * pSource,
  3472. expr_node * pLength )
  3473. {
  3474. ISTREAM * pStream = pCCB->GetStream();
  3475. expr_proc_call * pCall = new expr_proc_call( "memcpy" );
  3476. pStream->NewLine();
  3477. pCall->SetParam( new expr_param( pDest ) );
  3478. pCall->SetParam( new expr_param( pSource ) );
  3479. pCall->SetParam( new expr_param( pLength ) );
  3480. pCall->PrintCall( pStream, 0, 0 );
  3481. }
  3482. void
  3483. Out_strlen(
  3484. CCB * pCCB,
  3485. expr_node * pDest,
  3486. expr_node * pSource,
  3487. unsigned short Size )
  3488. {
  3489. ISTREAM * pStream = pCCB->GetStream();
  3490. PNAME pName = (Size == 1) ? "strlen" : "MIDL_wchar_strlen";
  3491. expr_proc_call * pCall = new expr_proc_call( pName );
  3492. expr_node * pExpr;
  3493. pStream->NewLine();
  3494. pCall->SetParam( new expr_param( pSource ) );
  3495. if( pDest )
  3496. pExpr = new expr_assign( pDest, pCall );
  3497. else
  3498. pExpr = pCall;
  3499. pExpr->PrintCall( pStream, 0, 0 );
  3500. }
  3501. void
  3502. Out_For(
  3503. CCB * pCCB,
  3504. expr_node * pIndexExpr,
  3505. expr_node * pInitialValue,
  3506. expr_node * pFinalValue,
  3507. expr_node * pIncrExpr )
  3508. {
  3509. ISTREAM * pStream = pCCB->GetStream();
  3510. expr_node * pExpr;
  3511. pStream->NewLine();
  3512. pStream->Write( "for( " );
  3513. pExpr = new expr_assign( pIndexExpr, pInitialValue );
  3514. pExpr->Print( pStream );
  3515. pStream->Write( ';' );
  3516. pExpr = new expr_op_binary( OP_LESS, pIndexExpr, pFinalValue );
  3517. pExpr->Print( pStream );
  3518. pStream->Write( ';' );
  3519. pExpr = new expr_op_binary( OP_PLUS, pIndexExpr, pIncrExpr );
  3520. pExpr = new expr_assign( pIndexExpr, pExpr );
  3521. pExpr->Print( pStream );
  3522. pStream->Write( ')' );
  3523. pStream->IndentInc();
  3524. pStream->NewLine();
  3525. pStream->Write( '{' );
  3526. }
  3527. void
  3528. Out_EndFor( CCB * pCCB )
  3529. {
  3530. pCCB->GetStream()->NewLine();
  3531. pCCB->GetStream()->Write( '}' );
  3532. Out_IndentDec( pCCB );
  3533. }
  3534. void
  3535. Out_PlusEquals(
  3536. CCB * pCCB,
  3537. expr_node *pL,
  3538. expr_node *pR )
  3539. {
  3540. ISTREAM * pStream = pCCB->GetStream();
  3541. pStream->NewLine();
  3542. pL->Print( pStream );
  3543. pStream->Write( " += " );
  3544. pR->Print( pStream );
  3545. pStream->Write(';');
  3546. }
  3547. void
  3548. Out_Comment(
  3549. CCB * pCCB,
  3550. char * pComment )
  3551. {
  3552. ISTREAM * pStream = pCCB->GetStream();
  3553. pStream->NewLine();
  3554. pStream->Write( "/* " );
  3555. pStream->Write( pComment );
  3556. pStream->Write( " */" );
  3557. }
  3558. void
  3559. Out_RpcSSEnableAllocate(
  3560. CCB * pCCB )
  3561. {
  3562. expr_proc_call * pCall = new expr_proc_call( RPC_SS_ENABLE_ALLOCATE_RTN_NAME );
  3563. pCall->SetParam( new expr_param (
  3564. new expr_u_address (
  3565. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3566. pCCB->GetStream()->NewLine();
  3567. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3568. }
  3569. void
  3570. Out_RpcSSSetClientToOsf(
  3571. CCB * pCCB )
  3572. {
  3573. expr_proc_call * pCall = new expr_proc_call( RPC_SM_SET_CLIENT_TO_OSF_RTN_NAME );
  3574. pCall->SetParam( new expr_param (
  3575. new expr_u_address (
  3576. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3577. pCCB->GetStream()->NewLine();
  3578. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3579. }
  3580. void
  3581. Out_RpcSSDisableAllocate(
  3582. CCB * pCCB )
  3583. {
  3584. expr_proc_call * pCall = new expr_proc_call( RPC_SS_DISABLE_ALLOCATE_RTN_NAME );
  3585. pCall->SetParam( new expr_param (
  3586. new expr_u_address (
  3587. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3588. pCCB->GetStream()->NewLine();
  3589. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3590. }
  3591. void
  3592. Out_MemsetToZero(
  3593. CCB * pCCB,
  3594. expr_node * pDest,
  3595. expr_node * pSize )
  3596. {
  3597. expr_proc_call * pProc = new expr_proc_call( (PNAME) MIDL_MEMSET_RTN_NAME );
  3598. pProc->SetParam( new expr_param( pDest ) );
  3599. pProc->SetParam( new expr_param( new expr_constant(0L) ) );
  3600. pProc->SetParam( new expr_param( pSize ) );
  3601. pCCB->GetStream()->NewLine();
  3602. pProc->PrintCall( pCCB->GetStream(), 0, 0 );
  3603. }
  3604. void
  3605. Out_CallAsProxyPrototypes(
  3606. CCB * pCCB,
  3607. ITERATOR& ListOfCallAsRoutines )
  3608. /*++
  3609. Routine Description:
  3610. This routine generates the call_as function prototypes.
  3611. One for the proxy( with local param list )
  3612. One for the stub( with remote param list )
  3613. Arguments:
  3614. pCCB - a pointer to the code generation control block.
  3615. --*/
  3616. {
  3617. ISTREAM * pStream = pCCB->GetStream();
  3618. node_proc * pProc;
  3619. pStream->NewLine();
  3620. while( ITERATOR_GETNEXT( ListOfCallAsRoutines, pProc ) )
  3621. {
  3622. node_interface * pIntf = pProc->GetMyInterfaceNode();
  3623. // skip for non-object routines
  3624. if ( !pIntf->FInSummary( ATTR_OBJECT ) )
  3625. continue;
  3626. // keep these on the stack...
  3627. CSzBuffer NewName;
  3628. node_call_as * pCallAs = (node_call_as *)
  3629. pProc->GetAttribute( ATTR_CALL_AS );
  3630. node_proc NewProc( pCallAs->GetCallAsType() );
  3631. // local proxy routine with local param list
  3632. NewName.Set( pIntf->GetSymName() );
  3633. NewName.Append( "_" );
  3634. NewName.Append( pCallAs->GetCallAsName() );
  3635. NewName.Append( "_Proxy" );
  3636. NewProc.SetSymName( NewName );
  3637. NewProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI | PRT_THIS_POINTER | PRT_FORCE_CALL_CONV,
  3638. pCCB->GetStream(),
  3639. NULL ,
  3640. pIntf );
  3641. pStream->NewLine();
  3642. // local stub routine, with remote param list
  3643. node_proc NewStubProc( pProc );
  3644. NewName.Set( pIntf->GetSymName() );
  3645. NewName.Append( "_" );
  3646. NewName.Append( pCallAs->GetCallAsName() );
  3647. NewName.Append( "_Stub" );
  3648. NewStubProc.SetSymName( NewName );
  3649. pStream->NewLine();
  3650. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI | PRT_THIS_POINTER | PRT_FORCE_CALL_CONV,
  3651. pStream,
  3652. NULL ,
  3653. pIntf );
  3654. pStream->NewLine();
  3655. }
  3656. }
  3657. void
  3658. CG_OBJECT_PROC::Out_ProxyFunctionPrototype(CCB *pCCB, PRTFLAGS F )
  3659. /*++
  3660. Routine Description:
  3661. This routine generates a proxy function prototype.
  3662. Arguments:
  3663. pCCB - a pointer to the code generation control block.
  3664. --*/
  3665. {
  3666. // keep these on the stack...
  3667. CSzBuffer NewName;
  3668. node_proc * pProc = (node_proc *)GetType();
  3669. node_proc NewProc( pProc );
  3670. NewName.Set( pCCB->GetInterfaceName() );
  3671. NewName.Append( "_" );
  3672. NewName.Append( pProc->GetSymName() );
  3673. NewName.Append( "_Proxy" );
  3674. NewProc.SetSymName( NewName );
  3675. pCCB->GetStream()->NewLine();
  3676. NewProc.PrintType( PRT_PROC_PROTOTYPE | PRT_THIS_POINTER | F | PRT_FORCE_CALL_CONV,
  3677. pCCB->GetStream(),
  3678. NULL ,
  3679. pCCB->GetInterfaceCG()->GetType() );
  3680. }
  3681. void
  3682. Out_IID(CCB *pCCB)
  3683. /*++
  3684. Routine Description:
  3685. This routine generates an IID declaration for the current interface.
  3686. Arguments:
  3687. pCCB - a pointer to the code generation control block.
  3688. --*/
  3689. {
  3690. ISTREAM *pStream = pCCB->GetStream();
  3691. pStream->NewLine();
  3692. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  3693. {
  3694. node_guid * pGuid = (node_guid *) ((node_interface *)pCCB->GetInterfaceCG()->GetType())->GetAttribute(ATTR_GUID);
  3695. if (pGuid)
  3696. Out_MKTYPLIB_Guid(pCCB, pGuid->GetStrs(), "IID_", pCCB->GetInterfaceName());
  3697. }
  3698. else
  3699. {
  3700. pStream->Write("EXTERN_C const IID IID_");
  3701. pStream->Write(pCCB->GetInterfaceName());
  3702. pStream->Write(';');
  3703. pStream->NewLine();
  3704. }
  3705. }
  3706. void
  3707. Out_CLSID(CCB *pCCB)
  3708. /*++
  3709. Routine Description:
  3710. This routine generates an CLSID declaration for the current com class.
  3711. Arguments:
  3712. pCCB - a pointer to the code generation control block.
  3713. --*/
  3714. {
  3715. ISTREAM *pStream = pCCB->GetStream();
  3716. pStream->NewLine();
  3717. pStream->Write("EXTERN_C const CLSID CLSID_");
  3718. pStream->Write(pCCB->GetInterfaceName());
  3719. pStream->Write(';');
  3720. pStream->NewLine();
  3721. }
  3722. void
  3723. CG_OBJECT_PROC::Out_StubFunctionPrototype(CCB *pCCB)
  3724. {
  3725. ISTREAM * pStream = pCCB->GetStream();
  3726. CSzBuffer TempBuffer;
  3727. TempBuffer.Set( "void __RPC_STUB " );
  3728. TempBuffer.Append( pCCB->GetInterfaceName() );
  3729. TempBuffer.Append( "_" );
  3730. TempBuffer.Append( GetType()->GetSymName() );
  3731. TempBuffer.Append( "_Stub(" );
  3732. pStream->NewLine();
  3733. pStream->Write( TempBuffer );
  3734. pStream->IndentInc();
  3735. pStream->NewLine();
  3736. pStream->Write("IRpcStubBuffer *This,");
  3737. pStream->NewLine();
  3738. pStream->Write("IRpcChannelBuffer *_pRpcChannelBuffer,");
  3739. pStream->NewLine();
  3740. pStream->Write("PRPC_MESSAGE _pRpcMessage,");
  3741. pStream->NewLine();
  3742. pStream->Write("DWORD *_pdwStubPhase)");
  3743. pStream->IndentDec();
  3744. }
  3745. void
  3746. CG_OBJECT_PROC::Out_ServerStubProlog(
  3747. CCB * pCCB,
  3748. ITERATOR& LocalsList,
  3749. ITERATOR& TransientList )
  3750. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3751. Routine Description:
  3752. Generate the server side procedure prolog.
  3753. Arguments:
  3754. pCCB - A pointer to the code generation controller block.
  3755. LocalsList - A list of local resources.
  3756. TransientList- A list of temp variables.
  3757. Return Value:
  3758. Notes:
  3759. The server side procedure prolog generation cannot use the normal
  3760. printtype method on the procedure node, since the server stub signature
  3761. looks different.
  3762. Also the name of the server side stub is mangled with the interface name.
  3763. All server side procs are void returns.
  3764. ----------------------------------------------------------------------------*/
  3765. {
  3766. ISTREAM * pStream = pCCB->GetStream();
  3767. RESOURCE* pRes;
  3768. Out_StubFunctionPrototype(pCCB);
  3769. //
  3770. // Write out the opening brace for the server proc and all that.
  3771. //
  3772. pStream->NewLine();
  3773. pStream->Write( '{' );
  3774. pStream->IndentInc();
  3775. pStream->NewLine();
  3776. //
  3777. // This is where we get off for /Oi. We have a special routine
  3778. // for local variable declaration for /Oi.
  3779. //
  3780. if ( pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER )
  3781. return;
  3782. //
  3783. // Print out declarations for the locals.
  3784. //
  3785. if( ITERATOR_GETCOUNT( LocalsList ) )
  3786. {
  3787. ITERATOR_INIT( LocalsList );
  3788. while( ITERATOR_GETNEXT( LocalsList, pRes ) )
  3789. {
  3790. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  3791. pStream, // into stream
  3792. (node_skl *)0 // no parent.
  3793. );
  3794. }
  3795. }
  3796. if( ITERATOR_GETCOUNT( TransientList ) )
  3797. {
  3798. ITERATOR_INIT( TransientList );
  3799. while( ITERATOR_GETNEXT( TransientList, pRes ) )
  3800. {
  3801. pStream->IndentInc();
  3802. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  3803. pStream, // into stream
  3804. (node_skl *)0 // no parent.
  3805. );
  3806. pStream->IndentDec();
  3807. }
  3808. }
  3809. pStream->IndentDec();
  3810. pStream->NewLine();
  3811. //
  3812. // Done.
  3813. //
  3814. }
  3815. void
  3816. Out_CallMemberFunction(
  3817. CCB * pCCB,
  3818. expr_proc_call * pProcExpr,
  3819. expr_node * pRet,
  3820. BOOL fThunk)
  3821. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3822. Routine Description:
  3823. Generate a call to the manager routine.
  3824. Arguments:
  3825. pCCB - A pointer to the code generation controller block.
  3826. pProcExpr - A pointer to the complete procedure expression.
  3827. pRet - An optional pointer to ther return variable.
  3828. fThunk - flag for "this call is in a thunk with a param struct"
  3829. Return Value:
  3830. None.
  3831. Notes:
  3832. //call server
  3833. _RetVal = (((IClassFactory *) ((CStdStubBuffer*)This)->pvServerObject)->lpVtbl) -> LockServer((IClassFactory *) ((CStdStubBuffer *)This)->pvServerObject,fLock);
  3834. ----------------------------------------------------------------------------*/
  3835. {
  3836. expr_node * pAss = pProcExpr;
  3837. expr_node * pExpr;
  3838. CSzBuffer Buffer;
  3839. ISTREAM * pStream = pCCB->GetStream();
  3840. char * pTemp;
  3841. if ( fThunk )
  3842. {
  3843. // ((IFoo*) ((CStdStubBuffer*)pParamStruct->This)->lpVtbl)->Bar();
  3844. Buffer.Set( "((" );
  3845. Buffer.Append( pCCB->GetInterfaceName() );
  3846. Buffer.Append( "*) ((CStdStubBuffer*)pParamStruct->This)->lpVtbl)" );
  3847. }
  3848. else
  3849. {
  3850. // (((IFoo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl)->Bar();
  3851. Buffer.Set( "(((" );
  3852. Buffer.Append( pCCB->GetInterfaceName() );
  3853. Buffer.Append( "*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl)" );
  3854. }
  3855. pTemp = new char [ strlen( Buffer ) + 1 ];
  3856. strcpy( pTemp, Buffer );
  3857. pExpr = new expr_variable( pTemp );//this has the rhs expr for the
  3858. // manager epv call. Sneaky !
  3859. pExpr = new expr_pointsto( pExpr, pProcExpr );
  3860. pAss = pExpr;
  3861. if( pRet )
  3862. {
  3863. pAss = new expr_assign( pRet, pExpr );
  3864. }
  3865. pAss->PrintCall( pStream, 0, 0 );
  3866. }
  3867. void
  3868. OutputNdrAlignment( CCB * pCCB,
  3869. unsigned short Alignment )
  3870. {
  3871. ISTREAM * pStream;
  3872. unsigned long Align = Alignment - 1;
  3873. CSzBuffer Buffer;
  3874. pStream = pCCB->GetStream();
  3875. Buffer.Set( STUB_MSG_BUFFER_VAR_NAME );
  3876. Buffer.Append( " = (unsigned char *)(((" );
  3877. Buffer.Append( (pCommand->Is64BitEnv() ? "__int64"
  3878. : "long" ));
  3879. Buffer.Append( ")" STUB_MSG_BUFFER_VAR_NAME " + " );
  3880. Buffer.Append( Align );
  3881. char sz[100];
  3882. sprintf( sz, ") & ~ %#x);", Align);
  3883. Buffer.Append( sz );
  3884. pStream->Write( Buffer );
  3885. pStream->NewLine();
  3886. }
  3887. CG_NDR *
  3888. GetFirstMulti(
  3889. CG_NDR * pNdr )
  3890. {
  3891. // Skip pointers leading to a multi-dimensional object.
  3892. while ( pNdr->GetCGID() == ID_CG_GENERIC_HDL ||
  3893. pNdr->GetCGID() == ID_CG_PTR )
  3894. {
  3895. pNdr = (CG_NDR *) pNdr->GetChild();
  3896. }
  3897. return pNdr;
  3898. }
  3899. void
  3900. Out_MultiDimVars(
  3901. CCB * pCCB,
  3902. CG_PARAM * pParam
  3903. )
  3904. /*
  3905. Output local resources related to multi-dimensional conf or varying arrays.
  3906. Note that the parameter may be a pointer to multidimensional object.
  3907. */
  3908. {
  3909. ISTREAM * pStream;
  3910. CG_NDR * pNdr;
  3911. char * pParamName;
  3912. long dim;
  3913. CSzBuffer Buffer;
  3914. pStream = pCCB->GetStream();
  3915. pParamName = pParam->GetType()->GetSymName();
  3916. pNdr = (CG_NDR *) pParam->GetChild();
  3917. pNdr = GetFirstMulti( pNdr );
  3918. if ( pNdr->IsArray() )
  3919. dim = ((CG_ARRAY *)pNdr)->GetDimensions();
  3920. else // pNdr->IsPointer()
  3921. dim = ((CG_POINTER *)pNdr)->SizedDimensions();
  3922. Buffer.Set( "unsigned long _maxcount_" );
  3923. Buffer.Append( pParamName );
  3924. Buffer.Append( "[" );
  3925. Buffer.Append( dim );
  3926. Buffer.Append( "]" );
  3927. pStream->Write( Buffer );
  3928. pStream->Write( ";" );
  3929. pStream->NewLine( 2 );
  3930. Buffer.Set( "unsigned long _offset_" );
  3931. Buffer.Append( pParamName );
  3932. Buffer.Append( "[" );
  3933. Buffer.Append( dim );
  3934. Buffer.Append( "]" );
  3935. pStream->Write( Buffer );
  3936. pStream->Write( ';' );
  3937. pStream->NewLine();
  3938. Buffer.Set( "unsigned long _length_" );
  3939. Buffer.Append( pParamName );
  3940. Buffer.Append( "[" );
  3941. Buffer.Append( dim );
  3942. Buffer.Append( "]" );
  3943. pStream->Write( Buffer );
  3944. pStream->Write( ';' );
  3945. pStream->NewLine();
  3946. }
  3947. void
  3948. Out_MultiDimVarsInit(
  3949. CCB * pCCB,
  3950. CG_PARAM * pParam
  3951. )
  3952. /*
  3953. Output local resources related to multi-dimensional conf or varying arrays.
  3954. Note that the parameter may be a pointer to multidimensional object.
  3955. */
  3956. {
  3957. ISTREAM * pStream;
  3958. CG_NDR * pNdr;
  3959. char * pParamName;
  3960. long i, dim;
  3961. CSzBuffer Buffer;
  3962. pStream = pCCB->GetStream();
  3963. pParamName = pParam->GetType()->GetSymName();
  3964. pNdr = (CG_NDR *) pParam->GetChild();
  3965. pNdr = GetFirstMulti( pNdr );
  3966. if ( pNdr->IsArray() )
  3967. dim = ((CG_ARRAY *)pNdr)->GetDimensions();
  3968. else // pNdr->IsPointer()
  3969. dim = ((CG_POINTER *)pNdr)->SizedDimensions();
  3970. pStream->NewLine();
  3971. //
  3972. // Max count var.
  3973. //
  3974. /*
  3975. if ( (pNdr->GetCGID() == ID_CG_CONF_ARRAY) ||
  3976. (pNdr->GetCGID() == ID_CG_CONF_VAR_ARRAY) ||
  3977. (pNdr->GetCGID() == ID_CG_SIZE_PTR) ||
  3978. (pNdr->GetCGID() == ID_CG_SIZE_LENGTH_PTR) )
  3979. */
  3980. {
  3981. expr_node * pSizeIsExpr = 0;
  3982. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  3983. {
  3984. Buffer.Set( "_maxcount_" );
  3985. Buffer.Append( pParamName );
  3986. Buffer.Append( "[" );
  3987. Buffer.Append( i );
  3988. Buffer.Append( "] = " );
  3989. pStream->Write( Buffer );
  3990. switch ( pNdr->GetCGID() )
  3991. {
  3992. case ID_CG_CONF_ARRAY :
  3993. case ID_CG_CONF_VAR_ARRAY :
  3994. case ID_CG_CONF_STRING_ARRAY :
  3995. case ID_CG_STRING_ARRAY :
  3996. pSizeIsExpr = ((CG_ARRAY *)pNdr)->GetSizeIsExpr();
  3997. break;
  3998. case ID_CG_SIZE_PTR :
  3999. pSizeIsExpr =
  4000. ((CG_SIZE_POINTER *)pNdr)->GetSizeIsExpr();
  4001. break;
  4002. case ID_CG_SIZE_LENGTH_PTR :
  4003. pSizeIsExpr =
  4004. ((CG_SIZE_LENGTH_POINTER *)pNdr)->GetSizeIsExpr();
  4005. break;
  4006. case ID_CG_SIZE_STRING_PTR :
  4007. pSizeIsExpr =
  4008. ((CG_SIZE_STRING_POINTER *)pNdr)->GetSizeIsExpr();
  4009. break;
  4010. }
  4011. if ( pSizeIsExpr )
  4012. pSizeIsExpr->Print( pStream );
  4013. else
  4014. pStream->Write( '0' );
  4015. pStream->Write( ';' );
  4016. pStream->NewLine();
  4017. }
  4018. }
  4019. pNdr = (CG_NDR *) pParam->GetChild();
  4020. pNdr = GetFirstMulti( pNdr );
  4021. //
  4022. // Offset and Length vars.
  4023. //
  4024. /*
  4025. if ( (pNdr->GetCGID() == ID_CG_VAR_ARRAY) ||
  4026. (pNdr->GetCGID() == ID_CG_CONF_VAR_ARRAY) ||
  4027. (pNdr->GetCGID() == ID_CG_SIZE_LENGTH_PTR) )
  4028. */
  4029. {
  4030. expr_node * pFirstIsExpr = 0;
  4031. expr_node * pLengthIsExpr = 0;
  4032. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  4033. {
  4034. Buffer.Set( "_offset_" );
  4035. Buffer.Append( pParamName );
  4036. Buffer.Append( "[" );
  4037. Buffer.Append( i );
  4038. Buffer.Append( "] = " );
  4039. pStream->Write( Buffer );
  4040. switch ( pNdr->GetCGID() )
  4041. {
  4042. case ID_CG_VAR_ARRAY :
  4043. pFirstIsExpr = ((CG_VARYING_ARRAY *)pNdr)->
  4044. GetFirstIsExpr();
  4045. break;
  4046. case ID_CG_CONF_VAR_ARRAY :
  4047. pFirstIsExpr = ((CG_CONFORMANT_VARYING_ARRAY *)pNdr)->
  4048. GetFirstIsExpr();
  4049. break;
  4050. case ID_CG_CONF_STRING_ARRAY :
  4051. case ID_CG_STRING_ARRAY :
  4052. pFirstIsExpr = 0;
  4053. break;
  4054. case ID_CG_SIZE_LENGTH_PTR :
  4055. pFirstIsExpr = ((CG_SIZE_LENGTH_POINTER *)pNdr)->
  4056. GetFirstIsExpr();
  4057. break;
  4058. }
  4059. if ( pFirstIsExpr )
  4060. pFirstIsExpr->Print( pStream );
  4061. else
  4062. pStream->Write( '0' );
  4063. pStream->Write( ';' );
  4064. pStream->NewLine();
  4065. }
  4066. pNdr = (CG_NDR *) pParam->GetChild();
  4067. pNdr = GetFirstMulti( pNdr );
  4068. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  4069. {
  4070. Buffer.Set( "_length_" );
  4071. Buffer.Append( pParamName );
  4072. Buffer.Append( "[" );
  4073. Buffer.Append( i );
  4074. Buffer.Append( "] = " );
  4075. pStream->Write( Buffer );
  4076. switch ( pNdr->GetCGID() )
  4077. {
  4078. case ID_CG_VAR_ARRAY :
  4079. pLengthIsExpr = ((CG_VARYING_ARRAY *)pNdr)->
  4080. GetLengthIsExpr();
  4081. break;
  4082. case ID_CG_CONF_VAR_ARRAY :
  4083. pLengthIsExpr = ((CG_CONFORMANT_VARYING_ARRAY *)pNdr)->
  4084. GetLengthIsExpr();
  4085. break;
  4086. case ID_CG_CONF_STRING_ARRAY :
  4087. case ID_CG_STRING_ARRAY :
  4088. pLengthIsExpr = 0;
  4089. break;
  4090. case ID_CG_SIZE_LENGTH_PTR :
  4091. pLengthIsExpr = ((CG_SIZE_LENGTH_POINTER *)pNdr)->
  4092. GetLengthIsExpr();
  4093. break;
  4094. }
  4095. if ( pLengthIsExpr )
  4096. pLengthIsExpr->Print( pStream );
  4097. else
  4098. pStream->Write( '0' );
  4099. pStream->Write( ';' );
  4100. pStream->NewLine();
  4101. }
  4102. }
  4103. }
  4104. void
  4105. Out_CheckUnMarshallPastBufferEnd(
  4106. CCB * pCCB,
  4107. ulong size )
  4108. {
  4109. /*
  4110. This method will be called only within the try-except of
  4111. unmarshalling on the server side.
  4112. Generate an expression of the form:
  4113. if( (StubMessage.pBuffer + size) > StubMessage.BufferEnd )
  4114. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  4115. */
  4116. expr_node * pBufferExpr =
  4117. new expr_variable( STUB_MSG_BUFFER_VAR_NAME , 0);
  4118. if ( 0 != size )
  4119. {
  4120. pBufferExpr = new expr_op_binary(
  4121. OP_PLUS,
  4122. pBufferExpr,
  4123. new expr_constant( size ) );
  4124. }
  4125. expr_node * pBufferEndExpr =
  4126. new expr_variable( STUB_MSG_BUFFER_END_VAR_NAME, 0);
  4127. expr_node * pExpr = new expr_relational( OP_GREATER,
  4128. pBufferExpr,
  4129. pBufferEndExpr );
  4130. Out_If( pCCB, pExpr );
  4131. Out_RaiseException( pCCB, "RPC_X_BAD_STUB_DATA" );
  4132. Out_Endif( pCCB );
  4133. }
  4134. void
  4135. Out_TypePicklingInfo(
  4136. CCB * pCCB )
  4137. {
  4138. ISTREAM * pStream;
  4139. MIDL_TYPE_PICKLING_FLAGS Flags;
  4140. unsigned long &intFlags = * (unsigned long *) &Flags;
  4141. static const char *pFlagNames[] =
  4142. {
  4143. "Oicf "
  4144. ,"NewCorrDesc "
  4145. };
  4146. pStream = pCCB->GetStream();
  4147. if ( pCommand->NeedsNDR64Run() )
  4148. {
  4149. pStream->WriteOnNewLine(
  4150. "extern unsigned long * TypePicklingOffsetTable[]; " );
  4151. pStream->NewLine();
  4152. }
  4153. pStream->WriteOnNewLine("static " MIDL_TYPE_PICKLING_INFO_NAME
  4154. " " PICKLING_INFO_STRUCT_NAME " =");
  4155. pStream->IndentInc();
  4156. pStream->WriteOnNewLine( "{" );
  4157. pStream->NewLine();
  4158. pStream->WriteNumber( "0x%x, /* Signature & version: TP 1 */", 0x33205054 );
  4159. intFlags = 0;
  4160. MIDL_ASSERT( pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER_V2 );
  4161. Flags.Oicf = 1;
  4162. if ( pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  4163. Flags.HasNewCorrDesc = 1;
  4164. pStream->NewLine();
  4165. pStream->WriteNumber( "0x%x,", intFlags );
  4166. if ( 0 != intFlags )
  4167. {
  4168. pStream->Write( " /* Flags: " );
  4169. for ( int i = 0; i < sizeof(pFlagNames)/sizeof(char*); i++ )
  4170. {
  4171. if ( intFlags & ( 1 << i ) )
  4172. pStream->Write( pFlagNames[i] );
  4173. }
  4174. pStream->Write( "*/" );
  4175. }
  4176. pStream->WriteOnNewLine( "0," );
  4177. pStream->WriteOnNewLine( "0," );
  4178. pStream->WriteOnNewLine( "0," );
  4179. pStream->WriteOnNewLine( "};" );
  4180. pStream->IndentDec();
  4181. pStream->NewLine();
  4182. }
  4183. void Out_PartialIgnoreClientBufferSize( CCB *pCCB, char *pParamName );
  4184. void
  4185. Out_PartialIgnoreClientMarshall(
  4186. CCB *pCCB,
  4187. char *pParamName )
  4188. {
  4189. ISTREAM *pStream = pCCB->GetStream();
  4190. unsigned short Spaces = sizeof("NdrPartialIgnoreClientMarshall( ")-1;
  4191. pStream->WriteOnNewLine( "NdrPartialIgnoreClientMarshall( (PMIDL_STUB_MESSAGE) &"
  4192. STUB_MESSAGE_VAR_NAME "," );
  4193. pStream->NewLine();
  4194. pStream->Spaces( Spaces );
  4195. pStream->Write( pParamName );
  4196. pStream->Write( " ); " );
  4197. pStream->NewLine();
  4198. }
  4199. void
  4200. Out_PartialIgnoreServerUnmarshall(
  4201. CCB *pCCB,
  4202. char *pParamName )
  4203. {
  4204. ISTREAM *pStream = pCCB->GetStream();
  4205. unsigned short Spaces = sizeof("NdrPartialIgnoreServerUnmarshall( ")-1;
  4206. pStream->WriteOnNewLine( "NdrPartialIgnoreServerUnmarshall( (PMIDL_STUB_MESSAGE) &"
  4207. STUB_MESSAGE_VAR_NAME ", " );
  4208. pStream->NewLine();
  4209. pStream->Spaces( Spaces );
  4210. pStream->Write( "&" );
  4211. pStream->Write( pParamName );
  4212. pStream->Write( " ); " );
  4213. pStream->NewLine();
  4214. }
  4215. void
  4216. Out_PartialIgnoreClientBufferSize(
  4217. CCB *pCCB,
  4218. char *pParamName )
  4219. {
  4220. ISTREAM *pStream = pCCB->GetStream();
  4221. unsigned short Spaces = sizeof("NdrPartialIgnoreClientBufferSize( ")-1;
  4222. pStream->WriteOnNewLine( "NdrPartialIgnoreClientBufferSize( (PMIDL_STUB_MESSAGE) &"
  4223. STUB_MESSAGE_VAR_NAME ", " );
  4224. pStream->NewLine();
  4225. pStream->Spaces( Spaces );
  4226. pStream->Write( pParamName );
  4227. pStream->Write( " ); " );
  4228. pStream->NewLine();
  4229. }
  4230. void
  4231. Out_PartialIgnoreServerInitialize(
  4232. CCB *pCCB,
  4233. char *pParamName,
  4234. long FormatStringOffset )
  4235. {
  4236. ISTREAM *pStream = pCCB->GetStream();
  4237. char Buffer[256];
  4238. unsigned short Spaces = sizeof("NdrPartialIgnoreServerInitialize( ")-1;
  4239. pStream->WriteOnNewLine( "NdrPartialIgnoreServerInitialize( (PMIDL_STUB_MESSAGE) &"
  4240. STUB_MESSAGE_VAR_NAME ", " );
  4241. pStream->NewLine();
  4242. pStream->Spaces( Spaces );
  4243. pStream->Write( "&" );
  4244. pStream->Write( pParamName );
  4245. pStream->Write( ", " );
  4246. pStream->NewLine();
  4247. pStream->Spaces( Spaces );
  4248. sprintf( Buffer, "(PFORMAT_STRING) &" FORMAT_STRING_STRUCT_NAME ".Format[%d] );",
  4249. FormatStringOffset );
  4250. pStream->Write( Buffer );
  4251. pStream->NewLine();
  4252. }