Module: wine Branch: master Commit: 1c119dad6dc9a5ca029e76e23ea64057bb31d2d3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1c119dad6dc9a5ca029e76e23e...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jan 20 17:11:03 2010 +0100
ntdll: Implement LdrQueryImageFileExecutionOptions and use it to retrieve the per-process global flag.
---
dlls/ntdll/loader.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 2 +- include/winternl.h | 1 + 3 files changed, 106 insertions(+), 1 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e3d7adb..c16e0f6 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2199,6 +2199,106 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smi, }
+static NTSTATUS query_dword_option( HANDLE hkey, LPCWSTR name, ULONG *value ) +{ + NTSTATUS status; + UNICODE_STRING str; + ULONG size; + WCHAR buffer[64]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + + RtlInitUnicodeString( &str, name ); + + size = sizeof(buffer) - sizeof(WCHAR); + if ((status = NtQueryValueKey( hkey, &str, KeyValuePartialInformation, buffer, size, &size ))) + return status; + + if (info->Type != REG_DWORD) + { + buffer[size / sizeof(WCHAR)] = 0; + *value = strtoulW( (WCHAR *)info->Data, 0, 16 ); + } + else memcpy( value, info->Data, sizeof(*value) ); + return status; +} + +static NTSTATUS query_string_option( HANDLE hkey, LPCWSTR name, ULONG type, + void *data, ULONG in_size, ULONG *out_size ) +{ + NTSTATUS status; + UNICODE_STRING str; + ULONG size; + char *buffer; + KEY_VALUE_PARTIAL_INFORMATION *info; + static const int info_size = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data ); + + RtlInitUnicodeString( &str, name ); + + size = info_size + in_size; + if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY; + info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + status = NtQueryValueKey( hkey, &str, KeyValuePartialInformation, buffer, size, &size ); + if (!status || status == STATUS_BUFFER_OVERFLOW) + { + if (out_size) *out_size = info->DataLength; + if (data && !status) memcpy( data, info->Data, info->DataLength ); + } + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + return status; +} + + +/****************************************************************** + * LdrQueryImageFileExecutionOptions (NTDLL.@) + */ +NTSTATUS WINAPI LdrQueryImageFileExecutionOptions( const UNICODE_STRING *key, LPCWSTR value, ULONG type, + void *data, ULONG in_size, ULONG *out_size ) +{ + static const WCHAR optionsW[] = {'M','a','c','h','i','n','e','\', + 'S','o','f','t','w','a','r','e','\', + 'M','i','c','r','o','s','o','f','t','\', + 'W','i','n','d','o','w','s',' ','N','T','\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', + 'I','m','a','g','e',' ','F','i','l','e',' ', + 'E','x','e','c','u','t','i','o','n',' ','O','p','t','i','o','n','s','\'}; + WCHAR path[MAX_PATH + sizeof(optionsW)/sizeof(WCHAR)]; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING name_str; + HANDLE hkey; + NTSTATUS status; + ULONG len; + WCHAR *p; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &name_str; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + if ((p = memrchrW( key->Buffer, '\', key->Length / sizeof(WCHAR) ))) p++; + else p = key->Buffer; + len = key->Length - (p - key->Buffer) * sizeof(WCHAR); + name_str.Buffer = path; + name_str.Length = sizeof(optionsW) + len; + name_str.MaximumLength = name_str.Length; + memcpy( path, optionsW, sizeof(optionsW) ); + memcpy( path + sizeof(optionsW)/sizeof(WCHAR), p, len ); + if ((status = NtOpenKey( &hkey, KEY_QUERY_VALUE, &attr ))) return status; + + if (type == REG_DWORD) + { + if (out_size) *out_size = sizeof(ULONG); + if (in_size >= sizeof(ULONG)) status = query_dword_option( hkey, value, data ); + else status = STATUS_BUFFER_OVERFLOW; + } + else status = query_string_option( hkey, value, type, data, in_size, out_size ); + + NtClose( hkey ); + return status; +} + + /****************************************************************** * RtlDllShutdownInProgress (NTDLL.@) */ @@ -2466,6 +2566,7 @@ static void start_process( void *kernel_start ) void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2, ULONG_PTR unknown3, ULONG_PTR unknown4 ) { + static const WCHAR globalflagW[] = {'G','l','o','b','a','l','F','l','a','g',0}; NTSTATUS status; WINE_MODREF *wm; LPCWSTR load_path; @@ -2487,6 +2588,9 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2, peb->ProcessParameters->ImagePathName = wm->ldr.FullDllName; version_init( wm->ldr.FullDllName.Buffer );
+ LdrQueryImageFileExecutionOptions( &peb->ProcessParameters->ImagePathName, globalflagW, + REG_DWORD, &peb->NtGlobalFlag, sizeof(peb->NtGlobalFlag), NULL ); + /* the main exe needs to be the first in the load order list */ RemoveEntryList( &wm->ldr.InLoadOrderModuleList ); InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList ); diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 0b3ebef..67a9d13 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -73,7 +73,7 @@ @ stdcall LdrLoadDll(wstr long ptr ptr) @ stdcall LdrLockLoaderLock(long ptr ptr) @ stdcall LdrProcessRelocationBlock(ptr long ptr long) -@ stub LdrQueryImageFileExecutionOptions +@ stdcall LdrQueryImageFileExecutionOptions(ptr wstr long ptr long ptr) @ stdcall LdrQueryProcessModuleInformation(ptr long ptr) @ stub LdrSetAppCompatDllRedirectionCallback @ stub LdrSetDllManifestProber diff --git a/include/winternl.h b/include/winternl.h index 6860950..a4dd93b 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1873,6 +1873,7 @@ NTSYSAPI void WINAPI LdrInitializeThunk(void*,ULONG_PTR,ULONG_PTR,ULONG_PTR NTSYSAPI NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*); NTSYSAPI NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG*); IMAGE_BASE_RELOCATION * WINAPI LdrProcessRelocationBlock(void*,UINT,USHORT*,INT_PTR); +NTSYSAPI NTSTATUS WINAPI LdrQueryImageFileExecutionOptions(const UNICODE_STRING*,LPCWSTR,ULONG,void*,ULONG,ULONG*); NTSYSAPI NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*); NTSYSAPI void WINAPI LdrShutdownProcess(void); NTSYSAPI void WINAPI LdrShutdownThread(void);