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

3615 lines
118 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. ndr64.cxx
  5. Abstract:
  6. Routines for the ndr64 transfer syntax.
  7. Notes:
  8. History:
  9. ----------------------------------------------------------------------------*/
  10. #include "becls.hxx"
  11. char * _SimpleTypeName[] = {
  12. "",
  13. "NDR64_FORMAT_UINT8",
  14. "NDR64_FORMAT_UINT16",
  15. "NDR64_FORMAT_UINT32",
  16. "NDR64_FORMAT_UINT64"
  17. };
  18. // define the name table for the NDR64 format characters
  19. #define NDR64_BEGIN_TABLE \
  20. const char *pNDR64FormatCharNames[] = {
  21. #define NDR64_TABLE_END \
  22. };
  23. #define NDR64_ZERO_ENTRY \
  24. "FC64_ZERO"
  25. #define NDR64_TABLE_ENTRY( number, tokenname, marshal, embeddedmarshall, unmarshall, embeddedunmarshal, buffersize, embeddedbuffersize, memsize, embeddedmemsize, free, embeddedfree, typeflags ) \
  26. , #tokenname
  27. #define NDR64_SIMPLE_TYPE_TABLE_ENTRY( number, tokenname, simpletypebuffersize, simpletypememorysize ) \
  28. , #tokenname
  29. #define NDR64_UNUSED_TABLE_ENTRY( number, tokenname ) \
  30. , #tokenname
  31. #define NDR64_UNUSED_TABLE_ENTRY_NOSYM( number ) \
  32. , NULL
  33. #include "tokntbl.h"
  34. extern const pNDR64FormatCharNamesSize = (sizeof(pNDR64FormatCharNames) / sizeof(*pNDR64FormatCharNames));
  35. C_ASSERT( (sizeof(pNDR64FormatCharNames) / sizeof(*pNDR64FormatCharNames)) == 256 );
  36. #undef NDR64_BEGIN_TABLE
  37. #undef NDR64_TABLE_END
  38. #undef NDR64_ZERO_ENTRY
  39. #undef NDR64_TABLE_ENTRY
  40. #undef NDR64_SIMPLE_TYPE_TABLE_ENTRY
  41. #undef NDR64_UNUSED_TABLE_ENTRY
  42. #undef NDR64_UNUSED_TABLE_ENTRY_NOSYM
  43. FormatFragment * GenExprFormatString(CCB *pCCB,
  44. expr_node *pSizeExpr,
  45. CompositeFormatFragment *FragmentList,
  46. BOOL * IsEarly,
  47. ulong * pExprLength );
  48. //+--------------------------------------------------------------------------
  49. //
  50. // Method: FormatFragment::OutputDescription
  51. //
  52. // Synopsis: Output a description of this fragment
  53. //
  54. // Notes: The output is in the form of a C style comment.
  55. // The decription is the name of the type that this fragment
  56. // represents. If this fragment represents more than on type
  57. // because of optimization then all the types will be output.
  58. //
  59. //---------------------------------------------------------------------------
  60. void FormatFragment::OutputDescription( ISTREAM *stream )
  61. {
  62. FormatFragment *frag = this;
  63. bool first = true;
  64. stream->WriteOnNewLine( "/* " );
  65. do
  66. {
  67. if ( !first )
  68. stream->Write(", ");
  69. CG_CLASS *pClass = frag->GetCGNode();
  70. const char *pName = NULL;
  71. while ( NULL != pClass && pClass->IsPointer() )
  72. {
  73. stream->Write( "*" );
  74. pClass = pClass->GetChild();
  75. }
  76. if ( NULL != pClass && NULL != pClass->GetType() )
  77. {
  78. pName = pClass->GetName();
  79. if ( pName != NULL && pName[0] == '\0' )
  80. pName = NULL;
  81. }
  82. if ( NULL == pName )
  83. pName = frag->GetTypeName();
  84. stream->Write( pName );
  85. frag = frag->pNextOptimized;
  86. first = false;
  87. }
  88. while ( NULL != frag );
  89. stream->Write( " */" );
  90. }
  91. //+--------------------------------------------------------------------------
  92. //
  93. // Method: CompositeFormatFragment::IsEqualTo
  94. //
  95. // Synopsis: Compare two composite fragments
  96. //
  97. // Notes: This method compares two composite fragments. Two composite
  98. // fragments are equal if and only if the elements of the composite
  99. // are equal.
  100. //
  101. //---------------------------------------------------------------------------
  102. bool CompositeFormatFragment::IsEqualTo( FormatFragment *candidate )
  103. {
  104. CompositeFormatFragment *pOther = (CompositeFormatFragment *)candidate;
  105. FormatFragment *pCurrent = pHead;
  106. FormatFragment *pCurrentOther = pOther->pHead;
  107. while ( (pCurrent != NULL) &&
  108. (pCurrentOther != NULL) )
  109. {
  110. const type_info &frag_type = typeid( *pCurrent );
  111. const type_info &other_type = typeid( *pCurrentOther );
  112. if ( frag_type != other_type )
  113. return false;
  114. if ( !pCurrent->IsEqualTo( pCurrentOther ) )
  115. return false;
  116. pCurrent = pCurrent->Next;
  117. pCurrentOther = pCurrentOther->Next;
  118. }
  119. // Both lists must have the same length.
  120. bool bResult = ( NULL == pCurrent ) && ( NULL == pCurrentOther );
  121. return bResult;
  122. }
  123. //+--------------------------------------------------------------------------
  124. //
  125. // Class: CompositeFormatFragment::LookupFragment
  126. //
  127. // Synopsis: Find the fragment corresponding to a class
  128. //
  129. // Parameters: [pClass] -- The class
  130. //
  131. // Returns: NULL if the class has no fragment yet
  132. //
  133. //---------------------------------------------------------------------------
  134. FormatFragment * CompositeFormatFragment::LookupFragment( CG_CLASS *pClass )
  135. {
  136. FormatFragment *frag;
  137. // Generic handles are a special case. They don't actually have any
  138. // representation in the format info.
  139. if ( ID_CG_GENERIC_HDL == pClass->GetCGID() )
  140. pClass = pClass->GetChild();
  141. for ( frag = pHead; NULL != frag; frag = frag->Next )
  142. if ( frag->pClass == pClass )
  143. return frag;
  144. return NULL;
  145. }
  146. //+--------------------------------------------------------------------------
  147. //
  148. // Class: CompositeFormatFragment::AddFragment
  149. //
  150. // Synopsis: Add a fragment to the list if it isn't already present
  151. //
  152. // Parameters: [frag] -- The fragment
  153. //
  154. // Returns: The id of the fragment
  155. //
  156. // Notes: Another way to think of this method is that it provides a
  157. // mapping between CG_CLASS pointers and FormatInfoRef's.
  158. //
  159. //---------------------------------------------------------------------------
  160. FormatInfoRef CompositeFormatFragment::AddFragment( FormatFragment *frag )
  161. {
  162. frag->Next = NULL;
  163. frag->RefID = NextRefID;
  164. frag->Prev = pTail;
  165. frag->Parent = this;
  166. if ( NULL == pTail )
  167. pHead = frag;
  168. else
  169. pTail->Next = frag;
  170. pTail = frag;
  171. NextRefID = (FormatInfoRef) ((size_t) NextRefID + 1);
  172. return frag->RefID;
  173. }
  174. //+--------------------------------------------------------------------------
  175. //
  176. // Class: CompositeFormatFragment::OutputFragmentType
  177. //
  178. // Synopsis: Output a type declaration for this composite
  179. //
  180. // Notes: It looks like:
  181. //
  182. // struct <name>
  183. // {
  184. // <frag1 type>,
  185. // <frag2 type>
  186. // ...
  187. // }
  188. //
  189. //---------------------------------------------------------------------------
  190. void CompositeFormatFragment::OutputFragmentType( CCB *pCCB )
  191. {
  192. ISTREAM *stream = pCCB->GetStream();
  193. stream->WriteOnNewLine("struct ");
  194. stream->Write( GetTypeName() );
  195. stream->WriteOnNewLine("{");
  196. stream->IndentInc();
  197. FormatFragment *pCurrent = pHead;
  198. for ( pCurrent = pHead; NULL != pCurrent; pCurrent = pCurrent->Next )
  199. {
  200. if ( pCurrent->WasOptimizedOut() )
  201. {
  202. // Only top-level stuff should be optimized
  203. MIDL_ASSERT( NULL == GetParent() );
  204. continue;
  205. }
  206. pCurrent->OutputFragmentType( pCCB );
  207. stream->WriteFormat(" frag%d;", (size_t) pCurrent->GetRefID());
  208. }
  209. stream->IndentDec();
  210. stream->WriteOnNewLine("}");
  211. }
  212. //+--------------------------------------------------------------------------
  213. //
  214. // Class: CompositeFormatFragment::OutputFragmentData
  215. //
  216. // Synopsis: Output the initializer data for this composite
  217. //
  218. // Notes: It looks like:
  219. //
  220. // {
  221. // <frag1 data>,
  222. // <frag2 type>
  223. // ...
  224. // }
  225. //
  226. //---------------------------------------------------------------------------
  227. void CompositeFormatFragment::OutputFragmentData( CCB *pCCB )
  228. {
  229. ISTREAM *stream = pCCB->GetStream();
  230. OutputStructDataStart( pCCB );
  231. FormatFragment *pCurrent;
  232. bool FirstFragment = true;
  233. for ( pCurrent = pHead; NULL != pCurrent; pCurrent = pCurrent->Next )
  234. {
  235. if ( pCurrent->WasOptimizedOut() )
  236. {
  237. // Only top-level stuff should be optimized
  238. MIDL_ASSERT( NULL == GetParent() );
  239. continue;
  240. }
  241. if ( !FirstFragment )
  242. stream->Write(",");
  243. FirstFragment = false;
  244. pCurrent->OutputFragmentData( pCCB );
  245. }
  246. OutputStructDataEnd( pCCB );
  247. }
  248. //+--------------------------------------------------------------------------
  249. //
  250. // Class: CompositeFormatFragment::OptimizeFragment
  251. //
  252. // Synopsis: Try to optimize out a fragment in the format string by
  253. // checking to see if it is the same as some other fragment.
  254. //
  255. // Parameters: [frag] -- The fragment to optimize
  256. //
  257. // Returns: The final ID of the fragment
  258. //
  259. // Notes: Optimization can be suppressed by the user by specifiying
  260. // -no_format_opt
  261. //
  262. //---------------------------------------------------------------------------
  263. FormatInfoRef CompositeFormatFragment::OptimizeFragment( FormatFragment *frag )
  264. {
  265. if ( pCommand->IsSwitchDefined( SWITCH_NO_FMT_OPT ) )
  266. return frag->RefID;
  267. // Only stuff in the root composite can be optimized
  268. if ( ! dynamic_cast<RootFormatFragment *>(frag->GetParent()) )
  269. return frag->RefID;
  270. FormatFragment *candidate;
  271. for ( candidate = pHead;
  272. NULL != candidate && candidate != frag;
  273. candidate = candidate->Next )
  274. {
  275. const type_info &frag_type = typeid( *frag );
  276. const type_info &candidate_type = typeid( *candidate );
  277. if ( frag_type != candidate_type )
  278. continue;
  279. if ( candidate->IsEqualTo( frag ) )
  280. {
  281. frag->RefID = candidate->RefID;
  282. while ( NULL != candidate->pNextOptimized )
  283. candidate = candidate->pNextOptimized;
  284. candidate->pNextOptimized = frag;
  285. frag->pPrevOptimized = candidate;
  286. break;
  287. }
  288. }
  289. return frag->RefID;
  290. }
  291. //+--------------------------------------------------------------------------
  292. //
  293. // Method: RootFormatFragement::Output
  294. //
  295. // Synopsis: Output a the whole ndr64 format structure
  296. //
  297. //---------------------------------------------------------------------------
  298. void RootFormatFragment::Output( CCB *pCCB )
  299. {
  300. ISTREAM *stream = pCCB->GetStream();
  301. stream->NewLine();
  302. // REVIEW: Is this the right place to output these?
  303. stream->WriteOnNewLine("#include \"ndr64types.h\"");
  304. stream->WriteOnNewLine("#include \"pshpack8.h\"");
  305. stream->NewLine();
  306. FormatFragment *pCurrent;
  307. for ( pCurrent = pTail; NULL != pCurrent; pCurrent = pCurrent->Prev )
  308. {
  309. if ( pCurrent->WasOptimizedOut() )
  310. continue;
  311. stream->NewLine();
  312. stream->WriteOnNewLine("typedef ");
  313. pCurrent->OutputFragmentType( pCCB );
  314. stream->NewLine();
  315. stream->WriteFormat("__midl_frag%d_t;", pCurrent->GetRefID() );
  316. stream->NewLine();
  317. stream->WriteFormat(
  318. "extern const __midl_frag%d_t __midl_frag%d;",
  319. pCurrent->GetRefID(),
  320. pCurrent->GetRefID() );
  321. }
  322. for ( pCurrent = pTail; NULL != pCurrent; pCurrent = pCurrent->Prev )
  323. {
  324. if ( pCurrent->WasOptimizedOut() )
  325. continue;
  326. stream->NewLine( 2 );
  327. stream->WriteFormat(
  328. "static const __midl_frag%d_t __midl_frag%d =",
  329. pCurrent->GetRefID(),
  330. pCurrent->GetRefID() );
  331. pCurrent->OutputFragmentData( pCCB );
  332. stream->Write(";");
  333. }
  334. stream->NewLine( 2 );
  335. stream->WriteOnNewLine("#include \"poppack.h\"");
  336. stream->NewLine( 2 );
  337. }
  338. //+--------------------------------------------------------------------------
  339. //
  340. // Method: GenNdr64Format::CreateInstance (static)
  341. //
  342. // Synopsis: Class factory for GenNdr64Format
  343. //
  344. //---------------------------------------------------------------------------
  345. GenNdr64Format * GenNdr64Format::CreateInstance( CCB *pCCB )
  346. {
  347. MIDL_ASSERT( pCommand->IsNDR64Run() );
  348. CG_VISITOR_TEMPLATE<GenNdr64Format> *pVisitor = new CG_VISITOR_TEMPLATE<GenNdr64Format>;
  349. GenNdr64Format *generator = pVisitor;
  350. generator->pCCB = pCCB;
  351. generator->pRoot = new RootFormatFragment;
  352. generator->pCurrent = generator->pRoot;
  353. generator->pVisitor = pVisitor;
  354. // add a dummy entry at the beginning of format string to prevent
  355. // an emptry structure being generated when there is only [local]
  356. // interface in an .idl file.
  357. MIDL_NDR_FORMAT_UINT32 * pDummy = new MIDL_NDR_FORMAT_UINT32;
  358. pDummy->Data = 0;
  359. generator->pRoot->AddFragment( pDummy );
  360. return generator;
  361. }
  362. //+--------------------------------------------------------------------------
  363. //
  364. // Method: GenNdr64Format::ContinueGeneration
  365. //
  366. // Synopsis: Do generation for a sub-tree. This is typically called
  367. // by a parent node to generate it's children so that it can
  368. // get offsets to the child format string indices, etc.
  369. //
  370. // Parameters: pClass -- The subtree to generate from
  371. // pCompositeFragment -- The composite to generate into
  372. //
  373. //---------------------------------------------------------------------------
  374. FormatInfoRef GenNdr64Format::ContinueGeneration(
  375. CG_CLASS *pClass,
  376. CompositeFormatFragment *pComposite )
  377. {
  378. CompositeFormatFragment *pOldCurrent = pCurrent;
  379. // Some CG classes don't have children. Those classes should not be
  380. // calling ContinueGeneration on thier non-existant children.
  381. MIDL_ASSERT( NULL != pClass );
  382. // Do this here to save from every visit function from doing it.
  383. FormatFragment* pFrag = pComposite->LookupFragment( pClass );
  384. if ( NULL != pFrag )
  385. return pFrag->GetRefID();
  386. if ( NULL != pComposite )
  387. pCurrent = pComposite;
  388. pClass->Visit( pVisitor );
  389. FormatInfoRef NewFragmentID = pCurrent->LookupFragmentID( pClass );
  390. pCurrent = pOldCurrent;
  391. return NewFragmentID;
  392. }
  393. //+--------------------------------------------------------------------------
  394. //
  395. // Method: GenNdr64Format::Generate
  396. //
  397. // Synopsis: External routine called to generate the string for a type.
  398. //
  399. // Parameters: pClass -- Type to generate string for.
  400. //
  401. //---------------------------------------------------------------------------
  402. FormatInfoRef GenNdr64Format::Generate( CG_CLASS *pClass )
  403. {
  404. return ContinueGeneration( pClass, GetRoot() );
  405. }
  406. //+--------------------------------------------------------------------------
  407. //
  408. // Method: GenNdr64Format::Output
  409. //
  410. // Synopsis: External routine called to output the string.
  411. //
  412. // Parameters: None
  413. //
  414. //---------------------------------------------------------------------------
  415. void GenNdr64Format::Output( )
  416. {
  417. GetRoot()->Output( pCCB );
  418. }
  419. //+--------------------------------------------------------------------------
  420. //
  421. // Method: GenNdr64Format::ContinueGenerationInRoot
  422. //
  423. // Synopsis: Same as ContinueGeneration except switches to root.
  424. //
  425. // Parameters: pClass -- The subtree to generate from
  426. //
  427. //---------------------------------------------------------------------------
  428. inline FormatInfoRef GenNdr64Format::ContinueGenerationInRoot( CG_CLASS *pClass )
  429. {
  430. return ContinueGeneration( pClass, GetRoot() );
  431. }
  432. //+--------------------------------------------------------------------------
  433. //
  434. // Method: GenNdr64Format::Visit( CG_CLASS )
  435. //
  436. // Synopsis: Default visitor that handles things that don't need any
  437. // handling.
  438. //
  439. //---------------------------------------------------------------------------
  440. void GenNdr64Format::Visit( CG_CLASS *pClass )
  441. {
  442. // Should only be called for these classes or drived ones
  443. /*
  444. assert(
  445. NULL != dynamic_cast<CG_AUX *>(pClass)
  446. );
  447. */
  448. CG_ITERATOR Iterator;
  449. CG_CLASS *pChild;
  450. pClass->GetMembers( Iterator );
  451. while ( ITERATOR_GETNEXT( Iterator, pChild ) )
  452. ContinueGenerationInRoot( pChild );
  453. }
  454. //+--------------------------------------------------------------------------
  455. //
  456. // Method: GenNdr64Format::Visit( CG_BASETYPE )
  457. //
  458. // Synopsis: Generate info for base types and ranges
  459. //
  460. // Notes: FC64_BYTE, FC64_CHAR, FC64_WCHAR, FC64_SMALL, FC64_USMALL,
  461. // FC64_SHORT, FC64_USHORT, FC64_LONG, FC64_ULONG, FC64_HYPER, FC64_UHYPER,
  462. // FC64_INT3264, FC64_UINT3264, FC64_FLOAT, FC64_DOUBLE,
  463. // FC64_ERROR_STATUS_T
  464. //
  465. // (also, pending support elsewhere)
  466. //
  467. // FC64_INT128, FC64_UINT128, FC64_FLOAT128, FC64_FLOAT80
  468. //
  469. //---------------------------------------------------------------------------
  470. void GenNdr64Format::Visit( CG_BASETYPE *pClass )
  471. {
  472. if ( pClass->GetRangeAttribute() )
  473. {
  474. GenRangeFormat( pClass );
  475. return;
  476. }
  477. MIDL_NDR64_FORMAT_CHAR *frag = new MIDL_NDR64_FORMAT_CHAR( pClass );
  478. GetCurrent()->AddFragment( frag );
  479. GetRoot()->OptimizeFragment( frag );
  480. }
  481. //+--------------------------------------------------------------------------
  482. //
  483. // Method: GenNdr64Format::GenRangeFormat
  484. //
  485. // Synopsis: Ranges are a special case of base types so we can't
  486. // distinguish between them polymorphically. The base type
  487. // visitor method calls this if we have a range.
  488. //
  489. //---------------------------------------------------------------------------
  490. void GenNdr64Format::GenRangeFormat( CG_BASETYPE *pRangeCG )
  491. {
  492. MIDL_NDR64_RANGE_FORMAT *format;
  493. node_range_attr *range;
  494. format = new MIDL_NDR64_RANGE_FORMAT( pRangeCG );
  495. range = pRangeCG->GetRangeAttribute();
  496. MIDL_ASSERT( NULL != range );
  497. format->FormatCode = FC64_RANGE;
  498. format->RangeType = (NDR64_FORMAT_CHAR)pRangeCG->GetNDR64FormatChar();
  499. format->Reserved = 0;
  500. format->MinValue = range->GetMinExpr()->GetValue();
  501. format->MaxValue = range->GetMaxExpr()->GetValue();
  502. GetCurrent()->AddFragment( format );
  503. }
  504. //+--------------------------------------------------------------------------
  505. //
  506. // Method: GenNdr64Format::Visit( CG_ENCAPSULATED_STRUCT )
  507. //
  508. // Synopsis: Despite the name, this is for generating info for
  509. // encapsulated unions
  510. //
  511. //---------------------------------------------------------------------------
  512. void GenNdr64Format::Visit( CG_ENCAPSULATED_STRUCT *pEncapUnion )
  513. {
  514. // A union is represented in the format info by a composite containing
  515. // the union header follow by fragments representing the arm selector
  516. CompositeFormatFragment *composite = new CompositeFormatFragment( pEncapUnion );
  517. GetCurrent()->AddFragment( composite );
  518. MIDL_NDR64_ENCAPSULATED_UNION *format;
  519. format = new MIDL_NDR64_ENCAPSULATED_UNION( pEncapUnion );
  520. composite->AddFragment( format );
  521. CG_FIELD *pSwitchField = (CG_FIELD *) pEncapUnion->GetChild();
  522. CG_BASETYPE *pSwitch = (CG_BASETYPE *) pSwitchField->GetChild();
  523. CG_FIELD *pUnionField = (CG_FIELD *) pSwitchField->GetSibling();
  524. CG_UNION *pUnion = (CG_UNION *) pUnionField->GetChild();
  525. MIDL_ASSERT( NULL != dynamic_cast<CG_BASETYPE *>(pSwitch) );
  526. MIDL_ASSERT( NULL != pUnion && NULL != dynamic_cast<CG_UNION *>(pUnion) );
  527. format->FormatCode = FC64_ENCAPSULATED_UNION;
  528. format->Alignment = ConvertAlignment( pEncapUnion->GetWireAlignment() );
  529. format->Flags = 0;
  530. format->SwitchType = (NDR64_FORMAT_CHAR)pSwitch->GetNDR64SignedFormatChar();
  531. format->MemoryOffset = pUnionField->GetMemOffset()
  532. - pSwitchField->GetMemOffset();
  533. format->MemorySize = pEncapUnion->GetMemorySize();
  534. format->Reserved = 0;
  535. GenerateUnionArmSelector( pUnion, composite );
  536. }
  537. //+--------------------------------------------------------------------------
  538. //
  539. // Method: GenNdr64Format::GenerateUnionArmSelector
  540. //
  541. // Synopsis: Generate info about union arms
  542. //
  543. //---------------------------------------------------------------------------
  544. void GenNdr64Format::GenerateUnionArmSelector(
  545. CG_UNION *pUnion,
  546. CompositeFormatFragment *FragmentList )
  547. {
  548. MIDL_NDR64_UNION_ARM_SELECTOR *header;
  549. header = new MIDL_NDR64_UNION_ARM_SELECTOR;
  550. header->Reserved1 = 0;
  551. header->Alignment = ConvertAlignment( pUnion->GetWireAlignment() );
  552. header->Reserved2 = 0;
  553. header->Arms = (NDR64_UINT32) pUnion->GetNumberOfArms();
  554. FragmentList->AddFragment( header );
  555. // Generate the non-default arms
  556. CG_ITERATOR Iterator;
  557. CG_CASE *pCase;
  558. CG_CASE *pDefaultCase = NULL;
  559. NDR64_UINT16 ArmCount = 0;
  560. pUnion->GetMembers( Iterator );
  561. while ( ITERATOR_GETNEXT( Iterator, pCase ) )
  562. {
  563. // The default case is always put at the end
  564. if ( ID_CG_DEFAULT_CASE == pCase->GetCGID() )
  565. {
  566. pDefaultCase = pCase;
  567. continue;
  568. }
  569. MIDL_NDR64_UNION_ARM *arm = new MIDL_NDR64_UNION_ARM;
  570. MIDL_ASSERT( NULL != pCase->GetExpr() );
  571. arm->CaseValue = pCase->GetExpr()->GetValue();
  572. // it's legal to have a case with no type
  573. if ( NULL == pCase->GetChild() || NULL == pCase->GetChild()->GetChild() )
  574. arm->Type = 0;
  575. else
  576. arm->Type = ContinueGenerationInRoot(
  577. pCase->GetChild()->GetChild() );
  578. arm->Reserved = 0;
  579. FragmentList->AddFragment( arm );
  580. ++ArmCount;
  581. }
  582. MIDL_ASSERT( ArmCount == header->Arms );
  583. // Generate the default
  584. PNDR64_FORMAT Type;
  585. if ( NULL == pDefaultCase )
  586. Type = (PNDR64_FORMAT) -1;
  587. else
  588. {
  589. CG_CLASS *pType = pDefaultCase->GetChild();
  590. if ( NULL != pType )
  591. pType = pType->GetChild();
  592. if ( NULL == pType )
  593. Type = 0;
  594. else
  595. Type = ContinueGenerationInRoot( pType );
  596. }
  597. FragmentList->AddFragment( new MIDL_NDR64_DEFAULT_CASE( Type ) );
  598. }
  599. //+--------------------------------------------------------------------------
  600. //
  601. // Method: GenNdr64Format::Visit( CG_INTERFACE )
  602. //
  603. // Synopsis: Generate info for interfaces
  604. //
  605. //---------------------------------------------------------------------------
  606. void GenNdr64Format::Visit( CG_INTERFACE *pInterface )
  607. {
  608. CG_ITERATOR I;
  609. CCB *pCCB = GetCCB();
  610. CG_PROC *pProc;
  611. pInterface->InitializeCCB( pCCB );
  612. pCCB->SetImplicitHandleIDNode( 0 );
  613. if( pInterface->GetMembers( I ) )
  614. while ( ITERATOR_GETNEXT( I, pProc ) )
  615. ContinueGenerationInRoot( pProc );
  616. }
  617. //+--------------------------------------------------------------------------
  618. //
  619. // Method: GenNdr64Format::Visit( CG_PARAM )
  620. //
  621. // Synopsis: Generate info for parameters
  622. //
  623. //---------------------------------------------------------------------------
  624. void GenNdr64Format::Visit( CG_PARAM *pParam )
  625. {
  626. if ( GetCurrent()->HasClassFragment( pParam ) )
  627. return;
  628. NDR64_PARAM_FLAGS Attributes;
  629. CG_NDR *pChild;
  630. CG_NDR *pOldPlaceholder;
  631. pChild = (CG_NDR *) pParam->GetChild();
  632. if ( pChild->GetCGID() == ID_CG_GENERIC_HDL )
  633. pChild = (CG_NDR *) pChild->GetChild();
  634. // Ignore the following type of arguments that don't go on wire:
  635. // - async handles
  636. // - primitive handles
  637. //
  638. if ( pChild->GetCGID() == ID_CG_PRIMITIVE_HDL || ( (CG_PARAM*) pParam)->IsAsyncHandleParam() )
  639. return;
  640. pOldPlaceholder = pCCB->SetLastPlaceholderClass( pParam );
  641. // Get the parameter attributes. The 32-bit PARAM_ATTRIBUTES structure
  642. // is essentially the same as the NDR64_PARAM_FLAGS structure except
  643. // the 64-bit structure has a single bit (UseCache) for the old
  644. // ServerAllocSize field
  645. PARAM_ATTRIBUTES *pattr = (PARAM_ATTRIBUTES *) &Attributes;
  646. pChild->GetNdrParamAttributes( pCCB, pattr );
  647. Attributes.UseCache = (NDR64_UINT16) ((pattr->ServerAllocSize) ? 1 : 0);
  648. Attributes.Reserved = 0;
  649. // For reasons not understood, GenNdrParamAttributes marks basetypes as
  650. // not by value even if they are (unless they are ranges). Fix the
  651. // insanity.
  652. if ( pChild->IsSimpleType() )
  653. Attributes.IsByValue = 1;
  654. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  655. // Get the fragment of the pointee.
  656. FormatFragment *pChildFragment;
  657. pChildFragment = GetCurrent()->GetParent()->LookupFragment( pChild );
  658. MIDL_ASSERT( NULL != pChildFragment );
  659. // Fill in the parameter information
  660. MIDL_NDR64_PARAM_FORMAT *format;
  661. format = new MIDL_NDR64_PARAM_FORMAT( pParam );
  662. format->Attributes = Attributes;
  663. format->Reserved = 0;
  664. pParam->GetStackOffsets( pCCB, &format->StackOffset );
  665. // REVIEW: The reason why we have to test base types seperately is
  666. // because of the inconsistent way things are stored. Consider
  667. // a string pointer. It's format info is a simple ref to an
  668. // string array - this can be intrepreted as a pointer to a block
  669. // of memory. However, it's CG representation is just a pointer.
  670. // The missing level of dereference causes the problem. In
  671. // constrast a pointer to a single long is represented as a ref
  672. // pointer to a long both in CG and in the format info.
  673. if ( Attributes.IsBasetype
  674. && ( Attributes.IsByValue || Attributes.IsSimpleRef ) )
  675. {
  676. if ( Attributes.IsSimpleRef )
  677. pChild = (CG_NDR *) pChild->GetChild();
  678. format->Type = GetRoot()->LookupFragment( pChild )->GetRefID();
  679. }
  680. else
  681. {
  682. FormatFragment *pCompChildFragment = GetCurrent()->GetParent()->LookupFragment( pChild );
  683. MIDL_ASSERT( NULL != pCompChildFragment );
  684. // Is the parameter is a simple ref, we need to bypass the pointer
  685. // in the format string.
  686. if ( Attributes.IsSimpleRef )
  687. {
  688. MIDL_NDR64_POINTER_FORMAT* pPointerFrag =
  689. dynamic_cast<MIDL_NDR64_POINTER_FORMAT*>(pCompChildFragment);
  690. format->Type = pPointerFrag->Pointee;
  691. }
  692. else
  693. {
  694. format->Type = pCompChildFragment->GetRefID();
  695. }
  696. }
  697. GetCurrent()->AddFragment( format );
  698. }
  699. //+--------------------------------------------------------------------------
  700. //
  701. // Method: GenNdr64Format::Visit( CG_PROC )
  702. //
  703. // Synopsis: Generate info for interfaces
  704. //
  705. //---------------------------------------------------------------------------
  706. void GenNdr64Format::Visit( CG_PROC *pProc )
  707. {
  708. if ( GetCurrent()->HasClassFragment( pProc ) )
  709. return;
  710. CG_NDR * pOldCGNodeContext;
  711. CG_ITERATOR Iterator;
  712. CG_PARAM * pParam;
  713. short ParamNum;
  714. long ServerBufferSize;
  715. long ClientBufferSize;
  716. long BufSize;
  717. BOOL fServerMustSize;
  718. BOOL fClientMustSize;
  719. // Make sure [call_as] targets are processed
  720. CG_PROC *pCallAs = pProc->GetCallAsCG();
  721. if (pCallAs)
  722. ContinueGenerationInRoot( pCallAs );
  723. CompositeFormatFragment *composite = new CompositeFormatFragment( pProc );
  724. composite->SetParent( GetCurrent() );
  725. GetCurrent()->AddFragment(composite);
  726. MIDL_NDR64_PROC_FORMAT *format = new MIDL_NDR64_PROC_FORMAT( pProc );
  727. composite->AddFragment( format );
  728. pCCB->SetInObjectInterface( pProc->IsObject() );
  729. pOldCGNodeContext = pCCB->SetCGNodeContext( pProc );
  730. //
  731. // If this procedure uses an explicit handle then set the
  732. // NdrBindDescriptionOffset to 0 so that it will not try to output it's
  733. // description when given the GenNdrParamOffLine method in the loop below.
  734. // It's description must be part of the procedure description.
  735. //
  736. if ( pProc->GetHandleUsage() == HU_EXPLICIT )
  737. {
  738. CG_HANDLE * pHandle = pProc->GetHandleClassPtr();
  739. pHandle->SetNdrBindDescriptionOffset( 0 );
  740. if ( pHandle->GetCGID() == ID_CG_CONTEXT_HDL )
  741. {
  742. // The context handle directs the call.
  743. ((CG_CONTEXT_HANDLE *)pHandle)->SetCannotBeNull();
  744. }
  745. }
  746. if ( !pProc->IsObject() && !pCCB->IsInCallback() )
  747. {
  748. if ( HU_IMPLICIT == pProc->GetHandleUsage() )
  749. {
  750. if ( pProc->IsGenericHandle() )
  751. pCCB->RegisterGenericHandleType(
  752. pProc->GetHandleClassPtr()->GetHandleType() );
  753. }
  754. }
  755. pProc->GetMembers( Iterator );
  756. ParamNum = 0;
  757. ServerBufferSize = 0;
  758. ClientBufferSize = 0;
  759. fServerMustSize = FALSE;
  760. fClientMustSize = FALSE;
  761. pCCB->SetInterpreterOutSize( 0 );
  762. while( ITERATOR_GETNEXT( Iterator, pParam ) )
  763. {
  764. CG_NDR * pChild;
  765. CG_NDR * pOldPlaceholder;
  766. pChild = (CG_NDR *) pParam->GetChild();
  767. // Ignore the following type of arguments that don't go on wire:
  768. // - async handles
  769. // - primitive handles
  770. //
  771. if ( pChild->GetCGID() == ID_CG_PRIMITIVE_HDL || ( (CG_PARAM*) pParam)->IsAsyncHandleParam() )
  772. continue;
  773. pParam->SetParamNumber( ParamNum++ );
  774. pCCB->SetCurrentParam( (CG_PARAM *) pParam );
  775. pOldPlaceholder = pCCB->SetLastPlaceholderClass( pParam );
  776. ContinueGenerationInRoot( pChild );
  777. // A procedure's buffer size does not depend on pipe arguments
  778. if (pChild->IsPipeOrPipeReference())
  779. {
  780. if (pChild->GetChild()->HasAFixedBufferSize())
  781. pParam->SetInterpreterMustSize(FALSE);
  782. else
  783. // There must be a union in there somewhere
  784. pParam->SetInterpreterMustSize(TRUE);
  785. }
  786. else
  787. {
  788. BufSize = pChild->FixedBufferSize( pCCB );
  789. if ( BufSize != -1 )
  790. {
  791. //
  792. // If either the client's or server's fixed buffer size gets too
  793. // big then we force the parameter to be sized.
  794. //
  795. if ( (pParam->IsParamIn() &&
  796. ((ClientBufferSize + BufSize) >= 65356)) ||
  797. (pParam->IsParamOut() &&
  798. ((ServerBufferSize + BufSize) >= 65356)) )
  799. {
  800. fClientMustSize = TRUE;
  801. fServerMustSize = TRUE;
  802. }
  803. else
  804. {
  805. pParam->SetInterpreterMustSize( FALSE );
  806. if ( pParam->IsParamIn() )
  807. ClientBufferSize += BufSize;
  808. if ( pParam->IsParamOut() )
  809. ServerBufferSize += BufSize;
  810. }
  811. }
  812. else
  813. {
  814. if ( pParam->IsParamIn() )
  815. fClientMustSize = TRUE;
  816. if ( pParam->IsParamOut() )
  817. fServerMustSize = TRUE;
  818. }
  819. }
  820. pCCB->SetCurrentParam( 0 );
  821. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  822. }
  823. //
  824. // Generate the format string for the return type if needed.
  825. //
  826. if ( pProc->GetReturnType() )
  827. {
  828. CG_NDR * pChild;
  829. CG_NDR * pOldPlaceholder;
  830. pProc->GetReturnType()->SetParamNumber( ParamNum++ );
  831. pChild = (CG_NDR *) pProc->GetReturnType()->GetChild();
  832. pCCB->SetCurrentParam( pProc->GetReturnType() );
  833. pOldPlaceholder = pCCB->SetLastPlaceholderClass( pProc->GetReturnType() );
  834. ContinueGenerationInRoot( pChild );
  835. BufSize = pChild->FixedBufferSize( pCCB );
  836. if ( BufSize != -1 )
  837. {
  838. if ( (ServerBufferSize + BufSize) >= 65536 )
  839. {
  840. fServerMustSize = TRUE;
  841. }
  842. else
  843. {
  844. ServerBufferSize += BufSize;
  845. pProc->GetReturnType()->SetInterpreterMustSize( FALSE );
  846. }
  847. }
  848. else
  849. fServerMustSize = TRUE;
  850. pCCB->SetCurrentParam( 0 );
  851. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  852. }
  853. pCCB->SetCurrentParam( 0 );
  854. //
  855. // REVIEW: This routine really needs to be broken up a bit
  856. //
  857. // Figure out the handle type
  858. if ( pProc->IsObject() )
  859. format->Flags.HandleType = NDR64_FC_AUTO_HANDLE;
  860. else if ( pCCB->IsInCallback() )
  861. format->Flags.HandleType = NDR64_FC_CALLBACK_HANDLE;
  862. else if ( HU_IMPLICIT != pProc->GetHandleUsage() )
  863. format->Flags.HandleType = NDR64_FC_EXPLICIT_HANDLE;
  864. else if ( pProc->IsAutoHandle() )
  865. format->Flags.HandleType = NDR64_FC_AUTO_HANDLE;
  866. else if ( pProc->IsPrimitiveHandle() )
  867. format->Flags.HandleType = NDR64_FC_BIND_PRIMITIVE;
  868. else if ( pProc->IsGenericHandle() )
  869. format->Flags.HandleType = NDR64_FC_BIND_GENERIC;
  870. // Set the proc flags
  871. format->Flags.ProcType = 0; // REVIEW: ??
  872. format->Flags.IsInterpreted = 1; // REVIEW: ??
  873. format->Flags.IsObject = pProc->IsObject();
  874. format->Flags.IsAsync = pProc->HasAsyncUUID(); // REVIEW: HasAsyncHandle?
  875. format->Flags.IsEncode = pProc->HasEncode();
  876. format->Flags.IsDecode = pProc->HasDecode();
  877. format->Flags.UsesFullPtrPackage = pProc->HasFullPtr();
  878. format->Flags.UsesRpcSmPackage = pProc->MustInvokeRpcSSAllocate();
  879. format->Flags.HandlesExceptions = pProc->HasStatuses(); // REVIEW: ??
  880. format->Flags.UsesPipes = pProc->HasPipes();
  881. format->Flags.ServerMustSize = fServerMustSize;
  882. format->Flags.ClientMustSize = fClientMustSize;
  883. format->Flags.HasReturn = ( NULL != pProc->GetReturnType() );
  884. format->Flags.HasComplexReturn = pProc->HasComplexReturnType();
  885. format->Flags.ServerHasCorrelation = pProc->HasServerCorr();
  886. format->Flags.ClientHasCorrelation = pProc->HasClientCorr();
  887. format->Flags.HasNotify = pProc->HasNotify() || pProc->HasNotifyFlag();
  888. format->Flags.HasOtherExtensions = 0; // Reset in GenExtendedProcInfo
  889. format->Flags.Reserved = 0;
  890. // Figure out the stack size. Note that stack size in the
  891. // NDR64_PROC_FORMAT structure is meaningless outside of ndr since it is
  892. // different for every processor
  893. format->ia64StackSize = pProc->GetTotalStackSize( pCCB );
  894. // Constant buffer sizes
  895. format->ConstantClientBufferSize = ClientBufferSize;
  896. format->ConstantServerBufferSize = ServerBufferSize;
  897. // RpcFlags
  898. //
  899. // REVIEW: Async is not an operation type!
  900. unsigned int opbits = pProc->GetOperationBits();
  901. format->RpcFlags.Idempotent = (NDR64_UINT16) (opbits & OPERATION_IDEMPOTENT ? 1 : 0);
  902. format->RpcFlags.Broadcast = (NDR64_UINT16) (opbits & OPERATION_BROADCAST ? 1 : 0);
  903. format->RpcFlags.Maybe = (NDR64_UINT16) (opbits & OPERATION_MAYBE ? 1 : 0);
  904. format->RpcFlags.Message = (NDR64_UINT16) (opbits & OPERATION_MESSAGE ? 1 : 0);
  905. format->RpcFlags.InputSynchronous = (NDR64_UINT16) (opbits & OPERATION_INPUT_SYNC ? 1 : 0);
  906. format->RpcFlags.Asynchronous = 0; // !!
  907. format->RpcFlags.Reserved1 = 0;
  908. format->RpcFlags.Reserved2 = 0;
  909. format->RpcFlags.Reserved3 = 0;
  910. // Miscellaneous
  911. format->FloatDoubleMask = pProc->GetFloatArgMask( pCCB );
  912. format->NumberOfParams = ParamNum;
  913. format->ExtensionSize = 0; // Reset in GenExtendedProcInfo
  914. // Generate the extended proc info if any
  915. if ( format->Flags.HasNotify || pProc->GetHandleUsage() == HU_EXPLICIT )
  916. GenExtendedProcInfo( composite );
  917. // Now generate the parameter descriptors
  918. ITERATOR_INIT( Iterator );
  919. while ( ITERATOR_GETNEXT( Iterator, pParam ) )
  920. ContinueGeneration( pParam, composite );
  921. if ( pProc->HasReturn() )
  922. ContinueGeneration( pProc->GetReturnType(), composite );
  923. // REVIEW: Are procs optimized? If so be careful because the stack size
  924. // field is set to 0 for all procs
  925. // composite->OptimizeFragment( format );
  926. }
  927. //+--------------------------------------------------------------------------
  928. //
  929. // Method: GenNdr64Format::GenExtendedProcInfo
  930. //
  931. // Synopsis: Generate info concerning explicit binding handles and
  932. // [notify] procs.
  933. //
  934. // Parameters: [composite] -- The composite to add the info to
  935. //
  936. //---------------------------------------------------------------------------
  937. void GenNdr64Format::GenExtendedProcInfo( CompositeFormatFragment *composite )
  938. {
  939. // The proc info should be the first thing in the composite
  940. MIDL_NDR64_PROC_FORMAT *procFormat;
  941. CG_PROC *procCG;
  942. MIDL_NDR64_BIND_AND_NOTIFY_EXTENSION *extension;
  943. extension = new MIDL_NDR64_BIND_AND_NOTIFY_EXTENSION;
  944. composite->AddFragment( extension );
  945. procFormat = dynamic_cast<MIDL_NDR64_PROC_FORMAT *>(composite->GetFirstFragment());
  946. MIDL_ASSERT( NULL != procFormat );
  947. procCG = (CG_PROC *) procFormat->GetCGNode();
  948. procFormat->Flags.HasOtherExtensions = 1; // REVIEW: ??
  949. //
  950. // explicit handles
  951. //
  952. if ( procCG->GetHandleUsage() == HU_EXPLICIT )
  953. {
  954. CG_HANDLE *pHandle = procCG->GetHandleClassPtr();
  955. CG_PARAM *pParam = procCG->GetHandleUsagePtr();
  956. CG_NDR *pOldPlaceholder;
  957. pOldPlaceholder = pCCB->SetLastPlaceholderClass( pParam );
  958. pHandle->GetNdrHandleInfo( pCCB, &extension->Binding );
  959. pParam->GetStackOffsets( pCCB, &extension->StackOffsets );
  960. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  961. }
  962. else
  963. {
  964. // No explicit handle, zero out the handle info.
  965. memset( &extension->Binding, 0, sizeof( extension->Binding ) );
  966. memset( &extension->StackOffsets, 0, sizeof( extension->StackOffsets ) );
  967. }
  968. //
  969. // [notify]
  970. //
  971. if ( procFormat->Flags.HasNotify )
  972. extension->NotifyIndex = procCG->GetNotifyTableOffset( pCCB );
  973. else
  974. extension->NotifyIndex = 0;
  975. // Update the extension size field.
  976. procFormat->ExtensionSize = sizeof(NDR64_BIND_AND_NOTIFY_EXTENSION);
  977. }
  978. //+--------------------------------------------------------------------------
  979. //
  980. // Method: GenNdr64Format::Visit( CG_POINTER )
  981. //
  982. // Synopsis: Generate info for simple pointer and add fragment to
  983. // current composite fragment.
  984. //
  985. //---------------------------------------------------------------------------
  986. void GenNdr64Format::Visit( CG_POINTER *pPointer )
  987. {
  988. MIDL_NDR64_POINTER_FORMAT *format;
  989. format = new MIDL_NDR64_POINTER_FORMAT( pPointer );
  990. // Get the type of the pointer (ref, etc) and any flags
  991. pPointer->GetTypeAndFlags( pCCB, format );
  992. CG_CLASS *pointee = pPointer->GetChild();
  993. if ( format->Flags & FC_SIMPLE_POINTER )
  994. {
  995. // generic handles are represented as thier underlying type and
  996. // otherwise pretty much ignored for our purposes.
  997. if ( ID_CG_GENERIC_HDL == pointee->GetCGID() )
  998. pointee = pointee->GetChild();
  999. MIDL_ASSERT( NULL != dynamic_cast<CG_BASETYPE *> ( pointee ) );
  1000. }
  1001. GetCurrent()->AddFragment( format );
  1002. format->Reserved = 0;
  1003. format->Pointee = ContinueGenerationInRoot( pointee );
  1004. GetRoot()->OptimizeFragment( format );
  1005. }
  1006. MIDL_NDR64_POINTER_FORMAT* GenNdr64Format::GenQualifiedPtrHdr( CG_QUALIFIED_POINTER *pPointer )
  1007. {
  1008. MIDL_NDR64_POINTER_FORMAT* pHeader = new MIDL_NDR64_POINTER_FORMAT( pPointer );
  1009. pPointer->GetTypeAndFlags( pCCB, pHeader );
  1010. // Always use complex pointer struct
  1011. pHeader->Flags &= ~FC_SIMPLE_POINTER;
  1012. pHeader->Reserved = 0;
  1013. pHeader->Pointee = INVALID_FRAGMENT_ID;
  1014. return pHeader;
  1015. }
  1016. MIDL_NDR64_POINTER_FORMAT* GenNdr64Format::GenQualifiedArrayPtr( CG_ARRAY *pArray )
  1017. {
  1018. // Ref arrays do not need the pointer header.
  1019. if ( pArray->GetPtrType() == PTR_REF )
  1020. return NULL;
  1021. MIDL_NDR64_POINTER_FORMAT* pFragment = new MIDL_NDR64_POINTER_FORMAT( pArray );
  1022. switch ( pArray->GetPtrType() )
  1023. {
  1024. case PTR_UNKNOWN:
  1025. case PTR_REF:
  1026. MIDL_ASSERT(0);
  1027. break;
  1028. case PTR_UNIQUE:
  1029. pFragment->FormatCode = FC64_UP;
  1030. break;
  1031. case PTR_FULL:
  1032. pFragment->FormatCode = FC64_FP;
  1033. break;
  1034. default:
  1035. MIDL_ASSERT(0);
  1036. break;
  1037. }
  1038. pFragment->Flags = 0;
  1039. pFragment->Reserved = 0;
  1040. return pFragment;
  1041. }
  1042. void GenNdr64Format::Visit( CG_STRING_POINTER *pPointer )
  1043. {
  1044. // REVIEW: This is essentially two routines distinguished by an if.
  1045. // Seperate them.
  1046. MIDL_NDR64_POINTER_FORMAT* pPointerHdr = GenQualifiedPtrHdr( pPointer );
  1047. GetCurrent()->AddFragment( pPointerHdr );
  1048. FormatFragment *pStringFrag = NULL;
  1049. if ( dynamic_cast<CG_SIZE_STRING_POINTER *>(pPointer) )
  1050. {
  1051. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE*>( pPointer );
  1052. FormatFragment *pFrag = GenerateCorrelationDescriptor( pConfAttribute->GetSizeIsExpr() );
  1053. MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT *pSizedConfFormat =
  1054. new MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT( pPointer );
  1055. pStringFrag = pSizedConfFormat;
  1056. InitStringHeader( pPointer, &pSizedConfFormat->Header, true, true);
  1057. pSizedConfFormat->SizeDescription = (PNDR64_FORMAT)pFrag->GetRefID();
  1058. }
  1059. else
  1060. {
  1061. MIDL_NDR64_CONFORMANT_STRING_FORMAT *pConfFormat =
  1062. new MIDL_NDR64_CONFORMANT_STRING_FORMAT( pPointer );
  1063. pStringFrag = pConfFormat;
  1064. InitStringHeader( pPointer, &pConfFormat->Header, true, false);
  1065. }
  1066. GetRoot()->AddFragment( pStringFrag );
  1067. GetRoot()->OptimizeFragment( pStringFrag );
  1068. pPointerHdr->Pointee = pStringFrag->GetRefID();
  1069. GetRoot()->OptimizeFragment( pPointerHdr );
  1070. }
  1071. void GenNdr64Format::GenerateNonStringQualifiedPtr( CG_QUALIFIED_POINTER *pPointer )
  1072. {
  1073. MIDL_NDR64_POINTER_FORMAT *pPointerFrag = GenQualifiedPtrHdr( pPointer );
  1074. GetCurrent()->AddFragment( pPointerFrag );
  1075. FormatFragment *pArrayFrag = GenerateNonStringQualifiedArrayLayout( pPointer, GetRoot() );
  1076. pPointerFrag->Pointee = pArrayFrag->GetRefID();
  1077. }
  1078. //+--------------------------------------------------------------------------
  1079. //
  1080. // Method: GenNdr64Format::GenInterfacePointer
  1081. //
  1082. // Synopsis: Generate info for interface pointers
  1083. //
  1084. //---------------------------------------------------------------------------
  1085. void GenNdr64Format::GenInterfacePointer( CG_POINTER *pPointer, BOOL IsConstantIID )
  1086. {
  1087. MIDL_NDR64_POINTER_FORMAT *format;
  1088. format = new MIDL_NDR64_POINTER_FORMAT( pPointer );
  1089. // Generate the pointer node
  1090. pPointer->GetTypeAndFlags( pCCB, format );
  1091. format->FormatCode = FC64_IP; // GetTypeAndFlags doesn't emit FC64_IP
  1092. format->Reserved = 0;
  1093. GetCurrent()->AddFragment( format );
  1094. // generate the interface type node
  1095. if ( IsConstantIID )
  1096. {
  1097. CG_INTERFACE_POINTER *pInterface =
  1098. dynamic_cast<CG_INTERFACE_POINTER*>( pPointer );
  1099. MIDL_NDR64_CONSTANT_IID_FORMAT *iid;
  1100. iid = new MIDL_NDR64_CONSTANT_IID_FORMAT;
  1101. iid->FormatCode = FC64_IP;
  1102. iid->Flags.ConstantIID = 1;
  1103. iid->Flags.Reserved = 0;
  1104. iid->Reserved = 0;
  1105. node_guid * pGuid = (node_guid *) pInterface
  1106. ->GetTheInterface()
  1107. ->GetAttribute( ATTR_GUID );
  1108. pGuid->GetGuid( iid->Guid );
  1109. format->Pointee = GetRoot()->AddFragment( iid );
  1110. }
  1111. else
  1112. {
  1113. CG_IIDIS_INTERFACE_POINTER *piidInterface =
  1114. dynamic_cast<CG_IIDIS_INTERFACE_POINTER*>( pPointer );
  1115. FormatFragment *pIIDExpr = GenerateCorrelationDescriptor( piidInterface->GetIIDExpr() );
  1116. MIDL_NDR64_IID_FORMAT *iid = new MIDL_NDR64_IID_FORMAT;
  1117. iid->FormatCode = FC64_IP;
  1118. iid->Flags.ConstantIID = 0;
  1119. iid->Flags.Reserved = 0;
  1120. iid->Reserved = 0;
  1121. iid->IIDDescriptor = pIIDExpr->GetRefID();
  1122. format->Pointee = GetRoot()->AddFragment( iid );
  1123. }
  1124. }
  1125. //+--------------------------------------------------------------------------
  1126. //
  1127. // Method: GenNdr64Format::Visit( CG_UNION )
  1128. //
  1129. // Synopsis: Generate info for unions
  1130. //
  1131. //---------------------------------------------------------------------------
  1132. void GenNdr64Format::Visit( CG_UNION *pUnion )
  1133. {
  1134. // A union is represented in the format info by a composite containing
  1135. // the union header follow by fragments representing the arm selector
  1136. CompositeFormatFragment *composite = new CompositeFormatFragment( pUnion );
  1137. GetCurrent()->AddFragment( composite );
  1138. MIDL_NDR64_NON_ENCAPSULATED_UNION *format;
  1139. format = new MIDL_NDR64_NON_ENCAPSULATED_UNION( pUnion );
  1140. composite->AddFragment( format );
  1141. MIDL_ASSERT( dynamic_cast<CG_BASETYPE *> (pUnion->GetSwitchType()) );
  1142. NDR64_FORMAT_CHAR SwitchType = (NDR64_FORMAT_CHAR)
  1143. ( (CG_BASETYPE *) pUnion->GetSwitchType() )
  1144. ->GetNDR64SignedFormatChar();
  1145. // The alignment of a union is the max of the type alignment and the arm alignment.
  1146. unsigned short UnionArmAlignment = pUnion->GetWireAlignment();
  1147. unsigned short SwitchTypeAlignment =
  1148. ( (CG_BASETYPE*) pUnion->GetSwitchType() )->GetWireAlignment() ;
  1149. unsigned short UnionAlignment = UnionArmAlignment > SwitchTypeAlignment ?
  1150. UnionArmAlignment : SwitchTypeAlignment;
  1151. format->FormatCode = FC64_NON_ENCAPSULATED_UNION;
  1152. format->Alignment = ConvertAlignment( UnionAlignment );
  1153. format->Flags = 0;
  1154. format->SwitchType = SwitchType;
  1155. format->MemorySize = pUnion->GetMemorySize();
  1156. format->Reserved = 0;
  1157. expr_node *pSwitchExpr = pUnion->GetNdr64SwitchIsExpr();
  1158. FormatFragment* pSwitchFormat = GenerateCorrelationDescriptor( pSwitchExpr );
  1159. format->Switch = (PNDR64_FORMAT)pSwitchFormat->GetRefID();
  1160. GenerateUnionArmSelector( pUnion, composite );
  1161. GetRoot()->OptimizeFragment( composite );
  1162. }
  1163. //+--------------------------------------------------------------------------
  1164. //
  1165. // Method: GenNdr64Format::Visit( CG_CONTEXT_HANDLE )
  1166. //
  1167. // Synopsis: Generate info for context handles
  1168. //
  1169. // Notes: This is an an abreviated version of the same information in
  1170. // the proc descriptor.
  1171. //
  1172. //---------------------------------------------------------------------------
  1173. void GenNdr64Format::Visit( CG_CONTEXT_HANDLE *pHandle )
  1174. {
  1175. CG_PARAM * pBindParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  1176. CG_PROC * pProc = (CG_PROC *) pCCB->GetCGNodeContext();
  1177. MIDL_NDR64_CONTEXT_HANDLE_FORMAT *format;
  1178. format = new MIDL_NDR64_CONTEXT_HANDLE_FORMAT( pHandle );
  1179. format->FormatCode = FC64_BIND_CONTEXT;
  1180. //
  1181. // Register the rundown routine always, even if the context handle is
  1182. // not used as the binding paramter.
  1183. //
  1184. if ( pHandle->GetHandleType()->NodeKind() == NODE_DEF )
  1185. {
  1186. pCCB->RegisterContextHandleType( pHandle->GetHandleType() );
  1187. }
  1188. // Flags
  1189. unsigned char uFlags = pHandle->MakeExplicitHandleFlag( pBindParam );
  1190. format->ContextFlags.CannotBeNull = pHandle->GetCannotBeNull()
  1191. || pBindParam->IsParamIn()
  1192. && !pBindParam->IsParamOut();
  1193. format->ContextFlags.Serialize = (NDR64_UINT8) ( pHandle->HasSerialize() ? 1 : 0 );
  1194. format->ContextFlags.NoSerialize = (NDR64_UINT8) ( pHandle->HasNoSerialize() ? 1 : 0 );
  1195. format->ContextFlags.Strict = (NDR64_UINT8) ( pHandle->HasStrict() ? 1 : 0 );
  1196. format->ContextFlags.IsReturn = (NDR64_UINT8) ( ( uFlags & HANDLE_PARAM_IS_RETURN ) ? 1 : 0 );
  1197. format->ContextFlags.IsOut = (NDR64_UINT8) ( ( uFlags & HANDLE_PARAM_IS_OUT ) ? 1 : 0 );
  1198. format->ContextFlags.IsIn = (NDR64_UINT8) ( ( uFlags & HANDLE_PARAM_IS_IN ) ? 1 : 0 );
  1199. format->ContextFlags.IsViaPointer = (NDR64_UINT8) ( ( uFlags & HANDLE_PARAM_IS_VIA_PTR ) ? 1 : 0 );
  1200. // Routine index.
  1201. // IndexMgr keeps indexes 1..n, we use indexes 0..n-1
  1202. format->RundownRoutineIndex = (NDR64_UINT8)
  1203. ( pCCB->LookupRundownRoutine( pHandle->GetRundownRtnName() ) - 1);
  1204. // Ordinal
  1205. format->Ordinal = (NDR64_UINT8) pProc->GetContextHandleCount();
  1206. pProc->SetContextHandleCount( (short) (format->Ordinal + 1) );
  1207. GetCurrent()->AddFragment( format );
  1208. }
  1209. //+--------------------------------------------------------------------------
  1210. //
  1211. // Method: GenNdr64Format::Visit( CG_GENERIC_HANDLE )
  1212. //
  1213. // Synopsis: Generate info for generic handles
  1214. //
  1215. // Notes: Actually generic handles are represented by thier underlying
  1216. // type, not by any special "generic handle" type. Therefore
  1217. // there's nothing to generate. We do need a place to
  1218. // register the handle though.
  1219. //
  1220. // Review: Since we're not generating perhaps registering is better
  1221. // placed in some other phase?
  1222. //
  1223. //---------------------------------------------------------------------------
  1224. void GenNdr64Format::Visit( CG_GENERIC_HANDLE *pHandle )
  1225. {
  1226. ContinueGenerationInRoot( pHandle->GetChild() );
  1227. MIDL_ASSERT( pCCB->GetCGNodeContext()->IsProc() );
  1228. CG_HANDLE *pBindingHandle = ((CG_PROC *)pCCB->GetCGNodeContext())
  1229. ->GetHandleClassPtr();
  1230. if ( pBindingHandle == pHandle )
  1231. pCCB->RegisterGenericHandleType( pHandle->GetHandleType() );
  1232. }
  1233. //---------------------------------------------------------------------------
  1234. //
  1235. // Pointer Layout Functions
  1236. //
  1237. //---------------------------------------------------------------------------
  1238. //+--------------------------------------------------------------------------
  1239. //
  1240. // Method: GenNdr64Format::GenSimplePtrLayout( CG_STRUCT, bool, ulong *)
  1241. //
  1242. // Synopsis: Generate a pointer layout for a block copyable structure.
  1243. //
  1244. //---------------------------------------------------------------------------
  1245. FormatFragment * GenNdr64Format::GenSimplePtrLayout( CG_STRUCT *pStruct,
  1246. bool bGenHeaderFooter,
  1247. ulong *pPtrInstances )
  1248. {
  1249. CompositeFormatFragment *pCompositeFormatFragment = NULL;
  1250. CCB *pCCB = GetCCB();
  1251. ulong NumberPointerInstances = 0;
  1252. CG_FIELD *pOldRegionField = NULL;
  1253. CG_NDR *pOldContext = NULL;
  1254. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1255. pOldRegionField = pCCB->StartRegion();
  1256. else
  1257. pOldContext = pCCB->SetCGNodeContext( pStruct );
  1258. CG_ITERATOR Iterator;
  1259. pStruct->GetMembers( Iterator );
  1260. CG_FIELD *pField;
  1261. ITERATOR_INIT( Iterator );
  1262. while ( ITERATOR_GETNEXT( Iterator, pField ) )
  1263. {
  1264. CG_NDR * pOldPlaceHolder = pCCB->SetLastPlaceholderClass( pField );
  1265. CG_CLASS *pMember = (CG_NDR *) pField->GetChild();
  1266. MIDL_ASSERT( !pMember->IsStruct() ); // Structure should have been unrolled.
  1267. if ( pMember->IsPointer() )
  1268. {
  1269. if ( NULL == pCompositeFormatFragment )
  1270. pCompositeFormatFragment = new CompositeFormatFragment();
  1271. if ( bGenHeaderFooter )
  1272. pCompositeFormatFragment->AddFragment(
  1273. new MIDL_NDR64_NO_REPEAT_FORMAT() );
  1274. pCompositeFormatFragment->AddFragment(
  1275. new MIDL_NDR64_POINTER_INSTANCE_HEADER_FORMAT( pField->GetMemOffset() ) );
  1276. ContinueGeneration( pMember, pCompositeFormatFragment );
  1277. NumberPointerInstances++;
  1278. }
  1279. // For now, arrays do not have pointers.
  1280. else if ( pMember->IsArray() )
  1281. {
  1282. FormatFragment *pPointerFragment = GenSimplePtrLayout( dynamic_cast<CG_ARRAY*>( pMember ),
  1283. false,
  1284. pField->GetMemOffset() );
  1285. if ( NULL != pPointerFragment )
  1286. {
  1287. if ( NULL == pCompositeFormatFragment )
  1288. pCompositeFormatFragment = new CompositeFormatFragment();
  1289. pCompositeFormatFragment->AddFragment( pPointerFragment );
  1290. }
  1291. }
  1292. pCCB->SetLastPlaceholderClass( pOldPlaceHolder );
  1293. }
  1294. if ( ( NULL != pCompositeFormatFragment ) &&
  1295. bGenHeaderFooter )
  1296. {
  1297. FormatFragment *pFormatFragment = new MIDL_NDR64_FORMAT_CHAR( FC64_END );
  1298. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1299. }
  1300. if ( NULL != pPtrInstances )
  1301. {
  1302. *pPtrInstances = NumberPointerInstances;
  1303. }
  1304. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1305. pCCB->EndRegion( pOldRegionField );
  1306. else
  1307. pCCB->SetCGNodeContext( pOldContext );
  1308. return pCompositeFormatFragment;
  1309. }
  1310. //+--------------------------------------------------------------------------
  1311. //
  1312. // Method: GenNdr64Format::GenSimplePtrLayout( CG_ARRAY, bool, ulong *)
  1313. //
  1314. // Synopsis: Generate a pointer layout for a block copyable structure.
  1315. //
  1316. //---------------------------------------------------------------------------
  1317. FormatFragment * GenNdr64Format::GenSimplePtrLayout( CG_NDR *pArray,
  1318. bool bGenHeaderFooter,
  1319. ulong MemoryOffset )
  1320. {
  1321. CompositeFormatFragment *pArrayLayout = NULL;
  1322. CG_CLASS *pChild = pArray->GetChild();
  1323. FormatFragment* pChildLayout = NULL;
  1324. unsigned long NumberPointers = 0;
  1325. // Multidimensional arrays should be bogus
  1326. MIDL_ASSERT( !pChild->IsArray() );
  1327. if ( pChild->IsPointer() )
  1328. {
  1329. CompositeFormatFragment *pCompositeFormatFragment =
  1330. new CompositeFormatFragment();
  1331. pCompositeFormatFragment->AddFragment(
  1332. new MIDL_NDR64_POINTER_INSTANCE_HEADER_FORMAT( 0 ) );
  1333. ContinueGeneration( pChild, pCompositeFormatFragment );
  1334. pChildLayout = pCompositeFormatFragment;
  1335. NumberPointers = 1;
  1336. }
  1337. else if ( pChild->IsStruct() )
  1338. {
  1339. pChildLayout = GenSimplePtrLayout( dynamic_cast< CG_STRUCT *>( pChild ),
  1340. false,
  1341. &NumberPointers );
  1342. }
  1343. if ( pChildLayout )
  1344. {
  1345. pArrayLayout = new CompositeFormatFragment();
  1346. FormatFragment *pHeader;
  1347. if ( dynamic_cast<CG_FIXED_ARRAY*>( pArray ) )
  1348. {
  1349. CG_FIXED_ARRAY *pFixedArray = (CG_FIXED_ARRAY*)( pArray );
  1350. pHeader = new MIDL_NDR64_FIXED_REPEAT_FORMAT( dynamic_cast<CG_NDR*>( pChild )->GetMemorySize(),
  1351. MemoryOffset,
  1352. NumberPointers,
  1353. pFixedArray->GetNumOfElements(),
  1354. dynamic_cast<CG_NDR*>( pChild )->IsStruct() );
  1355. }
  1356. else
  1357. {
  1358. pHeader = new MIDL_NDR64_REPEAT_FORMAT( dynamic_cast<CG_NDR*>( pChild )->GetMemorySize(),
  1359. MemoryOffset,
  1360. NumberPointers,
  1361. dynamic_cast< CG_NDR* >( pChild )->IsStruct() );
  1362. }
  1363. pArrayLayout->AddFragment( pHeader );
  1364. pArrayLayout->AddFragment( pChildLayout );
  1365. if ( bGenHeaderFooter )
  1366. {
  1367. pArrayLayout->AddFragment( new MIDL_NDR64_FORMAT_CHAR( FC64_END ) );
  1368. }
  1369. }
  1370. return pArrayLayout;
  1371. }
  1372. //--------------------------------------------------------------------------
  1373. //
  1374. // Structure layout
  1375. //
  1376. //
  1377. //--------------------------------------------------------------------------
  1378. //+--------------------------------------------------------------------------
  1379. //
  1380. // Method: GenNdr64Format::GenCmplxPtrLayout( CG_COMPLEX_STRUCT )
  1381. //
  1382. // Synopsis: Generate a pointer layout for a complex structure.
  1383. //
  1384. //---------------------------------------------------------------------------
  1385. FormatFragment * GenNdr64Format::GenCmplxPtrLayout( CG_COMPLEX_STRUCT *pStruct )
  1386. {
  1387. CompositeFormatFragment *pCompositeFormatFragment = NULL;
  1388. CCB *pCCB = GetCCB();
  1389. CG_ITERATOR Iterator;
  1390. pStruct->GetMembers( Iterator );
  1391. MIDL_ASSERT( pCCB->GetCurrentRegionField() == NULL );
  1392. CG_FIELD *pField;
  1393. ITERATOR_INIT( Iterator );
  1394. while ( ITERATOR_GETNEXT( Iterator, pField ) )
  1395. {
  1396. CG_NDR * pOldPlaceHolder = pCCB->SetLastPlaceholderClass( pField );
  1397. CG_CLASS *pMember = (CG_NDR *) pField->GetChild();
  1398. if ( pMember->IsPointer() )
  1399. {
  1400. if (NULL == pCompositeFormatFragment)
  1401. pCompositeFormatFragment = new CompositeFormatFragment();
  1402. ContinueGeneration( pMember, pCompositeFormatFragment );
  1403. }
  1404. pCCB->SetLastPlaceholderClass( pOldPlaceHolder );
  1405. }
  1406. return pCompositeFormatFragment;
  1407. }
  1408. //+--------------------------------------------------------------------------
  1409. //
  1410. // Method: GenNdr64Format::GenerateSimpleStructure( CG_STRUCT, bool )
  1411. //
  1412. // Synopsis: Generate the format string for a simple structure.
  1413. //
  1414. //---------------------------------------------------------------------------
  1415. void GenNdr64Format::GenerateSimpleStructure( CG_STRUCT *pStruct,
  1416. bool IsConformant )
  1417. {
  1418. // Add the fragment right away so recursive structure definitions
  1419. // are caught
  1420. CompositeFormatFragment *pMainFragment
  1421. = new CompositeFormatFragment( pStruct );
  1422. GetCurrent()->AddFragment( pMainFragment );
  1423. CG_FIELD *pOldRegionField = NULL;
  1424. CG_NDR *pOldContext = NULL;
  1425. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1426. pOldRegionField = pCCB->StartRegion();
  1427. else
  1428. {
  1429. pOldRegionField = pCCB->GetCurrentRegionField();
  1430. pCCB->EndRegion( NULL );
  1431. pOldContext = pCCB->SetCGNodeContext( pStruct );
  1432. }
  1433. FormatFragment* pMemberLayout = NULL;
  1434. FormatFragment* pPointerLayout = GenSimplePtrLayout( pStruct );
  1435. if ( pCommand->NeedsNDR64DebugInfo() )
  1436. pMemberLayout = GenerateStructureMemberLayout( pStruct, true );
  1437. if ( IsConformant )
  1438. {
  1439. CG_CONFORMANT_STRUCT *pConfStruct = dynamic_cast<CG_CONFORMANT_STRUCT*>( pStruct );
  1440. CG_FIELD *pConfField = dynamic_cast<CG_FIELD*>( pConfStruct->GetConformantField() );
  1441. MIDL_ASSERT( NULL != pConfField );
  1442. CG_ARRAY *pConfArray = dynamic_cast<CG_ARRAY*>( pConfField->GetChild() );
  1443. MIDL_ASSERT( NULL != pConfArray );
  1444. CG_NDR * pOldPlaceholder = GetCCB()->SetLastPlaceholderClass( pConfField );
  1445. FormatFragment *pHeader =
  1446. new MIDL_NDR64_CONF_STRUCTURE_HEADER_FORMAT( pConfStruct,
  1447. NULL != pPointerLayout,
  1448. NULL != pMemberLayout,
  1449. ContinueGenerationInRoot( pConfArray ) );
  1450. pMainFragment->AddFragment( pHeader );
  1451. GetCCB()->SetLastPlaceholderClass( pOldPlaceholder );
  1452. }
  1453. else
  1454. {
  1455. FormatFragment *pHeader =
  1456. new MIDL_NDR64_STRUCTURE_HEADER_FORMAT( pStruct,
  1457. NULL != pPointerLayout,
  1458. NULL != pMemberLayout );
  1459. pMainFragment->AddFragment( pHeader );
  1460. }
  1461. if ( NULL != pPointerLayout ) pMainFragment->AddFragment( pPointerLayout );
  1462. if ( NULL != pMemberLayout ) pMainFragment->AddFragment( pMemberLayout );
  1463. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1464. pCCB->EndRegion( pOldRegionField );
  1465. else
  1466. {
  1467. pCCB->EndRegion( pOldRegionField );
  1468. pCCB->SetCGNodeContext( pOldContext );
  1469. }
  1470. GetRoot()->OptimizeFragment( pMainFragment );
  1471. }
  1472. //+--------------------------------------------------------------------------
  1473. //
  1474. // Method: GenNdr64Format::GenerateComplexStruct( CG_STRUCT, bool )
  1475. //
  1476. // Synopsis: Generate the format string for a complex structure.
  1477. //
  1478. //---------------------------------------------------------------------------
  1479. void GenNdr64Format::GenerateComplexStruct( CG_COMPLEX_STRUCT *pStruct,
  1480. bool IsConformant )
  1481. {
  1482. if ( GetCurrent()->HasClassFragment( pStruct ) )
  1483. return;
  1484. // This must be done first to handle recurion.
  1485. CompositeFormatFragment *pMainFragment =
  1486. new CompositeFormatFragment( pStruct );
  1487. GetCurrent()->AddFragment( pMainFragment );
  1488. CG_FIELD *pOldRegionField = NULL;
  1489. CG_NDR *pOldContext = NULL;
  1490. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1491. pOldRegionField = pCCB->StartRegion();
  1492. else
  1493. {
  1494. pOldRegionField = pCCB->GetCurrentRegionField();
  1495. pCCB->EndRegion( NULL );
  1496. pOldContext = pCCB->SetCGNodeContext( pStruct );
  1497. }
  1498. FormatInfoRef ArrayID = INVALID_FRAGMENT_ID;
  1499. CG_ARRAY *pConfArray = NULL;
  1500. if ( IsConformant )
  1501. {
  1502. CG_FIELD *pConfField = dynamic_cast<CG_FIELD*>( pStruct->GetConformantField() );
  1503. MIDL_ASSERT( NULL != pConfField );
  1504. pConfArray = dynamic_cast<CG_ARRAY*>( pConfField->GetChild() );
  1505. MIDL_ASSERT( NULL != pConfArray );
  1506. CG_NDR * pOldPlaceholder = GetCCB()->SetLastPlaceholderClass( pConfField );
  1507. ArrayID = ContinueGenerationInRoot( pConfArray );
  1508. GetCCB()->SetLastPlaceholderClass( pOldPlaceholder );
  1509. }
  1510. FormatInfoRef PointerID = INVALID_FRAGMENT_ID;
  1511. FormatFragment *pPointerLayout = GenCmplxPtrLayout( pStruct );
  1512. if ( NULL != pPointerLayout )
  1513. {
  1514. // Pointer Layout for complex struct goes in the root fragment.
  1515. PointerID = GetRoot()->AddFragment( pPointerLayout );
  1516. }
  1517. FormatFragment* pMemberLayout = GenerateStructureMemberLayout( pStruct, false );
  1518. // The only difference between the member layout with debugging
  1519. // and without debugging is that simple region become complex regions
  1520. // with member layouts.
  1521. FormatInfoRef DebugPointerID = INVALID_FRAGMENT_ID;
  1522. FormatInfoRef DebugMemberLayoutID = INVALID_FRAGMENT_ID;
  1523. if ( pCommand->NeedsNDR64DebugInfo() )
  1524. {
  1525. DebugPointerID = PointerID;
  1526. FormatFragment *pDebugMemberLayout = GenerateStructureMemberLayout( pStruct, true );
  1527. DebugMemberLayoutID = GetRoot()->AddFragment( pDebugMemberLayout );
  1528. }
  1529. FormatFragment* pHeader;
  1530. if ( IsConformant )
  1531. {
  1532. MIDL_ASSERT( NULL != pConfArray );
  1533. pHeader = new MIDL_NDR64_CONF_BOGUS_STRUCTURE_HEADER_FORMAT( pStruct,
  1534. pConfArray,
  1535. ArrayID,
  1536. DebugMemberLayoutID,
  1537. DebugPointerID,
  1538. PointerID );
  1539. }
  1540. else
  1541. {
  1542. pHeader = new MIDL_NDR64_BOGUS_STRUCTURE_HEADER_FORMAT( pStruct,
  1543. DebugMemberLayoutID,
  1544. DebugPointerID,
  1545. PointerID );
  1546. }
  1547. pMainFragment->AddFragment( pHeader );
  1548. pMainFragment->AddFragment( pMemberLayout );
  1549. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1550. pCCB->EndRegion( pOldRegionField );
  1551. else
  1552. {
  1553. pCCB->EndRegion( pOldRegionField );
  1554. pCCB->SetCGNodeContext( pOldContext );
  1555. }
  1556. }
  1557. //+--------------------------------------------------------------------------
  1558. //
  1559. // Class: StructureMemberGenerator
  1560. //
  1561. // Synopsis: This object is responsible for generating the member layout
  1562. // of a structure.
  1563. //
  1564. //---------------------------------------------------------------------------
  1565. class StructureMemberGenerator
  1566. {
  1567. private:
  1568. GenNdr64Format *pMainGenerator;
  1569. CompositeFormatFragment *pCompositeFormatFragment;
  1570. CG_VISITOR *pVisitor;
  1571. bool bIsDebug;
  1572. void StartGeneration( CG_STRUCT *pStruct );
  1573. void GenerateMember( CG_CLASS *pClass )
  1574. {
  1575. pClass->Visit( pVisitor );
  1576. }
  1577. public:
  1578. static FormatFragment* Generate( GenNdr64Format *pMainGenerator,
  1579. CG_STRUCT *pStruct,
  1580. bool bIsDebug )
  1581. {
  1582. CG_VISITOR_TEMPLATE<StructureMemberGenerator> TemplateVisitor;
  1583. StructureMemberGenerator & Visitor = TemplateVisitor;
  1584. Visitor.pMainGenerator = pMainGenerator;
  1585. Visitor.pCompositeFormatFragment = new CompositeFormatFragment();
  1586. Visitor.pVisitor = &TemplateVisitor;
  1587. Visitor.bIsDebug = bIsDebug;
  1588. Visitor.StartGeneration( pStruct );
  1589. return Visitor.pCompositeFormatFragment;
  1590. }
  1591. // Items that get a unique member layout item.
  1592. void Visit( CG_POINTER *pPointer)
  1593. {
  1594. pPointer;
  1595. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_POINTER );
  1596. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1597. }
  1598. void Visit( CG_IGNORED_POINTER *pPointer )
  1599. {
  1600. pPointer;
  1601. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_IGNORE );
  1602. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1603. }
  1604. void Visit( CG_BASETYPE *pBaseType )
  1605. {
  1606. if ( pBaseType->GetRangeAttribute() != NULL )
  1607. {
  1608. // Send to generic catch all case(Embedded complex)
  1609. Visit( (CG_CLASS*) pBaseType );
  1610. return;
  1611. }
  1612. NDR64_FORMAT_CHAR FormatCode = (NDR64_FORMAT_CHAR)pBaseType->GetNDR64FormatChar();
  1613. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FormatCode );
  1614. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1615. }
  1616. void Visit( CG_SIMPLE_REGION *pSimpleRegion )
  1617. {
  1618. // If this member layout is for debugging, send this
  1619. // to the CG_CLASS visit function to create an
  1620. // embedded complex.
  1621. if ( bIsDebug )
  1622. {
  1623. Visit( (CG_CLASS*)pSimpleRegion );
  1624. return;
  1625. }
  1626. FormatFragment *pFormatFragment =
  1627. new MIDL_NDR64_SIMPLE_REGION_FORMAT( pSimpleRegion );
  1628. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1629. }
  1630. void Visit( CG_PAD *pPad )
  1631. {
  1632. FormatFragment *pFormatFragment
  1633. = new MIDL_NDR64_BUFFER_ALIGN_FORMAT( pPad );
  1634. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1635. }
  1636. // Do nothing for conformant arrays. They must be at the end.
  1637. void Visit( CG_CONFORMANT_ARRAY *pConfArray ) { pConfArray; }
  1638. void Visit( CG_CONFORMANT_VARYING_ARRAY *pConfVaryArray ) { pConfVaryArray; }
  1639. void Visit( CG_CONFORMANT_STRING_ARRAY *pConfStringArray ) { pConfStringArray; }
  1640. // Catch all case. Generates embedded complex
  1641. void Visit( CG_CLASS *pClass )
  1642. {
  1643. FormatInfoRef ID = pMainGenerator->ContinueGenerationInRoot( pClass );
  1644. FormatFragment *pFormatFragment = new MIDL_NDR64_EMBEDDED_COMPLEX_FORMAT( ID );
  1645. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1646. }
  1647. };
  1648. void StructureMemberGenerator::StartGeneration( CG_STRUCT *pStruct )
  1649. {
  1650. CCB *pCCB = pMainGenerator->GetCCB();
  1651. CG_NDR * pOldPlaceholder = pCCB->GetLastPlaceholderClass();
  1652. CG_ITERATOR Iterator;
  1653. pStruct->GetMembers( Iterator );
  1654. CG_FIELD * pField;
  1655. unsigned long BufferOffset = 0;
  1656. ITERATOR_INIT( Iterator );
  1657. while( ITERATOR_GETNEXT( Iterator, pField ) )
  1658. {
  1659. //FormatFragment *FormatFragment = NULL;
  1660. unsigned long MemPad = pField->GetMemOffset() - BufferOffset;
  1661. if ( MemPad != 0 )
  1662. {
  1663. MIDL_NDR64_MEMPAD_FORMAT *pMemPadFormat =
  1664. new MIDL_NDR64_MEMPAD_FORMAT( MemPad );
  1665. pCompositeFormatFragment->AddFragment( pMemPadFormat );
  1666. }
  1667. BufferOffset += MemPad;
  1668. pCCB->SetLastPlaceholderClass( pField );
  1669. CG_NDR *pMember = (CG_NDR *) pField->GetChild();
  1670. // Embedded unknown represent as is not allowed.
  1671. MIDL_ASSERT( ! pField->HasEmbeddedUnknownRepAs() );
  1672. GenerateMember( pMember );
  1673. BufferOffset += pField->GetMemorySize();
  1674. }
  1675. // Account for padding at the end of the structure.
  1676. MIDL_ASSERT( pStruct->GetMemorySize() >= BufferOffset );
  1677. unsigned long EndingPad = pStruct->GetMemorySize() - BufferOffset;
  1678. if ( EndingPad )
  1679. {
  1680. MIDL_NDR64_MEMPAD_FORMAT *pMemPadFormat =
  1681. new MIDL_NDR64_MEMPAD_FORMAT( EndingPad );
  1682. pCompositeFormatFragment->AddFragment( pMemPadFormat );
  1683. }
  1684. FormatFragment* pEndFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_END );
  1685. pCompositeFormatFragment->AddFragment( pEndFormatFragment );
  1686. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  1687. }
  1688. //+--------------------------------------------------------------------------
  1689. //
  1690. // Method: GenNdr64Format::GenerateStructureMemberLayout( CG_STRUCT, bool )
  1691. //
  1692. // Synopsis: Wrapper for the member layout generator
  1693. //
  1694. //---------------------------------------------------------------------------
  1695. FormatFragment *GenNdr64Format::GenerateStructureMemberLayout( CG_STRUCT *pStruct, bool bIsDebug )
  1696. {
  1697. return StructureMemberGenerator::Generate( this, pStruct, bIsDebug );
  1698. }
  1699. //---------------------------------------------------------------------------
  1700. //
  1701. //
  1702. // Arrays
  1703. //
  1704. //
  1705. //
  1706. //---------------------------------------------------------------------------
  1707. FormatFragment *GenNdr64Format::GenerateArrayElementInfo( CG_CLASS *pChild )
  1708. {
  1709. CG_NDR *pNdr = dynamic_cast<CG_NDR*>( pChild );
  1710. MIDL_ASSERT( NULL != pNdr );
  1711. MIDL_NDR64_ARRAY_ELEMENT_INFO *pElementInfo =
  1712. new MIDL_NDR64_ARRAY_ELEMENT_INFO();
  1713. pElementInfo->ElementMemSize = pNdr->GetMemorySize();
  1714. pElementInfo->Element = (PNDR64_FORMAT)ContinueGenerationInRoot( pNdr );
  1715. return pElementInfo;
  1716. }
  1717. void GenNdr64Format::Visit( CG_FIXED_ARRAY *pArray )
  1718. {
  1719. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pArray );
  1720. GetCurrent()->AddFragment( pMainFragment );
  1721. FormatFragment *pMemberInfo = NULL;
  1722. FormatFragment *pPointerLayout = GenSimplePtrLayout( pArray );
  1723. if ( pCommand->NeedsNDR64DebugInfo() )
  1724. pMemberInfo = GenerateArrayElementInfo( pArray->GetChild() );
  1725. MIDL_NDR64_FIX_ARRAY_HEADER_FORMAT *pArrayFormat =
  1726. new MIDL_NDR64_FIX_ARRAY_HEADER_FORMAT( pArray );
  1727. memset( (NDR64_FIX_ARRAY_HEADER_FORMAT*)pArrayFormat,
  1728. 0,
  1729. sizeof(NDR64_FIX_ARRAY_HEADER_FORMAT*));
  1730. pArrayFormat->FormatCode = (NDR64_FORMAT_CHAR) FC64_FIX_ARRAY;
  1731. pArrayFormat->Alignment = ConvertAlignment( pArray->GetWireAlignment() );
  1732. pArrayFormat->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1733. pArrayFormat->Flags.HasElementInfo = (NULL != pMemberInfo );;
  1734. pArrayFormat->Reserved = 0;
  1735. pArrayFormat->TotalSize = pArray->GetMemorySize();
  1736. pMainFragment->AddFragment( pArrayFormat );
  1737. if ( pPointerLayout )
  1738. pMainFragment->AddFragment( pPointerLayout );
  1739. if ( pMemberInfo )
  1740. pMainFragment->AddFragment( pMemberInfo );
  1741. }
  1742. void GenNdr64Format::GenerateFixBogusArrayCommon( CG_FIXED_ARRAY *pArray, bool IsFullBogus )
  1743. {
  1744. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pArray );
  1745. GetCurrent()->AddFragment( pMainFragment );
  1746. CG_ILANALYSIS_INFO *pAnalysisInfo = pArray->GetILAnalysisInfo();
  1747. MIDL_NDR64_BOGUS_ARRAY_HEADER_FORMAT *pHeaderFragment =
  1748. new MIDL_NDR64_BOGUS_ARRAY_HEADER_FORMAT( pArray );
  1749. memset( (NDR64_BOGUS_ARRAY_HEADER_FORMAT*)pHeaderFragment,
  1750. 0,
  1751. sizeof(NDR64_BOGUS_ARRAY_HEADER_FORMAT));
  1752. pHeaderFragment->FormatCode = (NDR64_FORMAT_CHAR)
  1753. ( IsFullBogus ? FC64_FIX_BOGUS_ARRAY :
  1754. FC64_FIX_FORCED_BOGUS_ARRAY );
  1755. pHeaderFragment->Alignment = ConvertAlignment( ((CG_NDR*)pArray->GetChild())
  1756. ->GetWireAlignment() );
  1757. pHeaderFragment->Flags.HasPointerInfo = false;
  1758. pHeaderFragment->Flags.HasElementInfo = true;
  1759. pHeaderFragment->Flags.IsArrayofStrings = pAnalysisInfo->IsArrayofStrings();
  1760. pHeaderFragment->Flags.IsMultiDimensional = pAnalysisInfo->IsMultiDimensional();
  1761. pHeaderFragment->NumberDims = pAnalysisInfo->GetDimensions();
  1762. pHeaderFragment->NumberElements = pArray->GetNumOfElements();
  1763. pHeaderFragment->Element = (PNDR64_FORMAT)
  1764. ContinueGenerationInRoot( pArray->GetChild() );
  1765. pMainFragment->AddFragment( pHeaderFragment );
  1766. }
  1767. FormatFragment *
  1768. GenNdr64Format::GenerateNonStringQualifiedArrayLayout( CG_NDR *pNdr,
  1769. CompositeFormatFragment *pComp )
  1770. {
  1771. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pNdr );
  1772. pComp->AddFragment( pMainFragment );
  1773. FormatFragment *pHeaderFragment;
  1774. FormatFragment *pPointerLayout = NULL;
  1775. FormatFragment *pMemberInfo = NULL;
  1776. CG_ILANALYSIS_INFO *pAnalysisInfo = pNdr->GetILAnalysisInfo();
  1777. FormatInfoRef SizeIsDescriptor = INVALID_FRAGMENT_ID;
  1778. FormatInfoRef OffsetOfDescriptor = INVALID_FRAGMENT_ID;
  1779. FormatInfoRef LengthIsDescriptor = INVALID_FRAGMENT_ID;
  1780. if ( pAnalysisInfo->IsConformant() )
  1781. {
  1782. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE*>( pNdr );
  1783. expr_node *pSizeIs = pConfAttribute->GetSizeIsExpr();
  1784. if ( pSizeIs != NULL )
  1785. {
  1786. FormatFragment *pSizeIsFrag = GenerateCorrelationDescriptor( pSizeIs );
  1787. SizeIsDescriptor = pSizeIsFrag->GetRefID();
  1788. }
  1789. }
  1790. if ( pAnalysisInfo->IsVarying() )
  1791. {
  1792. CG_VARY_ATTRIBUTE *pVaryAttribute = dynamic_cast<CG_VARY_ATTRIBUTE*>( pNdr );
  1793. expr_node *pLengthIs = pVaryAttribute->GetLengthIsExpr();
  1794. if ( pLengthIs != NULL )
  1795. {
  1796. FormatFragment *pLengthIsFrag = GenerateCorrelationDescriptor( pLengthIs );
  1797. LengthIsDescriptor = pLengthIsFrag->GetRefID();
  1798. }
  1799. expr_node *pFirstIs = pVaryAttribute->GetFirstIsExpr();
  1800. if ( pFirstIs != NULL )
  1801. {
  1802. FormatFragment *pOffsetOfFrag = GenerateCorrelationDescriptor( pFirstIs );
  1803. OffsetOfDescriptor = pOffsetOfFrag->GetRefID();
  1804. }
  1805. }
  1806. if ( pAnalysisInfo->IsFullBogus() || pAnalysisInfo->IsForcedBogus() )
  1807. {
  1808. // treat like a bogus array
  1809. MIDL_NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT *pArrayHeader =
  1810. new MIDL_NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT( pNdr );
  1811. NDR64_BOGUS_ARRAY_HEADER_FORMAT *pFixedArrayHeader = &pArrayHeader->FixedArrayFormat;
  1812. pHeaderFragment = pArrayHeader;
  1813. bool bIsFullBogus = pAnalysisInfo->IsFullBogus();
  1814. NDR64_UINT32 NumberElements = 0;
  1815. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE *>( pNdr );
  1816. if ( !pAnalysisInfo->IsConformant() &&
  1817. pConfAttribute &&
  1818. pConfAttribute->GetSizeIsExpr() &&
  1819. pConfAttribute->GetSizeIsExpr()->IsConstant() )
  1820. {
  1821. NumberElements = (NDR64_UINT32)pConfAttribute->GetSizeIsExpr()->GetValue();
  1822. }
  1823. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>( pNdr->GetChild() );
  1824. memset( (NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1825. 0,
  1826. sizeof(NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT));
  1827. pFixedArrayHeader->FormatCode = (NDR64_FORMAT_CHAR)
  1828. ( bIsFullBogus ? FC64_BOGUS_ARRAY :
  1829. FC64_FORCED_BOGUS_ARRAY );
  1830. pFixedArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1831. pFixedArrayHeader->Flags.HasPointerInfo = false;
  1832. pFixedArrayHeader->Flags.HasElementInfo = true;
  1833. pFixedArrayHeader->Flags.IsArrayofStrings = pAnalysisInfo->IsArrayofStrings();
  1834. pFixedArrayHeader->Flags.IsMultiDimensional = pAnalysisInfo->IsMultiDimensional();
  1835. pFixedArrayHeader->NumberDims = pAnalysisInfo->GetDimensions();
  1836. pFixedArrayHeader->NumberElements = NumberElements;
  1837. pFixedArrayHeader->Element = (PNDR64_FORMAT)
  1838. ContinueGenerationInRoot( pChildNdr );
  1839. pArrayHeader->ConfDescription = (PNDR64_FORMAT)SizeIsDescriptor;
  1840. pArrayHeader->VarDescription = (PNDR64_FORMAT)LengthIsDescriptor;
  1841. pArrayHeader->OffsetDescription = (PNDR64_FORMAT)OffsetOfDescriptor;
  1842. }
  1843. else
  1844. {
  1845. pPointerLayout = GenSimplePtrLayout( pNdr );
  1846. if ( pCommand->NeedsNDR64DebugInfo() )
  1847. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1848. if ( !pAnalysisInfo->IsConformant() &&
  1849. pAnalysisInfo->IsVarying() )
  1850. {
  1851. MIDL_NDR64_VAR_ARRAY_HEADER_FORMAT *pArrayHeader =
  1852. new MIDL_NDR64_VAR_ARRAY_HEADER_FORMAT( pNdr );
  1853. pHeaderFragment = pArrayHeader;
  1854. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1855. memset( (NDR64_VAR_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1856. 0,
  1857. sizeof(NDR64_VAR_ARRAY_HEADER_FORMAT));
  1858. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_VAR_ARRAY;
  1859. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1860. pArrayHeader->Flags.HasPointerInfo = ( NULL != pPointerLayout );
  1861. pArrayHeader->Flags.HasElementInfo = ( NULL != pMemberInfo );
  1862. pArrayHeader->Reserved = 0;
  1863. pArrayHeader->TotalSize = pNdr->GetMemorySize();
  1864. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1865. pArrayHeader->VarDescriptor = (PNDR64_FORMAT)LengthIsDescriptor;
  1866. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1867. }
  1868. else if ( pAnalysisInfo->IsConformant() &&
  1869. !pAnalysisInfo->IsVarying() )
  1870. {
  1871. MIDL_NDR64_CONF_ARRAY_HEADER_FORMAT *pArrayHeader =
  1872. new MIDL_NDR64_CONF_ARRAY_HEADER_FORMAT( pNdr );
  1873. pHeaderFragment = pArrayHeader;
  1874. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1875. memset( (NDR64_CONF_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1876. 0,
  1877. sizeof(NDR64_CONF_ARRAY_HEADER_FORMAT));
  1878. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_CONF_ARRAY;
  1879. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1880. pArrayHeader->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1881. pArrayHeader->Flags.HasElementInfo = (NULL != pMemberInfo);
  1882. pArrayHeader->Reserved = 0;
  1883. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1884. pArrayHeader->ConfDescriptor = (PNDR64_FORMAT)SizeIsDescriptor;
  1885. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1886. }
  1887. else if ( pAnalysisInfo->IsConformant() &&
  1888. pAnalysisInfo->IsVarying() )
  1889. {
  1890. MIDL_NDR64_CONF_VAR_ARRAY_HEADER_FORMAT *pArrayHeader =
  1891. new MIDL_NDR64_CONF_VAR_ARRAY_HEADER_FORMAT( pNdr );
  1892. pHeaderFragment = pArrayHeader;
  1893. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1894. memset( (NDR64_CONF_VAR_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1895. 0,
  1896. sizeof(NDR64_CONF_VAR_ARRAY_HEADER_FORMAT));
  1897. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_CONFVAR_ARRAY;
  1898. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1899. pArrayHeader->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1900. pArrayHeader->Flags.HasElementInfo = (NULL != pMemberInfo);
  1901. pArrayHeader->Reserved = 0;
  1902. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1903. pArrayHeader->ConfDescriptor = (PNDR64_FORMAT)SizeIsDescriptor;
  1904. pArrayHeader->VarDescriptor = (PNDR64_FORMAT)LengthIsDescriptor;
  1905. }
  1906. else
  1907. {
  1908. // !pAnalysisInfo->IsConformant && !pAnalysisInfo->IsVarying
  1909. MIDL_ASSERT(0);
  1910. pHeaderFragment = NULL;
  1911. }
  1912. }
  1913. pMainFragment->AddFragment( pHeaderFragment );
  1914. if ( pPointerLayout )
  1915. pMainFragment->AddFragment( pPointerLayout );
  1916. if ( pMemberInfo )
  1917. pMainFragment->AddFragment( pMemberInfo );
  1918. return pMainFragment;
  1919. }
  1920. void GenNdr64Format::GenerateNonStringQualifiedArray( CG_ARRAY *pArray )
  1921. {
  1922. CompositeFormatFragment *pContainer;
  1923. MIDL_NDR64_POINTER_FORMAT* pPointerHdr = GenQualifiedArrayPtr( pArray );
  1924. if ( pPointerHdr != NULL)
  1925. {
  1926. GetCurrent()->AddFragment( pPointerHdr );
  1927. pContainer = GetRoot();
  1928. }
  1929. else
  1930. pContainer = GetCurrent();
  1931. FormatFragment *pArrayFragment =
  1932. GenerateNonStringQualifiedArrayLayout( pArray, pContainer );
  1933. if ( NULL != pPointerHdr )
  1934. {
  1935. pPointerHdr->Pointee = pArrayFragment->GetRefID();
  1936. }
  1937. }
  1938. void GenNdr64Format::InitStringHeader( CG_NDR *pString,
  1939. NDR64_STRING_HEADER_FORMAT *pHeader,
  1940. bool bIsConformant,
  1941. bool bIsSized )
  1942. {
  1943. NDR64_FORMAT_CHAR FormatCode;
  1944. CG_BASETYPE *pBT = dynamic_cast<CG_BASETYPE*>( pString->GetChild() );
  1945. if ( NULL != pBT )
  1946. {
  1947. switch( pBT->GetType()->GetBasicType()->NodeKind() )
  1948. {
  1949. case NODE_BYTE:
  1950. case NODE_CHAR:
  1951. FormatCode = (NDR64_FORMAT_CHAR)
  1952. ( bIsConformant ? FC64_CONF_CHAR_STRING : FC64_CHAR_STRING );
  1953. break;
  1954. case NODE_WCHAR_T:
  1955. FormatCode = (NDR64_FORMAT_CHAR)
  1956. ( bIsConformant ? FC64_CONF_WCHAR_STRING : FC64_WCHAR_STRING );
  1957. break;
  1958. default:
  1959. FormatCode = (NDR64_FORMAT_CHAR)
  1960. ( bIsConformant ? FC64_CONF_STRUCT_STRING : FC64_STRUCT_STRING );
  1961. break;
  1962. }
  1963. }
  1964. else
  1965. FormatCode = (NDR64_FORMAT_CHAR)
  1966. ( bIsConformant ? FC64_CONF_STRUCT_STRING : FC64_STRUCT_STRING );
  1967. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>( pString->GetChild() );
  1968. MIDL_ASSERT( pChildNdr->GetMemorySize() <= 0xFFFF );
  1969. NDR64_UINT16 ElementSize = (NDR64_UINT16)pChildNdr->GetMemorySize();
  1970. MIDL_ASSERT( (FC64_CHAR_STRING == FormatCode) ? (1 == ElementSize) : 1 );
  1971. MIDL_ASSERT( (FC64_WCHAR_STRING == FormatCode) ? (2 == ElementSize) : 1 );
  1972. memset( pHeader, 0, sizeof(NDR64_STRING_HEADER_FORMAT));
  1973. pHeader->FormatCode = FormatCode;
  1974. pHeader->Flags.IsSized = bIsSized;
  1975. pHeader->ElementSize = ElementSize;
  1976. }
  1977. void GenNdr64Format::GenerateStringArray( CG_ARRAY *pArray,
  1978. bool bIsSized )
  1979. {
  1980. MIDL_NDR64_POINTER_FORMAT* pPointerHdr = GenQualifiedArrayPtr( pArray );
  1981. if ( pPointerHdr != NULL)
  1982. GetCurrent()->AddFragment( pPointerHdr );
  1983. FormatFragment *pStringFrag = NULL;
  1984. if ( bIsSized )
  1985. {
  1986. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE*>( pArray );
  1987. expr_node *pSizeIs = pConfAttribute->GetSizeIsExpr();
  1988. if ( NULL != pSizeIs )
  1989. {
  1990. FormatFragment *pFrag = GenerateCorrelationDescriptor( pConfAttribute->GetSizeIsExpr() );
  1991. MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT *pSizedConfFormat =
  1992. new MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT( pArray );
  1993. pStringFrag = pSizedConfFormat;
  1994. InitStringHeader( pArray, &pSizedConfFormat->Header, true, true);
  1995. pSizedConfFormat->SizeDescription = (PNDR64_FORMAT)pFrag->GetRefID();
  1996. }
  1997. else
  1998. {
  1999. MIDL_NDR64_CONFORMANT_STRING_FORMAT *pConfFormat =
  2000. new MIDL_NDR64_CONFORMANT_STRING_FORMAT( pArray );
  2001. pStringFrag = pConfFormat;
  2002. InitStringHeader( pArray, &pConfFormat->Header, true, false);
  2003. }
  2004. }
  2005. else
  2006. {
  2007. MIDL_NDR64_NON_CONFORMANT_STRING_FORMAT *pNonConfFormat =
  2008. new MIDL_NDR64_NON_CONFORMANT_STRING_FORMAT( pArray );
  2009. pStringFrag = pNonConfFormat;
  2010. InitStringHeader( pArray, &pNonConfFormat->Header, false, false);
  2011. pNonConfFormat->TotalSize = pArray->GetMemorySize();
  2012. }
  2013. if ( NULL != pPointerHdr )
  2014. {
  2015. GetRoot()->AddFragment( pStringFrag );
  2016. pPointerHdr->Pointee = pStringFrag->GetRefID();
  2017. }
  2018. else
  2019. {
  2020. GetCurrent()->AddFragment( pStringFrag );
  2021. }
  2022. }
  2023. class ExpressionGenerator
  2024. {
  2025. public:
  2026. static CompositeFormatFragment *
  2027. Generate( CCB * pCCB,
  2028. expr_node * pSizeExpr
  2029. );
  2030. private:
  2031. static void
  2032. GenExprPadIfNecessary(
  2033. CompositeFormatFragment * FragmentList,
  2034. ulong * pExprLength,
  2035. ulong Align );
  2036. static FormatFragment *
  2037. GenExprConstant(
  2038. NDR64_FORMAT_CHARACTER fc,
  2039. EXPR_VALUE lValue,
  2040. CompositeFormatFragment * FragmentList,
  2041. ulong * pExprLength );
  2042. static BOOL
  2043. IsConstantExpr (expr_node * pExpr );
  2044. static NDR64_FORMAT_CHARACTER
  2045. GetTypeForExpression( node_skl *pType );
  2046. static FormatFragment *
  2047. GenExprFormatString(
  2048. CCB *pCCB,
  2049. expr_node *pSizeExpr,
  2050. CompositeFormatFragment *FragmentList,
  2051. BOOL * pIsEarly,
  2052. ulong * pExprLength );
  2053. static CG_FIELD*
  2054. FindField(
  2055. node_skl * pFieldType,
  2056. CG_STRUCT *pStruct,
  2057. const char *pPrintPrefix,
  2058. unsigned long *pMemOffset );
  2059. static void
  2060. ComputeFieldCorrelationOffset(
  2061. CCB *pCCB,
  2062. node_skl *pFieldType,
  2063. // return parameters
  2064. CG_FIELD **ppVariableField, // var in expression
  2065. long *pOffset,
  2066. BOOL *pIsEarly );
  2067. };
  2068. //+--------------------------------------------------------------------------
  2069. //
  2070. // Method: GenNdr64Format::GenerateCorrelationDescriptor
  2071. //
  2072. // Synopsis:
  2073. //
  2074. //---------------------------------------------------------------------------
  2075. FormatFragment*
  2076. GenNdr64Format::GenerateCorrelationDescriptor( expr_node *pExpr )
  2077. {
  2078. MIDL_ASSERT(NULL != pExpr);
  2079. FormatFragment *pCorrelationDescriptor =
  2080. ExpressionGenerator::Generate( pCCB, pExpr );
  2081. GetRoot()->AddFragment( pCorrelationDescriptor );
  2082. GetRoot()->OptimizeFragment( pCorrelationDescriptor );
  2083. return pCorrelationDescriptor;
  2084. }
  2085. //+--------------------------------------------------------------------------
  2086. //
  2087. // Method: Generate
  2088. //
  2089. // Synopsis: generate correlation expression.
  2090. //
  2091. //
  2092. //---------------------------------------------------------------------------
  2093. CompositeFormatFragment *
  2094. ExpressionGenerator::Generate( CCB * pCCB,
  2095. expr_node * pSizeExpr
  2096. )
  2097. {
  2098. if ( NULL == pSizeExpr )
  2099. return NULL ;
  2100. #if defined(DBG)
  2101. CG_CLASS *pAttributedNode = pCCB->GetLastPlaceholderClass( );
  2102. MIDL_ASSERT( ( NULL != dynamic_cast<CG_PARAM*>( pAttributedNode ) ) ||
  2103. ( NULL != dynamic_cast<CG_FIELD*>( pAttributedNode ) ) );
  2104. #endif
  2105. BOOL IsEarly = FALSE;
  2106. CompositeFormatFragment * pExprComposite = new CompositeFormatFragment;
  2107. MIDL_NDR_FORMAT_UINT32 * pFlag = new MIDL_NDR_FORMAT_UINT32;
  2108. ulong ulExprLength = 0;
  2109. // correlation flags. 4 bytes.
  2110. pExprComposite->AddFragment( pFlag );
  2111. ulExprLength = sizeof( NDR64_UINT32 );
  2112. // recursive code to generate the expression stack.
  2113. GenExprFormatString( pCCB, pSizeExpr, pExprComposite, &IsEarly, &ulExprLength );
  2114. pFlag->Data = 0;
  2115. if ( IsEarly )
  2116. pFlag->Data |= FC_NDR64_EARLY_CORRELATION;
  2117. return pExprComposite;
  2118. }
  2119. void
  2120. ExpressionGenerator::GenExprPadIfNecessary(
  2121. CompositeFormatFragment * FragmentList,
  2122. ulong * pExprLength,
  2123. ulong Align )
  2124. {
  2125. MIDL_NDR64_EXPR_NOOP * pExprPad = NULL;
  2126. if ( *pExprLength & ( Align - 1 ) )
  2127. {
  2128. // need to add padding to align next element
  2129. pExprPad = new MIDL_NDR64_EXPR_NOOP;
  2130. pExprPad->Size = (NDR64_UINT8) ( ( Align - 1 ) & *pExprLength );
  2131. FragmentList->AddFragment( pExprPad );
  2132. *pExprLength += sizeof( NDR64_EXPR_NOOP );
  2133. }
  2134. else
  2135. return;
  2136. }
  2137. FormatFragment *
  2138. ExpressionGenerator::GenExprConstant(
  2139. NDR64_FORMAT_CHARACTER fc,
  2140. EXPR_VALUE lValue,
  2141. CompositeFormatFragment * FragmentList,
  2142. ulong * pExprLength )
  2143. {
  2144. if ( fc == FC64_INT64 )
  2145. {
  2146. MIDL_NDR64_EXPR_CONST64 * pFormat;
  2147. pFormat = new MIDL_NDR64_EXPR_CONST64;
  2148. pFormat->ConstValue = lValue;
  2149. GenExprPadIfNecessary( FragmentList, pExprLength, 8 );
  2150. FragmentList->AddFragment( pFormat );
  2151. *pExprLength += sizeof( NDR64_EXPR_CONST64 );
  2152. return pFormat;
  2153. }
  2154. else
  2155. {
  2156. MIDL_NDR64_EXPR_CONST32 *pFormat;
  2157. pFormat = new MIDL_NDR64_EXPR_CONST32;
  2158. pFormat->ConstValue = (NDR64_UINT32) lValue;
  2159. GenExprPadIfNecessary( FragmentList, pExprLength, 4 );
  2160. FragmentList->AddFragment( pFormat );
  2161. *pExprLength += sizeof( NDR64_EXPR_CONST64 );
  2162. return pFormat;
  2163. }
  2164. }
  2165. // check if the expression (including all sub expressions ) is a constant expression
  2166. BOOL
  2167. ExpressionGenerator::IsConstantExpr (expr_node * pExpr )
  2168. {
  2169. if ( pExpr->IsConstant() )
  2170. return TRUE;
  2171. if ( pExpr->IsAVariable() )
  2172. return FALSE;
  2173. if ( pExpr->IsBinaryOperator() )
  2174. {
  2175. return IsConstantExpr( ((expr_op_binary *)pExpr)->GetLeft() ) &&
  2176. IsConstantExpr( ((expr_op_binary *)pExpr)->GetRight() );
  2177. }
  2178. else
  2179. {
  2180. if ( pExpr->IsUnaryOperator() )
  2181. {
  2182. return IsConstantExpr( ((expr_op_unary *)pExpr)->GetLeft() );
  2183. }
  2184. else
  2185. {
  2186. MIDL_ASSERT( ((expr_ternary *)pExpr)->GetRelational() != NULL );
  2187. return IsConstantExpr( ((expr_ternary *)pExpr)->GetLeft() ) &&
  2188. IsConstantExpr( ((expr_ternary *)pExpr)->GetRight() ) &&
  2189. IsConstantExpr( ((expr_ternary *)pExpr)->GetRelational() ) ;
  2190. }
  2191. }
  2192. }
  2193. NDR64_FORMAT_CHARACTER
  2194. ExpressionGenerator::GetTypeForExpression(
  2195. node_skl *pType
  2196. )
  2197. {
  2198. // Get the size of the type.
  2199. unsigned long Size = pType->GetSize();
  2200. // determine if the type is signed or unsigned.
  2201. bool IsSigned = true;
  2202. node_base_type *pBaseType = dynamic_cast<node_base_type*>( pType->GetBasicType() );
  2203. if ( pBaseType )
  2204. {
  2205. IsSigned = !pBaseType->IsUnsigned();
  2206. }
  2207. switch ( Size )
  2208. {
  2209. case 1:
  2210. return IsSigned ? FC64_INT8 : FC64_UINT8;
  2211. case 2:
  2212. return IsSigned ? FC64_INT16 : FC64_UINT16;
  2213. case 4:
  2214. return IsSigned ? FC64_INT32 : FC64_UINT32;
  2215. case 8:
  2216. return IsSigned ? FC64_INT64 : FC64_UINT64;
  2217. default:
  2218. RpcError( NULL, 0, EXPR_NOT_EVALUATABLE, pType->GetSymName() );
  2219. return FC64_ZERO; // Keep the compiler happy
  2220. }
  2221. }
  2222. FormatFragment *
  2223. ExpressionGenerator::GenExprFormatString(
  2224. CCB *pCCB,
  2225. expr_node *pSizeExpr,
  2226. CompositeFormatFragment *FragmentList,
  2227. BOOL * pIsEarly,
  2228. ulong * pExprLength )
  2229. {
  2230. node_skl * pAttributeNodeType;
  2231. EXPR_TOKEN Op;
  2232. long Offset;
  2233. CG_PARAM * pParam = NULL;
  2234. CG_NDR * pSwitchNode = NULL;
  2235. // BUGBUG: how to generate 32bit constant?
  2236. if ( IsConstantExpr( pSizeExpr ) )
  2237. {
  2238. // Constant expressions are always early!
  2239. *pIsEarly = TRUE;
  2240. return GenExprConstant( FC64_INT64, pSizeExpr->GetValue(), FragmentList, pExprLength );
  2241. }
  2242. if ( pSizeExpr->IsAVariable() )
  2243. // variable
  2244. {
  2245. Op = FC_EXPR_VAR;
  2246. MIDL_NDR64_EXPR_VAR * pFormat;
  2247. CG_NDR * pNdr = pCCB->GetCGNodeContext();
  2248. CG_ITERATOR Iterator;
  2249. pAttributeNodeType = pSizeExpr->GetType();
  2250. if ( pNdr->IsProc() )
  2251. // top level param
  2252. {
  2253. CG_PARAM* pCurrentParam = (CG_PARAM*) pCCB->GetCurrentParam();
  2254. CG_PROC* pCurrentProc = (CG_PROC*) pNdr;
  2255. *pIsEarly = TRUE;
  2256. if ( ( (node_param *) pAttributeNodeType )->IsSaveForAsyncFinish() &&
  2257. pCurrentProc->IsFinishProc() )
  2258. {
  2259. // This is an async split where the finish proc is using
  2260. // a param from the begin proc. Since the parameter
  2261. // was stored on the split stack, the expression will
  2262. // always be early correlation. So all that is needed
  2263. // here is to find the parameter in the begin proc.
  2264. CG_PROC* pBeginProc = pCurrentProc->GetAsyncRelative();
  2265. pBeginProc->GetMembers( Iterator );
  2266. for (;;)
  2267. {
  2268. if (!ITERATOR_GETNEXT( Iterator, pParam ))
  2269. {
  2270. // Didn't find the parameter. We are in trouble!
  2271. MIDL_ASSERT(0);
  2272. return NULL;
  2273. }
  2274. if ( pParam->GetType() == pAttributeNodeType )
  2275. {
  2276. break;
  2277. }
  2278. }
  2279. }
  2280. else
  2281. {
  2282. // Typical case of correlation in the same parameter.
  2283. pCurrentProc->GetMembers( Iterator);
  2284. if ( pCurrentParam->GetType() == pAttributeNodeType )
  2285. *pIsEarly = FALSE;
  2286. for(;;)
  2287. {
  2288. if (!ITERATOR_GETNEXT( Iterator, pParam ))
  2289. {
  2290. // Didn't find the parameter. We are in trouble!
  2291. MIDL_ASSERT(0);
  2292. return NULL;
  2293. }
  2294. // If we find the current parameter before the variable,
  2295. // parameter, then late correlation is needed.
  2296. if ( pParam == pCurrentParam )
  2297. *pIsEarly = FALSE;
  2298. if ( pParam->GetType() == pAttributeNodeType )
  2299. break;
  2300. }
  2301. }
  2302. pSwitchNode = (CG_NDR *) pParam->GetChild();
  2303. }
  2304. else
  2305. // structure /union etc.
  2306. {
  2307. CG_FIELD *pSwitchField;
  2308. ComputeFieldCorrelationOffset( pCCB,
  2309. pAttributeNodeType,
  2310. // return parameters
  2311. &pSwitchField,
  2312. &Offset,
  2313. pIsEarly );
  2314. pSwitchNode = (CG_NDR*)pSwitchField->GetChild();
  2315. }
  2316. // Code the type of the size_is etc. expression.
  2317. NDR64_FORMAT_CHARACTER Type = GetTypeForExpression( pSwitchNode->GetType() );
  2318. pAttributeNodeType = pSizeExpr->GetType();
  2319. pFormat = new MIDL_NDR64_EXPR_VAR;
  2320. pFormat->ExprType = FC_EXPR_VAR;
  2321. pFormat->VarType = (NDR64_UINT8)Type;
  2322. if ( pNdr->IsProc() )
  2323. {
  2324. CG_NDR* pOld = 0;
  2325. BOOL IsFinish = FALSE;
  2326. MIDL_NDR64_EXPR_OPERATOR * pAsyncOp;
  2327. if ( ( (node_param *) pAttributeNodeType )->IsSaveForAsyncFinish() )
  2328. {
  2329. pAsyncOp = new MIDL_NDR64_EXPR_OPERATOR;
  2330. if ( ( (CG_PROC *)pNdr )->IsFinishProc() )
  2331. {
  2332. pOld = pCCB->SetCGNodeContext( ( (CG_PROC *)pNdr )->GetAsyncRelative() );
  2333. IsFinish = TRUE;
  2334. }
  2335. pAsyncOp->ExprType = (NDR64_FORMAT_CHAR) FC_EXPR_OPER;
  2336. pAsyncOp->Operator = (NDR64_FORMAT_CHAR) OP_ASYNCSPLIT;
  2337. FragmentList->AddFragment( pAsyncOp );
  2338. *pExprLength += sizeof( NDR64_EXPR_OPERATOR );
  2339. }
  2340. pFormat->fStackOffset = TRUE;
  2341. pFormat->ia64Offset = pParam->GetStackOffset( pCCB, I386_STACK_SIZING );
  2342. if ( IsFinish )
  2343. pCCB->SetCGNodeContext( pOld );
  2344. }
  2345. else
  2346. {
  2347. // Structure
  2348. pFormat->fStackOffset = FALSE;
  2349. pFormat->Offset = Offset;
  2350. }
  2351. GenExprPadIfNecessary( FragmentList, pExprLength, 4 );
  2352. FragmentList->AddFragment( pFormat );
  2353. *pExprLength += sizeof( NDR64_EXPR_VAR );
  2354. return pFormat;
  2355. }
  2356. else
  2357. // operator
  2358. {
  2359. expr_node * pLeftExpr = NULL;
  2360. BOOL bLeftExprIsEarly = TRUE;
  2361. expr_node * pRightExpr = NULL;
  2362. BOOL bRightExprIsEarly = TRUE;
  2363. expr_node * pRationalExpr = NULL;
  2364. BOOL bRationalExprIsEarly = TRUE;
  2365. MIDL_NDR64_EXPR_OPERATOR *pFormat;
  2366. NDR64_FORMAT_CHARACTER fcKind = (NDR64_FORMAT_CHARACTER)0;
  2367. OPERATOR Operator ;
  2368. if ( pSizeExpr->IsBinaryOperator() )
  2369. {
  2370. Operator = ((expr_op_binary *)pSizeExpr)->GetOperator();
  2371. pLeftExpr = ((expr_op_binary *)pSizeExpr)->GetLeft();
  2372. pRightExpr = ((expr_op_binary *)pSizeExpr)->GetRight();
  2373. }
  2374. else
  2375. {
  2376. if ( pSizeExpr->IsUnaryOperator() )
  2377. {
  2378. Operator = ((expr_op_unary *)pSizeExpr)->GetOperator();
  2379. pLeftExpr = ((expr_op_unary *)pSizeExpr)->GetLeft();
  2380. }
  2381. else
  2382. {
  2383. Operator = ((expr_ternary *)pSizeExpr)->GetOperator();
  2384. pLeftExpr = ((expr_ternary *)pSizeExpr)->GetLeft();
  2385. pRightExpr = ((expr_ternary *)pSizeExpr)->GetRight();
  2386. pRationalExpr = ((expr_ternary *)pSizeExpr)->GetRelational();
  2387. }
  2388. }
  2389. switch ( Operator )
  2390. {
  2391. case OP_UNARY_SIZEOF:
  2392. EXPR_VALUE lSize;
  2393. lSize = pSizeExpr->GetType()->GetSize();
  2394. *pIsEarly = TRUE;
  2395. return GenExprConstant( FC64_INT8, lSize, FragmentList, pExprLength);
  2396. case OP_UNARY_CAST:
  2397. case OP_UNARY_INDIRECTION:
  2398. fcKind = GetTypeForExpression( pSizeExpr->GetType() );
  2399. break;
  2400. }
  2401. pFormat = new MIDL_NDR64_EXPR_OPERATOR;
  2402. pFormat->ExprType = (NDR64_FORMAT_CHAR) FC_EXPR_OPER;
  2403. pFormat->Operator = (NDR64_FORMAT_CHAR) Operator;
  2404. // This was initially 0
  2405. pFormat->CastType = (NDR64_FORMAT_CHAR) fcKind;
  2406. FragmentList->AddFragment( pFormat );
  2407. *pExprLength += sizeof( NDR64_EXPR_OPERATOR );
  2408. GenExprFormatString( pCCB, pLeftExpr, FragmentList, &bLeftExprIsEarly, pExprLength );
  2409. if ( pRightExpr )
  2410. GenExprFormatString( pCCB, pRightExpr, FragmentList, &bRightExprIsEarly, pExprLength );
  2411. if ( pRationalExpr )
  2412. GenExprFormatString( pCCB, pRationalExpr, FragmentList, &bRationalExprIsEarly, pExprLength );
  2413. //
  2414. // An operator is early if and only if all the arguments to the
  2415. // operator are early.
  2416. //
  2417. *pIsEarly = bLeftExprIsEarly && bRightExprIsEarly && bRationalExprIsEarly;
  2418. return pFormat;
  2419. }
  2420. }
  2421. CG_FIELD*
  2422. ExpressionGenerator::FindField(
  2423. node_skl * pFieldType,
  2424. CG_STRUCT *pStruct,
  2425. const char *pPrintPrefix,
  2426. unsigned long *pMemOffset )
  2427. {
  2428. CG_ITERATOR Iterator;
  2429. pStruct->GetMembers( Iterator );
  2430. ITERATOR_INIT( Iterator );
  2431. CG_FIELD *pField;
  2432. while ( ITERATOR_GETNEXT( Iterator, pField ) )
  2433. {
  2434. // First check if the fields are the same type. If they
  2435. // are, then check the print prefixes to make sure the fields came
  2436. // from the same structure.
  2437. if ( ( pField->GetType() == pFieldType ) &&
  2438. ( strcmp( pField->GetPrintPrefix(), pPrintPrefix ) == 0 ) )
  2439. {
  2440. *pMemOffset = pField->GetMemOffset();
  2441. return pField;
  2442. }
  2443. CG_CLASS * pChildClass = pField->GetChild();
  2444. if ( pChildClass->IsStruct() )
  2445. {
  2446. unsigned long TempMemOffset;
  2447. CG_STRUCT *pChildStruct = (CG_STRUCT*)pChildClass;
  2448. CG_FIELD *pTempField = FindField( pFieldType,
  2449. pChildStruct,
  2450. pPrintPrefix,
  2451. &TempMemOffset );
  2452. if ( NULL != pTempField )
  2453. {
  2454. *pMemOffset = TempMemOffset + pField->GetMemOffset();
  2455. return pTempField;
  2456. }
  2457. }
  2458. }
  2459. return NULL;
  2460. }
  2461. void
  2462. ExpressionGenerator::ComputeFieldCorrelationOffset(
  2463. CCB *pCCB,
  2464. node_skl *pFieldType,
  2465. // return parameters
  2466. CG_FIELD **ppVariableField, // var in expression
  2467. long *pOffset,
  2468. BOOL *pIsEarly )
  2469. {
  2470. //
  2471. // Find the fields.
  2472. //
  2473. CG_FIELD *pCurrentField = dynamic_cast<CG_FIELD*>( pCCB->GetLastPlaceholderClass() );
  2474. MIDL_ASSERT( NULL != pCurrentField );
  2475. const char *pPrintPrefix = pCurrentField->GetPrintPrefix();
  2476. CG_STRUCT *pContext = dynamic_cast<CG_STRUCT*>( pCCB->GetCGNodeContext() );
  2477. MIDL_ASSERT( NULL != pContext );
  2478. unsigned long VariableOffset;
  2479. CG_FIELD* pVariableField = FindField( pFieldType,
  2480. pContext,
  2481. pPrintPrefix,
  2482. &VariableOffset );
  2483. MIDL_ASSERT( NULL != pVariableField );
  2484. *ppVariableField = pVariableField;
  2485. unsigned long CurrentOffset;
  2486. CG_FIELD* pAlsoCurrentField = FindField( pCurrentField->GetType(),
  2487. pContext,
  2488. pPrintPrefix,
  2489. &CurrentOffset );
  2490. pAlsoCurrentField;
  2491. MIDL_ASSERT( pAlsoCurrentField == pCurrentField );
  2492. //
  2493. // Determine the correlation type.
  2494. // The correlation type is early if the variable field will
  2495. // be completely marshalled before the current field.
  2496. //
  2497. BOOL bVariableIsPointer = pVariableField->GetChild()->IsPointer();
  2498. BOOL bCurrentFieldIsPointer = pCurrentField->GetChild()->IsPointer();
  2499. BOOL bOnlyVariableIsPointer = bVariableIsPointer && !bCurrentFieldIsPointer;
  2500. *pIsEarly = ( CurrentOffset > VariableOffset ) && !bOnlyVariableIsPointer;
  2501. // In the land of the new transfer syntax, all offsets are a positive offset
  2502. // from the start of the stack or the last structure/region that was passed.
  2503. CG_FIELD *pRegionField = pCCB->GetCurrentRegionField();
  2504. // Make offset relative to start of region
  2505. if (NULL != pRegionField)
  2506. VariableOffset -= pRegionField->GetMemOffset();
  2507. *pOffset = VariableOffset;
  2508. }
  2509. //+--------------------------------------------------------------------------
  2510. //
  2511. // Method: GenNdr64Format::Visit( CG_TRANSMIT_AS )
  2512. //
  2513. // Synopsis: Generate info for transmit_as types
  2514. //
  2515. //---------------------------------------------------------------------------
  2516. void GenNdr64Format::Visit( CG_TRANSMIT_AS *pTransmitAs )
  2517. {
  2518. MIDL_NDR64_TRANSMIT_AS_FORMAT *format;
  2519. format = new MIDL_NDR64_TRANSMIT_AS_FORMAT( pTransmitAs );
  2520. GetCurrent()->AddFragment( format );
  2521. GenXmitOrRepAsFormat(
  2522. pTransmitAs,
  2523. format,
  2524. pTransmitAs->GetPresentedType()->GetSymName(),
  2525. pTransmitAs->GetPresentedType(),
  2526. pTransmitAs->GetTransmittedType() );
  2527. }
  2528. //+--------------------------------------------------------------------------
  2529. //
  2530. // Method: GenNdr64Format::Visit( CG_REPRESENT_AS )
  2531. //
  2532. // Synopsis: Generate info for represent_as types
  2533. //
  2534. //---------------------------------------------------------------------------
  2535. void GenNdr64Format::Visit( CG_REPRESENT_AS *pRepresentAs )
  2536. {
  2537. MIDL_NDR64_REPRESENT_AS_FORMAT *format;
  2538. format = new MIDL_NDR64_REPRESENT_AS_FORMAT( pRepresentAs );
  2539. GetCurrent()->AddFragment( format );
  2540. GenXmitOrRepAsFormat(
  2541. pRepresentAs,
  2542. format,
  2543. pRepresentAs->GetRepAsTypeName(),
  2544. pRepresentAs->GetRepAsType(),
  2545. pRepresentAs->GetTransmittedType() );
  2546. }
  2547. //+--------------------------------------------------------------------------
  2548. //
  2549. // Method: GenNdr64Format::GenXmitOrRepAsFormat
  2550. //
  2551. // Synopsis: Do the actual work for transmit_as and represent_as types
  2552. //
  2553. //---------------------------------------------------------------------------
  2554. void GenNdr64Format::GenXmitOrRepAsFormat(
  2555. CG_TYPEDEF *pXmitNode,
  2556. MIDL_NDR64_TRANSMIT_AS_FORMAT *format,
  2557. char *pPresentedTypeName,
  2558. node_skl *pPresentedType,
  2559. node_skl *pTransmittedType )
  2560. {
  2561. CG_NDR *pChild = (CG_NDR *) pXmitNode->GetChild();
  2562. BOOL fXmit = ( NULL == dynamic_cast<CG_REPRESENT_AS *>(pXmitNode) );
  2563. NDR64_UINT16 RoutineIndex = pXmitNode->GenXmitOrRepAsQuintuple(
  2564. pCCB,
  2565. fXmit,
  2566. pXmitNode,
  2567. pPresentedTypeName,
  2568. (fXmit ? pPresentedType
  2569. : pTransmittedType) );
  2570. format->FormatCode = (NDR64_FORMAT_CHAR) ( fXmit ? FC64_TRANSMIT_AS : FC64_REPRESENT_AS );
  2571. format->RoutineIndex = RoutineIndex;
  2572. format->TransmittedTypeWireAlignment = (NDR64_UINT16) ( pChild->GetWireAlignment() - 1 );
  2573. // REVIEW: The spec doesn't say whether "MemoryAlignment" is the
  2574. // presented type or the transmitted type. Transmitted doesn't
  2575. // make much sense but on the other hand presented has some
  2576. // alignment flags already.
  2577. format->MemoryAlignment = pXmitNode->GetMemoryAlignment();
  2578. if ( pPresentedType )
  2579. format->PresentedTypeMemorySize = (NDR64_UINT16) pPresentedType->GetSize();
  2580. else
  2581. MIDL_ASSERT(!"BUGBUG: unknown rep/transmit_as");
  2582. if ( pChild->HasAFixedBufferSize() )
  2583. format->TransmittedTypeBufferSize = (NDR64_UINT16) pChild->GetWireSize();
  2584. else
  2585. format->TransmittedTypeBufferSize = 0;
  2586. format->Flags.PresentedTypeIsArray = 0;
  2587. format->Flags.PresentedTypeAlign4 = 0;
  2588. format->Flags.PresentedTypeAlign8 = 0;
  2589. format->Flags.Reserved = 0;
  2590. if ( pPresentedType )
  2591. {
  2592. if ( pPresentedType->GetBasicType()->NodeKind() == NODE_ARRAY )
  2593. format->Flags.PresentedTypeIsArray = 1;
  2594. else
  2595. {
  2596. if ( pXmitNode->GetMemoryAlignment() == 4 )
  2597. format->Flags.PresentedTypeAlign4 = 1;
  2598. else if ( pXmitNode->GetMemoryAlignment() == 8 )
  2599. format->Flags.PresentedTypeAlign8 = 1;
  2600. }
  2601. }
  2602. if ( pChild->GetCGID() == ID_CG_GENERIC_HDL )
  2603. pChild = (CG_NDR *)pChild->GetChild();
  2604. format->TransmittedType = ContinueGenerationInRoot( pChild );
  2605. }
  2606. //+--------------------------------------------------------------------------
  2607. //
  2608. // Method: GenNdr64Format::Visit( CG_USER_MARSHAL )
  2609. //
  2610. // Synopsis: Generate info for user_marshal types
  2611. //
  2612. // REVIEW: user_marshall and represent_as are so close to one another
  2613. // they really should probably be merged
  2614. //
  2615. //---------------------------------------------------------------------------
  2616. void GenNdr64Format::Visit( CG_USER_MARSHAL *pUserMarshal )
  2617. {
  2618. MIDL_NDR64_USER_MARSHAL_FORMAT *format;
  2619. format = new MIDL_NDR64_USER_MARSHAL_FORMAT( pUserMarshal );
  2620. GetCurrent()->AddFragment( format );
  2621. CG_NDR *pChild = (CG_NDR *) pUserMarshal->GetChild();
  2622. format->FormatCode = FC64_USER_MARSHAL;
  2623. format->TransmittedTypeWireAlignment = (NDR64_UINT16) (pChild->GetWireAlignment() - 1);
  2624. format->MemoryAlignment = pChild->GetMemoryAlignment();
  2625. memset( &format->Flags, 0, sizeof(format->Flags) );
  2626. if ( pChild->IsPointer() )
  2627. {
  2628. CG_POINTER *pPointer = (CG_POINTER *) pChild;
  2629. MIDL_ASSERT( ! pPointer->IsFull() );
  2630. if ( pPointer->IsUnique() )
  2631. format->Flags.UniquePointer = 1;
  2632. else if ( pPointer->IsRef() )
  2633. format->Flags.RefPointer = 1;
  2634. }
  2635. format->Flags.IID = 0; // Only used by JIT compiler
  2636. format->Flags.Reserved = 0;
  2637. USER_MARSHAL_CONTEXT * pUserMarshalContext = new USER_MARSHAL_CONTEXT;
  2638. pUserMarshalContext->pTypeName = pUserMarshal->GetRepAsTypeName();
  2639. pUserMarshalContext->pType = pUserMarshal->GetRepAsType();
  2640. BOOL Added = pCCB->GetQuadrupleDictionary()->Add( pUserMarshalContext );
  2641. format->RoutineIndex = pUserMarshalContext->Index;
  2642. if ( !Added )
  2643. delete pUserMarshalContext;
  2644. if ( pUserMarshal->GetRepAsType() )
  2645. format->UserTypeMemorySize = pUserMarshal->GetRepAsType()->GetSize();
  2646. else
  2647. MIDL_ASSERT( !"BUGBUG: undefined user_marshal" );
  2648. if ( pChild->HasAFixedBufferSize() )
  2649. format->TransmittedTypeBufferSize = pChild->GetWireSize();
  2650. else
  2651. format->TransmittedTypeBufferSize = 0;
  2652. format->TransmittedType = ContinueGenerationInRoot( pChild );
  2653. }
  2654. //+--------------------------------------------------------------------------
  2655. //
  2656. // Method: GenNdr64Format::Visit( CG_PIPE )
  2657. //
  2658. // Synopsis: Generate info for [pipe] types
  2659. //
  2660. //---------------------------------------------------------------------------
  2661. void GenNdr64Format::Visit( CG_PIPE *pPipe )
  2662. {
  2663. pCommand->GetNdrVersionControl().SetHasRawPipes();
  2664. MIDL_NDR64_PIPE_FORMAT *format = new MIDL_NDR64_PIPE_FORMAT( pPipe );
  2665. GetCurrent()->AddFragment( format );
  2666. CG_NDR *pChild = (CG_NDR *) pPipe->GetChild();
  2667. NDR64_UINT32 BufferSize = 0;
  2668. node_range_attr *range = pPipe->GetRangeAttribute();
  2669. NDR64_UINT32 MinValue = 0;
  2670. NDR64_UINT32 MaxValue = 0;
  2671. CG_ILANALYSIS_INFO *pAnalysisInfo = pChild->GetILAnalysisInfo();
  2672. if ( pChild->HasAFixedBufferSize() )
  2673. BufferSize = pChild->GetWireSize();
  2674. if ( range )
  2675. {
  2676. MinValue = (NDR64_UINT32) range->GetMinExpr()->GetValue();
  2677. MaxValue = (NDR64_UINT32) range->GetMaxExpr()->GetValue();
  2678. }
  2679. format->FormatCode = FC64_PIPE;
  2680. format->Flags.Reserved1 = 0;
  2681. format->Flags.HasRange = (bool) ( NULL != range );
  2682. format->Flags.BlockCopy = !pAnalysisInfo->IsForcedBogus() && !pAnalysisInfo->IsFullBogus();
  2683. format->Flags.Reserved2 = 0;
  2684. format->Alignment = (NDR64_UINT8) ( pChild->GetWireAlignment() - 1 );
  2685. format->Reserved = 0;
  2686. format->Type = ContinueGenerationInRoot( pChild );
  2687. format->MemorySize = pChild->GetMemorySize();
  2688. format->BufferSize = BufferSize;
  2689. format->MinValue = MinValue;
  2690. format->MaxValue = MaxValue;
  2691. }
  2692. //+--------------------------------------------------------------------------
  2693. //
  2694. // Method: OutputParamFlagDescription
  2695. //
  2696. // Synopsis: Output a description string for the ndr64 param flags
  2697. //
  2698. //---------------------------------------------------------------------------
  2699. void OutputParamFlagDescription( CCB *pCCB, const NDR64_PARAM_FLAGS &flags )
  2700. {
  2701. static const PNAME flag_descrip[16] =
  2702. {
  2703. "MustSize",
  2704. "MustFree",
  2705. "pipe",
  2706. "[in]",
  2707. "[out]",
  2708. "IsReturn",
  2709. "Basetype",
  2710. "ByValue",
  2711. "SimpleRef",
  2712. "DontFreeInst",
  2713. "AsyncFinish",
  2714. NULL,
  2715. NULL,
  2716. NULL,
  2717. NULL,
  2718. "UseCache"
  2719. };
  2720. pCCB->GetStream()->Write( " " );
  2721. OutputFlagDescriptions( pCCB->GetStream(), &flags, sizeof(flags), flag_descrip );
  2722. }
  2723. //+--------------------------------------------------------------------------
  2724. //
  2725. // Method: OutputFlagDescription
  2726. //
  2727. // Synopsis: Given a set of flags and a description for each flags,
  2728. // output the corresponding description for flag that is set.
  2729. // usused flags can be marked with a NULL description.
  2730. //
  2731. // Notes: Assumes little-endian memory layout!
  2732. //
  2733. //---------------------------------------------------------------------------
  2734. void OutputFlagDescriptions(
  2735. ISTREAM *stream,
  2736. const void *pvFlags,
  2737. int bytes,
  2738. const PNAME *description)
  2739. {
  2740. unsigned char *flags = (unsigned char *) pvFlags;
  2741. bool first = true;
  2742. stream->Write( "/*");
  2743. for (int i = 0; i < (bytes * 8); i++)
  2744. {
  2745. if ( ( NULL == description[i] )
  2746. || ( 0 == ( flags[i / 8] & ( 1 << (i % 8) ) ) ) )
  2747. {
  2748. continue;
  2749. }
  2750. if ( !first )
  2751. stream->Write( "," );
  2752. first = false;
  2753. stream->Write( " " );
  2754. stream->Write( description[i] );
  2755. }
  2756. stream->Write( " */" );
  2757. }