- Timestamp:
- Dec 8, 1999, 8:59:58 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/oleaut32/typelib.cpp
r1656 r2022 1 /* $Id: typelib.cpp,v 1.5 1999-11-09 11:04:33 bird Exp $ */ 2 /* 3 * TYPELIB 4 * 5 * Copyright 1997 Marcus Meissner 6 * 1999 Rein Klazes 7 * 8 * Copyright 1999 Sander van Leeuwen (WINE OS/2 Port 990815) 9 * 10 * Project Odin Software License can be found in LICENSE.TXT 11 * 12 * there is much left to do here before it can be usefull for real world 13 * programs 14 * know problems: 15 * -. Only one format of typelibs is supported 16 * -. All testing until sofar is done using special written windows programs 17 * -. Data structures are straightforward, but slow for look-ups. 18 * -. (related) nothing is hashed 19 * -. a typelib is always read in its entirely into memory and never released. 20 * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most 21 * of them I don't know yet how to implement them. 22 * -. Most error return values are just guessed not checked with windows 23 * behaviour. 24 * -. all locale stuf ignored 25 * -. move stuf to wine/dlls 26 * -. didn't bother with a c++ interface 27 * -. lousy fatal error handling 28 * -. some methods just return pointers to internal data structures, this is 29 * partly laziness, partly I want to check how windows does it. 30 * 31 */ 1 /* $Id: typelib.cpp,v 1.6 1999-12-08 19:59:58 davidr Exp $ */ 2 3 typedef enum tagREGKIND 4 { 5 REGKIND_DEFAULT, 6 REGKIND_REGISTER, 7 REGKIND_NONE 8 } REGKIND; 32 9 33 10 #include "oleaut32.h" 34 #include <stdlib.h> 35 #include <string.h> 36 #include <assert.h> 37 #include "windef.h" 38 #include "winerror.h" 39 #include "winreg.h" 40 #include "oleauto.h" 41 #include "winnls.h" 42 #include "wine/winbase16.h" 43 #include "heap.h" 44 #include "wine/obj_base.h" 45 #include "debugtools.h" 46 #include "winversion.h" 47 /* FIXME: get rid of these */ 48 typedef struct ITypeInfoVtbl ITypeLib_VTable, *LPTYPEINFO_VTABLE ; 49 typedef struct ITypeLibVtbl *LPTYPELIB_VTABLE ; 50 #include "typelib.h" 51 52 DEFAULT_DEBUG_CHANNEL(ole) 53 DECLARE_DEBUG_CHANNEL(typelib) 54 55 56 /**************************************************************************** 57 * QueryPathOfRegTypeLib [OLEAUT32.164] 58 * RETURNS 59 * path of typelib 60 */ 61 HRESULT WINAPI 62 QueryPathOfRegTypeLib( 63 REFGUID guid, /* [in] referenced guid */ 64 WORD wMaj, /* [in] major version */ 65 WORD wMin, /* [in] minor version */ 66 LCID lcid, /* [in] locale id */ 67 LPBSTR path /* [out] path of typelib */ 68 ) { 69 char xguid[80]; 70 char typelibkey[100],pathname[260]; 71 DWORD plen; 72 73 74 if (HIWORD(guid)) { 75 WINE_StringFromCLSID(guid,xguid); 76 sprintf(typelibkey,"SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32", 77 xguid,wMaj,wMin,lcid 78 ); 79 } else { 80 sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid); 81 FIXME_(ole)("(%s,%d,%d,0x%04lx,%p),stub!\n",xguid,wMaj,wMin,(DWORD)lcid,path); 82 return E_FAIL; 83 } 84 plen = sizeof(pathname); 85 if (RegQueryValueA(HKEY_LOCAL_MACHINE,typelibkey,pathname,(LPLONG)&plen)) { 86 /* try again without lang specific id */ 87 if (SUBLANGID(lcid)) 88 return QueryPathOfRegTypeLib(guid,wMaj,wMin,PRIMARYLANGID(lcid),path); 89 FIXME_(ole)("key %s not found\n",typelibkey); 90 return E_FAIL; 91 } 92 *path = HEAP_strdupAtoW(GetProcessHeap(),0,pathname); 93 return S_OK; 94 } 95 96 /****************************************************************************** 97 * LoadTypeLib [TYPELIB.3] Loads and registers a type library 98 * NOTES 99 * Docs: OLECHAR FAR* szFile 100 * Docs: iTypeLib FAR* FAR* pptLib 101 * 102 * RETURNS 103 * Success: S_OK 104 * Failure: Status 105 */ 106 HRESULT WINAPI LoadTypeLib16( 107 OLECHAR *szFile, /* [in] Name of file to load from */ 108 void * *pptLib) /* [out] Pointer to pointer to loaded type library */ 109 { 110 FIXME_(ole)("('%s',%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib); 111 112 if (pptLib!=0) 113 *pptLib=0; 114 115 return E_FAIL; 116 } 117 118 /****************************************************************************** 119 * LoadTypeLib [OLEAUT32.161] 120 * Loads and registers a type library 121 * NOTES 122 * Docs: OLECHAR FAR* szFile 123 * Docs: iTypeLib FAR* FAR* pptLib 124 * 125 * RETURNS 126 * Success: S_OK 127 * Failure: Status 128 */ 129 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypelib); 11 #include "olectl.h" 12 #include "oList.h" // linked list template 13 #include "itypelib.h" 14 15 // ====================================================================== 16 // Local Data 17 // ====================================================================== 18 static TYPEDESC stndTypeDesc[VT_LPWSTR+1] = 19 { /* VT_LPWSTR is largest type that */ 20 /* may appear in type description*/ 21 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4}, 22 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9}, 23 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14}, 24 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19}, 25 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24}, 26 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29}, 27 {{0},30},{{0},31} 28 }; 29 30 // ====================================================================== 31 // Public API's 32 // ====================================================================== 33 34 // ---------------------------------------------------------------------- 35 // QueryPathOfRegTypeLib() [OLEAUT32.164] 36 // 37 // Retrieves the path of a registered type library. 38 // ---------------------------------------------------------------------- 39 HRESULT WINAPI QueryPathOfRegTypeLib( 40 REFGUID guid, /* [in] referenced guid */ 41 WORD wMaj, /* [in] major version */ 42 WORD wMin, /* [in] minor version */ 43 LCID lcid, /* [in] locale id */ 44 LPBSTR path) /* [out] path of typelib */ 45 { 46 char xguid[80]; 47 char typelibkey[100]; 48 char pathname[260]; 49 DWORD plen; 50 51 dprintf(("OLEAUT32: QueryPathOfRegTypeLib()")); 52 53 if (HIWORD(guid)) 54 { 55 WINE_StringFromCLSID(guid, xguid); 56 sprintf(typelibkey, 57 "SOFTWARE\\Classes\\Typelib\\%s\\%d.%d\\%lx\\win32", 58 xguid, wMaj, wMin, lcid); 59 } 60 else 61 { 62 sprintf(xguid, "<guid 0x%08lx>", (DWORD)guid); 63 dprintf(("OLEAUT32: QueryPathOfRegTypeLib(%s,%d,%d,0x%04lx,%p) - stub!", 64 xguid, wMaj, wMin, (DWORD)lcid, path)); 65 return E_FAIL; 66 } 67 plen = sizeof(pathname); 68 if (RegQueryValueA(HKEY_LOCAL_MACHINE, typelibkey, pathname, (LPLONG)&plen)) 69 { 70 /* try again without lang specific id */ 71 if (SUBLANGID(lcid)) 72 return QueryPathOfRegTypeLib(guid, wMaj, wMin, PRIMARYLANGID(lcid), path); 73 74 dprintf(("OLEAUT32: QueryPathOfRegTypeLib() - key \"%s\" not found", typelibkey)); 75 return E_FAIL; 76 } 77 *path = HEAP_strdupAtoW(GetProcessHeap(), 0, pathname); 78 return S_OK; 79 } 80 81 // ---------------------------------------------------------------------- 82 // LoadTypeLibEx() [OLEAUT32.183] 83 // 84 // Loads a type library & optionally registers it in the system registry. 85 // * If file is a standalone type library - load it directly. 86 // * If the file is a DLL or EXE then load the module, and extract the TYPELIB 87 // resource from it. The default is the first TYPELIB resource - subsequent 88 // TYPELIBs may be accessed by appending an integer index to szFile 89 // * If neither of the above, the library is parsed into a filebased Moniker. 90 // No idea of what/when/where/how to do this yet ;-) 91 // 92 // If the library (guid, etc) is already loaded return the loaded ITypeLib 93 // and incr. its ref count. 94 // ---------------------------------------------------------------------- 95 HRESULT WINAPI LoadTypeLibEx( 96 LPCOLESTR szFile, 97 REGKIND regkind, 98 ITypeLib * * ppTlib) 99 { 100 HANDLE hHeap = GetProcessHeap(); 101 char * szFileA; 102 HRESULT rc; 103 104 szFileA = HEAP_strdupWtoA(hHeap, 0, szFile); 105 dprintf(("OLEAUT32: LoadTypeLibEx(%s)", szFileA)); 106 107 // Sanity check... 108 if (ppTlib == 0) 109 { 110 HeapFree(hHeap, 0, szFileA); 111 return E_POINTER; 112 } 113 114 *ppTlib = 0; 115 116 TypeLibExtract extractor(szFileA); 117 118 if (!extractor.Valid()) 119 { 120 HeapFree(hHeap, 0, szFileA); 121 dprintf((" Invalid typelib file")); 122 return E_FAIL; 123 } 124 125 rc = extractor.MakeITypeLib((ITypeLibImpl * *)ppTlib); 126 127 HeapFree(hHeap, 0, szFileA); 128 129 return rc; 130 } 131 132 // ---------------------------------------------------------------------- 133 // LoadTypeLib() [OLEAUT32.161] 134 // 135 // Loads a type library & registers it in the system registry. 136 // ---------------------------------------------------------------------- 130 137 HRESULT WINAPI LoadTypeLib( 131 OLECHAR *szFile, /* [in] Name of file to load from */ 132 ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */ 133 { 134 LPSTR p; 135 HRESULT res; 136 TRACE_(typelib)("('%s',%p)\n",debugstr_w(szFile),pptLib); 137 138 p=HEAP_strdupWtoA(GetProcessHeap(),0,szFile); 139 res= TLB_ReadTypeLib(p, pptLib); 140 /* XXX need to free p ?? */ 141 142 TRACE_(typelib)(" returns %ld\n",res); 138 LPCOLESTR szFile, /* [in] Name of file to load from */ 139 ITypeLib * * ppTLib) /* [out] Pointer to pointer to loaded type library */ 140 { 141 HRESULT res; 142 143 dprintf(("OLEAUT32: LoadTypeLib()")); 144 145 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, ppTLib); 146 } 147 148 // ---------------------------------------------------------------------- 149 // LoadRegTypeLib() [OLEAUT32.162] 150 // 151 // Use system registry information to locate and load a type library. 152 // ---------------------------------------------------------------------- 153 HRESULT WINAPI LoadRegTypeLib( 154 REFGUID rguid, /* [in] referenced guid */ 155 WORD wVerMajor, /* [in] major version */ 156 WORD wVerMinor, /* [in] minor version */ 157 LCID lcid, /* [in] locale id */ 158 ITypeLib * * ppTLib /* [out] path of typelib */ 159 ) 160 { 161 BSTR bstr = NULL; 162 HRESULT res; 163 164 dprintf(("OLEAUT32: LoadRegTypeLib()")); 165 166 res = QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr); 167 168 if (SUCCEEDED(res)) 169 { 170 res = LoadTypeLibEx(bstr, REGKIND_NONE, ppTLib); 171 SysFreeString(bstr); 172 } 143 173 144 174 return res; 145 175 } 146 176 147 /****************************************************************************** 148 * LoadRegTypeLib [OLEAUT32.162] 149 */ 150 HRESULT WINAPI LoadRegTypeLib( 151 REFGUID rguid, /* [in] referenced guid */ 152 WORD wVerMajor, /* [in] major version */ 153 WORD wVerMinor, /* [in] minor version */ 154 LCID lcid, /* [in] locale id */ 155 ITypeLib **ppTLib /* [out] path of typelib */ 156 ) { 157 BSTR bstr=NULL; 158 HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, 159 lcid, &bstr); 160 if(SUCCEEDED(res)){ 161 res= LoadTypeLib(bstr, ppTLib); 162 SysFreeString(bstr); 163 } 164 if(TRACE_ON(typelib)){ 165 char xriid[50]; 166 WINE_StringFromCLSID((LPCLSID)rguid,xriid); 167 TRACE_(typelib)("(IID: %s) load %s (%p)\n",xriid, 168 SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib); 169 } 170 return res; 171 } 172 173 174 /****************************************************************************** 175 * RegisterTypeLib [OLEAUT32.163] 176 * Adds information about a type library to the System Registry 177 * NOTES 178 * Docs: ITypeLib FAR * ptlib 179 * Docs: OLECHAR FAR* szFullPath 180 * Docs: OLECHAR FAR* szHelpDir 181 * 182 * RETURNS 183 * Success: S_OK 184 * Failure: Status 185 */ 177 // ---------------------------------------------------------------------- 178 // RegisterTypeLib() [OLEAUT32.163] 179 // 180 // Adds information about a type library to the System Registry 181 // ---------------------------------------------------------------------- 186 182 HRESULT WINAPI RegisterTypeLib( 187 ITypeLib * ptlib, /*[in] Pointer to the library*/188 OLECHAR * szFullPath, /*[in] full Path of the library*/189 OLECHAR * szHelpDir) /*[in] dir to the helpfile for the library,183 ITypeLib * ptlib, /* [in] Pointer to the library*/ 184 OLECHAR * szFullPath, /* [in] full Path of the library*/ 185 OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library, 190 186 may be NULL*/ 191 { FIXME_(ole)("(%p,%s,%s): stub\n",ptlib, debugstr_w(szFullPath),debugstr_w(szHelpDir)); 187 { 188 dprintf(("OLEAUT32: RegisterTypeLib() - stub\n")); 189 192 190 return S_OK; /* FIXME: pretend everything is OK */ 193 191 } 194 192 195 196 /****************************************************************************** 197 * UnRegisterTypeLib [OLEAUT32.186] 198 * Removes information about a type library from the System Registry 199 * NOTES 200 * 201 * RETURNS 202 * Success: S_OK 203 * Failure: Status 204 */ 193 // ---------------------------------------------------------------------- 194 // UnRegisterTypeLib() [OLEAUT32.186] 195 // 196 // Removes information about a type library from the System Registry 197 // ---------------------------------------------------------------------- 205 198 HRESULT WINAPI UnRegisterTypeLib( 206 REFGUID libid, /* [in] Guid of the library */ 207 WORD wVerMajor, /* [in] major version */ 208 WORD wVerMinor, /* [in] minor version */ 209 LCID lcid, /* [in] locale id */ 210 SYSKIND syskind) 211 { 212 char xriid[50]; 213 WINE_StringFromCLSID((LPCLSID)libid,xriid); 214 TRACE_(typelib)("(IID: %s): stub\n",xriid); 199 REFGUID libid, /* [in] Guid of the library */ 200 WORD wVerMajor, /* [in] major version */ 201 WORD wVerMinor, /* [in] minor version */ 202 LCID lcid, /* [in] locale id */ 203 SYSKIND syskind) 204 { 205 dprintf(("OLEAUT32: UnRegisterTypeLib() - stub")); 206 215 207 return S_OK; /* FIXME: pretend everything is OK */ 216 208 } 217 209 218 219 /* for better debugging info leave the static out for the time being */ 220 #define static 221 222 /*=======================Itypelib methods ===============================*/ 223 /* ITypeLib methods */ 224 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid, 225 VOID **ppvObject); 226 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB This); 227 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB This); 228 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB This); 229 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB This, UINT index, 230 ITypeInfo **ppTInfo); 231 232 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB This, UINT index, 233 TYPEKIND *pTKind); 234 235 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB This, REFGUID guid, 236 ITypeInfo **ppTinfo); 237 238 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB This, 239 LPTLIBATTR *ppTLibAttr); 240 241 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB This, 242 ITypeComp **ppTComp); 243 244 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB This, INT index, 245 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, 246 BSTR *pBstrHelpFile); 247 248 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB This, LPOLESTR szNameBuf, 249 ULONG lHashVal, BOOL *pfName); 250 251 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB This, LPOLESTR szNameBuf, 252 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound); 253 254 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB This, 255 TLIBATTR *pTLibAttr); 256 257 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * This, REFGUID guid, 258 VARIANT *pVarVal); 259 260 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * This, 261 UINT *pcUniqueNames, UINT *pcchUniqueNames); 262 263 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * This, 264 INT index, LCID lcid, BSTR *pbstrHelpString, 265 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll); 266 267 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * This, 268 CUSTDATA *pCustData); 269 static ICOM_VTABLE(ITypeLib) tlbvt = { 270 ITypeLib_fnQueryInterface, 271 ITypeLib_fnAddRef, 272 ITypeLib_fnRelease, 273 ITypeLib_fnGetTypeInfoCount, 274 ITypeLib_fnGetTypeInfo, 275 ITypeLib_fnGetTypeInfoType, 276 ITypeLib_fnGetTypeInfoOfGuid, 277 ITypeLib_fnGetLibAttr, 278 ITypeLib_fnGetTypeComp, 279 ITypeLib_fnGetDocumentation, 280 ITypeLib_fnIsName, 281 ITypeLib_fnFindName, 282 ITypeLib_fnReleaseTLibAttr, 283 ITypeLib2_fnGetCustData, 284 ITypeLib2_fnGetLibStatistics, 285 ITypeLib2_fnGetDocumentation2, 286 ITypeLib2_fnGetAllCustData 287 }; 288 /* TypeInfo Methods */ 289 290 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO This, REFIID riid, 291 VOID **ppvObject); 292 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO This); 293 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO This); 294 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO This, 295 LPTYPEATTR *ppTypeAttr); 296 297 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO This, 298 ITypeComp * *ppTComp); 299 300 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO This, UINT index, 301 LPFUNCDESC *ppFuncDesc); 302 303 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO This, UINT index, 304 LPVARDESC *ppVarDesc); 305 306 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO This, MEMBERID memid, 307 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames); 308 309 310 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO This, 311 UINT index, HREFTYPE *pRefType); 312 313 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO This, 314 UINT index, INT *pImplTypeFlags); 315 316 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO This, 317 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId); 318 319 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO This, VOID *pIUnk, 320 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams, 321 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr); 322 323 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO This, 324 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, 325 DWORD *pdwHelpContext, BSTR *pBstrHelpFile); 326 327 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO This, 328 MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, 329 BSTR *pBstrName, WORD *pwOrdinal); 330 331 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO This, 332 HREFTYPE hRefType, ITypeInfo * *ppTInfo); 333 334 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO This, 335 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv); 336 337 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO This, 338 IUnknown *pUnk, REFIID riid, VOID * *ppvObj); 339 340 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO This, MEMBERID memid, 341 BSTR *pBstrMops); 342 343 344 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO This, 345 ITypeLib * *ppTLib, UINT *pIndex); 346 347 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO This, 348 TYPEATTR *pTypeAttr); 349 350 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO This, 351 FUNCDESC *pFuncDesc); 352 353 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO This, 354 VARDESC *pVarDesc); 355 /* itypeinfo2 methods */ 356 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * This, 357 TYPEKIND *pTypeKind); 358 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * This, 359 UINT *pTypeFlags); 360 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * This, 361 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex); 362 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * This, 363 MEMBERID memid, UINT *pVarIndex); 364 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * This, 365 REFGUID guid, VARIANT *pVarVal); 366 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * This, 367 UINT index, REFGUID guid, VARIANT *pVarVal); 368 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * This, 369 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal); 370 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * This, 371 UINT index, REFGUID guid, VARIANT *pVarVal); 372 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * This, 373 UINT index, REFGUID guid, VARIANT *pVarVal); 374 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * This, 375 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString, 376 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll); 377 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * This, 378 CUSTDATA *pCustData); 379 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * This, 380 UINT index, CUSTDATA *pCustData); 381 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * This, 382 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData); 383 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * This, 384 UINT index, CUSTDATA *pCustData); 385 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * This, 386 UINT index, CUSTDATA *pCustData); 387 388 static ICOM_VTABLE(ITypeInfo) tinfvt = { 389 ITypeInfo_fnQueryInterface, 390 ITypeInfo_fnAddRef, 391 ITypeInfo_fnRelease, 392 ITypeInfo_fnGetTypeAttr, 393 ITypeInfo_fnGetTypeComp, 394 ITypeInfo_fnGetFuncDesc, 395 ITypeInfo_fnGetVarDesc, 396 ITypeInfo_fnGetNames, 397 ITypeInfo_fnGetRefTypeOfImplType, 398 ITypeInfo_fnGetImplTypeFlags, 399 ITypeInfo_fnGetIDsOfNames, 400 ITypeInfo_fnInvoke, 401 ITypeInfo_fnGetDocumentation, 402 ITypeInfo_fnGetDllEntry, 403 ITypeInfo_fnGetRefTypeInfo, 404 ITypeInfo_fnAddressOfMember, 405 ITypeInfo_fnCreateInstance, 406 ITypeInfo_fnGetMops, 407 ITypeInfo_fnGetContainingTypeLib, 408 ITypeInfo_fnReleaseTypeAttr, 409 ITypeInfo_fnReleaseFuncDesc, 410 ITypeInfo_fnReleaseVarDesc, 411 412 ITypeInfo2_fnGetTypeKind, 413 ITypeInfo2_fnGetTypeFlags, 414 ITypeInfo2_fnGetFuncIndexOfMemId, 415 ITypeInfo2_fnGetVarIndexOfMemId, 416 ITypeInfo2_fnGetCustData, 417 ITypeInfo2_fnGetFuncCustData, 418 ITypeInfo2_fnGetParamCustData, 419 ITypeInfo2_fnGetVarCustData, 420 ITypeInfo2_fnGetImplTypeCustData, 421 ITypeInfo2_fnGetDocumentation2, 422 ITypeInfo2_fnGetAllCustData, 423 ITypeInfo2_fnGetAllFuncCustData, 424 ITypeInfo2_fnGetAllParamCustData, 425 ITypeInfo2_fnGetAllVarCustData, 426 ITypeInfo2_fnGetAllImplTypeCustData, 427 428 }; 429 430 static TYPEDESC stndTypeDesc[VT_LPWSTR+1]={/* VT_LPWSTR is largest type that */ 431 /* may appear in type description*/ 432 {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4}, 433 {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9}, 434 {{0},10},{{0},11},{{0},12},{{0},13},{{0},14}, 435 {{0},15},{{0},16},{{0},17},{{0},18},{{0},19}, 436 {{0},20},{{0},21},{{0},22},{{0},23},{{0},24}, 437 {{0},25},{{0},26},{{0},27},{{0},28},{{0},29}, 438 {{0},30},{{0},31}}; 439 440 static void TLB_abort() 441 { 442 *((int *)0)=0; 443 } 444 static void * TLB_Alloc(unsigned size) 445 { 446 void * ret; 447 if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){ 448 /* FIXME */ 449 ERR_(ole)("cannot allocate memory\n"); 450 } 451 return ret; 452 } 453 454 /* candidate for a more global appearance... */ 455 static BSTR TLB_DupAtoBstr(PCHAR Astr) 456 { 457 int len; 458 BSTR bstr; 459 DWORD *pdw ; 460 if(!Astr) 461 return NULL; 462 len=strlen(Astr); 463 pdw = (DWORD *)TLB_Alloc((len+3)*sizeof(OLECHAR)); 464 pdw[0]=(len)*sizeof(OLECHAR); 465 bstr=(BSTR)&( pdw[1]); 466 lstrcpyAtoW( bstr, Astr); 467 TRACE_(typelib)("copying %s to (%p)\n", Astr, bstr); 468 return bstr; 469 } 470 471 static void TLB_Free(void * ptr) 472 { 473 HeapFree(GetProcessHeap(), 0, ptr); 474 } 475 /* read function */ 476 DWORD TLB_Read(void *buffer, DWORD count, TLBContext *pcx, long where ) 477 { 478 DWORD bytesread=0; 479 480 if (( where != DO_NOT_SEEK && 481 (0xffffffff == SetFilePointer( pcx->hFile, where, 0,FILE_BEGIN)) 482 ) || 483 !ReadFile(pcx->hFile, buffer, count, &bytesread, NULL) 484 ) { 485 /* FIXME */ 486 ERR_(typelib)("read error is 0x%lx reading %ld bytes at 0x%lx\n", 487 GetLastError(), count, where); 488 TLB_abort(); 489 exit(1); 490 } 491 return bytesread; 492 } 493 494 static void TLB_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx) 495 { 496 if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){ 497 memset(pGuid,0, sizeof(GUID)); 498 return; 499 } 500 TLB_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset ); 501 } 502 503 PCHAR TLB_ReadName( TLBContext *pcx, int offset) 504 { 505 char * name; 506 TLBNameIntro niName; 507 TLB_Read(&niName, sizeof(niName), pcx, 508 pcx->pTblDir->pNametab.offset+offset); 509 niName.namelen &= 0xFF; /* FIXME: correct ? */ 510 name=(char *)TLB_Alloc((niName.namelen & 0xff) +1); 511 TLB_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK); 512 name[niName.namelen & 0xff]='\0'; 513 return name; 514 } 515 PCHAR TLB_ReadString( TLBContext *pcx, int offset) 516 { 517 char * string; 518 INT16 length; 519 if(offset<0) return NULL; 520 TLB_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset); 521 if(length <= 0) return 0; 522 string=(char *)TLB_Alloc(length +1); 523 TLB_Read(string, length, pcx, DO_NOT_SEEK); 524 string[length]='\0'; 525 return string; 526 } 527 /* 528 * read a value and fill a VARIANT structure 529 */ 530 static void TLB_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx ) 531 { 532 int size; 533 if(offset <0) { /* data is packed in here */ 534 pVar->vt = (offset & 0x7c000000 )>> 26; 210 // ====================================================================== 211 // Class functions. 212 // ====================================================================== 213 214 // ---------------------------------------------------------------------- 215 // TypeLibExtract::TypeLibExtract 216 // ---------------------------------------------------------------------- 217 TypeLibExtract::TypeLibExtract(char * szName) : m_fValid(0), m_hHeap(GetProcessHeap()) 218 { 219 if ((Load(szName) == S_OK) 220 && (EstablishPointers() == S_OK)) 221 { 222 m_fValid = TRUE; 223 } 224 } 225 226 // ---------------------------------------------------------------------- 227 // TypeLibExtract::~TypeLibExtract 228 // ---------------------------------------------------------------------- 229 TypeLibExtract::~TypeLibExtract() 230 { 231 m_fValid = 0; 232 233 if (m_pTypeLib) 234 HeapFree(m_hHeap, 0, m_pTypeLib); 235 236 m_hHeap = 0; 237 } 238 239 // ---------------------------------------------------------------------- 240 // TypeLibExtract::EstablishPointers() 241 // ---------------------------------------------------------------------- 242 HRESULT TypeLibExtract::EstablishPointers() 243 { 244 // Locate segment directory... 245 m_pHeader = (TLB2Header *)m_pTypeLib; 246 if (m_pHeader->varflags & HELPDLLFLAG) 247 { 248 m_pHelpStringOff = (ULONG *)(m_pHeader + 1); 249 m_pTypeInfoDir = m_pHelpStringOff + 1; 250 } 251 else 252 { 253 m_pHelpStringOff = 0; 254 m_pTypeInfoDir = (ULONG *)(m_pHeader + 1); 255 } 256 m_pSegDir = (TLBSegDir *)(m_pTypeInfoDir + m_pHeader->nrtypeinfos); 257 258 // Segment directory sanity check... 259 if (m_pSegDir->pTypeInfoTab.res0c != 0x0F || m_pSegDir->pImpInfo.res0c != 0x0F) 260 { 261 dprintf((" Segment directory sanity check failed!")); 262 return E_FAIL; 263 } 264 265 // m_pLib 266 if (m_pSegDir->pImpInfo.offset > 0) 267 m_pImpInfo = (TLBImpInfo *)((char *)m_pTypeLib + m_pSegDir->pImpInfo.offset); 268 else 269 m_pImpInfo = 0; 270 271 if (m_pSegDir->pRefTab.offset > 0) 272 m_pRef = (TLBRefRecord *)((char *)m_pTypeLib + m_pSegDir->pRefTab.offset); 273 else 274 m_pRef = 0; 275 276 if (m_pSegDir->pGuidTab.offset > 0) 277 m_pGUID = (GUID *)((char *)m_pTypeLib + m_pSegDir->pGuidTab.offset); 278 else 279 m_pGUID = 0; 280 281 if (m_pSegDir->pNameTab.offset > 0) 282 m_pName = (TLBName *)((char *)m_pTypeLib + m_pSegDir->pNameTab.offset); 283 else 284 m_pName = 0; 285 286 if (m_pSegDir->pStringTab.offset > 0) 287 m_pString = (TLBString *)((char *)m_pTypeLib + m_pSegDir->pStringTab.offset); 288 else 289 m_pString = 0; 290 291 if (m_pSegDir->pTypedescTab.offset > 0) 292 m_pTypedesc = (TLBTypedesc *)((char *)m_pTypeLib + m_pSegDir->pTypedescTab.offset); 293 else 294 m_pTypedesc = 0; 295 296 if (m_pSegDir->pTypedescTab.offset > 0) 297 m_pArray = (TLBArray *)((char *)m_pTypeLib + m_pSegDir->pTypedescTab.offset); 298 else 299 m_pArray = 0; 300 301 if (m_pSegDir->pCustData.offset > 0) 302 m_pCustData = (void *)((char *)m_pTypeLib + m_pSegDir->pCustData.offset); 303 else 304 m_pCustData = 0; 305 306 if (m_pSegDir->pCDGuids.offset > 0) 307 m_pCDGuid = (TLBCDGuid *)((char *)m_pTypeLib + m_pSegDir->pCDGuids.offset); 308 else 309 m_pCDGuid = 0; 310 311 if (m_pSegDir->pImpFiles.offset > 0) 312 m_pImpFile = (TLBImpFile *)((char *)m_pTypeLib + m_pSegDir->pImpFiles.offset); 313 else 314 m_pImpFile = 0; 315 316 if (m_pSegDir->pTypeInfoTab.offset > 0) 317 m_pTypeInfo = (TLBTypeInfoBase *)((char *)m_pTypeLib + m_pSegDir->pTypeInfoTab.offset); 318 else 319 m_pTypeInfo = 0; 320 321 return S_OK; 322 } 323 324 // ---------------------------------------------------------------------- 325 // TypeLibExtract::Read 326 // 327 // If 'where' is != DO_NOT_SEEK then seek to 'where'. 328 // Read 'count' bytes from 'hfile' into 'buffer' 329 // ---------------------------------------------------------------------- 330 BOOL TypeLibExtract::Read(HANDLE hFile, void * buffer, DWORD count, DWORD * pBytesRead, long where) 331 { 332 if (where != DO_NOT_SEEK) 333 { 334 if (0xffffffff == SetFilePointer(hFile, where, 0, FILE_BEGIN)) 335 return FALSE; 336 } 337 return ReadFile(hFile, buffer, count, pBytesRead, NULL); 338 } 339 340 // ---------------------------------------------------------------------- 341 // TypeLibExtract::GetTypedesc 342 // ---------------------------------------------------------------------- 343 void TypeLibExtract::GetTypedesc(int type, TYPEDESC * pTd) 344 { 345 if (type < 0) 346 pTd->vt = type & VT_TYPEMASK; 347 else 348 *pTd = *m_pITypeLib->pTypedesc[type / (sizeof(TLBTypedesc))]; 349 } 350 351 // ---------------------------------------------------------------------- 352 // TypeLibExtract::ParseGuid 353 // ---------------------------------------------------------------------- 354 void TypeLibExtract::ParseGuid(int offset, GUID * pGuid) 355 { 356 if (offset < 0) 357 { 358 memset(pGuid, 0, sizeof(GUID)); 359 } 360 else 361 { 362 memcpy(pGuid, (char *)m_pGUID + offset, sizeof(GUID)); 363 } 364 } 365 366 // ---------------------------------------------------------------------- 367 // TypeLibExtract::ParseArray 368 // ---------------------------------------------------------------------- 369 void TypeLibExtract::ParseArray(int offset, TLBArray * pArray) 370 { 371 if (offset < 0) 372 { 373 memset(pArray, 0, sizeof(TLBArray)); 374 } 375 else 376 { 377 memcpy(pArray, (char *)m_pGUID + offset, sizeof(TLBArray)); 378 } 379 } 380 381 // ---------------------------------------------------------------------- 382 // TypeLibExtract::ParseName 383 // ---------------------------------------------------------------------- 384 void TypeLibExtract::ParseName(int offset, char * * ppName) 385 { 386 char * p; 387 388 if (offset < 0) 389 { 390 *ppName = 0; 391 } 392 else 393 { 394 TLBName * pName = (TLBName *)((char *)m_pName + offset); 395 int nameLen = pName->namelen & 0xff; 396 397 p = (char *)HeapAlloc(m_hHeap, 0, nameLen + 1); 398 memcpy(p, pName->name, nameLen); 399 p[nameLen] = 0; 400 401 *ppName = p; 402 } 403 } 404 405 // ---------------------------------------------------------------------- 406 // TypeLibExtract::ParseString 407 // ---------------------------------------------------------------------- 408 void TypeLibExtract::ParseString(int offset, char * * ppString) 409 { 410 char * p; 411 412 if (offset < 0) 413 { 414 *ppString = 0; 415 } 416 else 417 { 418 TLBString * pString = (TLBString *)((char *)m_pString + offset); 419 int stringLen = pString->stringlen; 420 421 p = (char *)HeapAlloc(m_hHeap, 0, stringLen + 1); 422 423 memcpy(p, pString->string, stringLen); 424 p[stringLen] = 0; 425 426 *ppString = p; 427 } 428 } 429 430 // ---------------------------------------------------------------------- 431 // TypeLibExtract::ParseValue 432 // ---------------------------------------------------------------------- 433 void TypeLibExtract::ParseValue(int offset, VARIANT * pVar) 434 { 435 int size; 436 437 if (offset < 0) /* data is packed in here */ 438 { 439 pVar->vt = (offset & 0x7c000000) >> 26; 535 440 V_UNION(pVar, iVal) = offset & 0xffff; 536 441 return; 537 442 } 538 TLB_Read(&(pVar->vt), sizeof(VARTYPE), pcx, 539 pcx->pTblDir->pCustData.offset + offset ); 540 switch(pVar->vt){ 443 444 VARTYPE * pVarType = (VARTYPE *)((char *)m_pCustData + offset); 445 446 pVar->vt = *pVarType; 447 448 switch(pVar->vt) 449 { 541 450 case VT_EMPTY: /* FIXME: is this right? */ 542 451 case VT_NULL: /* FIXME: is this right? */ … … 554 463 case VT_VOID : /* FIXME: is this right? */ 555 464 case VT_HRESULT : 556 size=4; break; 465 size=4; 466 break; 467 557 468 case VT_R8 : 558 469 case VT_CY : … … 562 473 case VT_DECIMAL : /* FIXME: is this right? */ 563 474 case VT_FILETIME : 564 size=8;break; 475 size=8; 476 break; 477 565 478 /* pointer types with known behaviour */ 566 case VT_BSTR : {567 char * ptr;568 TLB_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK);569 ptr=(char *)TLB_Alloc(size);/* allocate temp buffer */570 TLB_Read(ptr, size, pcx, DO_NOT_SEEK ); /* read string (ANSI) */ 571 V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size); 572 /* FIXME: do we need a AtoW conversion here? */ 573 V_UNION(pVar, bstrVal[size])=L'\0';574 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];575 TLB_Free(ptr);576 577 size=-4; break; 479 case VT_BSTR : 480 { 481 INT * pStringLen = (INT *)(pVarType + 1); 482 char * pString = (char *)(pStringLen + 1); 483 484 // Allocate BSTR container and then convert directly into it... 485 //???A Fix 486 V_UNION(pVar, bstrVal) = SysAllocStringLen(NULL, *pStringLen); 487 AsciiToUnicodeN(pString, V_UNION(pVar, bstrVal), *pStringLen); 488 return; 489 } 490 578 491 /* FIXME: this will not work AT ALL when the variant contains a pointer */ 579 492 case VT_DISPATCH : … … 595 508 case VT_CLSID : 596 509 default: 597 size=0; 598 FIXME_(ole)("VARTYPE %d is not supported, setting pointer to NULL\n", 599 pVar->vt); 600 } 601 602 if(size>0) /* (big|small) endian correct? */ 603 TLB_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK ); 604 return ; 605 } 606 /* 607 * create a linked list with custom data 608 */ 609 static int TLB_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData ) 610 { 611 TLBCDGuid entry; 612 TLBCustData* pNew; 613 int count=0; 614 while(offset >=0){ 615 count++; 616 pNew=(TLBCustData* )TLB_Alloc(sizeof(TLBCustData)); 617 TLB_Read(&entry, sizeof(entry), pcx, 618 pcx->pTblDir->pCDGuids.offset+offset); 619 TLB_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx); 620 TLB_ReadValue(&(pNew->data), entry.DataOffset, pcx); 621 /* add new custom data at head of the list */ 622 pNew->next=*ppCustData; 623 *ppCustData=pNew; 624 offset = entry.next; 625 } 626 return count; 627 } 628 629 static void TLB_GetTdesc(TLBContext *pcx, INT type,TYPEDESC * pTd ) 630 { 631 if(type <0) 632 pTd->vt=type & VT_TYPEMASK; 633 else 634 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))]; 635 } 636 static void TLB_DoFuncs(TLBContext *pcx, int cFuncs, int cVars, 637 int offset, TLBFuncDesc ** pptfd) 638 { 639 /* 640 * member information is stored in a data structure at offset 641 * indicated by the memoffset field of the typeinfo structure 642 * There are several distinctive parts. 643 * the first part starts with a field that holds the total length 644 * of this (first) part excluding this field. Then follow the records, 645 * for each member there is one record. 646 * 647 * First entry is always the length of the record (excluding this 648 * length word). 649 * Rest of the record depends on the type of the member. If there is 650 * a field indicating the member type (function variable intereface etc) 651 * I have not found it yet. At this time we depend on the information 652 * in the type info and the usual order how things are stored. 653 * 654 * Second follows an array sized nrMEM*sizeof(INT) with a memeber id 655 * for each member; 656 * 657 * Third is a equal sized array with file offsets to the name entry 658 * of each member. 659 * 660 * Forth and last (?) part is an array with offsets to the records in the 661 * first part of this file segment. 510 size = 0; 511 dprintf(("OLEAUT32: VARTYPE %d is not supported, setting pointer to NULL\n", pVar->vt)); 512 } 513 514 if (size > 0) /* (big|small) endian correct? */ 515 memcpy(&(V_UNION(pVar, iVal)), (pVarType + 1), size); 516 517 } 518 519 // ---------------------------------------------------------------------- 520 // TypeLibExtract::ParseCustomData 521 // ---------------------------------------------------------------------- 522 void TypeLibExtract::ParseCustomData(int offset, oList<TLBCustData *> * pCustomData) 523 { 524 TLBCDGuid * pCDGuid; 525 TLBCustData * pNew; 526 527 while (offset >=0) 528 { 529 pCDGuid = (TLBCDGuid *)((char *)m_pCDGuid + offset); 530 pNew = new TLBCustData; 531 532 ParseGuid(pCDGuid->GuidOffset, &(pNew->guid)); 533 ParseValue(pCDGuid->DataOffset, &(pNew->data)); 534 535 pCustomData->AddAtEnd(pNew); 536 offset = pCDGuid->next; 537 } 538 } 539 540 // ---------------------------------------------------------------------- 541 // TypeLibExtract::ParseTypeInfo 542 // ---------------------------------------------------------------------- 543 void TypeLibExtract::ParseTypeInfo(ITypeInfoImpl * pTypeInfo, TLBTypeInfoBase * pBase) 544 { 545 /* fill in the typeattr fields */ 546 ParseGuid(pBase->posguid, &pTypeInfo->TypeAttr.guid); 547 pTypeInfo->TypeAttr.lcid = m_pITypeLib->LibAttr.lcid; /* FIXME: correct? */ 548 pTypeInfo->TypeAttr.memidConstructor = MEMBERID_NIL ;/* FIXME */ 549 pTypeInfo->TypeAttr.memidDestructor = MEMBERID_NIL ; /* FIXME */ 550 pTypeInfo->TypeAttr.lpstrSchema = NULL; /* reserved */ 551 pTypeInfo->TypeAttr.cbSizeInstance = pBase->size; 552 pTypeInfo->TypeAttr.typekind = (tagTYPEKIND)(pBase->typekind & 0xF); 553 pTypeInfo->TypeAttr.cFuncs = LOWORD(pBase->cElement); 554 pTypeInfo->TypeAttr.cVars = HIWORD(pBase->cElement); 555 pTypeInfo->TypeAttr.cbAlignment = (pBase->typekind >> 11 )& 0x1F; /* more flags here ? */ 556 pTypeInfo->TypeAttr.wTypeFlags = pBase->flags; 557 pTypeInfo->TypeAttr.wMajorVerNum = LOWORD(pBase->version); 558 pTypeInfo->TypeAttr.wMinorVerNum = HIWORD(pBase->version); 559 pTypeInfo->TypeAttr.cImplTypes = pBase->cImplTypes; 560 pTypeInfo->TypeAttr.cbSizeVft = pBase->cbSizeVft; // FIXME: this is only the non inherited part 561 if (pTypeInfo->TypeAttr.typekind == TKIND_ALIAS) 562 GetTypedesc(pBase->datatype1, &pTypeInfo->TypeAttr.tdescAlias) ; 563 564 /* FIXME: */ 565 /* IDLDESC idldescType; *//* never saw this one ! = zero */ 566 567 /* name, eventually add to a hash table */ 568 ParseName(pBase->NameOffset, &pTypeInfo->szName); 569 570 dprintf((" -> typeinfo \"%s\"\n", pTypeInfo->szName)); 571 572 /* help info */ 573 ParseString(pBase->docstringoffs, &pTypeInfo->szDocString); 574 pTypeInfo->lHelpStringContext = pBase->helpstringcontext; 575 pTypeInfo->lHelpContext = pBase->helpcontext; 576 /* note: InfoType's Help file and HelpStringDll come from the containing 577 * library. Further HelpString and Docstring appear to be the same thing :( 662 578 */ 663 579 664 int infolen, nameoffset, reclength, nrattributes; 665 char recbuf[512]; 666 TLBFuncRecord * pFuncRec=(TLBFuncRecord *) recbuf; 667 int i, j; 668 int recoffset=offset+sizeof(INT); 669 TLB_Read(&infolen,sizeof(INT), pcx, offset); 670 for(i=0;i<cFuncs;i++){ 671 *pptfd=(TLBFuncDesc*)TLB_Alloc(sizeof(TLBFuncDesc)); 672 /* name, eventually add to a hash table */ 673 TLB_Read(&nameoffset, sizeof(INT), pcx, 674 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT)); 675 (*pptfd)->Name=TLB_ReadName(pcx, nameoffset); 676 /* read the function information record */ 677 TLB_Read(&reclength, sizeof(INT), pcx, recoffset); 678 reclength &=0x1ff; 679 TLB_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 680 /* do the attributes */ 681 nrattributes=(reclength-pFuncRec->nrargs*3*sizeof(int)-0x18) 682 /sizeof(int); 683 if(nrattributes>0){ 684 (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ; 685 if(nrattributes>1){ 686 (*pptfd)->HelpString = TLB_ReadString(pcx, 687 pFuncRec->OptAttr[1]) ; 688 if(nrattributes>2){ 689 if(pFuncRec->FKCCIC & 0x2000) 690 (*pptfd)->Entry = (char *) pFuncRec->OptAttr[2] ; 691 else 692 (*pptfd)->Entry = TLB_ReadString(pcx, 693 pFuncRec->OptAttr[2]); 694 if(nrattributes>5 ) 695 (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ; 696 if(nrattributes>6 && pFuncRec->FKCCIC & 0x80){ 697 TLB_CustData(pcx, pFuncRec->OptAttr[6], 698 &(*pptfd)->pCustData); 699 } 580 // Functions/ 581 ParseMembers(pTypeInfo, pBase); 582 583 // ImplTypes {DR: not sure this is OK yet} 584 if (pTypeInfo->TypeAttr.typekind == TKIND_COCLASS) 585 ParseImplemented(pTypeInfo, pBase); 586 587 // RefTypes {DR: not sure this is OK yet} 588 else if (pTypeInfo->TypeAttr.typekind != TKIND_DISPATCH) 589 { 590 TLBRefType * pNew = new TLBRefType; 591 ParseReference(pBase->datatype1, pNew); 592 pTypeInfo->pImplements.AddAtEnd(pNew); 593 594 } 595 596 // Load Custom data 597 ParseCustomData(pBase->oCustData, &pTypeInfo->pCustData); 598 } 599 600 // ---------------------------------------------------------------------- 601 // TypeLibExtract::ParseReference 602 // ---------------------------------------------------------------------- 603 void TypeLibExtract::ParseReference(int offset, TLBRefType * pNew) 604 { 605 int j; 606 607 if(!HREFTYPE_INTHISFILE( offset)) 608 { 609 /* external typelib */ 610 TLBImpInfo * pImpInfo = (TLBImpInfo *)((char *)m_pImpInfo + (offset & 0xfffffffc)); 611 oListIter<TLBImpLib *> itrImpLib(m_pITypeLib->pImpLibs); 612 613 // We have already loaded the external typelibs so 614 // loop thru them to find the one we want. 615 for (itrImpLib.MoveStart(); itrImpLib.IsValid(); itrImpLib.MoveNext()) 616 { 617 618 if (itrImpLib.Element()->offset == pImpInfo->oImpFile) 619 { 620 pNew->reference = offset; 621 pNew->pImpTLInfo = itrImpLib.Element(); 622 ParseGuid(pImpInfo->oGuid, &pNew->guid); 623 return; 624 } 625 } 626 dprintf((" WARNING: Cannot find a reference\n")); 627 pNew->reference = -1; 628 pNew->pImpTLInfo = (TLBImpLib *)-1; 629 } 630 else 631 { 632 /* in this typelib */ 633 pNew->reference = offset; 634 pNew->pImpTLInfo = (TLBImpLib *)-2; 635 } 636 } 637 638 // ---------------------------------------------------------------------- 639 // TypeLibExtract::ParseImplemented 640 // 641 // Process Implemented Interfaces of a com class 642 // ---------------------------------------------------------------------- 643 void TypeLibExtract::ParseImplemented(ITypeInfoImpl * pTypeInfo, TLBTypeInfoBase * pBase) 644 { 645 TLBRefRecord * pRefRec; 646 TLBRefType * pNew; 647 int ii; 648 int offset; 649 650 offset = pBase->datatype1; 651 for (ii = 0; ii < pTypeInfo->TypeAttr.cImplTypes; ii++) 652 { 653 if (offset < 0) 654 break; /* paranoia */ 655 656 pRefRec = (TLBRefRecord *)((char *)m_pRef + offset); 657 pNew = new TLBRefType; 658 659 ParseReference(pRefRec->reftype, pNew); 660 pNew->flags = pRefRec->flags; 661 662 // Custom data 663 ParseCustomData(pRefRec->oCustData, &pNew->pCustData); 664 665 pTypeInfo->pImplements.AddAtEnd(pNew); 666 667 offset = pRefRec->onext; 668 } 669 } 670 671 // ---------------------------------------------------------------------- 672 // TypeLibExtract::ParseMembers 673 // 674 // Member information is stored in a data structure at offset 675 // indicated by the memoffset field of the typeinfo structure 676 // There are several distinctive parts. 677 // the first part starts with a field that holds the total length 678 // of this (first) part excluding this field. Then follow the records, 679 // for each member there is one record. 680 // 681 // First entry is always the length of the record (excluding this 682 // length word). 683 // Rest of the record depends on the type of the member. If there is 684 // a field indicating the member type (function variable intereface etc) 685 // I have not found it yet. At this time we depend on the information 686 // in the type info and the usual order how things are stored. 687 // 688 // Second follows an array sized nrMEM*sizeof(INT) with a memeber id 689 // for each member; 690 // 691 // Third is a equal sized array with file offsets to the name entry 692 // of each member. 693 // 694 // Forth and last (?) part is an array with offsets to the records in the 695 // first part of this file segment. 696 // 697 // ---------------------------------------------------------------------- 698 void TypeLibExtract::ParseMembers(ITypeInfoImpl * pTypeInfo, TLBTypeInfoBase * pBase) 699 { 700 TLBFuncRecord * pFuncRec; 701 TLBVarRecord * pVarRec; 702 int ii; 703 int jj; 704 int iAttrCount; 705 INT * pInfoLen; 706 INT * pNameOff; 707 INT * pMemberID; 708 INT * pMemberOff; 709 710 // Map ptrs to sections of the typeinfo record... 711 pInfoLen = (INT *)((char *)m_pTypeLib + pBase->memoffset); 712 pFuncRec = (TLBFuncRecord *)(pInfoLen + 1); 713 pMemberID = (INT *)((char *)pFuncRec + *pInfoLen); 714 pNameOff = pMemberID + pTypeInfo->TypeAttr.cFuncs + pTypeInfo->TypeAttr.cVars; 715 pMemberOff = pNameOff + pTypeInfo->TypeAttr.cFuncs + pTypeInfo->TypeAttr.cVars; 716 717 // loop through each function... 718 for (ii = 0; ii < pTypeInfo->TypeAttr.cFuncs; ii++) 719 { 720 TLBFuncDesc * pNew; 721 722 pNew = new TLBFuncDesc; 723 ParseName(pNameOff[ii], &pNew->szName); 724 725 dprintf((" -> function \"%s\"\n", pNew->szName)); 726 727 // decode optional attributes 728 iAttrCount = (pFuncRec->recsize 729 - pFuncRec->nrargs * 3 * sizeof(int) - 0x18) / sizeof(int); 730 731 if (iAttrCount > 0) 732 pNew->helpcontext = pFuncRec->OptAttr[0] ; 733 734 if (iAttrCount > 1) 735 ParseString(pFuncRec->OptAttr[1], &pNew->szHelpString); 736 737 if (iAttrCount > 2) 738 { 739 if (pFuncRec->FKCCIC & 0x2000) 740 pNew->szEntry = (char *) pFuncRec->OptAttr[2] ; 741 else 742 ParseString(pFuncRec->OptAttr[2], &pNew->szEntry); 743 } 744 745 if (iAttrCount > 5 ) 746 pNew->lHelpStringContext = pFuncRec->OptAttr[5] ; 747 748 if (iAttrCount > 6 && pFuncRec->FKCCIC & 0x80) 749 ParseCustomData(pFuncRec->OptAttr[6], &pNew->pCustData); 750 751 // fill the FuncDesc Structure 752 pNew->funcdesc.memid = pMemberID[ii]; 753 pNew->funcdesc.funckind = (tagFUNCKIND)((pFuncRec->FKCCIC) & 0x7); 754 pNew->funcdesc.invkind = (tagINVOKEKIND)(((pFuncRec->FKCCIC) >>3) & 0xF); 755 pNew->funcdesc.callconv = (tagCALLCONV)((pFuncRec->FKCCIC) >>8 & 0xF); 756 pNew->funcdesc.cParams = pFuncRec->nrargs ; 757 pNew->funcdesc.cParamsOpt = pFuncRec->nroargs ; 758 pNew->funcdesc.oVft = pFuncRec->VtableOffset ; 759 pNew->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; 760 GetTypedesc(pFuncRec->DataType, &pNew->funcdesc.elemdescFunc.tdesc) ; 761 762 // do the parameters/arguments 763 if (pFuncRec->nrargs) 764 { 765 TLBParameterInfo * pParam; 766 767 pNew->funcdesc.lprgelemdescParam = new ELEMDESC[pFuncRec->nrargs]; 768 pNew->pParamDesc = new TLBParDesc[pFuncRec->nrargs]; 769 770 pParam = (TLBParameterInfo *)((char *)pFuncRec + pFuncRec->recsize - 771 pFuncRec->nrargs * sizeof(TLBParameterInfo)); 772 773 for(jj = 0 ; jj < pFuncRec->nrargs; jj++) 774 { 775 GetTypedesc(pParam->DataType, &pNew->funcdesc.lprgelemdescParam[jj].tdesc); 776 777 V_UNION(&(pNew->funcdesc.lprgelemdescParam[jj]), 778 paramdesc.wParamFlags) = pParam->Flags; 779 // Name 780 ParseName(pParam->oName, &pNew->pParamDesc[jj].szName); 781 dprintf((" -> param \"%s\"\n", pNew->pParamDesc[jj].szName)); 782 783 // default value 784 if ((PARAMFLAG_FHASDEFAULT & V_UNION(&(pNew->funcdesc. 785 lprgelemdescParam[jj]),paramdesc.wParamFlags)) && 786 ((pFuncRec->FKCCIC) & 0x1000)) 787 { 788 INT *pInt = (INT *)((char *)pFuncRec + pFuncRec->recsize - 789 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) ); 790 PARAMDESC * pParamDesc = &V_UNION(&(pNew->funcdesc. 791 lprgelemdescParam[jj]),paramdesc); 792 pParamDesc->pparamdescex = new PARAMDESCEX; 793 pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX); 794 ParseValue(pInt[jj], &(pParamDesc->pparamdescex->varDefaultValue)); 700 795 } 796 797 // custom info 798 if (iAttrCount > 7 + jj && pFuncRec->FKCCIC & 0x80) 799 ParseCustomData(pFuncRec->OptAttr[7 + jj], &pNew->pParamDesc[jj].pCustData); 800 801 pParam++; // Next record. 701 802 } 803 } 804 805 /* scode is not used: archaic win16 stuff FIXME: right? */ 806 pNew->funcdesc.cScodes = 0 ; 807 pNew->funcdesc.lprgscode = NULL ; 808 809 // Store 810 pTypeInfo->pFunctions.AddAtEnd(pNew); 811 812 // Next record... 813 pFuncRec = (TLBFuncRecord *)((char *)pFuncRec + pFuncRec->recsize); 814 } 815 816 // Wine calc's for this ptr were b**ll***s 817 pVarRec = (TLBVarRecord *)pFuncRec; 818 819 for (ii = 0; ii < pTypeInfo->TypeAttr.cVars; ii++) 820 { 821 TLBVarDesc * pNew; 822 823 pNew = new TLBVarDesc; 824 825 // name, eventually add to a hash table 826 ParseName(pNameOff[ii], &pNew->szName); 827 dprintf((" -> variable \"%s\"\n", pNew->szName)); 828 829 // Optional data 830 if (pVarRec->recsize > (6 * sizeof(INT)) ) 831 pNew->lHelpContext = pVarRec->HelpContext; 832 833 if (pVarRec->recsize > (7 * sizeof(INT)) ) 834 ParseString(pVarRec->oHelpString, &pNew->szHelpString); 835 836 if (pVarRec->recsize > (8 * sizeof(INT)) ) 837 ; 838 839 if (pVarRec->recsize > (9 * sizeof(INT)) ) 840 pNew->lHelpStringContext = pVarRec->HelpStringContext; 841 842 // fill the VarDesc Structure 843 pNew->vardesc.memid = pMemberID[ii]; 844 pNew->vardesc.varkind = (tagVARKIND)pVarRec->VarKind; 845 pNew->vardesc.wVarFlags = pVarRec->Flags; 846 GetTypedesc(pVarRec->DataType, &pNew->vardesc.elemdescVar.tdesc) ; 847 /* pNew->vardesc.lpstrSchema; is reserved (SDK) fixme?? */ 848 if (pVarRec->VarKind == VAR_CONST ) 849 { 850 V_UNION(&(pNew->vardesc), lpvarValue) = new VARIANT; 851 ParseValue(pVarRec->OffsValue, V_UNION(&(pNew->vardesc), lpvarValue)); 702 852 } 703 /* fill the FuncDesc Structure */ 704 TLB_Read(&(*pptfd)->funcdesc.memid, sizeof(INT), pcx, 705 offset + infolen + ( i + 1) * sizeof(INT)); 706 (*pptfd)->funcdesc.funckind = (tagFUNCKIND)((pFuncRec->FKCCIC) & 0x7); 707 (*pptfd)->funcdesc.invkind = (tagINVOKEKIND)(((pFuncRec->FKCCIC) >>3) & 0xF); 708 (*pptfd)->funcdesc.callconv = (tagCALLCONV)((pFuncRec->FKCCIC) >>8 & 0xF); 709 (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ; 710 (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ; 711 (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ; 712 (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; 713 TLB_GetTdesc(pcx, pFuncRec->DataType, 714 &(*pptfd)->funcdesc.elemdescFunc.tdesc) ; 715 716 /* do the parameters/arguments */ 717 if(pFuncRec->nrargs){ 718 TLBParameterInfo paraminfo; 719 (*pptfd)->funcdesc.lprgelemdescParam=(ELEMDESC*) 720 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC)); 721 (*pptfd)->pParamDesc=(TLBParDesc*)TLB_Alloc(pFuncRec->nrargs * 722 sizeof(TLBParDesc)); 723 724 TLB_Read(¶minfo,sizeof(paraminfo), pcx, recoffset+reclength - 725 pFuncRec->nrargs * sizeof(TLBParameterInfo)); 726 for(j=0;j<pFuncRec->nrargs;j++){ 727 TLB_GetTdesc(pcx, paraminfo.DataType, 728 &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc) ; 729 V_UNION(&((*pptfd)->funcdesc.lprgelemdescParam[j]), 730 paramdesc.wParamFlags) = paraminfo.Flags; 731 (*pptfd)->pParamDesc[j].Name=(char *)paraminfo.oName; 732 TLB_Read(¶minfo,sizeof(TLBParameterInfo), pcx, 733 DO_NOT_SEEK); 734 } 735 /* second time around */ 736 for(j=0;j<pFuncRec->nrargs;j++){ 737 /* name */ 738 (*pptfd)->pParamDesc[j].Name= 739 TLB_ReadName(pcx, (int)(*pptfd)->pParamDesc[j].Name); 740 /* default value */ 741 if((PARAMFLAG_FHASDEFAULT & V_UNION(&((*pptfd)->funcdesc. 742 lprgelemdescParam[j]),paramdesc.wParamFlags)) && 743 ((pFuncRec->FKCCIC) & 0x1000)){ 744 INT *pInt=(INT *)((char *)pFuncRec + reclength - 745 (pFuncRec->nrargs * 4 + 1) * sizeof(INT) ); 746 PARAMDESC * pParamDesc= &V_UNION(&((*pptfd)->funcdesc. 747 lprgelemdescParam[j]),paramdesc); 748 pParamDesc->pparamdescex = (tagPARAMDESCEX*)TLB_Alloc(sizeof(PARAMDESCEX)); 749 pParamDesc->pparamdescex->cBytes= sizeof(PARAMDESCEX); 750 TLB_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), 751 pInt[j], pcx); 752 } 753 /* custom info */ 754 if(nrattributes>7+j && pFuncRec->FKCCIC & 0x80) 755 TLB_CustData(pcx, pFuncRec->OptAttr[7+j], 756 &(*pptfd)->pParamDesc[j].pCustData); 757 } 853 else 854 V_UNION(&(pNew->vardesc), oInst) = pVarRec->OffsValue; 855 856 // Store 857 pTypeInfo->pVariables.AddAtEnd(pNew); 858 859 // Next record... 860 pVarRec = (TLBVarRecord *)((char *)pVarRec + pVarRec->recsize); 861 } 862 } 863 864 // ---------------------------------------------------------------------- 865 // LoadSub 866 // 867 // Callback handler function for the EnumResourceNamesA function... 868 // ---------------------------------------------------------------------- 869 static BOOL WIN32API LoadSub(HANDLE hMod, LPCTSTR pResType, LPTSTR pResName, LONG lParm) 870 { 871 dprintf((" LoadSub called")); 872 HRSRC hRsrc; 873 HGLOBAL hData; 874 875 hRsrc = FindResourceA(hMod, pResName, pResType); 876 hData = LoadResource(hMod, hRsrc); 877 *((void **)lParm) = LockResource(hData); 878 return FALSE; 879 } 880 881 // ---------------------------------------------------------------------- 882 // TypeLibExtract::Load 883 // 884 // Search for & load the TYPELIB into memory. 885 // ---------------------------------------------------------------------- 886 HRESULT TypeLibExtract::Load(char * szFile) 887 { 888 ULONG lStart; // Start of typelib in file 889 ULONG lReadLen; // Size of data read from file 890 ULONG lFileSize; // Size of file 891 char buf[5]; 892 OFSTRUCT ofStruct; 893 HANDLE hFile; 894 HRESULT rc; 895 896 dprintf(("OLEAUT32: TypeLibExtract::Load()")); 897 898 // Open file 899 if ((hFile = OpenFile(szFile, &ofStruct, OF_READ)) == HFILE_ERROR) 900 { 901 dprintf((" Error opening file - 0x%08x", GetLastError())); 902 return E_ACCESSDENIED; 903 } 904 905 lStart = 0; 906 907 // Read first four byts of file to identify it... 908 if (!Read(hFile, (void *)buf, 4, &lReadLen, lStart)) 909 { 910 CloseHandle(hFile); 911 dprintf((" Failed to read file start bytes")); 912 return E_FAIL; 913 } 914 915 // Check to see if this is a type 1 typelib... 916 if ((buf[0] == 'S') && (buf[1] == 'L') && (buf[2] == 'T') && (buf[3] == 'G')) 917 { 918 dprintf((" File identified as TYPE1 TYPELIB - not supported yet :-(")); 919 CloseHandle(hFile); 920 return E_FAIL; 921 } 922 923 // Check to see if this is a type 2 typelib... 924 if ((buf[0] == 'M') && (buf[1] == 'S') && (buf[2] == 'F') && (buf[3] == 'T')) 925 { 926 // Get typelib file size... 927 lFileSize = GetFileSize(hFile, NULL); 928 dprintf((" File identified as TYPE2 TYPELIB - Loading image (%lu bytes)...", lFileSize)); 929 930 m_pTypeLib = HeapAlloc(m_hHeap, 0, lFileSize); 931 if (!m_pTypeLib) 932 { 933 CloseHandle(hFile); 934 dprintf((" Failed to allocate a memory pool for typelib image")); 935 return E_OUTOFMEMORY; 936 } 937 938 // Read whole file into memory... 939 if (!Read(hFile, m_pTypeLib, lFileSize, &lReadLen, lStart)) 940 { 941 CloseHandle(hFile); 942 dprintf((" Failed to read typelib")); 943 HeapFree(m_hHeap, 0, m_pTypeLib); 944 return E_FAIL; 945 } 946 947 // Return buffer... 948 CloseHandle(hFile); 949 return S_OK; 950 } 951 952 // Done with file handle... 953 CloseHandle(hFile); 954 955 HINSTANCE hInst; 956 957 // Check to see if this is a module... 958 hInst = CoLoadLibrary(szFile, TRUE); 959 if (hInst) 960 { 961 // Yup - use EnumResourceNames to locate & load resource. 962 EnumResourceNamesA(hInst, "TYPELIB", LoadSub, (LONG)&m_pTypeLib); 963 } 964 965 if (!m_pTypeLib) 966 { 967 dprintf((" No TYPELIB resources found...")); 968 return E_FAIL; 969 } 970 971 return S_OK; 972 } 973 974 // ---------------------------------------------------------------------- 975 // TypeLibExtract::DumpHeader 976 // 977 // Drop a debug print of the header content to the ODIN log. 978 // ---------------------------------------------------------------------- 979 void TypeLibExtract::DumpHeader() 980 { 981 dprintf(("TYPELIB HEADER:")); 982 if (m_fValid) 983 { 984 dprintf((" Magic1 - 0x%08lx", m_pHeader->magic1)); 985 dprintf((" Magic2 - 0x%08lx", m_pHeader->magic2)); 986 dprintf((" posguid - 0x%08lx", m_pHeader->posguid)); 987 dprintf((" lcid - 0x%08lx", m_pHeader->lcid)); 988 dprintf((" lcid2 - 0x%08lx", m_pHeader->lcid2)); 989 dprintf((" varflags - 0x%08lx", m_pHeader->varflags)); 990 dprintf((" version - 0x%08lx", m_pHeader->version)); 991 dprintf((" flags - 0x%08lx", m_pHeader->flags)); 992 dprintf((" nrtypeinfos - 0x%08lx", m_pHeader->nrtypeinfos)); 993 dprintf((" helpstring - 0x%08lx", m_pHeader->helpstring)); 994 dprintf((" helpstringcontext - 0x%08lx", m_pHeader->helpstringcontext)); 995 dprintf((" helpcontext - 0x%08lx", m_pHeader->helpcontext)); 996 dprintf((" nametablecount - 0x%08lx", m_pHeader->nametablecount)); 997 dprintf((" nametablechars - 0x%08lx", m_pHeader->nametablechars)); 998 dprintf((" nameoffset - 0x%08lx", m_pHeader->nameOffset)); 999 dprintf((" helpfile - 0x%08lx", m_pHeader->helpfile)); 1000 dprintf((" custdataoffset - 0x%08lx", m_pHeader->customDataOffset)); 1001 dprintf((" res44 - 0x%08lx", m_pHeader->res44)); 1002 dprintf((" res48 - 0x%08lx", m_pHeader->res48)); 1003 dprintf((" dispatchpos - 0x%08lx", m_pHeader->dispatchpos)); 1004 dprintf((" res50 - 0x%08lx", m_pHeader->res50)); 1005 } 1006 else 1007 { 1008 dprintf((" INVALID")); 1009 } 1010 } 1011 1012 // ---------------------------------------------------------------------- 1013 // TypeLibExtract::MakeITypeLib 1014 // ---------------------------------------------------------------------- 1015 HRESULT TypeLibExtract::MakeITypeLib(ITypeLibImpl * * ppObject) 1016 { 1017 dprintf(("OLEAUT32: TypeLibExtract::MakeITypeLib")); 1018 1019 HRESULT rc; 1020 1021 // Create new typelib object... 1022 if ((m_pITypeLib = ITypeLibImpl_Constructor()) == 0) 1023 return E_OUTOFMEMORY; 1024 1025 // Parse the typelib into storeage independent format. 1026 rc = Parse(); 1027 if (rc != S_OK) 1028 { 1029 ITypeLibImpl_Destructor(m_pITypeLib); 1030 return rc; 1031 } 1032 1033 // Return new object 1034 *ppObject = m_pITypeLib; 1035 return S_OK; 1036 } 1037 1038 // ---------------------------------------------------------------------- 1039 // TypeLibExtract::Parse 1040 // ---------------------------------------------------------------------- 1041 HRESULT TypeLibExtract::Parse() 1042 { 1043 1044 dprintf(("OLEAUT32: TypeLibExtract::Parse")); 1045 1046 // Load header info... 1047 ParseGuid(m_pHeader->posguid, &m_pITypeLib->LibAttr.guid); 1048 1049 m_pITypeLib->LibAttr.lcid = m_pHeader->lcid; 1050 m_pITypeLib->LibAttr.syskind = (tagSYSKIND)(m_pHeader->varflags & 0x0f); /* check the mask */ 1051 m_pITypeLib->LibAttr.wMajorVerNum = LOWORD(m_pHeader->version); 1052 m_pITypeLib->LibAttr.wMinorVerNum = HIWORD(m_pHeader->version); 1053 m_pITypeLib->LibAttr.wLibFlags = (WORD) m_pHeader->flags & 0xffff; /* check mask */ 1054 1055 // name, eventually add to a hash table 1056 ParseName(m_pHeader->nameOffset, &m_pITypeLib->szName); 1057 dprintf((" reading library: \"%s\"", m_pITypeLib->szName)); 1058 1059 // help info 1060 m_pITypeLib->lHelpContext = m_pHeader->helpstringcontext; 1061 ParseString(m_pHeader->helpstring, &m_pITypeLib->szDocString); 1062 ParseString(m_pHeader->helpfile, &m_pITypeLib->szHelpFile); 1063 if (m_pHelpStringOff) 1064 ParseString(*m_pHelpStringOff, &m_pITypeLib->szHelpStringDll); 1065 1066 // Load Custom data 1067 ParseCustomData(m_pHeader->customDataOffset, &m_pITypeLib->pCustData); 1068 1069 // Load typedescriptions 1070 if (m_pSegDir->pTypedescTab.length > 0) 1071 { 1072 TLBTypedesc * pTd; 1073 TYPEDESC * pNew; 1074 TLBArray * pArray; 1075 ULONG clTd; 1076 ULONG ii; 1077 ULONG jj; 1078 1079 clTd = m_pSegDir->pTypedescTab.length / sizeof(TLBTypedesc); 1080 1081 // Preload (in case of forward references) 1082 for (ii = 0; ii < clTd; ii++) 1083 { 1084 pNew = new TYPEDESC; 1085 m_pITypeLib->pTypedesc.AddAtEnd(pNew); 1086 } 1087 1088 // Populate 1089 for (ii = 0, pTd = m_pTypedesc; ii < clTd; ii++, pTd++) 1090 { 1091 pNew = m_pITypeLib->pTypedesc[ii]; 1092 1093 pNew->vt = pTd->rec0 & VT_TYPEMASK; 1094 if ((pNew->vt == VT_PTR) || (pNew->vt == VT_SAFEARRAY)) 1095 { 1096 if (pTd->rec3 < 0) 1097 V_UNION(pNew, lptdesc) = &stndTypeDesc[pTd->rec2]; 1098 else 1099 V_UNION(pNew, lptdesc) = m_pITypeLib->pTypedesc[pTd->rec3 / 8]; 1100 } 1101 else if (pNew->vt == VT_CARRAY) 1102 { 1103 pArray = (TLBArray *)((char *)m_pArray + pTd->rec2); 1104 1105 V_UNION(pNew, lpadesc) = 1106 (tagARRAYDESC*) HeapAlloc(m_hHeap, 0, (sizeof(ARRAYDESC) 1107 + sizeof(SAFEARRAYBOUND) * (pArray->rec3 - 1))); 1108 1109 if (pArray->rec1 < 0) 1110 V_UNION(pNew,lpadesc)->tdescElem.vt= pArray->rec0 & VT_TYPEMASK; 1111 else 1112 V_UNION(pNew,lpadesc)->tdescElem = stndTypeDesc[pArray->rec0 / 8]; 1113 1114 V_UNION(pNew,lpadesc)->cDims = pArray->rec2; 1115 1116 INT * pInt = (INT *)(pArray + 1); 1117 1118 for (jj = 0; jj < pArray->rec2; jj++) 1119 { 1120 V_UNION(pNew,lpadesc)->rgbounds[jj].cElements = *pInt++; 1121 V_UNION(pNew,lpadesc)->rgbounds[jj].lLbound = *pInt++; 1122 } 1123 } 1124 else if (pNew->vt == VT_USERDEFINED) 1125 { 1126 V_UNION(pNew, hreftype) = MAKELONG(pTd->rec2, pTd->rec3); 1127 } 1128 } 1129 } 1130 1131 // Load Imported typelibs 1132 if (m_pSegDir->pImpFiles.length > 0) 1133 { 1134 TLBImpFile * pImpFile = m_pImpFile; 1135 TLBImpLib * pNew; 1136 ULONG recLen = 0; 1137 ULONG totLen = 0; 1138 ULONG size; 1139 1140 while(totLen < m_pSegDir->pImpFiles.length) 1141 { 1142 pNew = new TLBImpLib; 1143 pNew->offset = totLen; 1144 1145 ParseGuid(pImpFile->offGuid, &(pNew->guid)); 1146 1147 /* we are skipping some unknown info here */ 1148 1149 size = pImpFile->size >> 2; 1150 1151 pNew->name = (char *)HeapAlloc(m_hHeap, 0, size + 1); 1152 memcpy(pNew->name, pImpFile->name, size); 1153 1154 // Add to list 1155 m_pITypeLib->pImpLibs.AddAtEnd(pNew); 1156 1157 // Align to next 4 byte boundary... 1158 recLen = (sizeof(TLBImpFile) + size + 3) & 0xfffffffc; 1159 totLen += recLen; 1160 pImpFile = (TLBImpFile *)((char *)pImpFile + recLen); 758 1161 } 759 /* scode is not used: archaic win16 stuff FIXME: right? */ 760 (*pptfd)->funcdesc.cScodes = 0 ; 761 (*pptfd)->funcdesc.lprgscode = NULL ; 762 pptfd=&((*pptfd)->next); 763 recoffset += reclength; 764 } 765 } 766 static void TLB_DoVars(TLBContext *pcx, int cFuncs, int cVars, 767 int offset, TLBVarDesc ** pptvd) 768 { 769 int infolen, nameoffset, reclength; 770 char recbuf[256]; 771 TLBVarRecord * pVarRec=(TLBVarRecord *) recbuf; 772 int i; 773 int recoffset; 774 TLB_Read(&infolen,sizeof(INT), pcx, offset); 775 TLB_Read(&recoffset,sizeof(INT), pcx, offset + infolen + 776 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT)); 777 recoffset += offset+sizeof(INT); 778 for(i=0;i<cVars;i++){ 779 *pptvd=(TLBVarDesc*)TLB_Alloc(sizeof(TLBVarDesc)); 780 /* name, eventually add to a hash table */ 781 TLB_Read(&nameoffset, sizeof(INT), pcx, 782 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT)); 783 (*pptvd)->Name=TLB_ReadName(pcx, nameoffset); 784 /* read the variable information record */ 785 TLB_Read(&reclength, sizeof(INT), pcx, recoffset); 786 reclength &=0xff; 787 TLB_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 788 /* Optional data */ 789 if(reclength >(6*sizeof(INT)) ) 790 (*pptvd)->HelpContext=pVarRec->HelpContext; 791 if(reclength >(7*sizeof(INT)) ) 792 (*pptvd)->HelpString = TLB_ReadString(pcx, pVarRec->oHelpString) ; 793 if(reclength >(8*sizeof(INT)) ) 794 if(reclength >(9*sizeof(INT)) ) 795 (*pptvd)->HelpStringContext=pVarRec->HelpStringContext; 796 /* fill the VarDesc Structure */ 797 TLB_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx, 798 offset + infolen + ( i + 1) * sizeof(INT)); 799 (*pptvd)->vardesc.varkind = (tagVARKIND)pVarRec->VarKind; 800 (*pptvd)->vardesc.wVarFlags = pVarRec->Flags; 801 TLB_GetTdesc(pcx, pVarRec->DataType, 802 &(*pptvd)->vardesc.elemdescVar.tdesc) ; 803 /* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) fixme?? */ 804 if(pVarRec->VarKind == VAR_CONST ){ 805 V_UNION(&((*pptvd)->vardesc),lpvarValue)=(VARIANT*)TLB_Alloc(sizeof(VARIANT)); 806 TLB_ReadValue(V_UNION(&((*pptvd)->vardesc),lpvarValue), 807 pVarRec->OffsValue, pcx); 808 }else 809 V_UNION(&((*pptvd)->vardesc),oInst)=pVarRec->OffsValue; 810 pptvd=&((*pptvd)->next); 811 recoffset += reclength; 812 } 813 } 814 /* fill in data for a hreftype (offset). When the refernced type is contained 815 * in the typelib, its just an (file) offset in the type info base dir. 816 * If comes fom import, its an offset+1 in the ImpInfo table 817 * */ 818 static void TLB_DoRefType(TLBContext *pcx, 819 int offset, TLBRefType ** pprtd) 820 { 821 int j; 822 if(!HREFTYPE_INTHISFILE( offset)) { 823 /* external typelib */ 824 TLBImpInfo impinfo; 825 TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs); 826 TLB_Read(&impinfo, sizeof(impinfo), pcx, 827 pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc)); 828 for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */ 829 if(pImpLib->offset==impinfo.oImpFile) break; 830 pImpLib=pImpLib->next; 831 } 832 if(pImpLib){ 833 (*pprtd)->reference=offset; 834 (*pprtd)->pImpTLInfo=pImpLib; 835 TLB_ReadGuid(&(*pprtd)->guid, impinfo.oGuid, pcx); 836 }else{ 837 ERR_(typelib)("Cannot find a reference\n"); 838 (*pprtd)->reference=-1; 839 (*pprtd)->pImpTLInfo=(tagTLBImpLib*)-1; 840 } 841 }else{ 842 /* in this typelib */ 843 (*pprtd)->reference=offset; 844 (*pprtd)->pImpTLInfo=(tagTLBImpLib*)-2; 845 } 846 } 847 848 /* process Implemented Interfaces of a com class */ 849 static void TLB_DoImplTypes(TLBContext *pcx, int count, 850 int offset, TLBRefType ** pprtd) 851 { 852 int i; 853 TLBRefRecord refrec; 854 for(i=0;i<count;i++){ 855 if(offset<0) break; /* paranoia */ 856 *pprtd=(TLBRefType*)TLB_Alloc(sizeof(TLBRefType)); 857 TLB_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset); 858 TLB_DoRefType(pcx, refrec.reftype, pprtd); 859 (*pprtd)->flags=refrec.flags; 860 (*pprtd)->ctCustData= 861 TLB_CustData(pcx, refrec.oCustData, &(*pprtd)->pCustData); 862 offset=refrec.onext; 863 pprtd=&((*pprtd)->next); 864 } 865 } 866 /* 867 * process a typeinfo record 868 */ 869 TLBTypeInfo * TLB_DoTypeInfo(TLBContext *pcx, int count, TLBLibInfo* pLibInfo) 870 { 871 TLBTypeInfoBase tiBase; 872 TLBTypeInfo *ptiRet; 873 ptiRet=(TLBTypeInfo*)TLB_Alloc(sizeof(TLBTypeInfo)); 874 ptiRet->lpvtbl = &tinfvt; 875 ptiRet->ref=1; 876 TLB_Read(&tiBase, sizeof(tiBase) ,pcx , 877 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase)); 878 /* this where we are coming from */ 879 ptiRet->pTypeLib=pLibInfo; 880 ptiRet->index=count; 881 /* fill in the typeattr fields */ 882 TLB_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx); 883 ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */ 884 ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */ 885 ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */ 886 ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */ 887 ptiRet->TypeAttr.cbSizeInstance=tiBase.size; 888 ptiRet->TypeAttr.typekind=(tagTYPEKIND)(tiBase.typekind & 0xF); 889 ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement); 890 ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement); 891 ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */ 892 ptiRet->TypeAttr.wTypeFlags=tiBase.flags; 893 ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version); 894 ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version); 895 ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes; 896 ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */ 897 if(ptiRet->TypeAttr.typekind == TKIND_ALIAS) 898 TLB_GetTdesc(pcx, tiBase.datatype1, 899 &ptiRet->TypeAttr.tdescAlias) ; 900 /* FIXME: */ 901 /* IDLDESC idldescType; *//* never saw this one != zero */ 902 903 /* name, eventually add to a hash table */ 904 ptiRet->Name=TLB_ReadName(pcx, tiBase.NameOffset); 905 TRACE_(typelib)("reading %s\n", ptiRet->Name); 906 /* help info */ 907 ptiRet->DocString=TLB_ReadString(pcx, tiBase.docstringoffs); 908 ptiRet->dwHelpStringContext=tiBase.helpstringcontext; 909 ptiRet->dwHelpContext=tiBase.helpcontext; 910 /* note: InfoType's Help file and HelpStringDll come from the containing 911 * library. Further HelpString and Docstring appear to be the same thing :( 912 */ 913 /* functions */ 914 if(ptiRet->TypeAttr.cFuncs >0 ) 915 TLB_DoFuncs(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars, 916 tiBase.memoffset, & ptiRet->funclist); 917 /* variables */ 918 if(ptiRet->TypeAttr.cVars >0 ) 919 TLB_DoVars(pcx, ptiRet->TypeAttr.cFuncs ,ptiRet->TypeAttr.cVars, 920 tiBase.memoffset, & ptiRet->varlist); 921 if(ptiRet->TypeAttr.cImplTypes >0 ){ 922 if(ptiRet->TypeAttr.typekind == TKIND_COCLASS) 923 TLB_DoImplTypes(pcx, ptiRet->TypeAttr.cImplTypes , 924 tiBase.datatype1, & ptiRet->impltypelist); 925 else if(ptiRet->TypeAttr.typekind != TKIND_DISPATCH){ 926 ptiRet->impltypelist=(TLBRefType*)TLB_Alloc(sizeof(TLBRefType)); 927 TLB_DoRefType(pcx, tiBase.datatype1, & ptiRet->impltypelist); 928 } 1162 } 1163 1164 // Load Type info data 1165 if (m_pHeader->nrtypeinfos >=0 ) 1166 { 1167 ULONG ii; 1168 ITypeInfoImpl * pNew; 1169 TLBTypeInfoBase * pBase = m_pTypeInfo; 1170 1171 for (ii = 0; ii < m_pHeader->nrtypeinfos; ii++) 1172 { 1173 TLBTypeInfoBase * pBase = (TLBTypeInfoBase *) 1174 ((char *)m_pTypeInfo + m_pTypeInfoDir[ii]); 1175 pNew = ITypeInfoImpl_Constructor(); 1176 pNew->pTypeLib = (ITypeLib *)m_pITypeLib; 1177 pNew->index = ii; 1178 1179 ParseTypeInfo(pNew, pBase); 1180 1181 m_pITypeLib->pTypeInfo.AddAtEnd(pNew); 929 1182 } 930 ptiRet->ctCustData= 931 TLB_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData); 932 return ptiRet; 933 } 934 935 // ---------------------------------------------------------------------- 936 // TLB_FindMagic 937 // ---------------------------------------------------------------------- 938 static int TLB_FindMagic(TLBContext *pcx, char * pMagic) 939 { 940 long lBlkSize = 1024; // Block size 941 long lCurrentPos = 0; // Current search pos in file. 942 DWORD lFileSize; // Size of file to be searched. 943 long lDataSize; // Bytes last read. 944 long lNoBlocks; // Remaining blocks to scan. 945 long ll; 946 int fFound; // Found flag 947 char * pBuf; // Allow room for a trailing '\0' 948 HANDLE hHeap; // Heap Handle 949 int iLen = strlen(pMagic); // Length of search string 950 951 // Get a search buffer... 952 hHeap = GetProcessHeap(); 953 pBuf = (char *)HeapAlloc(hHeap, 0, lBlkSize * 2); 954 955 // Calc search params... 956 lFileSize = GetFileSize(pcx->hFile, NULL); 957 lNoBlocks = lFileSize / lBlkSize; 958 fFound = FALSE; 959 960 // Read first block... 961 lDataSize = TLB_Read(pBuf, lBlkSize, pcx, 0); 962 963 // Loop through blocks searching for target string... 964 // Two blocks are stored to simplify boundary checking. 965 // NB lNoBlocks is zero where the file fits into one block, 966 // so this is skipped 967 while((lNoBlocks > 0) && !fFound) 968 { 969 lNoBlocks -= 1; 970 lDataSize = TLB_Read(pBuf + lBlkSize, lBlkSize, pcx, DO_NOT_SEEK); 971 972 for (ll = 0; ll < lBlkSize; ll++) 973 { 974 if (strncmp(pBuf + ll, pMagic, iLen) == 0) 975 { 976 fFound = TRUE; 977 break; 978 } 979 lCurrentPos += 1; // Keep track of posn. 980 } 981 // Copy block2 to block1 982 memcpy(pBuf, pBuf + lBlkSize, lDataSize); 983 } 984 985 // Now search last block... 986 if (!fFound) 987 { 988 for (ll = 0; ll < (lDataSize - iLen); ll++) 989 { 990 if (strncmp(pBuf + ll, pMagic, iLen) == 0) 991 { 992 fFound = TRUE; 993 break; 994 } 995 lCurrentPos += 1; // Keep track of posn. 996 } 997 } 998 999 // Loose buffer. 1000 HeapFree(hHeap, 0, pBuf); 1001 1002 if (fFound) 1003 return lCurrentPos; 1004 1005 return 0; 1006 } 1007 1008 // ---------------------------------------------------------------------- 1009 // TLB_FindTlb 1010 // ---------------------------------------------------------------------- 1011 long TLB_FindTlb(TLBContext *pcx) 1012 { 1013 long lPosn; 1014 1015 lPosn = TLB_FindMagic(pcx, TLBMAGIC2 ); 1016 if (lPosn != 0) 1017 { 1018 dprintf(("OLEAUT32: TLB_FindTlb - Located MAGIC2 @%lx", lPosn)); 1019 return lPosn; 1020 } 1021 1022 lPosn = TLB_FindMagic(pcx, TLBMAGIC1 ); 1023 if (lPosn != 0) 1024 { 1025 dprintf(("OLEAUT32: TLB_FindTlb - Located MAGIC1 @%lx", lPosn)); 1026 dprintf(("OLEAUT32: ERROR UNSUPPORTED TYPELIB!")); 1027 return -1; 1028 } 1029 1030 dprintf(("OLEAUT32: TLB_FindTlb ERROR: NO TYPELIB FOUND")); 1031 return -1; 1032 } 1033 1034 // ---------------------------------------------------------------------- 1035 // TLB_ReadTypeLib 1036 // ---------------------------------------------------------------------- 1037 int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypeLib) 1038 { 1039 TLBContext cx; 1040 OFSTRUCT ofStruct; 1041 long oStart , lPSegDir; 1042 TLBLibInfo * pLibInfo = NULL; 1043 TLB2Header tlbHeader; 1044 TLBSegDir tlbSegDir; 1045 1046 if((cx.hFile = OpenFile(file, &ofStruct, OF_READ))==HFILE_ERROR) 1047 { 1048 ERR_(typelib)("cannot open %s error0x%lx\n",file, GetLastError()); 1049 return E_FAIL; 1050 } 1051 /* get pointer to beginning of typelib data */ 1052 oStart = TLB_FindTlb( & cx); 1053 if(oStart < 0) 1054 { 1055 ERR_(typelib)("cannot locate typelib in %s\n",file); 1056 return E_FAIL; 1057 } 1058 cx.oStart = oStart; 1059 pLibInfo=(TLBLibInfo*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TLBLibInfo)); 1060 if (!pLibInfo){ 1061 CloseHandle(cx.hFile); 1062 return E_OUTOFMEMORY; 1063 } 1064 pLibInfo->lpvtbl = &tlbvt; 1065 pLibInfo->ref=1; 1066 cx.pLibInfo=pLibInfo; 1067 /* read header */ 1068 TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, oStart); 1069 /* there is a small number of information here until the next important 1070 * part: 1071 * the segment directory . Try to calculate the amount of data */ 1072 lPSegDir=sizeof(tlbHeader)+ 1073 (tlbHeader.nrtypeinfos)*4+ 1074 (tlbHeader.varflags & HELPDLLFLAG? 4 :0); 1075 /* now read the segment directory */ 1076 TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, oStart + lPSegDir); 1077 cx.pTblDir=&tlbSegDir; 1078 /* just check two entries */ 1079 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || 1080 tlbSegDir.pImpInfo.res0c != 0x0F 1081 ) { 1082 ERR_(typelib)("cannot find the table directory, ptr=0x%lx\n",lPSegDir); 1083 CloseHandle(cx.hFile); 1084 return E_FAIL; 1085 } 1086 /* now fill our internal data */ 1087 /* TLIBATTR fields */ 1088 TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx); 1089 pLibInfo->LibAttr.lcid=tlbHeader.lcid; 1090 pLibInfo->LibAttr.syskind=(tagSYSKIND)(tlbHeader.varflags & 0x0f); /* check the mask */ 1091 pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version); 1092 pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version); 1093 pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */ 1094 /* name, eventually add to a hash table */ 1095 pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset); 1096 /* help info */ 1097 pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring); 1098 pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile); 1099 if( tlbHeader.varflags & HELPDLLFLAG){ 1100 int offset; 1101 TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader)); 1102 pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset); 1103 } 1104 1105 pLibInfo->dwHelpContext=tlbHeader.helpstringcontext; 1106 /* custom data */ 1107 if(tlbHeader.CustomDataOffset >= 0) { 1108 pLibInfo->ctCustData= 1109 TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData); 1110 } 1111 /* fill in typedescriptions */ 1112 if(tlbSegDir.pTypdescTab.length >0){ 1113 int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT)); 1114 INT16 td[4]; 1115 pLibInfo->pTypeDesc=(TYPEDESC*) 1116 TLB_Alloc( cTD * sizeof(TYPEDESC)); 1117 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset); 1118 for(i=0;i<cTD;){ 1119 /* FIXME: add several sanity checks here */ 1120 pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK; 1121 if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */ 1122 if(td[3]<0) 1123 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)= 1124 & stndTypeDesc[td[2]]; 1125 else 1126 V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)= 1127 & pLibInfo->pTypeDesc[td[3]/8]; 1128 }else if(td[0]==VT_CARRAY) 1129 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)= 1130 (tagARRAYDESC*)((int) td[2]); /* temp store offset in*/ 1131 /* array descr table here */ 1132 else if(td[0]==VT_USERDEFINED) 1133 V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]); 1134 if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK); 1135 } 1136 /* second time around to fill the array subscript info */ 1137 for(i=0;i<cTD;i++){ 1138 if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue; 1139 if(tlbSegDir.pArrayDescriptions.offset>0){ 1140 TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + 1141 (int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)); 1142 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=(tagARRAYDESC*) 1143 TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1)); 1144 if(td[1]<0) 1145 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK; 1146 else 1147 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8]; 1148 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2]; 1149 for(j=0;j<td[2];j++){ 1150 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements, 1151 sizeof(INT), &cx, DO_NOT_SEEK); 1152 TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc) 1153 ->rgbounds[j].lLbound, 1154 sizeof(INT), &cx, DO_NOT_SEEK); 1155 } 1156 }else{ 1157 V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL; 1158 ERR_(ole)("didn't find array description data\n"); 1159 } 1160 } 1161 } 1162 /* imported type libs */ 1163 if(tlbSegDir.pImpFiles.offset>0){ 1164 TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs); 1165 int offset=tlbSegDir.pImpFiles.offset; 1166 int oGuid; 1167 UINT16 size; 1168 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){ 1169 *ppImpLib=(TLBImpLib*)TLB_Alloc(sizeof(TLBImpLib)); 1170 (*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset; 1171 TLB_Read(&oGuid, sizeof(INT), &cx, offset); 1172 TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx); 1173 /* we are skipping some unknown info here */ 1174 TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT))); 1175 size >>=2; 1176 (*ppImpLib)->name=(CHAR*)TLB_Alloc(size+1); 1177 TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK); 1178 offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc; 1179 1180 ppImpLib=&(*ppImpLib)->next; 1181 } 1182 } 1183 /* type info's */ 1184 if(tlbHeader.nrtypeinfos >=0 ){ 1185 /*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */ 1186 TLBTypeInfo **ppTI=&(pLibInfo->pTypeInfo); 1187 int i; 1188 for(i=0;i<(int)tlbHeader.nrtypeinfos;i++){ 1189 *ppTI=TLB_DoTypeInfo(&cx, i, pLibInfo); 1190 ppTI=&((*ppTI)->next); 1191 (pLibInfo->TypeInfoCount)++; 1192 } 1193 } 1194 1195 CloseHandle(cx.hFile); 1196 *ppTypeLib=(LPTYPELIB)pLibInfo; 1183 } 1184 1197 1185 return S_OK; 1198 1186 } 1199 1187 1200 /*================== ITypeLib(2) Methods ===================================*/ 1201 1202 /* ITypeLib::QueryInterface 1203 */ 1204 static HRESULT WINAPI ITypeLib_fnQueryInterface( LPTYPELIB This, REFIID riid, 1205 VOID **ppvObject) 1206 { 1207 if(TRACE_ON(typelib)){ 1208 char xriid[50]; 1209 WINE_StringFromCLSID((LPCLSID)riid,xriid); 1210 TRACE_(typelib)("(%p)->(IID: %s)\n",This,xriid); 1211 } 1212 *ppvObject=NULL; 1213 if(IsEqualIID(riid, &IID_IUnknown) || 1214 IsEqualIID(riid,&IID_ITypeLib)|| 1215 IsEqualIID(riid,&IID_ITypeLib2)) 1216 *ppvObject = This; 1217 if(*ppvObject){ 1218 (ICOM_VTBL(*(LPTYPELIB*)ppvObject))->fnAddRef(This); 1219 TRACE_(typelib)("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); 1220 return S_OK; 1221 } 1222 TRACE_(typelib)("-- Interface: E_NOINTERFACE\n"); 1223 return E_NOINTERFACE; 1224 } 1225 1226 /* ITypeLib::AddRef 1227 */ 1228 static ULONG WINAPI ITypeLib_fnAddRef( LPTYPELIB iface) 1229 { 1230 ICOM_THIS( TLBLibInfo, iface); 1231 TRACE_(typelib)("(%p)->ref is %u\n",This, This->ref); 1232 return ++(This->ref); 1233 } 1234 1235 /* ITypeLib::Release 1236 */ 1237 static ULONG WINAPI ITypeLib_fnRelease( LPTYPELIB iface) 1238 { 1239 ICOM_THIS( TLBLibInfo, iface); 1240 FIXME_(typelib)("(%p)->ref is %u: stub\n",This, This->ref); 1241 (This->ref)--; 1242 return S_OK; 1243 } 1244 1245 /* ITypeLib::GetTypeInfoCount 1246 * 1247 * Returns the number of type descriptions in the type library 1248 */ 1249 static UINT WINAPI ITypeLib_fnGetTypeInfoCount( LPTYPELIB iface) 1250 { 1251 ICOM_THIS( TLBLibInfo, iface); 1252 TRACE_(typelib)("(%p)->count is %d\n",This, This->TypeInfoCount); 1253 return This->TypeInfoCount; 1254 } 1255 1256 /* ITypeLib::GetTypeInfo 1257 * 1258 *etrieves the specified type description in the library. 1259 */ 1260 static HRESULT WINAPI ITypeLib_fnGetTypeInfo( LPTYPELIB iface, UINT index, 1261 ITypeInfo **ppTInfo) 1262 { 1263 int i; 1264 ICOM_THIS( TLBLibInfo, iface); 1265 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo; 1266 TRACE_(typelib)("(%p) index %d \n",This, index); 1267 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && i != index;i++) 1268 *ppTLBTInfo=(*ppTLBTInfo)->next; 1269 if(*ppTLBTInfo){ 1270 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo); 1271 TRACE_(typelib)("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo); 1272 return S_OK; 1273 } 1274 TRACE_(typelib)("-- element not found\n"); 1275 return TYPE_E_ELEMENTNOTFOUND; 1276 } 1277 1278 /* ITypeLibs::GetTypeInfoType 1279 * 1280 * Retrieves the type of a type description. 1281 */ 1282 static HRESULT WINAPI ITypeLib_fnGetTypeInfoType( LPTYPELIB iface, UINT index, 1283 TYPEKIND *pTKind) 1284 { 1285 int i; 1286 TLBTypeInfo *pTInfo; 1287 ICOM_THIS( TLBLibInfo, iface); 1288 TRACE_(typelib)("(%p) index %d \n",This, index); 1289 for(i=0,pTInfo=This->pTypeInfo;pTInfo && i != index;i++) 1290 pTInfo=(pTInfo)->next; 1291 if(pTInfo){ 1292 *pTKind=pTInfo->TypeAttr.typekind; 1293 TRACE_(typelib)("-- found Type (%p)->%d\n",pTKind,*pTKind); 1294 return S_OK; 1295 } 1296 TRACE_(typelib)("-- element not found\n"); 1297 return TYPE_E_ELEMENTNOTFOUND; 1298 } 1299 1300 /* ITypeLib::GetTypeInfoOfGuid 1301 * 1302 * Retrieves the type description that corresponds to the specified GUID. 1303 * 1304 */ 1305 static HRESULT WINAPI ITypeLib_fnGetTypeInfoOfGuid( LPTYPELIB iface, 1306 REFGUID guid, ITypeInfo **ppTInfo) 1307 { 1308 int i; 1309 ICOM_THIS( TLBLibInfo, iface); 1310 TLBTypeInfo **ppTLBTInfo=(TLBTypeInfo **)ppTInfo; 1311 if(TRACE_ON(typelib)){ 1312 char xriid[50]; 1313 WINE_StringFromCLSID((LPCLSID)guid,xriid); 1314 TRACE_(typelib)("(%p) guid %sx)\n",This,xriid); 1315 } 1316 for(i=0,*ppTLBTInfo=This->pTypeInfo;*ppTLBTInfo && 1317 !IsEqualIID(guid,&(*ppTLBTInfo)->TypeAttr.guid);i++) 1318 *ppTLBTInfo=(*ppTLBTInfo)->next; 1319 if(*ppTLBTInfo){ 1320 (*ppTLBTInfo)->lpvtbl->fnAddRef(*ppTInfo); 1321 TRACE_(typelib)("-- found (%p)->(%p)\n",ppTLBTInfo,*ppTLBTInfo); 1322 return S_OK; 1323 } 1324 TRACE_(typelib)("-- element not found\n"); 1325 return TYPE_E_ELEMENTNOTFOUND; 1326 } 1327 1328 /* ITypeLib::GetLibAttr 1329 * 1330 * Retrieves the structure that contains the library's attributes. 1331 * 1332 */ 1333 static HRESULT WINAPI ITypeLib_fnGetLibAttr( LPTYPELIB iface, 1334 LPTLIBATTR *ppTLibAttr) 1335 { 1336 ICOM_THIS( TLBLibInfo, iface); 1337 TRACE_(typelib)("(%p)\n",This); 1338 /* FIXME: must do a copy here */ 1339 *ppTLibAttr=&This->LibAttr; 1340 return S_OK; 1341 } 1342 1343 /* ITypeLib::GetTypeComp 1344 * 1345 * Enables a client compiler to bind to a library's types, variables, 1346 * constants, and global functions. 1347 * 1348 */ 1349 static HRESULT WINAPI ITypeLib_fnGetTypeComp( LPTYPELIB iface, 1350 ITypeComp **ppTComp) 1351 { 1352 ICOM_THIS( TLBLibInfo, iface); 1353 FIXME_(typelib)("(%p): stub!\n",This); 1354 return E_NOTIMPL; 1355 } 1356 1357 /* ITypeLib::GetDocumentation 1358 * 1359 * Retrieves the library's documentation string, the complete Help file name 1360 * and path, and the context identifier for the library Help topic in the Help 1361 * file. 1362 * 1363 */ 1364 static HRESULT WINAPI ITypeLib_fnGetDocumentation( LPTYPELIB iface, INT index, 1365 BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, 1366 BSTR *pBstrHelpFile) 1367 { 1368 ICOM_THIS( TLBLibInfo, iface); 1369 HRESULT result; 1370 ITypeInfo *pTInfo; 1371 TRACE_(typelib)("(%p) index %d Name(%p) DocString(%p)" 1372 " HelpContext(%p) HelpFile(%p)\n", 1373 This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); 1374 if(index<0){ /* documentation for the typelib */ 1375 if(pBstrName) 1376 *pBstrName=TLB_DupAtoBstr(This->Name); 1377 if(pBstrDocString) 1378 *pBstrName=TLB_DupAtoBstr(This->DocString); 1379 if(pdwHelpContext) 1380 *pdwHelpContext=This->dwHelpContext; 1381 if(pBstrHelpFile) 1382 *pBstrName=TLB_DupAtoBstr(This->HelpFile); 1383 }else {/* for a typeinfo */ 1384 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo); 1385 if(SUCCEEDED(result)){ 1386 result=ITypeInfo_GetDocumentation(pTInfo, MEMBERID_NIL, pBstrName, 1387 pBstrDocString, pdwHelpContext, pBstrHelpFile); 1388 ITypeInfo_Release(pTInfo); 1389 } 1390 if(!SUCCEEDED(result)) 1391 return result; 1392 } 1393 return S_OK; 1394 } 1395 1396 /* ITypeLib::IsName 1397 * 1398 * Indicates whether a passed-in string contains the name of a type or member 1399 * described in the library. 1400 * 1401 */ 1402 static HRESULT WINAPI ITypeLib_fnIsName( LPTYPELIB iface, LPOLESTR szNameBuf, 1403 ULONG lHashVal, BOOL *pfName) 1404 { 1405 ICOM_THIS( TLBLibInfo, iface); 1406 TLBTypeInfo *pTInfo; 1407 TLBFuncDesc *pFInfo; 1408 TLBVarDesc *pVInfo; 1409 int i; 1410 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf ); 1411 *pfName=TRUE; 1412 if(!strcmp(astr,This->Name)) goto ITypeLib_fnIsName_exit; 1413 for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){ 1414 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnIsName_exit; 1415 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { 1416 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnIsName_exit; 1417 for(i=0;i<pFInfo->funcdesc.cParams;i++) 1418 if(!strcmp(astr,pFInfo->pParamDesc[i].Name)) 1419 goto ITypeLib_fnIsName_exit; 1420 } 1421 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ; 1422 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnIsName_exit; 1423 1424 } 1425 *pfName=FALSE; 1426 1427 ITypeLib_fnIsName_exit: 1428 TRACE_(typelib)("(%p)slow! search for %s: %s found!\n", This, 1429 debugstr_a(astr), *pfName?"NOT":""); 1430 1431 HeapFree( GetProcessHeap(), 0, astr ); 1432 return S_OK; 1433 } 1434 1435 /* ITypeLib::FindName 1436 * 1437 * Finds occurrences of a type description in a type library. This may be used 1438 * to quickly verify that a name exists in a type library. 1439 * 1440 */ 1441 static HRESULT WINAPI ITypeLib_fnFindName( LPTYPELIB iface, LPOLESTR szNameBuf, 1442 ULONG lHashVal, ITypeInfo **ppTInfo, MEMBERID *rgMemId, UINT16 *pcFound) 1443 { 1444 ICOM_THIS( TLBLibInfo, iface); 1445 TLBTypeInfo *pTInfo; 1446 TLBFuncDesc *pFInfo; 1447 TLBVarDesc *pVInfo; 1448 int i,j = 0; 1449 PCHAR astr= HEAP_strdupWtoA( GetProcessHeap(), 0, szNameBuf ); 1450 for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){ 1451 if(!strcmp(astr,pTInfo->Name)) goto ITypeLib_fnFindName_exit; 1452 for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { 1453 if(!strcmp(astr,pFInfo->Name)) goto ITypeLib_fnFindName_exit; 1454 for(i=0;i<pFInfo->funcdesc.cParams;i++) 1455 if(!strcmp(astr,pFInfo->pParamDesc[i].Name)) 1456 goto ITypeLib_fnFindName_exit; 1457 } 1458 for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) ; 1459 if(!strcmp(astr,pVInfo->Name)) goto ITypeLib_fnFindName_exit; 1460 continue; 1461 ITypeLib_fnFindName_exit: 1462 pTInfo->lpvtbl->fnAddRef((LPTYPEINFO)pTInfo); 1463 ppTInfo[j]=(LPTYPEINFO)pTInfo; 1464 j++; 1465 } 1466 TRACE_(typelib)("(%p)slow! search for %d with %s: found %d TypeInfo's!\n", 1467 This, *pcFound, debugstr_a(astr), j); 1468 1469 *pcFound=j; 1470 1471 HeapFree( GetProcessHeap(), 0, astr ); 1472 return S_OK; 1473 } 1474 1475 /* ITypeLib::ReleaseTLibAttr 1476 * 1477 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr. 1478 * 1479 */ 1480 static VOID WINAPI ITypeLib_fnReleaseTLibAttr( LPTYPELIB iface, TLIBATTR *pTLibAttr) 1481 { 1482 ICOM_THIS( TLBLibInfo, iface); 1483 TRACE_(typelib)("freeing (%p)\n",This); 1484 /* nothing to do */ 1485 } 1486 1487 /* ITypeLib2::GetCustData 1488 * 1489 * gets the custom data 1490 */ 1491 static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLib * iface, REFGUID guid, 1492 VARIANT *pVarVal) 1493 { 1494 ICOM_THIS( TLBLibInfo, iface); 1495 TLBCustData *pCData; 1496 for(pCData=This->pCustData; pCData; pCData = pCData->next) 1497 if( IsEqualIID(guid, &pCData->guid)) break; 1498 if(TRACE_ON(typelib)){ 1499 char xriid[50]; 1500 WINE_StringFromCLSID((LPCLSID)guid,xriid); 1501 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid, 1502 pCData? "" : "NOT"); 1503 } 1504 if(pCData){ 1505 VariantInit( pVarVal); 1506 VariantCopy( pVarVal, &pCData->data); 1507 return S_OK; 1508 } 1509 return E_INVALIDARG; /* FIXME: correct? */ 1510 } 1511 1512 /* ITypeLib2::GetLibStatistics 1513 * 1514 * Returns statistics about a type library that are required for efficient 1515 * sizing of hash tables. 1516 * 1517 */ 1518 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( ITypeLib * iface, 1519 UINT *pcUniqueNames, UINT *pcchUniqueNames) 1520 { 1521 ICOM_THIS( TLBLibInfo, iface); 1522 FIXME_(typelib)("(%p): stub!\n", This); 1523 if(pcUniqueNames) *pcUniqueNames=1; 1524 if(pcchUniqueNames) *pcchUniqueNames=1; 1525 return S_OK; 1526 } 1527 1528 /* ITypeLib2::GetDocumentation2 1529 * 1530 * Retrieves the library's documentation string, the complete Help file name 1531 * and path, the localization context to use, and the context ID for the 1532 * library Help topic in the Help file. 1533 * 1534 */ 1535 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( ITypeLib * iface, 1536 INT index, LCID lcid, BSTR *pbstrHelpString, 1537 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll) 1538 { 1539 ICOM_THIS( TLBLibInfo, iface); 1540 HRESULT result; 1541 ITypeInfo *pTInfo; 1542 FIXME_(typelib)("(%p) index %d lcid %ld half implemented stub!\n", This, 1543 index, lcid); 1544 /* the help string should be obtained from the helpstringdll, 1545 * using the _DLLGetDocumentation function, based on the supplied 1546 * lcid. Nice to do sometime... 1547 */ 1548 if(index<0){ /* documentation for the typelib */ 1549 if(pbstrHelpString) 1550 *pbstrHelpString=TLB_DupAtoBstr(This->DocString); 1551 if(pdwHelpStringContext) 1552 *pdwHelpStringContext=This->dwHelpContext; 1553 if(pbstrHelpStringDll) 1554 *pbstrHelpStringDll=TLB_DupAtoBstr(This->HelpStringDll); 1555 }else {/* for a typeinfo */ 1556 result=ITypeLib_fnGetTypeInfo(iface, index, &pTInfo); 1557 if(SUCCEEDED(result)){ 1558 result=ITypeInfo2_fnGetDocumentation2(pTInfo, MEMBERID_NIL, lcid, 1559 pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll); 1560 ITypeInfo_Release(pTInfo); 1561 } 1562 if(!SUCCEEDED(result)) 1563 return result; 1564 } 1565 return S_OK; 1566 } 1567 1568 /* ITypeLib2::GetAllCustData 1569 * 1570 * Gets all custom data items for the library. 1571 * 1572 */ 1573 static HRESULT WINAPI ITypeLib2_fnGetAllCustData( ITypeLib * iface, 1574 CUSTDATA *pCustData) 1575 { 1576 ICOM_THIS( TLBLibInfo, iface); 1577 TLBCustData *pCData; 1578 int i; 1579 TRACE_(typelib)("(%p) returning %d items\n", This, This->ctCustData); 1580 pCustData->prgCustData = (tagCUSTDATAITEM*)TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); 1581 if(pCustData->prgCustData ){ 1582 pCustData->cCustData=This->ctCustData; 1583 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ 1584 pCustData->prgCustData[i].guid=pCData->guid; 1585 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); 1586 } 1587 }else{ 1588 ERR_(typelib)(" OUT OF MEMORY! \n"); 1589 return E_OUTOFMEMORY; 1590 } 1591 return S_OK; 1592 } 1593 1594 1595 /*================== ITypeInfo(2) Methods ===================================*/ 1596 1597 /* ITypeInfo::QueryInterface 1598 */ 1599 static HRESULT WINAPI ITypeInfo_fnQueryInterface( LPTYPEINFO iface, REFIID riid, 1600 VOID **ppvObject) 1601 { 1602 ICOM_THIS( TLBTypeInfo, iface); 1603 if(TRACE_ON(typelib)){ 1604 char xriid[50]; 1605 WINE_StringFromCLSID((LPCLSID)riid,xriid); 1606 TRACE_(typelib)("(%p)->(IID: %s)\n",This,xriid); 1607 } 1608 *ppvObject=NULL; 1609 if(IsEqualIID(riid, &IID_IUnknown) || 1610 IsEqualIID(riid,&IID_ITypeInfo)|| 1611 IsEqualIID(riid,&IID_ITypeInfo2)) 1612 *ppvObject = This; 1613 if(*ppvObject){ 1614 (ICOM_VTBL(*(LPTYPEINFO*)ppvObject))->fnAddRef(iface); 1615 TRACE_(typelib)("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); 1616 return S_OK; 1617 } 1618 TRACE_(typelib)("-- Interface: E_NOINTERFACE\n"); 1619 return E_NOINTERFACE; 1620 } 1621 1622 /* ITypeInfo::AddRef 1623 */ 1624 static ULONG WINAPI ITypeInfo_fnAddRef( LPTYPEINFO iface) 1625 { 1626 ICOM_THIS( TLBTypeInfo, iface); 1627 TRACE_(typelib)("(%p)->ref is %u\n",This, This->ref); 1628 (This->pTypeLib->ref)++; 1629 return ++(This->ref); 1630 } 1631 1632 /* ITypeInfo::Release 1633 */ 1634 static ULONG WINAPI ITypeInfo_fnRelease( LPTYPEINFO iface) 1635 { 1636 ICOM_THIS( TLBTypeInfo, iface); 1637 FIXME_(typelib)("(%p)->ref is %u: stub\n",This, This->ref); 1638 (This->ref)--; 1639 (This->pTypeLib->ref)--; 1640 return S_OK; 1641 } 1642 1643 /* ITypeInfo::GetTypeAttr 1644 * 1645 * Retrieves a TYPEATTR structure that contains the attributes of the type 1646 * description. 1647 * 1648 */ 1649 static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( LPTYPEINFO iface, 1650 LPTYPEATTR *ppTypeAttr) 1651 { 1652 ICOM_THIS( TLBTypeInfo, iface); 1653 TRACE_(typelib)("(%p)\n",This); 1654 /* FIXME: must do a copy here */ 1655 *ppTypeAttr=&This->TypeAttr; 1656 return S_OK; 1657 } 1658 1659 /* ITypeInfo::GetTypeComp 1660 * 1661 * Retrieves the ITypeComp interface for the type description, which enables a 1662 * client compiler to bind to the type description's members. 1663 * 1664 */ 1665 static HRESULT WINAPI ITypeInfo_fnGetTypeComp( LPTYPEINFO iface, 1666 ITypeComp * *ppTComp) 1667 { 1668 ICOM_THIS( TLBTypeInfo, iface); 1669 FIXME_(typelib)("(%p) stub!\n", This); 1670 return S_OK; 1671 } 1672 1673 /* ITypeInfo::GetFuncDesc 1674 * 1675 * Retrieves the FUNCDESC structure that contains information about a 1676 * specified function. 1677 * 1678 */ 1679 static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( LPTYPEINFO iface, UINT index, 1680 LPFUNCDESC *ppFuncDesc) 1681 { 1682 ICOM_THIS( TLBTypeInfo, iface); 1683 int i; 1684 TLBFuncDesc * pFDesc; 1685 TRACE_(typelib)("(%p) index %d\n", This, index); 1686 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next) 1687 ; 1688 if(pFDesc){ 1689 /* FIXME: must do a copy here */ 1690 *ppFuncDesc=&pFDesc->funcdesc; 1691 return S_OK; 1692 } 1693 return E_INVALIDARG; 1694 } 1695 1696 /* ITypeInfo::GetVarDesc 1697 * 1698 * Retrieves a VARDESC structure that describes the specified variable. 1699 * 1700 */ 1701 static HRESULT WINAPI ITypeInfo_fnGetVarDesc( LPTYPEINFO iface, UINT index, 1702 LPVARDESC *ppVarDesc) 1703 { 1704 ICOM_THIS( TLBTypeInfo, iface); 1705 int i; 1706 TLBVarDesc * pVDesc; 1707 TRACE_(typelib)("(%p) index %d\n", This, index); 1708 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next) 1709 ; 1710 if(pVDesc){ 1711 /* FIXME: must do a copy here */ 1712 *ppVarDesc=&pVDesc->vardesc; 1713 return S_OK; 1714 } 1715 return E_INVALIDARG; 1716 } 1717 1718 /* ITypeInfo_GetNames 1719 * 1720 * Retrieves the variable with the specified member ID (or the name of the 1721 * property or method and its parameters) that correspond to the specified 1722 * function ID. 1723 */ 1724 static HRESULT WINAPI ITypeInfo_fnGetNames( LPTYPEINFO iface, MEMBERID memid, 1725 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) 1726 { 1727 ICOM_THIS( TLBTypeInfo, iface); 1728 TLBFuncDesc * pFDesc; 1729 TLBVarDesc * pVDesc; 1730 int i; 1731 TRACE_(typelib)("(%p) memid=0x%08lx Maxname=%d\n", This, memid, 1732 cMaxNames); 1733 for(pFDesc=This->funclist; pFDesc->funcdesc.memid != memid && pFDesc; 1734 pFDesc=pFDesc->next) 1735 ; 1736 if(pFDesc){ 1737 /* function found, now return function and parameter names */ 1738 for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++){ 1739 if(!i) *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name); 1740 else 1741 rgBstrNames[i]=TLB_DupAtoBstr(pFDesc->pParamDesc[i-1].Name); 1742 1743 } 1744 *pcNames=i; 1745 }else{ 1746 for(pVDesc=This->varlist; pVDesc->vardesc.memid != memid && pVDesc; 1747 pVDesc=pVDesc->next) 1748 ; 1749 if(pVDesc){ 1750 *rgBstrNames=TLB_DupAtoBstr(pFDesc->Name); 1751 *pcNames=1; 1752 }else{ 1753 if(This->TypeAttr.typekind==TKIND_INTERFACE && 1754 This->TypeAttr.cImplTypes ){ 1755 /* recursive search */ 1756 ITypeInfo *pTInfo; 1757 HRESULT result; 1758 result=This->lpvtbl->fnGetRefTypeInfo(iface, 1759 This->impltypelist->reference, &pTInfo); 1760 if(SUCCEEDED(result)){ 1761 result=ICOM_VTBL(pTInfo)->fnGetNames(pTInfo, memid, rgBstrNames, 1762 cMaxNames, pcNames); 1763 ICOM_VTBL(pTInfo)->fnRelease(pTInfo); 1764 return result; 1765 } 1766 WARN_(typelib)("Could not search inherited interface!\n"); 1767 } else 1768 WARN_(typelib)("no names found\n"); 1769 *pcNames=0; 1770 return TYPE_E_ELEMENTNOTFOUND; 1771 } 1772 } 1773 return S_OK; 1774 } 1775 1776 1777 /* ITypeInfo::GetRefTypeOfImplType 1778 * 1779 * If a type description describes a COM class, it retrieves the type 1780 * description of the implemented interface types. For an interface, 1781 * GetRefTypeOfImplType returns the type information for inherited interfaces, 1782 * if any exist. 1783 * 1784 */ 1785 static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( LPTYPEINFO iface, 1786 UINT index, HREFTYPE *pRefType) 1787 { 1788 ICOM_THIS( TLBTypeInfo, iface); 1789 int(i); 1790 TLBRefType *pIref; 1791 TRACE_(typelib)("(%p) index %d\n", This, index); 1792 for(i=0, pIref=This->impltypelist; i<index && pIref; 1793 i++, pIref=pIref->next) 1794 ; 1795 if(i==index){ 1796 *pRefType=pIref->reference; 1797 return S_OK; 1798 } 1799 return TYPE_E_ELEMENTNOTFOUND; 1800 } 1801 1802 /* ITypeInfo::GetImplTypeFlags 1803 * 1804 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface 1805 * or base interface in a type description. 1806 */ 1807 static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( LPTYPEINFO iface, 1808 UINT index, INT *pImplTypeFlags) 1809 { 1810 ICOM_THIS( TLBTypeInfo, iface); 1811 int(i); 1812 TLBRefType *pIref; 1813 TRACE_(typelib)("(%p) index %d\n", This, index); 1814 for(i=0, pIref=This->impltypelist; i<index && pIref; i++, pIref=pIref->next) 1815 ; 1816 if(i==index && pIref){ 1817 *pImplTypeFlags=pIref->flags; 1818 return S_OK; 1819 } 1820 *pImplTypeFlags=0; 1821 return TYPE_E_ELEMENTNOTFOUND; 1822 } 1823 1824 /* GetIDsOfNames 1825 * Maps between member names and member IDs, and parameter names and 1826 * parameter IDs. 1827 */ 1828 static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( LPTYPEINFO iface, 1829 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId) 1830 { 1831 ICOM_THIS( TLBTypeInfo, iface); 1832 TLBFuncDesc * pFDesc; 1833 TLBVarDesc * pVDesc; 1834 HRESULT ret=S_OK; 1835 PCHAR aszName= HEAP_strdupWtoA( GetProcessHeap(), 0, *rgszNames); 1836 TRACE_(typelib)("(%p) Name %s cNames %d\n", This, debugstr_a(aszName), 1837 cNames); 1838 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) { 1839 int i, j; 1840 if( !strcmp(aszName, pFDesc->Name)) { 1841 if(cNames) *pMemId=pFDesc->funcdesc.memid; 1842 for(i=1; i < cNames; i++){ 1843 PCHAR aszPar= HEAP_strdupWtoA( GetProcessHeap(), 0, 1844 rgszNames[i]); 1845 for(j=0; j<pFDesc->funcdesc.cParams; j++) 1846 if(strcmp(aszPar,pFDesc->pParamDesc[j].Name)) 1847 break; 1848 if( j<pFDesc->funcdesc.cParams) 1849 pMemId[i]=j; 1850 else 1851 ret=DISP_E_UNKNOWNNAME; 1852 HeapFree( GetProcessHeap(), 0, aszPar); 1853 }; 1854 HeapFree (GetProcessHeap(), 0, aszName); 1855 return ret; 1856 } 1857 } 1858 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) { 1859 if( !strcmp(aszName, pVDesc->Name)) { 1860 if(cNames) *pMemId=pVDesc->vardesc.memid; 1861 HeapFree (GetProcessHeap(), 0, aszName); 1862 return ret; 1863 } 1864 } 1865 /* not found, see if this is and interface with an inheritance */ 1866 if(This->TypeAttr.typekind==TKIND_INTERFACE && 1867 This->TypeAttr.cImplTypes ){ 1868 /* recursive search */ 1869 ITypeInfo *pTInfo; 1870 ret=This->lpvtbl->fnGetRefTypeInfo(iface, 1871 This->impltypelist->reference, &pTInfo); 1872 if(SUCCEEDED(ret)){ 1873 ret=ICOM_VTBL(pTInfo)->fnGetIDsOfNames(pTInfo, rgszNames, cNames, pMemId ); 1874 ICOM_VTBL(pTInfo)->fnRelease(pTInfo); 1875 return ret; 1876 } 1877 WARN_(typelib)("Could not search inherited interface!\n"); 1878 } else 1879 WARN_(typelib)("no names found\n"); 1880 return DISP_E_UNKNOWNNAME; 1881 } 1882 1883 /* ITypeInfo::Invoke 1884 * 1885 * Invokes a method, or accesses a property of an object, that implements the 1886 * interface described by the type description. 1887 */ 1888 static HRESULT WINAPI ITypeInfo_fnInvoke( LPTYPEINFO iface, VOID *pIUnk, 1889 MEMBERID memid, UINT16 dwFlags, DISPPARAMS *pDispParams, 1890 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr) 1891 { 1892 ICOM_THIS( TLBTypeInfo, iface); 1893 FIXME_(typelib)("(%p) stub!", This); 1894 return S_OK; 1895 } 1896 1897 /* ITypeInfo::GetDocumentation 1898 * 1899 * Retrieves the documentation string, the complete Help file name and path, 1900 * and the context ID for the Help topic for a specified type description. 1901 */ 1902 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( LPTYPEINFO iface, 1903 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, 1904 DWORD *pdwHelpContext, BSTR *pBstrHelpFile) 1905 { 1906 ICOM_THIS( TLBTypeInfo, iface); 1907 TLBFuncDesc * pFDesc; 1908 TLBVarDesc * pVDesc; 1909 TRACE_(typelib)("(%p) memid %ld Name(%p) DocString(%p)" 1910 " HelpContext(%p) HelpFile(%p)\n", 1911 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); 1912 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ 1913 if(pBstrName) 1914 *pBstrName=TLB_DupAtoBstr(This->Name); 1915 if(pBstrDocString) 1916 *pBstrDocString=TLB_DupAtoBstr(This->DocString); 1917 if(pdwHelpContext) 1918 *pdwHelpContext=This->dwHelpContext; 1919 if(pBstrHelpFile) 1920 *pBstrHelpFile=TLB_DupAtoBstr(This->DocString);/* FIXME */ 1921 return S_OK; 1922 }else {/* for a member */ 1923 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) 1924 if(pFDesc->funcdesc.memid==memid){ 1925 return S_OK; 1926 } 1927 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) 1928 if(pVDesc->vardesc.memid==memid){ 1929 return S_OK; 1930 } 1931 } 1932 return TYPE_E_ELEMENTNOTFOUND; 1933 } 1934 1935 /* ITypeInfo::GetDllEntry 1936 * 1937 * Retrieves a description or specification of an entry point for a function 1938 * in a DLL. 1939 */ 1940 static HRESULT WINAPI ITypeInfo_fnGetDllEntry( LPTYPEINFO iface, MEMBERID memid, 1941 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, 1942 WORD *pwOrdinal) 1943 { 1944 ICOM_THIS( TLBTypeInfo, iface); 1945 FIXME_(typelib)("(%p) stub!\n", This); 1946 return E_FAIL; 1947 } 1948 1949 /* ITypeInfo::GetRefTypeInfo 1950 * 1951 * If a type description references other type descriptions, it retrieves 1952 * the referenced type descriptions. 1953 */ 1954 static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( LPTYPEINFO iface, 1955 HREFTYPE hRefType, ITypeInfo * *ppTInfo) 1956 { 1957 ICOM_THIS( TLBTypeInfo, iface); 1958 HRESULT result; 1959 if(HREFTYPE_INTHISFILE(hRefType)){ 1960 ITypeLib *pTLib; 1961 int Index; 1962 result=This->lpvtbl->fnGetContainingTypeLib(iface, &pTLib, 1963 (UINT*)&Index); 1964 if(SUCCEEDED(result)){ 1965 result=ICOM_VTBL(pTLib)->fnGetTypeInfo(pTLib, 1966 HREFTYPE_INDEX(hRefType), 1967 ppTInfo); 1968 ICOM_VTBL(pTLib)->fnRelease(pTLib ); 1969 } 1970 } else{ 1971 /* imported type lib */ 1972 TLBRefType * pRefType; 1973 TLBLibInfo *pTypeLib; 1974 for( pRefType=This->impltypelist; pRefType && 1975 pRefType->reference != hRefType; pRefType=pRefType->next) 1976 ; 1977 if(!pRefType) 1978 return TYPE_E_ELEMENTNOTFOUND; /* FIXME : correct? */ 1979 pTypeLib=pRefType->pImpTLInfo->pImpTypeLib; 1980 if(pTypeLib) /* typelib already loaded */ 1981 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid( 1982 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo); 1983 else{ 1984 result=LoadRegTypeLib( &pRefType->pImpTLInfo->guid, 1985 0,0,0, /* FIXME */ 1986 (LPTYPELIB *)&pTypeLib); 1987 if(!SUCCEEDED(result)){ 1988 BSTR libnam=TLB_DupAtoBstr(pRefType->pImpTLInfo->name); 1989 result=LoadTypeLib(libnam, (LPTYPELIB *)&pTypeLib); 1990 SysFreeString(libnam); 1991 } 1992 if(SUCCEEDED(result)){ 1993 result=pTypeLib->lpvtbl->fnGetTypeInfoOfGuid( 1994 (LPTYPELIB)pTypeLib, &pRefType->guid, ppTInfo); 1995 pRefType->pImpTLInfo->pImpTypeLib=pTypeLib; 1996 } 1997 } 1998 } 1999 TRACE_(typelib)("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType, 2000 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo); 2001 return result; 2002 } 2003 2004 /* ITypeInfo::AddressOfMember 2005 * 2006 * Retrieves the addresses of static functions or variables, such as those 2007 * defined in a DLL. 2008 */ 2009 static HRESULT WINAPI ITypeInfo_fnAddressOfMember( LPTYPEINFO iface, 2010 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) 2011 { 2012 ICOM_THIS( TLBTypeInfo, iface); 2013 FIXME_(typelib)("(%p) stub!\n", This); 2014 return S_OK; 2015 } 2016 2017 /* ITypeInfo::CreateInstance 2018 * 2019 * Creates a new instance of a type that describes a component object class 2020 * (coclass). 2021 */ 2022 static HRESULT WINAPI ITypeInfo_fnCreateInstance( LPTYPEINFO iface, 2023 IUnknown *pUnk, REFIID riid, VOID **ppvObj) 2024 { 2025 ICOM_THIS( TLBTypeInfo, iface); 2026 FIXME_(typelib)("(%p) stub!\n", This); 2027 return S_OK; 2028 } 2029 2030 /* ITypeInfo::GetMops 2031 * 2032 * Retrieves marshaling information. 2033 */ 2034 static HRESULT WINAPI ITypeInfo_fnGetMops( LPTYPEINFO iface, MEMBERID memid, 2035 BSTR *pBstrMops) 2036 { 2037 ICOM_THIS( TLBTypeInfo, iface); 2038 FIXME_(typelib)("(%p) stub!\n", This); 2039 return S_OK; 2040 } 2041 2042 /* ITypeInfo::GetContainingTypeLib 2043 * 2044 * Retrieves the containing type library and the index of the type description 2045 * within that type library. 2046 */ 2047 static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( LPTYPEINFO iface, 2048 ITypeLib * *ppTLib, UINT *pIndex) 2049 { 2050 ICOM_THIS( TLBTypeInfo, iface); 2051 *ppTLib=(LPTYPELIB )(This->pTypeLib); 2052 *pIndex=This->index; 2053 ICOM_VTBL(*ppTLib)->fnAddRef(*ppTLib); 2054 TRACE_(typelib)("(%p) returns (%p) index %d!\n", This, *ppTLib, *pIndex); 2055 return S_OK; 2056 } 2057 2058 /* ITypeInfo::ReleaseTypeAttr 2059 * 2060 * Releases a TYPEATTR previously returned by GetTypeAttr. 2061 * 2062 */ 2063 static HRESULT WINAPI ITypeInfo_fnReleaseTypeAttr( LPTYPEINFO iface, 2064 TYPEATTR* pTypeAttr) 2065 { 2066 ICOM_THIS( TLBTypeInfo, iface); 2067 TRACE_(typelib)("(%p)->(%p)\n", This, pTypeAttr); 2068 return S_OK; 2069 } 2070 2071 /* ITypeInfo::ReleaseFuncDesc 2072 * 2073 * Releases a FUNCDESC previously returned by GetFuncDesc. * 2074 */ 2075 static HRESULT WINAPI ITypeInfo_fnReleaseFuncDesc( LPTYPEINFO iface, 2076 FUNCDESC *pFuncDesc) 2077 { 2078 ICOM_THIS( TLBTypeInfo, iface); 2079 TRACE_(typelib)("(%p)->(%p)\n", This, pFuncDesc); 2080 return S_OK; 2081 } 2082 2083 /* ITypeInfo::ReleaseVarDesc 2084 * 2085 * Releases a VARDESC previously returned by GetVarDesc. 2086 */ 2087 static HRESULT WINAPI ITypeInfo_fnReleaseVarDesc( LPTYPEINFO iface, 2088 VARDESC *pVarDesc) 2089 { 2090 ICOM_THIS( TLBTypeInfo, iface); 2091 TRACE_(typelib)("(%p)->(%p)\n", This, pVarDesc); 2092 return S_OK; 2093 } 2094 2095 /* ITypeInfo2::GetTypeKind 2096 * 2097 * Returns the TYPEKIND enumeration quickly, without doing any allocations. 2098 * 2099 */ 2100 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo * iface, 2101 TYPEKIND *pTypeKind) 2102 { 2103 ICOM_THIS( TLBTypeInfo, iface); 2104 *pTypeKind=This->TypeAttr.typekind; 2105 TRACE_(typelib)("(%p) type 0x%0x\n", This,*pTypeKind); 2106 return S_OK; 2107 } 2108 2109 /* ITypeInfo2::GetTypeFlags 2110 * 2111 * Returns the type flags without any allocations. This returns a DWORD type 2112 * flag, which expands the type flags without growing the TYPEATTR (type 2113 * attribute). 2114 * 2115 */ 2116 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo * iface, 2117 UINT *pTypeFlags) 2118 { 2119 ICOM_THIS( TLBTypeInfo, iface); 2120 *pTypeFlags=This->TypeAttr.wTypeFlags; 2121 TRACE_(typelib)("(%p) flags 0x%04x\n", This,*pTypeFlags); 2122 return S_OK; 2123 } 2124 2125 /* ITypeInfo2::GetFuncIndexOfMemId 2126 * Binds to a specific member based on a known DISPID, where the member name 2127 * is not known (for example, when binding to a default member). 2128 * 2129 */ 2130 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo * iface, 2131 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex) 2132 { 2133 ICOM_THIS( TLBTypeInfo, iface); 2134 TLBFuncDesc *pFuncInfo; 2135 int i; 2136 HRESULT result; 2137 /* FIXME: should check for invKind??? */ 2138 for(i=0, pFuncInfo=This->funclist;pFuncInfo && 2139 memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next); 2140 if(pFuncInfo){ 2141 *pFuncIndex=i; 2142 result= S_OK; 2143 }else{ 2144 *pFuncIndex=0; 2145 result=E_INVALIDARG; 2146 } 2147 TRACE_(typelib)("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This, 2148 memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED"); 2149 return result; 2150 } 2151 2152 /* TypeInfo2::GetVarIndexOfMemId 2153 * 2154 * Binds to a specific member based on a known DISPID, where the member name 2155 * is not known (for example, when binding to a default member). 2156 * 2157 */ 2158 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo * iface, 2159 MEMBERID memid, UINT *pVarIndex) 2160 { 2161 ICOM_THIS( TLBTypeInfo, iface); 2162 TLBVarDesc *pVarInfo; 2163 int i; 2164 HRESULT result; 2165 for(i=0, pVarInfo=This->varlist; pVarInfo && 2166 memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next) 2167 ; 2168 if(pVarInfo){ 2169 *pVarIndex=i; 2170 result= S_OK; 2171 }else{ 2172 *pVarIndex=0; 2173 result=E_INVALIDARG; 2174 } 2175 TRACE_(typelib)("(%p) memid 0x%08lx -> %s\n", This, 2176 memid, SUCCEEDED(result)? "SUCCES":"FAILED"); 2177 return result; 2178 } 2179 2180 /* ITypeInfo2::GetCustData 2181 * 2182 * Gets the custom data 2183 */ 2184 static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfo * iface, 2185 REFGUID guid, VARIANT *pVarVal) 2186 { 2187 ICOM_THIS( TLBTypeInfo, iface); 2188 TLBCustData *pCData; 2189 for(pCData=This->pCustData; pCData; pCData = pCData->next) 2190 if( IsEqualIID(guid, &pCData->guid)) break; 2191 if(TRACE_ON(typelib)){ 2192 char xriid[50]; 2193 WINE_StringFromCLSID((LPCLSID)guid,xriid); 2194 TRACE_(typelib)("(%p) guid %s %s found!x)\n", This, xriid, 2195 pCData? "" : "NOT"); 2196 } 2197 if(pCData){ 2198 VariantInit( pVarVal); 2199 VariantCopy( pVarVal, &pCData->data); 2200 return S_OK; 2201 } 2202 return E_INVALIDARG; /* FIXME: correct? */ 2203 } 2204 2205 /* ITypeInfo2::GetFuncCustData 2206 * 2207 * Gets the custom data 2208 */ 2209 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( ITypeInfo * iface, 2210 UINT index, REFGUID guid, VARIANT *pVarVal) 2211 { 2212 ICOM_THIS( TLBTypeInfo, iface); 2213 TLBCustData *pCData=NULL; 2214 TLBFuncDesc * pFDesc; 2215 int i; 2216 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, 2217 pFDesc=pFDesc->next) 2218 ; 2219 if(pFDesc) 2220 for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next) 2221 if( IsEqualIID(guid, &pCData->guid)) break; 2222 if(TRACE_ON(typelib)){ 2223 char xriid[50]; 2224 WINE_StringFromCLSID((LPCLSID)guid,xriid); 2225 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid, 2226 pCData? "" : "NOT"); 2227 } 2228 if(pCData){ 2229 VariantInit( pVarVal); 2230 VariantCopy( pVarVal, &pCData->data); 2231 return S_OK; 2232 } 2233 return E_INVALIDARG; /* FIXME: correct? */ 2234 } 2235 2236 /* ITypeInfo2::GetParamCustData 2237 * 2238 * Gets the custom data 2239 */ 2240 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( ITypeInfo * iface, 2241 UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal) 2242 { 2243 ICOM_THIS( TLBTypeInfo, iface); 2244 TLBCustData *pCData=NULL; 2245 TLBFuncDesc * pFDesc; 2246 int i; 2247 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++, 2248 pFDesc=pFDesc->next) 2249 ; 2250 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams) 2251 for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData; 2252 pCData = pCData->next) 2253 if( IsEqualIID(guid, &pCData->guid)) break; 2254 if(TRACE_ON(typelib)){ 2255 char xriid[50]; 2256 WINE_StringFromCLSID((LPCLSID)guid,xriid); 2257 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid, 2258 pCData? "" : "NOT"); 2259 } 2260 if(pCData){ 2261 VariantInit( pVarVal); 2262 VariantCopy( pVarVal, &pCData->data); 2263 return S_OK; 2264 } 2265 return E_INVALIDARG; /* FIXME: correct? */ 2266 } 2267 2268 /* ITypeInfo2::GetVarcCustData 2269 * 2270 * Gets the custom data 2271 */ 2272 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( ITypeInfo * iface, 2273 UINT index, REFGUID guid, VARIANT *pVarVal) 2274 { 2275 ICOM_THIS( TLBTypeInfo, iface); 2276 TLBCustData *pCData=NULL; 2277 TLBVarDesc * pVDesc; 2278 int i; 2279 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, 2280 pVDesc=pVDesc->next) 2281 ; 2282 if(pVDesc) 2283 for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next) 2284 if( IsEqualIID(guid, &pCData->guid)) break; 2285 if(TRACE_ON(typelib)){ 2286 char xriid[50]; 2287 WINE_StringFromCLSID((LPCLSID)guid,xriid); 2288 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid, 2289 pCData? "" : "NOT"); 2290 } 2291 if(pCData){ 2292 VariantInit( pVarVal); 2293 VariantCopy( pVarVal, &pCData->data); 2294 return S_OK; 2295 } 2296 return E_INVALIDARG; /* FIXME: correct? */ 2297 } 2298 2299 /* ITypeInfo2::GetImplcCustData 2300 * 2301 * Gets the custom data 2302 */ 2303 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( ITypeInfo * iface, 2304 UINT index, REFGUID guid, VARIANT *pVarVal) 2305 { 2306 ICOM_THIS( TLBTypeInfo, iface); 2307 TLBCustData *pCData=NULL; 2308 TLBRefType * pRDesc; 2309 int i; 2310 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, 2311 pRDesc=pRDesc->next) 2312 ; 2313 if(pRDesc) 2314 for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next) 2315 if( IsEqualIID(guid, &pCData->guid)) break; 2316 if(TRACE_ON(typelib)){ 2317 char xriid[50]; 2318 WINE_StringFromCLSID((LPCLSID)guid,xriid); 2319 TRACE_(typelib)("(%p) guid %s %s found!x)\n",This,xriid, 2320 pCData? "" : "NOT"); 2321 } 2322 if(pCData){ 2323 VariantInit( pVarVal); 2324 VariantCopy( pVarVal, &pCData->data); 2325 return S_OK; 2326 } 2327 return E_INVALIDARG; /* FIXME: correct? */ 2328 } 2329 2330 /* ITypeInfo2::GetDocumentation2 2331 * 2332 * Retrieves the documentation string, the complete Help file name and path, 2333 * the localization context to use, and the context ID for the library Help 2334 * topic in the Help file. 2335 * 2336 */ 2337 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( ITypeInfo * iface, 2338 MEMBERID memid, LCID lcid, BSTR *pbstrHelpString, 2339 INT *pdwHelpStringContext, BSTR *pbstrHelpStringDll) 2340 { 2341 ICOM_THIS( TLBTypeInfo, iface); 2342 TLBFuncDesc * pFDesc; 2343 TLBVarDesc * pVDesc; 2344 TRACE_(typelib)("(%p) memid %ld lcid(0x%lx) HelpString(%p) " 2345 "HelpStringContext(%p) HelpStringDll(%p)\n", 2346 This, memid, lcid, pbstrHelpString, pdwHelpStringContext, 2347 pbstrHelpStringDll ); 2348 /* the help string should be obtained from the helpstringdll, 2349 * using the _DLLGetDocumentation function, based on the supplied 2350 * lcid. Nice to do sometime... 2351 */ 2352 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ 2353 if(pbstrHelpString) 2354 *pbstrHelpString=TLB_DupAtoBstr(This->Name); 2355 if(pdwHelpStringContext) 2356 *pdwHelpStringContext=This->dwHelpStringContext; 2357 if(pbstrHelpStringDll) 2358 *pbstrHelpStringDll= 2359 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */ 2360 return S_OK; 2361 }else {/* for a member */ 2362 for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) 2363 if(pFDesc->funcdesc.memid==memid){ 2364 if(pbstrHelpString) 2365 *pbstrHelpString=TLB_DupAtoBstr(pFDesc->HelpString); 2366 if(pdwHelpStringContext) 2367 *pdwHelpStringContext=pFDesc->HelpStringContext; 2368 if(pbstrHelpStringDll) 2369 *pbstrHelpStringDll= 2370 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */ 2371 return S_OK; 2372 } 2373 for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) 2374 if(pVDesc->vardesc.memid==memid){ 2375 if(pbstrHelpString) 2376 *pbstrHelpString=TLB_DupAtoBstr(pVDesc->HelpString); 2377 if(pdwHelpStringContext) 2378 *pdwHelpStringContext=pVDesc->HelpStringContext; 2379 if(pbstrHelpStringDll) 2380 *pbstrHelpStringDll= 2381 TLB_DupAtoBstr(This->pTypeLib->HelpStringDll);/* FIXME */ 2382 return S_OK; 2383 } 2384 } 2385 return TYPE_E_ELEMENTNOTFOUND; 2386 } 2387 2388 /* ITypeInfo2::GetAllCustData 2389 * 2390 * Gets all custom data items for the Type info. 2391 * 2392 */ 2393 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( ITypeInfo * iface, 2394 CUSTDATA *pCustData) 2395 { 2396 ICOM_THIS( TLBTypeInfo, iface); 2397 TLBCustData *pCData; 2398 int i; 2399 TRACE_(typelib)("(%p) returning %d items\n", This, This->ctCustData); 2400 pCustData->prgCustData = (tagCUSTDATAITEM*)TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); 2401 if(pCustData->prgCustData ){ 2402 pCustData->cCustData=This->ctCustData; 2403 for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ 2404 pCustData->prgCustData[i].guid=pCData->guid; 2405 VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); 2406 } 2407 }else{ 2408 ERR_(typelib)(" OUT OF MEMORY! \n"); 2409 return E_OUTOFMEMORY; 2410 } 2411 return S_OK; 2412 } 2413 2414 /* ITypeInfo2::GetAllFuncCustData 2415 * 2416 * Gets all custom data items for the specified Function 2417 * 2418 */ 2419 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( ITypeInfo * iface, 2420 UINT index, CUSTDATA *pCustData) 2421 { 2422 ICOM_THIS( TLBTypeInfo, iface); 2423 TLBCustData *pCData; 2424 TLBFuncDesc * pFDesc; 2425 int i; 2426 TRACE_(typelib)("(%p) index %d\n", This, index); 2427 for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, 2428 pFDesc=pFDesc->next) 2429 ; 2430 if(pFDesc){ 2431 pCustData->prgCustData =(tagCUSTDATAITEM*) 2432 TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM)); 2433 if(pCustData->prgCustData ){ 2434 pCustData->cCustData=pFDesc->ctCustData; 2435 for(i=0, pCData=pFDesc->pCustData; pCData; i++, 2436 pCData = pCData->next){ 2437 pCustData->prgCustData[i].guid=pCData->guid; 2438 VariantCopy(& pCustData->prgCustData[i].varValue, 2439 & pCData->data); 2440 } 2441 }else{ 2442 ERR_(typelib)(" OUT OF MEMORY! \n"); 2443 return E_OUTOFMEMORY; 2444 } 2445 return S_OK; 2446 } 2447 return TYPE_E_ELEMENTNOTFOUND; 2448 } 2449 2450 /* ITypeInfo2::GetAllParamCustData 2451 * 2452 * Gets all custom data items for the Functions 2453 * 2454 */ 2455 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo * iface, 2456 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData) 2457 { 2458 ICOM_THIS( TLBTypeInfo, iface); 2459 TLBCustData *pCData=NULL; 2460 TLBFuncDesc * pFDesc; 2461 int i; 2462 TRACE_(typelib)("(%p) index %d\n", This, indexFunc); 2463 for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++, 2464 pFDesc=pFDesc->next) 2465 ; 2466 if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){ 2467 pCustData->prgCustData =(tagCUSTDATAITEM*) 2468 TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData * 2469 sizeof(CUSTDATAITEM)); 2470 if(pCustData->prgCustData ){ 2471 pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData; 2472 for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData; 2473 pCData; i++, pCData = pCData->next){ 2474 pCustData->prgCustData[i].guid=pCData->guid; 2475 VariantCopy(& pCustData->prgCustData[i].varValue, 2476 & pCData->data); 2477 } 2478 }else{ 2479 ERR_(typelib)(" OUT OF MEMORY! \n"); 2480 return E_OUTOFMEMORY; 2481 } 2482 return S_OK; 2483 } 2484 return TYPE_E_ELEMENTNOTFOUND; 2485 } 2486 2487 /* ITypeInfo2::GetAllVarCustData 2488 * 2489 * Gets all custom data items for the specified Variable 2490 * 2491 */ 2492 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo * iface, 2493 UINT index, CUSTDATA *pCustData) 2494 { 2495 ICOM_THIS( TLBTypeInfo, iface); 2496 TLBCustData *pCData; 2497 TLBVarDesc * pVDesc; 2498 int i; 2499 TRACE_(typelib)("(%p) index %d\n", This, index); 2500 for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, 2501 pVDesc=pVDesc->next) 2502 ; 2503 if(pVDesc){ 2504 pCustData->prgCustData =(tagCUSTDATAITEM*) 2505 TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM)); 2506 if(pCustData->prgCustData ){ 2507 pCustData->cCustData=pVDesc->ctCustData; 2508 for(i=0, pCData=pVDesc->pCustData; pCData; i++, 2509 pCData = pCData->next){ 2510 pCustData->prgCustData[i].guid=pCData->guid; 2511 VariantCopy(& pCustData->prgCustData[i].varValue, 2512 & pCData->data); 2513 } 2514 }else{ 2515 ERR_(typelib)(" OUT OF MEMORY! \n"); 2516 return E_OUTOFMEMORY; 2517 } 2518 return S_OK; 2519 } 2520 return TYPE_E_ELEMENTNOTFOUND; 2521 } 2522 2523 /* ITypeInfo2::GetAllImplCustData 2524 * 2525 * Gets all custom data items for the specified implementation type 2526 * 2527 */ 2528 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( ITypeInfo * iface, 2529 UINT index, CUSTDATA *pCustData) 2530 { 2531 ICOM_THIS( TLBTypeInfo, iface); 2532 TLBCustData *pCData; 2533 TLBRefType * pRDesc; 2534 int i; 2535 TRACE_(typelib)("(%p) index %d\n", This, index); 2536 for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, 2537 pRDesc=pRDesc->next) 2538 ; 2539 if(pRDesc){ 2540 pCustData->prgCustData =(tagCUSTDATAITEM*) 2541 TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM)); 2542 if(pCustData->prgCustData ){ 2543 pCustData->cCustData=pRDesc->ctCustData; 2544 for(i=0, pCData=pRDesc->pCustData; pCData; i++, 2545 pCData = pCData->next){ 2546 pCustData->prgCustData[i].guid=pCData->guid; 2547 VariantCopy(& pCustData->prgCustData[i].varValue, 2548 & pCData->data); 2549 } 2550 }else{ 2551 ERR_(typelib)(" OUT OF MEMORY! \n"); 2552 return E_OUTOFMEMORY; 2553 } 2554 return S_OK; 2555 } 2556 return TYPE_E_ELEMENTNOTFOUND; 2557 } 2558 1188 // ---------------------------------------------------------------------- 1189 // DupAtoBstr 1190 // ---------------------------------------------------------------------- 1191 extern BSTR DupAtoBstr(char * pAscii) 1192 { 1193 int len; 1194 BSTR bstr; 1195 DWORD * pl; 1196 1197 if (!pAscii) 1198 return NULL; 1199 1200 len = strlen(pAscii); 1201 pl = (DWORD *)HeapAlloc(GetProcessHeap(), 0, (len+3)*sizeof(OLECHAR)); 1202 pl[0] = (len)*sizeof(OLECHAR); 1203 bstr = (BSTR)&( pl[1]); 1204 lstrcpyAtoW( bstr, pAscii); 1205 return bstr; 1206 } 1207
Note:
See TracChangeset
for help on using the changeset viewer.