mshtml: Refactor Gecko loading code.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d393681e41
commit
ba462a0660
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue