[PATCH v2 2/2] ntdll: make find_dll_file load 16 bit dlls.
Oleh Nykyforchyn
oleh.nyk at gmail.com
Thu Oct 14 18:02:02 CDT 2021
Don't release nt_name in find_builtin_without_file for
STATUS_INVALID_IMAGE_NOT_MZ and use it to try to load
*.so instead of 16 bit fake dll, replace "-windows",
if found in the path, with "-unix", and append ".so".
--
Now Wine can't start any 16 bit app because if fails to
load krnl386.exe16. To load any 16 bit dll, ntdll uses
find_builtin_without_file -> open_dll_file -> NtCreateSection
which makes a request ( create_mapping ) to wineserver, which
in turn fails, hence nt_name of the fake dll is cleared.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51564
Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>
---
dlls/ntdll/loader.c | 48 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 797d72aedb6..d731b474e41 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2723,15 +2723,17 @@ static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *ne
if (found_image) status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
done:
- RtlFreeUnicodeString( new_name );
if (!status)
{
+ RtlFreeUnicodeString( new_name );
new_name->Length = (4 + wcslen(system_dir) + wcslen(name)) * sizeof(WCHAR);
new_name->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, new_name->Length + sizeof(WCHAR) );
wcscpy( new_name->Buffer, L"\\??\\" );
wcscat( new_name->Buffer, system_dir );
wcscat( new_name->Buffer, name );
}
+ else if (status != STATUS_INVALID_IMAGE_NOT_MZ)
+ RtlFreeUnicodeString( new_name );
return status;
}
@@ -2783,7 +2785,8 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *
if (found_image)
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
else if (is_prefix_bootstrap && !contains_path( search ))
- status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id );
+ if ((status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id )))
+ RtlFreeUnicodeString( nt_name );
done:
RtlFreeHeap( GetProcessHeap(), 0, name );
@@ -2800,7 +2803,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
UNICODE_STRING *nt_name, WINE_MODREF **pwm, HANDLE *mapping,
SECTION_IMAGE_INFORMATION *image_info, struct file_id *id )
{
- WCHAR *ext, *dllname;
+ WCHAR *ext, *dllname, *ch;
NTSTATUS status;
ULONG wow64_old_value = 0;
@@ -2854,7 +2857,46 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
/* 16-bit files can't be loaded from the prefix */
if (status && libname[0] && libname[1] && !wcscmp( libname + wcslen(libname) - 2, L"16" ) && !contains_path( libname ))
+ {
status = find_builtin_without_file( libname, nt_name, pwm, mapping, image_info, id );
+ if (status == STATUS_INVALID_IMAGE_NOT_MZ)
+ {
+ ch =wcsstr( nt_name->Buffer, L"-windows\\" );
+ if (ch)
+ {
+ *(++ch) = L'u';
+ *(++ch) = L'n';
+ *(++ch) = L'i';
+ *(++ch) = L'x';
+ ch++;
+ do *ch = *(ch + 3);
+ while (*(ch++));
+ nt_name->Length -= 3 * sizeof(WCHAR);
+ }
+ if ((nt_name->Length < 3 * sizeof(WCHAR)) || wcsncmp( nt_name->Buffer + (nt_name->Length / sizeof(WCHAR) - 3 ), L".so", 3))
+ {
+ if (ch)
+ {
+ wcscat( nt_name->Buffer, L".so" );
+ nt_name->Length += 3 * sizeof(WCHAR);
+ }
+ else
+ {
+ if (!(ch = RtlAllocateHeap( GetProcessHeap(), 0,
+ (nt_name->Length + 4 * sizeof(WCHAR)))))
+ return STATUS_NO_MEMORY;
+ wcscpy( ch, nt_name->Buffer );
+ wcscat( ch, L".so" );
+ RtlFreeHeap( GetProcessHeap(), 0, nt_name->Buffer );
+ nt_name->Buffer = ch;
+ nt_name->Length += 3 * sizeof(WCHAR);
+ }
+ }
+ }
+ else
+ RtlFreeUnicodeString( nt_name );
+
+ }
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) status = STATUS_INVALID_IMAGE_FORMAT;
--
2.33.0
More information about the wine-devel
mailing list