Alexandre Julliard : ntdll: Implement LdrQueryImageFileExecutionOptions and use it to retrieve the per-process global flag .
Alexandre Julliard
julliard at winehq.org
Wed Jan 20 14:29:45 CST 2010
Module: wine
Branch: master
Commit: 1c119dad6dc9a5ca029e76e23ea64057bb31d2d3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1c119dad6dc9a5ca029e76e23ea64057bb31d2d3
Author: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list