Jacek Caban : atl100: Added support for typelibs in separate files in AtlLoadTypeLib.

Alexandre Julliard julliard at winehq.org
Fri Dec 28 15:05:16 CST 2012


Module: wine
Branch: master
Commit: 7d23d3ecd64d77a2f4310b04e19d9d1a7fc6542e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7d23d3ecd64d77a2f4310b04e19d9d1a7fc6542e

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Dec 28 14:23:07 2012 +0100

atl100: Added support for typelibs in separate files in AtlLoadTypeLib.

---

 dlls/atl100/atl.c             |   56 +++++++++++++++++++++++++++++++++++-----
 dlls/atl100/tests/Makefile.in |    2 +-
 dlls/atl100/tests/atl.c       |   45 +++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/dlls/atl100/atl.c b/dlls/atl100/atl.c
index 219365d..accc88c 100644
--- a/dlls/atl100/atl.c
+++ b/dlls/atl100/atl.c
@@ -22,9 +22,20 @@
 #include "atlbase.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(atl100);
 
+static inline void *heap_alloc(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+static inline BOOL heap_free(void *mem)
+{
+    return HeapFree(GetProcessHeap(), 0, mem);
+}
+
 static ICatRegister *catreg;
 
 /***********************************************************************
@@ -268,25 +279,56 @@ void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
 }
 
 /***********************************************************************
- *           AtlLoadTypeLib             [atl100.@]
+ *           AtlLoadTypeLib             [atl100.56]
  */
 HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
         BSTR *pbstrPath, ITypeLib **ppTypeLib)
 {
-    OLECHAR path[MAX_PATH+8]; /* leave some space for index */
+    size_t path_len, index_len;
+    ITypeLib *typelib = NULL;
+    WCHAR *path;
     HRESULT hres;
 
+    static const WCHAR tlb_extW[] = {'.','t','l','b',0};
+
     TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
 
-    GetModuleFileNameW(inst, path, MAX_PATH);
-    if(lpszIndex)
-        lstrcatW(path, lpszIndex);
+    index_len = lpszIndex ? strlenW(lpszIndex) : 0;
+    path = heap_alloc((MAX_PATH+index_len)*sizeof(WCHAR) + sizeof(tlb_extW));
+    if(!path)
+        return E_OUTOFMEMORY;
+
+    path_len = GetModuleFileNameW(inst, path, MAX_PATH);
+    if(!path_len)
+        return HRESULT_FROM_WIN32(GetLastError());
+
+    if(index_len)
+        memcpy(path+path_len, lpszIndex, (index_len+1)*sizeof(WCHAR));
+
+    hres = LoadTypeLib(path, &typelib);
+    if(FAILED(hres)) {
+        WCHAR *ptr;
+
+        for(ptr = path+path_len-1; ptr > path && *ptr != '\\' && *ptr != '.'; ptr--);
+        if(*ptr != '.')
+            ptr = path+path_len;
+        memcpy(ptr, tlb_extW, sizeof(tlb_extW));
+        hres = LoadTypeLib(path, &typelib);
+    }
+
+    if(SUCCEEDED(hres)) {
+        *pbstrPath = SysAllocString(path);
+        if(!*pbstrPath) {
+            ITypeLib_Release(typelib);
+            hres = E_OUTOFMEMORY;
+        }
+    }
 
-    hres = LoadTypeLib(path, ppTypeLib);
+    heap_free(path);
     if(FAILED(hres))
         return hres;
 
-    *pbstrPath = SysAllocString(path);
+    *ppTypeLib = typelib;
     return S_OK;
 }
 
diff --git a/dlls/atl100/tests/Makefile.in b/dlls/atl100/tests/Makefile.in
index 29e83d0..7af0bcd 100644
--- a/dlls/atl100/tests/Makefile.in
+++ b/dlls/atl100/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = atl100.dll
-IMPORTS   = atl100 ole32 advapi32
+IMPORTS   = atl100 oleaut32 ole32 advapi32
 EXTRADEFS = -D_ATL_VER=_ATL_VER_100
 
 C_SRCS = \
diff --git a/dlls/atl100/tests/atl.c b/dlls/atl100/tests/atl.c
index 59268de..35ef34b 100644
--- a/dlls/atl100/tests/atl.c
+++ b/dlls/atl100/tests/atl.c
@@ -156,12 +156,57 @@ static void test_regcat(void)
     test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
 }
 
+static void test_typelib(void)
+{
+    ITypeLib *typelib;
+    HINSTANCE inst;
+    size_t len;
+    BSTR path;
+    HRESULT hres;
+
+    static const WCHAR scrrun_dll_suffixW[] = {'\\','s','c','r','r','u','n','.','d','l','l',0};
+    static const WCHAR mshtml_tlb_suffixW[] = {'\\','m','s','h','t','m','l','.','t','l','b',0};
+
+    inst = LoadLibraryA("scrrun.dll");
+    ok(inst != NULL, "Could not load scrrun.dll\n");
+
+    typelib = NULL;
+    hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
+    ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
+    FreeLibrary(inst);
+
+    len = SysStringLen(path);
+    ok(len > sizeof(scrrun_dll_suffixW)/sizeof(WCHAR)
+       && lstrcmpiW(path+len-sizeof(scrrun_dll_suffixW)/sizeof(WCHAR), scrrun_dll_suffixW),
+       "unexpected path %s\n", wine_dbgstr_w(path));
+    SysFreeString(path);
+    ok(typelib != NULL, "typelib == NULL\n");
+    ITypeLib_Release(typelib);
+
+    inst = LoadLibraryA("mshtml.dll");
+    ok(inst != NULL, "Could not load mshtml.dll\n");
+
+    typelib = NULL;
+    hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
+    ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
+    FreeLibrary(inst);
+
+    len = SysStringLen(path);
+    ok(len > sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR)
+       && lstrcmpiW(path+len-sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR), mshtml_tlb_suffixW),
+       "unexpected path %s\n", wine_dbgstr_w(path));
+    SysFreeString(path);
+    ok(typelib != NULL, "typelib == NULL\n");
+    ITypeLib_Release(typelib);
+}
+
 START_TEST(atl)
 {
     CoInitialize(NULL);
 
     test_winmodule();
     test_regcat();
+    test_typelib();
 
     CoUninitialize();
 }




More information about the wine-cvs mailing list