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.

1973 lines
67 KiB

  1. /*
  2. Related Files:
  3. [Section=Compile]
  4. %TlViewerDir%:tlviewer.hxx
  5. [Platform= 3] %ApGlobalSrcDir%:apglobal.h
  6. %OsUtilDir%:osutil.hxx
  7. [Section=Link]
  8. [Options=NO_COPY] tlviewer.obj
  9. OsUtil.obj %OsUtilDir%:OsUtil.cpp
  10. [Platform= 6,7,8 Options=CVTRES] _resfile.obj %TlViewerDir%:RcBuild.ins
  11. [Platform= 6,7,8 Options=product] ole32.lib
  12. [Platform= 6,7,8 Options=product] oleaut32.lib
  13. [Platform= 6,7,8 Options=product] uuid.lib
  14. [Platform= 6,7,8 Options=SYSTEM_LIB] kernel32.lib
  15. [Platform= 6,7,8 Options=SYSTEM_LIB] user32.lib
  16. [Platform= 6,7,8 Options=C_LIB] libc.lib
  17. [Platform= 3 Options=C_LIB] libw.lib
  18. [Platform= 3 Options=C_LIB] mlibcew.lib
  19. [Platform= 3 Options=Product] typelib.lib
  20. [Platform= 3 Options=Product] ole2disp.lib
  21. [Platform= 3 Options=Product] ole2.lib
  22. [Platform= 3 Options=DEFFILE] %TlViewerDir%:%platform%:tlviewer.def
  23. [Platform= 1] %BuildLibs%:Ole2Auto.far.debug.o
  24. [Platform= 1] %BuildLibs%:Ole2Lib.far.debug.o
  25. [Platform= 1] %BuildLibs%:StdCLib.o
  26. [Platform= 1] %BuildLibs%:Stubs.o
  27. [Platform= 1] %BuildLibs%:Runtime.o
  28. [Platform= 1] %BuildLibs%:Interface.o
  29. [Section=end]
  30. [ 0] Created AngelaCh
  31. [ 1] Added additional attributes ChrisK
  32. [ 2] 17-Mar-1994 Added support for Win32s AngelaCh
  33. [ 3] 08-Apr-1994 Added LPWSTR AngelaCh
  34. [ 4] 08-Apr-1994 Added check for Licensed attr AngelaCh
  35. [ 5] 20-Apr-1994 Added check for Alignment AngelaCh
  36. [ 6] 24-May-1994 Added check for Source in method AngelaCh
  37. [ 7] 25-May-1994 Added checks for diff attributes AngelaCh
  38. [ 8] 19-Dec-1994 Fixed problem in tOutDaul AngelaCh
  39. [ 9] 08-Feb-1995 Added support for Null str const AngelaCh
  40. [10] 08-Feb-1995 Added support for typeinfo level AngelaCh
  41. Restricted attribute
  42. [11] 08-Feb-1995 Added support for GetLastError Angelach
  43. [12] 18-Apr-1995 Added support for float's Angelach
  44. ============================================================================== */
  45. #include "tlviewer.hxx"
  46. const IID IID_ITypeLib2 = {0x00020411,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  47. const IID IID_ITypeInfo2 = {0x00020412,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  48. ITypeInfo2 * ptinfo2 = NULL;
  49. ITypeLib2 * ptlib2 = NULL;
  50. BSTRX g_bstrHelpDll = NULL; // name of help DLL
  51. VOID FAR mainEntry (LPXSTR lpCmd)
  52. {
  53. if ( *lpCmd )
  54. {
  55. ParseCmdLine (lpCmd) ; // get name of in/output files
  56. ProcessInput () ; // read input file
  57. }
  58. else
  59. osMessage(XSTR("Usage: tlviewer <tlbfile> [<outputfile> [Alignment] [</o]]"), XSTR("Tlviewer")) ; // [5]
  60. }
  61. VOID NEAR ParseCmdLine (LPXSTR lpsz)
  62. {
  63. XCHAR szlTmp[fMaxBuffer] ;
  64. LPXSTR lpszTmp ; // name of input type library
  65. // is expected to be in the
  66. lpszTmp = lpsz ; // first substring; name of
  67. lpszTmp = fGetFileName (lpszTmp, szInputFile) ;
  68. lpszTmp = fGetFileName (lpszTmp, szOutputFile) ;
  69. // output is in the second
  70. // substring if specified
  71. if ( !*szOutputFile ) // if no ouput file is
  72. osStrCpy ( szOutputFile, defaultOutput ) ;
  73. // specified; use default
  74. lpszTmp = fGetFileName (lpszTmp, szlTmp) ; // see if /o
  75. // option is given
  76. isOut = TRUE; // always as if /o was specified
  77. if ( osStrCmp(szlTmp, outOpt) == 0 )
  78. isOut = TRUE ;
  79. else // if may be specifying an [5]
  80. if ( *szlTmp ) // alignment value
  81. {
  82. inAlign = (unsigned short) osAtoL(szlTmp); // get alignment value
  83. lpszTmp = fGetFileName (lpszTmp, szlTmp) ; // see if /o
  84. if ( osStrCmp(szlTmp, outOpt) == 0 ) // option is given
  85. isOut = TRUE ;
  86. }
  87. }
  88. LPXSTR NEAR fGetFileName (LPXSTR lpszIn, LPXSTR lpszOut)
  89. {
  90. int i = 0 ;
  91. LPXSTR lpszTmp ;
  92. lpszTmp = lpszIn ;
  93. while ( *lpszTmp == ' ' ) // remove leading spaces
  94. lpszTmp++ ;
  95. while ( *lpszTmp != '\0' && *lpszTmp != ' ') // copy the substring (up
  96. { // to the first space) or
  97. lpszOut[i] = *lpszTmp ; // the entire string of
  98. lpszTmp++ ; // lpszIn to lpszOut
  99. i++ ;
  100. }
  101. lpszOut[i] = '\0' ;
  102. return lpszTmp ; // return the remaining string
  103. }
  104. VOID NEAR ProcessInput()
  105. {
  106. HRESULT hRes ; // return code
  107. XCHAR szTmp[fMaxBuffer] ;
  108. hRes = osOleInit () ; // ole initialization
  109. if ( !hRes )
  110. { // load the file
  111. hRes = LoadTypeLibX( szInputFile, &ptLib) ; // [2]
  112. OutToFile (hRes) ; // print result to the
  113. // output file
  114. osStrCpy(szTmp, szOutputFile) ;
  115. osStrCat(szTmp, szOutSuccess) ;
  116. if ( isOut )
  117. {
  118. mFile = fopenX(szOutMsgFile, fnWrite);// open message file [2]
  119. if (mFile == NULL)
  120. {
  121. osMessage (XSTR("Fail to open the message file"), XSTR("Tlviewer")) ;
  122. osMessage (szTmp, XSTR("Tlviewer")) ;
  123. }
  124. else
  125. {
  126. WriteOut(mFile, szTmp) ;
  127. fclose(mFile) ; // finish writing to message file
  128. mFile = NULL ; // close done
  129. }
  130. }
  131. else
  132. osMessage (szTmp, XSTR("Tlviewer")) ;
  133. osOleUninit () ;
  134. }
  135. else
  136. {
  137. if ( isOut )
  138. {
  139. mFile = fopenX(szOutMsgFile, fnWrite);// open message file [2]
  140. if (mFile == NULL)
  141. {
  142. osMessage (XSTR("Fail to open the message file"), XSTR("Tlviewer")) ;
  143. osMessage (XSTR("OleInitialize fails"), XSTR("Tlviewer")) ;
  144. }
  145. else
  146. {
  147. WriteOut(mFile, XSTR("OleInitialize fails")) ;
  148. fclose(mFile) ;
  149. mFile = NULL ;
  150. }
  151. }
  152. else
  153. osMessage (XSTR("OleInitialize fails"), XSTR("Tlviewer")) ;
  154. }
  155. }
  156. VOID NEAR OutToFile(HRESULT hRes)
  157. {
  158. FILE *hFile ; // file handle
  159. UINT tInfoCount ; // total number of type info
  160. int i ; // note: szTmp is either UNICODE
  161. XCHAR szTmp[fMaxBuffer] ; // or ANSI
  162. hFile = fopenX(szOutputFile, fnWrite); // but we want to open output file [2]
  163. if (hFile == NULL) // as an ANSI file regardless
  164. {
  165. osStrCpy(szTmp, XSTR("Fail to open the output file")) ;
  166. osStrCat(szTmp, szOutputFile) ;
  167. if ( isOut )
  168. {
  169. mFile = fopenX(szOutMsgFile, fnWrite);// open message file [2]
  170. if (mFile == NULL)
  171. {
  172. osMessage (XSTR("Fail to open the message file"), XSTR("Tlviewer")) ;
  173. osMessage (szTmp, XSTR("Tlviewer")) ;
  174. }
  175. else
  176. {
  177. WriteOut(mFile, szTmp) ;
  178. fclose(mFile) ;
  179. mFile = NULL ;
  180. }
  181. }
  182. else
  183. osMessage (szTmp, XSTR("Tlviewer")) ;
  184. }
  185. else
  186. {
  187. WriteOut(hFile, szFileHeader) ; // output file header
  188. OLECHAR FAR* pchDir;
  189. // remove the path.
  190. #if WIN32
  191. wcscpy(szTmp, szInputFile);
  192. pchDir = wcsrchr(szTmp, '\\');
  193. if (pchDir) {
  194. wcscpy(szTmp, pchDir + 1);
  195. }
  196. #else // !WIN32
  197. _fstrcpy(szTmp, szInputFile);
  198. pchDir = _fstrrchr(szTmp, '\\');
  199. if (pchDir) {
  200. _fstrcpy(szTmp, pchDir + 1);
  201. }
  202. #endif // !WIN32
  203. // force path to lower case
  204. #if WIN16
  205. AnsiLower(szTmp);
  206. #else //WIN16
  207. WCHAR * pch;
  208. for (pch = szTmp; *pch != 0; pch++) {
  209. if (*pch >= OLECHAR('A') && *pch <= OLECHAR('Z'))
  210. *pch = *pch + 'a' - 'A';
  211. }
  212. #endif //WIN16
  213. WriteOut(hFile, szTmp) ;
  214. WriteOut(hFile, szEndStr) ;
  215. if ( FAILED(hRes) ) // if it is not a valid type ****
  216. WriteOut(hFile, szInputInvalid) ;// library
  217. else
  218. {
  219. // try to QI the typelib for ITypeLib2
  220. ptLib->QueryInterface(IID_ITypeLib2, (void **)&ptlib2);
  221. if ( fOutLibrary(hFile) )
  222. {
  223. tInfoCount = ptLib->GetTypeInfoCount() ;
  224. for (i = 0 ; i < (int) tInfoCount ; i++)
  225. {
  226. if ( FAILED(ptLib->GetTypeInfo(i, &ptInfo)) )
  227. {
  228. WriteOut(hFile, szReadFail) ;
  229. WriteOut(hFile, XSTR("type info\n\n")) ;
  230. }
  231. else
  232. {
  233. // try to QI it for ITypeInfo2
  234. ptInfo->QueryInterface(IID_ITypeInfo2, (void **)&ptinfo2);
  235. if ( FAILED(ptInfo->GetTypeAttr(&lpTypeAttr)) )
  236. {
  237. WriteOut(hFile, szReadFail) ;
  238. WriteOut(hFile, XSTR("attributes of type info\n\n")) ;
  239. }
  240. else
  241. {
  242. expAlign = 0 ;
  243. alignFound = FALSE ;
  244. switch (lpTypeAttr->typekind)
  245. {
  246. case TKIND_ENUM:
  247. tOutEnum(hFile, i) ;
  248. break ;
  249. case TKIND_RECORD:
  250. tOutRecord(hFile, i) ;
  251. break ;
  252. case TKIND_MODULE:
  253. tOutModule(hFile, i) ;
  254. break ;
  255. case TKIND_INTERFACE:
  256. tOutInterface(hFile, i) ;
  257. break ;
  258. case TKIND_DISPATCH:
  259. tOutDispatch(hFile, i) ;
  260. break ;
  261. case TKIND_COCLASS:
  262. tOutCoclass(hFile, i) ;
  263. break ;
  264. case TKIND_ALIAS:
  265. tOutAlias(hFile, i) ;
  266. break ;
  267. case TKIND_UNION:
  268. tOutUnion(hFile, i) ;
  269. break ;
  270. /* case TKIND_ENCUNION:
  271. tOutEncunion(hFile, i) ;
  272. break ; */
  273. default:
  274. WriteOut(hFile, XSTR("Type of definition is unknown\n\n")) ;
  275. } // switch
  276. ptInfo->ReleaseTypeAttr (lpTypeAttr) ;
  277. } // if gettypeattr
  278. ptInfo->Release() ;// release the current TypeInfo
  279. if (ptinfo2) {
  280. ptinfo2->Release();
  281. }
  282. } // if gettypeinfo
  283. } // for i
  284. WriteOut(hFile, XSTR("}\n")) ; // output the closing }
  285. // if fOutLibrary
  286. ptLib->Release(); // clean up before exit
  287. }
  288. }
  289. fclose(hFile); // finish writing to the output
  290. hFile = NULL; // close done
  291. }
  292. if (ptlib2) {
  293. ptlib2->Release();
  294. }
  295. SysFreeString((BSTR)g_bstrHelpDll) ;
  296. }
  297. VOID NEAR tOutCustData (FILE *hFile, LPCUSTDATA pCustData)
  298. {
  299. XCHAR szTmp[50] ;
  300. UINT i;
  301. for (i = 0; i < pCustData->cCustData; i++) {
  302. // get a string representation
  303. // for the incoming Guid value
  304. if ( !(osRetrieveGuid (szTmp, pCustData->prgCustData[i].guid)) )
  305. { WriteOut(hFile, szReadFail) ;
  306. WriteOut(hFile, XSTR("insufficient memory")) ;
  307. }
  308. else
  309. { // string is in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
  310. szTmp[37] = '\0' ; // format, need to remove the {}
  311. WriteAttr(hFile, XSTR("CustomGuid"), &szTmp[1], numValue) ;
  312. VARIANT * pvar;
  313. pvar = &pCustData->prgCustData[i].varValue;
  314. if ( FAILED(VariantChangeType(pvar, pvar, VARIANT_NOVALUEPROP, VT_BSTR)) )
  315. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  316. else {
  317. WriteAttr(hFile, XSTR("CustomValue"), (BSTRX)pvar->bstrVal, strValue) ;
  318. }
  319. }
  320. }
  321. // done with it -- release all the memory
  322. ClearCustData(pCustData);
  323. }
  324. BOOL NEAR fOutLibrary(FILE *hFile)
  325. {
  326. TLIBATTR FAR *lpLibAttr ; // attributes of the library
  327. XCHAR szTmp[16] ;
  328. BOOL retval = FALSE ;
  329. if ( FAILED( ptLib->GetLibAttr(&lpLibAttr) ) )
  330. {
  331. WriteOut(hFile, szReadFail) ;
  332. WriteOut(hFile, XSTR("attributes of library\n\n")) ;
  333. }
  334. else
  335. { // output documentational
  336. tOutAttr(hFile, -1) ; // attributes first
  337. // output id-related attributes
  338. osLtoA((long)lpLibAttr->lcid, szTmp) ; // output lcid;
  339. WriteAttr(hFile, attrLcid, szTmp, numValue) ; // default is 0
  340. GetVerNumber (lpLibAttr->wMajorVerNum, lpLibAttr->wMinorVerNum, szTmp) ;
  341. WriteAttr(hFile, attrVer, szTmp, numValue) ; // output version
  342. tOutUUID(hFile, lpLibAttr->guid) ;
  343. // output restricted attribute
  344. if ( (lpLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) == LIBFLAG_FRESTRICTED )
  345. WriteAttr(hFile, attrRestrict, NULL, noValue) ;
  346. if ( (lpLibAttr->wLibFlags & LIBFLAG_FCONTROL) == LIBFLAG_FCONTROL ) // [7]
  347. WriteAttr(hFile, attrControl, NULL, noValue) ;
  348. if ( (lpLibAttr->wLibFlags & LIBFLAG_FHIDDEN) == LIBFLAG_FHIDDEN ) // [7]
  349. WriteAttr(hFile, attrHidden, NULL, noValue) ;
  350. if (ptlib2) {
  351. // new-format typelib
  352. XCHAR szTmp[16] ;
  353. DWORD cUniqueNames;
  354. DWORD cchUniqueNames;
  355. HRESULT hresult;
  356. hresult = ptlib2->GetLibStatistics(&cUniqueNames, &cchUniqueNames);
  357. osLtoA(cUniqueNames, szTmp);
  358. WriteAttr(hFile, XSTR("cUniqueNames"), szTmp, numValue) ;
  359. osLtoA(cchUniqueNames, szTmp);
  360. WriteAttr(hFile, XSTR("cchUniqueNames"), szTmp, numValue) ;
  361. CUSTDATA custdata;
  362. ptlib2->GetAllCustData(&custdata);
  363. tOutCustData(hFile, &custdata);
  364. }
  365. if ( endAttrFlag )
  366. {
  367. WriteOut(hFile, szEndAttr) ;
  368. endAttrFlag = FALSE ;
  369. }
  370. ptLib->ReleaseTLibAttr(lpLibAttr) ; // de-allocate attribute
  371. WriteOut(hFile, XSTR("\nlibrary ")) ;
  372. tOutName(hFile, MEMBERID_NIL) ; // output name of library
  373. WriteOut(hFile, XSTR("{\n\n")) ;
  374. retval = TRUE ;
  375. } // if GetLibAttributes
  376. return (retval) ; // before exit
  377. }
  378. VOID NEAR tOutEnum (FILE *hFile, int iTypeId)
  379. {
  380. WriteOut(hFile, XSTR("\ntypedef\n")); // output typedef first
  381. tOutAttr(hFile, (int)iTypeId) ; // output attribute
  382. tOutMoreAttr(hFile) ;
  383. WriteOut(hFile, XSTR("\nenum {\n")) ;
  384. tOutVar(hFile) ; // output enum members
  385. WriteOut(hFile, XSTR("} ")) ; // close the definition and
  386. tOutName(hFile, iTypeId) ; // output name of the enum type
  387. WriteOut(hFile, XSTR(" ;")) ;
  388. if ( inAlign ) // [5]
  389. if ( lpTypeAttr->cbAlignment != osGetAlignment(VT_INT, inAlign) )
  390. tOutAlignError (hFile) ;
  391. WriteOut(hFile, XSTR("\n\n")) ;
  392. }
  393. VOID NEAR tOutRecord (FILE *hFile, int iTypeId)
  394. {
  395. WriteOut(hFile, XSTR("\ntypedef\n")); // output typedef first
  396. tOutAttr(hFile, (int)iTypeId) ; // output attribute
  397. tOutMoreAttr(hFile) ;
  398. WriteOut(hFile, XSTR("\nstruct {\n")) ;
  399. tOutVar (hFile) ; // output members
  400. WriteOut(hFile, XSTR("} ")) ;
  401. tOutName(hFile, iTypeId) ;
  402. WriteOut(hFile, XSTR(" ;")) ;
  403. if ( inAlign ) // [5]
  404. if ( lpTypeAttr->cbAlignment != expAlign )
  405. tOutAlignError (hFile) ;
  406. WriteOut(hFile, XSTR("\n\n")) ;
  407. }
  408. VOID NEAR tOutModule (FILE *hFile, int iTypeId)
  409. {
  410. tOutAttr(hFile, (int)iTypeId) ; // output attribute first
  411. tOutMoreAttr(hFile) ;
  412. WriteOut(hFile, XSTR("\nmodule ")) ;
  413. tOutName(hFile, iTypeId) ;
  414. WriteOut(hFile, XSTR(" {\n")) ;
  415. tOutVar (hFile) ; // output each const
  416. tOutFunc (hFile) ; // output each member function
  417. WriteOut(hFile, XSTR("}\n\n")) ;
  418. }
  419. VOID NEAR tOutInterface(FILE *hFile, int iTypeId)
  420. {
  421. HREFTYPE phRefType ;
  422. tOutAttr(hFile, (int)iTypeId) ; // output attribute first
  423. tOutMoreAttr(hFile) ;
  424. WriteOut(hFile, XSTR("\ninterface ")) ;
  425. tOutName(hFile, iTypeId) ;
  426. // find out if the interface
  427. if ( !FAILED(ptInfo->GetRefTypeOfImplType(0, &phRefType)) )
  428. {
  429. isInherit = TRUE ;
  430. tOutAliasName(hFile, phRefType) ; // is inherited from some other
  431. isInherit = FALSE ; // interface
  432. }
  433. WriteOut(hFile, XSTR(" {\n")) ;
  434. tOutFunc (hFile) ; // output each member function
  435. if ( inAlign ) // [5]
  436. {
  437. if ( expAlign ) // is base-interface exists
  438. { // alignment depends on the base-
  439. if ( lpTypeAttr->cbAlignment != expAlign ) // interface
  440. tOutAlignError (hFile) ;
  441. }
  442. else // otherwise, it depends on
  443. if ( lpTypeAttr->cbAlignment != osGetAlignment(VT_PTR, inAlign) )
  444. tOutAlignError (hFile) ; // size of a pointer
  445. }
  446. WriteOut(hFile, XSTR("}\n\n")) ;
  447. }
  448. VOID NEAR tOutDual (FILE *hFile, int iTypeId) // [7]
  449. {
  450. ITypeInfoX FAR *lptInfo ;
  451. TYPEATTR FAR *lpAttr ;
  452. HREFTYPE phRefType ;
  453. // obtain reference to the
  454. if ( FAILED(ptInfo->GetRefTypeOfImplType((UINT)MEMBERID_NIL, &phRefType)) )
  455. { // dual interface
  456. WriteOut(hFile, szReadFail) ;
  457. WriteOut(hFile, XSTR("tOutDispach: GetRefTypeOfImpType\n")) ;
  458. }
  459. else
  460. { // get a pointer to the dual
  461. if ( FAILED(ptInfo->GetRefTypeInfo(phRefType, &lptInfo)) )
  462. { // interface
  463. WriteOut(hFile, szReadFail) ;
  464. WriteOut(hFile, XSTR("tOutDispatch: GetRefTypeInfo\n")) ;
  465. }
  466. else
  467. {
  468. if ( FAILED(lptInfo->GetTypeAttr(&lpAttr)) )
  469. {
  470. WriteOut(hFile, szReadFail) ;
  471. WriteOut(hFile, XSTR("attribute of reftype in tOutDual\n\n")) ;
  472. lptInfo->Release () ; // [8]
  473. }
  474. else
  475. {
  476. if ( lpAttr->typekind != TKIND_INTERFACE )
  477. {
  478. WriteOut(hFile, szReadFail) ;
  479. WriteOut(hFile, XSTR("attribute of reftype in tOutDual\n\n")) ;
  480. lptInfo->ReleaseTypeAttr (lpAttr) ;
  481. lptInfo->Release () ; // [8]
  482. }
  483. else
  484. {
  485. ptInfo->ReleaseTypeAttr (lpTypeAttr) ;
  486. ptInfo->Release () ; // release the Dispinterface [8]
  487. lpTypeAttr = lpAttr ;
  488. ptInfo = lptInfo ; // now points to the interface
  489. tOutInterface(hFile, iTypeId) ; // output the dual interface
  490. }
  491. } // if typekind
  492. } // if GetRefTypeInfo
  493. } // if GetRefTypeOfImplType
  494. }
  495. VOID NEAR tOutDispatch (FILE *hFile, int iTypeId)
  496. {
  497. // dump the dispinterface, and dispinterface versions of dual interfaces
  498. tOutAttr(hFile, (int)iTypeId) ; // output attribute first
  499. tOutMoreAttr(hFile) ;
  500. WriteOut(hFile, XSTR("\ndispinterface ")) ;
  501. tOutName(hFile, iTypeId) ;
  502. WriteOut(hFile, XSTR(" {\n")) ;
  503. // if there is no data nor function
  504. WriteOut(hFile, XSTR("\nproperties:\n")) ;
  505. tOutVar (hFile) ; // output each date member
  506. WriteOut(hFile, XSTR("\nmethods:\n")) ;
  507. tOutFunc (hFile) ; // output each member function
  508. // alignment depends on the base-
  509. if ( inAlign ) // interface which is stdole.tlb
  510. if ( lpTypeAttr->cbAlignment != osGetAlignment(VT_PTR, MaxAlignment) )
  511. tOutAlignError (hFile) ; // on that particular system [5]
  512. WriteOut(hFile, XSTR("}\n\n")) ;
  513. // also dump the interface version of dual interfaces
  514. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FDUAL ) == TYPEFLAG_FDUAL ) // [7]
  515. {
  516. // if dual, also dump the interface portion
  517. tOutDual (hFile, iTypeId) ;
  518. }
  519. }
  520. VOID NEAR tOutCoclass (FILE *hFile, int iTypeId)
  521. {
  522. HREFTYPE phRefType ;
  523. WORD i ;
  524. int iFlags ;
  525. tOutAttr(hFile, (int)iTypeId) ; // output attribute first
  526. // output appobject attribute if
  527. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FCANCREATE ) == 0 )
  528. WriteAttr(hFile, XSTR("noncreatable"), NULL, noValue) ;
  529. tOutMoreAttr(hFile) ;
  530. WriteOut(hFile, XSTR("\ncoclass ")) ;// well
  531. tOutName(hFile, iTypeId) ;
  532. WriteOut(hFile, XSTR(" {\n")) ;
  533. for ( i = 0 ; i < lpTypeAttr->cImplTypes; i++ )
  534. {
  535. if ( FAILED(ptInfo->GetRefTypeOfImplType(i, &phRefType)) )
  536. {
  537. WriteOut(hFile, szReadFail) ;
  538. WriteOut(hFile, XSTR("GetRefTypeOfImpType\n")) ;
  539. }
  540. else
  541. {
  542. if ( FAILED(ptInfo->GetImplTypeFlags(i, &iFlags)) )
  543. {
  544. WriteOut(hFile, szReadFail) ;
  545. WriteOut(hFile, XSTR("GetImplTypeFlags\n")) ;
  546. }
  547. else
  548. { // output attribute(s)
  549. if ( (iFlags & IMPLTYPEFLAG_FDEFAULT) == IMPLTYPEFLAG_FDEFAULT )
  550. WriteAttr(hFile, attrDefault, NULL, noValue) ;
  551. if ( (iFlags & IMPLTYPEFLAG_FRESTRICTED) == IMPLTYPEFLAG_FRESTRICTED )
  552. WriteAttr(hFile, attrRestrict, NULL, noValue) ;
  553. if ( (iFlags & IMPLTYPEFLAG_FSOURCE) == IMPLTYPEFLAG_FSOURCE )
  554. WriteAttr(hFile, attrSource, NULL, noValue) ;
  555. if ( (iFlags & IMPLTYPEFLAG_FDEFAULTVTABLE) == IMPLTYPEFLAG_FDEFAULTVTABLE)
  556. WriteAttr(hFile, XSTR("defaultvtable"), NULL, noValue) ;
  557. if (ptinfo2) {
  558. // new-format typelib -- output more stuff
  559. CUSTDATA custdata;
  560. ptinfo2->GetAllImplTypeCustData(i, &custdata);
  561. tOutCustData(hFile, &custdata);
  562. }
  563. if ( endAttrFlag )
  564. {
  565. WriteOut(hFile, szEndAttr) ;
  566. endAttrFlag = FALSE ;
  567. }
  568. }
  569. tOutAliasName(hFile, phRefType) ;
  570. }
  571. }
  572. if ( inAlign ) // alignment depends on the base-
  573. if ( lpTypeAttr->cbAlignment != expAlign ) // interface [5]
  574. tOutAlignError (hFile) ;
  575. WriteOut(hFile, XSTR("}\n\n")) ;
  576. }
  577. VOID NEAR tOutAlias (FILE *hFile, int iTypeId)
  578. {
  579. XCHAR szTmp[16] ;
  580. WriteOut(hFile, XSTR("\ntypedef ")) ;
  581. tOutAttr(hFile, (int)iTypeId) ; // output attribute first
  582. WriteAttr(hFile, attrPublic, szTmp, noValue) ; // public attr
  583. tOutMoreAttr(hFile) ;
  584. tOutType(hFile, lpTypeAttr->tdescAlias) ; // output name of base-type
  585. tOutName(hFile, iTypeId) ; // output name of new type
  586. WriteOut(hFile, XSTR(";")) ;
  587. if ( inAlign ) // alignment of the alias with
  588. if ( lpTypeAttr->cbAlignment != expAlign )
  589. tOutAlignError (hFile) ; // that of the basetype [5]
  590. WriteOut(hFile, XSTR("\n\n")) ;
  591. }
  592. VOID NEAR tOutUnion (FILE *hFile, int iTypeId)
  593. {
  594. WriteOut(hFile, XSTR("\ntypedef\n")); // output typedef first
  595. tOutAttr(hFile, (int)iTypeId) ; // output attribute
  596. tOutMoreAttr(hFile) ;
  597. WriteOut(hFile, XSTR("\nunion {\n")) ;
  598. tOutVar (hFile) ; // output members
  599. WriteOut(hFile, XSTR("} ")) ;
  600. tOutName(hFile, iTypeId) ;
  601. WriteOut(hFile, XSTR(" ;")) ;
  602. if ( inAlign ) // [5]
  603. if ( lpTypeAttr->cbAlignment != expAlign )
  604. tOutAlignError (hFile) ;
  605. WriteOut(hFile, XSTR("\n\n")) ;
  606. }
  607. VOID NEAR tOutEncunion (FILE *hFile, int iTypeId)
  608. {
  609. WriteOut(hFile, XSTR("\ntypedef\n")); // output typedef first
  610. tOutAttr(hFile, (int)iTypeId) ; // output attribute
  611. tOutMoreAttr(hFile) ;
  612. WriteOut(hFile, XSTR("\nencunion {\n")) ;
  613. tOutVar (hFile) ; // output members
  614. WriteOut(hFile, XSTR("} ")) ;
  615. tOutName(hFile, iTypeId) ;
  616. WriteOut(hFile, XSTR(" ;\n\n")) ;
  617. }
  618. VOID NEAR tOutName (FILE *hFile, int iTypeId)
  619. {
  620. BSTRX bstrName ;
  621. if ( FAILED(ptLib->GetDocumentation(iTypeId, &bstrName, NULL, NULL, NULL)) )
  622. {
  623. WriteOut(hFile, szReadFail) ;
  624. WriteOut(hFile, XSTR("name of type definition")) ;
  625. }
  626. else
  627. {
  628. WriteOut(hFile, bstrName) ;
  629. WriteOut(hFile, XSTR(" ")) ;
  630. if ( iTypeId == -1 ) // record name of the library
  631. osStrCpy(szLibName, bstrName) ;
  632. SysFreeString((BSTR)bstrName) ;
  633. }
  634. }
  635. VOID NEAR tOutType (FILE *hFile, TYPEDESC tdesc)
  636. {
  637. XCHAR szTmp[20] ;
  638. if ( inAlign && tdesc.vt != VT_USERDEFINED && tdesc.vt != VT_CARRAY && !alignFound ) // [5]
  639. {
  640. if ( expAlign < osGetAlignment(tdesc.vt, inAlign) )
  641. expAlign = osGetAlignment(tdesc.vt, inAlign) ;
  642. alignFound = TRUE ;
  643. }
  644. switch (tdesc.vt)
  645. {
  646. case VT_EMPTY:
  647. osStrCpy ( szTmp, XSTR("notSpec ") ) ;
  648. break ;
  649. case VT_NULL:
  650. osStrCpy ( szTmp, XSTR("NULL ") ) ;
  651. break ;
  652. case VT_I2:
  653. osStrCpy ( szTmp, XSTR("short ") ) ;
  654. break ;
  655. case VT_I4:
  656. osStrCpy ( szTmp, XSTR("long ") ) ;
  657. break ;
  658. case VT_R4:
  659. osStrCpy ( szTmp, XSTR("float ") ) ;
  660. break ;
  661. case VT_R8:
  662. osStrCpy ( szTmp, XSTR("double ") ) ;
  663. break ;
  664. case VT_CY:
  665. osStrCpy ( szTmp, XSTR("CURRENCY ") ) ;
  666. break ;
  667. case VT_DATE:
  668. osStrCpy ( szTmp, XSTR("DATE ") ) ;
  669. break ;
  670. case VT_BSTR:
  671. osStrCpy ( szTmp, XSTR("BSTR ") ) ;
  672. break ;
  673. case VT_DISPATCH:
  674. osStrCpy ( szTmp, XSTR("IDispatch * ") ) ;
  675. break ;
  676. case VT_ERROR:
  677. osStrCpy ( szTmp, XSTR("scode ") ) ;
  678. break ;
  679. case VT_BOOL:
  680. osStrCpy ( szTmp, XSTR("boolean ") ) ;
  681. break ;
  682. case VT_VARIANT:
  683. osStrCpy ( szTmp, XSTR("VARIANT ") ) ;
  684. break ;
  685. case VT_UNKNOWN:
  686. osStrCpy ( szTmp, XSTR("IUnknown * ") ) ;
  687. break ;
  688. case VT_DECIMAL:
  689. osStrCpy ( szTmp, XSTR("DECIMAL ") ) ;
  690. break ;
  691. case VT_I1:
  692. osStrCpy ( szTmp, XSTR("char ") ) ;
  693. break ;
  694. case VT_UI1:
  695. osStrCpy ( szTmp, XSTR("unsigned char ") ) ;
  696. break ;
  697. case VT_UI2:
  698. osStrCpy ( szTmp, XSTR("unsigned short ") ) ;
  699. break ;
  700. case VT_UI4:
  701. osStrCpy ( szTmp, XSTR("unsigned long ") ) ;
  702. break ;
  703. case VT_I8:
  704. osStrCpy ( szTmp, XSTR("long long ") ) ;
  705. break ;
  706. case VT_UI8:
  707. osStrCpy ( szTmp, XSTR("unsigned long long ") ) ;
  708. break ;
  709. case VT_INT:
  710. osStrCpy ( szTmp, XSTR("int ") ) ;
  711. break ;
  712. case VT_UINT:
  713. osStrCpy ( szTmp, XSTR("unsigned int ") ) ;
  714. break ;
  715. case VT_VOID:
  716. osStrCpy ( szTmp, XSTR("void ") ) ;
  717. break ;
  718. case VT_HRESULT:
  719. osStrCpy ( szTmp, XSTR("HRESULT ") ) ;
  720. break ;
  721. case VT_PTR:
  722. tOutType (hFile, *(tdesc.lptdesc)) ;
  723. osStrCpy ( szTmp, XSTR("* ") ) ;
  724. break ;
  725. case VT_SAFEARRAY:
  726. if ( endAttrFlag )
  727. {
  728. WriteOut(hFile, szEndAttr) ;
  729. endAttrFlag = FALSE ;
  730. }
  731. WriteOut(hFile, XSTR("SAFEARRAY ( ")) ;
  732. tOutType (hFile, *(tdesc.lptdesc)) ;
  733. break ;
  734. case VT_CARRAY:
  735. cArrFlag = tdesc.lpadesc->cDims ; // get dimemsion of array
  736. tOutType (hFile, tdesc.lpadesc->tdescElem) ;
  737. break ;
  738. case VT_USERDEFINED:
  739. if ( endAttrFlag )
  740. {
  741. WriteOut(hFile, szEndAttr) ;
  742. endAttrFlag = FALSE ;
  743. }
  744. tOutAliasName (hFile, tdesc.hreftype) ;
  745. break ; // output name of the user-defined type
  746. case VT_LPSTR:
  747. osStrCpy ( szTmp, XSTR("LPSTR ") ) ;
  748. break ;
  749. case VT_LPWSTR: // [3]
  750. osStrCpy ( szTmp, XSTR("LPWSTR ") ) ;
  751. break ;
  752. default:
  753. osStrCpy ( szTmp, XSTR("unknown type ") ) ;
  754. }
  755. if ( endAttrFlag )
  756. {
  757. WriteOut(hFile, szEndAttr) ;
  758. endAttrFlag = FALSE ;
  759. }
  760. if ( tdesc.vt != VT_CARRAY && tdesc.vt != VT_USERDEFINED && tdesc.vt != VT_SAFEARRAY )
  761. WriteOut(hFile, szTmp) ;
  762. if ( tdesc.vt == VT_SAFEARRAY )
  763. WriteOut(hFile, XSTR(") ")) ;
  764. }
  765. VOID NEAR tOutCDim (FILE *hFile, TYPEDESC tdesc)
  766. {
  767. USHORT i ;
  768. ULONG l ;
  769. XCHAR szTmp[16] ;
  770. for ( i = 0 ; i < cArrFlag ; i++ )
  771. {
  772. l = tdesc.lpadesc->rgbounds[i].cElements ;
  773. osLtoA(l, szTmp) ;
  774. WriteOut(hFile, XSTR("[")) ;
  775. WriteOut(hFile, szTmp) ;
  776. WriteOut(hFile, XSTR("]")) ;
  777. }
  778. cArrFlag = 0 ;
  779. }
  780. VOID NEAR tOutAliasName (FILE *hFile, HREFTYPE phRefType)
  781. {
  782. ITypeInfoX FAR *lpInfo ; // pointer to the type definition
  783. ITypeLibX FAR *lpLib ; // pointer to a type library
  784. TYPEATTR FAR *lptAttr ;
  785. BSTRX bstrName ;
  786. UINT iTypeId ;
  787. HRESULT hRes;
  788. hRes = ptInfo->GetRefTypeInfo(phRefType, &lpInfo);
  789. if ( FAILED(hRes) )
  790. { // get TypeInfo of the alias
  791. WriteOut(hFile, szReadFail) ;
  792. WriteOut(hFile, XSTR("GetRefTypeInfo\n")) ;
  793. }
  794. else
  795. {
  796. if ( FAILED(lpInfo->GetTypeAttr(&lptAttr)) )
  797. {
  798. WriteOut(hFile, szReadFail) ;
  799. WriteOut(hFile, XSTR("attribute of reftype\n\n")) ;
  800. }
  801. else
  802. {
  803. if ( inAlign && !alignFound && (lpTypeAttr->typekind != TKIND_DISPATCH) )
  804. { // [5]
  805. if ( expAlign < lptAttr->cbAlignment )
  806. expAlign = lptAttr->cbAlignment ;
  807. alignFound = TRUE ;
  808. }
  809. switch ( lpTypeAttr->typekind )
  810. {
  811. case TKIND_INTERFACE:
  812. if ( isInherit ) // output name of base-interface
  813. WriteOut(hFile, XSTR(" : ")) ;
  814. break ;
  815. default:
  816. if (lpTypeAttr->typekind == TKIND_COCLASS ||
  817. lptAttr->wTypeFlags & TYPEFLAG_FDUAL) {
  818. // output type of the referenced interface if we
  819. // are a coclass or if we are referencing a dual
  820. // interface.
  821. if ( lptAttr->typekind == TKIND_INTERFACE )
  822. WriteOut(hFile, XSTR("interface ")) ;
  823. else if ( lptAttr->typekind == TKIND_DISPATCH )
  824. WriteOut(hFile, XSTR("dispinterface ")) ;
  825. }
  826. }
  827. lpInfo->ReleaseTypeAttr(lptAttr) ;
  828. }
  829. if ( FAILED(lpInfo->GetContainingTypeLib(&lpLib, &iTypeId)) )
  830. { // get id of the alias
  831. WriteOut(hFile, szReadFail) ;
  832. WriteOut(hFile, XSTR("GetAlias: containing typelib\n\n")) ;
  833. }
  834. else
  835. { // check origin of the alias
  836. if ( FAILED(lpLib->GetDocumentation(MEMBERID_NIL, &bstrName, NULL, NULL, NULL)) )
  837. {
  838. WriteOut(hFile, szReadFail) ;
  839. WriteOut(hFile, XSTR("name of import library")) ;
  840. }
  841. else
  842. { // if it is not defined locally
  843. if ( osStrCmp(szLibName, bstrName) != 0 )
  844. { // i.e. name of origin is diff
  845. WriteOut(hFile, bstrName) ;
  846. WriteOut(hFile, XSTR(".")) ;
  847. } // from the name of library;
  848. // output its origin
  849. SysFreeString((BSTR)bstrName) ;
  850. }
  851. if ( FAILED(lpLib->GetDocumentation((int)iTypeId, &bstrName, NULL, NULL, NULL)) )
  852. { // retrieve name of the alias
  853. WriteOut(hFile, szReadFail) ;
  854. WriteOut(hFile, XSTR("name of alias")) ;
  855. }
  856. else
  857. {
  858. WriteOut(hFile, bstrName) ;
  859. if ( lpTypeAttr->typekind == TKIND_COCLASS ||
  860. (lpTypeAttr->typekind == TKIND_DISPATCH && isInherit) )
  861. WriteOut(hFile, XSTR(" ;\n")) ;
  862. else
  863. WriteOut(hFile, XSTR(" ")) ;
  864. SysFreeString((BSTR)bstrName) ;
  865. }
  866. lpLib->Release () ;
  867. }
  868. lpInfo->Release () ;
  869. }
  870. }
  871. VOID NEAR tOutValue(FILE *hFile, BSTRX bstrName, VARDESCX FAR *lpVarDesc)
  872. {
  873. VARTYPE vvt ;
  874. VARIANTX varTmp ; // [12]
  875. XCHAR szTmp[25] ;
  876. if ( endAttrFlag )
  877. {
  878. WriteOut(hFile, szEndAttr) ;
  879. endAttrFlag = FALSE ;
  880. }
  881. if ( lpTypeAttr->typekind == TKIND_MODULE )
  882. {
  883. WriteOut(hFile, XSTR("const ")) ; // output the const keyword
  884. tOutType(hFile, lpVarDesc->elemdescVar.tdesc) ; // output its type
  885. }
  886. WriteOut(hFile, bstrName) ; // output name of member
  887. WriteOut(hFile, XSTR(" = ")) ;
  888. vvt = lpVarDesc->lpvarValue->vt ;
  889. if ( vvt == VT_VARIANT )
  890. {
  891. vvt = lpVarDesc->lpvarValue->pvarVal->vt ;
  892. switch ( vvt )
  893. {
  894. case VT_I1:
  895. osItoA((int)lpVarDesc->lpvarValue->pvarVal->cVal, szTmp) ;
  896. break ;
  897. case VT_UI1:
  898. osItoA((int)lpVarDesc->lpvarValue->pvarVal->bVal, szTmp) ;
  899. break ;
  900. case VT_UI2:
  901. osItoA((int)lpVarDesc->lpvarValue->pvarVal->uiVal, szTmp) ;
  902. break ;
  903. case VT_BOOL:
  904. osItoA((int)lpVarDesc->lpvarValue->pvarVal->boolVal, szTmp) ;
  905. break ;
  906. case VT_I2:
  907. if ( ( lpVarDesc->elemdescVar.tdesc.vt == VT_UI2 || lpVarDesc->elemdescVar.tdesc.vt == VT_UINT ) && lpVarDesc->lpvarValue->iVal < 0 )
  908. osLtoA((long)65536+(lpVarDesc->lpvarValue->pvarVal->iVal), szTmp) ;
  909. else
  910. osItoA((int)lpVarDesc->lpvarValue->pvarVal->iVal, szTmp) ;
  911. break ;
  912. case VT_R4: // [12]
  913. case VT_R8:
  914. case VT_CY:
  915. case VT_UI4:
  916. case VT_UINT:
  917. case VT_DECIMAL:
  918. varTmp.vt = VT_EMPTY ;
  919. if ( FAILED(VariantChangeType(&varTmp, lpVarDesc->lpvarValue->pvarVal, VARIANT_NOVALUEPROP, VT_BSTR)) )
  920. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  921. else
  922. {
  923. osStrCpy(szTmp, varTmp.bstrVal) ;
  924. SysFreeStringX(varTmp.bstrVal) ;
  925. }
  926. break ;
  927. case VT_DATE: // [12]
  928. varTmp.vt = VT_EMPTY ;
  929. if ( FAILED(VariantChangeType(&varTmp, lpVarDesc->lpvarValue, VARIANT_NOVALUEPROP, VT_BSTR)) )
  930. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  931. else
  932. {
  933. WriteOut(hFile, XSTR("\"")) ;
  934. WriteOut(hFile, (LPXSTR)varTmp.bstrVal) ;
  935. WriteOut(hFile, XSTR("\"")) ;
  936. SysFreeStringX(varTmp.bstrVal) ;
  937. }
  938. break ;
  939. case VT_BSTR:
  940. if ( lpVarDesc->lpvarValue->pvarVal->bstrVal != NULL ) // [9]
  941. {
  942. WriteOut(hFile, XSTR("\"")) ;
  943. WriteOut(hFile, (LPXSTR)lpVarDesc->lpvarValue->pvarVal->bstrVal) ;
  944. WriteOut(hFile, XSTR("\"")) ;
  945. }
  946. else // [9]
  947. WriteOut(hFile, XSTR("0")) ;
  948. break ;
  949. default:
  950. osLtoA((long)lpVarDesc->lpvarValue->pvarVal->lVal, szTmp) ;
  951. break ;
  952. }
  953. }
  954. else
  955. {
  956. switch ( vvt )
  957. {
  958. case VT_I1:
  959. osItoA((int)lpVarDesc->lpvarValue->cVal, szTmp) ;
  960. break ;
  961. case VT_UI1:
  962. osItoA((int)lpVarDesc->lpvarValue->bVal, szTmp) ;
  963. break ;
  964. case VT_BOOL:
  965. osItoA((int)lpVarDesc->lpvarValue->boolVal, szTmp) ;
  966. break ;
  967. case VT_UI2:
  968. osItoA((int)lpVarDesc->lpvarValue->uiVal, szTmp) ;
  969. break ;
  970. case VT_I2:
  971. if ( ( lpVarDesc->elemdescVar.tdesc.vt == VT_UI2 || lpVarDesc->elemdescVar.tdesc.vt == VT_UINT ) && lpVarDesc->lpvarValue->iVal < 0 )
  972. osLtoA((long)65536+(lpVarDesc->lpvarValue->iVal), szTmp) ;
  973. else
  974. osItoA((int)lpVarDesc->lpvarValue->iVal, szTmp) ;
  975. break ;
  976. case VT_R4: // [12]
  977. case VT_R8:
  978. case VT_CY:
  979. case VT_UI4:
  980. case VT_UINT:
  981. case VT_DECIMAL:
  982. varTmp.vt = VT_EMPTY ;
  983. if ( FAILED(VariantChangeType(&varTmp, lpVarDesc->lpvarValue, VARIANT_NOVALUEPROP, VT_BSTR)) )
  984. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  985. else
  986. {
  987. osStrCpy(szTmp, varTmp.bstrVal) ;
  988. SysFreeStringX(varTmp.bstrVal) ;
  989. }
  990. break ;
  991. case VT_DATE: // [12]
  992. varTmp.vt = VT_EMPTY ;
  993. if ( FAILED(VariantChangeType(&varTmp, lpVarDesc->lpvarValue, VARIANT_NOVALUEPROP, VT_BSTR)) )
  994. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  995. else
  996. {
  997. WriteOut(hFile, XSTR("\"")) ;
  998. WriteOut(hFile, (LPXSTR)varTmp.bstrVal) ;
  999. WriteOut(hFile, XSTR("\"")) ;
  1000. SysFreeStringX(varTmp.bstrVal) ;
  1001. }
  1002. break ;
  1003. case VT_BSTR:
  1004. if ( lpVarDesc->lpvarValue->bstrVal != NULL ) // [9]
  1005. {
  1006. WriteOut(hFile, XSTR("\"")) ;
  1007. WriteOut(hFile, (LPXSTR)lpVarDesc->lpvarValue->bstrVal) ;
  1008. WriteOut(hFile, XSTR("\"")) ;
  1009. }
  1010. else // [9]
  1011. WriteOut(hFile, XSTR("0")) ;
  1012. break ;
  1013. default:
  1014. osLtoA((long)lpVarDesc->lpvarValue->lVal, szTmp) ;
  1015. break ;
  1016. }
  1017. }
  1018. if ( vvt != VT_BSTR && vvt != VT_DATE )
  1019. WriteOut(hFile, szTmp) ; // output value of member
  1020. if ( lpTypeAttr->typekind == TKIND_MODULE )
  1021. WriteOut(hFile, XSTR(" ;\n")) ;
  1022. else
  1023. WriteOut(hFile, XSTR(" ,\n")) ;
  1024. }
  1025. VOID NEAR tOutMember(FILE *hFile, LONG idMember, BSTRX bstrName, TYPEDESC tdesc)
  1026. {
  1027. XCHAR szTmp[16] ;
  1028. if ( lpTypeAttr->typekind == TKIND_DISPATCH )
  1029. {
  1030. osLtoA(idMember, szTmp) ; // output id
  1031. WriteAttr(hFile, attrId, szTmp, numValue) ;
  1032. }
  1033. else // [5]
  1034. if ( inAlign )
  1035. alignFound = FALSE ;
  1036. // output name of base-type
  1037. tOutType(hFile, tdesc) ;
  1038. WriteOut(hFile, bstrName) ; // output name of member
  1039. if ( cArrFlag != 0 ) // it is a c-array; output
  1040. tOutCDim (hFile, tdesc) ;
  1041. // dimensions of the array
  1042. WriteOut(hFile, XSTR(" ;\n")) ;
  1043. }
  1044. VOID NEAR tOutVar(FILE *hFile)
  1045. {
  1046. VARDESCX FAR *ptVarDesc ; // [2]
  1047. BSTRX bstrName ; // name of member
  1048. BSTRX bstrDoc ; // file string
  1049. DWORD hContext ; // help context
  1050. XCHAR szTmp[16] ;
  1051. WORD i ;
  1052. LONG idMember ;
  1053. BSTRX rgNames[MAX_NAMES];
  1054. UINT cNames, j ;
  1055. for (i = 0 ; i < lpTypeAttr->cVars; i++) // for every member
  1056. {
  1057. if ( FAILED(ptInfo->GetVarDesc(i, &ptVarDesc)) )
  1058. {
  1059. WriteOut(hFile, szReadFail) ;
  1060. WriteOut(hFile, XSTR("variables\n")) ;
  1061. }
  1062. else
  1063. {
  1064. idMember = ptVarDesc->memid ;
  1065. // this is readonly var
  1066. if ( (ptVarDesc->wVarFlags & VARFLAG_FREADONLY) == VARFLAG_FREADONLY ) // CK [ 1]
  1067. WriteAttr(hFile, attrReadonly, NULL, noValue) ;
  1068. // output source attribute // CK [ 2]
  1069. if (( ptVarDesc->wVarFlags & VARFLAG_FSOURCE ) == VARFLAG_FSOURCE) // CK [ 1]
  1070. WriteAttr(hFile, attrSource, NULL, noValue) ; // CK [ 1]
  1071. // output bindable attribute // CK [ 2]
  1072. if (( ptVarDesc->wVarFlags & VARFLAG_FBINDABLE)== VARFLAG_FBINDABLE ) // CK [ 1]
  1073. WriteAttr(hFile, attrBindable, NULL, noValue) ; // CK [ 1]
  1074. // output requestedit attribute // CK [ 2]
  1075. if (( ptVarDesc->wVarFlags & VARFLAG_FREQUESTEDIT)== VARFLAG_FREQUESTEDIT )// CK [ 1]
  1076. WriteAttr(hFile, attrRequestedit, NULL, noValue) ; // CK [ 1]
  1077. // output displaybind attribute // CK [ 2]
  1078. if (( ptVarDesc->wVarFlags & VARFLAG_FDISPLAYBIND)== VARFLAG_FDISPLAYBIND )// CK [ 1]
  1079. WriteAttr(hFile, attrDisplaybind, NULL, noValue) ; // CK [ 1]
  1080. // output defaultbind attribute // CK [ 2]
  1081. if (( ptVarDesc->wVarFlags & VARFLAG_FDEFAULTBIND)== VARFLAG_FDEFAULTBIND )// CK [ 1]
  1082. WriteAttr(hFile, attrDefaultbind, NULL, noValue) ; // CK [ 1]
  1083. if (( ptVarDesc->wVarFlags & VARFLAG_FIMMEDIATEBIND)== VARFLAG_FIMMEDIATEBIND )// CK [ 1]
  1084. WriteAttr(hFile, XSTR("immediatebind"), NULL, noValue) ; // CK [ 1]
  1085. // output hidden attribute
  1086. if (( ptVarDesc->wVarFlags & VARFLAG_FHIDDEN)== VARFLAG_FHIDDEN ) // [7]
  1087. WriteAttr(hFile, attrHidden, NULL, noValue) ; // CK [ 1]
  1088. if (( ptVarDesc->wVarFlags & VARFLAG_FDEFAULTCOLLELEM)== VARFLAG_FDEFAULTCOLLELEM)
  1089. WriteAttr(hFile, XSTR("defaultcollelem"), NULL, noValue) ;
  1090. if (( ptVarDesc->wVarFlags & VARFLAG_FUIDEFAULT)== VARFLAG_FUIDEFAULT)
  1091. WriteAttr(hFile, XSTR("uidefault"), NULL, noValue) ;
  1092. if (( ptVarDesc->wVarFlags & VARFLAG_FNONBROWSABLE)== VARFLAG_FNONBROWSABLE)
  1093. WriteAttr(hFile, XSTR("nonbrowsable"), NULL, noValue) ;
  1094. if (( ptVarDesc->wVarFlags & VARFLAG_FREPLACEABLE)== VARFLAG_FREPLACEABLE)
  1095. WriteAttr(hFile, XSTR("replaceable"), NULL, noValue) ;
  1096. // also dump out the varkind
  1097. osItoA(ptVarDesc->varkind, szTmp) ;
  1098. WriteAttr(hFile, XSTR("varkind"), szTmp, numValue) ;
  1099. // also dump out the oInst
  1100. if (ptVarDesc->varkind != VAR_CONST) {
  1101. osItoA(ptVarDesc->oInst, szTmp) ;
  1102. WriteAttr(hFile, XSTR("oInst"), szTmp, numValue) ;
  1103. }
  1104. if (ptinfo2) {
  1105. // new-format typelib -- output more stuff
  1106. CUSTDATA custdata;
  1107. ptinfo2->GetAllVarCustData(i, &custdata);
  1108. tOutCustData(hFile, &custdata);
  1109. BSTRX bstrHelpDll;
  1110. if ( FAILED(ptinfo2->GetDocumentation2(idMember, 0x409, &bstrDoc, &hContext, &bstrHelpDll)) )
  1111. {
  1112. WriteOut(hFile, szReadFail);
  1113. WriteOut(hFile, XSTR("GetDocumentation2 failed\n\n")) ;
  1114. } else {
  1115. if (hContext != 0) {
  1116. osLtoA((long)hContext, szTmp) ;
  1117. WriteAttr(hFile, XSTR("helpstringcontext"), szTmp, numValue) ;
  1118. }
  1119. if ( bstrDoc != NULL ) // output helpstring if exists
  1120. WriteAttr(hFile, XSTR("localizedhelpstring"), bstrDoc, strValue) ;
  1121. // output help dll name if exists && different from main
  1122. if (bstrHelpDll && (g_bstrHelpDll == NULL || osStrCmp(bstrHelpDll, g_bstrHelpDll)))
  1123. WriteAttr(hFile, XSTR("helpstringdll"), bstrHelpDll, strValue) ;
  1124. SysFreeString((BSTR)bstrDoc) ; // release local bstr's
  1125. SysFreeString((BSTR)bstrHelpDll) ;
  1126. }
  1127. }
  1128. if ( FAILED(ptInfo->GetDocumentation(idMember, &bstrName, &bstrDoc, &hContext, NULL)) )
  1129. {
  1130. WriteOut(hFile, szReadFail) ;
  1131. WriteOut(hFile, XSTR("attributes of variable\n")) ;
  1132. }
  1133. else
  1134. { // output helpcontext; default is 0
  1135. osLtoA((long)hContext, szTmp) ;
  1136. WriteAttr(hFile, attrHelpCont, szTmp, numValue) ;
  1137. if ( bstrDoc != NULL ) // output helpstring if exists
  1138. WriteAttr(hFile, attrHelpStr, bstrDoc, strValue) ;
  1139. // typedef enum or const in module
  1140. if ( lpTypeAttr->typekind == TKIND_ENUM || lpTypeAttr->typekind == TKIND_MODULE )
  1141. tOutValue (hFile, bstrName, ptVarDesc) ;
  1142. else // typedef struct or dispinterface
  1143. tOutMember (hFile, idMember, bstrName, ptVarDesc->elemdescVar.tdesc) ;
  1144. SysFreeString((BSTR)bstrDoc) ; // release local bstr
  1145. // also checking the name
  1146. if ( FAILED(ptInfo->GetNames(idMember, rgNames, MAX_NAMES, &cNames)) )
  1147. { // with GetNames
  1148. WriteOut(hFile, szReadFail) ;
  1149. WriteOut(hFile, XSTR("name of variable\n")) ;
  1150. }
  1151. else
  1152. {
  1153. if ( cNames != 1 )
  1154. {
  1155. WriteOut(hFile, szReadFail) ;
  1156. WriteOut(hFile, XSTR("GetNames return more than one name\n")) ;
  1157. }
  1158. else
  1159. {
  1160. if ( osStrCmp(rgNames[0], bstrName) != 0 )
  1161. {
  1162. WriteOut(hFile, szReadFail) ;
  1163. WriteOut(hFile, XSTR("name of variable inconsistent\n")) ;
  1164. }
  1165. }
  1166. for ( j = 0 ; j < cNames ; j++ )
  1167. SysFreeString((BSTR)rgNames[j]) ;
  1168. }
  1169. SysFreeString((BSTR)bstrName) ;
  1170. }
  1171. }
  1172. ptInfo->ReleaseVarDesc(ptVarDesc) ;
  1173. ptVarDesc = NULL ;
  1174. } // for i
  1175. }
  1176. VOID NEAR tOutFuncAttr(FILE *hFile, FUNCDESC FAR *lpFuncDesc, DWORD hContext, BSTRX bstrDoc)
  1177. {
  1178. XCHAR szTmp[16] ;
  1179. osLtoA((long)hContext, szTmp) ;// output helpcontext; default is 0
  1180. WriteAttr(hFile, attrHelpCont, szTmp, numValue) ;
  1181. if ( bstrDoc != NULL ) // output helpstring if exists
  1182. WriteAttr(hFile, attrHelpStr, bstrDoc, strValue) ;
  1183. // output restricted attribute
  1184. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FRESTRICTED)== FUNCFLAG_FRESTRICTED )
  1185. WriteAttr(hFile, attrRestrict, NULL, noValue) ;
  1186. // output usesgetlasterror attribute [11]
  1187. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FUSESGETLASTERROR)== FUNCFLAG_FUSESGETLASTERROR )
  1188. WriteAttr(hFile, attrGetLastErr, NULL, noValue) ;
  1189. // output soruce attribute
  1190. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FSOURCE ) == FUNCFLAG_FSOURCE ) // [6]
  1191. WriteAttr(hFile, attrSource, NULL, noValue) ;
  1192. // output bindable attribute
  1193. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FBINDABLE)== FUNCFLAG_FBINDABLE )
  1194. WriteAttr(hFile, attrBindable, NULL, noValue) ;
  1195. // output requestedit attribute
  1196. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FREQUESTEDIT)== FUNCFLAG_FREQUESTEDIT )
  1197. WriteAttr(hFile, attrRequestedit, NULL, noValue) ;
  1198. // output displaybind attribute
  1199. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FDISPLAYBIND)== FUNCFLAG_FDISPLAYBIND )
  1200. WriteAttr(hFile, attrDisplaybind, NULL, noValue) ;
  1201. // output defaultbind attribute
  1202. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FDEFAULTBIND)== FUNCFLAG_FDEFAULTBIND )
  1203. WriteAttr(hFile, attrDefaultbind, NULL, noValue) ;
  1204. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FIMMEDIATEBIND)== FUNCFLAG_FIMMEDIATEBIND )
  1205. WriteAttr(hFile, XSTR("immediatebind"), NULL, noValue) ;
  1206. // output hidden attribute
  1207. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FHIDDEN)== FUNCFLAG_FHIDDEN ) // [7]
  1208. WriteAttr(hFile, attrHidden, NULL, noValue) ;
  1209. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FDEFAULTCOLLELEM)== FUNCFLAG_FDEFAULTCOLLELEM )
  1210. WriteAttr(hFile, XSTR("defaultcollelem"), NULL, noValue) ;
  1211. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FUIDEFAULT)== FUNCFLAG_FUIDEFAULT )
  1212. WriteAttr(hFile, XSTR("uidefault"), NULL, noValue) ;
  1213. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FNONBROWSABLE)== FUNCFLAG_FNONBROWSABLE )
  1214. WriteAttr(hFile, XSTR("nonbrowsable"), NULL, noValue) ;
  1215. if (( lpFuncDesc->wFuncFlags & FUNCFLAG_FREPLACEABLE)== FUNCFLAG_FREPLACEABLE )
  1216. WriteAttr(hFile, XSTR("replaceable"), NULL, noValue) ;
  1217. // also dump the funckind
  1218. osItoA(lpFuncDesc->funckind, szTmp) ;
  1219. WriteAttr(hFile, XSTR("funckind"), szTmp, numValue) ;
  1220. // also dump out the oVft. Only do this if not FUNC_DISPATCH
  1221. // if (lpFuncDesc->funckind != FUNC_DISPATCH)
  1222. {
  1223. osItoA((int)lpFuncDesc->oVft, szTmp) ;
  1224. WriteAttr(hFile, XSTR("oVft"), szTmp, numValue) ;
  1225. }
  1226. // last parm is optional array
  1227. if ( lpFuncDesc->cParamsOpt == -1 ) // of Variants
  1228. WriteAttr(hFile, attrVar, NULL, noValue) ;
  1229. if ( lpFuncDesc->memid == DISPID_VALUE ) // DISPID designates the
  1230. { // default function
  1231. osLtoA((long)DISPID_VALUE, szTmp) ;
  1232. WriteAttr(hFile, attrId, szTmp, numValue) ;
  1233. }
  1234. else
  1235. if ( lpTypeAttr->typekind == TKIND_DISPATCH )
  1236. {
  1237. osLtoA(lpFuncDesc->memid, szTmp) ; // output id
  1238. WriteAttr(hFile, attrId, szTmp, numValue) ;
  1239. }
  1240. switch ( lpFuncDesc->invkind ) // Note: if one of these
  1241. { // flag is set, name of
  1242. case INVOKE_FUNC: // parm can't be set: i.e.
  1243. // WriteAttr(hFile, XSTR("invoke_func", NULL, noValue)) ;
  1244. break ; // GetNames only returns name
  1245. case INVOKE_PROPERTYGET: // of the function
  1246. WriteAttr(hFile, attrPropget, NULL, noValue) ;
  1247. break ;
  1248. case INVOKE_PROPERTYPUT:
  1249. WriteAttr(hFile, attrPropput, NULL, noValue) ;
  1250. break ;
  1251. case INVOKE_PROPERTYPUTREF:
  1252. WriteAttr(hFile, attrProppr, NULL, noValue) ;
  1253. break ;
  1254. default:
  1255. WriteAttr(hFile, XSTR("unknown invkind"), NULL, noValue) ;
  1256. }
  1257. }
  1258. VOID NEAR tOutCallConv(FILE *hFile, FUNCDESC FAR *lpFuncDesc, TYPEKIND tkind)
  1259. {
  1260. switch ( lpFuncDesc->callconv )
  1261. {
  1262. case CC_MSCPASCAL:
  1263. #if WIN16
  1264. if (tkind == TKIND_MODULE)
  1265. WriteOut(hFile, XSTR("STDAPICALLTYPE ")) ;
  1266. else
  1267. #endif //WIN16
  1268. WriteOut(hFile, XSTR("__pascal ")) ;
  1269. break ;
  1270. case CC_MACPASCAL:
  1271. WriteOut(hFile, XSTR("__pascal ")) ;
  1272. break ;
  1273. case CC_STDCALL:
  1274. #if WIN32
  1275. if (tkind == TKIND_MODULE)
  1276. WriteOut(hFile, XSTR("STDAPICALLTYPE ")) ;
  1277. else
  1278. WriteOut(hFile, XSTR("STDMETHODCALLTYPE ")) ;
  1279. #else //WIN32
  1280. WriteOut(hFile, XSTR("__stdcall ")) ;
  1281. #endif //WIN32
  1282. break ;
  1283. case CC_SYSCALL:
  1284. WriteOut(hFile, XSTR("__syscall ")) ;
  1285. break ;
  1286. case CC_CDECL:
  1287. #if WIN16
  1288. if (tkind != TKIND_MODULE)
  1289. WriteOut(hFile, XSTR("STDMETHODCALLTYPE ")) ;
  1290. else
  1291. #endif //WIN16
  1292. WriteOut(hFile, XSTR("__cdecl ")) ;
  1293. break ;
  1294. case CC_FASTCALL:
  1295. WriteOut(hFile, XSTR("__fastcall ")) ;
  1296. break ;
  1297. case CC_FPFASTCALL:
  1298. WriteOut(hFile, XSTR("__fpfastcall ")) ;
  1299. break ;
  1300. default:
  1301. WriteOut(hFile, XSTR("unknown calling convention ")) ;
  1302. break ;
  1303. }
  1304. }
  1305. VOID NEAR tOutParams(FILE *hFile, FUNCDESC FAR *lpFuncDesc, UINT iFunc, BSTRX bstrName)
  1306. {
  1307. BSTRX rgNames[MAX_NAMES];
  1308. UINT cNames ;
  1309. SHORT i ;
  1310. SHORT iArgOptLast;
  1311. WriteOut(hFile, XSTR("(")) ;
  1312. if ( lpFuncDesc->cParams == 0 )
  1313. WriteOut(hFile, XSTR("void")) ;
  1314. else
  1315. {
  1316. if ( FAILED(ptInfo->GetNames(lpFuncDesc->memid, rgNames, MAX_NAMES, &cNames)) )
  1317. {
  1318. WriteOut(hFile, szReadFail) ;
  1319. WriteOut(hFile, XSTR("parm of func in definition\n")) ;
  1320. }
  1321. else
  1322. {
  1323. if (bstrName && osStrCmp(rgNames[0], bstrName) != 0 )
  1324. {
  1325. WriteOut(hFile, szReadFail) ;
  1326. WriteOut(hFile, XSTR("name of function inconsistent\n")) ;
  1327. }
  1328. SysFreeString((BSTR)rgNames[0]) ; // release name of function
  1329. // figure out the last parameter to be given the [optional]
  1330. // attribute
  1331. iArgOptLast = lpFuncDesc->cParams;
  1332. if ( ( lpFuncDesc->invkind == INVOKE_PROPERTYPUT
  1333. || lpFuncDesc->invkind == INVOKE_PROPERTYPUTREF)) {
  1334. iArgOptLast--;
  1335. }
  1336. for (i = 1; i <= lpFuncDesc->cParams; i++)
  1337. {
  1338. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FRETVAL ) == IDLFLAG_FRETVAL ) // [7]
  1339. iArgOptLast--;
  1340. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FLCID ) == IDLFLAG_FLCID ) // [7]
  1341. iArgOptLast--;
  1342. }
  1343. for (i = 1; i <= lpFuncDesc->cParams; i++)
  1344. {
  1345. if ( i != 1 )
  1346. WriteOut(hFile, XSTR(", ")) ;
  1347. // output in/out attribute
  1348. if ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags != 0 )
  1349. {
  1350. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FIN ) == IDLFLAG_FIN )
  1351. WriteAttr(hFile, attrIn, NULL, noValue) ;
  1352. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FOUT ) == IDLFLAG_FOUT )
  1353. WriteAttr(hFile, attrOut, NULL, noValue) ;
  1354. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FRETVAL ) == IDLFLAG_FRETVAL ) // [7]
  1355. WriteAttr(hFile, attrRetval, NULL, noValue) ;
  1356. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & IDLFLAG_FLCID ) == IDLFLAG_FLCID ) // [7]
  1357. WriteAttr(hFile, attrLcid, NULL, noValue) ;
  1358. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & PARAMFLAG_FHASDEFAULT ) == PARAMFLAG_FHASDEFAULT ) {
  1359. VARIANT varTmp;
  1360. VARIANT *pVarDefault;
  1361. pVarDefault = &(lpFuncDesc->lprgelemdescParam[i-1].paramdesc.pparamdescex->varDefaultValue);
  1362. varTmp.vt = VT_EMPTY ;
  1363. if ( FAILED(VariantChangeType(&varTmp, pVarDefault, VARIANT_NOVALUEPROP, VT_BSTR)) )
  1364. WriteOut(hFile, XSTR("VariantChangeType fails\n")) ;
  1365. else {
  1366. WriteAttr(hFile, XSTR("defaultvalue"), (BSTRX)varTmp.bstrVal, strValue) ;
  1367. SysFreeStringX(varTmp.bstrVal) ;
  1368. }
  1369. }
  1370. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & PARAMFLAG_FOPT ) == PARAMFLAG_FOPT ) // [7]
  1371. WriteAttr(hFile, XSTR("PARAMFLAG_FOPT"), NULL, noValue) ;
  1372. if ( ( lpFuncDesc->lprgelemdescParam[i-1].idldesc.wIDLFlags & PARAMFLAG_FHASCUSTDATA ) == PARAMFLAG_FHASCUSTDATA ) // [7]
  1373. WriteAttr(hFile, XSTR("PARAMFLAG_FHASCUSTDATA"), NULL, noValue) ;
  1374. if (ptinfo2) {
  1375. // new-format typelib -- output more stuff
  1376. CUSTDATA custdata;
  1377. ptinfo2->GetAllParamCustData(iFunc, i-1, &custdata);
  1378. tOutCustData(hFile, &custdata);
  1379. }
  1380. }
  1381. // check for optional parm
  1382. if ( lpFuncDesc->cParamsOpt > 0) {
  1383. if ( ( lpFuncDesc->cParamsOpt + i ) > iArgOptLast
  1384. && i <= iArgOptLast )
  1385. WriteAttr(hFile, attrOption, NULL, noValue) ;
  1386. // and output optional attr
  1387. }
  1388. // output name of base-type
  1389. tOutType(hFile, lpFuncDesc->lprgelemdescParam[i-1].tdesc) ;
  1390. if ( i < (SHORT) cNames )// output name of parm if its is
  1391. { // not property-accessor function
  1392. if (rgNames[i] == NULL)
  1393. WriteOut(hFile, XSTR("_NONAME_")) ;
  1394. else
  1395. WriteOut(hFile, rgNames[i]) ;
  1396. SysFreeString((BSTR)rgNames[i]) ; // release name of parm's
  1397. }
  1398. else
  1399. WriteOut(hFile, XSTR("PseudoName")) ;
  1400. if ( cArrFlag != 0 ) // it is a c-array; output
  1401. tOutCDim (hFile, lpFuncDesc->lprgelemdescParam[i-1].tdesc) ;
  1402. // dimension of the array
  1403. } // for i = 1
  1404. } // GetNames
  1405. } // if (ptFunDesc->cParams)
  1406. WriteOut(hFile, XSTR(") ;\n")) ;
  1407. }
  1408. VOID NEAR tOutFunc(FILE *hFile)
  1409. {
  1410. FUNCDESC FAR *ptFuncDesc ;
  1411. BSTRX bstrName ; // name of member
  1412. BSTRX bstrDoc ; // file string
  1413. DWORD hContext ; // help context
  1414. BSTRX bstrDllName;
  1415. BSTRX bstrEntryName;
  1416. WORD wOrdinal;
  1417. XCHAR szTmp[16] ;
  1418. WORD i ;
  1419. LONG idMember ;
  1420. alignFound = TRUE ; // turn off align checking [5]
  1421. for (i = 0 ; i < lpTypeAttr->cFuncs; i++) // for every member function
  1422. {
  1423. if ( FAILED(ptInfo->GetFuncDesc(i, &ptFuncDesc)) )
  1424. {
  1425. WriteOut(hFile, szReadFail) ;
  1426. WriteOut(hFile, XSTR("function of definition\n")) ;
  1427. }
  1428. else
  1429. {
  1430. idMember = ptFuncDesc->memid ;
  1431. if ( FAILED(ptInfo->GetDocumentation(ptFuncDesc->memid, &bstrName, &bstrDoc, &hContext, NULL)) )
  1432. {
  1433. WriteOut(hFile, szReadFail) ;
  1434. WriteOut(hFile, XSTR("attributes of function\n")) ;
  1435. }
  1436. else
  1437. {
  1438. if ( lpTypeAttr->typekind == TKIND_MODULE )
  1439. if( !FAILED(ptInfo->GetDllEntry(ptFuncDesc->memid, ptFuncDesc->invkind, &bstrDllName, &bstrEntryName, &wOrdinal)) )
  1440. { // check for Dll entry
  1441. WriteAttr(hFile, attrDllName, bstrDllName, strValue) ;
  1442. SysFreeString((BSTR)bstrDllName) ;
  1443. if ( bstrEntryName != NULL )
  1444. {
  1445. WriteAttr(hFile, attrEntry, bstrEntryName, strValue) ;
  1446. SysFreeString((BSTR)bstrEntryName) ;
  1447. }
  1448. else
  1449. {
  1450. osItoA((int)wOrdinal, szTmp) ;
  1451. WriteAttr(hFile, attrEntry, szTmp, numValue) ;
  1452. }
  1453. }
  1454. if (ptinfo2) {
  1455. // new-format typelib -- output more stuff
  1456. CUSTDATA custdata;
  1457. ptinfo2->GetAllFuncCustData(i, &custdata);
  1458. tOutCustData(hFile, &custdata);
  1459. // new-format typelib -- output more stuff
  1460. BSTRX bstrHelpDll;
  1461. BSTRX bstrLocalDoc;
  1462. DWORD hStringContext;
  1463. if ( FAILED(ptinfo2->GetDocumentation2(idMember, 0x409, &bstrLocalDoc, &hStringContext, &bstrHelpDll)) )
  1464. {
  1465. WriteOut(hFile, szReadFail);
  1466. WriteOut(hFile, XSTR("GetDocumentation2 failed\n\n")) ;
  1467. } else {
  1468. if (hStringContext != 0) {
  1469. osLtoA((long)hStringContext, szTmp) ;
  1470. WriteAttr(hFile, XSTR("helpstringcontext"), szTmp, numValue) ;
  1471. }
  1472. if ( bstrLocalDoc != NULL ) // output helpstring if exists
  1473. WriteAttr(hFile, XSTR("localizedhelpstring"), bstrLocalDoc, strValue) ;
  1474. // output help dll name if exists && different from main
  1475. if (bstrHelpDll && (g_bstrHelpDll == NULL || osStrCmp(bstrHelpDll, g_bstrHelpDll)))
  1476. WriteAttr(hFile, XSTR("helpstringdll"), bstrHelpDll, strValue) ;
  1477. SysFreeString((BSTR)bstrLocalDoc);
  1478. SysFreeString((BSTR)bstrHelpDll) ;
  1479. }
  1480. }
  1481. // output attr for function
  1482. tOutFuncAttr(hFile, ptFuncDesc, hContext, bstrDoc) ;
  1483. // output return type
  1484. tOutType(hFile, ptFuncDesc->elemdescFunc.tdesc) ;
  1485. // output calling convention
  1486. tOutCallConv(hFile, ptFuncDesc, lpTypeAttr->typekind) ;
  1487. if (bstrName == NULL)
  1488. WriteOut(hFile, XSTR("_NONAME_")) ;
  1489. else
  1490. WriteOut(hFile, bstrName) ; // output name of member function
  1491. tOutParams(hFile, ptFuncDesc, i, bstrName) ;
  1492. // output parameters
  1493. SysFreeString((BSTR)bstrDoc) ; // release local bstr's
  1494. SysFreeString((BSTR)bstrName) ;
  1495. }
  1496. ptInfo->ReleaseFuncDesc(ptFuncDesc) ;
  1497. }
  1498. ptFuncDesc = NULL ;
  1499. } // for i
  1500. alignFound = FALSE ; // turn align checking back on [5]
  1501. }
  1502. VOID NEAR tOutUUID (FILE *hFile, GUID inGuid)
  1503. {
  1504. XCHAR szTmp[50] ;
  1505. // get a string representation
  1506. // for the incoming Guid value
  1507. if ( !(osRetrieveGuid (szTmp, inGuid)) )
  1508. { WriteOut(hFile, szReadFail) ;
  1509. WriteOut(hFile, XSTR("insufficient memory")) ;
  1510. }
  1511. else
  1512. { // string is in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
  1513. szTmp[37] = '\0' ; // format, need to remove the {}
  1514. WriteAttr(hFile, attrUuid, &szTmp[1], numValue) ;
  1515. }
  1516. }
  1517. VOID NEAR tOutAttr (FILE *hFile, int iTypeId)
  1518. {
  1519. BSTRX bstrDoc ; // file string
  1520. BSTRX bstrHelp ; // name of help file
  1521. DWORD hContext ; // help context
  1522. XCHAR szTmp[16] ;
  1523. if ( FAILED(ptLib->GetDocumentation(iTypeId, NULL, &bstrDoc, &hContext, &bstrHelp)) )
  1524. {
  1525. WriteOut(hFile, szReadFail) ;
  1526. WriteOut(hFile, XSTR("documentational attribute\n\n")) ;
  1527. }
  1528. else
  1529. { // output helpcontext; default is 0
  1530. osLtoA((long)hContext, szTmp) ;
  1531. WriteAttr(hFile, attrHelpCont, szTmp, numValue) ;
  1532. if ( bstrDoc != NULL ) // output helpstring if exists
  1533. WriteAttr(hFile, attrHelpStr, bstrDoc, strValue) ;
  1534. if ( bstrHelp != NULL ) { // output helpfile if exists
  1535. OLECHAR FAR* pchDir;
  1536. // remove the path.
  1537. #if WIN32
  1538. pchDir = wcsrchr(bstrHelp, '\\');
  1539. if (pchDir) {
  1540. wcscpy(bstrHelp, pchDir);
  1541. }
  1542. #else // !WIN32
  1543. pchDir = _fstrrchr(bstrHelp, '\\');
  1544. if (pchDir) {
  1545. _fstrcpy(bstrHelp, pchDir);
  1546. }
  1547. #endif // !WIN32
  1548. // force path to lower case
  1549. #if WIN16
  1550. AnsiLower(bstrHelp);
  1551. #else //WIN16
  1552. WCHAR * pch;
  1553. for (pch = bstrHelp; *pch != 0; pch++) {
  1554. if (*pch >= OLECHAR('A') && *pch <= OLECHAR('Z'))
  1555. *pch = *pch + 'a' - 'A';
  1556. }
  1557. #endif //WIN16
  1558. WriteAttr(hFile, attrHelpFile, bstrHelp, strValue) ;
  1559. }
  1560. SysFreeString((BSTR)bstrDoc) ; // release local bstr's
  1561. SysFreeString((BSTR)bstrHelp) ;
  1562. }
  1563. if (ptlib2) {
  1564. // new-format typelib -- output more stuff
  1565. if ( FAILED(ptlib2->GetDocumentation2(iTypeId, 0x409, &bstrDoc, &hContext, &bstrHelp)) )
  1566. {
  1567. WriteOut(hFile, szReadFail);
  1568. WriteOut(hFile, XSTR("GetDocumentation2 failed\n\n")) ;
  1569. } else {
  1570. if (hContext != 0) {
  1571. osLtoA((long)hContext, szTmp) ;
  1572. WriteAttr(hFile, XSTR("helpstringcontext"), szTmp, numValue) ;
  1573. }
  1574. if ( bstrDoc != NULL ) // output helpstring if exists
  1575. WriteAttr(hFile, XSTR("localizedhelpstring"), bstrDoc, strValue) ;
  1576. // output help dll name if exists && different from main one
  1577. if (bstrHelp && (!g_bstrHelpDll || osStrCmp(bstrHelp, g_bstrHelpDll)))
  1578. WriteAttr(hFile, XSTR("helpstringdll"), bstrHelp, strValue) ;
  1579. SysFreeString((BSTR)bstrDoc) ; // release local bstr's
  1580. if (iTypeId == -1) {
  1581. g_bstrHelpDll = bstrHelp;
  1582. } else {
  1583. SysFreeString((BSTR)bstrHelp) ;
  1584. }
  1585. }
  1586. }
  1587. }
  1588. VOID NEAR tOutMoreAttr (FILE *hFile)
  1589. {
  1590. XCHAR szTmp[16] ;
  1591. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FDUAL ) == TYPEFLAG_FDUAL ) {
  1592. WriteAttr(hFile, attrDual, NULL, noValue) ;
  1593. }
  1594. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION ) == TYPEFLAG_FOLEAUTOMATION ) // [7]
  1595. WriteAttr(hFile, attrOleAuto, NULL, noValue) ; // check for oleautomation attr
  1596. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FNONEXTENSIBLE ) == TYPEFLAG_FNONEXTENSIBLE ) // [7]
  1597. WriteAttr(hFile, attrNonExt, NULL, noValue) ; // check for nonextensible attr
  1598. #if 0 // messes up old vs new typelib diffs
  1599. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FDISPATCHABLE ) == TYPEFLAG_FDISPATCHABLE )
  1600. WriteAttr(hFile, XSTR("dispatchable"), NULL, noValue) ;
  1601. #endif //0
  1602. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FREPLACEABLE ) == TYPEFLAG_FREPLACEABLE )
  1603. WriteAttr(hFile, XSTR("replaceable"), NULL, noValue) ;
  1604. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FAPPOBJECT ) == TYPEFLAG_FAPPOBJECT )
  1605. WriteAttr(hFile, attrAppObj, NULL, noValue) ;
  1606. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FLICENSED ) == TYPEFLAG_FLICENSED ) // [4]
  1607. WriteAttr(hFile, attrLic, NULL, noValue) ; // check for license
  1608. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FCONTROL ) == TYPEFLAG_FCONTROL ) // [7]
  1609. WriteAttr(hFile, attrControl, NULL, noValue) ; // check for control attr
  1610. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FAGGREGATABLE ) == TYPEFLAG_FAGGREGATABLE )
  1611. WriteAttr(hFile, XSTR("aggregatable"), NULL, noValue) ;
  1612. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FPROXY ) == TYPEFLAG_FPROXY )
  1613. WriteAttr(hFile, XSTR("proxy"), NULL, noValue) ;
  1614. GetVerNumber (lpTypeAttr->wMajorVerNum, lpTypeAttr->wMinorVerNum, szTmp) ;
  1615. WriteAttr(hFile, attrVer, szTmp, numValue) ; // output version
  1616. tOutUUID(hFile, lpTypeAttr->guid) ;
  1617. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FHIDDEN ) == TYPEFLAG_FHIDDEN ) // [7]
  1618. WriteAttr(hFile, attrHidden, NULL, noValue) ; // check for hidden attr
  1619. if ( ( lpTypeAttr->wTypeFlags & TYPEFLAG_FRESTRICTED ) == TYPEFLAG_FRESTRICTED ) // [10]
  1620. WriteAttr(hFile, attrRestrict, NULL, noValue) ; // check for restricted attr
  1621. osItoA((int)lpTypeAttr->cbSizeVft, szTmp) ;
  1622. WriteAttr(hFile, XSTR("cbSizeVft"), szTmp, numValue) ;
  1623. osItoA(lpTypeAttr->cbSizeInstance, szTmp) ;
  1624. WriteAttr(hFile, XSTR("cbSizeInstance"), szTmp, numValue) ;
  1625. osItoA((int)lpTypeAttr->cbAlignment, szTmp) ;
  1626. WriteAttr(hFile, XSTR("cbAlignment"), szTmp, numValue) ;
  1627. if (ptinfo2) {
  1628. // new-format typelib -- output more stuff
  1629. CUSTDATA custdata;
  1630. ptinfo2->GetAllCustData(&custdata);
  1631. tOutCustData(hFile, &custdata);
  1632. }
  1633. if ( endAttrFlag )
  1634. {
  1635. WriteOut(hFile, szEndAttr) ;
  1636. endAttrFlag = FALSE ;
  1637. }
  1638. }
  1639. VOID NEAR WriteAttr(FILE *hFile, LPXSTR lpszAttr, LPXSTR lpszStr, int ivalType)
  1640. {
  1641. BOOL firstAttr = FALSE ;
  1642. if ( !endAttrFlag )
  1643. {
  1644. WriteOut(hFile, szBeginAttr) ; // output "[" first
  1645. endAttrFlag = TRUE ;
  1646. firstAttr = TRUE ;
  1647. }
  1648. // this is not the first
  1649. if ( !firstAttr ) // attribute to be written;
  1650. WriteOut(hFile, XSTR(", ")) ; // need to put a , before
  1651. // output name of attribute
  1652. WriteOut(hFile, lpszAttr) ;
  1653. if ( ivalType != noValue ) // attribute has a value
  1654. {
  1655. WriteOut(hFile, XSTR("(")) ;
  1656. if ( ivalType != numValue ) // value is a string
  1657. WriteOut(hFile, XSTR("\"")) ;
  1658. WriteOut(hFile, lpszStr) ; // output value of attribute
  1659. if ( ivalType != numValue ) // close the string value
  1660. WriteOut(hFile, XSTR("\"")) ;
  1661. WriteOut(hFile, XSTR(")")) ;
  1662. }
  1663. }
  1664. VOID NEAR GetVerNumber (WORD wMajorNum, WORD wMinorNum, LPXSTR szVersion)
  1665. {
  1666. XCHAR szTmp[6] ;
  1667. osLtoA((long)wMajorNum, szVersion) ;
  1668. osLtoA((long)wMinorNum, szTmp) ;
  1669. osStrCat(szVersion, XSTR(".")) ; // major.
  1670. osStrCat(szVersion, szTmp) ; // major.minor
  1671. }
  1672. VOID NEAR tOutAlignError (FILE * hFile) // [5]
  1673. {
  1674. XCHAR szTmp1[30] ;
  1675. XCHAR szTmp2[15] ;
  1676. WriteOut(hFile, szAlignErr) ;
  1677. osLtoA((long)inAlign, szTmp2) ;
  1678. osStrCpy(szTmp1, XSTR("inAlign = ")) ;
  1679. osStrCat(szTmp1, szTmp2) ;
  1680. WriteOut(hFile, szTmp1) ;
  1681. }
  1682. VOID NEAR WriteOut(FILE *hFile, LPXSTR lpszData)
  1683. { // Note: szBuffer is either UNICODE
  1684. // or ANSI depending of the UNICODE
  1685. XCHAR szBuffer[fMaxBuffer]; // compiler switch
  1686. if ( fputsX(lpszData, hFile) < 0 ) // [2]
  1687. { // regardless the OS enviornment
  1688. osStrCpy(szBuffer, XSTR("Fail to write to file ")) ;
  1689. osStrCat(szBuffer, lpszData) ;
  1690. if ( isOut )
  1691. {
  1692. mFile = fopenX(szOutMsgFile, fnWrite);// open message file [2]
  1693. if (mFile == NULL)
  1694. {
  1695. osMessage (XSTR("Fail to open the message file"), XSTR("Tlviewer")) ;
  1696. osMessage (szBuffer, XSTR("Tlviewer")) ;
  1697. }
  1698. else
  1699. {
  1700. WriteOut(mFile, szBuffer) ;
  1701. fclose(mFile) ;
  1702. mFile = NULL ;
  1703. }
  1704. }
  1705. else
  1706. osMessage (szBuffer, XSTR("Tlviewer")) ;
  1707. }
  1708. }
  1709. // test routine for use in the typelib dumping routines. Supposed to
  1710. // return a help string from a resource. (Called as a result of doing
  1711. // a GetDocumentation2). We just fake something out here.
  1712. extern "C" HRESULT __declspec(dllexport) DLLGetDocumentation
  1713. (
  1714. ITypeLib * /*ptlib*/,
  1715. ITypeInfo * /*ptinfo*/,
  1716. LCID lcid,
  1717. DWORD dwHelpStringContext,
  1718. BSTR * pbstrHelpString
  1719. )
  1720. {
  1721. switch (dwHelpStringContext) {
  1722. case 99:
  1723. if (lcid == 0x409) {
  1724. *pbstrHelpString = SysAllocString(OLESTR("English help for context 99"));
  1725. } else
  1726. if (lcid == 0) {
  1727. *pbstrHelpString = SysAllocString(OLESTR("Default help for context 99"));
  1728. } else {
  1729. *pbstrHelpString = SysAllocString(OLESTR("Foreign help for context 99"));
  1730. }
  1731. break;
  1732. default:
  1733. *pbstrHelpString = NULL; // no help for this item
  1734. }
  1735. return NOERROR;
  1736. }