Jacek Caban : mshtml: Refactor Gecko loading code.

Alexandre Julliard julliard at winehq.org
Mon Dec 9 16:57:39 CST 2019


Module: wine
Branch: master
Commit: ba462a06609b106ecaadce48f3c2544f8f81a9d7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ba462a06609b106ecaadce48f3c2544f8f81a9d7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Dec  9 17:04:22 2019 +0100

mshtml: Refactor Gecko loading code.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/nsembed.c | 271 ++++++++++++++++++++++++--------------------------
 1 file changed, 132 insertions(+), 139 deletions(-)

diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 244341248e..f47f727630 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -432,6 +432,8 @@ static BOOL install_wine_gecko(void)
         CloseHandle(pi.hThread);
         WaitForSingleObject(pi.hProcess, INFINITE);
         CloseHandle(pi.hProcess);
+    }else {
+        WARN("installation failed\n");
     }
 
     return ret;
@@ -483,139 +485,6 @@ static void set_environment(LPCWSTR gre_path)
     heap_free(path);
 }
 
-static BOOL load_xul(const PRUnichar *gre_path)
-{
-    static const WCHAR xul_dllW[] = {'\\','x','u','l','.','d','l','l',0};
-    WCHAR file_name[MAX_PATH];
-
-    lstrcpyW(file_name, gre_path);
-    lstrcatW(file_name, xul_dllW);
-
-    TRACE("(%s)\n", debugstr_w(file_name));
-
-    set_environment(gre_path);
-
-    xul_handle = LoadLibraryExW(file_name, 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
-    if(!xul_handle) {
-        WARN("Could not load XUL: %d\n", GetLastError());
-        return FALSE;
-    }
-
-#define NS_DLSYM(func) \
-    func = (void *)GetProcAddress(xul_handle, #func); \
-    if(!func) \
-        ERR("Could not GetProcAddress(" #func ") failed\n")
-
-    NS_DLSYM(NS_InitXPCOM2);
-    NS_DLSYM(NS_ShutdownXPCOM);
-    NS_DLSYM(NS_GetComponentRegistrar);
-    NS_DLSYM(NS_StringContainerInit2);
-    NS_DLSYM(NS_CStringContainerInit2);
-    NS_DLSYM(NS_StringContainerFinish);
-    NS_DLSYM(NS_CStringContainerFinish);
-    NS_DLSYM(NS_StringSetData);
-    NS_DLSYM(NS_CStringSetData);
-    NS_DLSYM(NS_NewLocalFile);
-    NS_DLSYM(NS_StringGetData);
-    NS_DLSYM(NS_CStringGetData);
-    NS_DLSYM(NS_StringGetIsVoid);
-    NS_DLSYM(NS_Alloc);
-    NS_DLSYM(NS_Free);
-    NS_DLSYM(ccref_incr);
-    NS_DLSYM(ccref_decr);
-    NS_DLSYM(ccref_init);
-    NS_DLSYM(ccp_init);
-    NS_DLSYM(describe_cc_node);
-    NS_DLSYM(note_cc_edge);
-
-#undef NS_DLSYM
-
-    return TRUE;
-}
-
-static BOOL check_version(LPCWSTR gre_path, const char *version_string)
-{
-    WCHAR file_name[MAX_PATH];
-    char version[128];
-    DWORD read=0;
-    HANDLE hfile;
-
-    static const WCHAR wszVersion[] = {'\\','V','E','R','S','I','O','N',0};
-
-    lstrcpyW(file_name, gre_path);
-    lstrcatW(file_name, wszVersion);
-
-    hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
-                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    if(hfile == INVALID_HANDLE_VALUE) {
-        ERR("Could not open VERSION file\n");
-        return FALSE;
-    }
-
-    ReadFile(hfile, version, sizeof(version), &read, NULL);
-    version[read] = 0;
-    CloseHandle(hfile);
-
-    TRACE("%s\n", debugstr_a(version));
-
-    if(strcmp(version, version_string)) {
-        ERR("Unexpected version %s, expected %s\n", debugstr_a(version),
-            debugstr_a(version_string));
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static BOOL load_wine_gecko_v(PRUnichar *gre_path, HKEY mshtml_key,
-        const char *version, const char *version_string)
-{
-    DWORD res, type, size = MAX_PATH;
-    HKEY hkey = mshtml_key;
-
-    static const WCHAR wszGeckoPath[] =
-        {'G','e','c','k','o','P','a','t','h',0};
-
-    if(version) {
-        /* @@ Wine registry key: HKLM\Software\Wine\MSHTML\<version> */
-        res = RegOpenKeyA(mshtml_key, version, &hkey);
-        if(res != ERROR_SUCCESS)
-            return FALSE;
-    }
-
-    res = RegQueryValueExW(hkey, wszGeckoPath, NULL, &type, (LPBYTE)gre_path, &size);
-    if(hkey != mshtml_key)
-        RegCloseKey(hkey);
-    if(res != ERROR_SUCCESS || type != REG_SZ)
-        return FALSE;
-
-    if(!check_version(gre_path, version_string))
-        return FALSE;
-
-    return load_xul(gre_path);
-}
-
-static BOOL load_wine_gecko(PRUnichar *gre_path)
-{
-    HKEY hkey;
-    DWORD res;
-    BOOL ret;
-
-    static const WCHAR wszMshtmlKey[] = {
-        'S','o','f','t','w','a','r','e','\\','W','i','n','e',
-        '\\','M','S','H','T','M','L',0};
-
-    /* @@ Wine registry key: HKLM\Software\Wine\MSHTML */
-    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszMshtmlKey, &hkey);
-    if(res != ERROR_SUCCESS)
-        return FALSE;
-
-    ret = load_wine_gecko_v(gre_path, hkey, GECKO_VERSION, GECKO_VERSION_STRING);
-
-    RegCloseKey(hkey);
-    return ret;
-}
-
 static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
 {
     nsresult nsres;
@@ -743,6 +612,124 @@ static BOOL init_xpcom(const PRUnichar *gre_path)
     return TRUE;
 }
 
+static BOOL load_xul(WCHAR *gecko_path)
+{
+    size_t len;
+
+    set_environment(gecko_path);
+
+    TRACE("(%s)\n", debugstr_w(gecko_path));
+
+    len = wcslen(gecko_path);
+    wcscpy(gecko_path + len, L"\\xul.dll");
+    xul_handle = LoadLibraryExW(gecko_path, 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+    gecko_path[len] = 0;
+    if(!xul_handle) {
+        WARN("Could not load XUL: %d\n", GetLastError());
+        return FALSE;
+    }
+
+#define NS_DLSYM(func) \
+    func = (void *)GetProcAddress(xul_handle, #func); \
+    if(!func) \
+        ERR("Could not GetProcAddress(" #func ") failed\n")
+
+    NS_DLSYM(NS_InitXPCOM2);
+    NS_DLSYM(NS_ShutdownXPCOM);
+    NS_DLSYM(NS_GetComponentRegistrar);
+    NS_DLSYM(NS_StringContainerInit2);
+    NS_DLSYM(NS_CStringContainerInit2);
+    NS_DLSYM(NS_StringContainerFinish);
+    NS_DLSYM(NS_CStringContainerFinish);
+    NS_DLSYM(NS_StringSetData);
+    NS_DLSYM(NS_CStringSetData);
+    NS_DLSYM(NS_NewLocalFile);
+    NS_DLSYM(NS_StringGetData);
+    NS_DLSYM(NS_CStringGetData);
+    NS_DLSYM(NS_StringGetIsVoid);
+    NS_DLSYM(NS_Alloc);
+    NS_DLSYM(NS_Free);
+    NS_DLSYM(ccref_incr);
+    NS_DLSYM(ccref_decr);
+    NS_DLSYM(ccref_init);
+    NS_DLSYM(ccp_init);
+    NS_DLSYM(describe_cc_node);
+    NS_DLSYM(note_cc_edge);
+
+#undef NS_DLSYM
+
+    return init_xpcom(gecko_path);
+}
+
+static WCHAR *check_version(const WCHAR *path)
+{
+    WCHAR *file_name;
+    char version[128];
+    DWORD read=0;
+    size_t len;
+    HANDLE hfile;
+
+    if(!wcsncmp(path, L"\\??\\", 4))
+        path += 4;
+    if(path[1] != ':') {
+        TRACE("Skipping %s\n", debugstr_w(path));
+        return FALSE; /* Gecko needs to be accessible via dos path */
+    }
+
+    len = wcslen(path);
+    file_name = heap_alloc((len + 12) * sizeof(WCHAR));
+    if(!file_name)
+        return NULL;
+
+    PathCanonicalizeW(file_name, path);
+    len = lstrlenW(file_name);
+    wcscpy(file_name + len, L"\\VERSION");
+
+    hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
+                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    file_name[len] = 0;
+    if(hfile == INVALID_HANDLE_VALUE) {
+        TRACE("%s not found\n", debugstr_w(file_name));
+        heap_free(file_name);
+        return NULL;
+    }
+
+    ReadFile(hfile, version, sizeof(version), &read, NULL);
+    version[read] = 0;
+    CloseHandle(hfile);
+
+    TRACE("%s: %s\n", debugstr_w(file_name), debugstr_a(version));
+
+    if(strcmp(version, GECKO_VERSION_STRING)) {
+        ERR("Unexpected version %s, expected \"%s\"\n", debugstr_a(version),
+            GECKO_VERSION_STRING);
+        heap_free(file_name);
+        return NULL;
+    }
+
+    return file_name;
+}
+
+static WCHAR *find_wine_gecko_reg(void)
+{
+    WCHAR buffer[MAX_PATH];
+    DWORD res, type, size;
+    HKEY hkey;
+
+    /* @@ Wine registry key: HKLM\Software\Wine\MSHTML\<version> */
+    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\Wine\\MSHTML\\" GECKO_VERSION, &hkey);
+    if(res != ERROR_SUCCESS)
+        return NULL;
+
+    size = ARRAY_SIZE(buffer);
+    res = RegQueryValueExW(hkey, L"GeckoPath", NULL, &type, (LPBYTE)buffer, &size);
+    RegCloseKey(hkey);
+    if(res != ERROR_SUCCESS || type != REG_SZ)
+        return FALSE;
+
+    return check_version(buffer);
+}
+
 static CRITICAL_SECTION cs_load_gecko;
 static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
 {
@@ -754,7 +741,6 @@ static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };
 
 BOOL load_gecko(void)
 {
-    PRUnichar gre_path[MAX_PATH];
     BOOL ret = FALSE;
 
     static DWORD loading_thread;
@@ -768,13 +754,20 @@ BOOL load_gecko(void)
     EnterCriticalSection(&cs_load_gecko);
 
     if(!loading_thread) {
+        WCHAR *gecko_path;
+
         loading_thread = GetCurrentThreadId();
 
-        if(load_wine_gecko(gre_path)
-           || (install_wine_gecko() && load_wine_gecko(gre_path)))
-            ret = init_xpcom(gre_path);
-        else
-           MESSAGE("Could not load wine-gecko. HTML rendering will be disabled.\n");
+        if(!(gecko_path = find_wine_gecko_reg())
+           && install_wine_gecko())
+            gecko_path = find_wine_gecko_reg();
+
+        if(gecko_path) {
+            ret = load_xul(gecko_path);
+            heap_free(gecko_path);
+        }else {
+           MESSAGE("Could not find Wine Gecko. HTML rendering will be disabled.\n");
+        }
     }else {
         ret = pCompMgr != NULL;
     }




More information about the wine-cvs mailing list