From a633e22bdd598993ea4d21964c8b8bd453fa58dc Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Thu, 9 Feb 2006 12:11:54 +0100 Subject: [PATCH] oleaut: Make TLB_ReadTypeLib not rely on the signature of executables or dlls. Try loading the dll first and then fall back to the regular file case. Only call SearchPath for the regular file case since LoadLibraryEx will do this for us and it previously excluded builtin dlls and executables from having their type libraries opened. --- dlls/oleaut32/typelib.c | 148 +++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 78 deletions(-) diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 77f1f5fdee9..a516fa5e434 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -2168,37 +2168,48 @@ static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, IT { ITypeLibImpl *entry; int ret = TYPE_E_CANTLOADLIBRARY; - DWORD dwSignature = 0; - HANDLE hFile; INT index = 1; + HINSTANCE hinstDLL; *ppTypeLib = NULL; - if (!SearchPathW(NULL, pszFileName, NULL, cchPath, pszPath, NULL)) + /* first try loading as a dll and access the typelib as a resource */ + hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES | + LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hinstDLL) { - WCHAR szFileCopy[MAX_PATH+1]; - /* Look for a trailing '\\' followed by an index */ - WCHAR *pIndexStr = strrchrW(pszFileName, '\\'); + /* it may have been specified with resource index appended to the + * path, so remove it and try again */ + const WCHAR *pIndexStr = strrchrW(pszFileName, '\\'); if(pIndexStr && pIndexStr != pszFileName && *++pIndexStr != '\0') { index = atoiW(pIndexStr); - memcpy(szFileCopy, pszFileName, + memcpy(pszPath, pszFileName, (pIndexStr - pszFileName - 1) * sizeof(WCHAR)); - szFileCopy[pIndexStr - pszFileName - 1] = '\0'; - if (!SearchPathW(NULL, szFileCopy, NULL, cchPath, pszPath, NULL)) - return TYPE_E_CANTLOADLIBRARY; - if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY) - return TYPE_E_CANTLOADLIBRARY; + pszPath[pIndexStr - pszFileName - 1] = '\0'; + + hinstDLL = LoadLibraryExW(pszPath, 0, DONT_RESOLVE_DLL_REFERENCES | + LOAD_LIBRARY_AS_DATAFILE | LOAD_WITH_ALTERED_SEARCH_PATH); } } + /* get the path to the specified typelib file */ + if (hinstDLL) + GetModuleFileNameW(hinstDLL, pszPath, cchPath); + else + { + /* otherwise, try loading as a regular file */ + if (!SearchPathW(NULL, pszFileName, NULL, cchPath, pszPath, NULL)) + return TYPE_E_CANTLOADLIBRARY; + } + TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index); /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */ EnterCriticalSection(&cache_section); for (entry = tlb_cache_first; entry != NULL; entry = entry->next) { - if (!strcmpiW(entry->path, pszFileName) && entry->index == index) + if (!strcmpiW(entry->path, pszPath) && entry->index == index) { TRACE("cache hit\n"); *ppTypeLib = (ITypeLib2*)entry; @@ -2209,80 +2220,61 @@ static int TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, IT } LeaveCriticalSection(&cache_section); - /* check the signature of the file */ - hFile = CreateFileW( pszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); - if (INVALID_HANDLE_VALUE != hFile) + /* now actually load and parse the typelib */ + if (hinstDLL) { - 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); - - /* first try to load as *.tlb */ - 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); - } - else - { - TRACE("not found, trying to load %s as library\n", debugstr_w(pszFileName)); - } - - /* if the file is a DLL or not found, try loading it with LoadLibrary */ - if (((WORD)dwSignature == IMAGE_DOS_SIGNATURE) || (dwSignature == 0)) - { - /* find the typelibrary resource*/ - HINSTANCE hinstDLL = LoadLibraryExW(pszPath, 0, DONT_RESOLVE_DLL_REFERENCES| - LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH); - if (hinstDLL) - { static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0}; HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW); if (hrsrc) { - HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc); - if (hGlobal) - { - LPVOID pBase = LockResource(hGlobal); - DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc); - - if (pBase) + HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc); + if (hGlobal) { - /* try to load as incore resource */ - 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%08lx not supported.\n",dwSignature); - } + 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%08lx not supported.\n",dwSignature); + } + FreeResource( hGlobal ); } - FreeResource( hGlobal ); - } } FreeLibrary(hinstDLL); - } + } + else + { + HANDLE hFile = CreateFileW( pszFileName, 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); + } } if(*ppTypeLib) {