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.

1725 lines
41 KiB

  1. // Copyright (c) 1993-1999 Microsoft Corporation
  2. #pragma warning ( disable : 4514 4710 4706)
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <direct.h>
  8. #include <io.h>
  9. #include <time.h>
  10. #include "errors.hxx"
  11. #include "cmdana.hxx"
  12. #include "stream.hxx"
  13. #include "midlvers.h"
  14. extern _swenum SearchForSwitch( char ** );
  15. extern void ReportUnimplementedSwitch( short );
  16. extern char * SwitchStringForValue( unsigned short );
  17. extern STATUS_T SelectChoice( const CHOICE *, char *, short *);
  18. const __int64 iMagic = 77736876677768;
  19. CHOICE PrefixChoices[] =
  20. {
  21. { "client" , PREFIX_CLIENT_STUB }
  22. ,{ "server" , PREFIX_SERVER_MGR }
  23. ,{ "switch" , PREFIX_SWICH_PROTOTYPE }
  24. ,{ "cstub" , PREFIX_CLIENT_STUB }
  25. ,{ "sstub" , PREFIX_SERVER_MGR }
  26. ,{ "all" , PREFIX_ALL }
  27. ,{ 0 , 0 }
  28. };
  29. _cmd_arg::_cmd_arg()
  30. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  31. Routine Description:
  32. The constructor
  33. Arguments:
  34. None.
  35. Return Value:
  36. NA.
  37. Notes:
  38. ----------------------------------------------------------------------------*/
  39. {
  40. switch_def_vector[0] = switch_def_vector[1] = switch_def_vector[2] =
  41. switch_def_vector[3] = switch_def_vector[4] = 0;
  42. fClient = CLNT_STUB;
  43. fServer = SRVR_STUB;
  44. Env = ENV_WIN32;
  45. CharOption = CHAR_SIGNED;
  46. fMintRun = FALSE;
  47. fIsNDR64Run = FALSE;
  48. fIsNDRRun = FALSE;
  49. fIs2ndCodegenRun = FALSE;
  50. fNeedsNDR64Header = FALSE;
  51. MajorVersion = rmj;
  52. MinorVersion = rmm;
  53. UpdateNumber = rup;
  54. ErrorOption = ERROR_NONE;
  55. WireCompatOption = 0;
  56. ConfigMask = 0;
  57. MSCVersion = 0;
  58. fShowLogo = true;
  59. // NdrVersionControl has a default constructor so it gets initialized.
  60. OptimFlags = OPTIMIZE_NONE;
  61. OptimLevel = OPT_LEVEL_OS;
  62. TargetSystem = NOTARGET;
  63. iArgV = 0;
  64. cArgs = 0;
  65. WLevel = 1;
  66. ZeePee = DEFAULT_ZEEPEE;
  67. EnumSize = 4;
  68. LocaleId = 0;
  69. fDoubleFor64 = FALSE;
  70. fHasAppend64 = FALSE;
  71. szCompileTime[0] = 0;
  72. szCompilerVersion[0] = 0;
  73. pInputFNSwitch =
  74. pOutputPathSwitch =
  75. pCStubSwitch =
  76. pSStubSwitch =
  77. pHeaderSwitch =
  78. pAcfSwitch = (filename_switch *)NULL;
  79. pIIDSwitch =
  80. pDllDataSwitch =
  81. pProxySwitch =
  82. pProxyDefSwitch =
  83. pTlibSwitch =
  84. pNetmonStubSwitch =
  85. pNetmonStubObjSwitch =
  86. pRedirectOutputSwitch = (filename_switch *)NULL;
  87. pSwitchPrefix = new pair_switch( &PrefixChoices[0] );
  88. pSwitchSuffix = (pair_switch *)0;
  89. pDSwitch =
  90. pISwitch =
  91. pUSwitch = (multiple_switch *)NULL;
  92. pCppCmdSwitch =
  93. pCppOptSwitch =
  94. pMSCVerSwitch =
  95. pDebug64Switch =
  96. pDebug64OptSwitch = (onetime_switch *) NULL;
  97. }
  98. BOOL
  99. CMD_ARG::IsValidZeePee(
  100. long NewZeePee
  101. )
  102. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  103. Routine Description:
  104. Tests if the argument is a valid packing level.
  105. Arguments:
  106. NewZeePee - Packing level.
  107. Return Value:
  108. TRUE if the argument is valid.
  109. Notes:
  110. Valid packing levels are nonzero powers of 2 less then 2^16.
  111. ----------------------------------------------------------------------------*/
  112. {
  113. switch( NewZeePee )
  114. {
  115. case (1 << 0):
  116. case (1 << 1):
  117. case (1 << 2):
  118. case (1 << 3):
  119. case (1 << 4):
  120. case (1 << 5):
  121. case (1 << 6):
  122. case (1 << 7):
  123. case (1 << 8):
  124. case (1 << 9):
  125. case (1 << 10):
  126. case (1 << 11):
  127. case (1 << 12):
  128. case (1 << 13):
  129. case (1 << 14):
  130. case (1 << 15):
  131. return TRUE;
  132. default:
  133. return FALSE;
  134. }
  135. }
  136. void
  137. CMD_ARG::SwitchDefined(
  138. short sw
  139. )
  140. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  141. Routine Description:
  142. Set switch to be defined.
  143. Arguments:
  144. sw - switch number.
  145. Return Value:
  146. None.
  147. Notes:
  148. set the switch definition vector bit.
  149. ----------------------------------------------------------------------------*/
  150. {
  151. switch_def_vector[ sw / 32 ] |=
  152. (ulong)( (ulong)0x1 << (ulong)( (ulong)sw % 32 ) );
  153. }
  154. char *
  155. CMD_ARG::GetOutputPath()
  156. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  157. Routine Description:
  158. Get the output path.
  159. Arguments:
  160. None.
  161. Return Value:
  162. None.
  163. Notes:
  164. Reconstitute the path name from the outputpath switch, if nothing
  165. was specified, put in a path and a slash at the end.
  166. ----------------------------------------------------------------------------*/
  167. {
  168. char agName[ _MAX_DRIVE + _MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
  169. char * pOut;
  170. char flag = 0;
  171. strcpy( agName, pOut = pOutputPathSwitch->GetFileName() );
  172. if( agName[0] == '\0' )
  173. {
  174. strcpy(agName, ".\\"), flag = 1;
  175. }
  176. if( flag )
  177. {
  178. pOut = new char [strlen( agName ) + 1];
  179. strcpy( pOut , agName );
  180. pOutputPathSwitch->SetFileName( pOut );
  181. }
  182. return pOut;
  183. }
  184. char *
  185. CMD_ARG::GetMinusISpecification()
  186. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  187. Routine Description:
  188. get the consolidate -i specification, without the -I characters in them
  189. Arguments:
  190. none.
  191. Return Value:
  192. pointer to a buffer containing the consolidated -i options. If the -i
  193. is not specified, then return a null.
  194. the returned area (if the pointer returned is not null) can be deleted
  195. by the caller.
  196. Notes:
  197. GetConsolidatedLength will always return a buffer size including the -I
  198. characters. We can safely assume, that since we are stripping those
  199. characters, the length returned is sufficient, even if we are appending
  200. a ; after each -I option
  201. Also assume that the -I specification buffer always has the -I to start
  202. with.
  203. ----------------------------------------------------------------------------*/
  204. {
  205. char * pMinusI;
  206. char * pTemp;
  207. if( IsSwitchDefined( SWITCH_I ) )
  208. {
  209. pMinusI = new char[ pISwitch->GetConsolidatedLength() + 1];
  210. pMinusI[0] = '\0';
  211. pISwitch->Init();
  212. size_t ActualOffset;
  213. while ( ( pTemp = pISwitch->GetNext( &ActualOffset ) ) != 0 )
  214. {
  215. strcat( pMinusI, pTemp+ActualOffset );
  216. strcat( pMinusI, ";");
  217. }
  218. return pMinusI;
  219. }
  220. else
  221. return (char *)0;
  222. }
  223. /*****************************************************************************
  224. * filename_switch member functions
  225. *****************************************************************************/
  226. filename_switch::filename_switch(
  227. char * pThisArg
  228. )
  229. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  230. Routine Description:
  231. constructor
  232. Arguments:
  233. pointer to the filename argument.
  234. Return Value:
  235. NA.
  236. Notes:
  237. set the filename.
  238. ----------------------------------------------------------------------------*/
  239. {
  240. pFullName = (char *)NULL;
  241. if( pThisArg )
  242. {
  243. SetFileName( pThisArg );
  244. }
  245. }
  246. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  247. Routine Description:
  248. consructor.
  249. Arguments:
  250. filename components.
  251. Return Value:
  252. NA.
  253. Notes:
  254. set the file names.
  255. ----------------------------------------------------------------------------*/
  256. filename_switch::filename_switch(
  257. char * pD,
  258. char * pP,
  259. char * pN,
  260. char * pE,
  261. char * pS )
  262. {
  263. pFullName = (char *)NULL;
  264. SetFileName( pD, pP, pN, pE, pS );
  265. }
  266. filename_switch::~filename_switch()
  267. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  268. Routine Description:
  269. KABOOOM !
  270. Arguments:
  271. None.
  272. Return Value:
  273. Huh ?
  274. Notes:
  275. ----------------------------------------------------------------------------*/
  276. {
  277. if( pFullName )
  278. delete pFullName;
  279. }
  280. void
  281. filename_switch::SetFileName(
  282. char * pName
  283. )
  284. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  285. Routine Description:
  286. set filename
  287. Arguments:
  288. pName - filename
  289. Return Value:
  290. None.
  291. Notes:
  292. ----------------------------------------------------------------------------*/
  293. {
  294. if( pFullName )
  295. delete pFullName;
  296. pFullName = new char [strlen(pName) + 1];
  297. strcpy( pFullName, pName );
  298. }
  299. void
  300. filename_switch::SetFileName(
  301. char * pD,
  302. char * pP,
  303. char * pN,
  304. char * pE,
  305. char * pS
  306. )
  307. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  308. Routine Description:
  309. set file name, given its components.
  310. Arguments:
  311. pD - pointer to drive name ( can be null );
  312. pP - pointer to path name ( can be null );
  313. pN - pointer to name ( can be null );
  314. pE - pointer to extension name ( can be null );
  315. pS - pointer to suffix.
  316. Return Value:
  317. None.
  318. Notes:
  319. The suffix is added to the filename if necesary. This routine is useful
  320. if we need to set the filename in partial name set operations. Any
  321. filename components previously set are overriden.
  322. ----------------------------------------------------------------------------*/
  323. {
  324. char agDrive[ _MAX_DRIVE ];
  325. char agPath[ _MAX_DIR ];
  326. char agBaseName[ _MAX_FNAME ];
  327. char agExt[ _MAX_EXT ];
  328. short len = 0;
  329. if( pFullName )
  330. {
  331. // modify only those portions of the filename that the
  332. // caller passed in
  333. _splitpath( pFullName, agDrive, agPath, agBaseName, agExt );
  334. delete pFullName;
  335. }
  336. else
  337. {
  338. // this is the first time the name is being set up.
  339. agDrive[0] = agPath[0] = agBaseName[0] = agExt[0] = '\0';
  340. }
  341. if(!pD) pD = agDrive;
  342. if(!pP) pP = agPath;
  343. if(!pN) pN = agBaseName;
  344. if(!pS) pS = "";
  345. if(!pE) pE = agExt;
  346. len = short(strlen( pD ) + strlen( pP ) + strlen( pN ) + strlen( pS ) + strlen( pE ) + 1);
  347. pFullName = new char[ len ];
  348. strcpy( pFullName, pD );
  349. strcat( pFullName, pP );
  350. strcat( pFullName, pN );
  351. strcat( pFullName, pS );
  352. strcat( pFullName, pE );
  353. }
  354. void
  355. filename_switch::TransformFileNameForOut(
  356. char * pD,
  357. char * pP)
  358. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  359. Routine Description:
  360. transform file name to incorporate the output path, given its drive
  361. and path components.
  362. Arguments:
  363. pD - pointer to drive name ( can be null );
  364. pP - pointer to path name ( can be null );
  365. Return Value:
  366. None.
  367. Notes:
  368. If the filename switch does not have the path component, the path specified
  369. by pP overrides it. If it does not have the drive component, the the drive
  370. specified by pD overrides it.
  371. ----------------------------------------------------------------------------*/
  372. {
  373. char agDrive[ _MAX_DRIVE ];
  374. char agPath[ _MAX_DIR ];
  375. char agPath1[ _MAX_DIR ];
  376. char agName[ _MAX_FNAME ];
  377. char agExt[ _MAX_EXT ];
  378. BOOL fTransformed = FALSE;
  379. if( pFullName )
  380. {
  381. _splitpath( pFullName, agDrive, agPath, agName, agExt );
  382. // if the original name did not have the drive component, derive it
  383. // from the specified one.
  384. if( (agDrive[0] == '\0') &&
  385. (agPath[0] != '\\' ) &&
  386. (agPath[0] != '/' ) )
  387. {
  388. if( pD && (*pD) )
  389. strcpy( agDrive, pD );
  390. if( pP && (*pP ) )
  391. {
  392. strcpy( agPath1, pP );
  393. strcat( agPath1, agPath );
  394. }
  395. else
  396. strcpy( agPath1, agPath );
  397. fTransformed = TRUE;
  398. }
  399. }
  400. if( fTransformed )
  401. {
  402. delete pFullName;
  403. pFullName = new char [ strlen( agDrive ) +
  404. strlen( agPath1 ) +
  405. strlen( agName ) +
  406. strlen( agExt ) +
  407. 1 ];
  408. strcpy( pFullName, agDrive );
  409. strcat( pFullName, agPath1 );
  410. strcat( pFullName, agName );
  411. strcat( pFullName, agExt );
  412. }
  413. }
  414. char *
  415. filename_switch::GetFileName()
  416. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  417. Routine Description:
  418. Getfile name.
  419. Arguments:
  420. none.
  421. Return Value:
  422. the filename.
  423. Notes:
  424. ----------------------------------------------------------------------------*/
  425. {
  426. return pFullName;
  427. }
  428. void
  429. filename_switch::GetFileNameComponents(
  430. char * pD,
  431. char * pP,
  432. char * pN,
  433. char * pE
  434. )
  435. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  436. Routine Description:
  437. get file name components.
  438. Arguments:
  439. pD - pointer to drive name area.
  440. pP - pointer to path name area.
  441. pN - pointer to name area.
  442. pE - pointer to extension area.
  443. Return Value:
  444. None.
  445. Notes:
  446. Assume that all pointers pass the right size buffers. I dont check here.
  447. Useful to get the filename components desired.
  448. ----------------------------------------------------------------------------*/
  449. {
  450. char agDrive[ _MAX_DRIVE ];
  451. char agPath[ _MAX_DIR ];
  452. char agBaseName[ _MAX_FNAME ];
  453. char agExt[ _MAX_EXT ];
  454. _splitpath( pFullName ? pFullName : "" ,
  455. agDrive, agPath, agBaseName, agExt );
  456. if( pD ) strcpy( pD , agDrive );
  457. if( pP ) strcpy( pP , agPath );
  458. if( pN ) strcpy( pN , agBaseName );
  459. if( pE ) strcpy( pE , agExt );
  460. }
  461. /*****************************************************************************
  462. * multiple_switch member functions
  463. *****************************************************************************
  464. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  465. Routine Description:
  466. constructor.
  467. Arguments:
  468. argument to switch. Actual argument offset.
  469. Return Value:
  470. Notes:
  471. ----------------------------------------------------------------------------*/
  472. multiple_switch::multiple_switch(
  473. char * pArg,
  474. size_t ActualArgOffset )
  475. {
  476. pFirst = pCurrent = (OptList *)NULL;
  477. if ( pArg )
  478. {
  479. Add( pArg, ActualArgOffset );
  480. }
  481. }
  482. void
  483. multiple_switch::Add(
  484. char * pValue,
  485. size_t ActualOffset
  486. )
  487. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  488. Routine Description:
  489. Add another argument to the multiple specification switch.
  490. Arguments:
  491. pValue - the argument.
  492. Return Value:
  493. None.
  494. Notes:
  495. ----------------------------------------------------------------------------*/
  496. {
  497. OptList * pOpt = pFirst;
  498. OptList * pNew = new OptList;
  499. pNew->pNext = (OptList *)NULL;
  500. pNew->pStr = pValue;
  501. pNew->ActualOffset = ActualOffset;
  502. // determine if argument needs quotes
  503. bool NeedsQuotes = false;
  504. // skip to the first character of the switch argument.
  505. pValue += ActualOffset;
  506. while( *pValue && !(NeedsQuotes = !!isspace(*pValue++)) );
  507. pNew->NeedsQuotes = NeedsQuotes;
  508. // link it up
  509. while( pOpt && pOpt->pNext ) pOpt = pOpt->pNext;
  510. if( !pOpt )
  511. pCurrent = pFirst = pNew;
  512. else
  513. pOpt->pNext = pNew;
  514. }
  515. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  516. Routine Description:
  517. Init a walk of the multiple input switch.
  518. Arguments:
  519. None.
  520. Return Value:
  521. None.
  522. Notes:
  523. ----------------------------------------------------------------------------*/
  524. void
  525. multiple_switch::Init()
  526. {
  527. pCurrent = pFirst;
  528. }
  529. char *
  530. multiple_switch::GetNext( size_t *pActualOffset, bool *pNeedsQuotes )
  531. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  532. Routine Description:
  533. Get the next argument to theis switch.
  534. Arguments:
  535. None.
  536. Return Value:
  537. pointer to the next argument.
  538. Notes:
  539. ----------------------------------------------------------------------------*/
  540. {
  541. char * pValue = (char *)NULL;
  542. if(pCurrent)
  543. {
  544. pValue = pCurrent->pStr;
  545. if ( pActualOffset )
  546. {
  547. *pActualOffset = pCurrent->ActualOffset;
  548. }
  549. if ( pNeedsQuotes )
  550. {
  551. *pNeedsQuotes = pCurrent->NeedsQuotes;
  552. }
  553. pCurrent = pCurrent->pNext;
  554. }
  555. return pValue;
  556. }
  557. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  558. Routine Description:
  559. Get all the options to the multiple options switch, consolidated into
  560. a buffer.
  561. Arguments:
  562. None.
  563. Return Value:
  564. pointer to a buffer containing all the concatenated arguments.
  565. Notes:
  566. ----------------------------------------------------------------------------*/
  567. char *
  568. multiple_switch::GetConsolidatedOptions( bool AddQuotes )
  569. {
  570. #define OPTION_GAP_STRING() (" ")
  571. #define OPTION_GAP_LENGTH() (1)
  572. int len;
  573. char * pReturn = 0;
  574. len = GetConsolidatedLength( AddQuotes );
  575. // consolidate the options into 1
  576. if ( len && ( pReturn = new char[ len + 1] ) != 0 )
  577. {
  578. char * pTemp;
  579. *pReturn = '\0';
  580. Init();
  581. size_t ActualOffset;
  582. bool NeedsQuotes;
  583. while ( ( pTemp = GetNext(&ActualOffset, &NeedsQuotes ) ) != 0)
  584. {
  585. if ( NeedsQuotes && AddQuotes )
  586. {
  587. char *pTempReturn = pReturn + strlen( pReturn );
  588. memcpy( pTempReturn, pTemp, ActualOffset );
  589. sprintf( pTempReturn + ActualOffset,
  590. "\"%s\"%s", pTemp + ActualOffset, OPTION_GAP_STRING() );
  591. }
  592. else
  593. {
  594. strcat( pReturn, pTemp );
  595. strcat( pReturn, OPTION_GAP_STRING() );
  596. }
  597. }
  598. }
  599. return pReturn;
  600. }
  601. short
  602. multiple_switch::GetConsolidatedLength( bool AddQuotes )
  603. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  604. Routine Description:
  605. Get the length of the consolidated options.
  606. Arguments:
  607. None.
  608. Return Value:
  609. length of the options.
  610. Notes:
  611. ----------------------------------------------------------------------------*/
  612. {
  613. char * pReturn;
  614. short len = 0;
  615. Init();
  616. bool NeedsQuotes;
  617. while ( ( pReturn = GetNext(NULL, &NeedsQuotes ) ) != 0 )
  618. {
  619. len = short(len + strlen( pReturn ) + OPTION_GAP_LENGTH());
  620. if ( AddQuotes && NeedsQuotes ) len += 2; //Add space for quotes
  621. }
  622. return len;
  623. }
  624. #undef OPTION_GAP_STRING
  625. #undef OPTION_GAP_LENGTH
  626. /*****************************************************************************
  627. * onetime_switch member functions
  628. *****************************************************************************/
  629. onetime_switch::onetime_switch(
  630. char * pArg
  631. )
  632. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  633. Routine Description:
  634. constructor.
  635. Arguments:
  636. pArg - pointer to switch argument.
  637. Return Value:
  638. NA.
  639. Notes:
  640. ----------------------------------------------------------------------------*/
  641. {
  642. if( pArg )
  643. {
  644. pOpt = new char[ strlen( pArg ) + 1];
  645. strcpy( pOpt, pArg );
  646. }
  647. else
  648. pOpt = (char *)NULL;
  649. }
  650. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  651. Routine Description:
  652. destructor.
  653. Arguments:
  654. None.
  655. Return Value:
  656. NA.
  657. Notes:
  658. ----------------------------------------------------------------------------*/
  659. onetime_switch::~onetime_switch()
  660. {
  661. if( pOpt )
  662. delete pOpt;
  663. }
  664. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  665. Routine Description:
  666. Get the option string.
  667. Arguments:
  668. None.
  669. Return Value:
  670. the option string.
  671. Notes:
  672. ----------------------------------------------------------------------------*/
  673. char *
  674. onetime_switch::GetOption()
  675. {
  676. return pOpt;
  677. }
  678. short
  679. onetime_switch::GetLength()
  680. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  681. Routine Description:
  682. get length of the option.
  683. Arguments:
  684. None.
  685. Return Value:
  686. the length of the option.
  687. Notes:
  688. ----------------------------------------------------------------------------*/
  689. {
  690. return (short)strlen( pOpt );
  691. }
  692. typedef char* PSTR;
  693. pair_switch::pair_switch(
  694. const CHOICE * pValidChoices )
  695. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  696. Routine Description:
  697. pair_switch_constructor
  698. Arguments:
  699. pValidChoiceArray - the array of valid choices (this is assumed
  700. pre-allocated).
  701. Return Value:
  702. NA
  703. Notes:
  704. ----------------------------------------------------------------------------*/
  705. {
  706. short MaxIndex = 0;
  707. CHOICE * pCurChoice = (CHOICE *) pValidChoices;
  708. pArrayOfChoices = pCurChoice;
  709. // find the size of the pair array
  710. while ( pCurChoice->pChoice )
  711. {
  712. if ( pCurChoice->Choice > MaxIndex )
  713. MaxIndex = pCurChoice->Choice;
  714. pCurChoice++;
  715. }
  716. ArraySize = short(MaxIndex + 1);
  717. pUserStrings = new PSTR [ ArraySize ];
  718. for ( int i = 0; i <= MaxIndex; i++ )
  719. pUserStrings[i] = NULL;
  720. Current = -1;
  721. }
  722. void
  723. pair_switch::AddPair(
  724. short Sys,
  725. char * pUsr )
  726. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  727. Routine Description:
  728. add another prefix pair
  729. Arguments:
  730. Sys - the system-defined string key
  731. pUsr - the user-defined string value.
  732. Return Value:
  733. None.
  734. Notes:
  735. ----------------------------------------------------------------------------*/
  736. {
  737. pUserStrings[ Sys ] = pUsr;
  738. }
  739. char *
  740. pair_switch::GetUserDefinedEquivalent(
  741. short Sys )
  742. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  743. Routine Description:
  744. get the user defined prefix corresponding to the system defined prefix.
  745. Arguments:
  746. pSystemDefined - the system defined prefix for which the user defined
  747. prefix is being searched.
  748. Return Value:
  749. The user defined prefix , if it is defined. If not, return the input
  750. Notes:
  751. ----------------------------------------------------------------------------*/
  752. {
  753. return pUserStrings[ Sys ];
  754. }
  755. short
  756. pair_switch::GetIndex(
  757. char * pGivenString )
  758. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  759. Routine Description:
  760. search is the array of choices, if this string is a valid system known
  761. string
  762. Arguments:
  763. pGivenString - the string to be searched for.
  764. Return Value:
  765. an index into the array of choice , -1 if the given string is not found.
  766. Notes:
  767. ----------------------------------------------------------------------------*/
  768. {
  769. int i;
  770. char * p;
  771. for( i = 0; ( p = (char *)pArrayOfChoices[ i ].pChoice ) != 0 ; ++i )
  772. {
  773. if( strcmp( p, pGivenString ) == 0 )
  774. return pArrayOfChoices[ i ].Choice;
  775. }
  776. return -1;
  777. }
  778. BOOL
  779. CMD_ARG::IsPrefixDifferentForStubs()
  780. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  781. Routine Description:
  782. see if any prefix for client or server or switch are different
  783. Arguments:
  784. None.
  785. Return Value:
  786. BOOL - true if different prefix strings.
  787. Notes:
  788. ----------------------------------------------------------------------------*/
  789. {
  790. char * pCPrefix;
  791. char * pSPrefix;
  792. char * pSwPrefix;
  793. pCPrefix = GetUserPrefix( PREFIX_CLIENT_STUB );
  794. pSPrefix = GetUserPrefix( PREFIX_SERVER_MGR );
  795. pSwPrefix = GetUserPrefix( PREFIX_SWICH_PROTOTYPE );
  796. if ( !pCPrefix )
  797. pCPrefix = "";
  798. if ( !pSPrefix )
  799. pSPrefix = "";
  800. if ( !pSwPrefix )
  801. pSwPrefix = "";
  802. return (BOOL) strcmp( pCPrefix, pSPrefix ) ||
  803. (BOOL) strcmp( pCPrefix, pSwPrefix ) ||
  804. (BOOL) strcmp( pSPrefix, pSwPrefix );
  805. }
  806. short
  807. pair_switch::GetNext( char ** pSys, char ** pUser )
  808. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  809. Routine Description:
  810. Get the Next pair of system & user values
  811. Arguments:
  812. None.
  813. Return Value:
  814. index in array of user value
  815. Notes:
  816. ----------------------------------------------------------------------------*/
  817. {
  818. // find the next non-null user string
  819. Current++;
  820. while ( ( Current < ArraySize) && !pUserStrings[ Current ] )
  821. Current++;
  822. if ( Current == ArraySize )
  823. return FALSE;
  824. // search for the first choice that matches this index
  825. *pUser = pUserStrings[Current];
  826. for ( short i = 0; i < ArraySize; i++ )
  827. {
  828. if ( ( pArrayOfChoices[i].Choice = Current ) != 0 )
  829. {
  830. *pSys = (char *)pArrayOfChoices[i].pChoice;
  831. return TRUE;
  832. }
  833. }
  834. return FALSE;
  835. }
  836. void
  837. CMD_ARG::EmitConfirm(
  838. ISTREAM * pStream )
  839. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  840. Routine Description:
  841. Emit confirm the arguments by dumping onto a stream in a more concise
  842. format.
  843. Arguments:
  844. pStream - the stream to dump it to.
  845. Return Value:
  846. None.
  847. ----------------------------------------------------------------------------*/
  848. {
  849. short Option;
  850. char *pEnvName, *pOptFlagName;
  851. char Buffer[100];
  852. pStream->Write( "/* Compiler settings for " );
  853. if ( !pCommand->IsSwitchDefined( SWITCH_NO_STAMP ) )
  854. {
  855. pStream->Write( GetInputFileName() );
  856. if ( IsSwitchDefined( SWITCH_ACF ) )
  857. {
  858. pStream->Write( ", " );
  859. pStream->Write( GetAcfFileName() );
  860. }
  861. }
  862. else
  863. {
  864. char FileName[_MAX_FNAME];
  865. char Ext[_MAX_EXT];
  866. GetInputFileNameComponents(NULL, NULL, FileName, Ext);
  867. pStream->Write(FileName);
  868. pStream->Write(Ext);
  869. if ( IsSwitchDefined( SWITCH_ACF ) )
  870. {
  871. pStream->Write( ", " );
  872. GetAcfFileNameComponents(NULL, NULL, FileName, Ext);
  873. pStream->Write(FileName);
  874. pStream->Write(Ext);
  875. }
  876. }
  877. pStream->Write( ":" );
  878. pStream->NewLine();
  879. pOptFlagName = "Os";
  880. if( GetOptimizationFlags() & OPTIMIZE_INTERPRETER )
  881. {
  882. if( OptimFlags & OPTIMIZE_INTERPRETER_IX )
  883. pOptFlagName= "Ox";
  884. else if( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
  885. pOptFlagName= "Oicf";
  886. else if( GetOptimizationFlags() & OPTIMIZE_STUBLESS_CLIENT )
  887. pOptFlagName= "Oic";
  888. else
  889. pOptFlagName= "Oi";
  890. }
  891. pEnvName = (GetEnv() == ENV_WIN64) ? "Win64"
  892. : "Win32";
  893. sprintf( Buffer, " %s, W%d, Zp%d, env=%s (%s%s)",
  894. pOptFlagName,
  895. GetWarningLevel(),
  896. GetZeePee(),
  897. pEnvName,
  898. (IsDoubleRunFor64() ? "64b run" : "32b run"),
  899. (HasAppend64() ? ",appending" : "") );
  900. pStream->Write( Buffer );
  901. pStream->NewLine();
  902. pStream->Write(" protocol : " );
  903. switch ( TargetSyntax )
  904. {
  905. case SYNTAX_DCE:
  906. pStream->Write("dce ");
  907. break;
  908. case SYNTAX_NDR64:
  909. pStream->Write("ndr64 ");
  910. break;
  911. case SYNTAX_BOTH:
  912. pStream->Write("all ");
  913. break;
  914. }
  915. if ( IsSwitchDefined( SWITCH_MS_EXT))
  916. pStream->Write( ", ms_ext" );
  917. if ( IsSwitchDefined( SWITCH_APP_CONFIG))
  918. pStream->Write( ", app_config" );
  919. if ( IsSwitchDefined( SWITCH_C_EXT))
  920. pStream->Write( ", c_ext" );
  921. if ( IsSwitchDefined( SWITCH_MS_UNION))
  922. pStream->Write( ", ms_union" );
  923. if ( IsSwitchDefined( SWITCH_OLDNAMES))
  924. pStream->Write( ", oldnames" );
  925. if ( IsSwitchDefined( SWITCH_ROBUST ))
  926. pStream->Write( ", robust" );
  927. if ( IsSwitchDefined( SWITCH_MS_CONF_STRUCT))
  928. pStream->Write( ", ms_conf_struct" );
  929. pStream->NewLine();
  930. strcpy( Buffer, " error checks: " );
  931. Option = GetErrorOption();
  932. if( Option != ERROR_NONE )
  933. {
  934. if( Option & ERROR_ALLOCATION )
  935. strcat( Buffer, "allocation ");
  936. if( Option & ERROR_REF )
  937. strcat( Buffer, "ref ");
  938. if( Option & ERROR_BOUNDS_CHECK )
  939. strcat( Buffer, "bounds_check ");
  940. if( Option & ERROR_ENUM )
  941. strcat( Buffer, "enum ");
  942. if( Option & ERROR_STUB_DATA )
  943. strcat( Buffer, "stub_data ");
  944. }
  945. else
  946. strcat( Buffer, "none" );
  947. pStream->Write( Buffer );
  948. if ( 0 != WireCompatOption)
  949. {
  950. pStream->WriteOnNewLine( " wire_compat options: " );
  951. if( ErrorOption & WIRE_COMPAT_ENUM16UNIONALIGN )
  952. pStream->Write( "enum16unionalign ");
  953. pStream->NewLine();
  954. }
  955. if ( IsSwitchDefined( SWITCH_NO_FMT_OPT))
  956. pStream->Write( ", no_format_optimization" );
  957. if ( IsSwitchDefined( SWITCH_RPCSS))
  958. pStream->Write( ", memory management on" );
  959. if ( IsSwitchDefined( SWITCH_NETMON))
  960. pStream->Write( ", NetMon" );
  961. if ( IsSwitchDefined( SWITCH_USE_EPV))
  962. pStream->Write( ", use_epv" );
  963. if ( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV))
  964. pStream->Write( ", no_default_epv" );
  965. pStream->NewLine();
  966. pStream->Write( " VC __declspec() decoration level: " );
  967. if ( GetMSCVer() < 1100 )
  968. pStream->Write( " none " );
  969. else
  970. {
  971. pStream->NewLine();
  972. pStream->Write( " __declspec(uuid()), __declspec(selectany), __declspec(novtable)\n" );
  973. pStream->Write( " DECLSPEC_UUID(), MIDL_INTERFACE()" );
  974. }
  975. pStream->NewLine();
  976. #if defined(TARGET_RKK)
  977. switch ( TargetSystem )
  978. {
  979. case NT35:
  980. pTarget = "NT 3.5";
  981. break;
  982. case NT351:
  983. pTarget = "NT 3.51 and Win95";
  984. break;
  985. case NT40:
  986. pTarget = "NT 4.0";
  987. break;
  988. default:
  989. pTarget = "NT ???";
  990. }
  991. pStream->Write( " Release: this stub is compatible with " );
  992. pStream->Write( pTarget );
  993. pStream->Write( " release" );
  994. pStream->NewLine();
  995. pStream->Write( " or a later version of MIDL and RPC" );
  996. pStream->NewLine();
  997. #endif
  998. pStream->Write( "*/" );
  999. pStream->NewLine();
  1000. }
  1001. // ISSUE-2000/08/03-mikew
  1002. // The ia64 C++ compiler is incorrectly optimizing memcpy in some cases.
  1003. // Mark the source buffer as unaligned to work around it. To repro just run
  1004. // midlc in a debugger and it will align fault while parsing the command file
  1005. #ifndef UNALIGNED
  1006. #ifdef IA64
  1007. #define UNALIGNED __unaligned
  1008. #else
  1009. #define UNALIGNED
  1010. #endif
  1011. #endif
  1012. #define CopyIntFromBuffer( buffer, dest ) memcpy( &dest, (UNALIGNED char *) (buffer), sizeof( dest ) ), pBuffer += sizeof( dest )
  1013. #define CopyStrFromBuffer( buffer, dest ) { \
  1014. char *sz = dest; \
  1015. while ( *buffer ) *sz++ = *buffer++;\
  1016. *sz++ = 0; \
  1017. buffer++; \
  1018. }
  1019. char*
  1020. AllocCopyStrFromBuffer( char* buffer, char*& dest )
  1021. {
  1022. unsigned long ulSize = 0;
  1023. char* szt = buffer;
  1024. while ( *szt++ ) ulSize++;
  1025. char* sz = ( ulSize ) ? new char[ ulSize + 1 ] : 0;
  1026. dest = sz;
  1027. if ( sz )
  1028. memcpy( sz, buffer, ulSize+1 );
  1029. return buffer+ulSize+1;
  1030. }
  1031. void
  1032. filename_switch::StreamIn( char*& pBuffer )
  1033. {
  1034. pBuffer = AllocCopyStrFromBuffer( pBuffer, pFullName );
  1035. }
  1036. void
  1037. filename_switch::StreamOut( STREAM* stream )
  1038. {
  1039. stream->Write(pFullName);
  1040. }
  1041. void
  1042. onetime_switch::StreamIn( char*& pBuffer )
  1043. {
  1044. pBuffer = AllocCopyStrFromBuffer( pBuffer, pOpt );
  1045. }
  1046. void
  1047. onetime_switch::StreamOut( STREAM *stream )
  1048. {
  1049. stream->Write( pOpt );
  1050. }
  1051. void
  1052. multiple_switch::StreamIn( char*& pBuffer )
  1053. {
  1054. unsigned long ulCount = 0;
  1055. CopyIntFromBuffer( pBuffer, ulCount );
  1056. while ( ulCount-- )
  1057. {
  1058. char* sz = 0;
  1059. size_t ActualOffset;
  1060. CopyIntFromBuffer( pBuffer, ActualOffset );
  1061. pBuffer = AllocCopyStrFromBuffer( pBuffer, sz );
  1062. Add( sz, ActualOffset );
  1063. }
  1064. }
  1065. void
  1066. multiple_switch::StreamOut( STREAM* stream )
  1067. {
  1068. OptList* pTemp = pFirst;
  1069. unsigned long ulCount = 0;
  1070. while ( pTemp )
  1071. {
  1072. ulCount++;
  1073. pTemp = pTemp->pNext;
  1074. }
  1075. stream->Write(&ulCount, sizeof(ulCount));
  1076. pTemp = pFirst;
  1077. while ( pTemp )
  1078. {
  1079. stream->Write( &pTemp->ActualOffset, sizeof( pTemp->ActualOffset ) );
  1080. stream->Write( pTemp->pStr );
  1081. pTemp = pTemp->pNext;
  1082. }
  1083. }
  1084. void
  1085. pair_switch::StreamIn( char*& pBuffer )
  1086. {
  1087. CopyIntFromBuffer( pBuffer, ArraySize );
  1088. pUserStrings = new PSTR [ ArraySize ];
  1089. if ( pUserStrings )
  1090. {
  1091. for ( short i = 0; i < ArraySize; i++ )
  1092. {
  1093. pBuffer = AllocCopyStrFromBuffer( pBuffer, pUserStrings[i] );
  1094. }
  1095. }
  1096. }
  1097. void
  1098. pair_switch::StreamOut( STREAM *stream )
  1099. {
  1100. stream->Write( &ArraySize, sizeof( ArraySize ) );
  1101. for ( short i = 0 ; i < ArraySize ; i++ )
  1102. {
  1103. stream->Write( pUserStrings[i] );
  1104. }
  1105. }
  1106. void
  1107. CMD_ARG::StreamOut( STREAM *stream )
  1108. {
  1109. #define Stream( x ) ( stream->Write( &x, sizeof( x ) ) )
  1110. Stream( iMagic );
  1111. Stream( MajorVersion );
  1112. Stream( MinorVersion );
  1113. Stream( UpdateNumber );
  1114. Stream( fHasAppend64 );
  1115. Stream( switch_def_vector );
  1116. Stream( fClient );
  1117. Stream( fServer );
  1118. Stream( Env );
  1119. Stream( CharOption );
  1120. Stream( fMintRun );
  1121. Stream( ErrorOption );
  1122. Stream( WireCompatOption );
  1123. Stream( ConfigMask );
  1124. Stream( MSCVersion );
  1125. Stream( fShowLogo );
  1126. // BUGBUG: VersionControl is a class
  1127. Stream( VersionControl );
  1128. Stream( OptimFlags );
  1129. Stream( OptimLevel );
  1130. Stream( TargetSystem );
  1131. Stream( iArgV );
  1132. Stream( cArgs );
  1133. Stream( WLevel );
  1134. Stream( ZeePee );
  1135. Stream( EnumSize );
  1136. Stream( LocaleId );
  1137. Stream( fDoubleFor64 );
  1138. Stream( TargetSyntax );
  1139. #undef Stream
  1140. stream->Write( &szCompileTime[0] );
  1141. stream->Write( &szCompilerVersion[0] );
  1142. //
  1143. // The following switches write a single NULL character is they are not
  1144. // present on the command line
  1145. //
  1146. #define StreamIfNecessary( x ) ( x ? x->StreamOut(stream) : stream->Write( '\0' ) )
  1147. StreamIfNecessary( pInputFNSwitch );
  1148. StreamIfNecessary( pOutputPathSwitch );
  1149. StreamIfNecessary( pCStubSwitch );
  1150. StreamIfNecessary( pSStubSwitch );
  1151. StreamIfNecessary( pHeaderSwitch );
  1152. StreamIfNecessary( pAcfSwitch );
  1153. StreamIfNecessary( pIIDSwitch );
  1154. StreamIfNecessary( pDllDataSwitch );
  1155. StreamIfNecessary( pProxySwitch );
  1156. StreamIfNecessary( pTlibSwitch );
  1157. StreamIfNecessary( pNetmonStubSwitch );
  1158. StreamIfNecessary( pNetmonStubObjSwitch );
  1159. StreamIfNecessary( pRedirectOutputSwitch );
  1160. StreamIfNecessary( pCppCmdSwitch );
  1161. StreamIfNecessary( pCppOptSwitch );
  1162. StreamIfNecessary( pMSCVerSwitch );
  1163. StreamIfNecessary( pDebug64Switch );
  1164. StreamIfNecessary( pDebug64OptSwitch );
  1165. #undef StreamIfNecessary
  1166. //
  1167. // The following switches write (long) 0 if they are not present on
  1168. // the command line
  1169. //
  1170. #define StreamIfNecessary( x ) \
  1171. { \
  1172. unsigned long zero = 0; \
  1173. x ? x->StreamOut(stream) \
  1174. : stream->Write( &zero, sizeof( zero ) ); \
  1175. }
  1176. StreamIfNecessary( pSwitchPrefix );
  1177. StreamIfNecessary( pSwitchSuffix );
  1178. StreamIfNecessary( pDSwitch );
  1179. StreamIfNecessary( pISwitch );
  1180. StreamIfNecessary( pUSwitch );
  1181. #undef StreamIfNecessary
  1182. }
  1183. STATUS_T
  1184. CMD_ARG::StreamIn( char* pBuffer )
  1185. {
  1186. __int64 magicNumber = 0;
  1187. CopyIntFromBuffer( pBuffer, magicNumber );
  1188. if ( magicNumber != iMagic )
  1189. {
  1190. return BAD_CMD_FILE;
  1191. }
  1192. CopyIntFromBuffer( pBuffer, MajorVersion );
  1193. CopyIntFromBuffer( pBuffer, MinorVersion );
  1194. CopyIntFromBuffer( pBuffer, UpdateNumber );
  1195. if ( ( MajorVersion != rmj ) ||
  1196. ( MinorVersion != rmm ) ||
  1197. ( UpdateNumber != rup ) )
  1198. {
  1199. return INCONSIST_VERSION;
  1200. }
  1201. CopyIntFromBuffer( pBuffer, fHasAppend64 );
  1202. CopyIntFromBuffer( pBuffer, switch_def_vector );
  1203. CopyIntFromBuffer( pBuffer, fClient );
  1204. CopyIntFromBuffer( pBuffer, fServer );
  1205. CopyIntFromBuffer( pBuffer, Env );
  1206. CopyIntFromBuffer( pBuffer, CharOption );
  1207. CopyIntFromBuffer( pBuffer, fMintRun );
  1208. CopyIntFromBuffer( pBuffer, ErrorOption );
  1209. CopyIntFromBuffer( pBuffer, WireCompatOption );
  1210. CopyIntFromBuffer( pBuffer, ConfigMask );
  1211. CopyIntFromBuffer( pBuffer, MSCVersion );
  1212. CopyIntFromBuffer( pBuffer, fShowLogo );
  1213. CopyIntFromBuffer( pBuffer, VersionControl );
  1214. CopyIntFromBuffer( pBuffer, OptimFlags );
  1215. CopyIntFromBuffer( pBuffer, OptimLevel );
  1216. CopyIntFromBuffer( pBuffer, TargetSystem );
  1217. CopyIntFromBuffer( pBuffer, iArgV );
  1218. CopyIntFromBuffer( pBuffer, cArgs );
  1219. CopyIntFromBuffer( pBuffer, WLevel );
  1220. CopyIntFromBuffer( pBuffer, ZeePee );
  1221. CopyIntFromBuffer( pBuffer, EnumSize );
  1222. CopyIntFromBuffer( pBuffer, LocaleId );
  1223. CopyIntFromBuffer( pBuffer, fDoubleFor64 );
  1224. CopyIntFromBuffer( pBuffer, TargetSyntax );
  1225. CopyStrFromBuffer( pBuffer, &szCompileTime[0] );
  1226. CopyStrFromBuffer( pBuffer, &szCompilerVersion[0] );
  1227. pInputFNSwitch = new filename_switch();
  1228. pOutputPathSwitch = new filename_switch();
  1229. pCStubSwitch = new filename_switch();
  1230. pSStubSwitch = new filename_switch();
  1231. pHeaderSwitch = new filename_switch();
  1232. pAcfSwitch = new filename_switch();
  1233. pIIDSwitch = new filename_switch();
  1234. pDllDataSwitch = new filename_switch();
  1235. pProxySwitch = new filename_switch();
  1236. pTlibSwitch = new filename_switch();
  1237. pNetmonStubSwitch = new filename_switch();
  1238. pNetmonStubObjSwitch = new filename_switch();
  1239. pRedirectOutputSwitch = new filename_switch();
  1240. pCppCmdSwitch = new onetime_switch();
  1241. pCppOptSwitch = new onetime_switch();
  1242. pMSCVerSwitch = new onetime_switch();
  1243. pDebug64Switch = new onetime_switch();
  1244. pDebug64OptSwitch = new onetime_switch();
  1245. pSwitchPrefix = new pair_switch( &PrefixChoices[0] );
  1246. pSwitchSuffix = new pair_switch( &PrefixChoices[0] );
  1247. pDSwitch = new multiple_switch();
  1248. pISwitch = new multiple_switch();
  1249. pUSwitch = new multiple_switch();
  1250. pInputFNSwitch->StreamIn( pBuffer );
  1251. pOutputPathSwitch->StreamIn( pBuffer );
  1252. pCStubSwitch->StreamIn( pBuffer );
  1253. pSStubSwitch->StreamIn( pBuffer );
  1254. pHeaderSwitch->StreamIn( pBuffer );
  1255. pAcfSwitch->StreamIn( pBuffer );
  1256. pIIDSwitch->StreamIn( pBuffer );
  1257. pDllDataSwitch->StreamIn( pBuffer );
  1258. pProxySwitch->StreamIn( pBuffer );
  1259. pTlibSwitch->StreamIn( pBuffer );
  1260. pNetmonStubSwitch->StreamIn( pBuffer );
  1261. pNetmonStubObjSwitch->StreamIn( pBuffer );
  1262. pRedirectOutputSwitch->StreamIn( pBuffer );
  1263. pCppCmdSwitch->StreamIn( pBuffer );
  1264. pCppOptSwitch->StreamIn( pBuffer );
  1265. pMSCVerSwitch->StreamIn( pBuffer );
  1266. pDebug64Switch->StreamIn( pBuffer );
  1267. pDebug64OptSwitch->StreamIn( pBuffer );
  1268. pSwitchPrefix->StreamIn( pBuffer );
  1269. pSwitchSuffix->StreamIn( pBuffer );
  1270. pDSwitch->StreamIn( pBuffer );
  1271. pISwitch->StreamIn( pBuffer );
  1272. pUSwitch->StreamIn( pBuffer );
  1273. // HACK ALERT: we want to generate right header if
  1274. // -protocol all and no -env is specified.
  1275. if ( ( TargetSyntax == SYNTAX_BOTH ) &&
  1276. ( Env == ENV_WIN32 ) &&
  1277. !IsSwitchDefined( SWITCH_INTERNAL ) )
  1278. {
  1279. TargetSyntax = SYNTAX_DCE;
  1280. if ( !IsSwitchDefined( SWITCH_ENV) )
  1281. SetNeedsNDR64Header();
  1282. }
  1283. if ( NeedsNDR64Run() )
  1284. GetNdrVersionControl().SetHasMultiTransferSyntax();
  1285. return STATUS_OK;
  1286. }