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

3591 lines
114 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 *pChildFragment = GetCurrent()->GetParent()->LookupFragment( pChild );
  683. MIDL_ASSERT( NULL != pChildFragment );
  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*>(pChildFragment);
  690. format->Type = pPointerFrag->Pointee;
  691. }
  692. else
  693. {
  694. format->Type = pChildFragment->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. CG_FIELD *pField;
  1392. ITERATOR_INIT( Iterator );
  1393. while ( ITERATOR_GETNEXT( Iterator, pField ) )
  1394. {
  1395. CG_NDR * pOldPlaceHolder = pCCB->SetLastPlaceholderClass( pField );
  1396. CG_CLASS *pMember = (CG_NDR *) pField->GetChild();
  1397. if ( pMember->IsPointer() )
  1398. {
  1399. if (NULL == pCompositeFormatFragment)
  1400. pCompositeFormatFragment = new CompositeFormatFragment();
  1401. ContinueGeneration( pMember, pCompositeFormatFragment );
  1402. }
  1403. pCCB->SetLastPlaceholderClass( pOldPlaceHolder );
  1404. }
  1405. return pCompositeFormatFragment;
  1406. }
  1407. //+--------------------------------------------------------------------------
  1408. //
  1409. // Method: GenNdr64Format::GenerateSimpleStructure( CG_STRUCT, bool )
  1410. //
  1411. // Synopsis: Generate the format string for a simple structure.
  1412. //
  1413. //---------------------------------------------------------------------------
  1414. void GenNdr64Format::GenerateSimpleStructure( CG_STRUCT *pStruct,
  1415. bool IsConformant )
  1416. {
  1417. // Add the fragment right away so recursive structure definitions
  1418. // are caught
  1419. CompositeFormatFragment *pMainFragment
  1420. = new CompositeFormatFragment( pStruct );
  1421. GetCurrent()->AddFragment( pMainFragment );
  1422. CG_FIELD *pOldRegionField = NULL;
  1423. CG_NDR *pOldContext = NULL;
  1424. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1425. pOldRegionField = pCCB->StartRegion();
  1426. else
  1427. pOldContext = pCCB->SetCGNodeContext( pStruct );
  1428. FormatFragment* pMemberLayout = NULL;
  1429. FormatFragment* pPointerLayout = GenSimplePtrLayout( pStruct );
  1430. if ( pCommand->NeedsNDR64DebugInfo() )
  1431. pMemberLayout = GenerateStructureMemberLayout( pStruct, true );
  1432. if ( IsConformant )
  1433. {
  1434. CG_CONFORMANT_STRUCT *pConfStruct = dynamic_cast<CG_CONFORMANT_STRUCT*>( pStruct );
  1435. CG_FIELD *pConfField = dynamic_cast<CG_FIELD*>( pConfStruct->GetConformantField() );
  1436. MIDL_ASSERT( NULL != pConfField );
  1437. CG_ARRAY *pConfArray = dynamic_cast<CG_ARRAY*>( pConfField->GetChild() );
  1438. MIDL_ASSERT( NULL != pConfArray );
  1439. CG_NDR * pOldPlaceholder = GetCCB()->SetLastPlaceholderClass( pConfField );
  1440. FormatFragment *pHeader =
  1441. new MIDL_NDR64_CONF_STRUCTURE_HEADER_FORMAT( pConfStruct,
  1442. NULL != pPointerLayout,
  1443. NULL != pMemberLayout,
  1444. ContinueGenerationInRoot( pConfArray ) );
  1445. pMainFragment->AddFragment( pHeader );
  1446. GetCCB()->SetLastPlaceholderClass( pOldPlaceholder );
  1447. }
  1448. else
  1449. {
  1450. FormatFragment *pHeader =
  1451. new MIDL_NDR64_STRUCTURE_HEADER_FORMAT( pStruct,
  1452. NULL != pPointerLayout,
  1453. NULL != pMemberLayout );
  1454. pMainFragment->AddFragment( pHeader );
  1455. }
  1456. if ( NULL != pPointerLayout ) pMainFragment->AddFragment( pPointerLayout );
  1457. if ( NULL != pMemberLayout ) pMainFragment->AddFragment( pMemberLayout );
  1458. if ( dynamic_cast<CG_REGION*>( pStruct ) )
  1459. pCCB->EndRegion( pOldRegionField );
  1460. else
  1461. pCCB->SetCGNodeContext( pOldContext );
  1462. GetRoot()->OptimizeFragment( pMainFragment );
  1463. }
  1464. //+--------------------------------------------------------------------------
  1465. //
  1466. // Method: GenNdr64Format::GenerateComplexStruct( CG_STRUCT, bool )
  1467. //
  1468. // Synopsis: Generate the format string for a complex structure.
  1469. //
  1470. //---------------------------------------------------------------------------
  1471. void GenNdr64Format::GenerateComplexStruct( CG_COMPLEX_STRUCT *pStruct,
  1472. bool IsConformant )
  1473. {
  1474. if ( GetCurrent()->HasClassFragment( pStruct ) )
  1475. return;
  1476. // This must be done first to handle recurion.
  1477. CompositeFormatFragment *pMainFragment =
  1478. new CompositeFormatFragment( pStruct );
  1479. GetCurrent()->AddFragment( pMainFragment );
  1480. CG_NDR *pOldContext = pCCB->SetCGNodeContext( pStruct );
  1481. FormatInfoRef ArrayID = INVALID_FRAGMENT_ID;
  1482. CG_ARRAY *pConfArray = NULL;
  1483. if ( IsConformant )
  1484. {
  1485. CG_FIELD *pConfField = dynamic_cast<CG_FIELD*>( pStruct->GetConformantField() );
  1486. MIDL_ASSERT( NULL != pConfField );
  1487. pConfArray = dynamic_cast<CG_ARRAY*>( pConfField->GetChild() );
  1488. MIDL_ASSERT( NULL != pConfArray );
  1489. CG_NDR * pOldPlaceholder = GetCCB()->SetLastPlaceholderClass( pConfField );
  1490. ArrayID = ContinueGenerationInRoot( pConfArray );
  1491. GetCCB()->SetLastPlaceholderClass( pOldPlaceholder );
  1492. }
  1493. FormatInfoRef PointerID = INVALID_FRAGMENT_ID;
  1494. FormatFragment *pPointerLayout = GenCmplxPtrLayout( pStruct );
  1495. if ( NULL != pPointerLayout )
  1496. {
  1497. // Pointer Layout for complex struct goes in the root fragment.
  1498. PointerID = GetRoot()->AddFragment( pPointerLayout );
  1499. }
  1500. FormatFragment* pMemberLayout = GenerateStructureMemberLayout( pStruct, false );
  1501. // The only difference between the member layout with debugging
  1502. // and without debugging is that simple region become complex regions
  1503. // with member layouts.
  1504. FormatInfoRef DebugPointerID = INVALID_FRAGMENT_ID;
  1505. FormatInfoRef DebugMemberLayoutID = INVALID_FRAGMENT_ID;
  1506. if ( pCommand->NeedsNDR64DebugInfo() )
  1507. {
  1508. DebugPointerID = PointerID;
  1509. FormatFragment *pDebugMemberLayout = GenerateStructureMemberLayout( pStruct, true );
  1510. DebugMemberLayoutID = GetRoot()->AddFragment( pDebugMemberLayout );
  1511. }
  1512. FormatFragment* pHeader;
  1513. if ( IsConformant )
  1514. {
  1515. MIDL_ASSERT( NULL != pConfArray );
  1516. pHeader = new MIDL_NDR64_CONF_BOGUS_STRUCTURE_HEADER_FORMAT( pStruct,
  1517. pConfArray,
  1518. ArrayID,
  1519. DebugMemberLayoutID,
  1520. DebugPointerID,
  1521. PointerID );
  1522. }
  1523. else
  1524. {
  1525. pHeader = new MIDL_NDR64_BOGUS_STRUCTURE_HEADER_FORMAT( pStruct,
  1526. DebugMemberLayoutID,
  1527. DebugPointerID,
  1528. PointerID );
  1529. }
  1530. pMainFragment->AddFragment( pHeader );
  1531. pMainFragment->AddFragment( pMemberLayout );
  1532. pCCB->SetCGNodeContext( pOldContext );
  1533. }
  1534. //+--------------------------------------------------------------------------
  1535. //
  1536. // Class: StructureMemberGenerator
  1537. //
  1538. // Synopsis: This object is responsible for generating the member layout
  1539. // of a structure.
  1540. //
  1541. //---------------------------------------------------------------------------
  1542. class StructureMemberGenerator
  1543. {
  1544. private:
  1545. GenNdr64Format *pMainGenerator;
  1546. CompositeFormatFragment *pCompositeFormatFragment;
  1547. CG_VISITOR *pVisitor;
  1548. bool bIsDebug;
  1549. void StartGeneration( CG_STRUCT *pStruct );
  1550. void GenerateMember( CG_CLASS *pClass )
  1551. {
  1552. pClass->Visit( pVisitor );
  1553. }
  1554. public:
  1555. static FormatFragment* Generate( GenNdr64Format *pMainGenerator,
  1556. CG_STRUCT *pStruct,
  1557. bool bIsDebug )
  1558. {
  1559. CG_VISITOR_TEMPLATE<StructureMemberGenerator> TemplateVisitor;
  1560. StructureMemberGenerator & Visitor = TemplateVisitor;
  1561. Visitor.pMainGenerator = pMainGenerator;
  1562. Visitor.pCompositeFormatFragment = new CompositeFormatFragment();
  1563. Visitor.pVisitor = &TemplateVisitor;
  1564. Visitor.bIsDebug = bIsDebug;
  1565. Visitor.StartGeneration( pStruct );
  1566. return Visitor.pCompositeFormatFragment;
  1567. }
  1568. // Items that get a unique member layout item.
  1569. void Visit( CG_POINTER *pPointer)
  1570. {
  1571. pPointer;
  1572. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_POINTER );
  1573. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1574. }
  1575. void Visit( CG_IGNORED_POINTER *pPointer )
  1576. {
  1577. pPointer;
  1578. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_IGNORE );
  1579. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1580. }
  1581. void Visit( CG_BASETYPE *pBaseType )
  1582. {
  1583. if ( pBaseType->GetRangeAttribute() != NULL )
  1584. {
  1585. // Send to generic catch all case(Embedded complex)
  1586. Visit( (CG_CLASS*) pBaseType );
  1587. return;
  1588. }
  1589. NDR64_FORMAT_CHAR FormatCode = (NDR64_FORMAT_CHAR)pBaseType->GetNDR64FormatChar();
  1590. FormatFragment *pFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FormatCode );
  1591. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1592. }
  1593. void Visit( CG_SIMPLE_REGION *pSimpleRegion )
  1594. {
  1595. // If this member layout is for debugging, send this
  1596. // to the CG_CLASS visit function to create an
  1597. // embedded complex.
  1598. if ( bIsDebug )
  1599. {
  1600. Visit( (CG_CLASS*)pSimpleRegion );
  1601. return;
  1602. }
  1603. FormatFragment *pFormatFragment =
  1604. new MIDL_NDR64_SIMPLE_REGION_FORMAT( pSimpleRegion );
  1605. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1606. }
  1607. void Visit( CG_PAD *pPad )
  1608. {
  1609. FormatFragment *pFormatFragment
  1610. = new MIDL_NDR64_BUFFER_ALIGN_FORMAT( pPad );
  1611. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1612. }
  1613. // Do nothing for conformant arrays. They must be at the end.
  1614. void Visit( CG_CONFORMANT_ARRAY *pConfArray ) { pConfArray; }
  1615. void Visit( CG_CONFORMANT_VARYING_ARRAY *pConfVaryArray ) { pConfVaryArray; }
  1616. void Visit( CG_CONFORMANT_STRING_ARRAY *pConfStringArray ) { pConfStringArray; }
  1617. // Catch all case. Generates embedded complex
  1618. void Visit( CG_CLASS *pClass )
  1619. {
  1620. FormatInfoRef ID = pMainGenerator->ContinueGenerationInRoot( pClass );
  1621. FormatFragment *pFormatFragment = new MIDL_NDR64_EMBEDDED_COMPLEX_FORMAT( ID );
  1622. pCompositeFormatFragment->AddFragment( pFormatFragment );
  1623. }
  1624. };
  1625. void StructureMemberGenerator::StartGeneration( CG_STRUCT *pStruct )
  1626. {
  1627. CCB *pCCB = pMainGenerator->GetCCB();
  1628. CG_NDR * pOldPlaceholder = pCCB->GetLastPlaceholderClass();
  1629. CG_ITERATOR Iterator;
  1630. pStruct->GetMembers( Iterator );
  1631. CG_FIELD * pField;
  1632. unsigned long BufferOffset = 0;
  1633. ITERATOR_INIT( Iterator );
  1634. while( ITERATOR_GETNEXT( Iterator, pField ) )
  1635. {
  1636. //FormatFragment *FormatFragment = NULL;
  1637. unsigned long MemPad = pField->GetMemOffset() - BufferOffset;
  1638. if ( MemPad != 0 )
  1639. {
  1640. MIDL_NDR64_MEMPAD_FORMAT *pMemPadFormat =
  1641. new MIDL_NDR64_MEMPAD_FORMAT( MemPad );
  1642. pCompositeFormatFragment->AddFragment( pMemPadFormat );
  1643. }
  1644. BufferOffset += MemPad;
  1645. pCCB->SetLastPlaceholderClass( pField );
  1646. CG_NDR *pMember = (CG_NDR *) pField->GetChild();
  1647. // Embedded unknown represent as is not allowed.
  1648. MIDL_ASSERT( ! pField->HasEmbeddedUnknownRepAs() );
  1649. GenerateMember( pMember );
  1650. BufferOffset += pField->GetMemorySize();
  1651. }
  1652. // Account for padding at the end of the structure.
  1653. MIDL_ASSERT( pStruct->GetMemorySize() >= BufferOffset );
  1654. unsigned long EndingPad = pStruct->GetMemorySize() - BufferOffset;
  1655. if ( EndingPad )
  1656. {
  1657. MIDL_NDR64_MEMPAD_FORMAT *pMemPadFormat =
  1658. new MIDL_NDR64_MEMPAD_FORMAT( EndingPad );
  1659. pCompositeFormatFragment->AddFragment( pMemPadFormat );
  1660. }
  1661. FormatFragment* pEndFormatFragment = new MIDL_NDR64_SIMPLE_MEMBER_FORMAT( FC64_END );
  1662. pCompositeFormatFragment->AddFragment( pEndFormatFragment );
  1663. pCCB->SetLastPlaceholderClass( pOldPlaceholder );
  1664. }
  1665. //+--------------------------------------------------------------------------
  1666. //
  1667. // Method: GenNdr64Format::GenerateStructureMemberLayout( CG_STRUCT, bool )
  1668. //
  1669. // Synopsis: Wrapper for the member layout generator
  1670. //
  1671. //---------------------------------------------------------------------------
  1672. FormatFragment *GenNdr64Format::GenerateStructureMemberLayout( CG_STRUCT *pStruct, bool bIsDebug )
  1673. {
  1674. return StructureMemberGenerator::Generate( this, pStruct, bIsDebug );
  1675. }
  1676. //---------------------------------------------------------------------------
  1677. //
  1678. //
  1679. // Arrays
  1680. //
  1681. //
  1682. //
  1683. //---------------------------------------------------------------------------
  1684. FormatFragment *GenNdr64Format::GenerateArrayElementInfo( CG_CLASS *pChild )
  1685. {
  1686. CG_NDR *pNdr = dynamic_cast<CG_NDR*>( pChild );
  1687. MIDL_ASSERT( NULL != pNdr );
  1688. MIDL_NDR64_ARRAY_ELEMENT_INFO *pElementInfo =
  1689. new MIDL_NDR64_ARRAY_ELEMENT_INFO();
  1690. pElementInfo->ElementMemSize = pNdr->GetMemorySize();
  1691. pElementInfo->Element = (PNDR64_FORMAT)ContinueGenerationInRoot( pNdr );
  1692. return pElementInfo;
  1693. }
  1694. void GenNdr64Format::Visit( CG_FIXED_ARRAY *pArray )
  1695. {
  1696. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pArray );
  1697. GetCurrent()->AddFragment( pMainFragment );
  1698. FormatFragment *pMemberInfo = NULL;
  1699. FormatFragment *pPointerLayout = GenSimplePtrLayout( pArray );
  1700. if ( pCommand->NeedsNDR64DebugInfo() )
  1701. pMemberInfo = GenerateArrayElementInfo( pArray->GetChild() );
  1702. MIDL_NDR64_FIX_ARRAY_HEADER_FORMAT *pArrayFormat =
  1703. new MIDL_NDR64_FIX_ARRAY_HEADER_FORMAT( pArray );
  1704. memset( (NDR64_FIX_ARRAY_HEADER_FORMAT*)pArrayFormat,
  1705. 0,
  1706. sizeof(NDR64_FIX_ARRAY_HEADER_FORMAT*));
  1707. pArrayFormat->FormatCode = (NDR64_FORMAT_CHAR) FC64_FIX_ARRAY;
  1708. pArrayFormat->Alignment = ConvertAlignment( pArray->GetWireAlignment() );
  1709. pArrayFormat->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1710. pArrayFormat->Flags.HasElementInfo = (NULL != pMemberInfo );;
  1711. pArrayFormat->Reserved = 0;
  1712. pArrayFormat->TotalSize = pArray->GetMemorySize();
  1713. pMainFragment->AddFragment( pArrayFormat );
  1714. if ( pPointerLayout )
  1715. pMainFragment->AddFragment( pPointerLayout );
  1716. if ( pMemberInfo )
  1717. pMainFragment->AddFragment( pMemberInfo );
  1718. }
  1719. void GenNdr64Format::GenerateFixBogusArrayCommon( CG_FIXED_ARRAY *pArray, bool IsFullBogus )
  1720. {
  1721. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pArray );
  1722. GetCurrent()->AddFragment( pMainFragment );
  1723. CG_ILANALYSIS_INFO *pAnalysisInfo = pArray->GetILAnalysisInfo();
  1724. MIDL_NDR64_BOGUS_ARRAY_HEADER_FORMAT *pHeaderFragment =
  1725. new MIDL_NDR64_BOGUS_ARRAY_HEADER_FORMAT( pArray );
  1726. memset( (NDR64_BOGUS_ARRAY_HEADER_FORMAT*)pHeaderFragment,
  1727. 0,
  1728. sizeof(NDR64_BOGUS_ARRAY_HEADER_FORMAT));
  1729. pHeaderFragment->FormatCode = (NDR64_FORMAT_CHAR)
  1730. ( IsFullBogus ? FC64_FIX_BOGUS_ARRAY :
  1731. FC64_FIX_FORCED_BOGUS_ARRAY );
  1732. pHeaderFragment->Alignment = ConvertAlignment( ((CG_NDR*)pArray->GetChild())
  1733. ->GetWireAlignment() );
  1734. pHeaderFragment->Flags.HasPointerInfo = false;
  1735. pHeaderFragment->Flags.HasElementInfo = true;
  1736. pHeaderFragment->Flags.IsArrayofStrings = pAnalysisInfo->IsArrayofStrings();
  1737. pHeaderFragment->Flags.IsMultiDimensional = pAnalysisInfo->IsMultiDimensional();
  1738. pHeaderFragment->NumberDims = pAnalysisInfo->GetDimensions();
  1739. pHeaderFragment->NumberElements = pArray->GetNumOfElements();
  1740. pHeaderFragment->Element = (PNDR64_FORMAT)
  1741. ContinueGenerationInRoot( pArray->GetChild() );
  1742. pMainFragment->AddFragment( pHeaderFragment );
  1743. }
  1744. FormatFragment *
  1745. GenNdr64Format::GenerateNonStringQualifiedArrayLayout( CG_NDR *pNdr,
  1746. CompositeFormatFragment *pComp )
  1747. {
  1748. CompositeFormatFragment *pMainFragment = new CompositeFormatFragment( pNdr );
  1749. pComp->AddFragment( pMainFragment );
  1750. FormatFragment *pHeaderFragment;
  1751. FormatFragment *pPointerLayout = NULL;
  1752. FormatFragment *pMemberInfo = NULL;
  1753. CG_ILANALYSIS_INFO *pAnalysisInfo = pNdr->GetILAnalysisInfo();
  1754. FormatInfoRef SizeIsDescriptor = INVALID_FRAGMENT_ID;
  1755. FormatInfoRef OffsetOfDescriptor = INVALID_FRAGMENT_ID;
  1756. FormatInfoRef LengthIsDescriptor = INVALID_FRAGMENT_ID;
  1757. if ( pAnalysisInfo->IsConformant() )
  1758. {
  1759. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE*>( pNdr );
  1760. expr_node *pSizeIs = pConfAttribute->GetSizeIsExpr();
  1761. if ( pSizeIs != NULL )
  1762. {
  1763. FormatFragment *pSizeIsFrag = GenerateCorrelationDescriptor( pSizeIs );
  1764. SizeIsDescriptor = pSizeIsFrag->GetRefID();
  1765. }
  1766. }
  1767. if ( pAnalysisInfo->IsVarying() )
  1768. {
  1769. CG_VARY_ATTRIBUTE *pVaryAttribute = dynamic_cast<CG_VARY_ATTRIBUTE*>( pNdr );
  1770. expr_node *pLengthIs = pVaryAttribute->GetLengthIsExpr();
  1771. if ( pLengthIs != NULL )
  1772. {
  1773. FormatFragment *pLengthIsFrag = GenerateCorrelationDescriptor( pLengthIs );
  1774. LengthIsDescriptor = pLengthIsFrag->GetRefID();
  1775. }
  1776. expr_node *pFirstIs = pVaryAttribute->GetFirstIsExpr();
  1777. if ( pFirstIs != NULL )
  1778. {
  1779. FormatFragment *pOffsetOfFrag = GenerateCorrelationDescriptor( pFirstIs );
  1780. OffsetOfDescriptor = pOffsetOfFrag->GetRefID();
  1781. }
  1782. }
  1783. if ( pAnalysisInfo->IsFullBogus() || pAnalysisInfo->IsForcedBogus() )
  1784. {
  1785. // treat like a bogus array
  1786. MIDL_NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT *pArrayHeader =
  1787. new MIDL_NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT( pNdr );
  1788. NDR64_BOGUS_ARRAY_HEADER_FORMAT *pFixedArrayHeader = &pArrayHeader->FixedArrayFormat;
  1789. pHeaderFragment = pArrayHeader;
  1790. bool bIsFullBogus = pAnalysisInfo->IsFullBogus();
  1791. NDR64_UINT32 NumberElements = 0;
  1792. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE *>( pNdr );
  1793. if ( !pAnalysisInfo->IsConformant() &&
  1794. pConfAttribute &&
  1795. pConfAttribute->GetSizeIsExpr() &&
  1796. pConfAttribute->GetSizeIsExpr()->IsConstant() )
  1797. {
  1798. NumberElements = (NDR64_UINT32)pConfAttribute->GetSizeIsExpr()->GetValue();
  1799. }
  1800. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>( pNdr->GetChild() );
  1801. memset( (NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1802. 0,
  1803. sizeof(NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT));
  1804. pFixedArrayHeader->FormatCode = (NDR64_FORMAT_CHAR)
  1805. ( bIsFullBogus ? FC64_BOGUS_ARRAY :
  1806. FC64_FORCED_BOGUS_ARRAY );
  1807. pFixedArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1808. pFixedArrayHeader->Flags.HasPointerInfo = false;
  1809. pFixedArrayHeader->Flags.HasElementInfo = true;
  1810. pFixedArrayHeader->Flags.IsArrayofStrings = pAnalysisInfo->IsArrayofStrings();
  1811. pFixedArrayHeader->Flags.IsMultiDimensional = pAnalysisInfo->IsMultiDimensional();
  1812. pFixedArrayHeader->NumberDims = pAnalysisInfo->GetDimensions();
  1813. pFixedArrayHeader->NumberElements = NumberElements;
  1814. pFixedArrayHeader->Element = (PNDR64_FORMAT)
  1815. ContinueGenerationInRoot( pChildNdr );
  1816. pArrayHeader->ConfDescription = (PNDR64_FORMAT)SizeIsDescriptor;
  1817. pArrayHeader->VarDescription = (PNDR64_FORMAT)LengthIsDescriptor;
  1818. pArrayHeader->OffsetDescription = (PNDR64_FORMAT)OffsetOfDescriptor;
  1819. }
  1820. else
  1821. {
  1822. pPointerLayout = GenSimplePtrLayout( pNdr );
  1823. if ( pCommand->NeedsNDR64DebugInfo() )
  1824. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1825. if ( !pAnalysisInfo->IsConformant() &&
  1826. pAnalysisInfo->IsVarying() )
  1827. {
  1828. MIDL_NDR64_VAR_ARRAY_HEADER_FORMAT *pArrayHeader =
  1829. new MIDL_NDR64_VAR_ARRAY_HEADER_FORMAT( pNdr );
  1830. pHeaderFragment = pArrayHeader;
  1831. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1832. memset( (NDR64_VAR_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1833. 0,
  1834. sizeof(NDR64_VAR_ARRAY_HEADER_FORMAT));
  1835. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_VAR_ARRAY;
  1836. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1837. pArrayHeader->Flags.HasPointerInfo = ( NULL != pPointerLayout );
  1838. pArrayHeader->Flags.HasElementInfo = ( NULL != pMemberInfo );
  1839. pArrayHeader->Reserved = 0;
  1840. pArrayHeader->TotalSize = pNdr->GetMemorySize();
  1841. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1842. pArrayHeader->VarDescriptor = (PNDR64_FORMAT)LengthIsDescriptor;
  1843. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1844. }
  1845. else if ( pAnalysisInfo->IsConformant() &&
  1846. !pAnalysisInfo->IsVarying() )
  1847. {
  1848. MIDL_NDR64_CONF_ARRAY_HEADER_FORMAT *pArrayHeader =
  1849. new MIDL_NDR64_CONF_ARRAY_HEADER_FORMAT( pNdr );
  1850. pHeaderFragment = pArrayHeader;
  1851. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1852. memset( (NDR64_CONF_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1853. 0,
  1854. sizeof(NDR64_CONF_ARRAY_HEADER_FORMAT));
  1855. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_CONF_ARRAY;
  1856. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1857. pArrayHeader->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1858. pArrayHeader->Flags.HasElementInfo = (NULL != pMemberInfo);
  1859. pArrayHeader->Reserved = 0;
  1860. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1861. pArrayHeader->ConfDescriptor = (PNDR64_FORMAT)SizeIsDescriptor;
  1862. pMemberInfo = GenerateArrayElementInfo( pNdr->GetChild() );
  1863. }
  1864. else if ( pAnalysisInfo->IsConformant() &&
  1865. pAnalysisInfo->IsVarying() )
  1866. {
  1867. MIDL_NDR64_CONF_VAR_ARRAY_HEADER_FORMAT *pArrayHeader =
  1868. new MIDL_NDR64_CONF_VAR_ARRAY_HEADER_FORMAT( pNdr );
  1869. pHeaderFragment = pArrayHeader;
  1870. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>(pNdr->GetChild());
  1871. memset( (NDR64_CONF_VAR_ARRAY_HEADER_FORMAT*)pArrayHeader,
  1872. 0,
  1873. sizeof(NDR64_CONF_VAR_ARRAY_HEADER_FORMAT));
  1874. pArrayHeader->FormatCode = (NDR64_FORMAT_CHAR) FC64_CONFVAR_ARRAY;
  1875. pArrayHeader->Alignment = ConvertAlignment( pChildNdr->GetWireAlignment() );
  1876. pArrayHeader->Flags.HasPointerInfo = (NULL != pPointerLayout);
  1877. pArrayHeader->Flags.HasElementInfo = (NULL != pMemberInfo);
  1878. pArrayHeader->Reserved = 0;
  1879. pArrayHeader->ElementSize = pChildNdr->GetMemorySize();
  1880. pArrayHeader->ConfDescriptor = (PNDR64_FORMAT)SizeIsDescriptor;
  1881. pArrayHeader->VarDescriptor = (PNDR64_FORMAT)LengthIsDescriptor;
  1882. }
  1883. else
  1884. {
  1885. // !pAnalysisInfo->IsConformant && !pAnalysisInfo->IsVarying
  1886. MIDL_ASSERT(0);
  1887. pHeaderFragment = NULL;
  1888. }
  1889. }
  1890. pMainFragment->AddFragment( pHeaderFragment );
  1891. if ( pPointerLayout )
  1892. pMainFragment->AddFragment( pPointerLayout );
  1893. if ( pMemberInfo )
  1894. pMainFragment->AddFragment( pMemberInfo );
  1895. return pMainFragment;
  1896. }
  1897. void GenNdr64Format::GenerateNonStringQualifiedArray( CG_ARRAY *pArray )
  1898. {
  1899. CompositeFormatFragment *pContainer;
  1900. MIDL_NDR64_POINTER_FORMAT* pPointerHdr = GenQualifiedArrayPtr( pArray );
  1901. if ( pPointerHdr != NULL)
  1902. {
  1903. GetCurrent()->AddFragment( pPointerHdr );
  1904. pContainer = GetRoot();
  1905. }
  1906. else
  1907. pContainer = GetCurrent();
  1908. FormatFragment *pArrayFragment =
  1909. GenerateNonStringQualifiedArrayLayout( pArray, pContainer );
  1910. if ( NULL != pPointerHdr )
  1911. {
  1912. pPointerHdr->Pointee = pArrayFragment->GetRefID();
  1913. }
  1914. }
  1915. void GenNdr64Format::InitStringHeader( CG_NDR *pString,
  1916. NDR64_STRING_HEADER_FORMAT *pHeader,
  1917. bool bIsConformant,
  1918. bool bIsSized )
  1919. {
  1920. NDR64_FORMAT_CHAR FormatCode;
  1921. CG_BASETYPE *pBT = dynamic_cast<CG_BASETYPE*>( pString->GetChild() );
  1922. if ( NULL != pBT )
  1923. {
  1924. switch( pBT->GetType()->GetBasicType()->NodeKind() )
  1925. {
  1926. case NODE_BYTE:
  1927. case NODE_CHAR:
  1928. FormatCode = (NDR64_FORMAT_CHAR)
  1929. ( bIsConformant ? FC64_CONF_CHAR_STRING : FC64_CHAR_STRING );
  1930. break;
  1931. case NODE_WCHAR_T:
  1932. FormatCode = (NDR64_FORMAT_CHAR)
  1933. ( bIsConformant ? FC64_CONF_WCHAR_STRING : FC64_WCHAR_STRING );
  1934. break;
  1935. default:
  1936. FormatCode = (NDR64_FORMAT_CHAR)
  1937. ( bIsConformant ? FC64_CONF_STRUCT_STRING : FC64_STRUCT_STRING );
  1938. break;
  1939. }
  1940. }
  1941. else
  1942. FormatCode = (NDR64_FORMAT_CHAR)
  1943. ( bIsConformant ? FC64_CONF_STRUCT_STRING : FC64_STRUCT_STRING );
  1944. CG_NDR *pChildNdr = dynamic_cast<CG_NDR*>( pString->GetChild() );
  1945. MIDL_ASSERT( pChildNdr->GetMemorySize() <= 0xFFFF );
  1946. NDR64_UINT16 ElementSize = (NDR64_UINT16)pChildNdr->GetMemorySize();
  1947. MIDL_ASSERT( (FC64_CHAR_STRING == FormatCode) ? (1 == ElementSize) : 1 );
  1948. MIDL_ASSERT( (FC64_WCHAR_STRING == FormatCode) ? (2 == ElementSize) : 1 );
  1949. memset( pHeader, 0, sizeof(NDR64_STRING_HEADER_FORMAT));
  1950. pHeader->FormatCode = FormatCode;
  1951. pHeader->Flags.IsSized = bIsSized;
  1952. pHeader->ElementSize = ElementSize;
  1953. }
  1954. void GenNdr64Format::GenerateStringArray( CG_ARRAY *pArray,
  1955. bool bIsSized )
  1956. {
  1957. MIDL_NDR64_POINTER_FORMAT* pPointerHdr = GenQualifiedArrayPtr( pArray );
  1958. if ( pPointerHdr != NULL)
  1959. GetCurrent()->AddFragment( pPointerHdr );
  1960. FormatFragment *pStringFrag = NULL;
  1961. if ( bIsSized )
  1962. {
  1963. CG_CONF_ATTRIBUTE *pConfAttribute = dynamic_cast<CG_CONF_ATTRIBUTE*>( pArray );
  1964. expr_node *pSizeIs = pConfAttribute->GetSizeIsExpr();
  1965. if ( NULL != pSizeIs )
  1966. {
  1967. FormatFragment *pFrag = GenerateCorrelationDescriptor( pConfAttribute->GetSizeIsExpr() );
  1968. MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT *pSizedConfFormat =
  1969. new MIDL_NDR64_SIZED_CONFORMANT_STRING_FORMAT( pArray );
  1970. pStringFrag = pSizedConfFormat;
  1971. InitStringHeader( pArray, &pSizedConfFormat->Header, true, true);
  1972. pSizedConfFormat->SizeDescription = (PNDR64_FORMAT)pFrag->GetRefID();
  1973. }
  1974. else
  1975. {
  1976. MIDL_NDR64_CONFORMANT_STRING_FORMAT *pConfFormat =
  1977. new MIDL_NDR64_CONFORMANT_STRING_FORMAT( pArray );
  1978. pStringFrag = pConfFormat;
  1979. InitStringHeader( pArray, &pConfFormat->Header, true, false);
  1980. }
  1981. }
  1982. else
  1983. {
  1984. MIDL_NDR64_NON_CONFORMANT_STRING_FORMAT *pNonConfFormat =
  1985. new MIDL_NDR64_NON_CONFORMANT_STRING_FORMAT( pArray );
  1986. pStringFrag = pNonConfFormat;
  1987. InitStringHeader( pArray, &pNonConfFormat->Header, false, false);
  1988. pNonConfFormat->TotalSize = pArray->GetMemorySize();
  1989. }
  1990. if ( NULL != pPointerHdr )
  1991. {
  1992. GetRoot()->AddFragment( pStringFrag );
  1993. pPointerHdr->Pointee = pStringFrag->GetRefID();
  1994. }
  1995. else
  1996. {
  1997. GetCurrent()->AddFragment( pStringFrag );
  1998. }
  1999. }
  2000. class ExpressionGenerator
  2001. {
  2002. public:
  2003. static CompositeFormatFragment *
  2004. Generate( CCB * pCCB,
  2005. expr_node * pSizeExpr
  2006. );
  2007. private:
  2008. static void
  2009. GenExprPadIfNecessary(
  2010. CompositeFormatFragment * FragmentList,
  2011. ulong * pExprLength,
  2012. ulong Align );
  2013. static FormatFragment *
  2014. GenExprConstant(
  2015. NDR64_FORMAT_CHARACTER fc,
  2016. EXPR_VALUE lValue,
  2017. CompositeFormatFragment * FragmentList,
  2018. ulong * pExprLength );
  2019. static BOOL
  2020. IsConstantExpr (expr_node * pExpr );
  2021. static NDR64_FORMAT_CHARACTER
  2022. GetTypeForExpression( node_skl *pType );
  2023. static FormatFragment *
  2024. GenExprFormatString(
  2025. CCB *pCCB,
  2026. expr_node *pSizeExpr,
  2027. CompositeFormatFragment *FragmentList,
  2028. BOOL * pIsEarly,
  2029. ulong * pExprLength );
  2030. static CG_FIELD*
  2031. FindField(
  2032. node_skl * pFieldType,
  2033. CG_STRUCT *pStruct,
  2034. const char *pPrintPrefix,
  2035. unsigned long *pMemOffset );
  2036. static void
  2037. ComputeFieldCorrelationOffset(
  2038. CCB *pCCB,
  2039. node_skl *pFieldType,
  2040. // return parameters
  2041. CG_FIELD **ppVariableField, // var in expression
  2042. long *pOffset,
  2043. BOOL *pIsEarly );
  2044. };
  2045. //+--------------------------------------------------------------------------
  2046. //
  2047. // Method: GenNdr64Format::GenerateCorrelationDescriptor
  2048. //
  2049. // Synopsis:
  2050. //
  2051. //---------------------------------------------------------------------------
  2052. FormatFragment*
  2053. GenNdr64Format::GenerateCorrelationDescriptor( expr_node *pExpr )
  2054. {
  2055. MIDL_ASSERT(NULL != pExpr);
  2056. FormatFragment *pCorrelationDescriptor =
  2057. ExpressionGenerator::Generate( pCCB, pExpr );
  2058. GetRoot()->AddFragment( pCorrelationDescriptor );
  2059. GetRoot()->OptimizeFragment( pCorrelationDescriptor );
  2060. return pCorrelationDescriptor;
  2061. }
  2062. //+--------------------------------------------------------------------------
  2063. //
  2064. // Method: Generate
  2065. //
  2066. // Synopsis: generate correlation expression.
  2067. //
  2068. //
  2069. //---------------------------------------------------------------------------
  2070. CompositeFormatFragment *
  2071. ExpressionGenerator::Generate( CCB * pCCB,
  2072. expr_node * pSizeExpr
  2073. )
  2074. {
  2075. if ( NULL == pSizeExpr )
  2076. return NULL ;
  2077. #if defined(DBG)
  2078. CG_CLASS *pAttributedNode = pCCB->GetLastPlaceholderClass( );
  2079. MIDL_ASSERT( ( NULL != dynamic_cast<CG_PARAM*>( pAttributedNode ) ) ||
  2080. ( NULL != dynamic_cast<CG_FIELD*>( pAttributedNode ) ) );
  2081. #endif
  2082. BOOL IsEarly = FALSE;
  2083. CompositeFormatFragment * pExprComposite = new CompositeFormatFragment;
  2084. MIDL_NDR_FORMAT_UINT32 * pFlag = new MIDL_NDR_FORMAT_UINT32;
  2085. ulong ulExprLength = 0;
  2086. // correlation flags. 4 bytes.
  2087. pExprComposite->AddFragment( pFlag );
  2088. ulExprLength = sizeof( NDR64_UINT32 );
  2089. // recursive code to generate the expression stack.
  2090. GenExprFormatString( pCCB, pSizeExpr, pExprComposite, &IsEarly, &ulExprLength );
  2091. pFlag->Data = 0;
  2092. if ( IsEarly )
  2093. pFlag->Data |= FC_NDR64_EARLY_CORRELATION;
  2094. return pExprComposite;
  2095. }
  2096. void
  2097. ExpressionGenerator::GenExprPadIfNecessary(
  2098. CompositeFormatFragment * FragmentList,
  2099. ulong * pExprLength,
  2100. ulong Align )
  2101. {
  2102. MIDL_NDR64_EXPR_NOOP * pExprPad = NULL;
  2103. if ( *pExprLength & ( Align - 1 ) )
  2104. {
  2105. // need to add padding to align next element
  2106. pExprPad = new MIDL_NDR64_EXPR_NOOP;
  2107. pExprPad->Size = (NDR64_UINT8) ( ( Align - 1 ) & *pExprLength );
  2108. FragmentList->AddFragment( pExprPad );
  2109. *pExprLength += sizeof( NDR64_EXPR_NOOP );
  2110. }
  2111. else
  2112. return;
  2113. }
  2114. FormatFragment *
  2115. ExpressionGenerator::GenExprConstant(
  2116. NDR64_FORMAT_CHARACTER fc,
  2117. EXPR_VALUE lValue,
  2118. CompositeFormatFragment * FragmentList,
  2119. ulong * pExprLength )
  2120. {
  2121. if ( fc == FC64_INT64 )
  2122. {
  2123. MIDL_NDR64_EXPR_CONST64 * pFormat;
  2124. pFormat = new MIDL_NDR64_EXPR_CONST64;
  2125. pFormat->ConstValue = lValue;
  2126. GenExprPadIfNecessary( FragmentList, pExprLength, 8 );
  2127. FragmentList->AddFragment( pFormat );
  2128. *pExprLength += sizeof( NDR64_EXPR_CONST64 );
  2129. return pFormat;
  2130. }
  2131. else
  2132. {
  2133. MIDL_NDR64_EXPR_CONST32 *pFormat;
  2134. pFormat = new MIDL_NDR64_EXPR_CONST32;
  2135. pFormat->ConstValue = (NDR64_UINT32) lValue;
  2136. GenExprPadIfNecessary( FragmentList, pExprLength, 4 );
  2137. FragmentList->AddFragment( pFormat );
  2138. *pExprLength += sizeof( NDR64_EXPR_CONST64 );
  2139. return pFormat;
  2140. }
  2141. }
  2142. // check if the expression (including all sub expressions ) is a constant expression
  2143. BOOL
  2144. ExpressionGenerator::IsConstantExpr (expr_node * pExpr )
  2145. {
  2146. if ( pExpr->IsConstant() )
  2147. return TRUE;
  2148. if ( pExpr->IsAVariable() )
  2149. return FALSE;
  2150. if ( pExpr->IsBinaryOperator() )
  2151. {
  2152. return IsConstantExpr( ((expr_op_binary *)pExpr)->GetLeft() ) &&
  2153. IsConstantExpr( ((expr_op_binary *)pExpr)->GetRight() );
  2154. }
  2155. else
  2156. {
  2157. if ( pExpr->IsUnaryOperator() )
  2158. {
  2159. return IsConstantExpr( ((expr_op_unary *)pExpr)->GetLeft() );
  2160. }
  2161. else
  2162. {
  2163. MIDL_ASSERT( pExpr->IsRelationalOperator() );
  2164. return IsConstantExpr( ((expr_ternary *)pExpr)->GetLeft() ) &&
  2165. IsConstantExpr( ((expr_ternary *)pExpr)->GetRight() ) &&
  2166. IsConstantExpr( ((expr_ternary *)pExpr)->GetRelational() ) ;
  2167. }
  2168. }
  2169. }
  2170. NDR64_FORMAT_CHARACTER
  2171. ExpressionGenerator::GetTypeForExpression(
  2172. node_skl *pType
  2173. )
  2174. {
  2175. // Get the size of the type.
  2176. unsigned long Size = pType->GetSize();
  2177. // determine if the type is signed or unsigned.
  2178. bool IsSigned = true;
  2179. node_base_type *pBaseType = dynamic_cast<node_base_type*>( pType->GetBasicType() );
  2180. if ( pBaseType )
  2181. {
  2182. IsSigned = !pBaseType->IsUnsigned();
  2183. }
  2184. switch ( Size )
  2185. {
  2186. case 1:
  2187. return IsSigned ? FC64_INT8 : FC64_UINT8;
  2188. case 2:
  2189. return IsSigned ? FC64_INT16 : FC64_UINT16;
  2190. case 4:
  2191. return IsSigned ? FC64_INT32 : FC64_UINT32;
  2192. case 8:
  2193. return IsSigned ? FC64_INT64 : FC64_UINT64;
  2194. default:
  2195. RpcError( NULL, 0, EXPR_NOT_EVALUATABLE, pType->GetSymName() );
  2196. return FC64_ZERO; // Keep the compiler happy
  2197. }
  2198. }
  2199. FormatFragment *
  2200. ExpressionGenerator::GenExprFormatString(
  2201. CCB *pCCB,
  2202. expr_node *pSizeExpr,
  2203. CompositeFormatFragment *FragmentList,
  2204. BOOL * pIsEarly,
  2205. ulong * pExprLength )
  2206. {
  2207. node_skl * pAttributeNodeType;
  2208. EXPR_TOKEN Op;
  2209. long Offset;
  2210. CG_PARAM * pParam = NULL;
  2211. CG_NDR * pSwitchNode = NULL;
  2212. // BUGBUG: how to generate 32bit constant?
  2213. if ( IsConstantExpr( pSizeExpr ) )
  2214. {
  2215. // Constant expressions are always early!
  2216. *pIsEarly = TRUE;
  2217. return GenExprConstant( FC64_INT64, pSizeExpr->GetValue(), FragmentList, pExprLength );
  2218. }
  2219. if ( pSizeExpr->IsAVariable() )
  2220. // variable
  2221. {
  2222. Op = FC_EXPR_VAR;
  2223. MIDL_NDR64_EXPR_VAR * pFormat;
  2224. CG_NDR * pNdr = pCCB->GetCGNodeContext();
  2225. CG_ITERATOR Iterator;
  2226. pAttributeNodeType = pSizeExpr->GetType();
  2227. if ( pNdr->IsProc() )
  2228. // top level param
  2229. {
  2230. CG_PARAM* pCurrentParam = (CG_PARAM*) pCCB->GetCurrentParam();
  2231. CG_PROC* pCurrentProc = (CG_PROC*) pNdr;
  2232. *pIsEarly = TRUE;
  2233. if ( ( (node_param *) pAttributeNodeType )->IsSaveForAsyncFinish() &&
  2234. pCurrentProc->IsFinishProc() )
  2235. {
  2236. // This is an async split where the finish proc is using
  2237. // a param from the begin proc. Since the parameter
  2238. // was stored on the split stack, the expression will
  2239. // always be early correlation. So all that is needed
  2240. // here is to find the parameter in the begin proc.
  2241. CG_PROC* pBeginProc = pCurrentProc->GetAsyncRelative();
  2242. pBeginProc->GetMembers( Iterator );
  2243. for (;;)
  2244. {
  2245. if (!ITERATOR_GETNEXT( Iterator, pParam ))
  2246. {
  2247. // Didn't find the parameter. We are in trouble!
  2248. MIDL_ASSERT(0);
  2249. return NULL;
  2250. }
  2251. if ( pParam->GetType() == pAttributeNodeType )
  2252. {
  2253. break;
  2254. }
  2255. }
  2256. }
  2257. else
  2258. {
  2259. // Typical case of correlation in the same parameter.
  2260. pCurrentProc->GetMembers( Iterator);
  2261. if ( pCurrentParam->GetType() == pAttributeNodeType )
  2262. *pIsEarly = FALSE;
  2263. for(;;)
  2264. {
  2265. if (!ITERATOR_GETNEXT( Iterator, pParam ))
  2266. {
  2267. // Didn't find the parameter. We are in trouble!
  2268. MIDL_ASSERT(0);
  2269. return NULL;
  2270. }
  2271. // If we find the current parameter before the variable,
  2272. // parameter, then late correlation is needed.
  2273. if ( pParam == pCurrentParam )
  2274. *pIsEarly = FALSE;
  2275. if ( pParam->GetType() == pAttributeNodeType )
  2276. break;
  2277. }
  2278. }
  2279. pSwitchNode = (CG_NDR *) pParam->GetChild();
  2280. }
  2281. else
  2282. // structure /union etc.
  2283. {
  2284. CG_FIELD *pSwitchField;
  2285. ComputeFieldCorrelationOffset( pCCB,
  2286. pAttributeNodeType,
  2287. // return parameters
  2288. &pSwitchField,
  2289. &Offset,
  2290. pIsEarly );
  2291. pSwitchNode = (CG_NDR*)pSwitchField->GetChild();
  2292. }
  2293. // Code the type of the size_is etc. expression.
  2294. NDR64_FORMAT_CHARACTER Type = GetTypeForExpression( pSwitchNode->GetType() );
  2295. pAttributeNodeType = pSizeExpr->GetType();
  2296. pFormat = new MIDL_NDR64_EXPR_VAR;
  2297. pFormat->ExprType = FC_EXPR_VAR;
  2298. pFormat->VarType = (NDR64_UINT8)Type;
  2299. if ( pNdr->IsProc() )
  2300. {
  2301. CG_NDR* pOld = 0;
  2302. BOOL IsFinish = FALSE;
  2303. MIDL_NDR64_EXPR_OPERATOR * pAsyncOp;
  2304. if ( ( (node_param *) pAttributeNodeType )->IsSaveForAsyncFinish() )
  2305. {
  2306. pAsyncOp = new MIDL_NDR64_EXPR_OPERATOR;
  2307. if ( ( (CG_PROC *)pNdr )->IsFinishProc() )
  2308. {
  2309. pOld = pCCB->SetCGNodeContext( ( (CG_PROC *)pNdr )->GetAsyncRelative() );
  2310. IsFinish = TRUE;
  2311. }
  2312. pAsyncOp->ExprType = (NDR64_FORMAT_CHAR) FC_EXPR_OPER;
  2313. pAsyncOp->Operator = (NDR64_FORMAT_CHAR) OP_ASYNCSPLIT;
  2314. FragmentList->AddFragment( pAsyncOp );
  2315. *pExprLength += sizeof( NDR64_EXPR_OPERATOR );
  2316. }
  2317. pFormat->fStackOffset = TRUE;
  2318. pFormat->ia64Offset = pParam->GetStackOffset( pCCB, I386_STACK_SIZING );
  2319. if ( IsFinish )
  2320. pCCB->SetCGNodeContext( pOld );
  2321. }
  2322. else
  2323. {
  2324. // Structure
  2325. pFormat->fStackOffset = FALSE;
  2326. pFormat->Offset = Offset;
  2327. }
  2328. GenExprPadIfNecessary( FragmentList, pExprLength, 4 );
  2329. FragmentList->AddFragment( pFormat );
  2330. *pExprLength += sizeof( NDR64_EXPR_VAR );
  2331. return pFormat;
  2332. }
  2333. else
  2334. // operator
  2335. {
  2336. expr_node * pLeftExpr = NULL;
  2337. BOOL bLeftExprIsEarly = TRUE;
  2338. expr_node * pRightExpr = NULL;
  2339. BOOL bRightExprIsEarly = TRUE;
  2340. expr_node * pRationalExpr = NULL;
  2341. BOOL bRationalExprIsEarly = TRUE;
  2342. MIDL_NDR64_EXPR_OPERATOR *pFormat;
  2343. NDR64_FORMAT_CHARACTER fcKind = (NDR64_FORMAT_CHARACTER)0;
  2344. OPERATOR Operator ;
  2345. if ( pSizeExpr->IsBinaryOperator() )
  2346. {
  2347. Operator = ((expr_op_binary *)pSizeExpr)->GetOperator();
  2348. pLeftExpr = ((expr_op_binary *)pSizeExpr)->GetLeft();
  2349. pRightExpr = ((expr_op_binary *)pSizeExpr)->GetRight();
  2350. }
  2351. else
  2352. {
  2353. if ( pSizeExpr->IsUnaryOperator() )
  2354. {
  2355. Operator = ((expr_op_unary *)pSizeExpr)->GetOperator();
  2356. pLeftExpr = ((expr_op_unary *)pSizeExpr)->GetLeft();
  2357. }
  2358. else
  2359. {
  2360. Operator = ((expr_ternary *)pSizeExpr)->GetOperator();
  2361. pLeftExpr = ((expr_ternary *)pSizeExpr)->GetLeft();
  2362. pRightExpr = ((expr_ternary *)pSizeExpr)->GetRight();
  2363. pRationalExpr = ((expr_ternary *)pSizeExpr)->GetRelational();
  2364. }
  2365. }
  2366. switch ( Operator )
  2367. {
  2368. case OP_UNARY_SIZEOF:
  2369. EXPR_VALUE lSize;
  2370. lSize = pSizeExpr->GetType()->GetSize();
  2371. *pIsEarly = TRUE;
  2372. return GenExprConstant( FC64_INT8, lSize, FragmentList, pExprLength);
  2373. case OP_UNARY_CAST:
  2374. case OP_UNARY_INDIRECTION:
  2375. fcKind = GetTypeForExpression( pSizeExpr->GetType() );
  2376. break;
  2377. }
  2378. pFormat = new MIDL_NDR64_EXPR_OPERATOR;
  2379. pFormat->ExprType = (NDR64_FORMAT_CHAR) FC_EXPR_OPER;
  2380. pFormat->Operator = (NDR64_FORMAT_CHAR) Operator;
  2381. // This was initially 0
  2382. pFormat->CastType = (NDR64_FORMAT_CHAR) fcKind;
  2383. FragmentList->AddFragment( pFormat );
  2384. *pExprLength += sizeof( NDR64_EXPR_OPERATOR );
  2385. GenExprFormatString( pCCB, pLeftExpr, FragmentList, &bLeftExprIsEarly, pExprLength );
  2386. if ( pRightExpr )
  2387. GenExprFormatString( pCCB, pRightExpr, FragmentList, &bRightExprIsEarly, pExprLength );
  2388. if ( pRationalExpr )
  2389. GenExprFormatString( pCCB, pRationalExpr, FragmentList, &bRationalExprIsEarly, pExprLength );
  2390. //
  2391. // An operator is early if and only if all the arguments to the
  2392. // operator are early.
  2393. //
  2394. *pIsEarly = bLeftExprIsEarly && bRightExprIsEarly && bRationalExprIsEarly;
  2395. return pFormat;
  2396. }
  2397. }
  2398. CG_FIELD*
  2399. ExpressionGenerator::FindField(
  2400. node_skl * pFieldType,
  2401. CG_STRUCT *pStruct,
  2402. const char *pPrintPrefix,
  2403. unsigned long *pMemOffset )
  2404. {
  2405. CG_ITERATOR Iterator;
  2406. pStruct->GetMembers( Iterator );
  2407. ITERATOR_INIT( Iterator );
  2408. CG_FIELD *pField;
  2409. while ( ITERATOR_GETNEXT( Iterator, pField ) )
  2410. {
  2411. // First check if the fields are the same type. If they
  2412. // are, then check the print prefixes to make sure the fields came
  2413. // from the same structure.
  2414. if ( ( pField->GetType() == pFieldType ) &&
  2415. ( strcmp( pField->GetPrintPrefix(), pPrintPrefix ) == 0 ) )
  2416. {
  2417. *pMemOffset = pField->GetMemOffset();
  2418. return pField;
  2419. }
  2420. CG_CLASS * pChildClass = pField->GetChild();
  2421. if ( pChildClass->IsStruct() )
  2422. {
  2423. unsigned long TempMemOffset;
  2424. CG_STRUCT *pChildStruct = (CG_STRUCT*)pChildClass;
  2425. CG_FIELD *pTempField = FindField( pFieldType,
  2426. pChildStruct,
  2427. pPrintPrefix,
  2428. &TempMemOffset );
  2429. if ( NULL != pTempField )
  2430. {
  2431. *pMemOffset = TempMemOffset + pField->GetMemOffset();
  2432. return pTempField;
  2433. }
  2434. }
  2435. }
  2436. return NULL;
  2437. }
  2438. void
  2439. ExpressionGenerator::ComputeFieldCorrelationOffset(
  2440. CCB *pCCB,
  2441. node_skl *pFieldType,
  2442. // return parameters
  2443. CG_FIELD **ppVariableField, // var in expression
  2444. long *pOffset,
  2445. BOOL *pIsEarly )
  2446. {
  2447. //
  2448. // Find the fields.
  2449. //
  2450. CG_FIELD *pCurrentField = dynamic_cast<CG_FIELD*>( pCCB->GetLastPlaceholderClass() );
  2451. MIDL_ASSERT( NULL != pCurrentField );
  2452. const char *pPrintPrefix = pCurrentField->GetPrintPrefix();
  2453. CG_STRUCT *pContext = dynamic_cast<CG_STRUCT*>( pCCB->GetCGNodeContext() );
  2454. MIDL_ASSERT( NULL != pContext );
  2455. unsigned long VariableOffset;
  2456. CG_FIELD* pVariableField = FindField( pFieldType,
  2457. pContext,
  2458. pPrintPrefix,
  2459. &VariableOffset );
  2460. MIDL_ASSERT( NULL != pVariableField );
  2461. *ppVariableField = pVariableField;
  2462. unsigned long CurrentOffset;
  2463. CG_FIELD* pAlsoCurrentField = FindField( pCurrentField->GetType(),
  2464. pContext,
  2465. pPrintPrefix,
  2466. &CurrentOffset );
  2467. pAlsoCurrentField;
  2468. MIDL_ASSERT( pAlsoCurrentField == pCurrentField );
  2469. //
  2470. // Determine the correlation type.
  2471. // The correlation type is early if the variable field will
  2472. // be completely marshalled before the current field.
  2473. //
  2474. BOOL bVariableIsPointer = pVariableField->GetChild()->IsPointer();
  2475. BOOL bCurrentFieldIsPointer = pCurrentField->GetChild()->IsPointer();
  2476. BOOL bOnlyVariableIsPointer = bVariableIsPointer && !bCurrentFieldIsPointer;
  2477. *pIsEarly = ( CurrentOffset > VariableOffset ) && !bOnlyVariableIsPointer;
  2478. // In the land of the new transfer syntax, all offsets are a positive offset
  2479. // from the start of the stack or the last structure/region that was passed.
  2480. CG_FIELD *pRegionField = pCCB->GetCurrentRegionField();
  2481. // Make offset relative to start of region
  2482. if (NULL != pRegionField)
  2483. VariableOffset -= pRegionField->GetMemOffset();
  2484. *pOffset = VariableOffset;
  2485. }
  2486. //+--------------------------------------------------------------------------
  2487. //
  2488. // Method: GenNdr64Format::Visit( CG_TRANSMIT_AS )
  2489. //
  2490. // Synopsis: Generate info for transmit_as types
  2491. //
  2492. //---------------------------------------------------------------------------
  2493. void GenNdr64Format::Visit( CG_TRANSMIT_AS *pTransmitAs )
  2494. {
  2495. MIDL_NDR64_TRANSMIT_AS_FORMAT *format;
  2496. format = new MIDL_NDR64_TRANSMIT_AS_FORMAT( pTransmitAs );
  2497. GetCurrent()->AddFragment( format );
  2498. GenXmitOrRepAsFormat(
  2499. pTransmitAs,
  2500. format,
  2501. pTransmitAs->GetPresentedType()->GetSymName(),
  2502. pTransmitAs->GetPresentedType(),
  2503. pTransmitAs->GetTransmittedType() );
  2504. }
  2505. //+--------------------------------------------------------------------------
  2506. //
  2507. // Method: GenNdr64Format::Visit( CG_REPRESENT_AS )
  2508. //
  2509. // Synopsis: Generate info for represent_as types
  2510. //
  2511. //---------------------------------------------------------------------------
  2512. void GenNdr64Format::Visit( CG_REPRESENT_AS *pRepresentAs )
  2513. {
  2514. MIDL_NDR64_REPRESENT_AS_FORMAT *format;
  2515. format = new MIDL_NDR64_REPRESENT_AS_FORMAT( pRepresentAs );
  2516. GetCurrent()->AddFragment( format );
  2517. GenXmitOrRepAsFormat(
  2518. pRepresentAs,
  2519. format,
  2520. pRepresentAs->GetRepAsTypeName(),
  2521. pRepresentAs->GetRepAsType(),
  2522. pRepresentAs->GetTransmittedType() );
  2523. }
  2524. //+--------------------------------------------------------------------------
  2525. //
  2526. // Method: GenNdr64Format::GenXmitOrRepAsFormat
  2527. //
  2528. // Synopsis: Do the actual work for transmit_as and represent_as types
  2529. //
  2530. //---------------------------------------------------------------------------
  2531. void GenNdr64Format::GenXmitOrRepAsFormat(
  2532. CG_TYPEDEF *pXmitNode,
  2533. MIDL_NDR64_TRANSMIT_AS_FORMAT *format,
  2534. char *pPresentedTypeName,
  2535. node_skl *pPresentedType,
  2536. node_skl *pTransmittedType )
  2537. {
  2538. CG_NDR *pChild = (CG_NDR *) pXmitNode->GetChild();
  2539. BOOL fXmit = ( NULL == dynamic_cast<CG_REPRESENT_AS *>(pXmitNode) );
  2540. NDR64_UINT16 RoutineIndex = pXmitNode->GenXmitOrRepAsQuintuple(
  2541. pCCB,
  2542. fXmit,
  2543. pXmitNode,
  2544. pPresentedTypeName,
  2545. (fXmit ? pPresentedType
  2546. : pTransmittedType) );
  2547. format->FormatCode = (NDR64_FORMAT_CHAR) ( fXmit ? FC64_TRANSMIT_AS : FC64_REPRESENT_AS );
  2548. format->RoutineIndex = RoutineIndex;
  2549. format->TransmittedTypeWireAlignment = (NDR64_UINT16) ( pChild->GetWireAlignment() - 1 );
  2550. // REVIEW: The spec doesn't say whether "MemoryAlignment" is the
  2551. // presented type or the transmitted type. Transmitted doesn't
  2552. // make much sense but on the other hand presented has some
  2553. // alignment flags already.
  2554. format->MemoryAlignment = pXmitNode->GetMemoryAlignment();
  2555. if ( pPresentedType )
  2556. format->PresentedTypeMemorySize = (NDR64_UINT16) pPresentedType->GetSize();
  2557. else
  2558. MIDL_ASSERT(!"BUGBUG: unknown rep/transmit_as");
  2559. if ( pChild->HasAFixedBufferSize() )
  2560. format->TransmittedTypeBufferSize = (NDR64_UINT16) pChild->GetWireSize();
  2561. else
  2562. format->TransmittedTypeBufferSize = 0;
  2563. format->Flags.PresentedTypeIsArray = 0;
  2564. format->Flags.PresentedTypeAlign4 = 0;
  2565. format->Flags.PresentedTypeAlign8 = 0;
  2566. format->Flags.Reserved = 0;
  2567. if ( pPresentedType )
  2568. {
  2569. if ( pPresentedType->GetBasicType()->NodeKind() == NODE_ARRAY )
  2570. format->Flags.PresentedTypeIsArray = 1;
  2571. else
  2572. {
  2573. if ( pXmitNode->GetMemoryAlignment() == 4 )
  2574. format->Flags.PresentedTypeAlign4 = 1;
  2575. else if ( pXmitNode->GetMemoryAlignment() == 8 )
  2576. format->Flags.PresentedTypeAlign8 = 1;
  2577. }
  2578. }
  2579. if ( pChild->GetCGID() == ID_CG_GENERIC_HDL )
  2580. pChild = (CG_NDR *)pChild->GetChild();
  2581. format->TransmittedType = ContinueGenerationInRoot( pChild );
  2582. }
  2583. //+--------------------------------------------------------------------------
  2584. //
  2585. // Method: GenNdr64Format::Visit( CG_USER_MARSHAL )
  2586. //
  2587. // Synopsis: Generate info for user_marshal types
  2588. //
  2589. // REVIEW: user_marshall and represent_as are so close to one another
  2590. // they really should probably be merged
  2591. //
  2592. //---------------------------------------------------------------------------
  2593. void GenNdr64Format::Visit( CG_USER_MARSHAL *pUserMarshal )
  2594. {
  2595. MIDL_NDR64_USER_MARSHAL_FORMAT *format;
  2596. format = new MIDL_NDR64_USER_MARSHAL_FORMAT( pUserMarshal );
  2597. GetCurrent()->AddFragment( format );
  2598. CG_NDR *pChild = (CG_NDR *) pUserMarshal->GetChild();
  2599. format->FormatCode = FC64_USER_MARSHAL;
  2600. format->TransmittedTypeWireAlignment = (NDR64_UINT16) (pChild->GetWireAlignment() - 1);
  2601. format->MemoryAlignment = pChild->GetMemoryAlignment();
  2602. memset( &format->Flags, 0, sizeof(format->Flags) );
  2603. if ( pChild->IsPointer() )
  2604. {
  2605. CG_POINTER *pPointer = (CG_POINTER *) pChild;
  2606. MIDL_ASSERT( ! pPointer->IsFull() );
  2607. if ( pPointer->IsUnique() )
  2608. format->Flags.UniquePointer = 1;
  2609. else if ( pPointer->IsRef() )
  2610. format->Flags.RefPointer = 1;
  2611. }
  2612. format->Flags.IID = 0; // Only used by JIT compiler
  2613. format->Flags.Reserved = 0;
  2614. USER_MARSHAL_CONTEXT * pUserMarshalContext = new USER_MARSHAL_CONTEXT;
  2615. pUserMarshalContext->pTypeName = pUserMarshal->GetRepAsTypeName();
  2616. pUserMarshalContext->pType = pUserMarshal->GetRepAsType();
  2617. BOOL Added = pCCB->GetQuadrupleDictionary()->Add( pUserMarshalContext );
  2618. format->RoutineIndex = pUserMarshalContext->Index;
  2619. if ( !Added )
  2620. delete pUserMarshalContext;
  2621. if ( pUserMarshal->GetRepAsType() )
  2622. format->UserTypeMemorySize = pUserMarshal->GetRepAsType()->GetSize();
  2623. else
  2624. MIDL_ASSERT( !"BUGBUG: undefined user_marshal" );
  2625. if ( pChild->HasAFixedBufferSize() )
  2626. format->TransmittedTypeBufferSize = pChild->GetWireSize();
  2627. else
  2628. format->TransmittedTypeBufferSize = 0;
  2629. format->TransmittedType = ContinueGenerationInRoot( pChild );
  2630. }
  2631. //+--------------------------------------------------------------------------
  2632. //
  2633. // Method: GenNdr64Format::Visit( CG_PIPE )
  2634. //
  2635. // Synopsis: Generate info for [pipe] types
  2636. //
  2637. //---------------------------------------------------------------------------
  2638. void GenNdr64Format::Visit( CG_PIPE *pPipe )
  2639. {
  2640. pCommand->GetNdrVersionControl().SetHasRawPipes();
  2641. MIDL_NDR64_PIPE_FORMAT *format = new MIDL_NDR64_PIPE_FORMAT( pPipe );
  2642. GetCurrent()->AddFragment( format );
  2643. CG_NDR *pChild = (CG_NDR *) pPipe->GetChild();
  2644. NDR64_UINT32 BufferSize = 0;
  2645. node_range_attr *range = pPipe->GetRangeAttribute();
  2646. NDR64_UINT32 MinValue = 0;
  2647. NDR64_UINT32 MaxValue = 0;
  2648. CG_ILANALYSIS_INFO *pAnalysisInfo = pChild->GetILAnalysisInfo();
  2649. if ( pChild->HasAFixedBufferSize() )
  2650. BufferSize = pChild->GetWireSize();
  2651. if ( range )
  2652. {
  2653. MinValue = (NDR64_UINT32) range->GetMinExpr()->GetValue();
  2654. MaxValue = (NDR64_UINT32) range->GetMaxExpr()->GetValue();
  2655. }
  2656. format->FormatCode = FC64_PIPE;
  2657. format->Flags.Reserved1 = 0;
  2658. format->Flags.HasRange = (bool) ( NULL != range );
  2659. format->Flags.BlockCopy = !pAnalysisInfo->IsForcedBogus() && !pAnalysisInfo->IsFullBogus();
  2660. format->Flags.Reserved2 = 0;
  2661. format->Alignment = (NDR64_UINT8) ( pChild->GetWireAlignment() - 1 );
  2662. format->Reserved = 0;
  2663. format->Type = ContinueGenerationInRoot( pChild );
  2664. format->MemorySize = pChild->GetMemorySize();
  2665. format->BufferSize = BufferSize;
  2666. format->MinValue = MinValue;
  2667. format->MaxValue = MaxValue;
  2668. }
  2669. //+--------------------------------------------------------------------------
  2670. //
  2671. // Method: OutputParamFlagDescription
  2672. //
  2673. // Synopsis: Output a description string for the ndr64 param flags
  2674. //
  2675. //---------------------------------------------------------------------------
  2676. void OutputParamFlagDescription( CCB *pCCB, const NDR64_PARAM_FLAGS &flags )
  2677. {
  2678. static const PNAME flag_descrip[16] =
  2679. {
  2680. "MustSize",
  2681. "MustFree",
  2682. "pipe",
  2683. "[in]",
  2684. "[out]",
  2685. "IsReturn",
  2686. "Basetype",
  2687. "ByValue",
  2688. "SimpleRef",
  2689. "DontFreeInst",
  2690. "AsyncFinish",
  2691. NULL,
  2692. NULL,
  2693. NULL,
  2694. NULL,
  2695. "UseCache"
  2696. };
  2697. pCCB->GetStream()->Write( " " );
  2698. OutputFlagDescriptions( pCCB->GetStream(), &flags, sizeof(flags), flag_descrip );
  2699. }
  2700. //+--------------------------------------------------------------------------
  2701. //
  2702. // Method: OutputFlagDescription
  2703. //
  2704. // Synopsis: Given a set of flags and a description for each flags,
  2705. // output the corresponding description for flag that is set.
  2706. // usused flags can be marked with a NULL description.
  2707. //
  2708. // Notes: Assumes little-endian memory layout!
  2709. //
  2710. //---------------------------------------------------------------------------
  2711. void OutputFlagDescriptions(
  2712. ISTREAM *stream,
  2713. const void *pvFlags,
  2714. int bytes,
  2715. const PNAME *description)
  2716. {
  2717. unsigned char *flags = (unsigned char *) pvFlags;
  2718. bool first = true;
  2719. stream->Write( "/*");
  2720. for (int i = 0; i < (bytes * 8); i++)
  2721. {
  2722. if ( ( NULL == description[i] )
  2723. || ( 0 == ( flags[i / 8] & ( 1 << (i % 8) ) ) ) )
  2724. {
  2725. continue;
  2726. }
  2727. if ( !first )
  2728. stream->Write( "," );
  2729. first = false;
  2730. stream->Write( " " );
  2731. stream->Write( description[i] );
  2732. }
  2733. stream->Write( " */" );
  2734. }