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

2529 lines
84 KiB

  1. #include "headers.hxx"
  2. // COM+ shim. Uncomment below line to build the COM+ shim.
  3. //#define COMPLUS_SHIM
  4. #ifndef X_PDLPARSE_HXX_
  5. #define X_PDLPARSE_HXX_
  6. #include "pdlparse.hxx"
  7. #endif
  8. #ifndef X_DATA_HXX_
  9. #define X_DATA_HXX_
  10. #include "data.hxx"
  11. #endif
  12. #ifndef X_VTABLE_HXX_
  13. #define X_VTABLE_HXX_
  14. #include <vtable.hxx>
  15. #endif
  16. #ifndef X_ASSERT_H_
  17. #define X_ASSERT_H_
  18. #include <assert.h>
  19. #endif
  20. // Win16 needs the old typelibs. Old Typelib can't cope
  21. // with default parameters. So if this flag is set we
  22. // ignore all the default parameters in the PDL files.
  23. // This flag is set based on run-time argument "win16"
  24. BOOL gbWin16Mode = FALSE;
  25. //
  26. // TO deal with the LONG_PTR problem : we need to translate it to different
  27. // automation type for Win32 and Win64
  28. //
  29. BOOL gfWin64 = FALSE;
  30. static
  31. BOOL
  32. GetALine ( FILE *fp, char *szLineBuffer, int nMaxLen, int &nLenRead );
  33. void PDLError (char *szTextError)
  34. {
  35. printf ( "PDLParse (0) : error PDL0001: /G %s", szTextError);
  36. }
  37. BOOL TagArray::CompareTag ( INT nIndex, char *szWith )
  38. {
  39. if ( szValues [ nIndex ] == NULL )
  40. return FALSE;
  41. else
  42. return _stricmp ( szValues [ nIndex ], szWith ) == 0 ? TRUE : FALSE;
  43. }
  44. char *TagArray::GetTagValue ( INT nIndex )
  45. {
  46. // If the string is null always return an empty string
  47. if ( szValues [ nIndex ] == NULL )
  48. return szEmptyString;
  49. else
  50. return szValues [ nIndex ];
  51. }
  52. BOOL TagArray::AddTag ( int iTag, LPCSTR szStr, int nLen )
  53. {
  54. if ( szValues [ iTag ] )
  55. delete [] ( szValues [ iTag ] );
  56. if ( nLen == -1 )
  57. nLen = strlen ( szStr );
  58. if ( szStr == NULL )
  59. {
  60. szValues [ iTag ] = NULL;
  61. return TRUE;
  62. }
  63. szValues [ iTag ] = new char [ nLen + 1 ];
  64. if ( !szValues [ iTag ] )
  65. return FALSE;
  66. strncpy ( szValues [ iTag ], szStr, nLen );
  67. szValues [ iTag ][ nLen ] = '\0';
  68. return TRUE;
  69. }
  70. Token::~Token()
  71. {
  72. if ( _pChildList )
  73. _pChildList -> Release();
  74. }
  75. void CTokenListWalker::Reset ( void )
  76. {
  77. _pCurrentToken = NULL;
  78. if ( _pszFileName )
  79. _fInCurrentFile = FALSE;
  80. else
  81. _fInCurrentFile = TRUE;
  82. _fAtEnd = FALSE;
  83. }
  84. UINT CString::Lookup ( Associate *pArray, LPCSTR pStr )
  85. {
  86. UINT uIndex =0;
  87. while ( pArray->szKey )
  88. {
  89. if ( strcmp ( pArray->szKey, pStr ) == 0 )
  90. {
  91. strcpy ( szString, pArray->szValue );
  92. return uIndex;
  93. }
  94. pArray++; uIndex++;
  95. }
  96. return (UINT)-1;
  97. }
  98. UINT CString::Lookup ( AssociateDataType *pArray, LPCSTR pStr )
  99. {
  100. UINT uIndex =0;
  101. while ( pArray->szKey )
  102. {
  103. if ( strcmp ( pArray->szKey, pStr ) == 0 )
  104. {
  105. strcpy ( szString, pArray->szValue );
  106. return uIndex;
  107. }
  108. pArray++; uIndex++;
  109. }
  110. return (UINT)-1;
  111. }
  112. /* static */
  113. char *TagArray::szEmptyString = "";
  114. BOOL
  115. GetStdInLine ( char *szLineBuffer, int nMaxLen )
  116. {
  117. int nLenRead,i;
  118. int nTotalRead = 0;
  119. do
  120. {
  121. if ( !GetALine ( NULL, szLineBuffer+nTotalRead,
  122. nMaxLen, nLenRead ) )
  123. {
  124. return FALSE;
  125. }
  126. nTotalRead += nLenRead;
  127. for ( i = nTotalRead-1 ; i >= 0 ; i-- )
  128. {
  129. if ( !isspace ( szLineBuffer [ i ] ) )
  130. {
  131. break;
  132. }
  133. }
  134. if ( i > 0 )
  135. {
  136. if ( szLineBuffer [ i ] == '\\' )
  137. {
  138. szLineBuffer [ i ] = ' ';
  139. szLineBuffer [ i+1 ] = '\0';
  140. // we'll go on to the next line
  141. nTotalRead = i+1;
  142. // Don't break, so we append the next line
  143. }
  144. else
  145. {
  146. // Regular line
  147. szLineBuffer [ i+1 ] = '\0';
  148. nTotalRead = i+1;
  149. // Not continuing - break so we process this line
  150. break;
  151. }
  152. }
  153. else
  154. {
  155. // Completly blank line - ignore it...
  156. nTotalRead = 0;
  157. }
  158. } while ( nTotalRead < nMaxLen );
  159. return TRUE;
  160. }
  161. static
  162. BOOL
  163. GetALine ( FILE *fp,char *szLineBuffer, int nMaxLen, int &nLenRead )
  164. {
  165. nLenRead = 0;
  166. // Keep reading in data until we blow the buffer size, or hit a real
  167. // EOL. If we have a trailing \ character, go on to the next line
  168. if ( fp )
  169. {
  170. if ( !fgets ( szLineBuffer, nMaxLen, fp ) )
  171. {
  172. return FALSE;
  173. }
  174. }
  175. else
  176. {
  177. if ( !gets ( szLineBuffer ) )
  178. {
  179. return FALSE;
  180. }
  181. }
  182. nLenRead = strlen ( szLineBuffer );
  183. if ( szLineBuffer [ 0 ] && szLineBuffer [ nLenRead-1 ] == '\n' )
  184. {
  185. szLineBuffer [ --nLenRead ] = '\0';
  186. }
  187. return TRUE;
  188. }
  189. Token *CTokenList::FindToken ( char *pTokenName, DESCRIPTOR_TYPE nType ) const
  190. {
  191. Token *pToken;
  192. for ( pToken = _pFirstToken ;
  193. pToken != NULL ; pToken = pToken-> GetNextToken() )
  194. {
  195. // Token 0 is always the name
  196. // Case sensitive match
  197. if ( strcmp ( pToken->GetTagValue ( 0 ), pTokenName ) == 0 )
  198. {
  199. return pToken->GetType() ? pToken : NULL;
  200. }
  201. }
  202. return NULL;
  203. }
  204. Token *CTokenList::AddNewToken ( DESCRIPTOR_TYPE nTokenDescriptor )
  205. {
  206. Token *pNewToken = new Token ( nTokenDescriptor );
  207. if ( !pNewToken )
  208. return NULL;
  209. if ( !_pFirstToken )
  210. {
  211. _pFirstToken = pNewToken;
  212. }
  213. else
  214. {
  215. _pLastToken->SetNextToken ( pNewToken );
  216. }
  217. _pLastToken = pNewToken;
  218. _uTokens++;
  219. return pNewToken;
  220. }
  221. /*
  222. Scan the input file and extract the 4 build arguments
  223. Do this to be compatible with previous version of mkprop
  224. */
  225. //--------------------------------------------------
  226. //TODO: Modify this to accept flags for ia64/i386!
  227. //--------------------------------------------------
  228. static
  229. BOOL
  230. ScanBuildFile ( char *szBuildFileName,
  231. char *szInputFile,
  232. char *szOutputFileRoot,
  233. char *szPDLFileName,
  234. char *szOutputPath )
  235. {
  236. FILE *fp = NULL;
  237. char szLineBuffer [ MAX_LINE_LEN+1 ];
  238. BOOL fReturn = FALSE;
  239. int nRead;
  240. fp = fopen ( szBuildFileName, "r" );
  241. if ( !fp )
  242. {
  243. printf ( "Cannot open %s\n", szBuildFileName );
  244. goto cleanup;
  245. }
  246. if ( !GetALine ( fp, szLineBuffer, sizeof ( szLineBuffer ), nRead ) )
  247. {
  248. printf ( "Cannot read %s\n", szBuildFileName );
  249. goto cleanup;
  250. }
  251. // Old input file used to support "-<flags>" - which was never used
  252. // so I just skip them
  253. if (sscanf ( szLineBuffer, "- %s %s %s",
  254. (LPCSTR)szOutputFileRoot,
  255. (LPCSTR)szInputFile,
  256. (LPCSTR)szOutputPath ) != 3)
  257. {
  258. printf ( "Cannot read params from %s\n", szBuildFileName );
  259. goto cleanup;
  260. }
  261. while ( GetALine ( fp, szLineBuffer, sizeof ( szLineBuffer ), nRead ) )
  262. printf ( "Build file Line:%s\n",szLineBuffer );
  263. strcpy ( szPDLFileName, szInputFile );
  264. fReturn = TRUE;
  265. goto cleanup;
  266. cleanup:
  267. if ( fp )
  268. fclose ( fp );
  269. return fReturn;
  270. }
  271. CTokenList::~CTokenList()
  272. {
  273. Token *pNextToken;
  274. Token *pToken;
  275. // Tidy up the list
  276. for ( pToken = _pFirstToken ; pToken != NULL ; pToken = pNextToken )
  277. {
  278. pNextToken = pToken -> _pNextToken;
  279. delete pToken;
  280. }
  281. }
  282. Token *CTokenListWalker::GetNext ( void )
  283. {
  284. Token *pToken;
  285. while ( pToken = GetNextToken() )
  286. {
  287. if ( _pszFileName )
  288. {
  289. if ( _pCurrentToken->nType == TYPE_FILE )
  290. {
  291. if ( _fInCurrentFile && _pszFileName )
  292. {
  293. _fInCurrentFile = FALSE;
  294. }
  295. else
  296. {
  297. _fInCurrentFile = pToken->CompareTag ( FILE_TAG, _pszFileName );
  298. }
  299. }
  300. else if ( _fInCurrentFile )
  301. {
  302. break;
  303. }
  304. }
  305. else
  306. {
  307. break;
  308. }
  309. }
  310. return pToken;
  311. }
  312. Token *CTokenListWalker::GetNext ( DESCRIPTOR_TYPE Type, LPCSTR pName )
  313. {
  314. Token *pToken;
  315. while ( pToken = GetNext() )
  316. {
  317. if ( pToken -> nType == Type &&
  318. ( pName == NULL || _stricmp ( pName, pToken -> GetTagValue ( NAME_TAG ) ) == 0 ) )
  319. {
  320. return pToken;
  321. }
  322. }
  323. return NULL;
  324. }
  325. Token *Token::AddChildToken ( DESCRIPTOR_TYPE nType )
  326. {
  327. Token *pNewToken;
  328. if ( _pChildList == NULL )
  329. {
  330. if ( ( _pChildList = new CTokenList() ) == NULL )
  331. {
  332. return NULL;
  333. }
  334. }
  335. // Created the new arg token
  336. if ( ! ( pNewToken = _pChildList->AddNewToken ( nType ) ) )
  337. {
  338. return NULL;
  339. }
  340. return pNewToken;
  341. }
  342. void Token::CalculateEnumMask ( Token *pParentToken )
  343. {
  344. INT nValue;
  345. if ( IsSet ( EVAL_VALUE ) )
  346. {
  347. nValue = atoi ( GetTagValue ( EVAL_VALUE ) );
  348. }
  349. else
  350. {
  351. char szText [ MAX_LINE_LEN+1 ];
  352. nValue = pParentToken -> nNextEnumValue;
  353. // Plug the new value into the tag
  354. sprintf ( szText, "%d", nValue );
  355. AddTag ( EVAL_VALUE, szText );
  356. }
  357. if ( nValue >=0 && nValue < 32 )
  358. {
  359. pParentToken -> uEnumMask |= (1 << (UINT)nValue);
  360. }
  361. pParentToken -> nNextEnumValue = ++nValue;
  362. }
  363. UINT Token::GetChildTokenCount ( void )
  364. {
  365. return _pChildList ? _pChildList -> GetTokenCount() : 0;
  366. }
  367. // Helper for building comma sperarated arg lists
  368. // if the arg is set add the corresponding text to
  369. // the arg string
  370. void Token::AddParam ( CString &szArg, INT nTag, LPCSTR szText )
  371. {
  372. if ( IsSet ( nTag ) )
  373. {
  374. if ( szArg [ 0 ] != '\0' )
  375. szArg += ", ";
  376. szArg += szText;
  377. }
  378. }
  379. // Helper for building comma sperarated arg lists
  380. // if the arg is set add the corresponding text to
  381. // the arg string. With the current arg value replacing the %s
  382. // szArg must contain one and only one %s
  383. void Token::AddParamStr ( CString &szArg, INT nTag, LPCSTR szText )
  384. {
  385. char szTemp [ MAX_LINE_LEN+1 ];
  386. if ( IsSet ( nTag ) )
  387. {
  388. sprintf ( szTemp, (LPCSTR)szText, (LPCSTR)GetTagValue ( nTag ) );
  389. if ( szArg [ 0 ] != '\0' )
  390. szArg += ", ";
  391. szArg += szTemp;
  392. }
  393. }
  394. void Token::Clone ( Token *pFrom )
  395. {
  396. UINT i;
  397. INT nLen;
  398. for ( i = 0 ; i < MAX_TAGS ; i++ )
  399. {
  400. nLen = pFrom -> TagValues.GetInternalValue ( i ) ? strlen ( pFrom -> TagValues.GetInternalValue ( i ) ) : 0;
  401. TagValues.AddTag ( i, pFrom -> TagValues.GetInternalValue ( i ), nLen );
  402. }
  403. nType = pFrom -> nType;
  404. // Now clone the child arg list if there is one
  405. // Implemented an Addref/Release to simplify the process
  406. if ( _pChildList )
  407. {
  408. _pChildList -> Release();
  409. _pChildList = NULL;
  410. }
  411. if ( pFrom -> _pChildList )
  412. {
  413. // Point ourselves at the child list & AddRef it
  414. _pChildList = pFrom -> _pChildList;
  415. _pChildList -> AddRef();
  416. }
  417. }
  418. struct METH_PARAMS {
  419. BOOL fOptional;
  420. BOOL fDefaultValue;
  421. CString szVTParamType;
  422. CString szCParamType;
  423. VARTYPE vtParam;
  424. };
  425. #define ATYPE_Undefined 0
  426. #define ATYPE_Method 1
  427. #define ATYPE_GetProperty 2
  428. #define ATYPE_SetProperty 4
  429. #define ATYPE_ReturnValue 8
  430. #define ATYPE_ParametersOnly 16
  431. struct DispatchHandler {
  432. CString szRawString;
  433. WORD invokeType;
  434. CString szDispName;
  435. CString szVTResult;
  436. CString szCResult;
  437. VARTYPE vtResult;
  438. METH_PARAMS params[8];
  439. };
  440. #define MAX_HANDLERS 130
  441. #define MAX_IIDS 330
  442. int _cHandlers;
  443. DispatchHandler _allHandlers[MAX_HANDLERS];
  444. int _cIID;
  445. LPSTR _allIIDs[MAX_IIDS];
  446. #ifdef COMPLUS_SHIM
  447. //////////////////////////////////////////////////////////////////////////////////////////////
  448. //////////////////////////////////////////////////////////////////////////////////////////////
  449. // Beginning of COM+ code //
  450. //////////////////////////////////////////////////////////////////////////////////////////////
  451. //////////////////////////////////////////////////////////////////////////////////////////////
  452. enum CODETYPE {CT_managed, CT_unmanaged, CT_managedNDirect};
  453. typedef void (__stdcall * NDBodyFunc)(FILE *, DispatchHandler *, CODETYPE, int);
  454. #define PARAM_NAME_PREFIX "param"
  455. #define PARAM_RESULT_PREFIX "resultParam"
  456. // When we have a setter or getter only we look to see if there were any properties with the same type that supported
  457. // getting/setting if so use that entry.
  458. BOOL AnyGSHandler(DispatchHandler & handler)
  459. {
  460. if (handler.invokeType & (ATYPE_GetProperty | ATYPE_SetProperty))
  461. {
  462. for (int i = 0; i < _cHandlers; i++)
  463. {
  464. if ((_allHandlers[i].invokeType & (ATYPE_GetProperty | ATYPE_SetProperty)) == (ATYPE_GetProperty | ATYPE_SetProperty))
  465. {
  466. if (_allHandlers[i].vtResult == handler.vtResult)
  467. {
  468. return TRUE;
  469. }
  470. }
  471. }
  472. }
  473. return FALSE;
  474. }
  475. LPCSTR ResultType(DispatchHandler *pHandler, CODETYPE codeType, BOOL *pfAllocate)
  476. {
  477. BOOL tempBool;
  478. if (!pfAllocate)
  479. {
  480. pfAllocate = &tempBool;
  481. }
  482. *pfAllocate = FALSE;
  483. VARTYPE vtResult = pHandler->vtResult & VT_TYPEMASK;
  484. if (codeType == CT_managedNDirect)
  485. {
  486. if (vtResult == VT_BSTR)
  487. {
  488. return "wchar_t*";
  489. }
  490. else if (vtResult == VT_DISPATCH || vtResult == VT_UNKNOWN)
  491. {
  492. return "unsigned int";
  493. }
  494. else if (vtResult == VT_VARIANT)
  495. {
  496. return "unsigned int";
  497. }
  498. else if (vtResult == VT_BOOL)
  499. {
  500. return "short";
  501. }
  502. else if (vtResult == VT_I4)
  503. {
  504. return "long";
  505. }
  506. else if (vtResult == VT_I2)
  507. {
  508. return "short";
  509. }
  510. else if (pHandler->vtResult == VT_ARRAY)
  511. {
  512. return "wchar_t*"; // ***TLL*** COM+: Need something different here for now it's a string.
  513. }
  514. else
  515. {
  516. return (LPCSTR)pHandler->szCResult;
  517. }
  518. }
  519. else if (codeType == CT_managed)
  520. {
  521. if (vtResult != VT_EMPTY)
  522. {
  523. if (vtResult == VT_BSTR)
  524. {
  525. return "String";
  526. }
  527. else if (vtResult == VT_DISPATCH || vtResult == VT_UNKNOWN)
  528. {
  529. return "unsigned int";
  530. }
  531. else if (vtResult == VT_VARIANT)
  532. {
  533. return "Variant";
  534. }
  535. else if (vtResult == VT_BOOL)
  536. {
  537. return "Boolean";
  538. }
  539. else if (vtResult == VT_I4)
  540. {
  541. return "long";
  542. }
  543. else if (vtResult == VT_I2)
  544. {
  545. return "short";
  546. }
  547. else if (pHandler->vtResult == VT_ARRAY)
  548. {
  549. return "String"; // ***TLL*** COM+: Need something different here for now it's a string.
  550. }
  551. else
  552. {
  553. LPCSTR pFoundSpace = strchr((LPCSTR)pHandler->szCResult, ' ');
  554. LPSTR pString;
  555. if (pFoundSpace)
  556. {
  557. UINT cLen = pFoundSpace - (LPCSTR)pHandler->szCResult;
  558. pString = new char[cLen + 1];
  559. if (pString)
  560. {
  561. *pfAllocate = TRUE;
  562. strncpy(pString, (LPCSTR)pHandler->szCResult, cLen);
  563. pString[cLen] = '\0';
  564. return pString;
  565. }
  566. else
  567. {
  568. return 0;
  569. }
  570. }
  571. else
  572. {
  573. return (LPCSTR)pHandler->szCResult;
  574. }
  575. }
  576. }
  577. else
  578. {
  579. return "void";
  580. }
  581. }
  582. else
  583. {
  584. return (LPCSTR)pHandler->szCResult;
  585. }
  586. }
  587. void
  588. OutputParameters(FILE *fpOut, DispatchHandler *pHandler, CODETYPE codeType, int invokeType)
  589. {
  590. BOOL fAllocate = FALSE;
  591. LPCSTR mappedParamType = ResultType(pHandler, codeType, &fAllocate);
  592. if (invokeType & ATYPE_GetProperty)
  593. {
  594. if (codeType != CT_managed)
  595. {
  596. fprintf(fpOut, ", %s* " PARAM_RESULT_PREFIX ")", mappedParamType);
  597. }
  598. else
  599. {
  600. fprintf(fpOut, ")");
  601. }
  602. }
  603. else if (invokeType & ATYPE_SetProperty)
  604. {
  605. fprintf(fpOut, ", %s " PARAM_NAME_PREFIX "1)", mappedParamType);
  606. }
  607. else if (invokeType & ATYPE_ReturnValue)
  608. {
  609. fprintf(fpOut, "%s ", mappedParamType);
  610. }
  611. else
  612. {
  613. int j = 0;
  614. int cArgs = 0;
  615. if (fAllocate)
  616. {
  617. delete [] (LPSTR)mappedParamType;
  618. fAllocate = FALSE;
  619. }
  620. while (pHandler->params[j].szVTParamType.Length())
  621. {
  622. VARTYPE vtParam = pHandler->params[j].vtParam & VT_TYPEMASK;
  623. if (codeType == CT_managedNDirect)
  624. {
  625. if (vtParam == VT_BSTR)
  626. {
  627. mappedParamType = "wchar_t*";
  628. }
  629. else if (vtParam == VT_DISPATCH || vtParam == VT_UNKNOWN)
  630. {
  631. mappedParamType = "unsigned int";
  632. }
  633. else if (vtParam == VT_VARIANT)
  634. {
  635. mappedParamType = "unsigned int";
  636. }
  637. else if (vtParam == VT_BOOL)
  638. {
  639. mappedParamType = "short";
  640. }
  641. else if (vtParam == VT_I4)
  642. {
  643. mappedParamType = "long";
  644. }
  645. else if (vtParam == VT_I2)
  646. {
  647. mappedParamType = "short";
  648. }
  649. else if (pHandler->params[j].vtParam == VT_ARRAY)
  650. {
  651. mappedParamType = "wchar_t*"; // ***TLL*** COM+: Need something different here for now it's a string.
  652. }
  653. else
  654. {
  655. mappedParamType = (LPCSTR)pHandler->params[j].szCParamType;
  656. }
  657. }
  658. else if (codeType == CT_managed)
  659. {
  660. if (vtParam == VT_BSTR)
  661. {
  662. mappedParamType = "String";
  663. }
  664. else if (vtParam == VT_DISPATCH || vtParam == VT_UNKNOWN)
  665. {
  666. mappedParamType = "unsigned int";
  667. }
  668. else if (vtParam == VT_VARIANT)
  669. {
  670. mappedParamType = "Variant";
  671. }
  672. else if (vtParam == VT_BOOL)
  673. {
  674. mappedParamType = "Boolean";
  675. }
  676. else if (vtParam == VT_I4)
  677. {
  678. mappedParamType = "long";
  679. }
  680. else if (vtParam == VT_I2)
  681. {
  682. mappedParamType = "short";
  683. }
  684. else if (pHandler->params[j].vtParam == VT_ARRAY)
  685. {
  686. mappedParamType = "String"; // ***TLL*** COM+: Need something different here for now it's a string.
  687. }
  688. else
  689. {
  690. mappedParamType = (LPCSTR)pHandler->params[j].szCParamType;
  691. }
  692. }
  693. else
  694. {
  695. mappedParamType = (LPCSTR)pHandler->params[j].szCParamType;
  696. }
  697. fprintf (fpOut, ", %s " PARAM_NAME_PREFIX "%i", mappedParamType, j + 1);
  698. j++;
  699. cArgs++;
  700. }
  701. if (!(invokeType & ATYPE_ParametersOnly))
  702. {
  703. if (pHandler->vtResult != VT_EMPTY)
  704. {
  705. mappedParamType = ResultType(pHandler, codeType, &fAllocate);
  706. fprintf(fpOut, ", %s " PARAM_RESULT_PREFIX, mappedParamType);
  707. }
  708. }
  709. fprintf(fpOut, ")");
  710. }
  711. if (fAllocate)
  712. {
  713. delete [] (LPSTR)mappedParamType;
  714. }
  715. }
  716. void
  717. OutputNDSignature(FILE *fpOut, DispatchHandler *pHandler, LPCSTR pPreHeader, CODETYPE codeType, NDBodyFunc pNDBodyFunc)
  718. {
  719. BOOL fSetDone = FALSE;
  720. int invokeType = pHandler->invokeType;
  721. BOOL fGetAndSet = ((invokeType & ATYPE_GetProperty) && (invokeType & ATYPE_SetProperty));
  722. CString funcName;
  723. if (!fGetAndSet)
  724. {
  725. if (AnyGSHandler(*pHandler))
  726. return;
  727. if (codeType == CT_managedNDirect || codeType == CT_unmanaged)
  728. {
  729. fprintf(fpOut, "%s NDCP_%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset", pPreHeader, (LPCSTR)(pHandler->szRawString));
  730. }
  731. else if (codeType == CT_managed)
  732. {
  733. if (!pNDBodyFunc)
  734. fprintf(fpOut, "\tstatic ");
  735. OutputParameters(fpOut, pHandler, codeType, ATYPE_ReturnValue);
  736. if (pNDBodyFunc)
  737. fprintf(fpOut, "\nCPThunks::");
  738. if (pHandler->szRawString[0] == 'G' || pHandler->szRawString[0] == 'S')
  739. {
  740. funcName = pHandler->szRawString[0] == 'G' ? "G_" : "S_";
  741. if (strcmp((LPCSTR)(pHandler->szRawString) + 2, "BSTR") == 0)
  742. {
  743. funcName += "String";
  744. }
  745. else if (strcmp((LPCSTR)(pHandler->szRawString) + 2, "VARIANT") == 0)
  746. {
  747. funcName += "Variant";
  748. }
  749. else if (strcmp((LPCSTR)(pHandler->szRawString) + 2, "VARIANTBOOL") == 0)
  750. {
  751. funcName += "Boolean";
  752. }
  753. else if (strcmp((LPCSTR)(pHandler->szRawString) + 2, "IDispatchp") == 0 ||
  754. strcmp((LPCSTR)(pHandler->szRawString) + 2, "IUnknownp") == 0)
  755. {
  756. funcName += "Object";
  757. }
  758. else
  759. {
  760. funcName = (LPCSTR)(pHandler->szRawString);
  761. }
  762. }
  763. else
  764. {
  765. funcName = (LPCSTR)(pHandler->szRawString);
  766. }
  767. fprintf(fpOut, "COMPLUS_%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset", (LPCSTR)funcName);
  768. invokeType |= (~ATYPE_ReturnValue & ATYPE_ParametersOnly);
  769. }
  770. OutputParameters(fpOut, pHandler, codeType, invokeType);
  771. if (pNDBodyFunc)
  772. {
  773. fprintf(fpOut, "\n");
  774. (*pNDBodyFunc)(fpOut, pHandler, codeType, invokeType);
  775. fprintf(fpOut, "\n\n");
  776. }
  777. else
  778. {
  779. fprintf(fpOut, ";\n");
  780. }
  781. }
  782. else
  783. {
  784. if (codeType == CT_managed)
  785. {
  786. if (strcmp((LPCSTR)(pHandler->szRawString) + 3, "BSTR") == 0)
  787. {
  788. funcName = "_String";
  789. }
  790. else if (strcmp((LPCSTR)(pHandler->szRawString) + 3, "VARIANT") == 0)
  791. {
  792. funcName = "_Variant";
  793. }
  794. else if (strcmp((LPCSTR)(pHandler->szRawString) + 3, "VARIANTBOOL") == 0)
  795. {
  796. funcName = "_Boolean";
  797. }
  798. else
  799. {
  800. funcName = (LPCSTR)((pHandler->szRawString)) + 2;
  801. }
  802. }
  803. else
  804. {
  805. funcName = pHandler->szRawString;
  806. }
  807. SpitOutAgain:
  808. if (!fSetDone && (pHandler->invokeType & ATYPE_GetProperty))
  809. {
  810. if (codeType == CT_managedNDirect || codeType == CT_unmanaged)
  811. {
  812. fprintf(fpOut, "%s NDCP_G%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset", pPreHeader, (LPCSTR)((pHandler->szRawString)) + 2);
  813. OutputParameters(fpOut, pHandler, codeType, ATYPE_GetProperty);
  814. }
  815. else if (codeType == CT_managed)
  816. {
  817. if (!pNDBodyFunc)
  818. fprintf(fpOut, "\tstatic ");
  819. OutputParameters(fpOut, pHandler, codeType, ATYPE_ReturnValue);
  820. if (pNDBodyFunc)
  821. fprintf(fpOut, "\nCPThunks::");
  822. fprintf(fpOut, "COMPLUS_G%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset)", (LPCSTR)funcName);
  823. }
  824. fSetDone = TRUE;
  825. if (pNDBodyFunc)
  826. {
  827. fprintf(fpOut, "\n");
  828. (*pNDBodyFunc)(fpOut, pHandler, codeType, ATYPE_GetProperty);
  829. fprintf(fpOut, "\n\n");
  830. }
  831. else
  832. {
  833. fprintf(fpOut, ";\n");
  834. }
  835. goto SpitOutAgain;
  836. }
  837. else if (pHandler->invokeType & ATYPE_SetProperty)
  838. {
  839. if (codeType == CT_managedNDirect || codeType == CT_unmanaged)
  840. {
  841. fprintf(fpOut, "%s NDCP_S%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset", pPreHeader, (LPCSTR)((pHandler->szRawString)) + 2);
  842. }
  843. else if (codeType == CT_managed)
  844. {
  845. if (!pNDBodyFunc)
  846. {
  847. fprintf(fpOut, "\tstatic void ");
  848. }
  849. else
  850. {
  851. fprintf(fpOut, "void\nCPThunks::");
  852. }
  853. fprintf(fpOut, "COMPLUS_S%s (unsigned int myThis, unsigned int idxIID, unsigned int wVTblOffset", (LPCSTR)funcName);
  854. }
  855. OutputParameters(fpOut, pHandler, codeType, ATYPE_SetProperty);
  856. if (pNDBodyFunc)
  857. {
  858. fprintf(fpOut, "\n");
  859. (*pNDBodyFunc)(fpOut, pHandler, codeType, ATYPE_SetProperty);
  860. fprintf(fpOut, "\n\n");
  861. }
  862. else
  863. {
  864. fprintf(fpOut, ";\n");
  865. }
  866. }
  867. }
  868. }
  869. BOOL GenerateNDirectHeader (LPCSTR pszOutputPath)
  870. {
  871. char chNDDefFileName[255];
  872. FILE *fpNDDefFile;
  873. strcpy(chNDDefFileName, pszOutputPath);
  874. strcat(chNDDefFileName, FILENAME_SEPARATOR_STR "ComPlsND.def");
  875. fpNDDefFile = fopen(chNDDefFileName, "w");
  876. if (!fpNDDefFile)
  877. {
  878. return FALSE;
  879. }
  880. fprintf(fpNDDefFile, "// Trident Def file NDirect functions.\n\n\n");
  881. // Spit out function signatures for NDirect functions.
  882. for (int i = 0; i < _cHandlers; i++)
  883. {
  884. BOOL fSetDone = FALSE;
  885. BOOL fGetAndSet = ((_allHandlers[i].invokeType & ATYPE_GetProperty) && (_allHandlers[i].invokeType & ATYPE_SetProperty));
  886. if (!fGetAndSet)
  887. {
  888. if (!AnyGSHandler(_allHandlers[i]))
  889. {
  890. fprintf(fpNDDefFile, "NDCP_%s\t\tPRIVATE\n", (LPCSTR)(_allHandlers[i].szRawString));
  891. }
  892. }
  893. else
  894. {
  895. SpitOutAgain:
  896. if (!fSetDone && (_allHandlers[i].invokeType & ATYPE_GetProperty))
  897. {
  898. fprintf(fpNDDefFile, "NDCP_G%s\t\tPRIVATE\n", (LPCSTR)((_allHandlers[i].szRawString)) + 2);
  899. fSetDone = TRUE;
  900. goto SpitOutAgain;
  901. }
  902. else if (_allHandlers[i].invokeType & ATYPE_SetProperty)
  903. {
  904. fprintf(fpNDDefFile, "NDCP_S%s\t\tPRIVATE\n", (LPCSTR)((_allHandlers[i].szRawString)) + 2);
  905. }
  906. }
  907. }
  908. fclose(fpNDDefFile);
  909. return TRUE;
  910. }
  911. void GenerateNDBody(FILE *fpOut, DispatchHandler *pHandler, CODETYPE codeType, int invokeType)
  912. {
  913. fprintf(fpOut, "{\n");
  914. fprintf(fpOut, "\ttypedef HRESULT (STDMETHODCALLTYPE *OLEVTblPropFunc)(IDispatch *");
  915. OutputParameters(fpOut, pHandler, codeType, invokeType);
  916. fprintf(fpOut, ";\n\n");
  917. fprintf(fpOut, "\tHRESULT\t\t\thr;\n\tIUnknown\t\t*pUnknownInstance;\n\tIDispatch\t\t*pInstance = 0;\n\tVTABLE_ENTRY\t*pVTbl;\n\n");
  918. fprintf(fpOut, "\tAssert(myThis);\n\n");
  919. fprintf(fpOut, "\tpUnknownInstance = (IUnknown *)myThis;\n\n");
  920. fprintf(fpOut, "\tAssert(idxIID <= MAX_IIDS);\n");
  921. fprintf(fpOut, "\thr = pUnknownInstance->QueryInterface(*_IIDTable[idxIID], (void **)&pInstance);\n");
  922. fprintf(fpOut, "\tif (hr)\n");
  923. fprintf(fpOut, "\t\tgoto Cleanup;\n\n");
  924. fprintf(fpOut, "\tpVTbl = (VTABLE_ENTRY *)(((BYTE *)(*(DWORD_PTR *)pInstance)) + (wVTblOffset*sizeof(VTABLE_ENTRY)/sizeof(DWORD_PTR) + FIRST_VTABLE_OFFSET));\n");
  925. fprintf(fpOut, "\thr = (*(OLEVTblPropFunc)VTBL_PFN(pVTbl))((IDispatch*) VTBL_THIS(pVTbl,pInstance)");
  926. if (invokeType & ATYPE_GetProperty)
  927. {
  928. fprintf(fpOut, ", resultParam");
  929. }
  930. else if (invokeType & ATYPE_SetProperty)
  931. {
  932. fprintf(fpOut, ", param1");
  933. }
  934. else
  935. {
  936. int i = 0;
  937. while (pHandler->params[i++].szVTParamType.Length())
  938. {
  939. fprintf (fpOut, ", param%i", i);
  940. }
  941. if (pHandler->vtResult != VT_EMPTY)
  942. {
  943. fprintf(fpOut, ", resultParam");
  944. }
  945. }
  946. fprintf(fpOut, ");\n\n");
  947. fprintf(fpOut, "\tpInstance->Release();\n\n");
  948. fprintf(fpOut, "Cleanup:\n\treturn hr;\n");
  949. fprintf(fpOut, "}\n");
  950. }
  951. BOOL GenerateNDirectCXX (LPCSTR pszOutputPath)
  952. {
  953. char chNDCXXFileName[255];
  954. FILE *fpNDCXXFile;
  955. strcpy(chNDCXXFileName, pszOutputPath);
  956. strcat(chNDCXXFileName, FILENAME_SEPARATOR_STR "funcND.cpp");
  957. fpNDCXXFile = fopen(chNDCXXFileName, "w");
  958. if (!fpNDCXXFile)
  959. {
  960. return FALSE;
  961. }
  962. fprintf(fpNDCXXFile, "// Trident NDirect functions source file.\n\n\n");
  963. // Spit out function signatures for NDirect functions.
  964. for (int i = 0; i < _cHandlers; i++)
  965. {
  966. OutputNDSignature(fpNDCXXFile, &(_allHandlers[i]), "STDAPI ", CT_unmanaged, GenerateNDBody);
  967. }
  968. fclose(fpNDCXXFile);
  969. return TRUE;
  970. }
  971. void GenerateManagedThunkBody(FILE *fpOut, DispatchHandler *pHandler, CODETYPE codeType, int invokeType)
  972. {
  973. CString szAfterBlock;
  974. CString szResult;
  975. fprintf(fpOut, "{\n");
  976. fprintf(fpOut, "\tif (myThis)\n");
  977. fprintf(fpOut, "\t{\n");
  978. fprintf(fpOut, "\t\tHRESULT\thr;\n");
  979. // Spit out the getter body.
  980. if (invokeType & ATYPE_GetProperty)
  981. {
  982. if ((pHandler->vtResult & VT_TYPEMASK) == VT_BSTR)
  983. {
  984. fprintf(fpOut, "\t\twchar_t\t*bstrString = 0;\n\n");
  985. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_BSTR(myThis, idxIID, wVTblOffset, &bstrString);\n\n");
  986. fprintf(fpOut, "\t\tString pString = CustomInvoke::BSTRToString(bstrString, 1);\n\n");
  987. fprintf(fpOut, "\t\treturn pString;\n");
  988. szAfterBlock = "\treturn 0;\n";
  989. }
  990. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_DISPATCH)
  991. {
  992. fprintf(fpOut, "\t\tunsigned int\tmyPDispatch = 0;\n\n");
  993. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_IDispatchp(myThis, idxIID, wVTblOffset, &myPDispatch);\n\n");
  994. fprintf(fpOut, "\t\treturn myPDispatch;\n");
  995. szAfterBlock = "\treturn 0;\n";
  996. }
  997. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_UNKNOWN)
  998. {
  999. fprintf(fpOut, "\t\tunsigned int\tmyPUnknown = 0;\n\n");
  1000. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_IUnknownp(myThis, idxIID, wVTblOffset, &myPUnknown);\n\n");
  1001. fprintf(fpOut, "\t\treturn myPUnknown;\n");
  1002. szAfterBlock = "\treturn 0;\n";
  1003. }
  1004. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_BOOL)
  1005. {
  1006. fprintf(fpOut, "\t\tshort\tmyCOMBool = 0;\n");
  1007. fprintf(fpOut, "\t\tBoolean\tmyCPBool = 0;\n\n");
  1008. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_VARIANTBOOL(myThis, idxIID, wVTblOffset, &myCOMBool);\n\n");
  1009. fprintf(fpOut, "\t\treturn myCPBool;\n");
  1010. szAfterBlock = "\treturn 0;\n";
  1011. }
  1012. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_VARIANT)
  1013. {
  1014. //
  1015. // COM+ Need to fix dispatch getter to return this as unsigned int and have the actual COM+ function create the
  1016. // COM+ Variant.
  1017. //
  1018. fprintf(fpOut, "\t\tunsigned int myPDispatch;\n");
  1019. fprintf(fpOut, "\t\tVariant myVariant;\n");
  1020. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_VARIANT(myThis, idxIID, wVTblOffset, &myPDispatch);\n\n");
  1021. fprintf(fpOut, "\t\treturn myVariant;\n");
  1022. szAfterBlock = "\treturn 0;\n";
  1023. }
  1024. else
  1025. {
  1026. if (pHandler->szCResult == "LONG")
  1027. {
  1028. szResult = "long";
  1029. }
  1030. else if (pHandler->szCResult == "SHORT")
  1031. {
  1032. szResult = "short";
  1033. }
  1034. else
  1035. {
  1036. szResult = pHandler->szCResult;
  1037. }
  1038. fprintf(fpOut, "\t\t%s\treturnValue = 0;\n\n", (LPCSTR)szResult);
  1039. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_G_%s(myThis, idxIID, wVTblOffset, &returnValue);\n\n", (LPCSTR)szResult);
  1040. fprintf(fpOut, "\t\treturn returnValue;\n");
  1041. szAfterBlock = "\treturn 0;\n";
  1042. }
  1043. }
  1044. // Spit out the setter body.
  1045. if (invokeType & ATYPE_SetProperty)
  1046. {
  1047. if ((pHandler->vtResult & VT_TYPEMASK) == VT_BSTR)
  1048. {
  1049. fprintf(fpOut, "\t\twchar_t\t*bstrString = 0;\n\n");
  1050. fprintf(fpOut, "\t\tbstrString = CustomInvoke::StringToBSTR(param1);\n");
  1051. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_BSTR(myThis, idxIID, wVTblOffset, bstrString);\n\n");
  1052. fprintf(fpOut, "\t\tCustomInvoke::SysFreeString(bstrString);\n");
  1053. }
  1054. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_DISPATCH)
  1055. {
  1056. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_IDispatchp(myThis, idxIID, wVTblOffset, param1);\n\n");
  1057. }
  1058. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_UNKNOWN)
  1059. {
  1060. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_IUnknownpp(myThis, idxIID, wVTblOffset, param1);\n\n");
  1061. }
  1062. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_VARIANT)
  1063. {
  1064. fprintf(fpOut, "\t\tunsigned myCOMVariant = 0;\n\n");
  1065. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_VARIANT(myThis, idxIID, wVTblOffset, myCOMVariant);\n\n");
  1066. }
  1067. else if ((pHandler->vtResult & VT_TYPEMASK) == VT_BOOL)
  1068. {
  1069. fprintf(fpOut, "\t\tshort myCOMBool = 0;\n\n");
  1070. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_VARIANTBOOL(myThis, idxIID, wVTblOffset, myCOMBool);\n\n");
  1071. }
  1072. else
  1073. {
  1074. if (pHandler->szCResult == "LONG")
  1075. {
  1076. szResult = "long";
  1077. }
  1078. else if (pHandler->szCResult == "SHORT")
  1079. {
  1080. szResult = "short";
  1081. }
  1082. else
  1083. {
  1084. szResult = pHandler->szCResult;
  1085. }
  1086. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_S_%s(myThis, idxIID, wVTblOffset, param1);\n\n", (LPCSTR)szResult);
  1087. }
  1088. }
  1089. // Spit out the method body.
  1090. if (invokeType & ATYPE_Method)
  1091. {
  1092. // ***TLL*** COM+: Just look for one parameter BSTR
  1093. if (pHandler->params[0].szVTParamType.Length() && !pHandler->params[1].szVTParamType.Length())
  1094. {
  1095. if (pHandler->params[0].vtParam == VT_BSTR)
  1096. {
  1097. fprintf(fpOut, "\t\twchar_t *bstrString = 0;\n\n");
  1098. fprintf(fpOut, "\t\tbstrString = CustomInvoke::StringToBSTR(param1);\n");
  1099. fprintf(fpOut, "\t\thr = CustomInvoke::NDCP_Method_void_BSTR(myThis, idxIID, wVTblOffset, bstrString);\n\n");
  1100. fprintf(fpOut, "\t\tCustomInvoke::SysFreeString(bstrString);\n");
  1101. }
  1102. }
  1103. // ***TLL*** COM+: Need to do.
  1104. // If no void result then return 0 for now.
  1105. if ((pHandler->vtResult & VT_TYPEMASK) != VT_EMPTY)
  1106. szAfterBlock = "\treturn 0;\n";
  1107. }
  1108. fprintf(fpOut, "\t}\n");
  1109. fprintf(fpOut, (LPCSTR)szAfterBlock);
  1110. fprintf(fpOut, "}\n");
  1111. }
  1112. BOOL GenerateComPlusHeader (LPCSTR pszOutputPath)
  1113. {
  1114. char chCPHeaderFileName[255];
  1115. FILE *fpCPHeaderFile;
  1116. int i;
  1117. strcpy(chCPHeaderFileName, pszOutputPath);
  1118. strcat(chCPHeaderFileName, FILENAME_SEPARATOR_STR "TComPlus.hxx");
  1119. fpCPHeaderFile = fopen(chCPHeaderFileName, "w");
  1120. if (!fpCPHeaderFile)
  1121. {
  1122. return FALSE;
  1123. }
  1124. fprintf(fpCPHeaderFile, "// Trident COM+ Header file.\n\n\n");
  1125. fprintf(fpCPHeaderFile, "[managed,coclass] class CustomInvoke {\n");
  1126. fprintf(fpCPHeaderFile, "public:\n");
  1127. fprintf(fpCPHeaderFile, "\t// Function signatures:\n");
  1128. // Spit out COM+ NDirect signatures
  1129. for (i = 0; i < _cHandlers; i++)
  1130. {
  1131. OutputNDSignature(fpCPHeaderFile, &(_allHandlers[i]), "\t[sysimport(dll=\"mshtml.dll\")]\n\tstatic HRESULT ", CT_managedNDirect, NULL);
  1132. }
  1133. fprintf(fpCPHeaderFile, "\n");
  1134. // Output misc. conversion routines:
  1135. fprintf(fpCPHeaderFile, "\t// Conversion routines:\n");
  1136. fprintf(fpCPHeaderFile, "\tstatic String BSTRToString(wchar_t* myBSTR, int fFreeBSTR);\n");
  1137. fprintf(fpCPHeaderFile, "\tstatic wchar_t* StringToBSTR(String myString);\n");
  1138. fprintf(fpCPHeaderFile, "\tstatic unsigned int VariantToVARIANT(Variant myVariant);\n");
  1139. fprintf(fpCPHeaderFile, "\tstatic void VariantClear(unsigned int myCOMVariant);\n\n");
  1140. fprintf(fpCPHeaderFile, "\t// Misc BSTR routines:\n");
  1141. fprintf(fpCPHeaderFile, "\t[sysimport(dll=\"oleaut32.dll\")]\n");
  1142. fprintf(fpCPHeaderFile, "\tstatic wchar_t* SysAllocStringLen(wchar_t *pch, unsigned int cch);\n\n");
  1143. fprintf(fpCPHeaderFile, "\t[sysimport(dll=\"oleaut32.dll\")]\n");
  1144. fprintf(fpCPHeaderFile, "\tstatic void SysFreeString(wchar_t *myBSTR);\n\n");
  1145. fprintf(fpCPHeaderFile, "\t// Misc VARIANT routines:\n");
  1146. fprintf(fpCPHeaderFile, "\t[sysimport(dll=\"oleaut32.dll\", name=\"SysAllocStringLen\")]\n");
  1147. fprintf(fpCPHeaderFile, "\tstatic unsigned int AllocVariant(wchar_t *pch, unsigned int cch);\n\n");
  1148. fprintf(fpCPHeaderFile, "\t[sysimport(dll=\"oleaut32.dll\")]\n");
  1149. fprintf(fpCPHeaderFile, "\tstatic void VariantInit(unsigned int);\n\n");
  1150. fprintf(fpCPHeaderFile, "\t[sysimport(dll=\"oleaut32.dll\", name=\"SysFreeString\")]\n");
  1151. fprintf(fpCPHeaderFile, "\tstatic void FreeVariant(wchar_t *myBSTR);\n");
  1152. fprintf(fpCPHeaderFile, "};\n\n");
  1153. fprintf(fpCPHeaderFile, "[managed,coclass] class CPThunks {\n");
  1154. fprintf(fpCPHeaderFile, "public:\n");
  1155. fprintf(fpCPHeaderFile, "\t// Function signatures:\n");
  1156. // Spit out COM+ thunks for each signature type
  1157. for (i = 0; i < _cHandlers; i++)
  1158. {
  1159. OutputNDSignature(fpCPHeaderFile, &(_allHandlers[i]), "", CT_managed, NULL);
  1160. }
  1161. fprintf(fpCPHeaderFile, "};\n\n");
  1162. fclose(fpCPHeaderFile);
  1163. return TRUE;
  1164. }
  1165. BOOL GenerateComPlusCXX (LPCSTR pszOutputPath)
  1166. {
  1167. char chCPCXXFileName[255];
  1168. FILE *fpCPCXXFile;
  1169. strcpy(chCPCXXFileName, pszOutputPath);
  1170. strcat(chCPCXXFileName, FILENAME_SEPARATOR_STR "TComPlus.cpp");
  1171. fpCPCXXFile = fopen(chCPCXXFileName, "w");
  1172. if (!fpCPCXXFile)
  1173. {
  1174. return FALSE;
  1175. }
  1176. fprintf(fpCPCXXFile, "// Trident COM+ source file.\n\n\n");
  1177. fprintf(fpCPCXXFile, "#import <mscorlib.dll>\n");
  1178. fprintf(fpCPCXXFile, "#include <crt.h>\n");
  1179. fprintf(fpCPCXXFile, "#include \"TComPlus.hxx\"\n\n\n");
  1180. // Spit out COM+ thunks for each signature type
  1181. for (int i = 0; i < _cHandlers; i++)
  1182. {
  1183. OutputNDSignature(fpCPCXXFile, &(_allHandlers[i]), "", CT_managed, GenerateManagedThunkBody);
  1184. }
  1185. // Output conversion routines:
  1186. fprintf(fpCPCXXFile, "\n\n");
  1187. fprintf(fpCPCXXFile, "//////////////////////////////////////////////////////////////////////////\n");
  1188. fprintf(fpCPCXXFile, "//////////////////////////////////////////////////////////////////////////\n");
  1189. fprintf(fpCPCXXFile, "// //\n");
  1190. fprintf(fpCPCXXFile, "// //\n");
  1191. fprintf(fpCPCXXFile, "// Conversion routines: //\n");
  1192. fprintf(fpCPCXXFile, "// //\n");
  1193. fprintf(fpCPCXXFile, "// //\n");
  1194. fprintf(fpCPCXXFile, "//////////////////////////////////////////////////////////////////////////\n");
  1195. fprintf(fpCPCXXFile, "//////////////////////////////////////////////////////////////////////////\n\n\n");
  1196. fprintf(fpCPCXXFile, "String\n");
  1197. fprintf(fpCPCXXFile, "CustomInvoke::BSTRToString(wchar_t *myBSTR, int fFreeBSTR)\n");
  1198. fprintf(fpCPCXXFile, "{\n");
  1199. fprintf(fpCPCXXFile, "\tString pString(\"\");\n\n");
  1200. fprintf(fpCPCXXFile, "\tif (myBSTR)\n");
  1201. fprintf(fpCPCXXFile, "\t{\n");
  1202. fprintf(fpCPCXXFile, "\t\tpString = Interop.PInvoke.PtrToStringAuto((int)myBSTR);\n");
  1203. fprintf(fpCPCXXFile, "\t\tif (fFreeBSTR)\n");
  1204. fprintf(fpCPCXXFile, "\t\t{\n");
  1205. fprintf(fpCPCXXFile, "\t\t\tSysFreeString(myBSTR);\n");
  1206. fprintf(fpCPCXXFile, "\t\t}\n");
  1207. fprintf(fpCPCXXFile, "\t}\n\n");
  1208. fprintf(fpCPCXXFile, "\treturn pString;\n");
  1209. fprintf(fpCPCXXFile, "}\n\n\n");
  1210. fprintf(fpCPCXXFile, "wchar_t*\n");
  1211. fprintf(fpCPCXXFile, "CustomInvoke::StringToBSTR(String myString)\n");
  1212. fprintf(fpCPCXXFile, "{\n");
  1213. fprintf(fpCPCXXFile, "\twchar_t *myBSTR = 0;\n");
  1214. fprintf(fpCPCXXFile, "\tint cch;\n\n");
  1215. fprintf(fpCPCXXFile, "\tcch = myString.GetLength();\n");
  1216. fprintf(fpCPCXXFile, "\tmyBSTR = CustomInvoke::SysAllocStringLen(0, cch);\n");
  1217. fprintf(fpCPCXXFile, "\tif (myBSTR)\n");
  1218. fprintf(fpCPCXXFile, "\t{\n");
  1219. fprintf(fpCPCXXFile, "\t\tunsigned int i = 0;\n\n");
  1220. fprintf(fpCPCXXFile, "\t\twhile (cch-- > 0)\n");
  1221. fprintf(fpCPCXXFile, "\t\t{\n");
  1222. fprintf(fpCPCXXFile, "\t\t\t*(myBSTR + i) = myString.GetChar(i);\n");
  1223. fprintf(fpCPCXXFile, "\t\t\ti++;\n");
  1224. fprintf(fpCPCXXFile, "\t\t};\n");
  1225. fprintf(fpCPCXXFile, "\t}\n\n");
  1226. fprintf(fpCPCXXFile, "\treturn myBSTR;\n");
  1227. fprintf(fpCPCXXFile, "}\n\n");
  1228. fprintf(fpCPCXXFile, "unsigned int\n");
  1229. fprintf(fpCPCXXFile, "CustomInvoke::VariantToVARIANT(Variant myVariant)\n");
  1230. fprintf(fpCPCXXFile, "{\n");
  1231. fprintf(fpCPCXXFile, "\treturn 0;\n");
  1232. fprintf(fpCPCXXFile, "}\n\n");
  1233. fprintf(fpCPCXXFile, "void\n");
  1234. fprintf(fpCPCXXFile, "CustomInvoke::VariantClear(unsigned int myCOMVariant)\n");
  1235. fprintf(fpCPCXXFile, "{\n");
  1236. fprintf(fpCPCXXFile, "\n\n");
  1237. fprintf(fpCPCXXFile, "}\n\n");
  1238. // Close file.
  1239. fclose(fpCPCXXFile);
  1240. return TRUE;
  1241. }
  1242. //////////////////////////////////////////////////////////////////////////////////////////////
  1243. //////////////////////////////////////////////////////////////////////////////////////////////
  1244. // End of COM+ code //
  1245. //////////////////////////////////////////////////////////////////////////////////////////////
  1246. //////////////////////////////////////////////////////////////////////////////////////////////
  1247. #endif // COMPLUS_SHIM
  1248. BOOL GenerateVTableHeader ( LPCSTR pszOutputPath )
  1249. {
  1250. char chHeaderFileName[255];
  1251. FILE *fpHeaderFile;
  1252. int i;
  1253. strcpy(chHeaderFileName, pszOutputPath);
  1254. strcat(chHeaderFileName, FILENAME_SEPARATOR_STR "funcsig.hxx");
  1255. fpHeaderFile = fopen ( chHeaderFileName, "w" );
  1256. if ( !fpHeaderFile )
  1257. {
  1258. return FALSE;
  1259. }
  1260. fprintf ( fpHeaderFile, "BOOL DispNonDualDIID(IID iid);\n" );
  1261. fprintf ( fpHeaderFile, "typedef HRESULT (*CustomHandler)(CBase *pBase,\n" );
  1262. fprintf ( fpHeaderFile, " IServiceProvider *pSrvProvider,\n" );
  1263. fprintf ( fpHeaderFile, " IDispatch *pInstance,\n" );
  1264. fprintf ( fpHeaderFile, " WORD wVTblOffset,\n" );
  1265. fprintf ( fpHeaderFile, " PROPERTYDESC_BASIC_ABSTRACT *pDesc,\n" );
  1266. fprintf ( fpHeaderFile, " WORD wFlags,\n" );
  1267. fprintf ( fpHeaderFile, " DISPPARAMS *pdispparams,\n" );
  1268. fprintf ( fpHeaderFile, " VARIANT *pvarResult);\n\n\n" );
  1269. // Spit out function signatures for handlers.
  1270. for (i = 0; i < _cHandlers; i++)
  1271. {
  1272. fprintf ( fpHeaderFile, "HRESULT %s (CBase *pBase,\n", (LPCSTR)(_allHandlers[i].szRawString) );
  1273. fprintf ( fpHeaderFile, " IServiceProvider *pSrvProvider,\n" );
  1274. fprintf ( fpHeaderFile, " IDispatch *pInstance,\n" );
  1275. fprintf ( fpHeaderFile, " WORD wVTblOffset,\n" );
  1276. fprintf ( fpHeaderFile, " PROPERTYDESC_BASIC_ABSTRACT *pDesc,\n" );
  1277. fprintf ( fpHeaderFile, " WORD wFlags,\n" );
  1278. fprintf ( fpHeaderFile, " DISPPARAMS *pdispparams,\n" );
  1279. fprintf ( fpHeaderFile, " VARIANT *pvarResult);\n\n" );
  1280. }
  1281. fprintf ( fpHeaderFile, "\n" );
  1282. // Spit out indexes into handler table.
  1283. for (i = 0; i < _cHandlers; i++)
  1284. {
  1285. fprintf ( fpHeaderFile, "#define \tIDX_%s \t%i\n", (LPCSTR)(_allHandlers[i].szRawString), i );
  1286. }
  1287. fclose ( fpHeaderFile );
  1288. return TRUE;
  1289. }
  1290. void GenerateFunctionBody ( FILE * fpCXXFile, DispatchHandler *pHandler)
  1291. {
  1292. if ((pHandler->invokeType & ATYPE_GetProperty) || (pHandler->invokeType & ATYPE_SetProperty))
  1293. {
  1294. BOOL fObjectRet = FALSE;
  1295. BOOL fBSTRParam = FALSE;
  1296. BOOL fGetAndSet = (pHandler->invokeType & ATYPE_GetProperty) &&
  1297. (pHandler->invokeType & ATYPE_SetProperty);
  1298. BOOL fGS_BSTR = pHandler->szRawString == "GS_BSTR";
  1299. BOOL fGS_VARIANT = pHandler->szRawString == "GS_VARIANT";
  1300. BOOL fGS_PropEnum = pHandler->szRawString == "GS_PropEnum";
  1301. char chIdent[16];
  1302. chIdent[0] = '\0';
  1303. // Does the property muck with an object?
  1304. fObjectRet = ((pHandler->vtResult & VT_TYPEMASK) == VT_UNKNOWN) ||
  1305. ((pHandler->vtResult & VT_TYPEMASK) == VT_DISPATCH);
  1306. fBSTRParam = ((pHandler->vtResult & VT_TYPEMASK) == VT_BSTR);
  1307. if (pHandler->invokeType & ATYPE_GetProperty)
  1308. {
  1309. fprintf ( fpCXXFile, " typedef HRESULT (STDMETHODCALLTYPE *OLEVTbl%sPropFunc)(IDispatch *, %s *);\n", fGetAndSet ? "Get" : "", (LPCSTR)pHandler->szCResult );
  1310. }
  1311. if (pHandler->invokeType & ATYPE_SetProperty)
  1312. {
  1313. fprintf ( fpCXXFile, " typedef HRESULT (STDMETHODCALLTYPE *OLEVTbl%sPropFunc)(IDispatch *, %s);\n", fGetAndSet ? "Set" : "", (LPCSTR)pHandler->szCResult );
  1314. }
  1315. fprintf ( fpCXXFile, "\n" );
  1316. fprintf ( fpCXXFile, " HRESULT hr;\n" );
  1317. // Any IDispatch* or IUnknown* arguments? If so then possible
  1318. // creation of BSTR/object needs to be handled.
  1319. if ((pHandler->invokeType & ATYPE_SetProperty) && (fObjectRet || fBSTRParam || fGS_VARIANT))
  1320. {
  1321. fprintf ( fpCXXFile, " ULONG ulAlloc = 0;\n" );
  1322. }
  1323. if (pHandler->invokeType & ATYPE_GetProperty)
  1324. {
  1325. fprintf ( fpCXXFile, " VTABLE_ENTRY *pVTbl;\n");
  1326. }
  1327. else if (pHandler->invokeType & ATYPE_SetProperty)
  1328. {
  1329. fprintf ( fpCXXFile, " VTABLE_ENTRY *pVTbl;\n");
  1330. }
  1331. fprintf ( fpCXXFile, " VARTYPE argTypes[] = { %s };\n", (LPCSTR)pHandler->szVTResult );
  1332. if (pHandler->invokeType & ATYPE_SetProperty && pHandler->szCResult.Length() > 0)
  1333. {
  1334. fprintf ( fpCXXFile, " %s param1;\n", (LPCSTR)pHandler->szCResult );
  1335. }
  1336. fprintf ( fpCXXFile, "\n Assert(pInstance || pDesc || pdispparams);\n\n" );
  1337. if (pHandler->invokeType & ATYPE_GetProperty)
  1338. {
  1339. fprintf ( fpCXXFile, " pVTbl = (VTABLE_ENTRY *)(((BYTE *)(*(DWORD_PTR *)pInstance)) + (wVTblOffset*sizeof(VTABLE_ENTRY)/sizeof(DWORD_PTR) + FIRST_VTABLE_OFFSET));\n\n");
  1340. }
  1341. else if (pHandler->invokeType & ATYPE_SetProperty)
  1342. {
  1343. fprintf ( fpCXXFile, " pVTbl = (VTABLE_ENTRY *)(((BYTE *)(*(DWORD_PTR *)pInstance)) + (wVTblOffset*sizeof(VTABLE_ENTRY)/sizeof(DWORD_PTR) + FIRST_VTABLE_OFFSET));\n\n");
  1344. }
  1345. if ((pHandler->invokeType & ATYPE_GetProperty) && (pHandler->invokeType & ATYPE_SetProperty))
  1346. {
  1347. fprintf ( fpCXXFile, " if (wFlags & INVOKE_PROPERTYGET)\n" );
  1348. fprintf ( fpCXXFile, " {\n" );
  1349. strcpy( chIdent, " " );
  1350. }
  1351. if (pHandler->invokeType & ATYPE_GetProperty)
  1352. {
  1353. if ((pHandler->szCResult.Length() > 0) && (pHandler->vtResult != VT_VARIANT))
  1354. {
  1355. fprintf ( fpCXXFile, "%s hr = (*(OLEVTbl%sPropFunc)VTBL_PFN(pVTbl))((IDispatch*) VTBL_THIS(pVTbl,pInstance), (%s *)&pvarResult->iVal);\n", chIdent, fGetAndSet ? "Get" : "", (LPCSTR)pHandler->szCResult);
  1356. fprintf ( fpCXXFile, "%s if (!hr)\n", chIdent );
  1357. fprintf ( fpCXXFile, "%s V_VT(pvarResult) = argTypes[0];\n", chIdent );
  1358. }
  1359. else
  1360. {
  1361. fprintf ( fpCXXFile, "%s hr = (*(OLEVTbl%sPropFunc)VTBL_PFN(pVTbl))((IDispatch*)VTBL_THIS(pVTbl, pInstance), pvarResult);\n", chIdent, fGetAndSet ? "Get" : "");
  1362. }
  1363. }
  1364. if ((pHandler->invokeType & ATYPE_GetProperty) && (pHandler->invokeType & ATYPE_SetProperty))
  1365. {
  1366. fprintf ( fpCXXFile, " }\n" );
  1367. fprintf ( fpCXXFile, " else\n" );
  1368. fprintf ( fpCXXFile, " {\n" );
  1369. }
  1370. if (pHandler->invokeType & ATYPE_SetProperty)
  1371. {
  1372. if (pHandler->szCResult.Length() > 0)
  1373. {
  1374. fprintf ( fpCXXFile, "%s // Convert dispatch params to C params.\n", chIdent );
  1375. fprintf ( fpCXXFile, "%s hr = DispParamsToCParams(pSrvProvider, pdispparams, ", chIdent);
  1376. if (fObjectRet || fBSTRParam || fGS_VARIANT)
  1377. fprintf ( fpCXXFile, "&ulAlloc, " ); // Keep track of all allocation.
  1378. else
  1379. fprintf ( fpCXXFile, "0L, " );
  1380. if (fGS_BSTR || fGS_VARIANT || fGS_PropEnum)
  1381. fprintf ( fpCXXFile, "((PROPERTYDESC_BASIC_ABSTRACT *)pDesc)->b.wMaxstrlen, " );
  1382. else
  1383. fprintf ( fpCXXFile, "0, " );
  1384. fprintf ( fpCXXFile, "argTypes, &param1, -1);\n" );
  1385. fprintf ( fpCXXFile, "%s if (hr)\n", chIdent );
  1386. fprintf ( fpCXXFile, "%s pBase->SetErrorInfo(hr);\n", chIdent );
  1387. fprintf ( fpCXXFile, "%s else\n", chIdent );
  1388. if (fGetAndSet)
  1389. {
  1390. fprintf ( fpCXXFile, "%s hr = (*(OLEVTblSetPropFunc)VTBL_PFN(pVTbl))((IDispatch*)VTBL_THIS(pVTbl,pInstance), (%s)param1);\n", chIdent, (LPCSTR)pHandler->szCResult);
  1391. }
  1392. else
  1393. {
  1394. fprintf ( fpCXXFile, "%s hr = (*(OLEVTblPropFunc)VTBL_PFN(pVTbl))((IDispatch*)VTBL_THIS(pVTbl,pInstance), (%s)param1);\n", chIdent, (LPCSTR)pHandler->szCResult);
  1395. }
  1396. }
  1397. else
  1398. {
  1399. fprintf ( fpCXXFile, "%s hr = (*(OLEVTblPropFunc)VTBL_PFN(pVTbl))((IDispatch*)VTBL_THIS(pVTbl,pInstance), pdispparams[0]);\n", chIdent );
  1400. }
  1401. }
  1402. if ((pHandler->invokeType & ATYPE_GetProperty) && (pHandler->invokeType & ATYPE_SetProperty))
  1403. {
  1404. fprintf ( fpCXXFile, " }\n" );
  1405. }
  1406. if ((pHandler->invokeType & ATYPE_SetProperty) && (fObjectRet || fBSTRParam || fGS_VARIANT))
  1407. {
  1408. if (fGS_VARIANT)
  1409. fprintf ( fpCXXFile, " if (ulAlloc)\n" );
  1410. else
  1411. fprintf ( fpCXXFile, " if (ulAlloc && param1)\n" );
  1412. if (fObjectRet)
  1413. {
  1414. fprintf ( fpCXXFile, " param1->Release();\n");
  1415. }
  1416. else if (fBSTRParam)
  1417. {
  1418. fprintf ( fpCXXFile, " SysFreeString(param1);\n");
  1419. }
  1420. else if (fGS_VARIANT)
  1421. {
  1422. fprintf ( fpCXXFile, " {\n" );
  1423. fprintf ( fpCXXFile, " Assert(V_VT(&param1) == VT_BSTR);\n" );
  1424. fprintf ( fpCXXFile, " SysFreeString(V_BSTR(&param1));\n" );
  1425. fprintf ( fpCXXFile, " }\n" );
  1426. }
  1427. }
  1428. fprintf ( fpCXXFile, "\n return hr;\n" );
  1429. }
  1430. else if ( pHandler->invokeType & ATYPE_Method )
  1431. {
  1432. // We've got a method to spit out.
  1433. char chVARMacro[16];
  1434. int i;
  1435. BOOL fParamConvert;
  1436. BOOL fBSTRParam = FALSE;
  1437. BOOL fObjectParam = FALSE;
  1438. BOOL fVariantParam = FALSE;
  1439. int cArgs;
  1440. if (pHandler->vtResult & VT_BYREF)
  1441. {
  1442. strcpy(chVARMacro, "V_BYREF");
  1443. }
  1444. else
  1445. {
  1446. switch (pHandler->vtResult & VT_TYPEMASK) {
  1447. case VT_EMPTY:
  1448. strcpy(chVARMacro, "");
  1449. break;
  1450. case VT_I2:
  1451. strcpy(chVARMacro, "V_I2");
  1452. break;
  1453. case VT_I4:
  1454. strcpy(chVARMacro, "V_I4");
  1455. break;
  1456. case VT_R4:
  1457. strcpy(chVARMacro, "V_R4");
  1458. break;
  1459. case VT_R8:
  1460. strcpy(chVARMacro, "V_R8");
  1461. break;
  1462. case VT_CY:
  1463. strcpy(chVARMacro, "V_CY");
  1464. break;
  1465. case VT_BSTR:
  1466. strcpy(chVARMacro, "V_BSTR");
  1467. break;
  1468. case VT_DISPATCH:
  1469. case VT_VARIANT:
  1470. case VT_UNKNOWN:
  1471. strcpy(chVARMacro, "V_BYREF");
  1472. break;
  1473. case VT_BOOL:
  1474. strcpy(chVARMacro, "V_BOOL");
  1475. break;
  1476. default:
  1477. strcpy(chVARMacro, "Unsupported");
  1478. }
  1479. }
  1480. fprintf ( fpCXXFile, " typedef HRESULT (STDMETHODCALLTYPE *MethodOLEVTblFunc)(IDispatch *" );
  1481. i = 0;
  1482. cArgs = 0;
  1483. while ( pHandler->params[i].szVTParamType.Length() )
  1484. {
  1485. fprintf ( fpCXXFile, ", %s", (LPCSTR)pHandler->params[i].szCParamType );
  1486. i++;
  1487. cArgs++;
  1488. }
  1489. if ( pHandler->vtResult != VT_EMPTY )
  1490. {
  1491. fprintf ( fpCXXFile, ", %s", (LPCSTR)pHandler->szCResult );
  1492. }
  1493. fprintf ( fpCXXFile, ");\n\n" );
  1494. fprintf ( fpCXXFile, " HRESULT hr;\n" );
  1495. fprintf ( fpCXXFile, " VTABLE_ENTRY *pVTbl;\n" );
  1496. fParamConvert = cArgs;
  1497. // Any paramters?
  1498. if (fParamConvert)
  1499. {
  1500. int iDefIndex;
  1501. fprintf ( fpCXXFile, " VARTYPE argTypes[] = {\n" );
  1502. i = 0;
  1503. while ( pHandler->params[i].szVTParamType.Length() )
  1504. {
  1505. fprintf ( fpCXXFile, " %s,\n",
  1506. (LPCSTR)pHandler->params[i].szVTParamType );
  1507. i++;
  1508. }
  1509. fprintf ( fpCXXFile, " };\n" );
  1510. i = 0;
  1511. iDefIndex = 0;
  1512. while ( pHandler->params[i].szVTParamType.Length() )
  1513. {
  1514. fBSTRParam |= ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_BSTR);
  1515. fVariantParam |= ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_VARIANT);
  1516. fObjectParam |= ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_UNKNOWN) ||
  1517. ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_DISPATCH);
  1518. if (pHandler->params[i].fOptional)
  1519. {
  1520. if (pHandler->params[i].vtParam == (VT_VARIANT | VT_BYREF))
  1521. {
  1522. fprintf ( fpCXXFile, " CVariant param%iopt(VT_ERROR); // optional variant\n", i + 1 );
  1523. fprintf ( fpCXXFile, " VARIANT *param%i = &param%iopt; // optional arg.\n", i + 1, i + 1 );
  1524. }
  1525. else if (pHandler->params[i].vtParam == VT_VARIANT)
  1526. {
  1527. fprintf ( fpCXXFile, " VARIANT param%i; // optional arg.\n", i + 1 );
  1528. }
  1529. else
  1530. {
  1531. // error, only VARIANT and VARIANT * can be optional.
  1532. PDLError("optional only allowed for VARIANT and VARIANT *");
  1533. return;
  1534. }
  1535. }
  1536. else if (pHandler->params[i].fDefaultValue)
  1537. {
  1538. if (pHandler->params[i].vtParam == VT_BSTR)
  1539. {
  1540. fprintf ( fpCXXFile, " %s paramDef%i = SysAllocString((TCHAR *)(((PROPERTYDESC_METHOD *)pDesc)->c->defargs[%i]));\n",
  1541. (LPCSTR)pHandler->params[i].szCParamType,
  1542. i + 1,
  1543. iDefIndex );
  1544. fprintf ( fpCXXFile, " %s param%i = paramDef%i;\n",
  1545. (LPCSTR)pHandler->params[i].szCParamType,
  1546. i + 1,
  1547. i + 1);
  1548. }
  1549. else
  1550. {
  1551. fprintf ( fpCXXFile, " %s param%i = (%s)(((PROPERTYDESC_METHOD *)pDesc)->c->defargs[%i]);\n",
  1552. (LPCSTR)pHandler->params[i].szCParamType,
  1553. i + 1,
  1554. (LPCSTR)pHandler->params[i].szCParamType,
  1555. iDefIndex );
  1556. }
  1557. iDefIndex++;
  1558. }
  1559. else
  1560. {
  1561. // Non optional variants need conversion if they contain a string that it longer than maxlen
  1562. fprintf ( fpCXXFile, " %s param%i;\n", (LPCSTR)pHandler->params[i].szCParamType, i + 1 );
  1563. }
  1564. i++;
  1565. }
  1566. // Any BSTR or IDispatch* or IUnknown* arguments? If so then possible
  1567. // creation of BSTR/object needs to be handled.
  1568. if (fBSTRParam || fObjectParam || fVariantParam)
  1569. {
  1570. fprintf ( fpCXXFile, " ULONG ulAlloc = 0;\n" );
  1571. }
  1572. fprintf ( fpCXXFile, "\n" );
  1573. }
  1574. i = 0;
  1575. while ( pHandler->params[i].szVTParamType.Length() )
  1576. {
  1577. if ( pHandler->params[i].fOptional &&
  1578. pHandler->params[i].vtParam == VT_VARIANT )
  1579. {
  1580. fprintf ( fpCXXFile, " V_VT(&param%i) = VT_ERROR;\n", i + 1 );
  1581. }
  1582. i++;
  1583. };
  1584. fprintf ( fpCXXFile, "\n" );
  1585. fprintf ( fpCXXFile, " Assert(pInstance || pDesc || pdispparams);\n\n" );
  1586. fprintf ( fpCXXFile, " pVTbl = (VTABLE_ENTRY*)(((BYTE *)(*(DWORD_PTR *)pInstance)) + wVTblOffset * sizeof(VTABLE_ENTRY)/sizeof(DWORD_PTR) + FIRST_VTABLE_OFFSET);\n\n" );
  1587. if ( pHandler->params[0].vtParam == VT_ARRAY )
  1588. {
  1589. fprintf ( fpCXXFile, " // Convert dispatch params to safearray.\n" );
  1590. fprintf ( fpCXXFile, " param1 = DispParamsToSAFEARRAY(pdispparams);\n" );
  1591. }
  1592. else if ( fParamConvert )
  1593. {
  1594. // Any parameters?
  1595. fprintf ( fpCXXFile, " // Convert dispatch params to C params.\n" );
  1596. fprintf ( fpCXXFile, " hr = DispParamsToCParams(pSrvProvider, pdispparams, " );
  1597. if (fBSTRParam || fObjectParam || fVariantParam)
  1598. fprintf ( fpCXXFile, "&ulAlloc, " );
  1599. else
  1600. fprintf ( fpCXXFile, "NULL, " );
  1601. if (fBSTRParam || fVariantParam)
  1602. fprintf ( fpCXXFile, "((PROPERTYDESC_BASIC_ABSTRACT *)pDesc)->b.wMaxstrlen" );
  1603. else
  1604. fprintf ( fpCXXFile, "0" );
  1605. fprintf ( fpCXXFile, ", argTypes" );
  1606. i = 0;
  1607. while ( pHandler->params[i].szVTParamType.Length() )
  1608. {
  1609. fprintf ( fpCXXFile, ", &param%i", i + 1 );
  1610. i++;
  1611. }
  1612. fprintf ( fpCXXFile, ", -1L);\n" );
  1613. fprintf ( fpCXXFile, " if (hr)\n" );
  1614. fprintf ( fpCXXFile, " {\n" );
  1615. fprintf ( fpCXXFile, " pBase->SetErrorInfo(hr);\n" );
  1616. fprintf ( fpCXXFile, " goto Cleanup;\n" );
  1617. fprintf ( fpCXXFile, " }\n\n" );
  1618. }
  1619. fprintf ( fpCXXFile, " hr = (*(MethodOLEVTblFunc)VTBL_PFN(pVTbl))((IDispatch*)VTBL_THIS(pVTbl,pInstance)", chVARMacro );
  1620. i = 0;
  1621. while ( pHandler->params[i].szVTParamType.Length() )
  1622. {
  1623. fprintf ( fpCXXFile, ", param%i", i + 1 );
  1624. i++;
  1625. }
  1626. // Do we have a result type?
  1627. if ( pHandler->vtResult != VT_EMPTY )
  1628. {
  1629. if (((pHandler->vtResult & VT_BYREF) == VT_BYREF) && ((pHandler->vtResult & VT_TYPEMASK) != VT_VARIANT))
  1630. {
  1631. fprintf ( fpCXXFile, ", (%s)(&(pvarResult->pdispVal))", (LPCSTR)pHandler->szCResult );
  1632. }
  1633. else
  1634. {
  1635. fprintf ( fpCXXFile, ", pvarResult" );
  1636. }
  1637. }
  1638. fprintf ( fpCXXFile, ");\n" );
  1639. if (((pHandler->vtResult & VT_BYREF) == VT_BYREF) && ((pHandler->vtResult & VT_TYPEMASK) != VT_VARIANT))
  1640. {
  1641. fprintf ( fpCXXFile, " if (!hr)\n");
  1642. fprintf ( fpCXXFile, " V_VT(pvarResult) = (%s) & ~VT_BYREF;\n", (LPCSTR)pHandler->szVTResult );
  1643. }
  1644. if ( pHandler->params[0].vtParam == VT_ARRAY )
  1645. {
  1646. fprintf ( fpCXXFile, " if (param1)\n" );
  1647. fprintf ( fpCXXFile, " {\n" );
  1648. fprintf ( fpCXXFile, " HRESULT hr1 = SafeArrayDestroy(param1);\n" );
  1649. fprintf ( fpCXXFile, " if (hr1)\n");
  1650. fprintf ( fpCXXFile, " hr = hr1;\n");
  1651. fprintf ( fpCXXFile, " }\n" );
  1652. }
  1653. else if ( fParamConvert )
  1654. {
  1655. // Any parameters then we'll need a cleanup routine.
  1656. fprintf ( fpCXXFile, "\nCleanup:\n" );
  1657. }
  1658. // Deallocate any default BSTR parameters.
  1659. i = 0;
  1660. while ( pHandler->params[i].szVTParamType.Length() )
  1661. {
  1662. if (pHandler->params[i].fDefaultValue && pHandler->params[i].vtParam == VT_BSTR)
  1663. {
  1664. fprintf ( fpCXXFile, " SysFreeString(paramDef%i);\n", i + 1);
  1665. }
  1666. i++;
  1667. }
  1668. if (fBSTRParam || fObjectParam || fVariantParam)
  1669. {
  1670. i = 0;
  1671. while ( pHandler->params[i].szVTParamType.Length() )
  1672. {
  1673. // Variants don't need conversion.
  1674. if ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_BSTR)
  1675. {
  1676. fprintf ( fpCXXFile, " if (ulAlloc & %i)\n", (1 << i) );
  1677. fprintf ( fpCXXFile, " SysFreeString(param%i);\n", i + 1);
  1678. }
  1679. if ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_UNKNOWN ||
  1680. (pHandler->params[i].vtParam & VT_TYPEMASK) == VT_DISPATCH)
  1681. {
  1682. if (!(pHandler->params[i].vtParam & VT_BYREF))
  1683. {
  1684. fprintf ( fpCXXFile, " if ((ulAlloc & %i) && param%i)\n", (1 << i), i + 1 );
  1685. fprintf ( fpCXXFile, " param%i->Release();\n", i + 1);
  1686. }
  1687. else
  1688. {
  1689. fprintf ( fpCXXFile, " if ((ulAlloc & %i) && *param%i)\n", (1 << i), i + 1 );
  1690. fprintf ( fpCXXFile, " (*param%i)->Release();\n", i + 1);
  1691. }
  1692. }
  1693. if ((pHandler->params[i].vtParam & VT_TYPEMASK) == VT_VARIANT)
  1694. {
  1695. fprintf ( fpCXXFile, " if (ulAlloc & %i)\n", (1 << i) );
  1696. fprintf ( fpCXXFile, " {\n" );
  1697. fprintf ( fpCXXFile, " Assert(V_VT(%sparam%i) == VT_BSTR);\n",
  1698. pHandler->params[i].vtParam & VT_BYREF ? "" : "&", i + 1);
  1699. fprintf ( fpCXXFile, " SysFreeString(V_BSTR(%sparam%i));\n",
  1700. pHandler->params[i].vtParam & VT_BYREF ? "" : "&", i + 1);
  1701. fprintf ( fpCXXFile, " }\n" );
  1702. }
  1703. i++;
  1704. }
  1705. }
  1706. fprintf ( fpCXXFile, " return hr;\n" );
  1707. }
  1708. }
  1709. BOOL GenerateVTableCXX ( LPCSTR pszOutputPath )
  1710. {
  1711. char chCXXFileName[255];
  1712. FILE *fpCXXFile;
  1713. int i;
  1714. strcpy(chCXXFileName, pszOutputPath);
  1715. strcat(chCXXFileName, FILENAME_SEPARATOR_STR "funcsig.cxx");
  1716. fpCXXFile = fopen ( chCXXFileName, "w" );
  1717. if ( !fpCXXFile )
  1718. {
  1719. return FALSE;
  1720. }
  1721. //
  1722. // Generate CXX file.
  1723. //
  1724. // Spit out handler table.
  1725. fprintf ( fpCXXFile, "\n\nstatic const CustomHandler _HandlerTable[] = {\n" );
  1726. for (i = 0; i < _cHandlers; i++)
  1727. {
  1728. fprintf ( fpCXXFile, " %s,\n", (LPCSTR)(_allHandlers[i].szRawString));
  1729. }
  1730. fprintf ( fpCXXFile, " NULL\n" );
  1731. fprintf ( fpCXXFile, "};\n\n" );
  1732. // Spit out function signatures for handlers.
  1733. for (i = 0; i < _cHandlers; i++)
  1734. {
  1735. fprintf ( fpCXXFile, "HRESULT %s (CBase *pBase,\n", (LPCSTR)(_allHandlers[i].szRawString) );
  1736. fprintf ( fpCXXFile, " IServiceProvider *pSrvProvider,\n" );
  1737. fprintf ( fpCXXFile, " IDispatch *pInstance,\n" );
  1738. fprintf ( fpCXXFile, " WORD wVTblOffset,\n" );
  1739. fprintf ( fpCXXFile, " PROPERTYDESC_BASIC_ABSTRACT *pDesc,\n" );
  1740. fprintf ( fpCXXFile, " WORD wFlags,\n" );
  1741. fprintf ( fpCXXFile, " DISPPARAMS *pdispparams,\n" );
  1742. fprintf ( fpCXXFile, " VARIANT *pvarResult)\n" );
  1743. fprintf ( fpCXXFile, "{\n" );
  1744. GenerateFunctionBody ( fpCXXFile, &(_allHandlers[i]) );
  1745. fprintf ( fpCXXFile, "}\n" );
  1746. }
  1747. fprintf ( fpCXXFile, "\n" );
  1748. for (i = 0; i < _cIID; i++)
  1749. {
  1750. fprintf ( fpCXXFile, "EXTERN_C const IID IID_%s;\n", _allIIDs[i] );
  1751. }
  1752. fprintf ( fpCXXFile, "\n\n" );
  1753. fprintf ( fpCXXFile, "#define MAX_IIDS %i\n", _cIID + 1); // The null entry at index 0.
  1754. fprintf ( fpCXXFile, "static const IID * _IIDTable[MAX_IIDS] = {\n" );
  1755. fprintf ( fpCXXFile, "\tNULL,\n" ); // Index 0 is reserved for primary dispatch interface.
  1756. // Spit out indexes into IID table.
  1757. for (i = 0; i < _cIID; i++)
  1758. {
  1759. fprintf ( fpCXXFile, "\t&IID_%s,\n", _allIIDs[i] );
  1760. }
  1761. fprintf ( fpCXXFile, "};\n");
  1762. fprintf ( fpCXXFile, "\n" );
  1763. // Helper function for mapping DISP_IHTMLxxxxx
  1764. fprintf ( fpCXXFile, "#define DIID_DispBase 0x3050f500\n" );
  1765. fprintf ( fpCXXFile, "#define DIID_DispMax 0x3050f5a0\n" );
  1766. fprintf ( fpCXXFile, "\n" );
  1767. fprintf ( fpCXXFile, "const GUID DIID_Low12Bytes = { 0x00000000, 0x98b5, 0x11cf, { 0xbb, 0x82, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x0b } };\n" );
  1768. fprintf ( fpCXXFile, "\n\n" );
  1769. fprintf ( fpCXXFile, "BOOL DispNonDualDIID(IID iid)\n" );
  1770. fprintf ( fpCXXFile, "{\n" );
  1771. fprintf ( fpCXXFile, "\tBOOL fRetVal = FALSE;\n" );
  1772. fprintf ( fpCXXFile, "\n" );
  1773. fprintf ( fpCXXFile, "\tif (iid.Data1 >= DIID_DispBase && iid.Data1 <= DIID_DispMax)\n" );
  1774. fprintf ( fpCXXFile, "\t{\n" );
  1775. fprintf ( fpCXXFile, "\t\tfRetVal = memcmp(&iid.Data2,\n" );
  1776. fprintf ( fpCXXFile, "\t\t\t\t&DIID_Low12Bytes.Data2,\n" );
  1777. fprintf ( fpCXXFile, "\t\t\t\tsizeof(IID) - sizeof(DWORD)) == 0;\n" );
  1778. fprintf ( fpCXXFile, "\t}\n" );
  1779. fprintf ( fpCXXFile, "\n" );
  1780. fprintf ( fpCXXFile, "\treturn fRetVal;\n" );
  1781. fprintf ( fpCXXFile, "}\n\n" );
  1782. fclose ( fpCXXFile );
  1783. return TRUE;
  1784. }
  1785. struct TypeMap {
  1786. char chType[32];
  1787. char chAutomationType[32];
  1788. char chCType[32];
  1789. VARTYPE vtResult;
  1790. };
  1791. static TypeMap _mapper[] = {
  1792. { "IDispatchp" , "VT_DISPATCH" , "IDispatch *" , VT_DISPATCH }, // Entry 0 is VT_DISPATCH
  1793. { "IDispatchpp" , "VT_DISPATCH | VT_BYREF" , "IDispatch **" , VT_DISPATCH | VT_BYREF }, // Entry 1 is VT_DISPATCH | VT_BYREF
  1794. { "DWORD" , "VT_I4" , "DWORD" , VT_I4 },
  1795. { "long" , "VT_I4" , "LONG" , VT_I4 },
  1796. { "LONG" , "VT_I4" , "LONG" , VT_I4 },
  1797. //************************************************************************************************
  1798. // Warning Warning Warning:
  1799. // This only works for abstract properies. To use it for non-abstract property, please modify corresponding Trident code
  1800. //
  1801. { "LONGPTR" , "VT_I4" , "LONG_PTR" , VT_I4},
  1802. { "LONGPTR" , "VT_I8" , "LONG_PTR" , VT_I8},
  1803. //
  1804. //************************************************************************************************
  1805. { "short" , "VT_I2" , "SHORT" , VT_I2 },
  1806. { "VARIANT" , "VT_VARIANT" , "VARIANT" , VT_VARIANT },
  1807. { "BSTR" , "VT_BSTR" , "BSTR" , VT_BSTR },
  1808. { "BOOL" , "VT_BOOL" , "VARIANT_BOOL" , VT_BOOL },
  1809. { "BOOLp" , "VT_BOOL | VT_BYREF" , "VARIANT_BOOL *" , VT_BOOL | VT_BYREF },
  1810. { "VARIANTp" , "VT_VARIANT | VT_BYREF" , "VARIANT *" , VT_VARIANT | VT_BYREF },
  1811. { "IUnknownp" , "VT_UNKNOWN" , "IUnknown *" , VT_UNKNOWN },
  1812. { "IUnknownpp" , "VT_UNKNOWN | VT_BYREF" , "IUnknown **" , VT_UNKNOWN | VT_BYREF },
  1813. { "float" , "VT_R4" , "float" , VT_R4 },
  1814. { "longp" , "VT_I4 | VT_BYREF" , "LONG *" , VT_I4 | VT_BYREF },
  1815. { "BSTRp" , "VT_BSTR | VT_BYREF" , "BSTR *" , VT_BSTR | VT_BYREF },
  1816. { "int" , "VT_I4" , "LONG" , VT_I4 },
  1817. { "VARIANTBOOL" , "VT_BOOL" , "VARIANT_BOOL" , VT_BOOL },
  1818. { "VARIANTBOOLp" , "VT_BOOL | VT_BYREF" , "VARIANT_BOOL *" , VT_BOOL | VT_BYREF },
  1819. { "SAFEARRAYPVARIANTP" , "VT_ARRAY" , "SAFEARRAY *" , VT_ARRAY },
  1820. { "void" , "" , "" , VT_EMPTY },
  1821. { "PropEnum" , "VT_BSTR" , "BSTR" , VT_BSTR }, // TODO: Remove and fix.
  1822. { "IHTMLControlElementp", "VT_DISPATCH" , "IDispatch *" , VT_DISPATCH }, // TODO: Not converted to IDispatch
  1823. { "IHTMLElementpp" , "VT_DISPATCH | VT_BYREF" , "IDispatch **" , VT_DISPATCH | VT_BYREF }, // TODO: Not converted to IDispatch
  1824. { "IHTMLElementCollectionpp" , "VT_DISPATCH | VT_BYREF" , "IDispatch **" , VT_DISPATCH | VT_BYREF }, // TODO: Not converted to IDispatch
  1825. { "" , "" , "" , VT_EMPTY }
  1826. };
  1827. BOOL MapTypeToAutomationType (char *pTypeStr, char **ppAutomationType, char **ppCType, VARTYPE *pVTType)
  1828. {
  1829. int i = 0;
  1830. int win64offset = 0;
  1831. VARTYPE vtTemp;
  1832. if (!pVTType)
  1833. pVTType = &vtTemp;
  1834. if (gfWin64)
  1835. win64offset = 1;
  1836. while (_mapper[i].chType[0])
  1837. {
  1838. if (strcmp(_mapper[i].chType, pTypeStr) == 0)
  1839. {
  1840. //
  1841. // special handling for LONGPTR is required since it will be
  1842. // resolved to two diffferent types depending on arch!
  1843. //
  1844. if (strcmp(_mapper[i].chType, "LONGPTR") == 0)
  1845. {
  1846. i += win64offset;
  1847. }
  1848. *ppAutomationType = _mapper[i].chAutomationType;
  1849. *ppCType = _mapper[i].chCType;
  1850. *pVTType = _mapper[i].vtResult;
  1851. return TRUE;
  1852. }
  1853. i++;
  1854. }
  1855. return FALSE;
  1856. }
  1857. BOOL ProcessDatFile ( LPCSTR pszOutputPath )
  1858. {
  1859. char *buffer;
  1860. FILE *fpDatFile;
  1861. char chDatFileName[255];
  1862. char szTextError[MAX_LINE_LEN+1];
  1863. char *pATypeStr;
  1864. char *pCTypeStr;
  1865. int cLines;
  1866. if ( !pszOutputPath )
  1867. return FALSE;
  1868. strcpy(chDatFileName, pszOutputPath);
  1869. strcat(chDatFileName, FILENAME_SEPARATOR_STR "funcsig.dat");
  1870. fpDatFile = fopen ( chDatFileName, "rb");
  1871. if ( !fpDatFile )
  1872. {
  1873. return FALSE;
  1874. }
  1875. if ( fseek( fpDatFile, 0, SEEK_END ) == 0 )
  1876. {
  1877. fpos_t pos;
  1878. if ( fgetpos( fpDatFile, &pos ) == 0 )
  1879. {
  1880. int i = 0;
  1881. buffer = new char[pos];
  1882. if (buffer == NULL)
  1883. return FALSE;
  1884. fseek( fpDatFile, 0, SEEK_SET );
  1885. if ( (unsigned) fread ( buffer, 1, pos, fpDatFile ) != pos )
  1886. return FALSE;
  1887. // Create the header file from the .dat file.
  1888. _cHandlers = buffer[0]; // Number of signatures
  1889. _cHandlers &= 0x000000ff;
  1890. _cIID = buffer[1]; // Number of IIDs
  1891. _cIID &= 0x000000ff;
  1892. if (_cHandlers >= MAX_HANDLERS)
  1893. {
  1894. PDLError("To many handlers increase MAX_HANDLERS\n");
  1895. goto Error;
  1896. }
  1897. if (_cIID >= MAX_IIDS)
  1898. {
  1899. PDLError("To many handlers increase MAX_IIDS\n");
  1900. goto Error;
  1901. }
  1902. i = 4; // Skip 4 byte header.
  1903. cLines = 0;
  1904. while ( cLines < _cHandlers )
  1905. {
  1906. char *pStrWork;
  1907. char *pStrWork2;
  1908. int cStr = strlen ( buffer + i );
  1909. // Copy raw function signature.
  1910. _allHandlers[cLines].szRawString = (buffer + i);
  1911. pStrWork = buffer + i;
  1912. // Get type
  1913. pStrWork2 = strchr(pStrWork, '_');
  1914. if (!pStrWork2)
  1915. goto Error;
  1916. *pStrWork2 = '\0';
  1917. _allHandlers[cLines].invokeType = ATYPE_Undefined;
  1918. if (strchr(pStrWork, 'G'))
  1919. _allHandlers[cLines].invokeType |= ATYPE_GetProperty;
  1920. if (strchr(pStrWork, 'S'))
  1921. _allHandlers[cLines].invokeType |= ATYPE_SetProperty;
  1922. if (strchr(pStrWork, 'M'))
  1923. _allHandlers[cLines].invokeType = ATYPE_Method;
  1924. // Point pass the G, S, GS or Method
  1925. pStrWork = pStrWork2 + 1;
  1926. if (_allHandlers[cLines].invokeType == ATYPE_Method)
  1927. {
  1928. // Do method parsing:
  1929. int iArg;
  1930. pStrWork2 = strchr(pStrWork, '_');
  1931. if (!pStrWork2)
  1932. {
  1933. PDLError("bad method result");
  1934. return FALSE;
  1935. }
  1936. *pStrWork2 = '\0';
  1937. // Get result type
  1938. if (MapTypeToAutomationType(pStrWork, &pATypeStr, &pCTypeStr, &(_allHandlers[cLines].vtResult)))
  1939. {
  1940. _allHandlers[cLines].szVTResult = pATypeStr;
  1941. _allHandlers[cLines].szCResult = pCTypeStr;
  1942. }
  1943. else
  1944. {
  1945. sprintf(szTextError, "result type '%s' not found.", pStrWork);
  1946. PDLError(szTextError);
  1947. return FALSE;
  1948. }
  1949. pStrWork = pStrWork2 + 1;
  1950. // arg parsing:
  1951. iArg = 0;
  1952. while (*pStrWork)
  1953. {
  1954. pStrWork2 = strchr(pStrWork, '_');
  1955. if (pStrWork2)
  1956. {
  1957. *pStrWork2 = '\0';
  1958. }
  1959. // optional argument?
  1960. _allHandlers[cLines].params[iArg].fOptional =
  1961. (pStrWork[0] == 'o' &&
  1962. pStrWork[1] == '0' &&
  1963. pStrWork[2] == 'o');
  1964. _allHandlers[cLines].params[iArg].fDefaultValue =
  1965. (pStrWork[0] == 'o' &&
  1966. pStrWork[1] == 'D' &&
  1967. pStrWork[2] == 'o');
  1968. if (_allHandlers[cLines].params[iArg].fOptional ||
  1969. _allHandlers[cLines].params[iArg].fDefaultValue)
  1970. {
  1971. pStrWork += 3; // Skip o0o or oDo which signals optional (litle o zero little o) or defaultValue.
  1972. }
  1973. if (MapTypeToAutomationType(pStrWork, &pATypeStr, &pCTypeStr, &(_allHandlers[cLines].params[iArg].vtParam)))
  1974. {
  1975. _allHandlers[cLines].params[iArg].szVTParamType = pATypeStr;
  1976. _allHandlers[cLines].params[iArg].szCParamType = pCTypeStr;
  1977. }
  1978. else
  1979. {
  1980. sprintf(szTextError, "argument type '%s' not found.", pStrWork);
  1981. PDLError(szTextError);
  1982. return FALSE;
  1983. }
  1984. pStrWork += strlen(pStrWork);
  1985. // More args to parse?
  1986. if (pStrWork2)
  1987. pStrWork++; // Point at next arg.
  1988. iArg++;
  1989. }
  1990. }
  1991. else
  1992. {
  1993. // Do property parsing
  1994. if (MapTypeToAutomationType(pStrWork, &pATypeStr, &pCTypeStr, &(_allHandlers[cLines].vtResult)))
  1995. {
  1996. _allHandlers[cLines].szVTResult = pATypeStr;
  1997. _allHandlers[cLines].szCResult = pCTypeStr;
  1998. }
  1999. else
  2000. {
  2001. sprintf(szTextError, "type '%s' not found.", pStrWork);
  2002. PDLError(szTextError);
  2003. return FALSE;
  2004. }
  2005. }
  2006. cLines++;
  2007. i += cStr + 1;
  2008. }
  2009. // Load up the IIDs.
  2010. cLines = 0;
  2011. while ( cLines < _cIID )
  2012. {
  2013. int cStr = strlen ( buffer + i );
  2014. _allIIDs[cLines] = buffer + i;
  2015. cLines++;
  2016. i += cStr + 1;
  2017. }
  2018. fclose ( fpDatFile );
  2019. return TRUE;
  2020. }
  2021. }
  2022. Error:
  2023. return FALSE;
  2024. }
  2025. int __cdecl
  2026. main ( int argc, char *argv[] )
  2027. {
  2028. int nReturnCode;
  2029. char szInputFile [ MAX_PATH+1 ];
  2030. char szOutputFileRoot [ MAX_PATH+1 ];
  2031. char szPDLFileName [ MAX_PATH+1 ];
  2032. char szOutputPath [ MAX_PATH+1 ];
  2033. BOOL fDebugging = FALSE;
  2034. {
  2035. CPDLParser Parser;
  2036. // argv[1] is the name of a file containing build args
  2037. // arg1 of this file is the full path/filename of the input file
  2038. // arg2 is the full name of the output file, minus the file extension
  2039. // arg3 is the 8.3 pdl file name
  2040. // arg4 is a log file name
  2041. if ( argc == 5 )
  2042. {
  2043. strcpy ( szInputFile, argv [ 1] );
  2044. strcpy ( szOutputFileRoot, argv [ 2 ] );
  2045. strcpy ( szPDLFileName, argv [ 3 ] );
  2046. strcpy ( szOutputPath, argv [ 4 ] );
  2047. fDebugging = TRUE;
  2048. }
  2049. else if ( argc == 4 && _stricmp( argv[1], "/g") == 0 ||
  2050. _stricmp( argv[1], "-g") == 0 )
  2051. {
  2052. if (_stricmp(argv[2], "win64") == 0)
  2053. {
  2054. gfWin64 = TRUE;
  2055. }
  2056. else if (_stricmp(argv[2], "i386") ==0)
  2057. {
  2058. gfWin64 = FALSE;
  2059. }
  2060. else
  2061. {
  2062. printf ( "Invalid command line params\n" );
  2063. nReturnCode = 3;
  2064. goto Cleanup;
  2065. }
  2066. // Process the funcsig.dat file and produce custsig.hxx file:
  2067. if (!ProcessDatFile ( argv [ 3 ] ))
  2068. {
  2069. nReturnCode = 4;
  2070. goto Cleanup;
  2071. }
  2072. if (!GenerateVTableHeader ( argv [ 3 ] ))
  2073. {
  2074. nReturnCode = 4;
  2075. goto Cleanup;
  2076. }
  2077. if (!GenerateVTableCXX ( argv [ 3 ] ))
  2078. {
  2079. nReturnCode = 4;
  2080. goto Cleanup;
  2081. }
  2082. FILE *fpMaxLenFile = NULL;
  2083. strcpy(szOutputPath, argv [ 3 ]);
  2084. strcat(szOutputPath, FILENAME_SEPARATOR_STR "maxlen.txt");
  2085. fpMaxLenFile = fopen(szOutputPath, "r+");
  2086. if (fpMaxLenFile)
  2087. {
  2088. char chMarker[6];
  2089. strcpy(chMarker, "Const");
  2090. fwrite(chMarker, sizeof(char), 5, fpMaxLenFile);
  2091. fclose(fpMaxLenFile);
  2092. }
  2093. #ifdef COMPLUS_SHIM
  2094. if (!GenerateNDirectHeader ( argv [ 3 ] ))
  2095. {
  2096. nReturnCode = 4;
  2097. goto Cleanup;
  2098. }
  2099. if (!GenerateNDirectCXX ( argv [ 3 ] ))
  2100. {
  2101. nReturnCode = 4;
  2102. goto Cleanup;
  2103. }
  2104. if (!GenerateComPlusHeader ( argv [ 3] ))
  2105. {
  2106. nReturnCode = 4;
  2107. goto Cleanup;
  2108. }
  2109. if (!GenerateComPlusCXX ( argv [ 3 ] ))
  2110. {
  2111. nReturnCode = 4;
  2112. goto Cleanup;
  2113. }
  2114. #endif // COMPLUS_SHIM
  2115. nReturnCode = 0;
  2116. goto Cleanup;
  2117. }
  2118. else if ( argc > 1 )
  2119. {
  2120. if ( !ScanBuildFile ( argv[ 1 ],
  2121. szInputFile,
  2122. szOutputFileRoot,
  2123. szPDLFileName,
  2124. szOutputPath ) )
  2125. {
  2126. printf ( "Cant scan build file\n" );
  2127. nReturnCode = 2;
  2128. goto Cleanup;
  2129. }
  2130. }
  2131. else
  2132. {
  2133. printf ( "Invalid command line params\n" );
  2134. nReturnCode = 3;
  2135. goto Cleanup;
  2136. }
  2137. nReturnCode = Parser.Parse ( szInputFile, szOutputFileRoot,
  2138. szPDLFileName, szOutputPath, fDebugging );
  2139. }
  2140. Cleanup:
  2141. if ( nReturnCode != 0 )
  2142. printf ( "Error %d building PDL file\n", nReturnCode );
  2143. exit ( nReturnCode );
  2144. }
  2145. #ifndef X_DATA_CXX_
  2146. #define X_DATA_CXX_
  2147. #include "data.cxx"
  2148. #endif
  2149. #ifndef X_ASSOC_CXX_
  2150. #define X_ASSOC_CXX_
  2151. #include "assoc.cxx"
  2152. #endif
  2153. #ifndef X_PARSER_CXX_
  2154. #define X_PARSER_CXX_
  2155. #include "parser.cxx"
  2156. #endif