Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5410 lines
149 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. // c compiler doesn't like to convert int to pointer in 64bit.
  1547. // this is checked in runtime. runtime will throw if user doesn't change
  1548. // this when calling RpcRegisterServerIfx.
  1549. if ( pCommand->Is32BitEnv() )
  1550. TempBuf.Append( "0xffffffff" );
  1551. else
  1552. TempBuf.Append( "0xffffffffffffffff" );
  1553. pStream->Write( TempBuf );
  1554. }
  1555. else
  1556. {
  1557. pStream->Write( '0' );
  1558. }
  1559. }
  1560. else if( pCCB->IsMEpV() )
  1561. {
  1562. if( fSide == 1)
  1563. pStream->Write( "&DEFAULT_EPV" );
  1564. else
  1565. pStream->Write( '0' );
  1566. }
  1567. else
  1568. {
  1569. pStream->Write('0');
  1570. }
  1571. //
  1572. // Intepreter info.
  1573. //
  1574. pStream->Write( ',' );
  1575. pStream->NewLine();
  1576. if ( ( pCCB->GetCodeGenSide() == CGSIDE_SERVER &&
  1577. pCCB->GetInterfaceCG()->HasInterpretedProc() ) ||
  1578. ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT &&
  1579. pCCB->GetInterfaceCG()->HasInterpretedCallbackProc() ) )
  1580. {
  1581. RpcIntfFlag |= RPCFLG_HAS_CALLBACK;
  1582. pStream->Write( '&' );
  1583. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  1584. pStream->Write( SERVER_INFO_VAR_NAME );
  1585. }
  1586. else if ( pCommand->NeedsNDR64Run() )
  1587. {
  1588. pStream->Write( '&' );
  1589. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  1590. pStream->Write( MIDL_PROXY_INFO_VAR_NAME );
  1591. }
  1592. else
  1593. {
  1594. pStream->Write( '0' );
  1595. }
  1596. //
  1597. // Emit flags
  1598. //
  1599. pStream->Write( ',' );
  1600. pStream->NewLine();
  1601. if (fHasPipes)
  1602. {
  1603. RpcIntfFlag |= RPC_INTERFACE_HAS_PIPES;
  1604. }
  1605. if ( pCommand->NeedsBothSyntaxes() )
  1606. {
  1607. RpcIntfFlag |= RPCFLG_HAS_MULTI_SYNTAXES;
  1608. }
  1609. pStream->WriteNumber( "0x%08x",(unsigned long )RpcIntfFlag );
  1610. //
  1611. // All Done. Phew !!
  1612. //
  1613. pStream->NewLine();
  1614. pStream->Write( "};" );
  1615. pStream->IndentDec();
  1616. }
  1617. void Out_OneSyntaxInfo( CCB * pCCB,
  1618. BOOL IsForCallback,
  1619. SYNTAX_ENUM syntaxType )
  1620. {
  1621. ISTREAM *pStream = pCCB->GetStream();
  1622. char Buffer[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT+1];
  1623. pStream->Write( "{" );
  1624. pStream->NewLine();
  1625. if ( syntaxType == SYNTAX_NDR64 )
  1626. {
  1627. if ( pCommand->IsSwitchDefined( SWITCH_INTERNAL ) &&
  1628. pCommand->GetEnv() == ENV_WIN32 )
  1629. Out_TransferSyntax( pCCB,
  1630. FakeNDR64TransferSyntaxGuidStrs,
  1631. NDR64_UUID_MAJOR_VERSION,
  1632. NDR64_UUID_MINOR_VERSION );
  1633. else
  1634. Out_TransferSyntax( pCCB,
  1635. NDR64TransferSyntaxGuidStrs,
  1636. NDR64_UUID_MAJOR_VERSION,
  1637. NDR64_UUID_MINOR_VERSION );
  1638. }
  1639. if ( syntaxType == SYNTAX_DCE )
  1640. Out_TransferSyntax( pCCB,
  1641. TransferSyntaxGuidStrs,
  1642. NDR_UUID_MAJOR_VERSION,
  1643. NDR_UUID_MINOR_VERSION );
  1644. pStream->Write( ',' );
  1645. // yongqu: DispatchTable: we need only one dispatch table for now.
  1646. // we need to generate dispatch table for syntax_info in MIDL_SERVER_INFO, where
  1647. // runtime will use it to dispatch call. This include regular server side syntaxinfo
  1648. // and client side callback syntax info.
  1649. if ( ! pCCB->GetInterfaceCG()->IsObject() &&
  1650. ( ( ( pCCB->GetCodeGenSide() == CGSIDE_SERVER ) && !IsForCallback ) ||
  1651. ( ( pCCB->GetCodeGenSide() == CGSIDE_CLIENT ) && IsForCallback ) ) )
  1652. {
  1653. pStream->WriteOnNewLine( "&" );
  1654. sprintf( Buffer,
  1655. "%s%s%s%_DispatchTable,",
  1656. pCCB->GetInterfaceName(),
  1657. ( syntaxType == SYNTAX_NDR64 )?"_NDR64_":"",
  1658. pCCB->GenMangledName() );
  1659. pStream->Write(Buffer );
  1660. }
  1661. else
  1662. pStream->WriteOnNewLine( "0," );
  1663. pStream->NewLine();
  1664. // proc format string.
  1665. if ( syntaxType == SYNTAX_DCE )
  1666. {
  1667. pStream->Write( PROC_FORMAT_STRING_STRING_FIELD );
  1668. }
  1669. else
  1670. {
  1671. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  1672. }
  1673. pStream->Write( ',' );
  1674. pStream->NewLine();
  1675. // The reference to the proc offset table
  1676. if ( SYNTAX_NDR64 == syntaxType)
  1677. pStream->Write( "(unsigned short *) " );
  1678. if ( pCCB->GetInterfaceCG()->IsObject() )
  1679. pStream->Write( '&' );
  1680. if ( IsForCallback )
  1681. pStream->Write( MIDL_CALLBACK_VAR_NAME );
  1682. pStream->Write( pCCB->GetInterfaceCG()->GetSymName() );
  1683. if ( syntaxType == SYNTAX_DCE )
  1684. pStream->Write( FORMAT_STRING_OFFSET_TABLE_NAME );
  1685. else
  1686. pStream->Write( "_Ndr64ProcTable" );
  1687. if ( pCCB->GetInterfaceCG()->IsObject() )
  1688. pStream->Write( "[-3]," );
  1689. else
  1690. pStream->Write( ',' );
  1691. pStream->NewLine();
  1692. //
  1693. if ( syntaxType == SYNTAX_DCE )
  1694. {
  1695. pStream->Write( FORMAT_STRING_STRING_FIELD );
  1696. }
  1697. else
  1698. pStream->Write( "(unsigned char *) &NDR64_MIDL_FORMATINFO" );
  1699. pStream->Write( ',' );
  1700. // TODO: Usermarshal routines?
  1701. pStream->NewLine();
  1702. if ( pCCB->HasQuadrupleRoutines() )
  1703. {
  1704. if ( syntaxType == SYNTAX_DCE )
  1705. pStream->Write( USER_MARSHAL_ROUTINE_TABLE_VAR );
  1706. else
  1707. pStream->Write( NDR64_USER_MARSHAL_ROUTINE_TABLE_VAR );
  1708. pStream->Write( "," );
  1709. }
  1710. else
  1711. pStream->Write( "0," );
  1712. pStream->WriteOnNewLine( "0," );
  1713. pStream->WriteOnNewLine( "0" );
  1714. pStream->NewLine();
  1715. pStream->Write( "}" );
  1716. pStream->NewLine();
  1717. }
  1718. // separate out because this is being called from multiple places.
  1719. void
  1720. Out_TransferSyntax(
  1721. CCB * pCCB,
  1722. GUID_STRS & XferGuidStr,
  1723. unsigned short XferSynMajor,
  1724. unsigned short XferSynMinor )
  1725. {
  1726. CSzBuffer TempBuf;
  1727. ISTREAM *pStream = pCCB->GetStream();
  1728. pStream->Write( '{' );
  1729. Out_Guid( pCCB,
  1730. XferGuidStr
  1731. );
  1732. //
  1733. // Emit the interface version specified by the user.
  1734. //
  1735. TempBuf.Set( ",{" );
  1736. TempBuf.Append( XferSynMajor );
  1737. TempBuf.Append( "," );
  1738. TempBuf.Append( XferSynMinor );
  1739. TempBuf.Append( "}" );
  1740. pStream->Write( TempBuf );
  1741. pStream->Write( "}" );
  1742. }
  1743. void
  1744. Out_MarshallSimple(
  1745. CCB * pCCB,
  1746. RESOURCE * pResource,
  1747. node_skl * pType,
  1748. expr_node * pSource,
  1749. BOOL fIncr,
  1750. unsigned short Size )
  1751. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1752. Routine Description:
  1753. Generate marshalling for a type of a given alignment.
  1754. Arguments:
  1755. pCCB - A pointer to the code generation controller block.
  1756. pResource - The marshalling buffer pointer resource.
  1757. pType - A pointer to the type of the entity being marshalled.
  1758. pSource - A pointer to the expression representing the source of
  1759. the marshalling.
  1760. fIncr - Output pointer increment code.
  1761. Size - The target alignment.
  1762. Return Value:
  1763. Notes:
  1764. ----------------------------------------------------------------------------*/
  1765. {
  1766. BOOL fUnsigned = pType->FInSummary( ATTR_UNSIGNED );
  1767. CSzBuffer TempBuf;
  1768. ISTREAM * pStream = pCCB->GetStream();
  1769. char * pRtn;
  1770. switch( Size )
  1771. {
  1772. case 1: pRtn = "char"; break;
  1773. case 2: pRtn = "short"; break;
  1774. case 4: pRtn = "long"; break;
  1775. case 8: pRtn = "hyper";break;
  1776. default: break;
  1777. }
  1778. pStream->NewLine();
  1779. TempBuf.Set( "*((" );
  1780. if (fUnsigned)
  1781. TempBuf.Append( "unsigned " );
  1782. TempBuf.Append( pRtn );
  1783. TempBuf.Append( "*)" );
  1784. TempBuf.Append( pResource->GetResourceName() );
  1785. TempBuf.Append( ")" );
  1786. if (fIncr)
  1787. TempBuf.Append( "++" );
  1788. TempBuf.Append( " = " );
  1789. pStream->Write( TempBuf );
  1790. pSource->Print( pStream );
  1791. pStream->Write(';');
  1792. }
  1793. void
  1794. Out_AddToBufferPointer(
  1795. CCB * pCCB,
  1796. expr_node * pSource,
  1797. expr_node * pExprAmount )
  1798. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1799. Routine Description:
  1800. Generate a force alignment by the specified alignment.
  1801. Arguments:
  1802. pCCB - A pointer to the code generation controller block.
  1803. pSource - A source pointer
  1804. pExprAmount - The amount to add
  1805. Return Value:
  1806. Notes:
  1807. ----------------------------------------------------------------------------*/
  1808. {
  1809. ISTREAM * pStream = pCCB->GetStream();
  1810. expr_node * pExpr;
  1811. pStream->NewLine();
  1812. pExpr = new expr_b_arithmetic( OP_PLUS,
  1813. pSource,
  1814. pExprAmount
  1815. );
  1816. pExpr = new expr_assign( pSource, pExpr );
  1817. pExpr->Print( pStream );
  1818. pStream->Write(';');
  1819. }
  1820. void
  1821. Out_DispatchTableStuff(
  1822. CCB * pCCB,
  1823. ITERATOR& ProcList,
  1824. short CountOfProcs)
  1825. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1826. Routine Description:
  1827. Generate the dispatch table and related data structures.
  1828. Arguments:
  1829. pCCB - A pointer to the code generation controller block.
  1830. ProcList - A list of all the procedure names in the dispatch table.
  1831. CountOfProcs- The number of procedures in the list.
  1832. Return Value:
  1833. None.
  1834. Notes:
  1835. Generate the dispatch table entries and then the dispatch table stuff.
  1836. ----------------------------------------------------------------------------*/
  1837. {
  1838. // if ( !pCommand->IsFinalProtocolRun() )
  1839. // return;
  1840. ISTREAM * pStream = pCCB->GetStream();
  1841. CSzBuffer TempBuf;
  1842. unsigned short M, m;
  1843. pStream->NewLine();
  1844. //
  1845. // Generate the dispatch table structure name. Currently we just do
  1846. // simple name mangling. This needs to be changed for dce stuff.
  1847. //
  1848. TempBuf.Set( "static " );
  1849. TempBuf.Append( RPC_DISPATCH_FUNCTION_TYPE_NAME );
  1850. TempBuf.Append( " " );
  1851. TempBuf.Append( pCCB->GetInterfaceName() );
  1852. if ( pCommand->IsNDR64Run() )
  1853. TempBuf.Append( "_NDR64_" );
  1854. TempBuf.Append( "_table[] =" );
  1855. pStream->Write( TempBuf );
  1856. pStream->IndentInc();
  1857. pStream->NewLine();
  1858. pStream->Write('{');
  1859. pStream->NewLine();
  1860. //
  1861. // Now print out the names of all the procedures.
  1862. //
  1863. ITERATOR_INIT( ProcList );
  1864. for( int i = 0; i < CountOfProcs; ++i )
  1865. {
  1866. DISPATCH_TABLE_ENTRY * p;
  1867. node_skl * pNode;
  1868. ITERATOR_GETNEXT( ProcList, p );
  1869. if ( p->Flags & DTF_PICKLING_PROC )
  1870. pStream->Write( '0' );
  1871. // BUGBUG: yongqu: code cleanup needed.
  1872. // -----------------------------------------------------------------
  1873. // Server dispatch routine names:
  1874. // raw rpc:
  1875. // sync interface
  1876. // ndr64 only: NdrServerCallNdr64
  1877. // ndr20 only: NdrServerCall2
  1878. // both syntaxes: NdrServerCallAll
  1879. // async interface
  1880. // ndr64 only: Ndr64AsyncServerCall64
  1881. // ndr20 only: NdrAsyncServerCall
  1882. // both syntaxes: Ndr64AsyncServerCallAll
  1883. // ORPC:
  1884. // sync interface
  1885. // ndr64 only: NdrStubCall3
  1886. // both syntaxes: NdrStubCall3
  1887. // ndr20 only: NdrStubCall2
  1888. // async interface
  1889. // ndr64 only: NdrDcomAsyncStubCall
  1890. // ndr20 only: NdrDcomAsyncStubCall
  1891. // both syntaxes: NdrDcomAsyncStubCall
  1892. //
  1893. // reason for so many different entries:
  1894. // In raw RPC, there is one dispatch table for each transfer syntax. RPC runtime
  1895. // will call into the right dispatch table according to the syntax being used.
  1896. // for raw rpc interface, we want to improvement server performance.
  1897. // after runtime select the right transfer syntax and called into
  1898. // right dispatch table, we know where MIDL_SYNTAX_INFO is and we can
  1899. // pickup the right format string etc. directly.
  1900. //
  1901. // In ORPC, all calls will be forwarded to the stub's Invoke, so we don't know
  1902. // which transfer syntax is being used when ole dispatch the call to engine.
  1903. // we need to find out the selected syntax anyway.
  1904. //
  1905. // ------------------------------------------------------------------
  1906. #ifndef TEMPORARY_OI_SERVER_STUBS
  1907. else if ( p->Flags & DTF_INTERPRETER )
  1908. {
  1909. if ( ((node_proc *)p->pNode)->HasAsyncUUID() )
  1910. {
  1911. if ( pCommand->IsNDR64Run() )
  1912. pStream->Write( S_NDR64_CALL_RTN_NAME_DCOM_ASYNC );
  1913. else
  1914. pStream->Write( S_NDR_CALL_RTN_NAME_DCOM_ASYNC );
  1915. }
  1916. else if ( ((node_proc *)p->pNode)->HasAsyncHandle() )
  1917. {
  1918. if ( pCommand->IsNDR64Run() )
  1919. {
  1920. if ( pCommand->NeedsBothSyntaxes() )
  1921. pStream->Write( S_ALL_CALL_RTN_NAME_ASYNC );
  1922. else
  1923. pStream->Write( S_NDR64_CALL_RTN_NAME_ASYNC );
  1924. }
  1925. else
  1926. pStream->Write( S_NDR_CALL_RTN_NAME_ASYNC );
  1927. }
  1928. else if ( ((node_proc *)p->pNode)->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
  1929. {
  1930. if ( pCommand->IsNDR64Run() )
  1931. {
  1932. if ( pCommand->NeedsBothSyntaxes() )
  1933. pStream->Write( S_ALL_CALL_RTN_NAME );
  1934. else
  1935. pStream->Write( S_NDR64_CALL_RTN_NAME );
  1936. }
  1937. else
  1938. pStream->Write( S_NDR_CALL_RTN_NAME_V2 );
  1939. }
  1940. else
  1941. pStream->Write( S_NDR_CALL_RTN_NAME );
  1942. }
  1943. #endif // TEMPORARY_OI_SERVER_STUBS
  1944. else
  1945. {
  1946. pNode = p->pNode;
  1947. TempBuf.Set( pCCB->GetInterfaceName() );
  1948. TempBuf.Append( "_" );
  1949. TempBuf.Append( pNode->GetSymName() );
  1950. pStream->Write( TempBuf );
  1951. }
  1952. pStream->Write( ',' );
  1953. pStream->NewLine();
  1954. }
  1955. //
  1956. // Write out a null and the closing brace.
  1957. //
  1958. pStream->Write( '0' ); pStream->NewLine();
  1959. pStream->Write( "};" );
  1960. pStream->IndentDec();
  1961. //
  1962. // Write out the dispatch table.
  1963. //
  1964. pCCB->GetVersion( &M, &m );
  1965. pStream->NewLine();
  1966. TempBuf.Set( RPC_DISPATCH_TABLE_TYPE_NAME );
  1967. TempBuf.Append( " " );
  1968. TempBuf.Append( pCCB->GetInterfaceName() );
  1969. if ( pCommand->IsNDR64Run() )
  1970. TempBuf.Append( "_NDR64_" );
  1971. TempBuf.Append( pCCB->GenMangledName() );
  1972. TempBuf.Append( "_DispatchTable = " );
  1973. pStream->Write( TempBuf );
  1974. pStream->IndentInc();
  1975. pStream->NewLine();
  1976. pStream->Write( '{' );
  1977. pStream->NewLine();
  1978. TempBuf.Set( "" );
  1979. TempBuf.Append( CountOfProcs );
  1980. TempBuf.Append( "," );
  1981. pStream->Write( TempBuf );
  1982. pStream->NewLine();
  1983. TempBuf.Set( pCCB->GetInterfaceName() );
  1984. if ( pCommand->IsNDR64Run() )
  1985. TempBuf.Append( "_NDR64_" );
  1986. TempBuf.Append( "_table" );
  1987. pStream->Write( TempBuf ); pStream->NewLine(); pStream->Write( "};" );
  1988. pStream->IndentDec();
  1989. pStream->NewLine();
  1990. }
  1991. void
  1992. Out_CallManager(
  1993. CCB * pCCB,
  1994. expr_proc_call * pProcExpr,
  1995. expr_node * pRet,
  1996. BOOL fIsCallback )
  1997. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1998. Routine Description:
  1999. Generate a call to the manager routine.
  2000. Arguments:
  2001. pCCB - A pointer to the code generation controller block.
  2002. pProcExpr - A pointer to the complete procedure expression.
  2003. pRet - An optional pointer to ther return variable.
  2004. fIsCallback - Is this a callback proc ?
  2005. Return Value:
  2006. None.
  2007. Notes:
  2008. Emit code to check for the manager epv also.
  2009. ----------------------------------------------------------------------------*/
  2010. {
  2011. expr_node * pAss = pProcExpr;
  2012. expr_node * pExpr;
  2013. CSzBuffer Buffer;
  2014. ISTREAM * pStream = pCCB->GetStream();
  2015. unsigned short M, m;
  2016. char * pTemp;
  2017. short Indent = 0;
  2018. pCCB->GetStream()->NewLine();
  2019. // If he specified the -epv flag, then dont generate the call to the
  2020. // static procedure. This is the opposite of the dce functionality.
  2021. //
  2022. // In case of -epv:
  2023. // ((interface_...) -> proc( ... );
  2024. // else
  2025. // proc ( ... );
  2026. //
  2027. if( pCCB->IsMEpV() && !fIsCallback )
  2028. {
  2029. pCCB->GetVersion( &M, &m );
  2030. Buffer.Set( "((" );
  2031. Buffer.Append( pCCB->GetInterfaceName() );
  2032. Buffer.Append( pCCB->GenMangledName() );
  2033. Buffer.Append( "_" );
  2034. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2035. Buffer.Append( " *)(" );
  2036. Buffer.Append( PRPC_MESSAGE_MANAGER_EPV_NAME );
  2037. Buffer.Append( "))" );
  2038. pTemp = new char [ strlen( Buffer ) + 1 ];
  2039. strcpy( pTemp, Buffer );
  2040. pExpr = new expr_variable( pTemp );//this has the rhs expr for the
  2041. // manager epv call. Sneaky !
  2042. pExpr = new expr_pointsto( pExpr, pProcExpr );
  2043. pAss = pExpr;
  2044. if( pRet )
  2045. {
  2046. pAss = new expr_assign( pRet, pExpr );
  2047. Indent = 7; // sizeof "_RetVal"
  2048. }
  2049. pStream->NewLine();
  2050. }
  2051. else
  2052. {
  2053. pAss = pProcExpr;
  2054. if( pRet )
  2055. {
  2056. pAss = new expr_assign( pRet, pProcExpr );
  2057. Indent = 7; // sizeof "_RetVal"
  2058. }
  2059. pStream->NewLine();
  2060. }
  2061. pAss->PrintCall( pStream, Indent, 0 );
  2062. }
  2063. void
  2064. Out_FormatInfoExtern( CCB * pCCB )
  2065. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2066. Routine Description:
  2067. Generates the forward extern declaration for the FormatInfo.
  2068. (64bit format string)
  2069. Arguments:
  2070. pCCB - A pointer to the code generation controller block.
  2071. Return Value:
  2072. None.
  2073. Notes:
  2074. ----------------------------------------------------------------------------*/
  2075. {
  2076. ISTREAM * pStream = pCCB->GetStream();
  2077. if ( pCommand->NeedsNDR64Run() )
  2078. {
  2079. pStream->NewLine();
  2080. // BUGBUG: We really don't need this anymore.
  2081. pStream->WriteOnNewLine(
  2082. "static const int NDR64_MIDL_FORMATINFO = 0;" );
  2083. }
  2084. }
  2085. void
  2086. Out_TypeFormatStringExtern( CCB * pCCB )
  2087. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2088. Routine Description:
  2089. Generates the forward extern declaration of the global type format string.
  2090. Arguments:
  2091. pCCB - A pointer to the code generation controller block.
  2092. Return Value:
  2093. None.
  2094. Notes:
  2095. ----------------------------------------------------------------------------*/
  2096. {
  2097. ISTREAM * pStream = pCCB->GetStream();
  2098. if ( pCommand->NeedsNDRRun() )
  2099. {
  2100. pStream->NewLine( 1 );
  2101. pStream->Write( "extern const " FORMAT_STRING_TYPE_NAME " " );
  2102. pStream->Write( FORMAT_STRING_STRUCT_NAME ";" );
  2103. }
  2104. }
  2105. void
  2106. Out_ProcFormatStringExtern( CCB * pCCB )
  2107. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2108. Routine Description:
  2109. Generates the forward extern declaration of the interface-wide
  2110. procedure/parameter format string.
  2111. Arguments:
  2112. pCCB - A pointer to the code generation controller block.
  2113. Return Value:
  2114. None.
  2115. Notes:
  2116. ----------------------------------------------------------------------------*/
  2117. {
  2118. ISTREAM * pStream = pCCB->GetStream();
  2119. if ( pCommand->NeedsNDRRun() )
  2120. {
  2121. pStream->NewLine( 1 );
  2122. pStream->Write( "extern const " PROC_FORMAT_STRING_TYPE_NAME " " );
  2123. pStream->Write( PROC_FORMAT_STRING_STRUCT_NAME ";" );
  2124. }
  2125. }
  2126. void
  2127. Out_StubDescriptorExtern(
  2128. CCB * pCCB )
  2129. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2130. Routine Description:
  2131. Generates the forward extern declaration of the global stub descriptor
  2132. variable.
  2133. Arguments:
  2134. pCCB - A pointer to the code generation controller block.
  2135. Return Value:
  2136. None.
  2137. Notes:
  2138. ----------------------------------------------------------------------------*/
  2139. {
  2140. ISTREAM * pStream = pCCB->GetStream();
  2141. pStream->NewLine( 2 );
  2142. pStream->Write( "extern const " STUB_DESC_STRUCT_TYPE_NAME );
  2143. pStream->Write( ' ' );
  2144. pStream->Write( pCCB->GetInterfaceCG()->GetStubDescName() );
  2145. pStream->Write( ';' );
  2146. pStream->NewLine();
  2147. }
  2148. void
  2149. Out_ProxyInfoExtern( CCB * pCCB )
  2150. {
  2151. ISTREAM * pStream = pCCB->GetStream();
  2152. pStream->NewLine();
  2153. pStream->Write( " extern const " MIDL_PROXY_INFO_TYPE_NAME );
  2154. pStream->Write( ' ' );
  2155. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  2156. pStream->Write( MIDL_PROXY_INFO_VAR_NAME );
  2157. pStream->Write( ';' );
  2158. }
  2159. void
  2160. Out_InterpreterServerInfoExtern( CCB * pCCB )
  2161. {
  2162. ISTREAM * pStream;
  2163. pStream = pCCB->GetStream();
  2164. pStream->NewLine( 2 );
  2165. pStream->Write( "extern const " SERVER_INFO_TYPE_NAME );
  2166. pStream->Write( ' ' );
  2167. pStream->Write( pCCB->GetInterfaceCG()->GetType()->GetSymName() );
  2168. pStream->Write( SERVER_INFO_VAR_NAME );
  2169. pStream->Write( ';' );
  2170. }
  2171. void
  2172. Out_NdrMarshallCall( CCB * pCCB,
  2173. char * pRoutineName,
  2174. char * pParamName,
  2175. long FormatStringOffset,
  2176. BOOL fTakeAddress,
  2177. BOOL fDereference )
  2178. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2179. Routine Description:
  2180. Ouputs a call to an Ndr marshalling routine.
  2181. Arguments:
  2182. pStream - the stream to write the output to
  2183. pRoutineName - the routine name (without the trailing "Marshall")
  2184. pParamName - the name of the parameter/variable being marshalled
  2185. FormatStringOffset - the offset into the format string where this
  2186. parameter's/variable's description begins
  2187. Return Value:
  2188. None.
  2189. Notes:
  2190. ----------------------------------------------------------------------------*/
  2191. {
  2192. ISTREAM * pStream = pCCB->GetStream();
  2193. unsigned short Spaces;
  2194. char Buf[80];
  2195. pStream->NewLine();
  2196. Spaces = (unsigned short)(strlen(pRoutineName) + 10); // strlen("Marshall( ");
  2197. pStream->Write( pRoutineName );
  2198. pStream->Write( "Marshall( (PMIDL_STUB_MESSAGE)& "STUB_MESSAGE_VAR_NAME"," );
  2199. pStream->NewLine();
  2200. pStream->Spaces( Spaces );
  2201. pStream->Write( "(unsigned char *)" );
  2202. if ( fTakeAddress )
  2203. pStream->Write( '&' );
  2204. if ( fDereference )
  2205. pStream->Write( '*' );
  2206. pStream->Write( pParamName );
  2207. pStream->Write( ',' );
  2208. pStream->NewLine();
  2209. pStream->Spaces( Spaces );
  2210. pStream->Write( "(PFORMAT_STRING) &" );
  2211. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2212. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2213. pStream->Write( Buf );
  2214. pStream->NewLine();
  2215. }
  2216. void
  2217. Out_NdrUnmarshallCall( CCB * pCCB,
  2218. char * pRoutineName,
  2219. char * pParamName,
  2220. long FormatStringOffset,
  2221. BOOL fTakeAddress,
  2222. BOOL fMustAllocFlag )
  2223. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2224. Routine Description:
  2225. Outputs a call to an Ndr unmarshalling routine.
  2226. Arguments:
  2227. pStream - the stream to write the output to
  2228. pRoutineName - the routine name (without the trailing "Unmarshall")
  2229. pParamName - the name of the parameter/variable being unmarshalled
  2230. FormatStringOffset - the offset into the format string where this
  2231. parameter's/variable's description begins
  2232. Return Value:
  2233. None.
  2234. Notes:
  2235. ----------------------------------------------------------------------------*/
  2236. {
  2237. ISTREAM * pStream = pCCB->GetStream();
  2238. unsigned short Spaces = 0;
  2239. char Buf[80];
  2240. pStream->NewLine();
  2241. Spaces = (unsigned short)(strlen(pRoutineName) + 12); // strlen("Unmarshall( ");
  2242. pStream->Write( pRoutineName );
  2243. pStream->Write( "Unmarshall( (PMIDL_STUB_MESSAGE) &"STUB_MESSAGE_VAR_NAME"," );
  2244. pStream->NewLine();
  2245. pStream->Spaces( Spaces );
  2246. pStream->Write( "(unsigned char * *)" );
  2247. if ( fTakeAddress )
  2248. pStream->Write( '&' );
  2249. pStream->Write( pParamName );
  2250. pStream->Write( ',' );
  2251. pStream->NewLine();
  2252. pStream->Spaces( Spaces );
  2253. pStream->Write( "(PFORMAT_STRING) &" );
  2254. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2255. sprintf( Buf, ".Format[%d],", FormatStringOffset );
  2256. pStream->Write( Buf );
  2257. pStream->NewLine();
  2258. pStream->Spaces( Spaces );
  2259. pStream->Write( "(unsigned char)" );
  2260. pStream->Write( fMustAllocFlag ? "1" : "0" );
  2261. pStream->Write( " );" );
  2262. pStream->NewLine();
  2263. }
  2264. void
  2265. Out_NdrBufferSizeCall( CCB * pCCB,
  2266. char * pRoutineName,
  2267. char * pParamName,
  2268. long FormatStringOffset,
  2269. BOOL fTakeAddress,
  2270. BOOL fDereference,
  2271. BOOL fPtrToStubMsg )
  2272. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2273. Routine Description:
  2274. Outputs a call to an Ndr buffer sizing routine.
  2275. Arguments:
  2276. pStream - the stream to write the output to
  2277. pRoutineName - the routine name (without the trailing "BufferSize")
  2278. pParamName - the name of the parameter/variable being sized
  2279. FormatStringOffset - the offset into the format string where this
  2280. parameter's/variable's description begins
  2281. fPtrToStubMsg - defines how the StubMsg should be referenced to
  2282. FALSE: &_StubMsg
  2283. TRUE : pStupMsg
  2284. Return Value:
  2285. None.
  2286. Notes:
  2287. ----------------------------------------------------------------------------*/
  2288. {
  2289. ISTREAM * pStream = pCCB->GetStream();
  2290. unsigned short Spaces;
  2291. char Buf[80];
  2292. pStream->NewLine();
  2293. Spaces = (unsigned short)(strlen(pRoutineName) + 12); // strlen("BufferSize( ");
  2294. // Stub message
  2295. pStream->Write( pRoutineName );
  2296. pStream->Write( fPtrToStubMsg ? "BufferSize( (PMIDL_STUB_MESSAGE) "PSTUB_MESSAGE_PAR_NAME","
  2297. : "BufferSize( (PMIDL_STUB_MESSAGE) &"STUB_MESSAGE_VAR_NAME"," );
  2298. pStream->NewLine();
  2299. // Param
  2300. pStream->Spaces( Spaces );
  2301. pStream->Write( "(unsigned char *)" );
  2302. if ( fTakeAddress )
  2303. pStream->Write( '&' );
  2304. if ( fDereference )
  2305. pStream->Write( '*' );
  2306. pStream->Write( pParamName );
  2307. pStream->Write( ',' );
  2308. pStream->NewLine();
  2309. // Format string
  2310. pStream->Spaces( Spaces );
  2311. pStream->Write( "(PFORMAT_STRING) &" );
  2312. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2313. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2314. pStream->Write( Buf );
  2315. pStream->NewLine();
  2316. }
  2317. void
  2318. Out_NdrFreeCall( CCB * pCCB,
  2319. char * pRoutineName,
  2320. char * pParamName,
  2321. long FormatStringOffset,
  2322. BOOL fTakeAddress,
  2323. BOOL fDereference )
  2324. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2325. Routine Description:
  2326. Outputs a call to an Ndr unmarshalling routine.
  2327. Arguments:
  2328. pStream - the stream to write the output to
  2329. pRoutineName - the routine name (without the trailing "Free")
  2330. pParamName - the name of the parameter/variable being freed
  2331. FormatStringOffset - the offset into the format string where this
  2332. parameter's/variable's description begins
  2333. Return Value:
  2334. None.
  2335. Notes:
  2336. ----------------------------------------------------------------------------*/
  2337. {
  2338. ISTREAM * pStream = pCCB->GetStream();
  2339. unsigned short Spaces;
  2340. char Buf[80];
  2341. pStream->NewLine();
  2342. Spaces = (unsigned short)(strlen(pRoutineName) + 6); // strlen("Free( ");
  2343. pStream->Write( pRoutineName );
  2344. pStream->Write( "Free( &"STUB_MESSAGE_VAR_NAME"," );
  2345. pStream->NewLine();
  2346. pStream->Spaces( Spaces );
  2347. pStream->Write( "(unsigned char *)" );
  2348. if ( fTakeAddress )
  2349. pStream->Write( '&' );
  2350. if ( fDereference )
  2351. pStream->Write( '*' );
  2352. pStream->Write( pParamName );
  2353. pStream->Write( ',' );
  2354. pStream->NewLine();
  2355. pStream->Spaces( Spaces );
  2356. pStream->Write( '&' );
  2357. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2358. sprintf( Buf, ".Format[%d] );", FormatStringOffset );
  2359. pStream->Write( Buf );
  2360. pStream->NewLine();
  2361. }
  2362. void
  2363. Out_NdrConvert( CCB * pCCB,
  2364. long FormatStringOffset,
  2365. long ParamTotal,
  2366. unsigned short ProcOptimFlags )
  2367. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2368. Routine Description:
  2369. Outputs a call to NdrConvert().
  2370. Arguments:
  2371. None.
  2372. ----------------------------------------------------------------------------*/
  2373. {
  2374. ISTREAM * pStream = pCCB->GetStream();
  2375. char Buf[80];
  2376. pStream->NewLine();
  2377. pStream->Write( "if ( (" );
  2378. pStream->Write( (pCCB->GetCodeGenSide() == CGSIDE_CLIENT) ?
  2379. RPC_MESSAGE_VAR_NAME"." : PRPC_MESSAGE_VAR_NAME"->" );
  2380. pStream->Write( "DataRepresentation & 0X0000FFFFUL) != "
  2381. "NDR_LOCAL_DATA_REPRESENTATION )" );
  2382. pStream->IndentInc();
  2383. pStream->NewLine();
  2384. if ( ProcOptimFlags & OPTIMIZE_NON_NT351 )
  2385. pStream->Write( NDR_CONVERT_RTN_NAME_V2 );
  2386. else
  2387. pStream->Write( NDR_CONVERT_RTN_NAME );
  2388. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2389. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2390. pStream->Write( "(PFORMAT_STRING) &" );
  2391. pStream->Write( PROC_FORMAT_STRING_STRING_FIELD );
  2392. sprintf( Buf, "[%d]", FormatStringOffset );
  2393. pStream->Write( Buf );
  2394. //
  2395. // NdrConvert2 takes a third parameter.
  2396. //
  2397. if ( ProcOptimFlags & OPTIMIZE_NON_NT351 )
  2398. {
  2399. sprintf( Buf, ", %d", ParamTotal );
  2400. pStream->Write( Buf );
  2401. }
  2402. pStream->Write( " );" );
  2403. pStream->IndentDec();
  2404. pStream->NewLine();
  2405. }
  2406. void
  2407. Out_NdrNsGetBuffer( CCB * pCCB )
  2408. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2409. Routine Description:
  2410. Outputs a call to NdrNsGetBuffer().
  2411. Arguments:
  2412. None.
  2413. ----------------------------------------------------------------------------*/
  2414. {
  2415. ISTREAM * pStream = pCCB->GetStream();
  2416. pStream->NewLine();
  2417. pStream->Write( AUTO_NDR_GB_RTN_NAME );
  2418. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2419. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2420. pStream->Write( STUB_MSG_LENGTH_VAR_NAME ", " );
  2421. if( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  2422. {
  2423. pStream->Write( pCCB->GetInterfaceName() );
  2424. pStream->Write( AUTO_BH_VAR_NAME );
  2425. }
  2426. else
  2427. pStream->Write( '0' );
  2428. pStream->Write( " );" );
  2429. pStream->NewLine();
  2430. }
  2431. void
  2432. Out_NdrGetBuffer( CCB * pCCB )
  2433. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2434. Routine Description:
  2435. Outputs a call to NdrGetBuffer().
  2436. Arguments:
  2437. None.
  2438. ----------------------------------------------------------------------------*/
  2439. {
  2440. ISTREAM * pStream = pCCB->GetStream();
  2441. unsigned short Env;
  2442. Env = pCommand->GetEnv();
  2443. if (pCCB->GetCodeGenSide() == CGSIDE_CLIENT)
  2444. {
  2445. pStream->NewLine();
  2446. pStream->Write( DEFAULT_NDR_GB_RTN_NAME );
  2447. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2448. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2449. pStream->Write( STUB_MSG_LENGTH_VAR_NAME ", " );
  2450. if( pCCB->GetCodeGenSide() == CGSIDE_CLIENT )
  2451. pStream->Write( BH_LOCAL_VAR_NAME );
  2452. else
  2453. pStream->Write( '0' );
  2454. pStream->Write( " );" );
  2455. pStream->NewLine();
  2456. }
  2457. else
  2458. {
  2459. //
  2460. // This saves us at least 15 instructions on an x86 server.
  2461. //
  2462. pStream->NewLine();
  2463. pStream->Write( PRPC_MESSAGE_VAR_NAME "->BufferLength = "
  2464. STUB_MSG_LENGTH_VAR_NAME ";" );
  2465. pStream->NewLine();
  2466. pStream->NewLine();
  2467. pStream->Write( RPC_STATUS_VAR_NAME" = I_RpcGetBuffer( "
  2468. PRPC_MESSAGE_VAR_NAME " ); ");
  2469. pStream->NewLine();
  2470. pStream->Write( "if ( "RPC_STATUS_VAR_NAME" )" );
  2471. pStream->IndentInc();
  2472. pStream->NewLine();
  2473. pStream->Write( "RpcRaiseException( "RPC_STATUS_VAR_NAME" );" );
  2474. pStream->IndentDec();
  2475. pStream->NewLine();
  2476. pStream->NewLine();
  2477. pStream->Write( STUB_MSG_BUFFER_VAR_NAME
  2478. " = (unsigned char *) "
  2479. PRPC_MESSAGE_VAR_NAME "->Buffer;" );
  2480. pStream->NewLine();
  2481. }
  2482. }
  2483. void
  2484. Out_NdrNsSendReceive( CCB * pCCB )
  2485. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2486. Routine Description:
  2487. Outputs a call to NdrNsSendReceive().
  2488. Arguments:
  2489. None.
  2490. ----------------------------------------------------------------------------*/
  2491. {
  2492. ISTREAM * pStream = pCCB->GetStream();
  2493. pStream->NewLine();
  2494. pStream->Write( AUTO_NDR_SR_RTN_NAME );
  2495. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2496. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2497. pStream->Write( "(unsigned char *) "STUB_MESSAGE_VAR_NAME ".Buffer, " );
  2498. pStream->Write( "(RPC_BINDING_HANDLE *) ""&" );
  2499. pStream->Write( pCCB->GetInterfaceName() );
  2500. pStream->Write( AUTO_BH_VAR_NAME );
  2501. pStream->Write( " );" );
  2502. pStream->NewLine();
  2503. }
  2504. void
  2505. Out_NdrSendReceive( CCB * pCCB )
  2506. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2507. Routine Description:
  2508. Outputs a call to NdrSendReceive().
  2509. Arguments:
  2510. None.
  2511. ----------------------------------------------------------------------------*/
  2512. {
  2513. ISTREAM * pStream = pCCB->GetStream();
  2514. pStream->NewLine();
  2515. pStream->Write( DEFAULT_NDR_SR_RTN_NAME );
  2516. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2517. pStream->Write( STUB_MESSAGE_VAR_NAME ", " );
  2518. pStream->Write( "(unsigned char *) "STUB_MESSAGE_VAR_NAME ".Buffer" );
  2519. pStream->Write( " );" );
  2520. pStream->NewLine();
  2521. }
  2522. void
  2523. Out_FreeParamInline( CCB * pCCB )
  2524. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2525. Routine Description:
  2526. Frees a top level param using the current stub message deallocator.
  2527. Arguments:
  2528. pCCB - Code control block.
  2529. ----------------------------------------------------------------------------*/
  2530. {
  2531. CG_PARAM * pParam;
  2532. ISTREAM * pStream;
  2533. pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  2534. pStream = pCCB->GetStream();
  2535. pStream->NewLine();
  2536. pStream->Write( "if ( " );
  2537. pStream->Write( pParam->GetResource()->GetResourceName() );
  2538. pStream->Write( " )" );
  2539. pStream->IndentInc();
  2540. pStream->NewLine();
  2541. pStream->Write( STUB_MESSAGE_VAR_NAME ".pfnFree( " );
  2542. pStream->Write( pParam->GetResource()->GetResourceName() );
  2543. pStream->Write( " );" );
  2544. pStream->IndentDec();
  2545. pStream->NewLine();
  2546. }
  2547. void
  2548. Out_CContextHandleMarshall( CCB * pCCB,
  2549. char * pName,
  2550. BOOL IsPointer )
  2551. {
  2552. ISTREAM * pStream;
  2553. expr_proc_call * pCall;
  2554. expr_node * pHandle;
  2555. expr_node * pExpr;
  2556. pStream = pCCB->GetStream();
  2557. pStream->NewLine();
  2558. pCall = new expr_proc_call( "NdrClientContextMarshall" );
  2559. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2560. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2561. pCall->SetParam( new expr_param( pExpr ) );
  2562. pHandle = new expr_variable( pName );
  2563. if ( IsPointer )
  2564. pHandle = new expr_u_deref( pHandle );
  2565. pHandle = MakeExpressionOfCastToTypeName( CTXT_HDL_C_CONTEXT_TYPE_NAME,
  2566. pHandle );
  2567. pCall->SetParam( new expr_param( pHandle ) );
  2568. pCall->SetParam( new expr_param(
  2569. new expr_variable( IsPointer ? "0" : "1" ) ) );
  2570. pCall->PrintCall( pStream, 0, 0 );
  2571. }
  2572. void
  2573. Out_SContextHandleMarshall( CCB * pCCB,
  2574. char * pName,
  2575. char * pRundownRoutineName )
  2576. {
  2577. ISTREAM * pStream;
  2578. expr_proc_call * pCall;
  2579. expr_node * pHandle;
  2580. expr_node * pRoutine;
  2581. expr_node * pExpr;
  2582. pStream = pCCB->GetStream();
  2583. pStream->NewLine();
  2584. pCall = new expr_proc_call( "NdrServerContextMarshall" );
  2585. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2586. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2587. pCall->SetParam( new expr_param( pExpr ) );
  2588. pHandle = new expr_variable( pName );
  2589. pHandle = MakeExpressionOfCastToTypeName( CTXT_HDL_S_CONTEXT_TYPE_NAME,
  2590. pHandle );
  2591. pCall->SetParam( new expr_param( pHandle ) );
  2592. pRoutine = new expr_variable( pRundownRoutineName );
  2593. pRoutine = MakeExpressionOfCastToTypeName( CTXT_HDL_RUNDOWN_TYPE_NAME,
  2594. pRoutine );
  2595. pCall->SetParam( new expr_param( pRoutine ) );
  2596. pCall->PrintCall( pStream, 0, 0 );
  2597. pStream->NewLine();
  2598. }
  2599. void
  2600. Out_SContextHandleNewMarshall( CCB * pCCB,
  2601. char * pName,
  2602. char * pRundownRoutineName,
  2603. long TypeOffset )
  2604. {
  2605. ISTREAM * pStream;
  2606. unsigned short Spaces;
  2607. char Buf[80];
  2608. pStream = pCCB->GetStream();
  2609. pStream->NewLine();
  2610. pStream->Write( "NdrServerContextNewMarshall(" );
  2611. pStream->NewLine();
  2612. Spaces = 20;
  2613. pStream->Spaces( Spaces );
  2614. pStream->Write( "( PMIDL_STUB_MESSAGE )& "STUB_MESSAGE_VAR_NAME"," );
  2615. pStream->NewLine();
  2616. pStream->Spaces( Spaces );
  2617. pStream->Write( "( " CTXT_HDL_S_CONTEXT_TYPE_NAME " ) " );
  2618. pStream->Write( pName );
  2619. pStream->Write( "," );
  2620. pStream->NewLine();
  2621. pStream->Spaces( Spaces );
  2622. pStream->Write( "( " CTXT_HDL_RUNDOWN_TYPE_NAME " ) " );
  2623. pStream->Write( pRundownRoutineName );
  2624. pStream->Write( "," );
  2625. pStream->NewLine();
  2626. pStream->Spaces( Spaces );
  2627. pStream->Write( "(PFORMAT_STRING) &" );
  2628. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2629. sprintf( Buf, ".Format[%d] );", TypeOffset );
  2630. pStream->Write( Buf );
  2631. pStream->NewLine();
  2632. }
  2633. void
  2634. Out_CContextHandleUnmarshall( CCB * pCCB,
  2635. char * pName,
  2636. BOOL IsPointer,
  2637. BOOL IsReturn )
  2638. {
  2639. ISTREAM * pStream;
  2640. expr_proc_call * pCall;
  2641. expr_node * pHandle;
  2642. expr_node * pExpr;
  2643. pStream = pCCB->GetStream();
  2644. pStream->NewLine();
  2645. if ( IsPointer )
  2646. {
  2647. pStream->Write( '*' );
  2648. pStream->Write( pName );
  2649. pStream->Write( " = (void *)0;" );
  2650. pStream->NewLine();
  2651. }
  2652. else if ( IsReturn )
  2653. {
  2654. pStream->Write( pName );
  2655. pStream->Write( " = 0;" );
  2656. pStream->NewLine();
  2657. }
  2658. pCall = new expr_proc_call( "NdrClientContextUnmarshall" );
  2659. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2660. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2661. pCall->SetParam( new expr_param( pExpr ) );
  2662. pHandle = new expr_variable( pName );
  2663. if ( ! IsPointer && IsReturn )
  2664. pHandle = new expr_u_address( pHandle );
  2665. pHandle = MakeExpressionOfCastPtrToType(
  2666. (node_skl *) new node_def(CTXT_HDL_C_CONTEXT_TYPE_NAME),
  2667. pHandle );
  2668. pCall->SetParam( new expr_param( pHandle ) );
  2669. CG_PROC * pProc;
  2670. pProc = (CG_PROC *)pCCB->GetCGNodeContext();
  2671. char * FullAutoHandleName = NULL;
  2672. if ( pProc->IsAutoHandle() )
  2673. {
  2674. FullAutoHandleName = new char[ strlen( pCCB->GetInterfaceName()) +
  2675. strlen( AUTO_BH_VAR_NAME ) + 1 ];
  2676. strcpy( FullAutoHandleName, pCCB->GetInterfaceName() );
  2677. strcat( FullAutoHandleName, AUTO_BH_VAR_NAME );
  2678. }
  2679. pCall->SetParam( new expr_param(
  2680. new expr_variable( pProc->IsAutoHandle()
  2681. ? FullAutoHandleName
  2682. : BH_LOCAL_VAR_NAME ) ) );
  2683. pCall->PrintCall( pStream, 0, 0 );
  2684. pStream->NewLine();
  2685. }
  2686. void
  2687. Out_SContextHandleUnmarshall( CCB * pCCB,
  2688. char * pName,
  2689. BOOL IsOutOnly )
  2690. {
  2691. ISTREAM * pStream;
  2692. expr_proc_call * pCall;
  2693. expr_node * pExpr;
  2694. pStream = pCCB->GetStream();
  2695. pStream->NewLine();
  2696. if ( IsOutOnly )
  2697. {
  2698. CSzBuffer Buffer;
  2699. Buffer.Set( pName );
  2700. Buffer.Append( " = NDRSContextUnmarshall( (uchar *)0, " );
  2701. Buffer.Append( PRPC_MESSAGE_VAR_NAME "->DataRepresentation" );
  2702. Buffer.Append( " );" );
  2703. pStream->Write(Buffer);
  2704. pStream->NewLine();
  2705. return;
  2706. }
  2707. pCall = new expr_proc_call( "NdrServerContextUnmarshall" );
  2708. pExpr = new expr_u_address( new expr_variable( STUB_MESSAGE_VAR_NAME ));
  2709. pExpr = MakeExpressionOfCastToTypeName( PSTUB_MESSAGE_TYPE_NAME , pExpr );
  2710. pCall->SetParam( new expr_param( pExpr ) );
  2711. pExpr = new expr_variable( pName );
  2712. pExpr = new expr_assign( pExpr, pCall );
  2713. pExpr->PrintCall( pStream, 0, 0 );
  2714. pStream->NewLine();
  2715. }
  2716. void
  2717. Out_SContextHandleNewUnmarshall( CCB * pCCB,
  2718. char * pName,
  2719. BOOL IsOutOnly,
  2720. long TypeOffset )
  2721. {
  2722. ISTREAM * pStream;
  2723. unsigned short Spaces;
  2724. char Buf[80];
  2725. if ( IsOutOnly )
  2726. return;
  2727. pStream = pCCB->GetStream();
  2728. pStream->NewLine();
  2729. pStream->Write( pName );
  2730. pStream->Write( " = " );
  2731. pStream->Write( "NdrServerContextNewUnmarshall(" );
  2732. pStream->NewLine();
  2733. Spaces = (unsigned short)(strlen( pName ) + 7);
  2734. pStream->Spaces( Spaces );
  2735. pStream->Write( "( PMIDL_STUB_MESSAGE )& "STUB_MESSAGE_VAR_NAME"," );
  2736. pStream->NewLine();
  2737. pStream->Spaces( Spaces );
  2738. pStream->Write( "( PFORMAT_STRING )& " );
  2739. pStream->Write( FORMAT_STRING_STRUCT_NAME );
  2740. sprintf( Buf, ".Format[%d] );", TypeOffset );
  2741. pStream->Write( Buf );
  2742. pStream->NewLine();
  2743. }
  2744. void
  2745. Out_NdrFreeBuffer( CCB * pCCB )
  2746. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2747. Routine Description:
  2748. Outputs a call to NdrFreeBuffer().
  2749. Arguments:
  2750. None.
  2751. ----------------------------------------------------------------------------*/
  2752. {
  2753. ISTREAM * pStream = pCCB->GetStream();
  2754. pStream->NewLine();
  2755. pStream->Write( DEFAULT_NDR_FB_RTN_NAME );
  2756. pStream->Write( "( (PMIDL_STUB_MESSAGE) &" );
  2757. pStream->Write( STUB_MESSAGE_VAR_NAME );
  2758. pStream->Write( " );" );
  2759. pStream->NewLine();
  2760. }
  2761. void
  2762. Out_FullPointerInit( CCB * pCCB )
  2763. {
  2764. ISTREAM * pStream = pCCB->GetStream();
  2765. expr_proc_call * pProc;
  2766. expr_node * pExpr;
  2767. pProc = new expr_proc_call( FULL_POINTER_INIT_RTN_NAME );
  2768. pProc->SetParam( new expr_param(
  2769. new expr_constant( (long) 0 ) ) );
  2770. pProc->SetParam( new expr_param(
  2771. new expr_variable(
  2772. (pCCB->GetCodeGenSide() == CGSIDE_SERVER)
  2773. ? "XLAT_SERVER" : "XLAT_CLIENT" ) ) );
  2774. pExpr = new expr_variable( STUB_MESSAGE_VAR_NAME ".FullPtrXlatTables" );
  2775. pExpr = new expr_assign( pExpr, pProc );
  2776. pStream->NewLine();
  2777. pExpr->PrintCall( pStream, 0, 0 );
  2778. pStream->NewLine();
  2779. }
  2780. void
  2781. Out_FullPointerFree( CCB * pCCB )
  2782. {
  2783. ISTREAM * pStream = pCCB->GetStream();
  2784. expr_proc_call * pProc;
  2785. pProc = new expr_proc_call( FULL_POINTER_FREE_RTN_NAME );
  2786. pProc->SetParam( new expr_param(
  2787. new expr_variable(
  2788. STUB_MESSAGE_VAR_NAME ".FullPtrXlatTables" ) ) );
  2789. pStream->NewLine();
  2790. pProc->PrintCall( pStream, 0, 0 );
  2791. pStream->NewLine();
  2792. }
  2793. void
  2794. Out_NdrInitStackTop( CCB * pCCB )
  2795. {
  2796. ISTREAM * pStream;
  2797. pStream = pCCB->GetStream();
  2798. pStream->NewLine();
  2799. pStream->Write( STUB_MESSAGE_VAR_NAME ".StackTop = 0;" );
  2800. pStream->NewLine();
  2801. }
  2802. void
  2803. Out_DispatchTableTypedef(
  2804. CCB * pCCB,
  2805. PNAME pInterfaceName,
  2806. ITERATOR& ProcNodeList,
  2807. int flag )
  2808. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2809. Routine Description:
  2810. Output the dispatch table typedef.
  2811. Arguments:
  2812. pCCB - A pointer to the code gen controller block.
  2813. pInterfacename - The base interface name.
  2814. ProcNodeList - The list of procedure node_proc nodes.
  2815. flag - 0 : normal, 1 : callback
  2816. Return Value:
  2817. None.
  2818. Notes:
  2819. ----------------------------------------------------------------------------*/
  2820. {
  2821. ISTREAM * pStream = pCCB->GetStream();
  2822. CSzBuffer Buffer;
  2823. node_skl * pNode;
  2824. node_pointer * pPtr;
  2825. node_id * pID;
  2826. unsigned short M, m;
  2827. DISPATCH_TABLE_ENTRY * pDEntry;
  2828. if( flag == 1 )
  2829. return;
  2830. pCCB->GetVersion( &M, &m );
  2831. pStream->NewLine();
  2832. if( flag == 0 )
  2833. {
  2834. Buffer.Set( "typedef struct _" );
  2835. Buffer.Append( pInterfaceName );
  2836. Buffer.Append( pCCB->GenMangledName() );
  2837. Buffer.Append( "_" );
  2838. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2839. pStream->Write( Buffer );
  2840. pStream->NewLine();
  2841. pStream->IndentInc();
  2842. pStream->Write('{');
  2843. pStream->NewLine();
  2844. }
  2845. #if 0
  2846. else
  2847. {
  2848. Buffer.Set( "typedef struct _" );
  2849. Buffer.Append( pInterfaceName );
  2850. Buffer.Append( pCCB->GenMangledName() );
  2851. Buffer.Append( "_CLIENT_EPV" );
  2852. }
  2853. #endif // 0
  2854. ITERATOR_INIT( ProcNodeList );
  2855. while( ITERATOR_GETNEXT( ProcNodeList, pDEntry ) )
  2856. {
  2857. pNode = pDEntry->pNode;
  2858. pID = new node_id( pNode->GetSymName() );
  2859. pPtr = new node_pointer( pNode );
  2860. pID->SetBasicType( pPtr );
  2861. pPtr->SetBasicType( pNode );
  2862. pID->SetEdgeType( EDGE_DEF );
  2863. pPtr->SetEdgeType( EDGE_USE );
  2864. pID->PrintType( PRT_PROC_PTR_PROTOTYPE, pStream, (node_skl *)0 );
  2865. }
  2866. pStream->NewLine();
  2867. pStream->IndentDec();
  2868. if( flag == 0 )
  2869. {
  2870. Buffer.Set( "} " );
  2871. Buffer.Append( pInterfaceName );
  2872. Buffer.Append( pCCB->GenMangledName() );
  2873. Buffer.Append( "_" );
  2874. Buffer.Append( pCCB->IsOldNames() ?"SERVER_EPV" : "epv_t" );
  2875. Buffer.Append( ";" );
  2876. }
  2877. else
  2878. {
  2879. Buffer.Set( "} " );
  2880. Buffer.Append( pInterfaceName );
  2881. Buffer.Append( pCCB->GenMangledName() );
  2882. Buffer.Append( "_" );
  2883. Buffer.Append( (flag == 0) ?"SERVER" : "CLIENT" );
  2884. Buffer.Append( "_EPV;" );
  2885. }
  2886. pStream->Write( Buffer );
  2887. pStream->NewLine();
  2888. }
  2889. void
  2890. Out_ManagerEpv(
  2891. CCB * pCCB,
  2892. PNAME pInterfaceName,
  2893. ITERATOR& ProcNodeList,
  2894. short Count )
  2895. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2896. Routine Description:
  2897. Output the manager epv table.
  2898. Arguments:
  2899. pCCB - A pointer to the code gen controller block.
  2900. pInterfacename - The base interface name.
  2901. ProcNodeList - The list of procedure node_proc nodes.
  2902. Count - Count of procs.
  2903. Return Value:
  2904. None.
  2905. Notes:
  2906. ----------------------------------------------------------------------------*/
  2907. {
  2908. if ( !pCommand->IsFinalProtocolRun() )
  2909. return;
  2910. ISTREAM * pStream = pCCB->GetStream();
  2911. CSzBuffer Buffer;
  2912. unsigned short M, m;
  2913. DISPATCH_TABLE_ENTRY * pDEntry;
  2914. pCCB->GetVersion( &M, &m );
  2915. pStream->NewLine();
  2916. Buffer.Set( "static " );
  2917. Buffer.Append( pInterfaceName );
  2918. Buffer.Append( pCCB->GenMangledName() );
  2919. Buffer.Append( "_" );
  2920. Buffer.Append( pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  2921. Buffer.Append( " DEFAULT_EPV = " );
  2922. pStream->Write( Buffer );
  2923. pStream->IndentInc();
  2924. pStream->NewLine();
  2925. pStream->Write('{');
  2926. pStream->NewLine();
  2927. ITERATOR_INIT( ProcNodeList );
  2928. while( ITERATOR_GETNEXT( ProcNodeList, pDEntry ) )
  2929. {
  2930. char * pPrefix = pCommand->GetUserPrefix( PREFIX_SERVER_MGR );
  2931. if ( pPrefix )
  2932. pStream->Write( pPrefix );
  2933. pStream->Write( pDEntry->pNode->GetSymName() );
  2934. if( --Count != 0 )
  2935. {
  2936. pStream->Write( ',' );
  2937. pStream->NewLine();
  2938. }
  2939. }
  2940. pStream->IndentDec();
  2941. pStream->NewLine();
  2942. pStream->Write( "};" );
  2943. pStream->NewLine();
  2944. }
  2945. void
  2946. Out_GenHdlPrototypes(
  2947. CCB * pCCB,
  2948. ITERATOR& List )
  2949. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2950. Routine Description:
  2951. Output a list of generic handle prototypes.
  2952. Arguments:
  2953. pCCB - A pointer to the code gen controller block.
  2954. List - List of type nodes.
  2955. Return Value:
  2956. Notes:
  2957. ----------------------------------------------------------------------------*/
  2958. {
  2959. ISTREAM * pStream = pCCB->GetStream();
  2960. CSzBuffer Buffer;
  2961. node_skl* pN;
  2962. pStream->NewLine();
  2963. while( ITERATOR_GETNEXT( List, pN ) )
  2964. {
  2965. PNAME pName = pN->GetSymName();
  2966. Buffer.Set( "handle_t __RPC_USER " );
  2967. Buffer.Append( pName );
  2968. Buffer.Append( "_bind ( " );
  2969. Buffer.Append( pName );
  2970. Buffer.Append( " );" );
  2971. pStream->Write( Buffer );
  2972. pStream->NewLine();
  2973. Buffer.Set( "void __RPC_USER " );
  2974. Buffer.Append( pName );
  2975. Buffer.Append( "_unbind( " );
  2976. Buffer.Append( pName );
  2977. Buffer.Append( ", handle_t );" );
  2978. pStream->Write( Buffer );
  2979. pStream->NewLine();
  2980. }
  2981. }
  2982. void
  2983. Out_CtxtHdlPrototypes(
  2984. CCB * pCCB,
  2985. ITERATOR& List )
  2986. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2987. Routine Description:
  2988. Output a list of context handle prototypes.
  2989. Arguments:
  2990. pCCB - A pointer to the code gen controller block.
  2991. List - List of type nodes.
  2992. Return Value:
  2993. Notes:
  2994. ----------------------------------------------------------------------------*/
  2995. {
  2996. ISTREAM * pStream = pCCB->GetStream();
  2997. CSzBuffer Buffer;
  2998. node_skl* pN;
  2999. pStream->NewLine();
  3000. while( ITERATOR_GETNEXT( List, pN ) )
  3001. {
  3002. PNAME pName = pN->GetSymName();
  3003. // A name can be a "" (an empty string).
  3004. if ( strlen(pName) )
  3005. {
  3006. Buffer.Set( "void __RPC_USER " );
  3007. Buffer.Append( pName );
  3008. Buffer.Append( "_rundown( " );
  3009. Buffer.Append( pName );
  3010. Buffer.Append( " );" );
  3011. pStream->Write( Buffer );
  3012. pStream->NewLine();
  3013. }
  3014. }
  3015. }
  3016. void
  3017. Out_TransmitAsPrototypes(
  3018. CCB * pCCB,
  3019. ITERATOR& ListOfPresentedTypes )
  3020. {
  3021. ISTREAM * pStream = pCCB->GetStream();
  3022. ISTREAM * pMemoryStream = new ISTREAM;
  3023. CSzBuffer Buffer;
  3024. node_skl * pXmittedType;
  3025. node_skl * pPresentedType;
  3026. char * pMemBufferStart = pMemoryStream->GetCurrentPtr();
  3027. pStream->NewLine();
  3028. while( ITERATOR_GETNEXT( ListOfPresentedTypes, pPresentedType ) )
  3029. {
  3030. // we reuse the same memory stream.
  3031. pMemoryStream->SetCurrentPtr( pMemBufferStart );
  3032. pXmittedType = ((node_def *)pPresentedType)->GetTransmittedType();
  3033. PNAME pPresentedTypeName = pPresentedType->GetSymName();
  3034. PNAME pTransmittedTypeName= pXmittedType->GetSymName();
  3035. pXmittedType->PrintType( PRT_TYPE_SPECIFIER,
  3036. pMemoryStream, // into stream
  3037. (node_skl *)0 // no parent.
  3038. );
  3039. //
  3040. // The type spec is in the stream, except that it needs a terminating
  3041. // null to use it as a string.
  3042. //
  3043. pTransmittedTypeName = pMemBufferStart;
  3044. *(pMemoryStream->GetCurrentPtr()) = 0;
  3045. pStream->NewLine();
  3046. Buffer.Set( "void __RPC_USER " );
  3047. Buffer.Append( pPresentedTypeName );
  3048. Buffer.Append( "_to_xmit( " );
  3049. Buffer.Append( pPresentedTypeName );
  3050. Buffer.Append( " *, " );
  3051. Buffer.Append( pTransmittedTypeName );
  3052. Buffer.Append( " * * );" );
  3053. pStream->Write( Buffer );
  3054. pStream->NewLine();
  3055. Buffer.Set( "void __RPC_USER " );
  3056. Buffer.Append( pPresentedTypeName );
  3057. Buffer.Append( "_from_xmit( " );
  3058. Buffer.Append( pTransmittedTypeName );
  3059. Buffer.Append( " *, " );
  3060. Buffer.Append( pPresentedTypeName );
  3061. Buffer.Append( " * );" );
  3062. pStream->Write( Buffer );
  3063. pStream->NewLine();
  3064. Buffer.Set( "void __RPC_USER " );
  3065. Buffer.Append( pPresentedTypeName );
  3066. Buffer.Append( "_free_inst( " );
  3067. Buffer.Append( pPresentedTypeName );
  3068. Buffer.Append( " * );" );
  3069. pStream->Write( Buffer );
  3070. pStream->NewLine();
  3071. Buffer.Set( "void __RPC_USER " );
  3072. Buffer.Append( pPresentedTypeName );
  3073. Buffer.Append( "_free_xmit( " );
  3074. Buffer.Append( pTransmittedTypeName );
  3075. Buffer.Append( " * );" );
  3076. pStream->Write( Buffer );
  3077. pStream->NewLine();
  3078. }
  3079. delete pMemoryStream;
  3080. }
  3081. void
  3082. Out_RepAsPrototypes(
  3083. CCB * pCCB,
  3084. ITERATOR& ListOfRepAsWireTypes )
  3085. {
  3086. ISTREAM * pStream = pCCB->GetStream();
  3087. CSzBuffer Buffer;
  3088. node_skl * pWireType;
  3089. pStream->NewLine();
  3090. while( ITERATOR_GETNEXT( ListOfRepAsWireTypes, pWireType ) )
  3091. {
  3092. PNAME pRepAsTypeName = ((node_def *)pWireType)->GetRepresentationName();
  3093. PNAME pTransmittedTypeName= pWireType->GetSymName();
  3094. pStream->NewLine();
  3095. Buffer.Set( "void __RPC_USER " );
  3096. Buffer.Append( pTransmittedTypeName );
  3097. Buffer.Append( "_from_local( " );
  3098. Buffer.Append( pRepAsTypeName );
  3099. Buffer.Append( " *, " );
  3100. Buffer.Append( pTransmittedTypeName );
  3101. Buffer.Append( " * * );" );
  3102. pStream->Write( Buffer );
  3103. pStream->NewLine();
  3104. Buffer.Set( "void __RPC_USER ");
  3105. Buffer.Append( pTransmittedTypeName );
  3106. Buffer.Append( "_to_local( " );
  3107. Buffer.Append( pTransmittedTypeName );
  3108. Buffer.Append( " *, " );
  3109. Buffer.Append( pRepAsTypeName );
  3110. Buffer.Append( " * );" );
  3111. pStream->Write( Buffer );
  3112. pStream->NewLine();
  3113. Buffer.Set(" void __RPC_USER " );
  3114. Buffer.Append( pTransmittedTypeName );
  3115. Buffer.Append( "_free_inst( " );
  3116. Buffer.Append( pTransmittedTypeName );
  3117. Buffer.Append( " * );" );
  3118. pStream->Write( Buffer );
  3119. pStream->NewLine();
  3120. Buffer.Set( "void __RPC_USER " );
  3121. Buffer.Append( pTransmittedTypeName );
  3122. Buffer.Append( "_free_local( " );
  3123. Buffer.Append( pRepAsTypeName );
  3124. Buffer.Append( " * );" );
  3125. pStream->Write( Buffer );
  3126. pStream->NewLine();
  3127. }
  3128. }
  3129. #define USRM_SIZE 0
  3130. #define USRM_FREE 3
  3131. char * UserMProtoName[ 4 ] =
  3132. {
  3133. USER_MARSHAL_SIZE "( ",
  3134. USER_MARSHAL_MARSHALL "( ",
  3135. USER_MARSHAL_UNMARSHALL "(",
  3136. USER_MARSHAL_FREE "( "
  3137. };
  3138. char * NDR64_UserMProtoName[ 4 ] =
  3139. {
  3140. NDR64_USER_MARSHAL_SIZE "( ",
  3141. NDR64_USER_MARSHAL_MARSHALL "( ",
  3142. NDR64_USER_MARSHAL_UNMARSHALL "(",
  3143. NDR64_USER_MARSHAL_FREE "( "
  3144. };
  3145. void
  3146. Out_UserMarshalSingleProto(
  3147. ISTREAM * pStream,
  3148. char * pTypeName,
  3149. int fProto,
  3150. SYNTAX_ENUM SyntaxType )
  3151. {
  3152. switch ( fProto )
  3153. {
  3154. case USRM_SIZE:
  3155. pStream->Write( "unsigned long __RPC_USER " );
  3156. break;
  3157. case USRM_FREE:
  3158. pStream->Write( "void __RPC_USER " );
  3159. break;
  3160. default:
  3161. pStream->Write( "unsigned char * __RPC_USER " );
  3162. break;
  3163. }
  3164. pStream->Write( pTypeName );
  3165. if ( SyntaxType == SYNTAX_NDR64 )
  3166. pStream->Write( NDR64_UserMProtoName[ fProto ] );
  3167. else
  3168. pStream->Write( UserMProtoName[ fProto ] );
  3169. pStream->Write( "unsigned long *, " ); // flags
  3170. switch ( fProto )
  3171. {
  3172. case USRM_SIZE:
  3173. pStream->Write( "unsigned long , " );
  3174. break;
  3175. case USRM_FREE:
  3176. break;
  3177. default:
  3178. pStream->Write( "unsigned char *, " );
  3179. break;
  3180. }
  3181. pStream->Write( pTypeName );
  3182. pStream->Write( " * ); " );
  3183. pStream->NewLine();
  3184. }
  3185. void
  3186. Out_OneUserMarshalProtoTypes(
  3187. CCB * pCCB,
  3188. ITERATOR& ListOfPresentedTypes,
  3189. SYNTAX_ENUM SyntaxType )
  3190. {
  3191. USER_MARSHAL_CONTEXT * pUsrContext;
  3192. ISTREAM * pStream = pCCB->GetStream();
  3193. ITERATOR_INIT( ListOfPresentedTypes );
  3194. while( ITERATOR_GETNEXT( ListOfPresentedTypes, pUsrContext ) )
  3195. {
  3196. pStream->NewLine();
  3197. for (int i=0; i < 4; i++)
  3198. Out_UserMarshalSingleProto( pStream,
  3199. pUsrContext->pTypeName,
  3200. i,
  3201. SyntaxType );
  3202. }
  3203. }
  3204. void
  3205. Out_UserMarshalPrototypes(
  3206. CCB * pCCB,
  3207. ITERATOR& ListOfPresentedTypes )
  3208. {
  3209. if ( pCommand->NeedsNDRRun() )
  3210. Out_OneUserMarshalProtoTypes( pCCB, ListOfPresentedTypes, SYNTAX_DCE );
  3211. if ( pCommand->NeedsNDR64Run() ||
  3212. pCommand->NeedsNDR64Header() )
  3213. Out_OneUserMarshalProtoTypes( pCCB, ListOfPresentedTypes, SYNTAX_NDR64 );
  3214. }
  3215. char CsNetSizePrototype[] =
  3216. "_net_size(\n"
  3217. " RPC_BINDING_HANDLE hBinding,\n"
  3218. " unsigned long ulNetworkCodeSet,\n"
  3219. " unsigned long ulLocalBufferSize,\n"
  3220. " IDL_CS_CONVERT * conversionType,\n"
  3221. " unsigned long * pulNetworkBufferSize,\n"
  3222. " error_status_t * pStatus);\n\n";
  3223. char CsLocalSizePrototype[] =
  3224. "_local_size(\n"
  3225. " RPC_BINDING_HANDLE hBinding,\n"
  3226. " unsigned long ulNetworkCodeSet,\n"
  3227. " unsigned long ulNetworkBufferSize,\n"
  3228. " IDL_CS_CONVERT * conversionType,\n"
  3229. " unsigned long * pulLocalBufferSize,\n"
  3230. " error_status_t * pStatus);\n\n";
  3231. char CsToNetCsPrototype[] =
  3232. "_to_netcs(\n"
  3233. " RPC_BINDING_HANDLE hBinding,\n"
  3234. " unsigned long ulNetworkCodeSet,\n"
  3235. " void * pLocalData,\n"
  3236. " unsigned long ulLocalDataLength,\n"
  3237. " byte * pNetworkData,\n"
  3238. " unsigned long * pulNetworkDataLength,\n"
  3239. " error_status_t * pStatus);\n\n";
  3240. char CsFromNetCsPrototype[] =
  3241. "_from_netcs(\n"
  3242. " RPC_BINDING_HANDLE hBinding,\n"
  3243. " unsigned long ulNetworkCodeSet,\n"
  3244. " byte * pNetworkData,\n"
  3245. " unsigned long ulNetworkDataLength,\n"
  3246. " unsigned long ulLocalBufferSize,\n"
  3247. " void * pLocalData,\n"
  3248. " unsigned long * pulLocalDataLength,\n"
  3249. " error_status_t * pStatus);\n\n";
  3250. void
  3251. Out_CSSizingAndConversionPrototypes(
  3252. CCB * pCCB,
  3253. ITERATOR & types )
  3254. {
  3255. PNAME pTypeName;
  3256. ISTREAM * pStream = pCCB->GetStream();
  3257. ITERATOR_INIT( types );
  3258. while ( ITERATOR_GETNEXT( types, pTypeName ) )
  3259. {
  3260. pStream->Write( "void __RPC_USER " );
  3261. pStream->Write( pTypeName );
  3262. pStream->Write( CsNetSizePrototype );
  3263. pStream->Write( "void __RPC_USER " );
  3264. pStream->Write( pTypeName );
  3265. pStream->Write( CsLocalSizePrototype );
  3266. pStream->Write( "void __RPC_USER " );
  3267. pStream->Write( pTypeName );
  3268. pStream->Write( CsToNetCsPrototype );
  3269. pStream->Write( "void __RPC_USER " );
  3270. pStream->Write( pTypeName );
  3271. pStream->Write( CsFromNetCsPrototype );
  3272. }
  3273. }
  3274. void
  3275. Out_CallAsServerPrototypes(
  3276. CCB * pCCB,
  3277. ITERATOR& ListOfCallAsRoutines )
  3278. {
  3279. ISTREAM * pStream = pCCB->GetStream();
  3280. node_proc * pProc;
  3281. pStream->NewLine();
  3282. while( ITERATOR_GETNEXT( ListOfCallAsRoutines, pProc ) )
  3283. {
  3284. // keep these on the stack...
  3285. CSzBuffer NewName;
  3286. char TempBuf[40];
  3287. node_call_as * pCallAs = (node_call_as *)
  3288. pProc->GetAttribute( ATTR_CALL_AS );
  3289. unsigned short M, m;
  3290. node_interface * pIntf = pProc->GetMyInterfaceNode();
  3291. // don't emit the server prototype for object routines
  3292. if ( pIntf->FInSummary( ATTR_OBJECT ) )
  3293. continue;
  3294. // local stub routine, with remote param list
  3295. node_proc NewStubProc( pProc );
  3296. pIntf->GetVersionDetails( &M, &m );
  3297. sprintf( TempBuf,
  3298. "_v%d_%d",
  3299. M,
  3300. m );
  3301. NewName.Set( pIntf->GetSymName() );
  3302. NewName.Append( TempBuf );
  3303. NewName.Append( "_" );
  3304. NewName.Append( pCallAs->GetCallAsName() );
  3305. NewStubProc.SetSymName( NewName );
  3306. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI,
  3307. pCCB->GetStream(),
  3308. NULL ,
  3309. pIntf );
  3310. pCCB->GetStream()->NewLine();
  3311. }
  3312. }
  3313. void
  3314. Out_NotifyPrototypes(
  3315. CCB * pCCB,
  3316. ITERATOR& ListOfNotifyProcedures)
  3317. /*
  3318. We generate
  3319. void <proc_name>_notify( void );
  3320. void <proc_name>_notify_flag( boolean );
  3321. */
  3322. {
  3323. ISTREAM * pStream = pCCB->GetStream();
  3324. CG_PROC * pProcCG;
  3325. node_proc * pProc;
  3326. node_skl * pRet;
  3327. BOOL fHasFlag;
  3328. GetBaseTypeNode( &pRet, SIGN_UNDEF, SIZE_UNDEF, TYPE_VOID );
  3329. pStream->NewLine();
  3330. while( ITERATOR_GETNEXT( ListOfNotifyProcedures, pProcCG ) )
  3331. {
  3332. // keep these on the stack...
  3333. CSzBuffer NewName;
  3334. node_proc NewStubProc( 0, 0 );
  3335. node_param FlagParam;
  3336. fHasFlag = pProcCG->HasNotifyFlag();
  3337. pProc = (node_proc *) pProcCG->GetType();
  3338. NewStubProc.SetChild( pRet );
  3339. if ( fHasFlag )
  3340. {
  3341. node_skl * pParamType;
  3342. GetBaseTypeNode( &pParamType, SIGN_UNDEF, SIZE_UNDEF, TYPE_BOOLEAN );
  3343. FlagParam.SetChild( pParamType );
  3344. FlagParam.SetSymName( NOTIFY_FLAG_VAR_NAME );
  3345. NewStubProc.SetFirstMember( & FlagParam );
  3346. }
  3347. NewName.Set( pProc->GetSymName() );
  3348. NewName.Append( (fHasFlag ? NOTIFY_FLAG_SUFFIX
  3349. : NOTIFY_SUFFIX ) );
  3350. NewStubProc.SetSymName( NewName );
  3351. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI,
  3352. pStream,
  3353. NULL );
  3354. pCCB->GetStream()->NewLine();
  3355. }
  3356. }
  3357. void
  3358. Out_PatchReference(
  3359. CCB * pCCB,
  3360. expr_node * pDest,
  3361. expr_node * pSrc,
  3362. BOOL fIncr )
  3363. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3364. Routine Description:
  3365. Output a patch of a pointer to the source pointer.
  3366. Arguments:
  3367. pCCB - The cg cont. block.
  3368. pDest - The destination expression
  3369. pSrc - The source expression.
  3370. fIncr - Should we increment the ptr ?
  3371. Return Value:
  3372. None.
  3373. Notes:
  3374. Both the expressions must be pointers.
  3375. Cast the source expression to the destination.
  3376. ----------------------------------------------------------------------------*/
  3377. {
  3378. ISTREAM * pStream = pCCB->GetStream();
  3379. node_skl * pType = pDest->GetType();
  3380. NODE_T NT = pType->NodeKind();
  3381. expr_node * pCast;
  3382. expr_node * pAss;
  3383. if( (NT == NODE_ID) || (NT == NODE_PARAM) || (NT == NODE_FIELD) )
  3384. {
  3385. pType = pType->GetBasicType();
  3386. }
  3387. pCast = (expr_node *) new expr_cast( pType, pSrc );
  3388. if( fIncr )
  3389. pCast = (expr_node *) new expr_post_incr( pCast );
  3390. pAss = (expr_node *) new expr_assign( pDest, pCast );
  3391. pStream->NewLine();
  3392. pAss->Print( pStream );
  3393. pStream->Write(';');
  3394. }
  3395. void
  3396. Out_Endif( CCB * pCCB )
  3397. {
  3398. pCCB->GetStream()->NewLine();
  3399. pCCB->GetStream()->Write( '}' );
  3400. Out_IndentDec( pCCB );
  3401. }
  3402. void
  3403. Out_If(
  3404. CCB * pCCB,
  3405. expr_node * pExpr )
  3406. {
  3407. ISTREAM * pStream = pCCB->GetStream();
  3408. pStream->NewLine();
  3409. pStream->Write( "if(" );
  3410. pExpr->Print( pStream );
  3411. pStream->Write( ')' );
  3412. Out_IndentInc( pCCB );
  3413. pStream->NewLine();
  3414. pStream->Write( '{' );
  3415. }
  3416. void
  3417. Out_Else(
  3418. CCB * pCCB )
  3419. {
  3420. ISTREAM * pStream = pCCB->GetStream();
  3421. pStream->NewLine();
  3422. pStream->Write( "else" );
  3423. Out_IndentInc( pCCB );
  3424. pStream->NewLine();
  3425. pStream->Write( '{' );
  3426. }
  3427. void
  3428. Out_UniquePtrMarshall(
  3429. CCB * pCCB,
  3430. expr_node * pDestExpr,
  3431. expr_node * pSrcExpr )
  3432. {
  3433. ISTREAM * pStream = pCCB->GetStream();
  3434. expr_proc_call * pProc;
  3435. pStream->NewLine();
  3436. pProc = new expr_proc_call( MARSHALL_UNIQUE_PTR_RTN_NAME );
  3437. pProc->SetParam(new expr_param( pDestExpr ));
  3438. pProc->SetParam(new expr_param( pSrcExpr ));
  3439. pProc->PrintCall( pStream, 0, 0 );
  3440. }
  3441. void
  3442. Out_IfUniquePtrInBuffer(
  3443. CCB * pCCB,
  3444. expr_node * pSrc )
  3445. //
  3446. // This appears to be a fossil. Ryszard 3/30/98.
  3447. // However, the routine above appears to be used.
  3448. //
  3449. {
  3450. expr_proc_call * pProc = new expr_proc_call( CHECK_UNIQUE_PTR_IN_BUFFER );
  3451. ISTREAM * pStream = pCCB->GetStream();
  3452. pProc->SetParam( new expr_param( pSrc ) );
  3453. pStream->NewLine();
  3454. pStream->Write( "if(" );
  3455. pProc->Print( pStream );
  3456. pStream->Write( ')' );
  3457. Out_IndentInc( pCCB );
  3458. pStream->NewLine();
  3459. pStream->Write( '{' );
  3460. }
  3461. void
  3462. Out_Assign( CCB * pCCB,
  3463. expr_node * pDest,
  3464. expr_node * pSrc )
  3465. {
  3466. ISTREAM * pStream = pCCB->GetStream();
  3467. pStream->NewLine();
  3468. pDest->Print( pStream );
  3469. pStream->Write( " = " );
  3470. pSrc->Print( pStream );
  3471. pStream->Write( ';' );
  3472. }
  3473. void
  3474. Out_Memcopy(
  3475. CCB * pCCB,
  3476. expr_node * pDest,
  3477. expr_node * pSource,
  3478. expr_node * pLength )
  3479. {
  3480. ISTREAM * pStream = pCCB->GetStream();
  3481. expr_proc_call * pCall = new expr_proc_call( "memcpy" );
  3482. pStream->NewLine();
  3483. pCall->SetParam( new expr_param( pDest ) );
  3484. pCall->SetParam( new expr_param( pSource ) );
  3485. pCall->SetParam( new expr_param( pLength ) );
  3486. pCall->PrintCall( pStream, 0, 0 );
  3487. }
  3488. void
  3489. Out_strlen(
  3490. CCB * pCCB,
  3491. expr_node * pDest,
  3492. expr_node * pSource,
  3493. unsigned short Size )
  3494. {
  3495. ISTREAM * pStream = pCCB->GetStream();
  3496. PNAME pName = (Size == 1) ? "strlen" : "MIDL_wchar_strlen";
  3497. expr_proc_call * pCall = new expr_proc_call( pName );
  3498. expr_node * pExpr;
  3499. pStream->NewLine();
  3500. pCall->SetParam( new expr_param( pSource ) );
  3501. if( pDest )
  3502. pExpr = new expr_assign( pDest, pCall );
  3503. else
  3504. pExpr = pCall;
  3505. pExpr->PrintCall( pStream, 0, 0 );
  3506. }
  3507. void
  3508. Out_For(
  3509. CCB * pCCB,
  3510. expr_node * pIndexExpr,
  3511. expr_node * pInitialValue,
  3512. expr_node * pFinalValue,
  3513. expr_node * pIncrExpr )
  3514. {
  3515. ISTREAM * pStream = pCCB->GetStream();
  3516. expr_node * pExpr;
  3517. pStream->NewLine();
  3518. pStream->Write( "for( " );
  3519. pExpr = new expr_assign( pIndexExpr, pInitialValue );
  3520. pExpr->Print( pStream );
  3521. pStream->Write( ';' );
  3522. pExpr = new expr_op_binary( OP_LESS, pIndexExpr, pFinalValue );
  3523. pExpr->Print( pStream );
  3524. pStream->Write( ';' );
  3525. pExpr = new expr_op_binary( OP_PLUS, pIndexExpr, pIncrExpr );
  3526. pExpr = new expr_assign( pIndexExpr, pExpr );
  3527. pExpr->Print( pStream );
  3528. pStream->Write( ')' );
  3529. pStream->IndentInc();
  3530. pStream->NewLine();
  3531. pStream->Write( '{' );
  3532. }
  3533. void
  3534. Out_EndFor( CCB * pCCB )
  3535. {
  3536. pCCB->GetStream()->NewLine();
  3537. pCCB->GetStream()->Write( '}' );
  3538. Out_IndentDec( pCCB );
  3539. }
  3540. void
  3541. Out_PlusEquals(
  3542. CCB * pCCB,
  3543. expr_node *pL,
  3544. expr_node *pR )
  3545. {
  3546. ISTREAM * pStream = pCCB->GetStream();
  3547. pStream->NewLine();
  3548. pL->Print( pStream );
  3549. pStream->Write( " += " );
  3550. pR->Print( pStream );
  3551. pStream->Write(';');
  3552. }
  3553. void
  3554. Out_Comment(
  3555. CCB * pCCB,
  3556. char * pComment )
  3557. {
  3558. ISTREAM * pStream = pCCB->GetStream();
  3559. pStream->NewLine();
  3560. pStream->Write( "/* " );
  3561. pStream->Write( pComment );
  3562. pStream->Write( " */" );
  3563. }
  3564. void
  3565. Out_RpcSSEnableAllocate(
  3566. CCB * pCCB )
  3567. {
  3568. expr_proc_call * pCall = new expr_proc_call( RPC_SS_ENABLE_ALLOCATE_RTN_NAME );
  3569. pCall->SetParam( new expr_param (
  3570. new expr_u_address (
  3571. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3572. pCCB->GetStream()->NewLine();
  3573. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3574. }
  3575. void
  3576. Out_RpcSSSetClientToOsf(
  3577. CCB * pCCB )
  3578. {
  3579. expr_proc_call * pCall = new expr_proc_call( RPC_SM_SET_CLIENT_TO_OSF_RTN_NAME );
  3580. pCall->SetParam( new expr_param (
  3581. new expr_u_address (
  3582. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3583. pCCB->GetStream()->NewLine();
  3584. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3585. }
  3586. void
  3587. Out_RpcSSDisableAllocate(
  3588. CCB * pCCB )
  3589. {
  3590. expr_proc_call * pCall = new expr_proc_call( RPC_SS_DISABLE_ALLOCATE_RTN_NAME );
  3591. pCall->SetParam( new expr_param (
  3592. new expr_u_address (
  3593. new expr_variable( STUB_MESSAGE_VAR_NAME ) ) ) );
  3594. pCCB->GetStream()->NewLine();
  3595. pCall->PrintCall( pCCB->GetStream(), 0, 0 );
  3596. }
  3597. void
  3598. Out_MemsetToZero(
  3599. CCB * pCCB,
  3600. expr_node * pDest,
  3601. expr_node * pSize )
  3602. {
  3603. expr_proc_call * pProc = new expr_proc_call( (PNAME) MIDL_MEMSET_RTN_NAME );
  3604. pProc->SetParam( new expr_param( pDest ) );
  3605. pProc->SetParam( new expr_param( new expr_constant(0L) ) );
  3606. pProc->SetParam( new expr_param( pSize ) );
  3607. pCCB->GetStream()->NewLine();
  3608. pProc->PrintCall( pCCB->GetStream(), 0, 0 );
  3609. }
  3610. void
  3611. Out_CallAsProxyPrototypes(
  3612. CCB * pCCB,
  3613. ITERATOR& ListOfCallAsRoutines )
  3614. /*++
  3615. Routine Description:
  3616. This routine generates the call_as function prototypes.
  3617. One for the proxy( with local param list )
  3618. One for the stub( with remote param list )
  3619. Arguments:
  3620. pCCB - a pointer to the code generation control block.
  3621. --*/
  3622. {
  3623. ISTREAM * pStream = pCCB->GetStream();
  3624. node_proc * pProc;
  3625. pStream->NewLine();
  3626. while( ITERATOR_GETNEXT( ListOfCallAsRoutines, pProc ) )
  3627. {
  3628. node_interface * pIntf = pProc->GetMyInterfaceNode();
  3629. // skip for non-object routines
  3630. if ( !pIntf->FInSummary( ATTR_OBJECT ) )
  3631. continue;
  3632. // keep these on the stack...
  3633. CSzBuffer NewName;
  3634. node_call_as * pCallAs = (node_call_as *)
  3635. pProc->GetAttribute( ATTR_CALL_AS );
  3636. node_proc NewProc( pCallAs->GetCallAsType() );
  3637. // local proxy routine with local param list
  3638. NewName.Set( pIntf->GetSymName() );
  3639. NewName.Append( "_" );
  3640. NewName.Append( pCallAs->GetCallAsName() );
  3641. NewName.Append( "_Proxy" );
  3642. NewProc.SetSymName( NewName );
  3643. NewProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI | PRT_THIS_POINTER | PRT_FORCE_CALL_CONV,
  3644. pCCB->GetStream(),
  3645. NULL ,
  3646. pIntf );
  3647. pStream->NewLine();
  3648. // local stub routine, with remote param list
  3649. node_proc NewStubProc( pProc );
  3650. NewName.Set( pIntf->GetSymName() );
  3651. NewName.Append( "_" );
  3652. NewName.Append( pCallAs->GetCallAsName() );
  3653. NewName.Append( "_Stub" );
  3654. NewStubProc.SetSymName( NewName );
  3655. pStream->NewLine();
  3656. NewStubProc.PrintType( PRT_PROC_PROTOTYPE_WITH_SEMI | PRT_THIS_POINTER | PRT_FORCE_CALL_CONV,
  3657. pStream,
  3658. NULL ,
  3659. pIntf );
  3660. pStream->NewLine();
  3661. }
  3662. }
  3663. void
  3664. CG_OBJECT_PROC::Out_ProxyFunctionPrototype(CCB *pCCB, PRTFLAGS F )
  3665. /*++
  3666. Routine Description:
  3667. This routine generates a proxy function prototype.
  3668. Arguments:
  3669. pCCB - a pointer to the code generation control block.
  3670. --*/
  3671. {
  3672. // keep these on the stack...
  3673. CSzBuffer NewName;
  3674. node_proc * pProc = (node_proc *)GetType();
  3675. node_proc NewProc( pProc );
  3676. NewName.Set( pCCB->GetInterfaceName() );
  3677. NewName.Append( "_" );
  3678. NewName.Append( pProc->GetSymName() );
  3679. NewName.Append( "_Proxy" );
  3680. NewProc.SetSymName( NewName );
  3681. pCCB->GetStream()->NewLine();
  3682. NewProc.PrintType( PRT_PROC_PROTOTYPE | PRT_THIS_POINTER | F | PRT_FORCE_CALL_CONV,
  3683. pCCB->GetStream(),
  3684. NULL ,
  3685. pCCB->GetInterfaceCG()->GetType() );
  3686. }
  3687. void
  3688. Out_IID(CCB *pCCB)
  3689. /*++
  3690. Routine Description:
  3691. This routine generates an IID declaration for the current interface.
  3692. Arguments:
  3693. pCCB - a pointer to the code generation control block.
  3694. --*/
  3695. {
  3696. ISTREAM *pStream = pCCB->GetStream();
  3697. pStream->NewLine();
  3698. if (pCommand->IsSwitchDefined(SWITCH_MKTYPLIB))
  3699. {
  3700. node_guid * pGuid = (node_guid *) ((node_interface *)pCCB->GetInterfaceCG()->GetType())->GetAttribute(ATTR_GUID);
  3701. if (pGuid)
  3702. Out_MKTYPLIB_Guid(pCCB, pGuid->GetStrs(), "IID_", pCCB->GetInterfaceName());
  3703. }
  3704. else
  3705. {
  3706. pStream->Write("EXTERN_C const IID IID_");
  3707. pStream->Write(pCCB->GetInterfaceName());
  3708. pStream->Write(';');
  3709. pStream->NewLine();
  3710. }
  3711. }
  3712. void
  3713. Out_CLSID(CCB *pCCB)
  3714. /*++
  3715. Routine Description:
  3716. This routine generates an CLSID declaration for the current com class.
  3717. Arguments:
  3718. pCCB - a pointer to the code generation control block.
  3719. --*/
  3720. {
  3721. ISTREAM *pStream = pCCB->GetStream();
  3722. pStream->NewLine();
  3723. pStream->Write("EXTERN_C const CLSID CLSID_");
  3724. pStream->Write(pCCB->GetInterfaceName());
  3725. pStream->Write(';');
  3726. pStream->NewLine();
  3727. }
  3728. void
  3729. CG_OBJECT_PROC::Out_StubFunctionPrototype(CCB *pCCB)
  3730. {
  3731. ISTREAM * pStream = pCCB->GetStream();
  3732. CSzBuffer TempBuffer;
  3733. TempBuffer.Set( "void __RPC_STUB " );
  3734. TempBuffer.Append( pCCB->GetInterfaceName() );
  3735. TempBuffer.Append( "_" );
  3736. TempBuffer.Append( GetType()->GetSymName() );
  3737. TempBuffer.Append( "_Stub(" );
  3738. pStream->NewLine();
  3739. pStream->Write( TempBuffer );
  3740. pStream->IndentInc();
  3741. pStream->NewLine();
  3742. pStream->Write("IRpcStubBuffer *This,");
  3743. pStream->NewLine();
  3744. pStream->Write("IRpcChannelBuffer *_pRpcChannelBuffer,");
  3745. pStream->NewLine();
  3746. pStream->Write("PRPC_MESSAGE _pRpcMessage,");
  3747. pStream->NewLine();
  3748. pStream->Write("DWORD *_pdwStubPhase)");
  3749. pStream->IndentDec();
  3750. }
  3751. void
  3752. CG_OBJECT_PROC::Out_ServerStubProlog(
  3753. CCB * pCCB,
  3754. ITERATOR& LocalsList,
  3755. ITERATOR& TransientList )
  3756. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3757. Routine Description:
  3758. Generate the server side procedure prolog.
  3759. Arguments:
  3760. pCCB - A pointer to the code generation controller block.
  3761. LocalsList - A list of local resources.
  3762. TransientList- A list of temp variables.
  3763. Return Value:
  3764. Notes:
  3765. The server side procedure prolog generation cannot use the normal
  3766. printtype method on the procedure node, since the server stub signature
  3767. looks different.
  3768. Also the name of the server side stub is mangled with the interface name.
  3769. All server side procs are void returns.
  3770. ----------------------------------------------------------------------------*/
  3771. {
  3772. ISTREAM * pStream = pCCB->GetStream();
  3773. RESOURCE* pRes;
  3774. Out_StubFunctionPrototype(pCCB);
  3775. //
  3776. // Write out the opening brace for the server proc and all that.
  3777. //
  3778. pStream->NewLine();
  3779. pStream->Write( '{' );
  3780. pStream->IndentInc();
  3781. pStream->NewLine();
  3782. //
  3783. // This is where we get off for /Oi. We have a special routine
  3784. // for local variable declaration for /Oi.
  3785. //
  3786. if ( pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER )
  3787. return;
  3788. //
  3789. // Print out declarations for the locals.
  3790. //
  3791. if( ITERATOR_GETCOUNT( LocalsList ) )
  3792. {
  3793. ITERATOR_INIT( LocalsList );
  3794. while( ITERATOR_GETNEXT( LocalsList, pRes ) )
  3795. {
  3796. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  3797. pStream, // into stream
  3798. (node_skl *)0 // no parent.
  3799. );
  3800. }
  3801. }
  3802. if( ITERATOR_GETCOUNT( TransientList ) )
  3803. {
  3804. ITERATOR_INIT( TransientList );
  3805. while( ITERATOR_GETNEXT( TransientList, pRes ) )
  3806. {
  3807. pStream->IndentInc();
  3808. pRes->GetType()->PrintType( PRT_ID_DECLARATION, // print decl
  3809. pStream, // into stream
  3810. (node_skl *)0 // no parent.
  3811. );
  3812. pStream->IndentDec();
  3813. }
  3814. }
  3815. pStream->IndentDec();
  3816. pStream->NewLine();
  3817. //
  3818. // Done.
  3819. //
  3820. }
  3821. void
  3822. Out_CallMemberFunction(
  3823. CCB * pCCB,
  3824. expr_proc_call * pProcExpr,
  3825. expr_node * pRet,
  3826. BOOL fThunk)
  3827. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3828. Routine Description:
  3829. Generate a call to the manager routine.
  3830. Arguments:
  3831. pCCB - A pointer to the code generation controller block.
  3832. pProcExpr - A pointer to the complete procedure expression.
  3833. pRet - An optional pointer to ther return variable.
  3834. fThunk - flag for "this call is in a thunk with a param struct"
  3835. Return Value:
  3836. None.
  3837. Notes:
  3838. //call server
  3839. _RetVal = (((IClassFactory *) ((CStdStubBuffer*)This)->pvServerObject)->lpVtbl) -> LockServer((IClassFactory *) ((CStdStubBuffer *)This)->pvServerObject,fLock);
  3840. ----------------------------------------------------------------------------*/
  3841. {
  3842. expr_node * pAss = pProcExpr;
  3843. expr_node * pExpr;
  3844. CSzBuffer Buffer;
  3845. ISTREAM * pStream = pCCB->GetStream();
  3846. char * pTemp;
  3847. if ( fThunk )
  3848. {
  3849. // ((IFoo*) ((CStdStubBuffer*)pParamStruct->This)->lpVtbl)->Bar();
  3850. Buffer.Set( "((" );
  3851. Buffer.Append( pCCB->GetInterfaceName() );
  3852. Buffer.Append( "*) ((CStdStubBuffer*)pParamStruct->This)->lpVtbl)" );
  3853. }
  3854. else
  3855. {
  3856. // (((IFoo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl)->Bar();
  3857. Buffer.Set( "(((" );
  3858. Buffer.Append( pCCB->GetInterfaceName() );
  3859. Buffer.Append( "*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl)" );
  3860. }
  3861. pTemp = new char [ strlen( Buffer ) + 1 ];
  3862. strcpy( pTemp, Buffer );
  3863. pExpr = new expr_variable( pTemp );//this has the rhs expr for the
  3864. // manager epv call. Sneaky !
  3865. pExpr = new expr_pointsto( pExpr, pProcExpr );
  3866. pAss = pExpr;
  3867. if( pRet )
  3868. {
  3869. pAss = new expr_assign( pRet, pExpr );
  3870. }
  3871. pAss->PrintCall( pStream, 0, 0 );
  3872. }
  3873. void
  3874. OutputNdrAlignment( CCB * pCCB,
  3875. unsigned short Alignment )
  3876. {
  3877. ISTREAM * pStream;
  3878. unsigned long Align = Alignment - 1;
  3879. CSzBuffer Buffer;
  3880. pStream = pCCB->GetStream();
  3881. Buffer.Set( STUB_MSG_BUFFER_VAR_NAME );
  3882. Buffer.Append( " = (unsigned char *)(((" );
  3883. Buffer.Append( (pCommand->Is64BitEnv() ? "__int64"
  3884. : "long" ));
  3885. Buffer.Append( ")" STUB_MSG_BUFFER_VAR_NAME " + " );
  3886. Buffer.Append( Align );
  3887. char sz[100];
  3888. sprintf( sz, ") & ~ %#x);", Align);
  3889. Buffer.Append( sz );
  3890. pStream->Write( Buffer );
  3891. pStream->NewLine();
  3892. }
  3893. CG_NDR *
  3894. GetFirstMulti(
  3895. CG_NDR * pNdr )
  3896. {
  3897. // Skip pointers leading to a multi-dimensional object.
  3898. while ( pNdr->GetCGID() == ID_CG_GENERIC_HDL ||
  3899. pNdr->GetCGID() == ID_CG_PTR )
  3900. {
  3901. pNdr = (CG_NDR *) pNdr->GetChild();
  3902. }
  3903. return pNdr;
  3904. }
  3905. void
  3906. Out_MultiDimVars(
  3907. CCB * pCCB,
  3908. CG_PARAM * pParam
  3909. )
  3910. /*
  3911. Output local resources related to multi-dimensional conf or varying arrays.
  3912. Note that the parameter may be a pointer to multidimensional object.
  3913. */
  3914. {
  3915. ISTREAM * pStream;
  3916. CG_NDR * pNdr;
  3917. char * pParamName;
  3918. long dim;
  3919. CSzBuffer Buffer;
  3920. pStream = pCCB->GetStream();
  3921. pParamName = pParam->GetType()->GetSymName();
  3922. pNdr = (CG_NDR *) pParam->GetChild();
  3923. pNdr = GetFirstMulti( pNdr );
  3924. if ( pNdr->IsArray() )
  3925. dim = ((CG_ARRAY *)pNdr)->GetDimensions();
  3926. else // pNdr->IsPointer()
  3927. dim = ((CG_POINTER *)pNdr)->SizedDimensions();
  3928. Buffer.Set( "unsigned long _maxcount_" );
  3929. Buffer.Append( pParamName );
  3930. Buffer.Append( "[" );
  3931. Buffer.Append( dim );
  3932. Buffer.Append( "]" );
  3933. pStream->Write( Buffer );
  3934. pStream->Write( ";" );
  3935. pStream->NewLine( 2 );
  3936. Buffer.Set( "unsigned long _offset_" );
  3937. Buffer.Append( pParamName );
  3938. Buffer.Append( "[" );
  3939. Buffer.Append( dim );
  3940. Buffer.Append( "]" );
  3941. pStream->Write( Buffer );
  3942. pStream->Write( ';' );
  3943. pStream->NewLine();
  3944. Buffer.Set( "unsigned long _length_" );
  3945. Buffer.Append( pParamName );
  3946. Buffer.Append( "[" );
  3947. Buffer.Append( dim );
  3948. Buffer.Append( "]" );
  3949. pStream->Write( Buffer );
  3950. pStream->Write( ';' );
  3951. pStream->NewLine();
  3952. }
  3953. void
  3954. Out_MultiDimVarsInit(
  3955. CCB * pCCB,
  3956. CG_PARAM * pParam
  3957. )
  3958. /*
  3959. Output local resources related to multi-dimensional conf or varying arrays.
  3960. Note that the parameter may be a pointer to multidimensional object.
  3961. */
  3962. {
  3963. ISTREAM * pStream;
  3964. CG_NDR * pNdr;
  3965. char * pParamName;
  3966. long i, dim;
  3967. CSzBuffer Buffer;
  3968. pStream = pCCB->GetStream();
  3969. pParamName = pParam->GetType()->GetSymName();
  3970. pNdr = (CG_NDR *) pParam->GetChild();
  3971. pNdr = GetFirstMulti( pNdr );
  3972. if ( pNdr->IsArray() )
  3973. dim = ((CG_ARRAY *)pNdr)->GetDimensions();
  3974. else // pNdr->IsPointer()
  3975. dim = ((CG_POINTER *)pNdr)->SizedDimensions();
  3976. pStream->NewLine();
  3977. //
  3978. // Max count var.
  3979. //
  3980. /*
  3981. if ( (pNdr->GetCGID() == ID_CG_CONF_ARRAY) ||
  3982. (pNdr->GetCGID() == ID_CG_CONF_VAR_ARRAY) ||
  3983. (pNdr->GetCGID() == ID_CG_SIZE_PTR) ||
  3984. (pNdr->GetCGID() == ID_CG_SIZE_LENGTH_PTR) )
  3985. */
  3986. {
  3987. expr_node * pSizeIsExpr = 0;
  3988. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  3989. {
  3990. Buffer.Set( "_maxcount_" );
  3991. Buffer.Append( pParamName );
  3992. Buffer.Append( "[" );
  3993. Buffer.Append( i );
  3994. Buffer.Append( "] = " );
  3995. pStream->Write( Buffer );
  3996. switch ( pNdr->GetCGID() )
  3997. {
  3998. case ID_CG_CONF_ARRAY :
  3999. case ID_CG_CONF_VAR_ARRAY :
  4000. case ID_CG_CONF_STRING_ARRAY :
  4001. case ID_CG_STRING_ARRAY :
  4002. pSizeIsExpr = ((CG_ARRAY *)pNdr)->GetSizeIsExpr();
  4003. break;
  4004. case ID_CG_SIZE_PTR :
  4005. pSizeIsExpr =
  4006. ((CG_SIZE_POINTER *)pNdr)->GetSizeIsExpr();
  4007. break;
  4008. case ID_CG_SIZE_LENGTH_PTR :
  4009. pSizeIsExpr =
  4010. ((CG_SIZE_LENGTH_POINTER *)pNdr)->GetSizeIsExpr();
  4011. break;
  4012. case ID_CG_SIZE_STRING_PTR :
  4013. pSizeIsExpr =
  4014. ((CG_SIZE_STRING_POINTER *)pNdr)->GetSizeIsExpr();
  4015. break;
  4016. }
  4017. if ( pSizeIsExpr )
  4018. pSizeIsExpr->Print( pStream );
  4019. else
  4020. pStream->Write( '0' );
  4021. pStream->Write( ';' );
  4022. pStream->NewLine();
  4023. }
  4024. }
  4025. pNdr = (CG_NDR *) pParam->GetChild();
  4026. pNdr = GetFirstMulti( pNdr );
  4027. //
  4028. // Offset and Length vars.
  4029. //
  4030. /*
  4031. if ( (pNdr->GetCGID() == ID_CG_VAR_ARRAY) ||
  4032. (pNdr->GetCGID() == ID_CG_CONF_VAR_ARRAY) ||
  4033. (pNdr->GetCGID() == ID_CG_SIZE_LENGTH_PTR) )
  4034. */
  4035. {
  4036. expr_node * pFirstIsExpr = 0;
  4037. expr_node * pLengthIsExpr = 0;
  4038. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  4039. {
  4040. Buffer.Set( "_offset_" );
  4041. Buffer.Append( pParamName );
  4042. Buffer.Append( "[" );
  4043. Buffer.Append( i );
  4044. Buffer.Append( "] = " );
  4045. pStream->Write( Buffer );
  4046. switch ( pNdr->GetCGID() )
  4047. {
  4048. case ID_CG_VAR_ARRAY :
  4049. pFirstIsExpr = ((CG_VARYING_ARRAY *)pNdr)->
  4050. GetFirstIsExpr();
  4051. break;
  4052. case ID_CG_CONF_VAR_ARRAY :
  4053. pFirstIsExpr = ((CG_CONFORMANT_VARYING_ARRAY *)pNdr)->
  4054. GetFirstIsExpr();
  4055. break;
  4056. case ID_CG_CONF_STRING_ARRAY :
  4057. case ID_CG_STRING_ARRAY :
  4058. pFirstIsExpr = 0;
  4059. break;
  4060. case ID_CG_SIZE_LENGTH_PTR :
  4061. pFirstIsExpr = ((CG_SIZE_LENGTH_POINTER *)pNdr)->
  4062. GetFirstIsExpr();
  4063. break;
  4064. }
  4065. if ( pFirstIsExpr )
  4066. pFirstIsExpr->Print( pStream );
  4067. else
  4068. pStream->Write( '0' );
  4069. pStream->Write( ';' );
  4070. pStream->NewLine();
  4071. }
  4072. pNdr = (CG_NDR *) pParam->GetChild();
  4073. pNdr = GetFirstMulti( pNdr );
  4074. for ( i = 0; i < dim; pNdr = (CG_NDR *) pNdr->GetChild(), i++ )
  4075. {
  4076. Buffer.Set( "_length_" );
  4077. Buffer.Append( pParamName );
  4078. Buffer.Append( "[" );
  4079. Buffer.Append( i );
  4080. Buffer.Append( "] = " );
  4081. pStream->Write( Buffer );
  4082. switch ( pNdr->GetCGID() )
  4083. {
  4084. case ID_CG_VAR_ARRAY :
  4085. pLengthIsExpr = ((CG_VARYING_ARRAY *)pNdr)->
  4086. GetLengthIsExpr();
  4087. break;
  4088. case ID_CG_CONF_VAR_ARRAY :
  4089. pLengthIsExpr = ((CG_CONFORMANT_VARYING_ARRAY *)pNdr)->
  4090. GetLengthIsExpr();
  4091. break;
  4092. case ID_CG_CONF_STRING_ARRAY :
  4093. case ID_CG_STRING_ARRAY :
  4094. pLengthIsExpr = 0;
  4095. break;
  4096. case ID_CG_SIZE_LENGTH_PTR :
  4097. pLengthIsExpr = ((CG_SIZE_LENGTH_POINTER *)pNdr)->
  4098. GetLengthIsExpr();
  4099. break;
  4100. }
  4101. if ( pLengthIsExpr )
  4102. pLengthIsExpr->Print( pStream );
  4103. else
  4104. pStream->Write( '0' );
  4105. pStream->Write( ';' );
  4106. pStream->NewLine();
  4107. }
  4108. }
  4109. }
  4110. void
  4111. Out_CheckUnMarshallPastBufferEnd(
  4112. CCB * pCCB,
  4113. ulong size )
  4114. {
  4115. /*
  4116. This method will be called only within the try-except of
  4117. unmarshalling on the server side.
  4118. Generate an expression of the form:
  4119. if( (StubMessage.pBuffer + size) > StubMessage.BufferEnd )
  4120. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  4121. */
  4122. expr_node * pBufferExpr =
  4123. new expr_variable( STUB_MSG_BUFFER_VAR_NAME , 0);
  4124. if ( 0 != size )
  4125. {
  4126. pBufferExpr = new expr_op_binary(
  4127. OP_PLUS,
  4128. pBufferExpr,
  4129. new expr_constant( size ) );
  4130. }
  4131. expr_node * pBufferEndExpr =
  4132. new expr_variable( STUB_MSG_BUFFER_END_VAR_NAME, 0);
  4133. expr_node * pExpr = new expr_relational( OP_GREATER,
  4134. pBufferExpr,
  4135. pBufferEndExpr );
  4136. Out_If( pCCB, pExpr );
  4137. Out_RaiseException( pCCB, "RPC_X_BAD_STUB_DATA" );
  4138. Out_Endif( pCCB );
  4139. }
  4140. void
  4141. Out_TypePicklingInfo(
  4142. CCB * pCCB )
  4143. {
  4144. ISTREAM * pStream;
  4145. MIDL_TYPE_PICKLING_FLAGS Flags;
  4146. unsigned long &intFlags = * (unsigned long *) &Flags;
  4147. static const char *pFlagNames[] =
  4148. {
  4149. "Oicf "
  4150. ,"NewCorrDesc "
  4151. };
  4152. pStream = pCCB->GetStream();
  4153. if ( pCommand->NeedsNDR64Run() )
  4154. {
  4155. pStream->WriteOnNewLine(
  4156. "extern unsigned long * TypePicklingOffsetTable[]; " );
  4157. pStream->NewLine();
  4158. }
  4159. pStream->WriteOnNewLine("static " MIDL_TYPE_PICKLING_INFO_NAME
  4160. " " PICKLING_INFO_STRUCT_NAME " =");
  4161. pStream->IndentInc();
  4162. pStream->WriteOnNewLine( "{" );
  4163. pStream->NewLine();
  4164. pStream->WriteNumber( "0x%x, /* Signature & version: TP 1 */", 0x33205054 );
  4165. intFlags = 0;
  4166. MIDL_ASSERT( pCCB->GetOptimOption() & OPTIMIZE_INTERPRETER_V2 );
  4167. Flags.Oicf = 1;
  4168. if ( pCommand->IsSwitchDefined( SWITCH_ROBUST ) )
  4169. Flags.HasNewCorrDesc = 1;
  4170. pStream->NewLine();
  4171. pStream->WriteNumber( "0x%x,", intFlags );
  4172. if ( 0 != intFlags )
  4173. {
  4174. pStream->Write( " /* Flags: " );
  4175. for ( int i = 0; i < sizeof(pFlagNames)/sizeof(char*); i++ )
  4176. {
  4177. if ( intFlags & ( 1 << i ) )
  4178. pStream->Write( pFlagNames[i] );
  4179. }
  4180. pStream->Write( "*/" );
  4181. }
  4182. pStream->WriteOnNewLine( "0," );
  4183. pStream->WriteOnNewLine( "0," );
  4184. pStream->WriteOnNewLine( "0," );
  4185. pStream->WriteOnNewLine( "};" );
  4186. pStream->IndentDec();
  4187. pStream->NewLine();
  4188. }
  4189. void Out_PartialIgnoreClientBufferSize( CCB *pCCB, char *pParamName );
  4190. void
  4191. Out_PartialIgnoreClientMarshall(
  4192. CCB *pCCB,
  4193. char *pParamName )
  4194. {
  4195. ISTREAM *pStream = pCCB->GetStream();
  4196. unsigned short Spaces = sizeof("NdrPartialIgnoreClientMarshall( ")-1;
  4197. pStream->WriteOnNewLine( "NdrPartialIgnoreClientMarshall( (PMIDL_STUB_MESSAGE) &"
  4198. STUB_MESSAGE_VAR_NAME "," );
  4199. pStream->NewLine();
  4200. pStream->Spaces( Spaces );
  4201. pStream->Write( pParamName );
  4202. pStream->Write( " ); " );
  4203. pStream->NewLine();
  4204. }
  4205. void
  4206. Out_PartialIgnoreServerUnmarshall(
  4207. CCB *pCCB,
  4208. char *pParamName )
  4209. {
  4210. ISTREAM *pStream = pCCB->GetStream();
  4211. unsigned short Spaces = sizeof("NdrPartialIgnoreServerUnmarshall( ")-1;
  4212. pStream->WriteOnNewLine( "NdrPartialIgnoreServerUnmarshall( (PMIDL_STUB_MESSAGE) &"
  4213. STUB_MESSAGE_VAR_NAME ", " );
  4214. pStream->NewLine();
  4215. pStream->Spaces( Spaces );
  4216. pStream->Write( "&" );
  4217. pStream->Write( pParamName );
  4218. pStream->Write( " ); " );
  4219. pStream->NewLine();
  4220. }
  4221. void
  4222. Out_PartialIgnoreClientBufferSize(
  4223. CCB *pCCB,
  4224. char *pParamName )
  4225. {
  4226. ISTREAM *pStream = pCCB->GetStream();
  4227. unsigned short Spaces = sizeof("NdrPartialIgnoreClientBufferSize( ")-1;
  4228. pStream->WriteOnNewLine( "NdrPartialIgnoreClientBufferSize( (PMIDL_STUB_MESSAGE) &"
  4229. STUB_MESSAGE_VAR_NAME ", " );
  4230. pStream->NewLine();
  4231. pStream->Spaces( Spaces );
  4232. pStream->Write( pParamName );
  4233. pStream->Write( " ); " );
  4234. pStream->NewLine();
  4235. }
  4236. void
  4237. Out_PartialIgnoreServerInitialize(
  4238. CCB *pCCB,
  4239. char *pParamName,
  4240. long FormatStringOffset )
  4241. {
  4242. ISTREAM *pStream = pCCB->GetStream();
  4243. char Buffer[256];
  4244. unsigned short Spaces = sizeof("NdrPartialIgnoreServerInitialize( ")-1;
  4245. pStream->WriteOnNewLine( "NdrPartialIgnoreServerInitialize( (PMIDL_STUB_MESSAGE) &"
  4246. STUB_MESSAGE_VAR_NAME ", " );
  4247. pStream->NewLine();
  4248. pStream->Spaces( Spaces );
  4249. pStream->Write( "&" );
  4250. pStream->Write( pParamName );
  4251. pStream->Write( ", " );
  4252. pStream->NewLine();
  4253. pStream->Spaces( Spaces );
  4254. sprintf( Buffer, "(PFORMAT_STRING) &" FORMAT_STRING_STRUCT_NAME ".Format[%d] );",
  4255. FormatStringOffset );
  4256. pStream->Write( Buffer );
  4257. pStream->NewLine();
  4258. }