Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1077 lines
25 KiB

4 years ago
  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. misccls.hxx
  5. Abstract:
  6. Code generation methods for miscellaneous cg classes.
  7. Notes:
  8. History:
  9. Sep-01-1993 VibhasC Created.
  10. ----------------------------------------------------------------------------*/
  11. /****************************************************************************
  12. * include files
  13. ***************************************************************************/
  14. #include "becls.hxx"
  15. #pragma hdrstop
  16. /****************************************************************************
  17. * local definitions
  18. ***************************************************************************/
  19. /****************************************************************************
  20. * local data
  21. ***************************************************************************/
  22. GUID_STRS TransferSyntaxGuidStrs( TRANSFER_SYNTAX_GUID_STR_1,
  23. TRANSFER_SYNTAX_GUID_STR_2,
  24. TRANSFER_SYNTAX_GUID_STR_3,
  25. TRANSFER_SYNTAX_GUID_STR_4,
  26. TRANSFER_SYNTAX_GUID_STR_5);
  27. /****************************************************************************
  28. * externs
  29. ***************************************************************************/
  30. extern CMD_ARG * pCommand;
  31. extern BOOL IsTempName( char * );
  32. /****************************************************************************/
  33. CG_INTERFACE::CG_INTERFACE(
  34. node_interface * pI,
  35. GUID_STRS GStrs,
  36. BOOL fCallbacks,
  37. BOOL fMopInfo,
  38. CG_HANDLE * pIH
  39. ) :CG_NDR(pI, XLAT_SIZE_INFO() )
  40. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  41. Routine Description:
  42. The constructor for the code generation file node.
  43. Arguments:
  44. pI - A pointer to the interface node in type graph.
  45. GStrs - guid strings
  46. fCallbacks - Does the interface have any callbacks ?
  47. fMopInfo - Does the interface have any mops ?
  48. pIH - A pointer to the CG nodes for any implicit handle
  49. Return Value:
  50. Notes:
  51. ----------------------------------------------------------------------------*/
  52. {
  53. _pCTI = NULL;
  54. char * pName = GetType()->GetSymName();
  55. GuidStrs = GStrs;
  56. GuidStrs.SetValue();
  57. fMopsPresent = fMopInfo;
  58. fCallbacksPresent = fCallbacks;
  59. pImpHdlCG = (CG_HANDLE *) pIH;
  60. CreateDispatchTables();
  61. fAllRpcSS = FALSE;
  62. fUsesRpcSS = FALSE;
  63. pIntfName = pName;
  64. //
  65. // For now.
  66. //
  67. ProtSeqEPCount = 0;
  68. pStubDescName = new char[ strlen(STUB_DESC_STRUCT_VAR_NAME) +
  69. strlen(pName) + 1 ];
  70. strcpy( pStubDescName, pName );
  71. strcat( pStubDescName, STUB_DESC_STRUCT_VAR_NAME );
  72. }
  73. CG_STATUS
  74. CG_INTERFACE::GenClientStub(
  75. CCB * pCCB )
  76. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  77. Routine Description:
  78. Generate code for the file node.
  79. Arguments:
  80. pCCB - a pointer to the code generation control block.
  81. Return Value:
  82. CG_OK if all is well, error otherwise.
  83. Notes:
  84. ----------------------------------------------------------------------------*/
  85. {
  86. unsigned short M,m; // for MAJOR and minor versions :-)
  87. CG_ITERATOR I;
  88. CG_PROC * pCG;
  89. CG_HANDLE * pCGHandle = GetImplicitHandle();
  90. node_skl * pID;
  91. char Buffer[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT+1];
  92. short CallbackCount;
  93. ITERATOR ProcList;
  94. ISTREAM * pStream = pCCB->GetStream();
  95. int ProtSeqEPCount = 0;
  96. ITERATOR * pProtSeqIterator;
  97. char * pCStubPrefix;
  98. //Initialize the CCB for this interface.
  99. InitializeCCB(pCCB);
  100. pCCB->SetImplicitHandleIDNode( 0 );
  101. if( !GetMembers( I ) )
  102. {
  103. return CG_OK;
  104. }
  105. //
  106. // Emit the external variables needed.
  107. //
  108. if ( HasInterpretedCallbackProc() )
  109. Out_InterpreterServerInfoExtern( pCCB );
  110. pStream->NewLine();
  111. if( pCGHandle )
  112. {
  113. pID = pCGHandle->GetHandleIDOrParam();
  114. pID->PrintType( PRT_ID_DECLARATION, pStream, 0 );
  115. }
  116. //
  117. // Emit the protseq endpoint structure if necessary. It is not
  118. // necessary if the endpoint attribute was not specified in which
  119. // case the ep count is 0.
  120. //
  121. if( pProtSeqIterator = GetProtSeqEps())
  122. {
  123. ProtSeqEPCount = ITERATOR_GETCOUNT( *pProtSeqIterator );
  124. Out_EP_Info( pCCB, pProtSeqIterator );
  125. }
  126. //
  127. // Emit the interface information structure.
  128. //
  129. pCCB->GetVersion( &M,&m );
  130. CallbackCount = ((node_interface *)GetType())->GetCallBackProcCount();
  131. if( CallbackCount )
  132. {
  133. sprintf( Buffer,
  134. "extern %s %s%s%_DispatchTable;",
  135. RPC_DISPATCH_TABLE_TYPE_NAME,
  136. pCCB->GetInterfaceName(),
  137. pCCB->GenMangledName() );
  138. pStream->NewLine( 2 );
  139. pStream->Write( Buffer );
  140. /// NOTE:: This buffer is printed in the Out_IfInfo call !!!!
  141. sprintf( Buffer,
  142. "&%s%s_DispatchTable",
  143. pCCB->GetInterfaceName(),
  144. pCCB->GenMangledName() );
  145. }
  146. //
  147. // Must set this before outputing the interface info.
  148. //
  149. pCCB->SetCodeGenSide( CGSIDE_CLIENT );
  150. Out_IFInfo( pCCB, // controller block.
  151. RPC_C_INT_INFO_TYPE_NAME, // interface info type name.
  152. RPC_C_INT_INFO_STRUCT_NAME, // variable name.
  153. SIZEOF_RPC_CLIENT_INTERFACE, // string speicifying size.
  154. GuidStrs, // Guid specified in idl
  155. M, // user specified major version
  156. m, // user specified minor version
  157. TransferSyntaxGuidStrs, // ndr identifying guid.
  158. NDR_UUID_MAJOR_VERSION, // ndr's version
  159. NDR_UUID_MINOR_VERSION,
  160. CallbackCount ? Buffer : 0, // call back dispatch table name
  161. ProtSeqEPCount, // if this is 0, then the next
  162. // 2 fields are ignored by
  163. // the call.
  164. PROTSEQ_EP_TYPE_NAME, // RPC_PROTSEQ_ENDPOINT
  165. PROTSEQ_EP_VAR_NAME, // ___RpcProtSeqEndpoint
  166. pCCB->IsNoDefaultEpv(),
  167. 0, // client side
  168. HasPipes()
  169. );
  170. if( !(pCStubPrefix = pCommand->GetUserPrefix( PREFIX_CLIENT_STUB ) ) )
  171. {
  172. pCStubPrefix = "";
  173. }
  174. pStream->NewLine();
  175. sprintf( Buffer,
  176. "RPC_IF_HANDLE %s%s%s_%s = (RPC_IF_HANDLE)& %s" RPC_C_INT_INFO_STRUCT_NAME";",
  177. pCStubPrefix,
  178. pCCB->GetInterfaceName(),
  179. pCCB->GenMangledName(),
  180. ((pCCB->IsOldNames()) ? "ClientIfHandle" : "c_ifspec"),
  181. pCCB->GetInterfaceName()
  182. );
  183. pStream->Write( Buffer );
  184. //
  185. // Emit the stub descriptor extern declaration.
  186. //
  187. Out_StubDescriptorExtern( pCCB );
  188. // Emit the auto handle extern
  189. pStream->NewLine();
  190. sprintf( Buffer,
  191. "static %s %s%s;",
  192. AUTO_BH_TYPE_NAME,
  193. pCCB->GetInterfaceName(),
  194. AUTO_BH_VAR_NAME
  195. );
  196. pStream->Write( Buffer );
  197. pStream->NewLine();
  198. //
  199. // Send the message to the children to emit code.
  200. //
  201. //
  202. // for all procedure in this interface, generate code.
  203. //
  204. while( ITERATOR_GETNEXT( I, pCG ) )
  205. {
  206. pCG->GenClientStub( pCCB );
  207. }
  208. //
  209. // Emit the stub descriptor and all that is specific to the interface,
  210. // Generate externs to tables that may be common to several interfaces.
  211. //
  212. Out_StubDescriptor( GetImplicitHandle(), pCCB );
  213. //
  214. // Generate the dispatch table.
  215. //
  216. if( CallbackCount )
  217. {
  218. GetCallbackProcedureList( ProcList, DTF_NONE );
  219. Out_DispatchTableStuff( pCCB,
  220. ProcList,
  221. CallbackCount
  222. );
  223. }
  224. if ( HasInterpretedCallbackProc() )
  225. Out_InterpreterServerInfo( pCCB, CGSIDE_CLIENT );
  226. return CG_OK;
  227. }
  228. CG_STATUS
  229. CG_INTERFACE::GenServerStub(
  230. CCB * pCCB )
  231. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  232. Routine Description:
  233. Generate code for the interface node.
  234. Arguments:
  235. pCCB - a pointer to the code generation control block.
  236. Return Value:
  237. CG_OK if all is well, error otherwise.
  238. Notes:
  239. ----------------------------------------------------------------------------*/
  240. {
  241. unsigned short M,m; // for MAJOR and minor versions :-)
  242. CG_PROC * pCG;
  243. CG_ITERATOR I;
  244. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  245. ISTREAM * pStream = pCCB->GetStream();
  246. ITERATOR * pProtSeqIterator;
  247. short NormalProcCount;
  248. ITERATOR NormalProcList;
  249. node_interface * pInterface = (node_interface *)GetType();
  250. char * pSStubPrefix;
  251. InitializeCCB(pCCB);
  252. if( !GetMembers( I ) )
  253. {
  254. return CG_OK;
  255. }
  256. //
  257. // Emit the external variables needed.
  258. //
  259. if ( HasInterpretedProc() )
  260. Out_InterpreterServerInfoExtern( pCCB );
  261. //
  262. // Emit the protseq endpoint structure if necessary. It is not
  263. // necessary if the endpoint attribute was not specified in which
  264. // case the ep count is 0.
  265. //
  266. if( pProtSeqIterator = GetProtSeqEps() )
  267. {
  268. ProtSeqEPCount = ITERATOR_GETCOUNT( *pProtSeqIterator );
  269. Out_EP_Info( pCCB, pProtSeqIterator );
  270. }
  271. //
  272. // Emit the interface information structure.
  273. //
  274. pCCB->GetVersion( &M,&m );
  275. //
  276. // Emit the extern decl for the server's dispatch table, which goes
  277. // in the server interface structure which follows.
  278. //
  279. sprintf( Buffer,
  280. "extern %s %s%s_DispatchTable;",
  281. RPC_DISPATCH_TABLE_TYPE_NAME,
  282. pCCB->GetInterfaceName(),
  283. pCCB->GenMangledName() );
  284. pStream->NewLine( 2 );
  285. pStream->Write( Buffer );
  286. //
  287. // Emit the extern decl for the server side manager epv table, which goes
  288. // in the server interface structure which follows.
  289. //
  290. if( pCCB->IsMEpV() &&
  291. !pCCB->IsNoDefaultEpv() &&
  292. (pInterface->GetProcCount() != 0) )
  293. {
  294. sprintf( Buffer,
  295. "extern %s%s_%s DEFAULT_EPV;",
  296. pCCB->GetInterfaceName(),
  297. pCCB->GenMangledName(),
  298. pCCB->IsOldNames() ? "SERVER_EPV" : "epv_t" );
  299. pStream->NewLine( 2 );
  300. pStream->Write( Buffer );
  301. }
  302. // Prepare address string for the address of the dispatch table in the
  303. // interface information structure.
  304. sprintf( Buffer,
  305. "&%s%s_DispatchTable",
  306. pCCB->GetInterfaceName(),
  307. pCCB->GenMangledName()
  308. );
  309. //
  310. // Must set this before outputing the interface info.
  311. //
  312. pCCB->SetCodeGenSide( CGSIDE_SERVER );
  313. Out_IFInfo( pCCB, // controller block.
  314. RPC_S_INT_INFO_TYPE_NAME, // interface info type name.
  315. RPC_S_INT_INFO_STRUCT_NAME, // variable name.
  316. SIZEOF_RPC_SERVER_INTERFACE, // string speicifying size.
  317. GuidStrs, // Guid specified in idl
  318. M, // user specified major version
  319. m, // user specified minor version
  320. TransferSyntaxGuidStrs, // ndr identifying guid.
  321. NDR_UUID_MAJOR_VERSION, // ndr's version
  322. NDR_UUID_MINOR_VERSION,
  323. Buffer,
  324. ProtSeqEPCount, // if this is 0, then the next
  325. // 2 fields are ignored by
  326. // the call.
  327. PROTSEQ_EP_TYPE_NAME, // RPC_PROTSEQ_ENDPOINT
  328. PROTSEQ_EP_VAR_NAME, // ___RpcProtSeqEndpoint
  329. pCCB->IsNoDefaultEpv(),
  330. 1,
  331. HasPipes()
  332. );
  333. if( !(pSStubPrefix = pCommand->GetUserPrefix( PREFIX_SERVER_MGR ) ) )
  334. {
  335. pSStubPrefix = "";
  336. }
  337. pStream->NewLine();
  338. sprintf( Buffer,
  339. "RPC_IF_HANDLE %s%s%s_%s = (RPC_IF_HANDLE)& %s"
  340. RPC_S_INT_INFO_STRUCT_NAME";",
  341. pSStubPrefix,
  342. pCCB->GetInterfaceName(),
  343. pCCB->GenMangledName(),
  344. ((pCCB->IsOldNames()) ? "ServerIfHandle" : "s_ifspec"),
  345. pCCB->GetInterfaceName()
  346. );
  347. pStream->Write( Buffer );
  348. //
  349. // Emit the stub descriptor extern declaration.
  350. //
  351. Out_StubDescriptorExtern( pCCB );
  352. //
  353. // Send the message to the children to emit code.
  354. //
  355. //
  356. // For all procedures in this interface, generate code.
  357. //
  358. PNAME ContextHandleTypeName = NULL;
  359. BOOL GotContextHandle = FALSE;
  360. while( ITERATOR_GETNEXT( I, pCG ) )
  361. {
  362. pCG->GenServerStub( pCCB );
  363. }
  364. //
  365. // Emit the stub descriptor.
  366. //
  367. if ( HasInterpretedProc() )
  368. pCCB->SetOptimOption( pCCB->GetOptimOption() | OPTIMIZE_INTERPRETER );
  369. Out_StubDescriptor( GetImplicitHandle(), pCCB );
  370. //
  371. // Generate the dispatch table.
  372. //
  373. NormalProcCount = GetNormalProcedureList( NormalProcList,
  374. DTF_NONE
  375. );
  376. if( NormalProcCount )
  377. Out_DispatchTableStuff( pCCB,
  378. NormalProcList,
  379. NormalProcCount
  380. );
  381. // Generate the manager epv if the -use epv switch has been specified.
  382. if( pCCB->IsMEpV() && !pCCB->IsNoDefaultEpv() )
  383. {
  384. ITERATOR ProcList;
  385. short Count;
  386. Count = GetNormalProcedureList( ProcList,
  387. DTF_NONE
  388. );
  389. if( Count )
  390. {
  391. Out_ManagerEpv( pCCB, pCCB->GetInterfaceName(), ProcList, Count );
  392. }
  393. }
  394. if ( HasInterpretedProc() )
  395. Out_InterpreterServerInfo( pCCB, CGSIDE_SERVER );
  396. return CG_OK;
  397. }
  398. CG_STATUS
  399. CG_INTERFACE::GenHeader(
  400. CCB * pCCB )
  401. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  402. Routine Description:
  403. Generate interface header file.
  404. Arguments:
  405. pCCB - a pointer to the code generation control block.
  406. Return Value:
  407. CG_OK if all is well, error otherwise.
  408. Notes:
  409. ----------------------------------------------------------------------------*/
  410. {
  411. node_interface * pInterface = (node_interface *) GetType();
  412. ITERATOR I;
  413. ITERATOR J;
  414. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  415. CG_HANDLE * pCGHandle = GetImplicitHandle();
  416. node_skl * pID;
  417. ISTREAM * pStream = pCCB->GetStream();
  418. unsigned short M, m;
  419. char * pCStubPrefix;
  420. char * pSStubPrefix;
  421. char * pName = pInterface->GetSymName();
  422. BOOL fAnonymous = IsTempName( pName );
  423. //Initialize the CCB for this interface.
  424. InitializeCCB(pCCB);
  425. // put out the interface guards
  426. if ( !fAnonymous )
  427. {
  428. pStream->Write("\n#ifndef __");
  429. pStream->Write( pName );
  430. pStream->Write( "_INTERFACE_DEFINED__\n" );
  431. pStream->Write( "#define __");
  432. pStream->Write( pName );
  433. pStream->Write( "_INTERFACE_DEFINED__\n" );
  434. }
  435. // Print out the declarations of the types and the procedures.
  436. // If the user defined a prefix for the cstub or sstub,
  437. // then emit prototypes with the prefix in them.
  438. pStream->NewLine();
  439. pInterface->PrintType( (PRT_INTERFACE | PRT_BOTH_PREFIX), pStream, 0 );
  440. if( pCGHandle )
  441. {
  442. pID = pCGHandle->GetHandleIDOrParam();
  443. pStream->NewLine();
  444. pStream->Write( "extern " );
  445. pID->PrintType( PRT_ID_DECLARATION, pStream, 0 );
  446. }
  447. // Emit the declarations for user supplied routines.
  448. // Print out the dispatch table.
  449. pStream->NewLine();
  450. GetNormalProcedureList( I, DTF_NONE );
  451. if( pCCB->IsMEpV() )
  452. {
  453. if( ITERATOR_GETCOUNT(I) )
  454. Out_DispatchTableTypedef(
  455. pCCB,
  456. pCCB->GetInterfaceName(),
  457. I,
  458. 0
  459. );
  460. }
  461. GetCallbackProcedureList( J, DTF_NONE );
  462. if( ITERATOR_GETCOUNT(J ) )
  463. Out_DispatchTableTypedef(
  464. pCCB,
  465. pCCB->GetInterfaceName(),
  466. J,
  467. 1
  468. );
  469. pCCB->GetVersion( &M, &m );
  470. if( !(pCStubPrefix = pCommand->GetUserPrefix( PREFIX_CLIENT_STUB ) ) )
  471. {
  472. pCStubPrefix = 0;
  473. }
  474. if( !(pSStubPrefix = pCommand->GetUserPrefix( PREFIX_SERVER_MGR ) ) )
  475. {
  476. pSStubPrefix = 0;
  477. }
  478. // Generate the extern for the client if handle.
  479. pStream->NewLine();
  480. sprintf( Buffer, "extern RPC_IF_HANDLE %s%s%s_%s;",
  481. (pCStubPrefix == 0) ? "" : pCStubPrefix,
  482. pCCB->GetInterfaceName(),
  483. pCCB->GenMangledName(),
  484. (pCCB->IsOldNames()) ? "ClientIfHandle" : "c_ifspec" );
  485. pStream->Write( Buffer );
  486. // If a prefix is defined for cstub, generate another extern for the
  487. // non - prefixed client if handle. Remember, in the header file we need
  488. // both the externs, since the header file generated out of the -prefix
  489. // cstub invocation contains prototypes for both prefixed and non-prefix
  490. // stuff.
  491. if( pCStubPrefix )
  492. {
  493. pStream->NewLine();
  494. sprintf( Buffer, "extern RPC_IF_HANDLE %s%s%s_%s;",
  495. "",
  496. pCCB->GetInterfaceName(),
  497. pCCB->GenMangledName(),
  498. (pCCB->IsOldNames()) ? "ClientIfHandle" : "c_ifspec" );
  499. pStream->Write( Buffer );
  500. }
  501. pStream->NewLine();
  502. sprintf( Buffer, "extern RPC_IF_HANDLE %s%s%s_%s;",
  503. (pSStubPrefix == 0) ? "" : pSStubPrefix,
  504. pCCB->GetInterfaceName(),
  505. pCCB->GenMangledName(),
  506. (pCCB->IsOldNames()) ? "ServerIfHandle" : "s_ifspec" );
  507. pStream->Write( Buffer );
  508. pStream->NewLine();
  509. // put out the trailing interface guard
  510. if ( !fAnonymous )
  511. {
  512. pStream->Write( "#endif /* __");
  513. pStream->Write( pName );
  514. pStream->Write( "_INTERFACE_DEFINED__ */\n" );
  515. }
  516. return CG_OK;
  517. }
  518. ITERATOR *
  519. CG_INTERFACE::GetProtSeqEps()
  520. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  521. Routine Description:
  522. Get the protocol sequences pairs iterator.
  523. Arguments:
  524. Iterator reference.
  525. Return Value:
  526. FALSE if there are no endpoints
  527. Notes:
  528. The iterator is invalid if there are no endpoints.
  529. ----------------------------------------------------------------------------*/
  530. {
  531. node_interface * pIntf = (node_interface *) GetType();
  532. node_endpoint * pEps = (node_endpoint *)
  533. pIntf->GetAttribute( ATTR_ENDPOINT );
  534. return ( pEps ) ? &(pEps->GetEndPointPairs()) : NULL;
  535. }
  536. void
  537. CG_INTERFACE::CreateDispatchTables()
  538. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  539. Routine Description:
  540. Set up the stub dispatch tables.
  541. Arguments:
  542. None.
  543. Return Value:
  544. None.
  545. Notes:
  546. ----------------------------------------------------------------------------*/
  547. {
  548. pNormalDispatchTable = new DISPATCH_TABLE();
  549. pCallbackDispatchTable = new DISPATCH_TABLE();
  550. ppDispatchTableSaved = ppDispatchTable = &pNormalDispatchTable;
  551. }
  552. BOOL
  553. CG_INTERFACE::HasInterpretedProc()
  554. {
  555. CG_ITERATOR Iterator;
  556. CG_PROC * pProc;
  557. GetMembers( Iterator );
  558. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  559. if ( pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER )
  560. return TRUE;
  561. return FALSE;
  562. }
  563. BOOL
  564. CG_INTERFACE::HasOnlyInterpretedProcs()
  565. {
  566. CG_ITERATOR Iterator;
  567. CG_PROC * pProc;
  568. GetMembers( Iterator );
  569. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  570. if ( (pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER ) == 0 )
  571. return FALSE;
  572. return TRUE;
  573. }
  574. BOOL
  575. CG_OBJECT_INTERFACE::HasOnlyInterpretedMethods()
  576. {
  577. CG_ITERATOR Iterator;
  578. CG_PROC * pProc;
  579. if ( pBaseCG && !pBaseCG->HasOnlyInterpretedMethods() )
  580. return FALSE;
  581. GetMembers( Iterator );
  582. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  583. if ( (pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER ) == 0 )
  584. return FALSE;
  585. return TRUE;
  586. }
  587. BOOL
  588. CG_INTERFACE::HasItsOwnOi2()
  589. {
  590. CG_ITERATOR Iterator;
  591. CG_PROC * pProc;
  592. GetMembers( Iterator );
  593. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  594. if ( (pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2) )
  595. return TRUE;
  596. return FALSE;
  597. }
  598. void
  599. CG_INTERFACE::EvaluateVersionControl()
  600. {
  601. if ( HasItsOwnOi2() )
  602. {
  603. GetNdrVersionControl().SetHasOi2();
  604. }
  605. }
  606. BOOL
  607. CG_OBJECT_INTERFACE::HasItsOwnStublessProxies()
  608. {
  609. CG_ITERATOR Iterator;
  610. CG_PROC * pProc;
  611. GetMembers( Iterator );
  612. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  613. if (pProc->GetOptimizationFlags() & OPTIMIZE_STUBLESS_CLIENT )
  614. return TRUE;
  615. return FALSE;
  616. }
  617. void
  618. CG_OBJECT_INTERFACE::EvaluateVersionControl()
  619. {
  620. if ( pBaseCG )
  621. {
  622. pBaseCG->EvaluateVersionControl();
  623. }
  624. if ( HasItsOwnStublessProxies() ||
  625. pBaseCG && pBaseCG->HasStublessProxies() )
  626. {
  627. GetNdrVersionControl().SetHasStublessProxies();
  628. }
  629. if ( HasItsOwnOi2() ||
  630. pBaseCG && pBaseCG->HasOi2() )
  631. {
  632. GetNdrVersionControl().SetHasOi2();
  633. }
  634. }
  635. BOOL
  636. CG_INTERFACE::HasInterpretedCallbackProc()
  637. {
  638. CG_ITERATOR Iterator;
  639. CG_PROC * pProc;
  640. GetMembers( Iterator );
  641. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  642. if ( pProc->GetCGID() == ID_CG_CALLBACK_PROC &&
  643. pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER )
  644. return TRUE;
  645. return FALSE;
  646. }
  647. BOOL
  648. CG_INTERFACE::HasClientInterpretedCommOrFaultProc( CCB * pCCB )
  649. {
  650. CG_ITERATOR Iterator;
  651. CG_PROC * pProc;
  652. CGSIDE Side;
  653. Side = pCCB->GetCodeGenSide();
  654. GetMembers( Iterator );
  655. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  656. if ( (pProc->GetOptimizationFlags() & OPTIMIZE_INTERPRETER) &&
  657. pProc->HasStatuses() &&
  658. ( ((pProc->GetCGID() == ID_CG_PROC) && (Side == CGSIDE_CLIENT)) ||
  659. ((pProc->GetCGID() == ID_CG_CALLBACK_PROC) && (Side == CGSIDE_SERVER)) ) )
  660. return TRUE;
  661. return FALSE;
  662. }
  663. CG_STATUS
  664. CG_INTERFACE::InitializeCCB( CCB * pCCB )
  665. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  666. Routine Description:
  667. Initialize the CCB for this interface.
  668. Arguments:
  669. pCCB - a pointer to the code generation control block.
  670. Return Value:
  671. CG_OK if all is well, error otherwise.
  672. Notes:
  673. ----------------------------------------------------------------------------*/
  674. {
  675. unsigned short Major,minor;
  676. node_interface *pInterface = (node_interface *) GetType();
  677. pInterface->GetVersionDetails(&Major, &minor);
  678. pCCB->SetVersion(Major, minor);
  679. pCCB->SetInterfaceName(pInterface->GetSymName());
  680. pCCB->SetInterfaceCG(this);
  681. return CG_OK;
  682. }
  683. void
  684. CG_INTERFACE::OutputProcOffsets( CCB * pCCB, BOOL fLast, BOOL fLocal)
  685. {
  686. CG_PROC * pProc;
  687. CG_ITERATOR Iterator;
  688. ISTREAM * pStream = pCCB->GetStream();
  689. char Buffer[80];
  690. CGSIDE Side;
  691. long Offset;
  692. // IUnknown doesn't get entries in the proc offsets table
  693. if ( IsIUnknown() )
  694. {
  695. if ( fLast )
  696. {
  697. pStream->Write( '0' );
  698. pStream->NewLine();
  699. }
  700. return;
  701. }
  702. Side = pCCB->GetCodeGenSide();
  703. if ( IsObject() )
  704. {
  705. CG_OBJECT_INTERFACE * pObjInterface;
  706. pObjInterface = (CG_OBJECT_INTERFACE *) this;
  707. if ( pObjInterface->GetBaseInterfaceCG() )
  708. {
  709. pObjInterface->GetBaseInterfaceCG()->OutputProcOffsets( pCCB, FALSE, fLocal );
  710. }
  711. }
  712. GetMembers( Iterator );
  713. BOOL fNoOffsetsEmitted = TRUE;
  714. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  715. {
  716. if ( (Side == CGSIDE_CLIENT) &&
  717. (pProc->GetCGID() != ID_CG_CALLBACK_PROC) )
  718. continue;
  719. if ( (Side == CGSIDE_SERVER) &&
  720. (pProc->GetCGID() == ID_CG_CALLBACK_PROC) )
  721. continue;
  722. fNoOffsetsEmitted = FALSE;
  723. if (pProc->IsHookOleLocal() == fLocal)
  724. Offset = pProc->GetFormatStringOffset();
  725. else
  726. {
  727. CG_PROC * pCallAs = pProc->GetCallAsCG();
  728. if (fLocal && pCallAs)
  729. Offset = pCallAs->GetFormatStringOffset();
  730. else
  731. Offset = -1;
  732. }
  733. MIDL_ITOA( Offset, Buffer, 10 );
  734. if ( Offset == -1 )
  735. pStream->Write( "(unsigned short) " );
  736. pStream->Write( Buffer );
  737. if ( pProc->GetSibling() || !fLast )
  738. pStream->Write( ',' );
  739. pStream->NewLine();
  740. }
  741. if ( fNoOffsetsEmitted && fLast )
  742. {
  743. pStream->Write( '0' );
  744. pStream->NewLine();
  745. }
  746. }
  747. void
  748. CG_INTERFACE::OutputThunkTableEntries( CCB * pCCB, BOOL fLast )
  749. {
  750. CG_PROC * pProc;
  751. CG_ITERATOR Iterator;
  752. ISTREAM * pStream = pCCB->GetStream();
  753. CGSIDE Side = pCCB->GetCodeGenSide();
  754. char * pIntfName = GetType()->GetSymName();
  755. // IUnknown doesn't get entries in the thunk table
  756. if ( IsIUnknown() )
  757. {
  758. if ( fLast )
  759. {
  760. pStream->Write( '0' );
  761. pStream->NewLine();
  762. }
  763. return;
  764. }
  765. if ( IsObject() )
  766. {
  767. CG_OBJECT_INTERFACE * pObjInterface;
  768. pObjInterface = (CG_OBJECT_INTERFACE *) this;
  769. if ( pObjInterface->GetBaseInterfaceCG() )
  770. {
  771. pObjInterface->GetBaseInterfaceCG()->OutputThunkTableEntries( pCCB, FALSE );
  772. }
  773. }
  774. GetMembers( Iterator );
  775. while ( ITERATOR_GETNEXT( Iterator, pProc ) )
  776. {
  777. if ( (Side == CGSIDE_CLIENT) &&
  778. (pProc->GetCGID() != ID_CG_CALLBACK_PROC) )
  779. continue;
  780. if ( (Side == CGSIDE_SERVER) &&
  781. (pProc->GetCGID() == ID_CG_CALLBACK_PROC) )
  782. continue;
  783. if ( pProc->NeedsServerThunk( pCCB, Side ) && !pProc->IsDelegated() )
  784. {
  785. pStream->Write( pIntfName );
  786. pStream->Write( '_' );
  787. pStream->Write( pProc->GetType()->GetSymName() );
  788. // if( IsObject() )
  789. pStream->Write( "_Thunk" );
  790. }
  791. else
  792. pStream->Write( '0' );
  793. if ( pProc->GetSibling() || !fLast )
  794. pStream->Write( ',' );
  795. pStream->NewLine();
  796. }
  797. }
  798. void
  799. CG_INTERFACE::OutputInterfaceIdComment( CCB * pCCB )
  800. {
  801. char TmpBuf[40];
  802. unsigned short Major, Minor;
  803. ISTREAM * pStream = pCCB->GetStream();
  804. char * pIfKind = IsObject() ? "Object"
  805. : HasPicklingStuffOnly() ? "Pickling"
  806. : "Standard";
  807. pStream->NewLine(2);
  808. sprintf( TmpBuf, "/* %s interface: ", pIfKind );
  809. pStream->Write( TmpBuf );
  810. pStream->Write( GetInterfaceName() );
  811. ((node_interface *) GetType())->GetVersionDetails( &Major, &Minor );
  812. sprintf( TmpBuf, ", ver. %d.%d,\n GUID=", Major, Minor );
  813. pStream->Write( TmpBuf );
  814. Out_Guid( pCCB, GetGuidStrs() );
  815. pStream->Write( " */" );
  816. pStream->NewLine();
  817. }