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.

2953 lines
63 KiB

4 years ago
  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. filecls.hxx
  5. Abstract:
  6. Code generation methods for file 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. /****************************************************************************
  23. * externs
  24. ***************************************************************************/
  25. extern CMD_ARG * pCommand;
  26. extern BOOL IsTempName( char * );
  27. /****************************************************************************/
  28. void
  29. CG_FILE::CheckForHeadingToken(
  30. CCB * pCCB )
  31. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  32. Routine Description:
  33. Emit standard block comment file heading portion.
  34. Arguments:
  35. pCCB - a pointer to the code generation control block.
  36. Return Value:
  37. CG_OK if all is well, error otherwise.
  38. Notes:
  39. ----------------------------------------------------------------------------*/
  40. {
  41. ISTREAM * pStream = pCCB->GetStream();
  42. if ( pCCB->IsReparsingCurrentFile() )
  43. {
  44. MIDL_TOKEN FoundToken;
  45. ((RW_ISTREAM *) pStream)->SaveToNextMidlToken( FoundToken );
  46. if ( FoundToken.GetTokenType() != FILE_HEADING_TOKEN )
  47. {
  48. assert(!"expecting file heading token" );
  49. }
  50. }
  51. pStream->EmitToken( MIDL_TOKEN( FILE_HEADING_TOKEN ) );
  52. pStream->NewLine();
  53. }
  54. void
  55. CG_FILE::EmitStandardHeadingBlock(
  56. CCB * pCCB,
  57. char * CommentStr )
  58. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  59. Routine Description:
  60. Emit standard block comment file heading portion.
  61. Arguments:
  62. pCCB - a pointer to the code generation control block.
  63. Return Value:
  64. CG_OK if all is well, error otherwise.
  65. Notes:
  66. ----------------------------------------------------------------------------*/
  67. {
  68. ISTREAM * pStream = pCCB->GetStream();
  69. pStream->NewLine();
  70. if ( CommentStr )
  71. pStream->Write( CommentStr );
  72. else
  73. pStream->Write( "/*" );
  74. pStream->Write(" File created by MIDL compiler version ");
  75. pStream->Write( GetCompilerVersion() );
  76. if ( CommentStr == 0 )
  77. pStream->Write(" */");
  78. pStream->NewLine();
  79. if ( CommentStr )
  80. pStream->Write( CommentStr );
  81. else
  82. pStream->Write( "/*" );
  83. pStream->Write(" at ");
  84. pStream->Write( GetCompileTime() );
  85. if ( CommentStr == 0 )
  86. pStream->Write(" */");
  87. pStream->NewLine();
  88. // Emit command line switches information.
  89. pCommand->EmitConfirm( pStream );
  90. if ( pCCB->IsReparsingCurrentFile() )
  91. {
  92. MIDL_TOKEN FoundToken;
  93. ((RW_ISTREAM *) pStream)->DiscardToNextMidlToken( FoundToken );
  94. if ( FoundToken.GetTokenType() != FILE_HEADING_TOKEN )
  95. {
  96. assert(!"expecting file heading token" );
  97. }
  98. }
  99. pStream->EmitToken( MIDL_TOKEN( FILE_HEADING_TOKEN ) );
  100. pStream->NewLine();
  101. }
  102. void
  103. CG_FILE::EmitFormatStringTypedefs(
  104. CCB * pCCB )
  105. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  106. Routine Description:
  107. Emit dummy #defines with sizes for the format string structs,
  108. then emit typedefs for the type and proc format string structs.
  109. Sets the context position in the file node for later use.
  110. Arguments:
  111. pCCB - a pointer to the code generation control block.
  112. Notes:
  113. The typedefs are going to be fixed later by a call to
  114. EmitFixupFormatStringTpedefs. This is needed for ANSI.
  115. The dummies would work for ANSI non-compliant code.
  116. --------------------------------------------------------------------------*/
  117. {
  118. ISTREAM * pStream = pCCB->GetStream();
  119. pStream->NewLine(2);
  120. pStream->Write( "#define TYPE_FORMAT_STRING_SIZE " );
  121. SetTypeSizeContextPosition( pStream->GetCurrentPosition() );
  122. pStream->Write( " " );
  123. pStream->NewLine();
  124. pStream->Write( "#define PROC_FORMAT_STRING_SIZE " );
  125. SetProcSizeContextPosition( pStream->GetCurrentPosition() );
  126. pStream->Write( " " );
  127. if (pCommand->IsHookOleEnabled())
  128. {
  129. pStream->NewLine();
  130. pStream->Write( "#define LOCAL_TYPE_FORMAT_STRING_SIZE " );
  131. SetLocalTypeSizeContextPosition( pStream->GetCurrentPosition() );
  132. pStream->Write( " " );
  133. pStream->NewLine();
  134. pStream->Write( "#define LOCAL_PROC_FORMAT_STRING_SIZE " );
  135. SetLocalProcSizeContextPosition( pStream->GetCurrentPosition() );
  136. pStream->Write( " " );
  137. }
  138. pStream->NewLine(2);
  139. pStream->Write( "typedef struct _" FORMAT_STRING_TYPE_NAME );
  140. pStream->IndentInc();
  141. pStream->NewLine();
  142. pStream->Write( "{" );
  143. pStream->NewLine();
  144. pStream->Write( "short Pad;" );
  145. pStream->NewLine();
  146. pStream->Write( "unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];" );
  147. pStream->NewLine();
  148. pStream->Write( "} " FORMAT_STRING_TYPE_NAME ";" );
  149. pStream->IndentDec();
  150. pStream->NewLine(2);
  151. pStream->Write( "typedef struct _" PROC_FORMAT_STRING_TYPE_NAME );
  152. pStream->IndentInc();
  153. pStream->NewLine();
  154. pStream->Write( "{" );
  155. pStream->NewLine();
  156. pStream->Write( "short Pad;" );
  157. pStream->NewLine();
  158. pStream->Write( "unsigned char Format[ PROC_FORMAT_STRING_SIZE ];" );
  159. pStream->NewLine();
  160. pStream->Write( "} " PROC_FORMAT_STRING_TYPE_NAME ";" );
  161. pStream->IndentDec();
  162. pStream->NewLine();
  163. if (pCommand->IsHookOleEnabled())
  164. {
  165. pStream->NewLine();
  166. pStream->Write( "typedef struct _" LOCAL_FORMAT_STRING_TYPE_NAME );
  167. pStream->IndentInc();
  168. pStream->Write( "{" );
  169. pStream->NewLine();
  170. pStream->Write( "short Pad;" );
  171. pStream->NewLine();
  172. pStream->Write( "unsigned char Format[ LOCAL_TYPE_FORMAT_STRING_SIZE ];" );
  173. pStream->NewLine();
  174. pStream->Write( "} " LOCAL_FORMAT_STRING_TYPE_NAME ";" );
  175. pStream->IndentDec();
  176. pStream->NewLine(2);
  177. pStream->Write( "typedef struct _" LOCAL_PROC_FORMAT_STRING_TYPE_NAME );
  178. pStream->IndentInc();
  179. pStream->NewLine();
  180. pStream->Write( "{" );
  181. pStream->NewLine();
  182. pStream->Write( "short Pad;" );
  183. pStream->NewLine();
  184. pStream->Write( "unsigned char Format[ LOCAL_PROC_FORMAT_STRING_SIZE ];" );
  185. pStream->NewLine();
  186. pStream->Write( "} " LOCAL_PROC_FORMAT_STRING_TYPE_NAME ";" );
  187. pStream->IndentDec();
  188. pStream->NewLine();
  189. }
  190. }
  191. void
  192. CG_FILE::EmitFixupToFormatStringTypedefs(
  193. CCB * pCCB )
  194. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  195. Routine Description:
  196. Fixes he dummy #defines emitted by EmitFormatStringTypedefs.
  197. Arguments:
  198. pCCB - a pointer to the code generation control block.
  199. pContext - a pointer to the position context
  200. --------------------------------------------------------------------------*/
  201. {
  202. char Buffer[20];
  203. ISTREAM * pStream = pCCB->GetStream();
  204. long EofPosition = pStream->GetCurrentPosition();
  205. pStream->SetCurrentPosition( GetTypeSizeContextPosition() );
  206. sprintf( Buffer, "%d", pCCB->GetFormatString()->GetCurrentOffset() + 1);
  207. pStream->Write( Buffer );
  208. pStream->SetCurrentPosition( GetProcSizeContextPosition() );
  209. sprintf( Buffer, "%d", pCCB->GetProcFormatString()->GetCurrentOffset() + 1);
  210. pStream->Write( Buffer );
  211. if ( pCommand->IsHookOleEnabled() )
  212. {
  213. pStream->SetCurrentPosition( GetLocalTypeSizeContextPosition() );
  214. sprintf( Buffer, "%d", GetLocalFormatString()->GetCurrentOffset() + 1);
  215. pStream->Write( Buffer );
  216. pStream->SetCurrentPosition( GetLocalProcSizeContextPosition() );
  217. sprintf( Buffer, "%d", GetLocalProcFormatString()->GetCurrentOffset() + 1);
  218. pStream->Write( Buffer );
  219. }
  220. pStream->SetCurrentPosition( EofPosition );
  221. }
  222. CG_STATUS
  223. CG_SOURCE::GenCode(
  224. CCB * pCCB )
  225. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  226. Routine Description:
  227. Generate code for the source node.
  228. Arguments:
  229. pCCB - a pointer to the code generation control block.
  230. Return Value:
  231. CG_OK if all is well, error otherwise.
  232. Notes:
  233. ----------------------------------------------------------------------------*/
  234. {
  235. CG_ITERATOR I;
  236. CG_FILE * pCG;
  237. //
  238. // for all files nodes in this interface, generate code.
  239. //
  240. GetMembers( I );
  241. while( ITERATOR_GETNEXT( I, pCG ) )
  242. {
  243. pCG->GenCode( pCCB );
  244. }
  245. return CG_OK;
  246. }
  247. void
  248. CG_CSTUB_FILE::EmitFileHeadingBlock(
  249. CCB * pCCB )
  250. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  251. Routine Description:
  252. Emit block comment file heading.
  253. Arguments:
  254. pCCB - a pointer to the code generation control block.
  255. Return Value:
  256. none.
  257. Notes:
  258. ----------------------------------------------------------------------------*/
  259. {
  260. ISTREAM * pStream = pCCB->GetStream();
  261. pStream->Write( "/* this ALWAYS GENERATED file contains the RPC client stubs */" );
  262. pStream->NewLine(2);
  263. EmitStandardHeadingBlock( pCCB );
  264. }
  265. CG_STATUS
  266. CG_CSTUB_FILE::GenCode(
  267. CCB * pCCB )
  268. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  269. Routine Description:
  270. Generate code for the file node.
  271. Arguments:
  272. pCCB - a pointer to the code generation control block.
  273. Return Value:
  274. CG_OK if all is well, error otherwise.
  275. Notes:
  276. ----------------------------------------------------------------------------*/
  277. {
  278. CG_ITERATOR I;
  279. CG_NDR * pCG;
  280. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  281. char Drive[ _MAX_DRIVE ];
  282. char Path[ _MAX_DIR ];
  283. char Name[ _MAX_FNAME ];
  284. char Ext[ _MAX_EXT ];
  285. if( !GetMembers( I ) )
  286. {
  287. return CG_OK;
  288. }
  289. ISTREAM Stream( GetFileName(), 4 );
  290. ISTREAM * pStream = &Stream;
  291. pCCB->SetStream(pStream);
  292. // Set HasStublessProxies and HasOi2 for each interface.
  293. EvaluateVersionControl();
  294. EmitFileHeadingBlock( pCCB );
  295. // Emit the hash includes.
  296. Out_IncludeOfFile( pCCB, STRING_H_INC_FILE_NAME, TRUE );
  297. pStream->NewLine();
  298. pStream->Write( ALPHA_IFDEF );
  299. Out_IncludeOfFile( pCCB, STDARG_H_INC_FILE_NAME, TRUE );
  300. pStream->NewLine();
  301. pStream->Write( "#endif");
  302. pStream->NewLine();
  303. // rpcssm puts a reference to malloc and free in the stub_c.c.
  304. // So, we have to emit the appropriate include.
  305. // In ms_ext when explicit, in osf always, to cover some weird cases.
  306. while( ITERATOR_GETNEXT( I, pCG ) )
  307. {
  308. if ( ( ((CG_INTERFACE *)pCG)->GetUsesRpcSS() || (pCCB->GetMode() == 0) ))
  309. {
  310. Out_IncludeOfFile( pCCB, "malloc.h", TRUE );
  311. break;
  312. }
  313. }
  314. _splitpath( GetHeaderFileName(), Drive, Path, Name, Ext );
  315. strcpy( Buffer, Name );
  316. strcat( Buffer, Ext );
  317. Out_IncludeOfFile( pCCB, Buffer, FALSE );
  318. EmitFormatStringTypedefs( pCCB );
  319. //
  320. // Emit the external variables needed.
  321. //
  322. pStream->NewLine();
  323. //
  324. // Emit the format string extern declarations.
  325. //
  326. Out_TypeFormatStringExtern( pCCB );
  327. Out_ProcFormatStringExtern( pCCB );
  328. Out_LocalTypeFormatStringExtern( pCCB );
  329. Out_LocalProcFormatStringExtern( pCCB );
  330. pCCB->ClearOptionalExternFlags();
  331. pCCB->SetFileCG(this);
  332. //
  333. // Create a new format string object if it does not yet exist.
  334. //
  335. if ( !GetFormatString() )
  336. {
  337. SetFormatString(new FORMAT_STRING());
  338. SetLocalFormatString(new FORMAT_STRING());
  339. }
  340. pCCB->SetFormatString( GetFormatString() );
  341. if ( !GetProcFormatString() )
  342. {
  343. SetProcFormatString(new FORMAT_STRING());
  344. SetLocalProcFormatString(new FORMAT_STRING());
  345. }
  346. pCCB->SetProcFormatString( GetProcFormatString() );
  347. //
  348. // Send the message to the children to emit code.
  349. //
  350. //
  351. // for all interfaces in this file, generate code.
  352. //
  353. ITERATOR_INIT( I );
  354. while( ITERATOR_GETNEXT( I, pCG ) )
  355. {
  356. switch(pCG->GetCGID())
  357. {
  358. case ID_CG_INTERFACE:
  359. ((CG_INTERFACE *)pCG)->OutputInterfaceIdComment( pCCB );
  360. ((CG_INTERFACE *)pCG)->GenClientStub( pCCB );
  361. break;
  362. case ID_CG_OBJECT_INTERFACE:
  363. case ID_CG_INHERITED_OBJECT_INTERFACE:
  364. break;
  365. default:
  366. break;
  367. }
  368. }
  369. //
  370. // Output the tables that may be common to several interfaces.
  371. //
  372. EmitFixupToFormatStringTypedefs( pCCB );
  373. pCCB->OutputMultipleInterfaceTables(GetLocalFormatString(), GetLocalProcFormatString());
  374. return CG_OK;
  375. }
  376. /****************************************************************************
  377. * sstub file implementation class.
  378. ***************************************************************************/
  379. void
  380. CG_SSTUB_FILE::EmitFileHeadingBlock(
  381. CCB * pCCB )
  382. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  383. Routine Description:
  384. Emit block comment file heading.
  385. Arguments:
  386. pCCB - a pointer to the code generation control block.
  387. Return Value:
  388. none.
  389. Notes:
  390. ----------------------------------------------------------------------------*/
  391. {
  392. ISTREAM * pStream = pCCB->GetStream();
  393. pStream->Write( "/* this ALWAYS GENERATED file contains the RPC server stubs */" );
  394. pStream->NewLine(2);
  395. EmitStandardHeadingBlock( pCCB );
  396. }
  397. CG_STATUS
  398. CG_SSTUB_FILE::GenCode(
  399. CCB * pCCB )
  400. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  401. Routine Description:
  402. Generate code for the file node.
  403. Arguments:
  404. pCCB - a pointer to the code generation control block.
  405. Return Value:
  406. CG_OK if all is well, error otherwise.
  407. Notes:
  408. ----------------------------------------------------------------------------*/
  409. {
  410. CG_ITERATOR I;
  411. CG_NDR * pCG;
  412. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  413. char Drive[ _MAX_DRIVE ];
  414. char Path[ _MAX_DIR ];
  415. char Name[ _MAX_FNAME ];
  416. char Ext[ _MAX_EXT ];
  417. if( !GetMembers( I ) )
  418. {
  419. return CG_OK;
  420. }
  421. ISTREAM Stream( GetFileName(), 4 );
  422. ISTREAM * pStream = &Stream;
  423. pCCB->SetStream(pStream);
  424. // Set HasStublessProxies and HasOi2 for each interface.
  425. EvaluateVersionControl();
  426. EmitFileHeadingBlock( pCCB );
  427. //
  428. // Emit the hash includes.
  429. //
  430. Out_IncludeOfFile( pCCB, STRING_H_INC_FILE_NAME, TRUE );
  431. _splitpath( GetHeaderFileName(), Drive, Path, Name, Ext );
  432. strcpy( Buffer, Name );
  433. strcat( Buffer, Ext );
  434. Out_IncludeOfFile( pCCB, Buffer, FALSE );
  435. EmitFormatStringTypedefs( pCCB );
  436. //
  437. // Emit the external variables needed.
  438. //
  439. //
  440. // Emit the format string extern declarations.
  441. //
  442. Out_TypeFormatStringExtern( pCCB );
  443. Out_ProcFormatStringExtern( pCCB );
  444. Out_LocalTypeFormatStringExtern( pCCB );
  445. Out_LocalProcFormatStringExtern( pCCB );
  446. pCCB->ClearOptionalExternFlags();
  447. pCCB->SetFileCG(this);
  448. //
  449. // Create a new format string object if it does not exist.
  450. //
  451. if ( !GetFormatString() )
  452. {
  453. SetFormatString(new FORMAT_STRING());
  454. SetLocalFormatString(new FORMAT_STRING());
  455. }
  456. pCCB->SetFormatString( GetFormatString() );
  457. if ( !GetProcFormatString() )
  458. {
  459. SetProcFormatString(new FORMAT_STRING());
  460. SetLocalProcFormatString(new FORMAT_STRING());
  461. }
  462. pCCB->SetProcFormatString( GetProcFormatString() );
  463. //
  464. // Send the message to the children to emit code.
  465. //
  466. //
  467. // For all interfaces in this file, generate code.
  468. //
  469. PNAME ContextHandleTypeName = NULL;
  470. BOOL GotContextHandle = FALSE;
  471. BOOL HasInterpretedProc = FALSE;
  472. while( ITERATOR_GETNEXT( I, pCG ) )
  473. {
  474. if ( pCG->GetCGID() == ID_CG_INTERFACE )
  475. {
  476. if ( ! ((CG_INTERFACE *)pCG)->HasPicklingStuffOnly() )
  477. {
  478. pCCB->SetSkipFormatStreamGeneration( FALSE );
  479. ((CG_INTERFACE *)pCG)->OutputInterfaceIdComment( pCCB );
  480. ((CG_INTERFACE *)pCG)->GenServerStub( pCCB );
  481. if ( ((CG_INTERFACE *)pCG)->HasInterpretedProc() )
  482. HasInterpretedProc = TRUE;
  483. }
  484. }
  485. }
  486. //
  487. // Output the tables that may be common to several interfaces.
  488. pCCB->SetCodeGenSide( CGSIDE_SERVER );
  489. //
  490. // If there was at least one interpreted proc in the interfaces of this
  491. // file than make sure to turn the optimization bit in the CCB's
  492. // OptimOption on.
  493. //
  494. EmitFixupToFormatStringTypedefs( pCCB );
  495. if ( HasInterpretedProc )
  496. pCCB->SetOptimOption( pCCB->GetOptimOption() | OPTIMIZE_INTERPRETER );
  497. pCCB->OutputMultipleInterfaceTables(GetLocalFormatString(), GetLocalProcFormatString());
  498. return CG_OK;
  499. }
  500. class GUID_DICTIONARY : public Dictionary
  501. {
  502. public:
  503. GUID_DICTIONARY()
  504. {
  505. }
  506. virtual
  507. int Compare (pUserType p1, pUserType p2)
  508. {
  509. INTERNAL_UUID * u1 = &( ((CG_INTERFACE *)p1)->GetGuidStrs().Value );
  510. INTERNAL_UUID * u2 = &( ((CG_INTERFACE *)p2)->GetGuidStrs().Value );
  511. return memcmp( u1, u2, 16 );
  512. }
  513. };
  514. void
  515. CG_PROXY_FILE::MakeImplementedInterfacesList(
  516. CCB * pCCB )
  517. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  518. Routine Description:
  519. Make a list of all the interfaces supported by this proxy file
  520. ( non-inherited, non-local interfaces ).
  521. Arguments:
  522. pCCB - a pointer to the code generation control block.
  523. Return Value:
  524. CG_OK if all is well, error otherwise.
  525. Notes:
  526. ----------------------------------------------------------------------------*/
  527. {
  528. CG_INTERFACE * pCG;
  529. CG_ITERATOR I;
  530. GUID_DICTIONARY GuidDict;
  531. // work directly on the real list
  532. GetMembers( I );
  533. while( ITERATOR_GETNEXT( I, pCG ) )
  534. {
  535. if ( pCG->GetCGID() != ID_CG_OBJECT_INTERFACE )
  536. continue;
  537. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsLocal() && !pCommand->IsHookOleEnabled())
  538. continue;
  539. GuidDict.Dict_Insert( pCG );
  540. }
  541. GuidDict.Dict_GetList( ImplementedInterfaces );
  542. GuidDict.Dict_Discard();
  543. }
  544. void
  545. CG_FILE::EvaluateVersionControl()
  546. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  547. Routine Description:
  548. Calculates HasStublessProxies and Oi2 flags only through the
  549. interfaces.
  550. Arguments:
  551. pCCB - a pointer to the code generation control block.
  552. Return Value:
  553. Notes:
  554. ----------------------------------------------------------------------------*/
  555. {
  556. if ( (pCommand->GetOptimizationFlags() & OPTIMIZE_STUBLESS_CLIENT ) ||
  557. pCommand->GetNdrVersionControl().HasStublessProxies() )
  558. GetNdrVersionControl().SetHasStublessProxies();
  559. if ( (pCommand->GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 ) ||
  560. pCommand->GetNdrVersionControl().HasOi2() )
  561. GetNdrVersionControl().SetHasOi2();
  562. CG_ITERATOR I;
  563. CG_NDR * pCG;
  564. CG_INTERFACE * pIntf;
  565. if( !GetMembers( I ) )
  566. {
  567. return;
  568. }
  569. while( ITERATOR_GETNEXT( I, pCG ) )
  570. {
  571. pIntf = (CG_INTERFACE *)pCG;
  572. switch(pCG->GetCGID())
  573. {
  574. case ID_CG_INTERFACE:
  575. case ID_CG_INHERITED_OBJECT_INTERFACE:
  576. case ID_CG_OBJECT_INTERFACE:
  577. pIntf->EvaluateVersionControl();
  578. if ( pIntf->HasStublessProxies() )
  579. GetNdrVersionControl().SetHasStublessProxies();
  580. if ( pIntf->GetNdrVersionControl().HasOi2() )
  581. GetNdrVersionControl().SetHasOi2();
  582. break;
  583. default:
  584. break;
  585. }
  586. }
  587. if ( GetNdrVersionControl().HasStublessProxies() )
  588. pCommand->GetNdrVersionControl().SetHasStublessProxies();
  589. if ( GetNdrVersionControl().HasOi2() )
  590. pCommand->GetNdrVersionControl().SetHasOi2();
  591. }
  592. void
  593. CG_PROXY_FILE::EmitFileHeadingBlock(
  594. CCB * pCCB )
  595. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  596. Routine Description:
  597. Emit block comment file heading.
  598. Arguments:
  599. pCCB - a pointer to the code generation control block.
  600. Return Value:
  601. none.
  602. Notes:
  603. ----------------------------------------------------------------------------*/
  604. {
  605. ISTREAM * pStream = pCCB->GetStream();
  606. pStream->Write( "/* this ALWAYS GENERATED file contains the proxy stub code */" );
  607. pStream->NewLine(2);
  608. EmitStandardHeadingBlock( pCCB );
  609. }
  610. CG_STATUS
  611. CG_PROXY_FILE::GenCode(
  612. CCB * pCCB )
  613. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  614. Routine Description:
  615. Generate a proxy file containing the proxies and stubs for
  616. the [object] interfaces defined in the IDL file.
  617. Arguments:
  618. pCCB - a pointer to the code generation control block.
  619. Return Value:
  620. CG_OK if all is well, error otherwise.
  621. Notes:
  622. ----------------------------------------------------------------------------*/
  623. {
  624. CG_ITERATOR I;
  625. CG_NDR * pCG;
  626. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  627. char Drive[ _MAX_DRIVE ];
  628. char Path[ _MAX_DIR ];
  629. char Name[ _MAX_FNAME ];
  630. char Ext[ _MAX_EXT ];
  631. unsigned long index = 0;
  632. if( !GetMembers( I ) )
  633. {
  634. return CG_OK;
  635. }
  636. ISTREAM Stream( GetFileName(), 4 );
  637. ISTREAM * pStream = &Stream;
  638. pCCB->SetStream(pStream);
  639. // Set HasStublessProxies and HasOi2 for each interface.
  640. EvaluateVersionControl();
  641. EmitFileHeadingBlock( pCCB );
  642. //
  643. // Check if midl was invoked with -O1. This means we can create
  644. // binaries using stubless proxies (if also compiled -Oi). These
  645. // proxies will not work on 807.
  646. //
  647. if ( GetNdrVersionControl().HasStublessProxies() )
  648. {
  649. pStream->NewLine();
  650. pStream->Write( "#define USE_STUBLESS_PROXY" );
  651. pStream->NewLine();
  652. }
  653. //
  654. // Emit the hash includes.
  655. //
  656. Out_IncludeOfFile( pCCB, "rpcproxy.h", FALSE );
  657. _splitpath( GetHeaderFileName(), Drive, Path, Name, Ext );
  658. strcpy( Buffer, Name );
  659. strcat( Buffer, Ext );
  660. Out_IncludeOfFile( pCCB, Buffer, FALSE );
  661. EmitFormatStringTypedefs( pCCB );
  662. //
  663. // Emit the external variables needed.
  664. //
  665. pStream->NewLine();
  666. //
  667. // Emit the format string extern declarations.
  668. //
  669. Out_TypeFormatStringExtern( pCCB );
  670. Out_ProcFormatStringExtern( pCCB );
  671. Out_LocalTypeFormatStringExtern( pCCB );
  672. Out_LocalProcFormatStringExtern( pCCB );
  673. pCCB->ClearOptionalExternFlags();
  674. pStream->NewLine();
  675. pCCB->SetFileCG(this);
  676. //
  677. // Create a new format string object if it does not yet exist.
  678. //
  679. if ( !GetFormatString() )
  680. {
  681. SetFormatString(new FORMAT_STRING());
  682. SetLocalFormatString(new FORMAT_STRING());
  683. }
  684. pCCB->SetFormatString( GetFormatString() );
  685. if ( !GetProcFormatString() )
  686. {
  687. SetProcFormatString(new FORMAT_STRING());
  688. SetLocalProcFormatString(new FORMAT_STRING());
  689. }
  690. pCCB->SetProcFormatString( GetProcFormatString() );
  691. // make the list of interfaces provided by this proxy file
  692. MakeImplementedInterfacesList( pCCB );
  693. //
  694. // Send the message to the children to emit code.
  695. //
  696. //
  697. // generate code for all [object] interfaces in the IDL file.
  698. //
  699. while( ITERATOR_GETNEXT( I, pCG ) )
  700. {
  701. switch(pCG->GetCGID())
  702. {
  703. case ID_CG_INTERFACE:
  704. ((CG_INTERFACE *)pCG)->OutputInterfaceIdComment( pCCB );
  705. break;
  706. case ID_CG_INHERITED_OBJECT_INTERFACE:
  707. {
  708. CG_INHERITED_OBJECT_INTERFACE * pInhObjCG =
  709. ( CG_INHERITED_OBJECT_INTERFACE * ) pCG;
  710. //
  711. // Generate format string description for all procs.
  712. //
  713. pInhObjCG->OutputInterfaceIdComment( pCCB );
  714. pInhObjCG->GenCode( pCCB );
  715. // make no code or tables for local interfaces
  716. if ( pInhObjCG->IsLocal() && !pCommand->IsHookOleEnabled())
  717. break;
  718. //
  719. // Both of these do nothing right now. 4/25.
  720. //
  721. pInhObjCG->GenInterfaceProxy( pCCB, index );
  722. pInhObjCG->GenInterfaceStub( pCCB, index );
  723. break;
  724. }
  725. case ID_CG_OBJECT_INTERFACE:
  726. {
  727. CG_OBJECT_INTERFACE * pObjCG =
  728. (CG_OBJECT_INTERFACE * ) pCG;
  729. // make no code or tables for local interfaces
  730. pObjCG->OutputInterfaceIdComment( pCCB );
  731. pObjCG->GenCode( pCCB );
  732. if ( pObjCG->IsLocal() && !pCommand->IsHookOleEnabled())
  733. break;
  734. pObjCG->GenInterfaceProxy( pCCB, index );
  735. pObjCG->GenInterfaceStub( pCCB, index );
  736. if (pObjCG->IsLocal())
  737. break;
  738. index++; // index is index in stub/proxy buffer tables
  739. break;
  740. }
  741. default:
  742. break;
  743. }
  744. }
  745. pCCB->SetSkipFormatStreamGeneration( FALSE );
  746. pStream->NewLine();
  747. pStream->Write( "#pragma data_seg(\".rdata\")" );
  748. pStream->NewLine();
  749. EmitFixupToFormatStringTypedefs( pCCB );
  750. pCCB->OutputMultipleInterfaceTables(GetLocalFormatString(), GetLocalProcFormatString());
  751. Out_ProxyFileInfo(pCCB);
  752. UpdateDLLDataFile( pCCB );
  753. return CG_OK;
  754. }
  755. void
  756. CG_COM_METHODS_FILE::EmitFileHeadingBlock(
  757. CCB * pCCB )
  758. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  759. Routine Description:
  760. Emit block comment file heading.
  761. Arguments:
  762. pCCB - a pointer to the code generation control block.
  763. Return Value:
  764. none.
  765. Notes:
  766. ----------------------------------------------------------------------------*/
  767. {
  768. ISTREAM * pStream = pCCB->GetStream();
  769. CheckForHeadingToken( pCCB );
  770. pStream->Write( "/* this USER-ALTERABLE file contains the class methods for COM classes */" );
  771. pStream->NewLine(2);
  772. EmitStandardHeadingBlock( pCCB );
  773. }
  774. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  775. COM_METHODS_FILE overall structure:
  776. << optional user stuff >>
  777. < MIDL header comment, always generated>
  778. //@@MIDL_INCLUDES_LIST()
  779. <headers>
  780. //@@MIDL_INCLUDES_LIST_END()
  781. repeat the below:
  782. | //@@MIDL_CLASS( <class> )
  783. |
  784. | repeat the below:
  785. | | //@@MIDL_CLASS_METHODS( <class::interface> )
  786. | |
  787. | | repeat the below:
  788. | | | //@@MIDL_METHOD( <class::method> )
  789. | | | <function header>
  790. | | | //@@MIDL_METHOD_BODY( <class::method> )
  791. | | |
  792. | //@@MIDL_CLASS_END( class )
  793. |
  794. //@@MIDL_CLASS_METHODS_END()
  795. user changes are preserved outside of :
  796. the file includes block
  797. the function headers
  798. new methods/interfaces/classes have their stuff added at
  799. the end of their block.
  800. deleted methods/interfaces/classes are mentioned in added comments and
  801. ignored.
  802. ----------------------------------------------------------------------------*/
  803. CG_STATUS
  804. CG_COM_METHODS_FILE::GenCode(
  805. CCB * pCCB )
  806. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  807. Routine Description:
  808. Generate a COM server file containing the class factory and class
  809. implementation for the COM classes defined in the IDL file.
  810. Arguments:
  811. pCCB - a pointer to the code generation control block.
  812. Return Value:
  813. CG_OK if all is well, error otherwise.
  814. Notes:
  815. ----------------------------------------------------------------------------*/
  816. {
  817. CG_ITERATOR I;
  818. CG_NDR * pCG;
  819. unsigned long index = 0;
  820. if( !GetMembers( I ) )
  821. {
  822. return CG_OK;
  823. }
  824. RW_ISTREAM Stream( GetFileName(), 4 );
  825. RW_ISTREAM * pStream = &Stream;
  826. pCCB->SetStream(pStream);
  827. if ( Stream.IsTempStream() )
  828. {
  829. pCCB->SetReparsingCurrentFile( TRUE );
  830. }
  831. EmitFileHeadingBlock( pCCB );
  832. //
  833. // Emit the hash includes.
  834. //
  835. OutputIncludes( pCCB );
  836. //
  837. // Emit the external variables needed.
  838. //
  839. pStream->NewLine();
  840. if ( Stream.IsTempStream() )
  841. {
  842. ParseAndGenCode( pCCB, pStream );
  843. }
  844. else
  845. {
  846. //
  847. // generate code for all com classes in the IDL file.
  848. //
  849. while( ITERATOR_GETNEXT( I, pCG ) )
  850. {
  851. switch(pCG->GetCGID())
  852. {
  853. case ID_CG_INHERITED_OBJECT_INTERFACE:
  854. case ID_CG_OBJECT_INTERFACE:
  855. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  856. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  857. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  858. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  859. break;
  860. case ID_CG_COM_CLASS:
  861. {
  862. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  863. pComCG->GenComClassServer( pCCB );
  864. break;
  865. }
  866. default:
  867. break;
  868. }
  869. }
  870. }
  871. // propogate changes from the tmpfile, if any
  872. Stream.UpdateOriginalFile();
  873. pCCB->SetReparsingCurrentFile( FALSE );
  874. return CG_OK;
  875. }
  876. CG_STATUS
  877. CG_COM_METHODS_FILE::ParseAndGenCode(
  878. CCB * pCCB,
  879. RW_ISTREAM * pStream )
  880. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  881. Routine Description:
  882. Generate a COM server file containing the class factory and class
  883. implementation for the COM classes defined in the IDL file.
  884. Arguments:
  885. pCCB - a pointer to the code generation control block.
  886. Return Value:
  887. CG_OK if all is well, error otherwise.
  888. Notes:
  889. ----------------------------------------------------------------------------*/
  890. {
  891. CG_ITERATOR I;
  892. CG_NDR * pCG;
  893. unsigned long index = 0;
  894. if( !GetMembers( I ) )
  895. {
  896. return CG_OK;
  897. }
  898. //
  899. // go through the old file, propogating changes and
  900. // generating code for new things
  901. //
  902. while( ITERATOR_GETNEXT( I, pCG ) )
  903. {
  904. switch(pCG->GetCGID())
  905. {
  906. case ID_CG_INHERITED_OBJECT_INTERFACE:
  907. case ID_CG_OBJECT_INTERFACE:
  908. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  909. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  910. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  911. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  912. break;
  913. case ID_CG_COM_CLASS:
  914. {
  915. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  916. pComCG->ReGenComClassServer( pCCB );
  917. break;
  918. }
  919. default:
  920. break;
  921. }
  922. }
  923. return CG_OK;
  924. }
  925. void
  926. CG_COM_IUNKNOWN_FILE::EmitFileHeadingBlock(
  927. CCB * pCCB )
  928. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  929. Routine Description:
  930. Emit block comment file heading.
  931. Arguments:
  932. pCCB - a pointer to the code generation control block.
  933. Return Value:
  934. none.
  935. Notes:
  936. ----------------------------------------------------------------------------*/
  937. {
  938. ISTREAM * pStream = pCCB->GetStream();
  939. pStream->Write( "/* this ALWAYS GENERATED file contains the implementations of */" );
  940. pStream->NewLine();
  941. pStream->Write( "/* the IUnknowns and the class factories */" );
  942. pStream->NewLine(2);
  943. EmitStandardHeadingBlock( pCCB );
  944. }
  945. CG_STATUS
  946. CG_COM_IUNKNOWN_FILE::GenCode(
  947. CCB * pCCB )
  948. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  949. Routine Description:
  950. Generate a COM server file containing the class factory and class
  951. implementation for the COM classes defined in the IDL file.
  952. Arguments:
  953. pCCB - a pointer to the code generation control block.
  954. Return Value:
  955. CG_OK if all is well, error otherwise.
  956. Notes:
  957. ----------------------------------------------------------------------------*/
  958. {
  959. CG_ITERATOR I;
  960. CG_NDR * pCG;
  961. unsigned long index = 0;
  962. if( !GetMembers( I ) )
  963. {
  964. return CG_OK;
  965. }
  966. ISTREAM Stream( GetFileName(), 4 );
  967. ISTREAM * pStream = &Stream;
  968. pCCB->SetStream(pStream);
  969. EmitFileHeadingBlock( pCCB );
  970. Out_IncludeOfFile( pCCB, "rpcunkcf.h", FALSE );
  971. //
  972. // Emit the hash includes.
  973. //
  974. OutputIncludes( pCCB );
  975. //
  976. // Emit the external variables needed.
  977. //
  978. pStream->NewLine();
  979. //
  980. // generate code for all com classes in the IDL file.
  981. //
  982. while( ITERATOR_GETNEXT( I, pCG ) )
  983. {
  984. switch(pCG->GetCGID())
  985. {
  986. case ID_CG_INHERITED_OBJECT_INTERFACE:
  987. case ID_CG_OBJECT_INTERFACE:
  988. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  989. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  990. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  991. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  992. break;
  993. case ID_CG_COM_CLASS:
  994. {
  995. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  996. pComCG->GenComClassIUnknown( pCCB );
  997. pComCG->GenComClassFactory( pCCB );
  998. break;
  999. }
  1000. default:
  1001. break;
  1002. }
  1003. }
  1004. return CG_OK;
  1005. }
  1006. void
  1007. CG_PROXY_DEF_FILE::EmitFileHeadingBlock(
  1008. CCB * pCCB )
  1009. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1010. Routine Description:
  1011. Emit block comment file heading.
  1012. Arguments:
  1013. pCCB - a pointer to the code generation control block.
  1014. Return Value:
  1015. none.
  1016. Notes:
  1017. ----------------------------------------------------------------------------*/
  1018. {
  1019. ISTREAM * pStream = pCCB->GetStream();
  1020. pStream->Write( "; this GENERATED ONCE file contains the contains the exports for the proxy dll */" );
  1021. pStream->NewLine(2);
  1022. EmitStandardHeadingBlock( pCCB, ";" );
  1023. }
  1024. CG_STATUS
  1025. CG_PROXY_DEF_FILE::GenCode(
  1026. CCB * pCCB )
  1027. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1028. Routine Description:
  1029. Generate a COM server file containing the class factory and class
  1030. implementation for the COM classes defined in the IDL file.
  1031. Arguments:
  1032. pCCB - a pointer to the code generation control block.
  1033. Return Value:
  1034. CG_OK if all is well, error otherwise.
  1035. Notes:
  1036. ----------------------------------------------------------------------------*/
  1037. {
  1038. CG_ITERATOR I;
  1039. CG_NDR * pCG;
  1040. unsigned long index = 0;
  1041. if( !GetMembers( I ) )
  1042. {
  1043. return CG_OK;
  1044. }
  1045. ISTREAM Stream( GetFileName(), 4 );
  1046. ISTREAM * pStream = &Stream;
  1047. pCCB->SetStream(pStream);
  1048. EmitFileHeadingBlock( pCCB );
  1049. //
  1050. // Emit the external variables needed.
  1051. //
  1052. pStream->NewLine();
  1053. //
  1054. // generate code for all com classes in the IDL file.
  1055. //
  1056. while( ITERATOR_GETNEXT( I, pCG ) )
  1057. {
  1058. #if 0
  1059. switch(pCG->GetCGID())
  1060. {
  1061. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1062. case ID_CG_OBJECT_INTERFACE:
  1063. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  1064. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  1065. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  1066. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  1067. break;
  1068. case ID_CG_COM_CLASS:
  1069. {
  1070. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  1071. pComCG->GenComClassIUnknown( pCCB );
  1072. pComCG->GenComClassFactory( pCCB );
  1073. break;
  1074. }
  1075. default:
  1076. break;
  1077. }
  1078. #endif
  1079. }
  1080. return CG_OK;
  1081. }
  1082. void
  1083. CG_DLL_SERVER_DEF_FILE::EmitFileHeadingBlock(
  1084. CCB * pCCB )
  1085. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1086. Routine Description:
  1087. Emit block comment file heading.
  1088. Arguments:
  1089. pCCB - a pointer to the code generation control block.
  1090. Return Value:
  1091. none.
  1092. Notes:
  1093. ----------------------------------------------------------------------------*/
  1094. {
  1095. ISTREAM * pStream = pCCB->GetStream();
  1096. pStream->Write( "; this GENERATED ONCE file contains the contains the implementations of the exports for */" );
  1097. pStream->NewLine();
  1098. pStream->Write( "; the InprocServer32 " );
  1099. pStream->NewLine(2);
  1100. EmitStandardHeadingBlock( pCCB, ";" );
  1101. }
  1102. CG_STATUS
  1103. CG_DLL_SERVER_DEF_FILE::GenCode(
  1104. CCB * pCCB )
  1105. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1106. Routine Description:
  1107. Generate a COM server file containing the class factory and class
  1108. implementation for the COM classes defined in the IDL file.
  1109. Arguments:
  1110. pCCB - a pointer to the code generation control block.
  1111. Return Value:
  1112. CG_OK if all is well, error otherwise.
  1113. Notes:
  1114. ----------------------------------------------------------------------------*/
  1115. {
  1116. CG_ITERATOR I;
  1117. CG_NDR * pCG;
  1118. unsigned long index = 0;
  1119. if( !GetMembers( I ) )
  1120. {
  1121. return CG_OK;
  1122. }
  1123. ISTREAM Stream( GetFileName(), 4 );
  1124. ISTREAM * pStream = &Stream;
  1125. pCCB->SetStream(pStream);
  1126. EmitFileHeadingBlock( pCCB );
  1127. //
  1128. // Emit the external variables needed.
  1129. //
  1130. //
  1131. // generate code for all com classes in the IDL file.
  1132. //
  1133. while( ITERATOR_GETNEXT( I, pCG ) )
  1134. {
  1135. switch(pCG->GetCGID())
  1136. {
  1137. case ID_CG_COM_SERVER_DLL:
  1138. {
  1139. CG_COM_SERVER_DLL * pDllCG = ( CG_COM_SERVER_DLL * ) pCG;
  1140. pDllCG->GenDllDefFile( pCCB );
  1141. break;
  1142. }
  1143. default:
  1144. break;
  1145. }
  1146. }
  1147. return CG_OK;
  1148. }
  1149. void
  1150. CG_DLL_SERVER_FILE::EmitFileHeadingBlock(
  1151. CCB * pCCB )
  1152. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1153. Routine Description:
  1154. Emit block comment file heading.
  1155. Arguments:
  1156. pCCB - a pointer to the code generation control block.
  1157. Return Value:
  1158. none.
  1159. Notes:
  1160. ----------------------------------------------------------------------------*/
  1161. {
  1162. ISTREAM * pStream = pCCB->GetStream();
  1163. pStream->Write( "/* this ALWAYS GENERATED file contains the implementations of */" );
  1164. pStream->NewLine();
  1165. pStream->Write( "/* the IUnknowns and the class factories */" );
  1166. pStream->NewLine(2);
  1167. EmitStandardHeadingBlock( pCCB );
  1168. }
  1169. CG_STATUS
  1170. CG_DLL_SERVER_FILE::GenCode(
  1171. CCB * pCCB )
  1172. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1173. Routine Description:
  1174. Generate a COM server file containing the class factory and class
  1175. implementation for the COM classes defined in the IDL file.
  1176. Arguments:
  1177. pCCB - a pointer to the code generation control block.
  1178. Return Value:
  1179. CG_OK if all is well, error otherwise.
  1180. Notes:
  1181. ----------------------------------------------------------------------------*/
  1182. {
  1183. CG_ITERATOR I;
  1184. CG_NDR * pCG;
  1185. unsigned long index = 0;
  1186. if( !GetMembers( I ) )
  1187. {
  1188. return CG_OK;
  1189. }
  1190. ISTREAM Stream( GetFileName(), 4 );
  1191. ISTREAM * pStream = &Stream;
  1192. pCCB->SetStream(pStream);
  1193. EmitFileHeadingBlock( pCCB );
  1194. //
  1195. // Emit the hash includes.
  1196. //
  1197. Out_IncludeOfFile( pCCB, "rpcunkcf.h", FALSE );
  1198. pStream->NewLine();
  1199. OutputIncludes( pCCB );
  1200. //
  1201. // Emit the external variables needed.
  1202. //
  1203. pStream->NewLine();
  1204. //
  1205. // generate code for all com classes in the IDL file.
  1206. //
  1207. while( ITERATOR_GETNEXT( I, pCG ) )
  1208. {
  1209. switch(pCG->GetCGID())
  1210. {
  1211. case ID_CG_COM_SERVER_DLL:
  1212. case ID_CG_COM_SERVER_EXE:
  1213. {
  1214. pCG->GenCode( pCCB );
  1215. break;
  1216. }
  1217. default:
  1218. break;
  1219. }
  1220. }
  1221. return CG_OK;
  1222. }
  1223. void
  1224. CG_SERVER_REG_FILE::EmitFileHeadingBlock(
  1225. CCB * pCCB )
  1226. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1227. Routine Description:
  1228. Emit block comment file heading.
  1229. Arguments:
  1230. pCCB - a pointer to the code generation control block.
  1231. Return Value:
  1232. none.
  1233. Notes:
  1234. ----------------------------------------------------------------------------*/
  1235. {
  1236. ISTREAM * pStream = pCCB->GetStream();
  1237. static STRING_BLOCK RegHeader =
  1238. {
  1239. "#",
  1240. "# This .reg file is recreated every time a dllserver or exeserver",
  1241. "# is processed by MIDL. User changes are preserved.",
  1242. "#",
  1243. "# the pathnames should be changed if the executables will not be",
  1244. "# in the system directory",
  1245. "#",
  1246. 0
  1247. };
  1248. pStream->Write("REGEDIT");
  1249. pStream->NewLine();
  1250. EmitStandardHeadingBlock( pCCB, "#" );
  1251. pStream->WriteBlock( RegHeader );
  1252. }
  1253. CG_STATUS
  1254. CG_SERVER_REG_FILE::GenCode(
  1255. CCB * pCCB )
  1256. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1257. Routine Description:
  1258. Generate a COM server file containing the class factory and class
  1259. implementation for the COM classes defined in the IDL file.
  1260. Arguments:
  1261. pCCB - a pointer to the code generation control block.
  1262. Return Value:
  1263. CG_OK if all is well, error otherwise.
  1264. Notes:
  1265. ----------------------------------------------------------------------------*/
  1266. {
  1267. CG_ITERATOR I;
  1268. CG_NDR * pCG;
  1269. unsigned long index = 0;
  1270. if( !GetMembers( I ) )
  1271. {
  1272. return CG_OK;
  1273. }
  1274. ISTREAM Stream( GetFileName(), 4 );
  1275. ISTREAM * pStream = &Stream;
  1276. pCCB->SetStream(pStream);
  1277. //
  1278. // Emit the external variables needed.
  1279. //
  1280. EmitFileHeadingBlock( pCCB );
  1281. pStream->NewLine();
  1282. //
  1283. // generate code for all com classes in the IDL file.
  1284. //
  1285. while( ITERATOR_GETNEXT( I, pCG ) )
  1286. {
  1287. #if 0
  1288. switch(pCG->GetCGID())
  1289. {
  1290. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1291. case ID_CG_OBJECT_INTERFACE:
  1292. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  1293. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  1294. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  1295. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  1296. break;
  1297. case ID_CG_COM_CLASS:
  1298. {
  1299. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  1300. pComCG->GenComClassIUnknown( pCCB );
  1301. pComCG->GenComClassFactory( pCCB );
  1302. break;
  1303. }
  1304. default:
  1305. break;
  1306. }
  1307. #endif
  1308. }
  1309. return CG_OK;
  1310. }
  1311. void
  1312. CG_COM_FILE::OutputIncludes(
  1313. CCB * pCCB )
  1314. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1315. Routine Description:
  1316. output an includes file list to the stream.
  1317. Arguments:
  1318. pCCB - a pointer to the code generation control block.
  1319. Return Value:
  1320. none.
  1321. Notes:
  1322. ----------------------------------------------------------------------------*/
  1323. {
  1324. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  1325. char Name[ _MAX_FNAME ];
  1326. char Ext[ _MAX_EXT ];
  1327. ISTREAM * pStream = pCCB->GetStream();
  1328. MIDL_TOKEN DelimiterToken( START_INCLUDES_TOKEN );
  1329. RW_ISTREAM * pOldStream = NULL;
  1330. if ( pCCB->IsReparsingCurrentFile() )
  1331. {
  1332. MIDL_TOKEN FoundToken;
  1333. pOldStream = (RW_ISTREAM *) pStream;
  1334. pOldStream->SaveToNextMidlToken( FoundToken );
  1335. if ( FoundToken.GetTokenType() != START_INCLUDES_TOKEN )
  1336. {
  1337. assert( 0 );
  1338. }
  1339. }
  1340. else
  1341. pStream->NewLine();
  1342. DelimiterToken.EmitToken( pStream );
  1343. pStream->NewLine();
  1344. if ( GetHeaderFileName() )
  1345. {
  1346. _splitpath( GetHeaderFileName(), NULL, NULL, Name, Ext );
  1347. strcpy( Buffer, Name );
  1348. strcat( Buffer, Ext );
  1349. Out_IncludeOfFile( pCCB, Buffer, FALSE );
  1350. }
  1351. else
  1352. {
  1353. // Include the import files.
  1354. OutputImportIncludes( pCCB );
  1355. }
  1356. pStream->NewLine(2);
  1357. DelimiterToken.SetTokenType( END_INCLUDES_TOKEN );
  1358. DelimiterToken.EmitToken( pStream );
  1359. if ( pCCB->IsReparsingCurrentFile() )
  1360. {
  1361. MIDL_TOKEN FoundToken;
  1362. pOldStream->DiscardToNextMidlToken( FoundToken );
  1363. if ( FoundToken.GetTokenType() != END_INCLUDES_TOKEN )
  1364. {
  1365. assert( 0 );
  1366. }
  1367. }
  1368. }
  1369. void
  1370. CG_EXE_SERVER_FILE::EmitFileHeadingBlock(
  1371. CCB * pCCB )
  1372. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1373. Routine Description:
  1374. Emit block comment file heading.
  1375. Arguments:
  1376. pCCB - a pointer to the code generation control block.
  1377. Return Value:
  1378. none.
  1379. Notes:
  1380. ----------------------------------------------------------------------------*/
  1381. {
  1382. ISTREAM * pStream = pCCB->GetStream();
  1383. pStream->Write( "/* this ALWAYS GENERATED file contains support routines for the LocalServer32 */" );
  1384. pStream->NewLine(2);
  1385. EmitStandardHeadingBlock( pCCB );
  1386. }
  1387. CG_STATUS
  1388. CG_EXE_SERVER_FILE::GenCode(
  1389. CCB * pCCB )
  1390. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1391. Routine Description:
  1392. Generate a COM server file containing the class factory and class
  1393. implementation for the COM classes defined in the IDL file.
  1394. Arguments:
  1395. pCCB - a pointer to the code generation control block.
  1396. Return Value:
  1397. CG_OK if all is well, error otherwise.
  1398. Notes:
  1399. ----------------------------------------------------------------------------*/
  1400. {
  1401. CG_ITERATOR I;
  1402. CG_NDR * pCG;
  1403. unsigned long index = 0;
  1404. if( !GetMembers( I ) )
  1405. {
  1406. return CG_OK;
  1407. }
  1408. ISTREAM Stream( GetFileName(), 4 );
  1409. ISTREAM * pStream = &Stream;
  1410. pCCB->SetStream(pStream);
  1411. EmitFileHeadingBlock( pCCB );
  1412. Out_IncludeOfFile( pCCB, "rpcunkcf.h", FALSE );
  1413. //
  1414. // Emit the hash includes.
  1415. //
  1416. OutputIncludes( pCCB );
  1417. //
  1418. // Emit the external variables needed.
  1419. //
  1420. pStream->NewLine();
  1421. //
  1422. // generate code for all com classes in the IDL file.
  1423. //
  1424. while( ITERATOR_GETNEXT( I, pCG ) )
  1425. {
  1426. switch(pCG->GetCGID())
  1427. {
  1428. case ID_CG_COM_SERVER_DLL:
  1429. case ID_CG_COM_SERVER_EXE:
  1430. {
  1431. pCG->GenCode( pCCB );
  1432. break;
  1433. }
  1434. default:
  1435. break;
  1436. }
  1437. }
  1438. return CG_OK;
  1439. }
  1440. void
  1441. CG_EXE_SERVER_MAIN_FILE::EmitFileHeadingBlock(
  1442. CCB * pCCB )
  1443. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1444. Routine Description:
  1445. Emit block comment file heading.
  1446. Arguments:
  1447. pCCB - a pointer to the code generation control block.
  1448. Return Value:
  1449. none.
  1450. Notes:
  1451. ----------------------------------------------------------------------------*/
  1452. {
  1453. ISTREAM * pStream = pCCB->GetStream();
  1454. pStream->Write( "/* this GENERATED ONCE file contains support routines for the LocalServer32 */" );
  1455. pStream->NewLine(2);
  1456. EmitStandardHeadingBlock( pCCB );
  1457. }
  1458. CG_STATUS
  1459. CG_EXE_SERVER_MAIN_FILE::GenCode(
  1460. CCB * pCCB )
  1461. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1462. Routine Description:
  1463. Generate a COM server file containing the class factory and class
  1464. implementation for the COM classes defined in the IDL file.
  1465. Arguments:
  1466. pCCB - a pointer to the code generation control block.
  1467. Return Value:
  1468. CG_OK if all is well, error otherwise.
  1469. Notes:
  1470. ----------------------------------------------------------------------------*/
  1471. {
  1472. CG_ITERATOR I;
  1473. CG_NDR * pCG;
  1474. unsigned long index = 0;
  1475. if( !GetMembers( I ) )
  1476. {
  1477. return CG_OK;
  1478. }
  1479. ISTREAM Stream( GetFileName(), 4 );
  1480. ISTREAM * pStream = &Stream;
  1481. pCCB->SetStream(pStream);
  1482. EmitFileHeadingBlock( pCCB );
  1483. Out_IncludeOfFile( pCCB, "rpcunkcf.h", FALSE );
  1484. //
  1485. // Emit the hash includes.
  1486. //
  1487. OutputIncludes( pCCB );
  1488. //
  1489. // Emit the external variables needed.
  1490. //
  1491. pStream->NewLine();
  1492. //
  1493. // generate code for all com classes in the IDL file.
  1494. //
  1495. while( ITERATOR_GETNEXT( I, pCG ) )
  1496. {
  1497. #if 0
  1498. switch(pCG->GetCGID())
  1499. {
  1500. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1501. case ID_CG_OBJECT_INTERFACE:
  1502. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsIUnknown() )
  1503. pCCB->SetIUnknownCG( (CG_IUNKNOWN_OBJECT_INTERFACE *) pCG );
  1504. else if ( !strcmp( pCG->GetSymName(), "IClassFactory" ) )
  1505. pCCB->SetIClassfCG( (CG_OBJECT_INTERFACE *) pCG );
  1506. break;
  1507. case ID_CG_COM_CLASS:
  1508. {
  1509. CG_COM_CLASS * pComCG = ( CG_COM_CLASS * ) pCG;
  1510. pComCG->GenComClassIUnknown( pCCB );
  1511. pComCG->GenComClassFactory( pCCB );
  1512. break;
  1513. }
  1514. default:
  1515. break;
  1516. }
  1517. #endif
  1518. }
  1519. return CG_OK;
  1520. }
  1521. void
  1522. CG_TEST_CLIENT_FILE::EmitFileHeadingBlock(
  1523. CCB * pCCB )
  1524. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1525. Routine Description:
  1526. Emit block comment file heading.
  1527. Arguments:
  1528. pCCB - a pointer to the code generation control block.
  1529. Return Value:
  1530. none.
  1531. Notes:
  1532. ----------------------------------------------------------------------------*/
  1533. {
  1534. ISTREAM * pStream = pCCB->GetStream();
  1535. pStream->Write( "/* this GENERATED ONCE file contains the example test client for the interfaces in the COM class */" );
  1536. pStream->NewLine(2);
  1537. EmitStandardHeadingBlock( pCCB );
  1538. }
  1539. CG_STATUS
  1540. CG_TEST_CLIENT_FILE::GenCode(
  1541. CCB * pCCB )
  1542. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1543. Routine Description:
  1544. Generate a COM test client file to create a COM object, and invoke all
  1545. the methods of the COM classes defined in the IDL file.
  1546. Arguments:
  1547. pCCB - a pointer to the code generation control block.
  1548. Return Value:
  1549. CG_OK if all is well, error otherwise.
  1550. Notes:
  1551. ----------------------------------------------------------------------------*/
  1552. {
  1553. #if 0
  1554. ITERATOR I;
  1555. CG_NDR * pCG;
  1556. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  1557. char Drive[ _MAX_DRIVE ];
  1558. char Path[ _MAX_DIR ];
  1559. char Name[ _MAX_FNAME ];
  1560. char Ext[ _MAX_EXT ];
  1561. ITERATOR ProcList;
  1562. ISTREAM * pStream;
  1563. unsigned long index = 0;
  1564. if( !GetMembers( I ) )
  1565. {
  1566. return CG_OK;
  1567. }
  1568. pStream = new ISTREAM( (char *) GetFileName(), 4 );
  1569. pCCB->SetStream(pStream);
  1570. EmitFileHeadingBlock( pCCB );
  1571. //
  1572. // Emit the hash includes.
  1573. //
  1574. Out_IncludeOfFile( pCCB, "rpcproxy.h", FALSE );
  1575. _splitpath( GetHeaderFileName(), Drive, Path, Name, Ext );
  1576. strcpy( Buffer, Name );
  1577. strcat( Buffer, Ext );
  1578. Out_IncludeOfFile( pCCB, Buffer, FALSE );
  1579. EmitFormatStringTypedefs( pCCB );
  1580. //
  1581. // Emit the external variables needed.
  1582. //
  1583. pStream->NewLine();
  1584. //
  1585. // Emit the format string extern declarations.
  1586. //
  1587. Out_TypeFormatStringExtern( pCCB );
  1588. Out_ProcFormatStringExtern( pCCB );
  1589. Out_LocalTypeFormatStringExtern( pCCB );
  1590. Out_LocalProcFormatStringExtern( pCCB );
  1591. pCCB->ClearOptionalExternFlags();
  1592. pStream->NewLine();
  1593. pCCB->SetFileCG(this);
  1594. //
  1595. // Create a new format string object if it does not yet exist.
  1596. //
  1597. if ( !GetFormatString() )
  1598. {
  1599. SetFormatString(new FORMAT_STRING());
  1600. SetLocalFormatString(new FORMAT_STRING());
  1601. }
  1602. pCCB->SetFormatString( GetFormatString() );
  1603. if ( !GetProcFormatString() )
  1604. {
  1605. SetProcFormatString(new FORMAT_STRING());
  1606. SetLocalProcFormatString(new FORMAT_STRING());
  1607. }
  1608. pCCB->SetProcFormatString( GetProcFormatString() );
  1609. //
  1610. // Send the message to the children to emit code.
  1611. //
  1612. //
  1613. // generate code for all [object] interfaces in the IDL file.
  1614. //
  1615. while( ITERATOR_GETNEXT( I, pCG ) )
  1616. {
  1617. switch(pCG->GetCGID())
  1618. {
  1619. case ID_CG_INTERFACE:
  1620. break;
  1621. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1622. //
  1623. // Generate format string description for all procs.
  1624. //
  1625. ((CG_INHERITED_OBJECT_INTERFACE *)pCG)->GenCode( pCCB );
  1626. // make no code or tables for local interfaces
  1627. if ( ((CG_INHERITED_OBJECT_INTERFACE*)pCG)->IsLocal() )
  1628. break;
  1629. //
  1630. // Both of these do nothing right now. 4/25.
  1631. //
  1632. ((CG_INHERITED_OBJECT_INTERFACE *)pCG)->
  1633. GenInterfaceProxy( pCCB, index );
  1634. ((CG_INHERITED_OBJECT_INTERFACE *)pCG)->
  1635. GenInterfaceStub( pCCB, index );
  1636. break;
  1637. case ID_CG_OBJECT_INTERFACE:
  1638. // make no code or tables for local interfaces
  1639. ((CG_OBJECT_INTERFACE *)pCG)->GenCode( pCCB );
  1640. if ( ((CG_OBJECT_INTERFACE*)pCG)->IsLocal() )
  1641. break;
  1642. ((CG_OBJECT_INTERFACE *)pCG)->GenInterfaceProxy( pCCB, index );
  1643. ((CG_OBJECT_INTERFACE *)pCG)->GenInterfaceStub( pCCB, index );
  1644. index++; // index is index in stub/proxy buffer tables
  1645. break;
  1646. default:
  1647. break;
  1648. }
  1649. }
  1650. EmitFixupToFormatStringTypedefs( pCCB );
  1651. pCCB->SetSkipFormatStreamGeneration( FALSE );
  1652. pCCB->OutputMultipleInterfaceTables();
  1653. Out_ProxyFileInfo(pCCB);
  1654. UpdateDLLDataFile( pCCB );
  1655. #endif // 0
  1656. return CG_OK;
  1657. }
  1658. void
  1659. CG_HDR_FILE::OutputImportIncludes(
  1660. CCB * pCCB)
  1661. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1662. Routine Description:
  1663. Generate the header file.
  1664. Arguments:
  1665. pCCB - The code gen controller block.
  1666. Return Value:
  1667. none.
  1668. Notes:
  1669. ----------------------------------------------------------------------------*/
  1670. {
  1671. ITERATOR * pImpList = GetImportList();
  1672. node_file * pIFile;
  1673. ISTREAM * pStream = pCCB->GetStream();
  1674. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  1675. char Drive[ _MAX_DRIVE ];
  1676. char Path[ _MAX_DIR ];
  1677. char Name[ _MAX_FNAME ];
  1678. char Ext[ _MAX_EXT ];
  1679. if( pImpList && pImpList->NonNull() )
  1680. {
  1681. pStream->NewLine();
  1682. pStream->Write( "/* header files for imported files */" );
  1683. pImpList->Init();
  1684. while( ITERATOR_GETNEXT( (*pImportList), pIFile ) )
  1685. {
  1686. pStream->NewLine();
  1687. // if this was specified with ACF include, print out as is
  1688. if ( pIFile->IsAcfInclude() )
  1689. sprintf( Buffer, "#include \"%s\"", pIFile->GetSymName() );
  1690. else if ( pIFile->HasComClasses() )
  1691. {
  1692. _splitpath( pIFile->GetSymName(), Drive, Path, Name, Ext );
  1693. sprintf( Buffer, "#include \"%s_d.h\"", Name );
  1694. }
  1695. else
  1696. {
  1697. _splitpath( pIFile->GetSymName(), Drive, Path, Name, Ext );
  1698. sprintf( Buffer, "#include \"%s.h\"", Name );
  1699. }
  1700. pStream->Write( Buffer );
  1701. }
  1702. pStream->NewLine();
  1703. }
  1704. }
  1705. void
  1706. CG_HDR_FILE::EmitFileHeadingBlock(
  1707. CCB * pCCB )
  1708. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1709. Routine Description:
  1710. Emit block comment file heading.
  1711. Arguments:
  1712. pCCB - a pointer to the code generation control block.
  1713. Return Value:
  1714. none.
  1715. Notes:
  1716. ----------------------------------------------------------------------------*/
  1717. {
  1718. ISTREAM * pStream = pCCB->GetStream();
  1719. pStream->Write( "/* this ALWAYS GENERATED file contains the definitions for the interfaces */" );
  1720. pStream->NewLine(2);
  1721. EmitStandardHeadingBlock( pCCB );
  1722. }
  1723. void OutputInterfaceForwards(
  1724. ISTREAM * pStream,
  1725. CG_ITERATOR & I )
  1726. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1727. Routine Description:
  1728. Generate the forwards section of the header file.
  1729. Arguments:
  1730. pCCB - The code gen controller block.
  1731. I - an iterator for the nodes to process
  1732. Return Value:
  1733. none.
  1734. Notes:
  1735. ----------------------------------------------------------------------------*/
  1736. {
  1737. CG_INTERFACE * pCG;
  1738. char * pszInterfaceName;
  1739. while( ITERATOR_GETNEXT( I, pCG ) )
  1740. {
  1741. switch(pCG->GetCGID())
  1742. {
  1743. case ID_CG_INTERFACE:
  1744. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1745. break;
  1746. case ID_CG_OBJECT_INTERFACE:
  1747. case ID_CG_DISPINTERFACE:
  1748. pszInterfaceName = pCG->GetType()->GetSymName();
  1749. pStream->NewLine();
  1750. // put out the interface guards
  1751. pStream->Write("\n#ifndef __");
  1752. pStream->Write( pszInterfaceName );
  1753. pStream->Write( "_FWD_DEFINED__\n" );
  1754. pStream->Write( "#define __");
  1755. pStream->Write( pszInterfaceName );
  1756. pStream->Write( "_FWD_DEFINED__\n" );
  1757. // put out the forward definition
  1758. pStream->Write("typedef interface ");
  1759. pStream->Write(pszInterfaceName);
  1760. pStream->Write(' ');
  1761. pStream->Write(pszInterfaceName);
  1762. pStream->Write(';');
  1763. // put out the trailing interface guard
  1764. pStream->Write( "\n#endif \t/* __");
  1765. pStream->Write( pszInterfaceName );
  1766. pStream->Write( "_FWD_DEFINED__ */\n" );
  1767. break;
  1768. case ID_CG_LIBRARY:
  1769. {
  1770. CG_ITERATOR Inner;
  1771. if ( pCG->GetMembers( Inner ) )
  1772. {
  1773. OutputInterfaceForwards( pStream, Inner );
  1774. }
  1775. break;
  1776. }
  1777. default:
  1778. break;
  1779. }
  1780. }
  1781. }
  1782. CG_STATUS
  1783. CG_HDR_FILE::GenCode(
  1784. CCB * pCCB)
  1785. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1786. Routine Description:
  1787. Generate the header file.
  1788. Arguments:
  1789. pCCB - The code gen controller block.
  1790. Return Value:
  1791. CG_OK if all is well.
  1792. Notes:
  1793. ----------------------------------------------------------------------------*/
  1794. {
  1795. ISTREAM Stream( GetFileName(), 4 );
  1796. ISTREAM * pStream = pCCB->SetStream( &Stream );
  1797. CG_ITERATOR I;
  1798. CG_INTERFACE * pCG;
  1799. char * pszInterfaceName;
  1800. BOOL fHasPickle = FALSE;
  1801. BOOL fHasObject = FALSE;
  1802. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  1803. char Drive[ _MAX_DRIVE ];
  1804. char Path[ _MAX_DIR ];
  1805. char Name[ _MAX_FNAME ];
  1806. char Ext[ _MAX_EXT ];
  1807. if( !GetMembers( I ) )
  1808. {
  1809. return CG_OK;
  1810. }
  1811. EmitFileHeadingBlock( pCCB );
  1812. // Include standard files.
  1813. pStream->Write( "#include \"rpc.h\"\n#include \"rpcndr.h\"\n" );
  1814. // If there is at least one pickle interface, emit the include
  1815. // of midles.h
  1816. while( ITERATOR_GETNEXT( I, pCG ) )
  1817. {
  1818. if ( pCG->HasPicklingStuff() )
  1819. {
  1820. fHasPickle = TRUE;
  1821. }
  1822. if ( pCG->IsObject() )
  1823. {
  1824. fHasObject = TRUE;
  1825. }
  1826. }
  1827. if ( fHasPickle )
  1828. {
  1829. pStream->Write( "#include \"midles.h\"\n" );
  1830. }
  1831. if ( fHasObject )
  1832. {
  1833. pStream->Write( "#ifndef COM_NO_WINDOWS_H\n");
  1834. pStream->Write( "#include \"windows.h\"\n#include \"ole2.h\"\n" );
  1835. pStream->Write( "#endif /*COM_NO_WINDOWS_H*/\n");
  1836. }
  1837. // extract the name and the extension to create the ifdefs
  1838. _splitpath( GetFileName(), Drive, Path, Name, Ext );
  1839. // Write out the #ifndefs and #defines
  1840. pStream->NewLine();
  1841. sprintf( Buffer,
  1842. "#ifndef __%s_%s__\n#define __%s_%s__",
  1843. Name,
  1844. &Ext[1], // skip the "." in the extension
  1845. Name,
  1846. &Ext[1] // skip the "." in the extension
  1847. );
  1848. pStream->Write( Buffer );
  1849. // Write out the cplusplus guard.
  1850. pStream->NewLine( 2 );
  1851. pStream->Write( "#ifdef __cplusplus\nextern \"C\"{\n#endif " );
  1852. pStream->NewLine();
  1853. //Generate forward declarations for object interfaces.
  1854. pStream->NewLine();
  1855. pStream->Write("/* Forward Declarations */ ");
  1856. I.Init();
  1857. OutputInterfaceForwards( pStream, I );
  1858. pStream->NewLine();
  1859. // Include the import files.
  1860. OutputImportIncludes( pCCB );
  1861. pStream->NewLine();
  1862. pStream->Write(
  1863. "void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);" );
  1864. pStream->NewLine();
  1865. pStream->Write(
  1866. "void __RPC_USER MIDL_user_free( void __RPC_FAR * ); " );
  1867. pStream->NewLine();
  1868. //
  1869. // For all interfaces in this file, generate code.
  1870. //
  1871. I.Init();
  1872. while( ITERATOR_GETNEXT( I, pCG ) )
  1873. {
  1874. switch(pCG->GetCGID())
  1875. {
  1876. case ID_CG_INTERFACE:
  1877. case ID_CG_OBJECT_INTERFACE:
  1878. case ID_CG_LIBRARY:
  1879. pCG->GenHeader( pCCB );
  1880. case ID_CG_COM_CLASS:
  1881. case ID_CG_INHERITED_OBJECT_INTERFACE:
  1882. default:
  1883. break;
  1884. }
  1885. }
  1886. // put out all the prototypes that are only needed once
  1887. OutputMultipleInterfacePrototypes( pCCB );
  1888. // print out the closing endifs.
  1889. // first the cplusplus stuff.
  1890. pStream->Write( "#ifdef __cplusplus\n}\n#endif\n" );
  1891. // The endif for the file name ifndef
  1892. pStream->NewLine();
  1893. pStream->Write( "#endif" );
  1894. pStream->NewLine();
  1895. pStream->Close();
  1896. return CG_OK;
  1897. }
  1898. void
  1899. CG_HDR_FILE::OutputMultipleInterfacePrototypes(
  1900. CCB * pCCB )
  1901. {
  1902. ITERATOR I;
  1903. ISTREAM * pStream = pCCB->GetStream();
  1904. pStream->NewLine();
  1905. pStream->Write("/* Additional Prototypes for ALL interfaces */");
  1906. pStream->NewLine();
  1907. if( pCCB->GetListOfGenHdlTypes( I ) )
  1908. {
  1909. Out_GenHdlPrototypes( pCCB, I );
  1910. }
  1911. if( pCCB->GetListOfCtxtHdlTypes( I ) )
  1912. {
  1913. Out_CtxtHdlPrototypes( pCCB, I );
  1914. }
  1915. if( pCCB->GetListOfPresentedTypes( I ) )
  1916. {
  1917. Out_TransmitAsPrototypes( pCCB, I );
  1918. }
  1919. if( pCCB->GetListOfRepAsWireTypes( I ) )
  1920. {
  1921. Out_RepAsPrototypes( pCCB, I );
  1922. }
  1923. if( pCCB->GetQuadrupleDictionary()->GetListOfItems( I ) )
  1924. {
  1925. Out_UserMarshalPrototypes( pCCB, I );
  1926. }
  1927. if( pCCB->GetListOfTypeAlignSizeTypes( I ) )
  1928. {
  1929. Out_TypeAlignSizePrototypes( pCCB, I );
  1930. }
  1931. if( pCCB->GetListOfTypeEncodeTypes( I ) )
  1932. {
  1933. Out_TypeEncodePrototypes( pCCB, I );
  1934. }
  1935. if( pCCB->GetListOfTypeDecodeTypes( I ) )
  1936. {
  1937. Out_TypeDecodePrototypes( pCCB, I );
  1938. }
  1939. if( pCCB->GetListOfTypeFreeTypes( I ) )
  1940. {
  1941. Out_TypeFreePrototypes( pCCB, I );
  1942. }
  1943. if ( pCCB->GetListOfCallAsRoutines( I ) )
  1944. {
  1945. Out_CallAsProxyPrototypes( pCCB, I );
  1946. }
  1947. if ( pCCB->GetListOfCallAsRoutines( I ) )
  1948. {
  1949. Out_CallAsServerPrototypes( pCCB, I );
  1950. }
  1951. if( pCCB->GetListOfNotifyRoutines( I ) )
  1952. {
  1953. Out_NotifyPrototypes( pCCB, I, FALSE ); // without flags
  1954. }
  1955. if( pCCB->GetListOfNotifyFlagRoutines( I ) )
  1956. {
  1957. Out_NotifyPrototypes( pCCB, I, TRUE ); // with flags
  1958. }
  1959. pStream->NewLine();
  1960. pStream->Write("/* end of Additional Prototypes */");
  1961. pStream->NewLine( 2 );
  1962. }
  1963. void
  1964. CG_COM_HDR_FILE::EmitFileHeadingBlock(
  1965. CCB * pCCB )
  1966. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1967. Routine Description:
  1968. Emit block comment file heading.
  1969. Arguments:
  1970. pCCB - a pointer to the code generation control block.
  1971. Return Value:
  1972. none.
  1973. Notes:
  1974. ----------------------------------------------------------------------------*/
  1975. {
  1976. ISTREAM * pStream = pCCB->GetStream();
  1977. CheckForHeadingToken( pCCB );
  1978. pStream->Write( "/* this USER-ALTERABLE file contains the definition of COM classes */" );
  1979. pStream->NewLine(2);
  1980. EmitStandardHeadingBlock( pCCB );
  1981. }
  1982. void
  1983. CG_COM_HDR_FILE::EmitIncludesBlock(
  1984. CCB * pCCB)
  1985. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1986. Routine Description:
  1987. Generate the header file includes block.
  1988. Arguments:
  1989. pCCB - The code gen controller block.
  1990. Return Value:
  1991. CG_OK if all is well.
  1992. Notes:
  1993. ----------------------------------------------------------------------------*/
  1994. {
  1995. ISTREAM * pStream = pCCB->GetStream();
  1996. char Buffer[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 1 ];
  1997. char Drive[ _MAX_DRIVE ];
  1998. char Path[ _MAX_DIR ];
  1999. char Name[ _MAX_FNAME ];
  2000. char Ext[ _MAX_EXT ];
  2001. BOOL fReParse = pCCB->IsReparsingCurrentFile();
  2002. MIDL_TOKEN Token( START_INCLUDES_TOKEN );
  2003. if ( fReParse )
  2004. {
  2005. MIDL_TOKEN FoundToken;
  2006. ((RW_ISTREAM *) pStream)->SaveToNextMidlToken( FoundToken );
  2007. if ( FoundToken.GetTokenType() != START_INCLUDES_TOKEN )
  2008. {
  2009. assert(!"expecting includes token" );
  2010. }
  2011. }
  2012. else
  2013. pStream->NewLine();
  2014. pStream->EmitToken( Token );
  2015. pStream->NewLine();
  2016. pStream->Write( "/* the standard includes */" );
  2017. // Include standard files.
  2018. pStream->NewLine();
  2019. pStream->Write( "#include \"rpc.h\"\n#include \"rpcndr.h\"\n#include \"rpcunkcf.h\"\n" );
  2020. pStream->NewLine();
  2021. pStream->Write( "#ifndef COM_NO_WINDOWS_H\n");
  2022. pStream->Write( "#include \"windows.h\"\n#include \"ole2.h\"\n" );
  2023. pStream->Write( "#endif /*COM_NO_WINDOWS_H*/\n");
  2024. // tbd - do the include of the plain header
  2025. // extract the name and the extension to create the ifdefs
  2026. _splitpath( GetFileName(), Drive, Path, Name, Ext );
  2027. // Write out the #ifndefs and #defines
  2028. pStream->NewLine();
  2029. sprintf( Buffer,
  2030. "#ifndef __%s_%s__\n#define __%s_%s__",
  2031. Name,
  2032. &Ext[1], // skip the "." in the extension
  2033. Name,
  2034. &Ext[1] // skip the "." in the extension
  2035. );
  2036. pStream->Write( Buffer );
  2037. if ( GetPlainHdrName() )
  2038. {
  2039. _splitpath( GetPlainHdrName(), Drive, Path, Name, Ext );
  2040. pStream->NewLine(2);
  2041. pStream->Write( "#include \"" );
  2042. pStream->Write( Name );
  2043. if ( Ext[0] )
  2044. {
  2045. pStream->Write( Ext );
  2046. }
  2047. pStream->Write( "\"" );
  2048. pStream->NewLine();
  2049. }
  2050. else
  2051. {
  2052. pStream->NewLine(2);
  2053. // Include the import files.
  2054. OutputImportIncludes( pCCB );
  2055. }
  2056. if ( fReParse )
  2057. {
  2058. MIDL_TOKEN FoundToken;
  2059. ((RW_ISTREAM *) pStream)->DiscardToNextMidlToken( FoundToken );
  2060. if ( FoundToken.GetTokenType() != END_INCLUDES_TOKEN )
  2061. {
  2062. assert(!"expecting includes token" );
  2063. }
  2064. }
  2065. pStream->NewLine();
  2066. Token.SetTokenType( END_INCLUDES_TOKEN );
  2067. pStream->EmitToken( Token );
  2068. pStream->NewLine( ( fReParse ) ? 1 : 2 );
  2069. }
  2070. void
  2071. CG_COM_HDR_FILE::EmitClosingBlock(
  2072. CCB * pCCB)
  2073. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2074. Routine Description:
  2075. Generate the header file includes block.
  2076. Arguments:
  2077. pCCB - The code gen controller block.
  2078. Return Value:
  2079. CG_OK if all is well.
  2080. Notes:
  2081. ----------------------------------------------------------------------------*/
  2082. {
  2083. ISTREAM * pStream = pCCB->GetStream();
  2084. // print out the closing endifs.
  2085. // The endif for the file name ifndef
  2086. pStream->NewLine();
  2087. pStream->Write( "#endif" );
  2088. pStream->NewLine();
  2089. }
  2090. CG_STATUS
  2091. CG_COM_HDR_FILE::GenCode(
  2092. CCB * pCCB)
  2093. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2094. Routine Description:
  2095. Generate the header file.
  2096. Arguments:
  2097. pCCB - The code gen controller block.
  2098. Return Value:
  2099. CG_OK if all is well.
  2100. Notes:
  2101. ----------------------------------------------------------------------------*/
  2102. {
  2103. CG_ITERATOR I;
  2104. CG_INTERFACE * pCG;
  2105. BOOL fHasPlainHeader = FALSE;
  2106. RW_ISTREAM Stream( GetFileName(), 4 );
  2107. RW_ISTREAM * pStream = &Stream;
  2108. pCCB->SetStream(pStream);
  2109. if ( Stream.IsTempStream() )
  2110. {
  2111. pCCB->SetReparsingCurrentFile( TRUE );
  2112. }
  2113. EmitFileHeadingBlock( pCCB );
  2114. EmitIncludesBlock( pCCB );
  2115. //
  2116. // For all com classes in this file, generate code.
  2117. //
  2118. GetMembers( I );
  2119. I.Init();
  2120. while( ITERATOR_GETNEXT( I, pCG ) )
  2121. {
  2122. switch(pCG->GetCGID())
  2123. {
  2124. case ID_CG_COM_CLASS:
  2125. pCG->GenHeader( pCCB );
  2126. case ID_CG_OBJECT_INTERFACE:
  2127. case ID_CG_INTERFACE:
  2128. case ID_CG_INHERITED_OBJECT_INTERFACE:
  2129. default:
  2130. break;
  2131. }
  2132. }
  2133. EmitClosingBlock( pCCB );
  2134. // propogate changes from the tmpfile, if any
  2135. Stream.UpdateOriginalFile();
  2136. pCCB->SetReparsingCurrentFile( FALSE );
  2137. return CG_OK;
  2138. }