- better loading of *.tlb files
- seperated code for loading tlb resource into memory from code for parsing the tlb resource.
This commit is contained in:
parent
4d67892358
commit
e3b8640c77
|
@ -160,7 +160,8 @@ HRESULT WINAPI LoadTypeLib16(
|
||||||
* Success: S_OK
|
* Success: S_OK
|
||||||
* Failure: Status
|
* Failure: Status
|
||||||
*/
|
*/
|
||||||
int TLB_ReadTypeLib(PCHAR file, ITypeLib **ppTypelib);
|
int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
|
||||||
|
|
||||||
HRESULT WINAPI LoadTypeLib(
|
HRESULT WINAPI LoadTypeLib(
|
||||||
OLECHAR *szFile, /* [in] Name of file to load from */
|
OLECHAR *szFile, /* [in] Name of file to load from */
|
||||||
ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
|
ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
|
||||||
|
@ -191,7 +192,7 @@ HRESULT WINAPI LoadTypeLibEx(
|
||||||
if(regkind != REGKIND_NONE)
|
if(regkind != REGKIND_NONE)
|
||||||
FIXME ("registration of typelibs not supported yet!\n");
|
FIXME ("registration of typelibs not supported yet!\n");
|
||||||
|
|
||||||
res= TLB_ReadTypeLib(p, pptLib);
|
res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
|
||||||
HeapFree(GetProcessHeap(),0,p);
|
HeapFree(GetProcessHeap(),0,p);
|
||||||
TRACE(" returns %08lx\n",res);
|
TRACE(" returns %08lx\n",res);
|
||||||
|
|
||||||
|
@ -351,7 +352,7 @@ typedef struct tagITypeLibImpl
|
||||||
static struct ICOM_VTABLE(ITypeLib2) tlbvt;
|
static struct ICOM_VTABLE(ITypeLib2) tlbvt;
|
||||||
|
|
||||||
/* ITypeLib methods */
|
/* ITypeLib methods */
|
||||||
static ITypeLib2* ITypeLib2_Constructor();
|
static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib);
|
||||||
|
|
||||||
/*======================= ITypeInfo implementation =======================*/
|
/*======================= ITypeInfo implementation =======================*/
|
||||||
|
|
||||||
|
@ -1072,231 +1073,263 @@ ITypeInfoImpl * TLB_DoTypeInfo(
|
||||||
return ptiRet;
|
return ptiRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib **ppTypeLib)
|
/****************************************************************************
|
||||||
|
* TLB_ReadTypeLib
|
||||||
|
*
|
||||||
|
* find the type of the typelib file and map the typelib resource into
|
||||||
|
* the memory
|
||||||
|
*/
|
||||||
|
#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
|
||||||
|
int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
|
||||||
{
|
{
|
||||||
TLBContext cx;
|
|
||||||
long lPSegDir;
|
|
||||||
ITypeLibImpl* pLibInfo=NULL;
|
|
||||||
TLB2Header tlbHeader;
|
|
||||||
TLBSegDir tlbSegDir;
|
|
||||||
HINSTANCE hinstDLL;
|
|
||||||
int ret = E_FAIL;
|
int ret = E_FAIL;
|
||||||
HRSRC hrsrc;
|
DWORD dwSignature = 0;
|
||||||
HGLOBAL hGlobal;
|
HFILE hFile;
|
||||||
LPVOID pLib;
|
|
||||||
|
|
||||||
TRACE("%s\n", pszFileName);
|
TRACE("%s\n", pszFileName);
|
||||||
|
|
||||||
/* find the typelibrary resource*/
|
*ppTypeLib = NULL;
|
||||||
hinstDLL = LoadLibraryExA(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
|
|
||||||
if (!hinstDLL)
|
/* check the signature of the file */
|
||||||
|
hFile = CreateFileA( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, -1 );
|
||||||
|
if (INVALID_HANDLE_VALUE != hFile)
|
||||||
{
|
{
|
||||||
ERR("error: couldn't load the DLL %s\n", pszFileName);
|
HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
|
||||||
goto err1;
|
if (hMapping)
|
||||||
|
{
|
||||||
|
LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if(pBase)
|
||||||
|
{
|
||||||
|
/* first try to load as *.tlb */
|
||||||
|
dwSignature = *((DWORD*) pBase);
|
||||||
|
if ( dwSignature == MSFT_SIGNATURE)
|
||||||
|
{
|
||||||
|
*ppTypeLib = ITypeLib2_Constructor(pBase);
|
||||||
|
}
|
||||||
|
UnmapViewOfFile(pBase);
|
||||||
|
}
|
||||||
|
CloseHandle(hMapping);
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(1), "TYPELIB");
|
if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
|
||||||
if (!hrsrc)
|
|
||||||
{
|
{
|
||||||
ERR("error: couldn't find initial TLB data\n");
|
/* find the typelibrary resource*/
|
||||||
goto err2;
|
HINSTANCE hinstDLL = LoadLibraryExA(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
|
||||||
|
LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
if (hinstDLL)
|
||||||
|
{
|
||||||
|
HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(1), "TYPELIB");
|
||||||
|
if (hrsrc)
|
||||||
|
{
|
||||||
|
HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
|
||||||
|
if (hGlobal)
|
||||||
|
{
|
||||||
|
LPVOID pBase = LockResource(hGlobal);
|
||||||
|
if (pBase)
|
||||||
|
{
|
||||||
|
*ppTypeLib = ITypeLib2_Constructor(pBase);
|
||||||
|
}
|
||||||
|
FreeResource( hGlobal );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeLibrary(hinstDLL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hGlobal = LoadResource(hinstDLL, hrsrc);
|
if(*ppTypeLib)
|
||||||
if (!hGlobal)
|
ret = S_OK;
|
||||||
{
|
else
|
||||||
ERR("error: couldn't load TLB data from DLL\n");
|
ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
|
||||||
goto err2;
|
|
||||||
}
|
|
||||||
|
|
||||||
pLib = LockResource(hGlobal);
|
return ret;
|
||||||
if (! pLib)
|
}
|
||||||
{
|
|
||||||
goto err3;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("found at %p\n", pLib);
|
/*================== ITypeLib(2) Methods ===================================*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* ITypeLib2_Constructor
|
||||||
|
*
|
||||||
|
* loading a typelib from a in-memory image
|
||||||
|
*/
|
||||||
|
static ITypeLib2* ITypeLib2_Constructor(LPVOID pLib)
|
||||||
|
{
|
||||||
|
TLBContext cx;
|
||||||
|
long lPSegDir;
|
||||||
|
TLB2Header tlbHeader;
|
||||||
|
TLBSegDir tlbSegDir;
|
||||||
|
ITypeLibImpl * pTypeLibImpl;
|
||||||
|
|
||||||
|
TRACE("%p\n", pLib);
|
||||||
|
|
||||||
|
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
|
||||||
|
if (!pTypeLibImpl) return NULL;
|
||||||
|
|
||||||
|
ICOM_VTBL(pTypeLibImpl) = &tlbvt;
|
||||||
|
pTypeLibImpl->ref = 1;
|
||||||
|
|
||||||
/* get pointer to beginning of typelib data */
|
/* get pointer to beginning of typelib data */
|
||||||
cx.pos = 0;
|
cx.pos = 0;
|
||||||
cx.oStart=0;
|
cx.oStart=0;
|
||||||
cx.mapping = pLib;
|
cx.mapping = pLib;
|
||||||
|
cx.pLibInfo = pTypeLibImpl;
|
||||||
pLibInfo = (ITypeLibImpl*) ITypeLib2_Constructor();
|
|
||||||
|
|
||||||
if (!pLibInfo)
|
|
||||||
{
|
|
||||||
ret = E_OUTOFMEMORY;
|
|
||||||
goto err3;
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.pLibInfo=pLibInfo;
|
|
||||||
|
|
||||||
/* read header */
|
/* read header */
|
||||||
TRACE("read header\n");
|
|
||||||
TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
|
TLB_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
|
||||||
TRACE("read header (0x%08x 0x%08x)\n",tlbHeader.magic1,tlbHeader.magic2 );
|
TRACE("read header (0x%08x 0x%08x)\n",tlbHeader.magic1,tlbHeader.magic2 );
|
||||||
|
|
||||||
/* there is a small number of information here until the next important
|
/* there is a small number of information here until the next important
|
||||||
* part:
|
* part:
|
||||||
* the segment directory . Try to calculate the amount of data */
|
* the segment directory . Try to calculate the amount of data */
|
||||||
lPSegDir=sizeof(tlbHeader)+
|
lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + (tlbHeader.varflags & HELPDLLFLAG? 4 :0);
|
||||||
(tlbHeader.nrtypeinfos)*4+
|
|
||||||
(tlbHeader.varflags & HELPDLLFLAG? 4 :0);
|
|
||||||
|
|
||||||
/* now read the segment directory */
|
/* now read the segment directory */
|
||||||
TRACE("read segment directory\n");
|
TRACE("read segment directory\n");
|
||||||
TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
|
TLB_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
|
||||||
cx.pTblDir=&tlbSegDir;
|
cx.pTblDir = &tlbSegDir;
|
||||||
|
|
||||||
/* just check two entries */
|
/* just check two entries */
|
||||||
if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F ||
|
if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
|
||||||
tlbSegDir.pImpInfo.res0c != 0x0F
|
{
|
||||||
) {
|
|
||||||
ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
|
ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
|
||||||
goto err3;
|
HeapFree(GetProcessHeap(),0,pTypeLibImpl);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now fill our internal data */
|
/* now fill our internal data */
|
||||||
/* TLIBATTR fields */
|
/* TLIBATTR fields */
|
||||||
TLB_ReadGuid(&pLibInfo->LibAttr.guid, tlbHeader.posguid, &cx);
|
TLB_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
|
||||||
pLibInfo->LibAttr.lcid=tlbHeader.lcid;
|
pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;
|
||||||
pLibInfo->LibAttr.syskind=tlbHeader.varflags & 0x0f; /* check the mask */
|
pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
|
||||||
pLibInfo->LibAttr.wMajorVerNum=LOWORD(tlbHeader.version);
|
pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
|
||||||
pLibInfo->LibAttr.wMinorVerNum=HIWORD(tlbHeader.version);
|
pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
|
||||||
pLibInfo->LibAttr.wLibFlags=(WORD) tlbHeader.flags & 0xffff;/* check mask */
|
pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
|
||||||
|
|
||||||
/* name, eventually add to a hash table */
|
/* name, eventually add to a hash table */
|
||||||
pLibInfo->Name=TLB_ReadName(&cx, tlbHeader.NameOffset);
|
pTypeLibImpl->Name = TLB_ReadName(&cx, tlbHeader.NameOffset);
|
||||||
|
|
||||||
/* help info */
|
/* help info */
|
||||||
pLibInfo->DocString=TLB_ReadString(&cx, tlbHeader.helpstring);
|
pTypeLibImpl->DocString = TLB_ReadString(&cx, tlbHeader.helpstring);
|
||||||
pLibInfo->HelpFile=TLB_ReadString(&cx, tlbHeader.helpfile);
|
pTypeLibImpl->HelpFile = TLB_ReadString(&cx, tlbHeader.helpfile);
|
||||||
if( tlbHeader.varflags & HELPDLLFLAG){
|
|
||||||
|
if( tlbHeader.varflags & HELPDLLFLAG)
|
||||||
|
{
|
||||||
int offset;
|
int offset;
|
||||||
TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
|
TLB_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
|
||||||
pLibInfo->HelpStringDll=TLB_ReadString(&cx, offset);
|
pTypeLibImpl->HelpStringDll = TLB_ReadString(&cx, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
pLibInfo->dwHelpContext=tlbHeader.helpstringcontext;
|
pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
|
||||||
|
|
||||||
/* custom data */
|
/* custom data */
|
||||||
if(tlbHeader.CustomDataOffset >= 0) {
|
if(tlbHeader.CustomDataOffset >= 0)
|
||||||
pLibInfo->ctCustData=
|
{
|
||||||
TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pLibInfo->pCustData);
|
pTypeLibImpl->ctCustData = TLB_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in typedescriptions */
|
/* fill in typedescriptions */
|
||||||
if(tlbSegDir.pTypdescTab.length >0){
|
if(tlbSegDir.pTypdescTab.length > 0)
|
||||||
int i, j, cTD=tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
|
{
|
||||||
|
int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
|
||||||
INT16 td[4];
|
INT16 td[4];
|
||||||
pLibInfo->pTypeDesc=
|
pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
|
||||||
TLB_Alloc( cTD * sizeof(TYPEDESC));
|
|
||||||
TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
|
TLB_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
|
||||||
for(i=0;i<cTD;){
|
for(i=0; i<cTD; )
|
||||||
|
{
|
||||||
/* FIXME: add several sanity checks here */
|
/* FIXME: add several sanity checks here */
|
||||||
pLibInfo->pTypeDesc[i].vt=td[0] & VT_TYPEMASK;
|
pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
|
||||||
if(td[0]==VT_PTR ||td[0]==VT_SAFEARRAY){/* FIXME: check safearray */
|
if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
|
||||||
if(td[3]<0)
|
{
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
|
/* FIXME: check safearray */
|
||||||
& stndTypeDesc[td[2]];
|
if(td[3] < 0)
|
||||||
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & stndTypeDesc[td[2]];
|
||||||
else
|
else
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lptdesc)=
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lptdesc)= & pTypeLibImpl->pTypeDesc[td[3]/8];
|
||||||
& pLibInfo->pTypeDesc[td[3]/8];
|
}
|
||||||
}else if(td[0]==VT_CARRAY)
|
else if(td[0] == VT_CARRAY)
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
|
{
|
||||||
(void *)((int) td[2]); /* temp store offset in*/
|
/* array descr table here */
|
||||||
/* array descr table here */
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = (void *)((int) td[2]); /* temp store offset in*/
|
||||||
else if(td[0]==VT_USERDEFINED)
|
}
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),hreftype)=MAKELONG(td[2],td[3]);
|
else if(td[0] == VT_USERDEFINED)
|
||||||
if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
|
{
|
||||||
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),hreftype) = MAKELONG(td[2],td[3]);
|
||||||
|
}
|
||||||
|
if(++i<cTD) TLB_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* second time around to fill the array subscript info */
|
/* second time around to fill the array subscript info */
|
||||||
for(i=0;i<cTD;i++){
|
for(i=0;i<cTD;i++)
|
||||||
if(pLibInfo->pTypeDesc[i].vt != VT_CARRAY) continue;
|
{
|
||||||
if(tlbSegDir.pArrayDescriptions.offset>0){
|
if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
|
||||||
TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset +
|
if(tlbSegDir.pArrayDescriptions.offset>0)
|
||||||
(int) V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc));
|
{
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=
|
TLB_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc));
|
||||||
TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
|
||||||
|
|
||||||
if(td[1]<0)
|
if(td[1]<0)
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem.vt=td[0] & VT_TYPEMASK;
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem.vt = td[0] & VT_TYPEMASK;
|
||||||
else
|
else
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->tdescElem=stndTypeDesc[td[0]/8];
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->tdescElem = stndTypeDesc[td[0]/8];
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->cDims=td[2];
|
|
||||||
for(j=0;j<td[2];j++){
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->cDims = td[2];
|
||||||
TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
|
|
||||||
|
for(j = 0; j<td[2]; j++)
|
||||||
|
{
|
||||||
|
TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].cElements,
|
||||||
sizeof(INT), &cx, DO_NOT_SEEK);
|
sizeof(INT), &cx, DO_NOT_SEEK);
|
||||||
TLB_Read(& V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)
|
TLB_Read(& V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc)->rgbounds[j].lLbound,
|
||||||
->rgbounds[j].lLbound,
|
|
||||||
sizeof(INT), &cx, DO_NOT_SEEK);
|
sizeof(INT), &cx, DO_NOT_SEEK);
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
V_UNION(&(pLibInfo->pTypeDesc[i]),lpadesc)=NULL;
|
else
|
||||||
|
{
|
||||||
|
V_UNION(&(pTypeLibImpl->pTypeDesc[i]),lpadesc) = NULL;
|
||||||
ERR("didn't find array description data\n");
|
ERR("didn't find array description data\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* imported type libs */
|
/* imported type libs */
|
||||||
if(tlbSegDir.pImpFiles.offset>0){
|
if(tlbSegDir.pImpFiles.offset>0)
|
||||||
TLBImpLib **ppImpLib=&(pLibInfo->pImpLibs);
|
{
|
||||||
int offset=tlbSegDir.pImpFiles.offset;
|
TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
|
||||||
int oGuid;
|
int oGuid, offset = tlbSegDir.pImpFiles.offset;
|
||||||
UINT16 size;
|
UINT16 size;
|
||||||
while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length){
|
|
||||||
*ppImpLib=TLB_Alloc(sizeof(TLBImpLib));
|
while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
|
||||||
(*ppImpLib)->offset=offset - tlbSegDir.pImpFiles.offset;
|
{
|
||||||
|
*ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
|
||||||
|
(*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
|
||||||
TLB_Read(&oGuid, sizeof(INT), &cx, offset);
|
TLB_Read(&oGuid, sizeof(INT), &cx, offset);
|
||||||
TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
|
TLB_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
|
||||||
|
|
||||||
/* we are skipping some unknown info here */
|
/* we are skipping some unknown info here */
|
||||||
TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
|
TLB_Read(& size,sizeof(UINT16), &cx, offset+3*(sizeof(INT)));
|
||||||
size >>=2;
|
size >>= 2;
|
||||||
(*ppImpLib)->name=TLB_Alloc(size+1);
|
(*ppImpLib)->name = TLB_Alloc(size+1);
|
||||||
TLB_Read((*ppImpLib)->name,size, &cx, DO_NOT_SEEK);
|
TLB_Read((*ppImpLib)->name, size, &cx, DO_NOT_SEEK);
|
||||||
offset=(offset+3*(sizeof(INT))+sizeof(UINT16)+size+3) & 0xfffffffc;
|
offset = (offset + 3 * (sizeof(INT)) + sizeof(UINT16) + size + 3) & 0xfffffffc;
|
||||||
|
|
||||||
ppImpLib=&(*ppImpLib)->next;
|
ppImpLib = &(*ppImpLib)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* type info's */
|
/* type info's */
|
||||||
if(tlbHeader.nrtypeinfos >=0 )
|
if(tlbHeader.nrtypeinfos >= 0 )
|
||||||
{
|
{
|
||||||
/*pLibInfo->TypeInfoCount=tlbHeader.nrtypeinfos; */
|
/*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
|
||||||
ITypeInfoImpl **ppTI = &(pLibInfo->pTypeInfo);
|
ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<(int)tlbHeader.nrtypeinfos;i++)
|
for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
|
||||||
{
|
{
|
||||||
*ppTI = TLB_DoTypeInfo(&cx, i, pLibInfo);
|
*ppTI = TLB_DoTypeInfo(&cx, i, pTypeLibImpl);
|
||||||
ppTI = &((*ppTI)->next);
|
ppTI = &((*ppTI)->next);
|
||||||
(pLibInfo->TypeInfoCount)++;
|
(pTypeLibImpl->TypeInfoCount)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*ppTypeLib=(LPTYPELIB)pLibInfo;
|
|
||||||
ret = S_OK;
|
|
||||||
|
|
||||||
err3:
|
|
||||||
FreeResource( hGlobal );
|
|
||||||
err2:
|
|
||||||
FreeLibrary(hinstDLL);
|
|
||||||
err1:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*================== ITypeLib(2) Methods ===================================*/
|
|
||||||
|
|
||||||
static ITypeLib2* ITypeLib2_Constructor()
|
|
||||||
{
|
|
||||||
ITypeLibImpl * pTypeLibImpl;
|
|
||||||
|
|
||||||
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
|
|
||||||
if (pTypeLibImpl)
|
|
||||||
{
|
|
||||||
ICOM_VTBL(pTypeLibImpl) = &tlbvt;
|
|
||||||
pTypeLibImpl->ref = 1;
|
|
||||||
}
|
|
||||||
TRACE("(%p)\n", pTypeLibImpl);
|
TRACE("(%p)\n", pTypeLibImpl);
|
||||||
return (ITypeLib2*) pTypeLibImpl;
|
return (ITypeLib2*) pTypeLibImpl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue