Changeset 2022 for trunk/src


Ignore:
Timestamp:
Dec 8, 1999, 8:59:58 PM (26 years ago)
Author:
davidr
Message:

New parser for typelibs

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
     3typedef enum tagREGKIND
     4{
     5    REGKIND_DEFAULT,
     6    REGKIND_REGISTER,
     7    REGKIND_NONE
     8} REGKIND;
    329
    3310#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// ======================================================================
     18static 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// ----------------------------------------------------------------------
     39HRESULT 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// ----------------------------------------------------------------------
     95HRESULT 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// ----------------------------------------------------------------------
    130137HRESULT 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// ----------------------------------------------------------------------
     153HRESULT 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    }
    143173
    144174    return res;
    145175}
    146176
    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// ----------------------------------------------------------------------
    186182HRESULT 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,
    190186                                                         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
    192190    return S_OK;        /* FIXME: pretend everything is OK */
    193191}
    194192
    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// ----------------------------------------------------------------------
    205198HRESULT 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
    215207    return S_OK;        /* FIXME: pretend everything is OK */
    216208}
    217209
    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// ----------------------------------------------------------------------
     217TypeLibExtract::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// ----------------------------------------------------------------------
     229TypeLibExtract::~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// ----------------------------------------------------------------------
     242HRESULT 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// ----------------------------------------------------------------------
     330BOOL 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// ----------------------------------------------------------------------
     343void 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// ----------------------------------------------------------------------
     354void 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// ----------------------------------------------------------------------
     369void 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// ----------------------------------------------------------------------
     384void 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// ----------------------------------------------------------------------
     408void 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// ----------------------------------------------------------------------
     433void 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;
    535440        V_UNION(pVar, iVal) = offset & 0xffff;
    536441        return;
    537442    }
    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    {
    541450        case VT_EMPTY:  /* FIXME: is this right? */
    542451        case VT_NULL:   /* FIXME: is this right? */
     
    554463        case VT_VOID    : /* FIXME: is this right? */
    555464        case VT_HRESULT :
    556             size=4; break;
     465            size=4;
     466            break;
     467
    557468        case VT_R8  :
    558469        case VT_CY  :
     
    562473        case VT_DECIMAL :  /* FIXME: is this right? */
    563474        case VT_FILETIME :
    564             size=8;break;
     475            size=8;
     476            break;
     477
    565478            /* 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
    578491    /* FIXME: this will not work AT ALL when the variant contains a pointer */
    579492        case VT_DISPATCH :
     
    595508        case VT_CLSID   :
    596509        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// ----------------------------------------------------------------------
     522void 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// ----------------------------------------------------------------------
     543void 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 :(
    662578     */
    663579
    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// ----------------------------------------------------------------------
     603void 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// ----------------------------------------------------------------------
     643void 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// ----------------------------------------------------------------------
     698void    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));
    700795                }
     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.
    701802            }
     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));
    702852        }
    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(&paraminfo,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(&paraminfo,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// ----------------------------------------------------------------------
     869static 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// ----------------------------------------------------------------------
     886HRESULT 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// ----------------------------------------------------------------------
     979void 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// ----------------------------------------------------------------------
     1015HRESULT 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// ----------------------------------------------------------------------
     1041HRESULT 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);
    7581161        }
    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);
    9291182        }
    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
    11971185    return S_OK;
    11981186}
    11991187
    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// ----------------------------------------------------------------------
     1191extern 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.