Paul Gofman : ntoskrnl.exe: Call load image notify routines for driver modules.
Alexandre Julliard
julliard at winehq.org
Fri May 29 15:22:55 CDT 2020
Module: wine
Branch: master
Commit: 5d92cf7dbf11038c08eb35a042958faab3ef5b83
URL: https://source.winehq.org/git/wine.git/?a=commit;h=5d92cf7dbf11038c08eb35a042958faab3ef5b83
Author: Paul Gofman <pgofman at codeweavers.com>
Date: Fri May 29 10:53:12 2020 +0300
ntoskrnl.exe: Call load image notify routines for driver modules.
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 24 ++++++++++++++++
dlls/ntoskrnl.exe/tests/driver.c | 60 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 94733ec60a..fbf6262b3e 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -3673,6 +3673,30 @@ static HMODULE load_driver( const WCHAR *driver_name, const UNICODE_STRING *keyn
TRACE( "loading driver %s\n", wine_dbgstr_w(str) );
module = load_driver_module( str );
+
+ if (module && load_image_notify_routine_count)
+ {
+ UNICODE_STRING module_name;
+ IMAGE_NT_HEADERS *nt;
+ IMAGE_INFO info;
+ unsigned int i;
+
+ RtlInitUnicodeString(&module_name, str);
+ nt = RtlImageNtHeader(module);
+ memset(&info, 0, sizeof(info));
+ info.u.s.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
+ info.u.s.SystemModeImage = TRUE;
+ info.ImageSize = nt->OptionalHeader.SizeOfImage;
+ info.ImageBase = module;
+
+ for (i = 0; i < load_image_notify_routine_count; ++i)
+ {
+ TRACE("Calling image load notify %p.\n", load_image_notify_routines[i]);
+ load_image_notify_routines[i](&module_name, NULL, &info);
+ TRACE("Called image load notify %p.\n", load_image_notify_routines[i]);
+ }
+ }
+
HeapFree( GetProcessHeap(), 0, path );
return module;
}
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index f6cc442bab..ba2b4d6ac8 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -308,21 +308,79 @@ static const WCHAR driver2_path[] = {
'\\','W','i','n','e','T','e','s','t','D','r','i','v','e','r','2',0
};
+static IMAGE_INFO test_image_info;
+static int test_load_image_notify_count;
+static WCHAR test_load_image_name[MAX_PATH];
+
+static void WINAPI test_load_image_notify_routine(UNICODE_STRING *image_name, HANDLE process_id,
+ IMAGE_INFO *image_info)
+{
+ if (test_load_image_notify_count == -1
+ || (image_name->Buffer && wcsstr(image_name->Buffer, L".tmp")))
+ {
+ ++test_load_image_notify_count;
+ test_image_info = *image_info;
+ wcscpy(test_load_image_name, image_name->Buffer);
+ }
+}
+
static void test_load_driver(void)
{
- UNICODE_STRING name;
+ static WCHAR image_path_key_name[] = L"ImagePath";
+ RTL_QUERY_REGISTRY_TABLE query_table[2];
+ UNICODE_STRING name, image_path;
NTSTATUS ret;
+ ret = PsSetLoadImageNotifyRoutine(test_load_image_notify_routine);
+ ok(ret == STATUS_SUCCESS, "Got unexpected status %#x.\n", ret);
+
+ /* Routine gets registered twice on Windows. */
+ ret = PsSetLoadImageNotifyRoutine(test_load_image_notify_routine);
+ ok(ret == STATUS_SUCCESS, "Got unexpected status %#x.\n", ret);
+
+ RtlInitUnicodeString(&image_path, NULL);
+ memset(query_table, 0, sizeof(query_table));
+ query_table[0].QueryRoutine = NULL;
+ query_table[0].Name = image_path_key_name;
+ query_table[0].EntryContext = &image_path;
+ query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
+ query_table[0].DefaultType = REG_EXPAND_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT;
+
+ ret = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, driver2_path, query_table, NULL, NULL);
+ ok(ret == STATUS_SUCCESS, "Got unexpected status %#x.\n", ret);
+ ok(!!image_path.Buffer, "image_path.Buffer is NULL.\n");
+
RtlInitUnicodeString(&name, driver2_path);
ret = ZwLoadDriver(&name);
ok(!ret, "got %#x\n", ret);
+ ok(test_load_image_notify_count == 2, "Got unexpected test_load_image_notify_count %u.\n",
+ test_load_image_notify_count);
+ ok(test_image_info.ImageAddressingMode == IMAGE_ADDRESSING_MODE_32BIT,
+ "Got unexpected ImageAddressingMode %#x.\n", test_image_info.ImageAddressingMode);
+ ok(test_image_info.SystemModeImage,
+ "Got unexpected SystemModeImage %#x.\n", test_image_info.SystemModeImage);
+ ok(!wcscmp(test_load_image_name, image_path.Buffer), "Image path names do not match.\n");
+
+ test_load_image_notify_count = -1;
+
ret = ZwLoadDriver(&name);
ok(ret == STATUS_IMAGE_ALREADY_LOADED, "got %#x\n", ret);
ret = ZwUnloadDriver(&name);
ok(!ret, "got %#x\n", ret);
+
+ ret = PsRemoveLoadImageNotifyRoutine(test_load_image_notify_routine);
+ ok(ret == STATUS_SUCCESS, "Got unexpected status %#x.\n", ret);
+ ret = PsRemoveLoadImageNotifyRoutine(test_load_image_notify_routine);
+ ok(ret == STATUS_SUCCESS, "Got unexpected status %#x.\n", ret);
+ ret = PsRemoveLoadImageNotifyRoutine(test_load_image_notify_routine);
+ ok(ret == STATUS_PROCEDURE_NOT_FOUND, "Got unexpected status %#x.\n", ret);
+
+ ok(test_load_image_notify_count == -1, "Got unexpected test_load_image_notify_count %u.\n",
+ test_load_image_notify_count);
+ RtlFreeUnicodeString(&image_path);
}
static NTSTATUS wait_single(void *obj, ULONGLONG timeout)
More information about the wine-cvs
mailing list