oleaut32: Split the methods for opening different sources of typelibs out of TLB_ReadTypeLib.
This commit is contained in:
parent
66c728dec1
commit
0ec1e2842a
|
@ -2217,6 +2217,188 @@ static CRITICAL_SECTION_DEBUG cache_section_debug =
|
|||
static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
typedef struct TLB_PEFile
|
||||
{
|
||||
const IUnknownVtbl *lpvtbl;
|
||||
LONG refs;
|
||||
HMODULE dll;
|
||||
HRSRC typelib_resource;
|
||||
HGLOBAL typelib_global;
|
||||
LPVOID typelib_base;
|
||||
} TLB_PEFile;
|
||||
|
||||
static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TLB_PEFile_AddRef(IUnknown *iface)
|
||||
{
|
||||
TLB_PEFile *This = (TLB_PEFile *)iface;
|
||||
return InterlockedIncrement(&This->refs);
|
||||
}
|
||||
|
||||
static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface)
|
||||
{
|
||||
TLB_PEFile *This = (TLB_PEFile *)iface;
|
||||
ULONG refs = InterlockedDecrement(&This->refs);
|
||||
if (!refs)
|
||||
{
|
||||
if (This->typelib_global)
|
||||
FreeResource(This->typelib_global);
|
||||
if (This->dll)
|
||||
FreeLibrary(This->dll);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
static const IUnknownVtbl TLB_PEFile_Vtable =
|
||||
{
|
||||
TLB_PEFile_QueryInterface,
|
||||
TLB_PEFile_AddRef,
|
||||
TLB_PEFile_Release
|
||||
};
|
||||
|
||||
static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
|
||||
{
|
||||
TLB_PEFile *This;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->lpvtbl = &TLB_PEFile_Vtable;
|
||||
This->refs = 1;
|
||||
This->dll = NULL;
|
||||
This->typelib_resource = NULL;
|
||||
This->typelib_global = NULL;
|
||||
This->typelib_base = NULL;
|
||||
|
||||
This->dll = LoadLibraryExW(path, 0, DONT_RESOLVE_DLL_REFERENCES |
|
||||
LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
|
||||
if (This->dll)
|
||||
{
|
||||
static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
|
||||
This->typelib_resource = FindResourceW(This->dll, MAKEINTRESOURCEW(index), TYPELIBW);
|
||||
if (This->typelib_resource)
|
||||
{
|
||||
This->typelib_global = LoadResource(This->dll, This->typelib_resource);
|
||||
if (This->typelib_global)
|
||||
{
|
||||
This->typelib_base = LockResource(This->typelib_global);
|
||||
|
||||
if (This->typelib_base)
|
||||
{
|
||||
*pdwTLBLength = SizeofResource(This->dll, This->typelib_resource);
|
||||
*ppBase = This->typelib_base;
|
||||
*ppFile = (IUnknown *)&This->lpvtbl;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TLB_PEFile_Release((IUnknown *)&This->lpvtbl);
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
|
||||
|
||||
typedef struct TLB_Mapping
|
||||
{
|
||||
const IUnknownVtbl *lpvtbl;
|
||||
LONG refs;
|
||||
HANDLE file;
|
||||
HANDLE mapping;
|
||||
LPVOID typelib_base;
|
||||
} TLB_Mapping;
|
||||
|
||||
static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TLB_Mapping_AddRef(IUnknown *iface)
|
||||
{
|
||||
TLB_Mapping *This = (TLB_Mapping *)iface;
|
||||
return InterlockedIncrement(&This->refs);
|
||||
}
|
||||
|
||||
static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface)
|
||||
{
|
||||
TLB_Mapping *This = (TLB_Mapping *)iface;
|
||||
ULONG refs = InterlockedDecrement(&This->refs);
|
||||
if (!refs)
|
||||
{
|
||||
if (This->typelib_base)
|
||||
UnmapViewOfFile(This->typelib_base);
|
||||
if (This->mapping)
|
||||
CloseHandle(This->mapping);
|
||||
if (This->file != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(This->file);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
static const IUnknownVtbl TLB_Mapping_Vtable =
|
||||
{
|
||||
TLB_Mapping_QueryInterface,
|
||||
TLB_Mapping_AddRef,
|
||||
TLB_Mapping_Release
|
||||
};
|
||||
|
||||
static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
|
||||
{
|
||||
TLB_Mapping *This;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->lpvtbl = &TLB_Mapping_Vtable;
|
||||
This->refs = 1;
|
||||
This->file = INVALID_HANDLE_VALUE;
|
||||
This->mapping = NULL;
|
||||
This->typelib_base = NULL;
|
||||
|
||||
This->file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (INVALID_HANDLE_VALUE != This->file)
|
||||
{
|
||||
This->mapping = CreateFileMappingW(This->file, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
|
||||
if (This->mapping)
|
||||
{
|
||||
This->typelib_base = MapViewOfFile(This->mapping, FILE_MAP_READ, 0, 0, 0);
|
||||
if(This->typelib_base)
|
||||
{
|
||||
/* retrieve file size */
|
||||
*pdwTLBLength = GetFileSize(This->file, NULL);
|
||||
*ppBase = This->typelib_base;
|
||||
*ppFile = (IUnknown *)&This->lpvtbl;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IUnknown_Release((IUnknown *)&This->lpvtbl);
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* TLB_ReadTypeLib
|
||||
*
|
||||
|
@ -2228,10 +2410,12 @@ static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 }
|
|||
static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
|
||||
{
|
||||
ITypeLibImpl *entry;
|
||||
int ret = TYPE_E_CANTLOADLIBRARY;
|
||||
HRESULT ret;
|
||||
INT index = 1;
|
||||
HINSTANCE hinstDLL;
|
||||
LPWSTR index_str, file = (LPWSTR)pszFileName;
|
||||
LPVOID pBase = NULL;
|
||||
DWORD dwTLBLength = 0;
|
||||
IUnknown *pFile = NULL;
|
||||
|
||||
*ppTypeLib = NULL;
|
||||
|
||||
|
@ -2285,63 +2469,27 @@ static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, IT
|
|||
|
||||
/* now actually load and parse the typelib */
|
||||
|
||||
hinstDLL = LoadLibraryExW(pszPath, 0, DONT_RESOLVE_DLL_REFERENCES |
|
||||
LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
|
||||
if (hinstDLL)
|
||||
ret = TLB_PEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
|
||||
if (ret == TYPE_E_CANTLOADLIBRARY)
|
||||
ret = TLB_Mapping_Open(pszPath, &pBase, &dwTLBLength, &pFile);
|
||||
if (SUCCEEDED(ret))
|
||||
{
|
||||
static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
|
||||
HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW);
|
||||
if (hrsrc)
|
||||
if (dwTLBLength >= 4)
|
||||
{
|
||||
HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
|
||||
if (hGlobal)
|
||||
{
|
||||
LPVOID pBase = LockResource(hGlobal);
|
||||
DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
|
||||
|
||||
if (pBase)
|
||||
{
|
||||
/* try to load as incore resource */
|
||||
DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
|
||||
if (dwSignature == MSFT_SIGNATURE)
|
||||
*ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
|
||||
else if (dwSignature == SLTG_SIGNATURE)
|
||||
*ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
|
||||
else
|
||||
{
|
||||
FIXME("Header type magic 0x%08x not supported.\n",dwSignature);
|
||||
ret = TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
FreeResource( hGlobal );
|
||||
}
|
||||
}
|
||||
FreeLibrary(hinstDLL);
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE hFile = CreateFileW(pszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||
if (INVALID_HANDLE_VALUE != hFile)
|
||||
{
|
||||
HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
|
||||
if (hMapping)
|
||||
{
|
||||
LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
|
||||
if(pBase)
|
||||
{
|
||||
/* retrieve file size */
|
||||
DWORD dwTLBLength = GetFileSize(hFile, NULL);
|
||||
DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
|
||||
|
||||
if (dwSignature == MSFT_SIGNATURE)
|
||||
*ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
|
||||
else if (dwSignature == SLTG_SIGNATURE)
|
||||
*ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
|
||||
|
||||
UnmapViewOfFile(pBase);
|
||||
}
|
||||
CloseHandle(hMapping);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
ret = TYPE_E_CANTLOADLIBRARY;
|
||||
IUnknown_Release(pFile);
|
||||
}
|
||||
|
||||
if(*ppTypeLib) {
|
||||
|
|
Loading…
Reference in New Issue