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