mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to implement support for loader dll redirections.
This commit is contained in:
parent
f474c5783f
commit
60f7d52725
@ -37,7 +37,7 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
===================================
|
||||
|
||||
**Bugfixes and features included in the next upcoming release [12]:**
|
||||
**Bugfixes and features included in the next upcoming release [13]:**
|
||||
|
||||
* Add support for GetPropValue to PulseAudio backend
|
||||
* Fix condition mask handling in RtlVerifyVersionInfo ([Wine Bug #36143](https://bugs.winehq.org/show_bug.cgi?id=36143))
|
||||
@ -50,6 +50,7 @@ Included bug fixes and improvements
|
||||
* Set last error when GetRawInputDeviceList fails ([Wine Bug #37667](https://bugs.winehq.org/show_bug.cgi?id=37667))
|
||||
* Support for StrCatChainW
|
||||
* Support for combase HSTRING objects
|
||||
* Support for loader dll redirections
|
||||
* wininet should allow Accept-Encoding header for HTTP/1.0 ([Wine Bug #37046](https://bugs.winehq.org/show_bug.cgi?id=37046))
|
||||
|
||||
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -13,6 +13,7 @@ wine-compholio (1.7.33) UNRELEASED; urgency=low
|
||||
* Added patch to ignore unsupported flags for CoInternetSetFeatureEnabled.
|
||||
* Added patch to provide named entry point shell32.SHILCreateFromPath for vista apps.
|
||||
* Added patch to reallocate buffer when adding records to AVI files.
|
||||
* Added patch to implement support for loader dll redirections.
|
||||
* Removed patch to fix copy and paste errors in ws2_32 tests (accepted upstream).
|
||||
* Removed patch to fix ordering of IP addresses by metric if two addresses have the same metric (accepted upstream).
|
||||
* Removed patch to reset data->pWintrustData->u.pFile->hFile after closing handle (accepted upstream).
|
||||
|
@ -60,6 +60,7 @@ PATCHLIST := \
|
||||
msvcp90-basic_string_wchar_dtor.ok \
|
||||
msvcrt-atof_strtod.ok \
|
||||
ntdll-DOS_Attributes.ok \
|
||||
ntdll-DllRedirects.ok \
|
||||
ntdll-Dynamic_DST.ok \
|
||||
ntdll-Exception.ok \
|
||||
ntdll-FD_Cache.ok \
|
||||
@ -881,6 +882,26 @@ ntdll-DOS_Attributes.ok:
|
||||
echo '+ { "Erich E. Hoover", "ntdll: Perform the Unix-style hidden file check within the unified file info grabbing routine.", 1 },'; \
|
||||
) > ntdll-DOS_Attributes.ok
|
||||
|
||||
# Patchset ntdll-DllRedirects
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/loader.c, dlls/ntdll/loadorder.c, dlls/ntdll/ntdll_misc.h
|
||||
# |
|
||||
.INTERMEDIATE: ntdll-DllRedirects.ok
|
||||
ntdll-DllRedirects.ok:
|
||||
$(call APPLY_FILE,ntdll-DllRedirects/0001-ntdll-Move-logic-to-determine-loadorder-HKCU-app-key.patch)
|
||||
$(call APPLY_FILE,ntdll-DllRedirects/0002-ntdll-Move-logic-to-read-loadorder-registry-values-i.patch)
|
||||
$(call APPLY_FILE,ntdll-DllRedirects/0003-ntdll-Move-code-to-determine-module-basename-into-se.patch)
|
||||
$(call APPLY_FILE,ntdll-DllRedirects/0004-ntdll-Implement-get_redirect-function.patch)
|
||||
$(call APPLY_FILE,ntdll-DllRedirects/0005-ntdll-Implement-loader-redirection-scheme.patch)
|
||||
@( \
|
||||
echo '+ { "Michael Müller", "ntdll: Move logic to determine loadorder HKCU/app key into separate functions.", 1 },'; \
|
||||
echo '+ { "Michael Müller", "ntdll: Move logic to read loadorder registry values into separate function.", 1 },'; \
|
||||
echo '+ { "Michael Müller", "ntdll: Move code to determine module basename into separate function.", 1 },'; \
|
||||
echo '+ { "Michael Müller", "ntdll: Implement get_redirect function.", 1 },'; \
|
||||
echo '+ { "Michael Müller", "ntdll: Implement loader redirection scheme.", 1 },'; \
|
||||
) > ntdll-DllRedirects.ok
|
||||
|
||||
# Patchset ntdll-Dynamic_DST
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,146 @@
|
||||
From 13b6ccee7fb76c5eb81b7e02afe25b58553cfebf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 13 Dec 2014 02:14:30 +0100
|
||||
Subject: ntdll: Move logic to determine loadorder HKCU/app key into separate
|
||||
functions.
|
||||
|
||||
---
|
||||
dlls/ntdll/loadorder.c | 104 +++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 58 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c
|
||||
index 401d256..d45a85f 100644
|
||||
--- a/dlls/ntdll/loadorder.c
|
||||
+++ b/dlls/ntdll/loadorder.c
|
||||
@@ -290,6 +290,60 @@ static inline enum loadorder get_env_load_order( const WCHAR *module )
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
+ * open_user_reg_key
|
||||
+ *
|
||||
+ * Return a handle to a registry key under HKCU.
|
||||
+ */
|
||||
+static HANDLE open_user_reg_key(const WCHAR *key_name)
|
||||
+{
|
||||
+ HANDLE hkey, root;
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ UNICODE_STRING nameW;
|
||||
+
|
||||
+ RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
|
||||
+ attr.Length = sizeof(attr);
|
||||
+ attr.RootDirectory = root;
|
||||
+ attr.ObjectName = &nameW;
|
||||
+ attr.Attributes = 0;
|
||||
+ attr.SecurityDescriptor = NULL;
|
||||
+ attr.SecurityQualityOfService = NULL;
|
||||
+ RtlInitUnicodeString( &nameW, key_name );
|
||||
+
|
||||
+ if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0;
|
||||
+ NtClose( root );
|
||||
+
|
||||
+ return hkey;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
+ * open_app_reg_key
|
||||
+ *
|
||||
+ * Return a handle to an app-specific registry key.
|
||||
+ */
|
||||
+static HANDLE open_app_reg_key( const WCHAR *sub_key, const WCHAR *app_name )
|
||||
+{
|
||||
+ static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
|
||||
+ 'A','p','p','D','e','f','a','u','l','t','s','\\',0};
|
||||
+ WCHAR *str;
|
||||
+ HANDLE hkey;
|
||||
+
|
||||
+ str = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
+ sizeof(AppDefaultsW) +
|
||||
+ strlenW(sub_key) * sizeof(WCHAR) +
|
||||
+ strlenW(app_name) * sizeof(WCHAR) );
|
||||
+ if (!str) return 0;
|
||||
+ strcpyW( str, AppDefaultsW );
|
||||
+ strcatW( str, app_name );
|
||||
+ strcatW( str, sub_key );
|
||||
+
|
||||
+ hkey = open_user_reg_key( str );
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, str );
|
||||
+ return hkey;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
* get_standard_key
|
||||
*
|
||||
* Return a handle to the standard DllOverrides registry section.
|
||||
@@ -301,24 +355,8 @@ static HANDLE get_standard_key(void)
|
||||
static HANDLE std_key = (HANDLE)-1;
|
||||
|
||||
if (std_key == (HANDLE)-1)
|
||||
- {
|
||||
- OBJECT_ATTRIBUTES attr;
|
||||
- UNICODE_STRING nameW;
|
||||
- HANDLE root;
|
||||
-
|
||||
- RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
|
||||
- attr.Length = sizeof(attr);
|
||||
- attr.RootDirectory = root;
|
||||
- attr.ObjectName = &nameW;
|
||||
- attr.Attributes = 0;
|
||||
- attr.SecurityDescriptor = NULL;
|
||||
- attr.SecurityQualityOfService = NULL;
|
||||
- RtlInitUnicodeString( &nameW, DllOverridesW );
|
||||
-
|
||||
- /* @@ Wine registry key: HKCU\Software\Wine\DllOverrides */
|
||||
- if (NtOpenKey( &std_key, KEY_ALL_ACCESS, &attr )) std_key = 0;
|
||||
- NtClose( root );
|
||||
- }
|
||||
+ std_key = open_user_reg_key( DllOverridesW );
|
||||
+
|
||||
return std_key;
|
||||
}
|
||||
|
||||
@@ -330,38 +368,12 @@ static HANDLE get_standard_key(void)
|
||||
*/
|
||||
static HANDLE get_app_key( const WCHAR *app_name )
|
||||
{
|
||||
- OBJECT_ATTRIBUTES attr;
|
||||
- UNICODE_STRING nameW;
|
||||
- HANDLE root;
|
||||
- WCHAR *str;
|
||||
- static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
|
||||
- 'A','p','p','D','e','f','a','u','l','t','s','\\',0};
|
||||
static const WCHAR DllOverridesW[] = {'\\','D','l','l','O','v','e','r','r','i','d','e','s',0};
|
||||
static HANDLE app_key = (HANDLE)-1;
|
||||
|
||||
- if (app_key != (HANDLE)-1) return app_key;
|
||||
+ if (app_key == (HANDLE)-1)
|
||||
+ app_key = open_app_reg_key( DllOverridesW, app_name );
|
||||
|
||||
- str = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
- sizeof(AppDefaultsW) + sizeof(DllOverridesW) +
|
||||
- strlenW(app_name) * sizeof(WCHAR) );
|
||||
- if (!str) return 0;
|
||||
- strcpyW( str, AppDefaultsW );
|
||||
- strcatW( str, app_name );
|
||||
- strcatW( str, DllOverridesW );
|
||||
-
|
||||
- RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
|
||||
- attr.Length = sizeof(attr);
|
||||
- attr.RootDirectory = root;
|
||||
- attr.ObjectName = &nameW;
|
||||
- attr.Attributes = 0;
|
||||
- attr.SecurityDescriptor = NULL;
|
||||
- attr.SecurityQualityOfService = NULL;
|
||||
- RtlInitUnicodeString( &nameW, str );
|
||||
-
|
||||
- /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DllOverrides */
|
||||
- if (NtOpenKey( &app_key, KEY_ALL_ACCESS, &attr )) app_key = 0;
|
||||
- NtClose( root );
|
||||
- RtlFreeHeap( GetProcessHeap(), 0, str );
|
||||
return app_key;
|
||||
}
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
@ -0,0 +1,85 @@
|
||||
From 659b7d1dce76b50a488472fd8fc53b1f4e9b48ce Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 13 Dec 2014 02:32:51 +0100
|
||||
Subject: ntdll: Move logic to read loadorder registry values into separate
|
||||
function.
|
||||
|
||||
---
|
||||
dlls/ntdll/loadorder.c | 40 ++++++++++++++++++++++++++++------------
|
||||
1 file changed, 28 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c
|
||||
index d45a85f..8250692 100644
|
||||
--- a/dlls/ntdll/loadorder.c
|
||||
+++ b/dlls/ntdll/loadorder.c
|
||||
@@ -379,25 +379,41 @@ static HANDLE get_app_key( const WCHAR *app_name )
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
- * get_registry_value
|
||||
+ * get_registry_string
|
||||
*
|
||||
- * Load the registry loadorder value for a given module.
|
||||
+ * Load a registry string for a given module.
|
||||
*/
|
||||
-static enum loadorder get_registry_value( HANDLE hkey, const WCHAR *module )
|
||||
+static WCHAR* get_registry_string( HANDLE hkey, const WCHAR *module, BYTE *buffer,
|
||||
+ ULONG size )
|
||||
{
|
||||
UNICODE_STRING valueW;
|
||||
- char buffer[80];
|
||||
DWORD count;
|
||||
+ WCHAR *ret = NULL;
|
||||
|
||||
RtlInitUnicodeString( &valueW, module );
|
||||
-
|
||||
- if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation,
|
||||
- buffer, sizeof(buffer), &count ))
|
||||
+ if (size >= sizeof(WCHAR) &&
|
||||
+ !NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation,
|
||||
+ buffer, size - sizeof(WCHAR), &count ))
|
||||
{
|
||||
- WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)buffer)->Data;
|
||||
- return parse_load_order( str );
|
||||
+ KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buffer;
|
||||
+ ret = (WCHAR *)info->Data;
|
||||
+ ret[info->DataLength / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
- return LO_INVALID;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
+ * get_registry_load_order
|
||||
+ *
|
||||
+ * Load the registry loadorder value for a given module.
|
||||
+ */
|
||||
+static enum loadorder get_registry_load_order( HANDLE hkey, const WCHAR *module )
|
||||
+{
|
||||
+ BYTE buffer[81];
|
||||
+ WCHAR *str = get_registry_string( hkey, module, buffer, sizeof(buffer) );
|
||||
+ return str ? parse_load_order( str ) : LO_INVALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -419,13 +435,13 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (app_key && ((ret = get_registry_value( app_key, module )) != LO_INVALID))
|
||||
+ if (app_key && ((ret = get_registry_load_order( app_key, module )) != LO_INVALID))
|
||||
{
|
||||
TRACE( "got app defaults %s for %s\n", debugstr_loadorder(ret), debugstr_w(module) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (std_key && ((ret = get_registry_value( std_key, module )) != LO_INVALID))
|
||||
+ if (std_key && ((ret = get_registry_load_order( std_key, module )) != LO_INVALID))
|
||||
{
|
||||
TRACE( "got standard key %s for %s\n", debugstr_loadorder(ret), debugstr_w(module) );
|
||||
return ret;
|
||||
--
|
||||
1.9.1
|
||||
|
@ -0,0 +1,87 @@
|
||||
From 219c4257ae314f8e2abe1e1567232336cdbbbdb4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 13 Dec 2014 02:57:41 +0100
|
||||
Subject: ntdll: Move code to determine module basename into separate function.
|
||||
|
||||
---
|
||||
dlls/ntdll/loadorder.c | 48 ++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 32 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c
|
||||
index 8250692..fbaa2d6 100644
|
||||
--- a/dlls/ntdll/loadorder.c
|
||||
+++ b/dlls/ntdll/loadorder.c
|
||||
@@ -452,25 +452,17 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
- * get_load_order (internal)
|
||||
+ * get_module_basename
|
||||
*
|
||||
- * Return the loadorder of a module.
|
||||
- * The system directory and '.dll' extension is stripped from the path.
|
||||
+ * Determine the module basename. The caller is responsible for releasing
|
||||
+ * the memory.
|
||||
*/
|
||||
-enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
|
||||
+static WCHAR* get_module_basename( const WCHAR *path, WCHAR **basename )
|
||||
{
|
||||
- enum loadorder ret = LO_INVALID;
|
||||
- HANDLE std_key, app_key = 0;
|
||||
- WCHAR *module, *basename;
|
||||
UNICODE_STRING path_str;
|
||||
+ WCHAR *module;
|
||||
int len;
|
||||
|
||||
- if (!init_done) init_load_order();
|
||||
- std_key = get_standard_key();
|
||||
- if (app_name) app_key = get_app_key( app_name );
|
||||
-
|
||||
- TRACE("looking for %s\n", debugstr_w(path));
|
||||
-
|
||||
/* Strip path information if the module resides in the system directory
|
||||
*/
|
||||
RtlInitUnicodeString( &path_str, path );
|
||||
@@ -481,12 +473,36 @@ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
|
||||
if (!strchrW( p, '\\' ) && !strchrW( p, '/' )) path = p;
|
||||
}
|
||||
|
||||
- if (!(len = strlenW(path))) return ret;
|
||||
- if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) ))) return ret;
|
||||
+ if (!(len = strlenW(path))) return NULL;
|
||||
+ if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) ))) return NULL;
|
||||
strcpyW( module+1, path ); /* reserve module[0] for the wildcard char */
|
||||
- basename = (WCHAR *)get_basename( module+1 );
|
||||
+ *basename = (WCHAR *)get_basename( module+1 );
|
||||
|
||||
if (len >= 4) remove_dll_ext( module + 1 + len - 4 );
|
||||
+ return module;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
+ * get_load_order (internal)
|
||||
+ *
|
||||
+ * Return the loadorder of a module.
|
||||
+ * The system directory and '.dll' extension is stripped from the path.
|
||||
+ */
|
||||
+enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
|
||||
+{
|
||||
+ enum loadorder ret = LO_INVALID;
|
||||
+ HANDLE std_key, app_key = 0;
|
||||
+ WCHAR *module, *basename;
|
||||
+
|
||||
+ if (!init_done) init_load_order();
|
||||
+ std_key = get_standard_key();
|
||||
+ if (app_name) app_key = get_app_key( app_name );
|
||||
+
|
||||
+ TRACE("looking for %s\n", debugstr_w(path));
|
||||
+
|
||||
+ if (!(module = get_module_basename(path, &basename)))
|
||||
+ return ret;
|
||||
|
||||
/* first explicit module name */
|
||||
if ((ret = get_load_order_value( std_key, app_key, module+1 )) != LO_INVALID)
|
||||
--
|
||||
1.9.1
|
||||
|
@ -0,0 +1,195 @@
|
||||
From 61fb04be5f07b22582095cbf7ed0f16408eeac53 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 13 Dec 2014 03:18:35 +0100
|
||||
Subject: ntdll: Implement get_redirect function.
|
||||
|
||||
---
|
||||
dlls/ntdll/loadorder.c | 120 +++++++++++++++++++++++++++++++++++++++++++++---
|
||||
dlls/ntdll/ntdll_misc.h | 1 +
|
||||
2 files changed, 114 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c
|
||||
index fbaa2d6..c7c4592 100644
|
||||
--- a/dlls/ntdll/loadorder.c
|
||||
+++ b/dlls/ntdll/loadorder.c
|
||||
@@ -344,11 +344,11 @@ static HANDLE open_app_reg_key( const WCHAR *sub_key, const WCHAR *app_name )
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
- * get_standard_key
|
||||
+ * get_override_standard_key
|
||||
*
|
||||
* Return a handle to the standard DllOverrides registry section.
|
||||
*/
|
||||
-static HANDLE get_standard_key(void)
|
||||
+static HANDLE get_override_standard_key(void)
|
||||
{
|
||||
static const WCHAR DllOverridesW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
|
||||
'D','l','l','O','v','e','r','r','i','d','e','s',0};
|
||||
@@ -362,11 +362,11 @@ static HANDLE get_standard_key(void)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
- * get_app_key
|
||||
+ * get_override_app_key
|
||||
*
|
||||
* Get the registry key for the app-specific DllOverrides list.
|
||||
*/
|
||||
-static HANDLE get_app_key( const WCHAR *app_name )
|
||||
+static HANDLE get_override_app_key( const WCHAR *app_name )
|
||||
{
|
||||
static const WCHAR DllOverridesW[] = {'\\','D','l','l','O','v','e','r','r','i','d','e','s',0};
|
||||
static HANDLE app_key = (HANDLE)-1;
|
||||
@@ -379,6 +379,41 @@ static HANDLE get_app_key( const WCHAR *app_name )
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
+ * get_redirect_standard_key
|
||||
+ *
|
||||
+ * Return a handle to the standard DllRedirects registry section.
|
||||
+ */
|
||||
+static HANDLE get_redirect_standard_key(void)
|
||||
+{
|
||||
+ static const WCHAR DllRedirectsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
|
||||
+ 'D','l','l','R','e','d','i','r','e','c','t','s',0};
|
||||
+ static HANDLE std_key = (HANDLE)-1;
|
||||
+
|
||||
+ if (std_key == (HANDLE)-1)
|
||||
+ std_key = open_user_reg_key( DllRedirectsW );
|
||||
+
|
||||
+ return std_key;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
+ * get_redirect_app_key
|
||||
+ *
|
||||
+ * Get the registry key for the app-specific DllRedirects list.
|
||||
+ */
|
||||
+static HANDLE get_redirect_app_key( const WCHAR *app_name )
|
||||
+{
|
||||
+ static const WCHAR DllRedirectsW[] = {'\\','D','l','l','R','e','d','i','r','e','c','t','s',0};
|
||||
+ static HANDLE app_key = (HANDLE)-1;
|
||||
+
|
||||
+ if (app_key == (HANDLE)-1)
|
||||
+ app_key = open_app_reg_key( DllRedirectsW, app_name );
|
||||
+
|
||||
+ return app_key;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
* get_registry_string
|
||||
*
|
||||
* Load a registry string for a given module.
|
||||
@@ -452,6 +487,34 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
+ * get_redirect_value
|
||||
+ *
|
||||
+ * Get the redirect value for the exact specified module string, looking in:
|
||||
+ * 1. The per-application DllRedirects key
|
||||
+ * 2. The standard DllRedirects key
|
||||
+ */
|
||||
+static WCHAR* get_redirect_value( HANDLE std_key, HANDLE app_key, const WCHAR *module,
|
||||
+ BYTE *buffer, ULONG size )
|
||||
+{
|
||||
+ WCHAR *ret = NULL;
|
||||
+
|
||||
+ if (app_key && (ret = get_registry_string( app_key, module, buffer, size )))
|
||||
+ {
|
||||
+ TRACE( "got app defaults %s for %s\n", debugstr_w(ret), debugstr_w(module) );
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (std_key && (ret = get_registry_string( std_key, module, buffer, size )))
|
||||
+ {
|
||||
+ TRACE( "got standard key %s for %s\n", debugstr_w(ret), debugstr_w(module) );
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
* get_module_basename
|
||||
*
|
||||
* Determine the module basename. The caller is responsible for releasing
|
||||
@@ -496,10 +559,10 @@ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
|
||||
WCHAR *module, *basename;
|
||||
|
||||
if (!init_done) init_load_order();
|
||||
- std_key = get_standard_key();
|
||||
- if (app_name) app_key = get_app_key( app_name );
|
||||
+ std_key = get_override_standard_key();
|
||||
+ if (app_name) app_key = get_override_app_key( app_name );
|
||||
|
||||
- TRACE("looking for %s\n", debugstr_w(path));
|
||||
+ TRACE("looking up loadorder for %s\n", debugstr_w(path));
|
||||
|
||||
if (!(module = get_module_basename(path, &basename)))
|
||||
return ret;
|
||||
@@ -533,3 +596,46 @@ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
|
||||
RtlFreeHeap( GetProcessHeap(), 0, module );
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+
|
||||
+/***************************************************************************
|
||||
+ * get_redirect (internal)
|
||||
+ *
|
||||
+ * Return the redirect value of a module.
|
||||
+ * The system directory and '.dll' extension is stripped from the path.
|
||||
+ */
|
||||
+WCHAR* get_redirect( const WCHAR *app_name, const WCHAR *path, BYTE *buffer, ULONG size )
|
||||
+{
|
||||
+ WCHAR *ret = NULL;
|
||||
+ HANDLE std_key, app_key = 0;
|
||||
+ WCHAR *module, *basename;
|
||||
+
|
||||
+ std_key = get_redirect_standard_key();
|
||||
+ if (app_name) app_key = get_redirect_app_key( app_name );
|
||||
+
|
||||
+ TRACE("looking up redirection for %s\n", debugstr_w(path));
|
||||
+
|
||||
+ if (!(module = get_module_basename(path, &basename)))
|
||||
+ return ret;
|
||||
+
|
||||
+ /* first explicit module name */
|
||||
+ if ((ret = get_redirect_value( std_key, app_key, module+1, buffer, size )))
|
||||
+ goto done;
|
||||
+
|
||||
+ /* then module basename preceded by '*' */
|
||||
+ basename[-1] = '*';
|
||||
+ if ((ret = get_redirect_value( std_key, app_key, basename-1, buffer, size )))
|
||||
+ goto done;
|
||||
+
|
||||
+ /* then module basename without '*' (only if explicit path) */
|
||||
+ if (basename != module+1 && (ret = get_redirect_value( std_key, app_key, basename, buffer, size )))
|
||||
+ goto done;
|
||||
+
|
||||
+ /* and last the hard-coded default */
|
||||
+ ret = NULL;
|
||||
+ TRACE( "no redirection found for %s\n", debugstr_w(path) );
|
||||
+
|
||||
+ done:
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, module );
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index aac9320..aa2e660 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -202,6 +202,7 @@ enum loadorder
|
||||
};
|
||||
|
||||
extern enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) DECLSPEC_HIDDEN;
|
||||
+extern WCHAR* get_redirect( const WCHAR *app_name, const WCHAR *path, BYTE *buffer, ULONG size ) DECLSPEC_HIDDEN;
|
||||
|
||||
struct debug_info
|
||||
{
|
||||
--
|
||||
1.9.1
|
||||
|
@ -0,0 +1,225 @@
|
||||
From ea4f613ec5b7e4cdc5cb9d850f66c194af9eb5e6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 13 Dec 2014 05:34:48 +0100
|
||||
Subject: ntdll: Implement loader redirection scheme.
|
||||
|
||||
---
|
||||
dlls/ntdll/loader.c | 66 +++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 44 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index e1444d2..c392f72 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -87,6 +87,7 @@ struct builtin_load_info
|
||||
{
|
||||
const WCHAR *load_path;
|
||||
const WCHAR *filename;
|
||||
+ const WCHAR *fakemodule;
|
||||
NTSTATUS status;
|
||||
WINE_MODREF *wm;
|
||||
};
|
||||
@@ -112,7 +113,8 @@ static WINE_MODREF *cached_modref;
|
||||
static WINE_MODREF *current_modref;
|
||||
static WINE_MODREF *last_failed_modref;
|
||||
|
||||
-static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm );
|
||||
+static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, LPCWSTR fakemodule,
|
||||
+ DWORD flags, WINE_MODREF** pwm );
|
||||
static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved );
|
||||
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
||||
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
|
||||
@@ -438,7 +440,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
|
||||
if (!(wm = find_basename_module( mod_name )))
|
||||
{
|
||||
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
|
||||
- if (load_dll( load_path, mod_name, 0, &wm ) == STATUS_SUCCESS &&
|
||||
+ if (load_dll( load_path, mod_name, NULL, 0, &wm ) == STATUS_SUCCESS &&
|
||||
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||
{
|
||||
if (process_attach( wm, NULL ) != STATUS_SUCCESS)
|
||||
@@ -587,7 +589,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
|
||||
{
|
||||
ascii_to_unicode( buffer, name, len );
|
||||
buffer[len] = 0;
|
||||
- status = load_dll( load_path, buffer, 0, &wmImp );
|
||||
+ status = load_dll( load_path, buffer, NULL, 0, &wmImp );
|
||||
}
|
||||
else /* need to allocate a larger buffer */
|
||||
{
|
||||
@@ -595,7 +597,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
|
||||
if (!ptr) return NULL;
|
||||
ascii_to_unicode( ptr, name, len );
|
||||
ptr[len] = 0;
|
||||
- status = load_dll( load_path, ptr, 0, &wmImp );
|
||||
+ status = load_dll( load_path, ptr, NULL, 0, &wmImp );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
@@ -906,7 +908,7 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
|
||||
* Allocate a WINE_MODREF structure and add it to the process list
|
||||
* The loader_section must be locked while calling this function.
|
||||
*/
|
||||
-static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
||||
+static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename, LPCWSTR fakemodule )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
const WCHAR *p;
|
||||
@@ -929,7 +931,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
||||
wm->ldr.TimeDateStamp = 0;
|
||||
wm->ldr.ActivationContext = 0;
|
||||
|
||||
- RtlCreateUnicodeString( &wm->ldr.FullDllName, filename );
|
||||
+ RtlCreateUnicodeString( &wm->ldr.FullDllName, fakemodule ? fakemodule : filename );
|
||||
if ((p = strrchrW( wm->ldr.FullDllName.Buffer, '\\' ))) p++;
|
||||
else p = wm->ldr.FullDllName.Buffer;
|
||||
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
|
||||
@@ -1546,7 +1548,7 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||
return;
|
||||
}
|
||||
|
||||
- wm = alloc_module( module, fullname );
|
||||
+ wm = alloc_module( module, fullname, builtin_load_info->fakemodule );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, fullname );
|
||||
if (!wm)
|
||||
{
|
||||
@@ -1602,8 +1604,8 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||
/******************************************************************************
|
||||
* load_native_dll (internal)
|
||||
*/
|
||||
-static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
|
||||
- DWORD flags, WINE_MODREF** pwm )
|
||||
+static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, LPCWSTR fakemodule,
|
||||
+ HANDLE file, DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
void *module;
|
||||
HANDLE mapping;
|
||||
@@ -1627,7 +1629,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
|
||||
|
||||
/* create the MODREF */
|
||||
|
||||
- if (!(wm = alloc_module( module, name )))
|
||||
+ if (!(wm = alloc_module( module, name, fakemodule )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
@@ -1689,8 +1691,8 @@ done:
|
||||
/***********************************************************************
|
||||
* load_builtin_dll
|
||||
*/
|
||||
-static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file,
|
||||
- DWORD flags, WINE_MODREF** pwm )
|
||||
+static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, LPCWSTR fakemodule,
|
||||
+ HANDLE file, DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
char error[256], dllname[MAX_PATH];
|
||||
const WCHAR *name, *p;
|
||||
@@ -1710,6 +1712,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file,
|
||||
*/
|
||||
info.load_path = load_path;
|
||||
info.filename = NULL;
|
||||
+ info.fakemodule = fakemodule;
|
||||
info.status = STATUS_SUCCESS;
|
||||
info.wm = NULL;
|
||||
|
||||
@@ -2028,14 +2031,14 @@ overflow:
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
-
|
||||
/***********************************************************************
|
||||
* load_dll (internal)
|
||||
*
|
||||
* Load a PE style module according to the load order.
|
||||
* The loader_section must be locked while calling this function.
|
||||
*/
|
||||
-static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
|
||||
+static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, LPCWSTR fakemodule,
|
||||
+ DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
enum loadorder loadorder;
|
||||
WCHAR buffer[32];
|
||||
@@ -2072,6 +2075,25 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||
}
|
||||
|
||||
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
|
||||
+
|
||||
+ /* handle dll redirection */
|
||||
+ if (!fakemodule)
|
||||
+ {
|
||||
+ BYTE buffer2[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
|
||||
+ WCHAR *redirect = get_redirect( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL,
|
||||
+ filename, buffer2, sizeof(buffer2) );
|
||||
+ if (redirect)
|
||||
+ {
|
||||
+ FIXME("Loader redirect from %s to %s\n", debugstr_w(libname), debugstr_w(redirect));
|
||||
+
|
||||
+ nts = load_dll( load_path, redirect, filename, flags, pwm );
|
||||
+
|
||||
+ if (handle) NtClose( handle );
|
||||
+ if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
|
||||
+ return nts;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
|
||||
|
||||
if (handle && is_fake_dll( handle ))
|
||||
@@ -2094,22 +2116,22 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||
if (!handle) nts = STATUS_DLL_NOT_FOUND;
|
||||
else
|
||||
{
|
||||
- nts = load_native_dll( load_path, filename, handle, flags, pwm );
|
||||
+ nts = load_native_dll( load_path, filename, fakemodule, handle, flags, pwm );
|
||||
if (nts == STATUS_INVALID_IMAGE_NOT_MZ)
|
||||
/* not in PE format, maybe it's a builtin */
|
||||
- nts = load_builtin_dll( load_path, filename, handle, flags, pwm );
|
||||
+ nts = load_builtin_dll( load_path, filename, fakemodule, handle, flags, pwm );
|
||||
}
|
||||
if (nts == STATUS_DLL_NOT_FOUND && loadorder == LO_NATIVE_BUILTIN)
|
||||
- nts = load_builtin_dll( load_path, filename, 0, flags, pwm );
|
||||
+ nts = load_builtin_dll( load_path, filename, fakemodule, 0, flags, pwm );
|
||||
break;
|
||||
case LO_BUILTIN:
|
||||
case LO_BUILTIN_NATIVE:
|
||||
case LO_DEFAULT: /* default is builtin,native */
|
||||
- nts = load_builtin_dll( load_path, filename, handle, flags, pwm );
|
||||
+ nts = load_builtin_dll( load_path, filename, fakemodule, handle, flags, pwm );
|
||||
if (!handle) break; /* nothing else we can try */
|
||||
/* file is not a builtin library, try without using the specified file */
|
||||
if (nts != STATUS_SUCCESS)
|
||||
- nts = load_builtin_dll( load_path, filename, 0, flags, pwm );
|
||||
+ nts = load_builtin_dll( load_path, filename, fakemodule, 0, flags, pwm );
|
||||
if (nts == STATUS_SUCCESS && loadorder == LO_DEFAULT &&
|
||||
(MODULE_InitDLL( *pwm, DLL_WINE_PREATTACH, NULL ) != STATUS_SUCCESS))
|
||||
{
|
||||
@@ -2119,7 +2141,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
if (nts == STATUS_DLL_NOT_FOUND && loadorder != LO_BUILTIN)
|
||||
- nts = load_native_dll( load_path, filename, handle, flags, pwm );
|
||||
+ nts = load_native_dll( load_path, filename, fakemodule, handle, flags, pwm );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2152,7 +2174,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
||||
- nts = load_dll( path_name, libname->Buffer, flags, &wm );
|
||||
+ nts = load_dll( path_name, libname->Buffer, NULL, flags, &wm );
|
||||
|
||||
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||
{
|
||||
@@ -3115,7 +3137,7 @@ void __wine_process_init(void)
|
||||
/* setup the load callback and create ntdll modref */
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
|
||||
- if ((status = load_builtin_dll( NULL, kernel32W, 0, 0, &wm )) != STATUS_SUCCESS)
|
||||
+ if ((status = load_builtin_dll( NULL, kernel32W, NULL, 0, 0, &wm )) != STATUS_SUCCESS)
|
||||
{
|
||||
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
|
||||
exit(1);
|
||||
--
|
||||
1.9.1
|
||||
|
1
patches/ntdll-DllRedirects/definition
Normal file
1
patches/ntdll-DllRedirects/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Support for loader dll redirections
|
Loading…
Reference in New Issue
Block a user