Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 4 ++-- include/ddk/wdm.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index d50eac6c821..3cb5591920d 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2807,9 +2807,9 @@ void FASTCALL ObfDereferenceObject( void *obj ) /*********************************************************************** * ObRegisterCallbacks (NTOSKRNL.EXE.@) */ -NTSTATUS WINAPI ObRegisterCallbacks(POB_CALLBACK_REGISTRATION *callBack, void **handle) +NTSTATUS WINAPI ObRegisterCallbacks(POB_CALLBACK_REGISTRATION callback, void **handle) { - FIXME( "stub: %p %p\n", callBack, handle ); + FIXME( "callback %p, handle %p.\n", callback, handle );
if(handle) *handle = UlongToHandle(0xdeadbeaf); diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 38a3098994b..a67377352d8 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1749,7 +1749,7 @@ static inline void *MmGetSystemAddressForMdlSafe(MDL *mdl, ULONG priority) void FASTCALL ObfReferenceObject(void*); void WINAPI ObDereferenceObject(void*); USHORT WINAPI ObGetFilterVersion(void); -NTSTATUS WINAPI ObRegisterCallbacks(POB_CALLBACK_REGISTRATION*, void**); +NTSTATUS WINAPI ObRegisterCallbacks(POB_CALLBACK_REGISTRATION, void**); NTSTATUS WINAPI ObReferenceObjectByHandle(HANDLE,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE,PVOID*,POBJECT_HANDLE_INFORMATION); NTSTATUS WINAPI ObReferenceObjectByName(UNICODE_STRING*,ULONG,ACCESS_STATE*,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE,void*,void**); NTSTATUS WINAPI ObReferenceObjectByPointer(void*,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE);
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 3cb5591920d..09d4796ad4b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2059,7 +2059,7 @@ NTSTATUS WINAPI ExCreateCallback(PCALLBACK_OBJECT *obj, POBJECT_ATTRIBUTES attr, { FIXME("(%p, %p, %u, %u): stub\n", obj, attr, create, allow_multiple);
- return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; }
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 9 +++++++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- include/ddk/wdm.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 09d4796ad4b..f0892141c26 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2062,6 +2062,14 @@ NTSTATUS WINAPI ExCreateCallback(PCALLBACK_OBJECT *obj, POBJECT_ATTRIBUTES attr, return STATUS_SUCCESS; }
+void * WINAPI ExRegisterCallback(PCALLBACK_OBJECT callback_object, + PCALLBACK_FUNCTION callback_function, void *callback_context) +{ + FIXME("callback_object %p, callback_function %p, callback_context %p stub.\n", + callback_object, callback_function, callback_context); + + return (void *)0xdeadbeef; +}
/*********************************************************************** * ExFreePool (NTOSKRNL.EXE.@) @@ -3046,6 +3054,7 @@ PVOID WINAPI MmGetSystemRoutineAddress(PUNICODE_STRING SystemRoutineName) if (!pFunc) { hMod = GetModuleHandleW( halW ); + if (hMod) pFunc = GetProcAddress( hMod, routineNameA.Buffer ); } RtlFreeAnsiString( &routineNameA ); diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 72a620a3f7a..23a2b8e6ee4 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -183,7 +183,7 @@ @ stub ExRaiseException @ stub ExRaiseHardError @ stub ExRaiseStatus -@ stub ExRegisterCallback +@ stdcall ExRegisterCallback(ptr ptr ptr) @ stub ExReinitializeResourceLite @ stdcall ExReleaseResourceForThreadLite(ptr long) @ extern ExSemaphoreObjectType diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index a67377352d8..282ea14b77d 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1356,6 +1356,7 @@ typedef void * (NTAPI *PALLOCATE_FUNCTION)(POOL_TYPE, SIZE_T, ULONG); typedef void * (NTAPI *PALLOCATE_FUNCTION_EX)(POOL_TYPE, SIZE_T, ULONG, PLOOKASIDE_LIST_EX); typedef void (NTAPI *PFREE_FUNCTION)(void *); typedef void (NTAPI *PFREE_FUNCTION_EX)(void *, PLOOKASIDE_LIST_EX); +typedef void (NTAPI *PCALLBACK_FUNCTION)(void *, void *, void *);
#ifdef _WIN64 #define LOOKASIDE_ALIGN DECLSPEC_CACHEALIGN @@ -1627,6 +1628,7 @@ PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPI LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); BOOLEAN WINAPI ExIsResourceAcquiredExclusiveLite(ERESOURCE*); ULONG WINAPI ExIsResourceAcquiredSharedLite(ERESOURCE*); +void * WINAPI ExRegisterCallback(PCALLBACK_OBJECT,PCALLBACK_FUNCTION,void*); void FASTCALL ExReleaseFastMutexUnsafe(PFAST_MUTEX); void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN);
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 5 +++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- include/ddk/wdm.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index f0892141c26..3c8b207a4a3 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2071,6 +2071,11 @@ void * WINAPI ExRegisterCallback(PCALLBACK_OBJECT callback_object, return (void *)0xdeadbeef; }
+void WINAPI ExUnregisterCallback(void *callback_registration) +{ + FIXME("callback_registration %p stub.\n", callback_registration); +} + /*********************************************************************** * ExFreePool (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 23a2b8e6ee4..95e31f2c12a 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -191,7 +191,7 @@ @ stdcall ExSetTimerResolution(long long) @ stub ExSystemExceptionFilter @ stdcall ExSystemTimeToLocalTime(ptr ptr) RtlSystemTimeToLocalTime -@ stub ExUnregisterCallback +@ stdcall ExUnregisterCallback(ptr) @ stdcall ExUuidCreate(ptr) @ stub ExVerifySuite @ stub ExWindowStationObjectType diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 282ea14b77d..0d98680cfa5 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1632,6 +1632,7 @@ void * WINAPI ExRegisterCallback(PCALLBACK_OBJECT,PCALLBACK_FUNCTION,void*); void FASTCALL ExReleaseFastMutexUnsafe(PFAST_MUTEX); void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN); +void WINAPI ExUnregisterCallback(void*);
void WINAPI IoAcquireCancelSpinLock(KIRQL*); NTSTATUS WINAPI IoAcquireRemoveLockEx(IO_REMOVE_LOCK*,void*,const char*,ULONG, ULONG);
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 11 +++++++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ntoskrnl.exe/tests/driver.c | 37 +++++++++++++++++++++++++++++ include/ddk/wdm.h | 1 + 4 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 3c8b207a4a3..e9c35cf7e31 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -975,6 +975,17 @@ void WINAPI IoInitializeIrp( IRP *irp, USHORT size, CCHAR stack_size ) (PIO_STACK_LOCATION)(irp + 1) + stack_size; }
+void WINAPI IoReuseIrp(IRP *irp, NTSTATUS iostatus) +{ + UCHAR AllocationFlags; + + TRACE("irp %p, iostatus %#x.\n", irp, iostatus); + + AllocationFlags = irp->AllocationFlags; + IoInitializeIrp(irp, irp->Size, irp->StackCount); + irp->AllocationFlags = AllocationFlags; + irp->IoStatus.u.Status = iostatus; +}
/*********************************************************************** * IoInitializeTimer (NTOSKRNL.EXE.@) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 95e31f2c12a..2b7f57e895f 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -462,7 +462,7 @@ @ stub IoReportTargetDeviceChange @ stub IoReportTargetDeviceChangeAsynchronous @ stub IoRequestDeviceEject -@ stub IoReuseIrp +@ stdcall IoReuseIrp(ptr long) @ stub IoSetCompletionRoutineEx @ stdcall IoSetDeviceInterfaceState(ptr long) @ stub IoSetDeviceToVerify diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index e762ad0ccd7..f6cc442bab0 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -211,9 +211,18 @@ static void *get_proc_address(const char *name) static FILE_OBJECT *last_created_file; static unsigned int create_count, close_count;
+static NTSTATUS WINAPI test_irp_struct_completion_routine(DEVICE_OBJECT *reserved, IRP *irp, void *context) +{ + unsigned int *result = context; + + *result = 1; + return STATUS_MORE_PROCESSING_REQUIRED; +} + static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + unsigned int irp_completion_result;
ok(device == upper_device, "Expected device %p, got %p.\n", upper_device, device); ok(last_created_file != NULL, "last_created_file = NULL\n"); @@ -225,6 +234,34 @@ static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device) "IRP thread is not the current thread\n");
ok(IoGetRequestorProcess(irp) == IoGetCurrentProcess(), "processes didn't match\n"); + + irp = IoAllocateIrp(1, FALSE); + ok(irp->AllocationFlags == IRP_ALLOCATED_FIXED_SIZE, "Got unexpected irp->AllocationFlags %#x.\n", + irp->AllocationFlags); + ok(irp->CurrentLocation == 2, + "Got unexpected irp->CurrentLocation %u.\n", irp->CurrentLocation); + IoSetCompletionRoutine(irp, test_irp_struct_completion_routine, &irp_completion_result, + TRUE, TRUE, TRUE); + + irp_completion_result = 0; + + irp->IoStatus.Status = STATUS_SUCCESS; + --irp->CurrentLocation; + --irp->Tail.Overlay.CurrentStackLocation; + IoCompleteRequest(irp, IO_NO_INCREMENT); + ok(irp->CurrentLocation == 2, + "Got unexpected irp->CurrentLocation %u.\n", irp->CurrentLocation); + ok(irp_completion_result, "IRP completion was not called.\n"); + + --irp->CurrentLocation; + --irp->Tail.Overlay.CurrentStackLocation; + IoReuseIrp(irp, STATUS_UNSUCCESSFUL); + ok(irp->CurrentLocation == 2, + "Got unexpected irp->CurrentLocation %u.\n", irp->CurrentLocation); + ok(irp->AllocationFlags == IRP_ALLOCATED_FIXED_SIZE, "Got unexpected irp->AllocationFlags %#x.\n", + irp->AllocationFlags); + + IoFreeIrp(irp); }
static void test_mdl_map(void) diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 0d98680cfa5..57e4cf4fe53 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1679,6 +1679,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(PDEVICE_OBJECT,const GUID*,PUNICODE_S void WINAPI IoReleaseCancelSpinLock(KIRQL); void WINAPI IoReleaseRemoveLockAndWaitEx(IO_REMOVE_LOCK*,void*,ULONG); void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG); +void WINAPI IoReuseIrp(IRP*,NTSTATUS); NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN); NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- include/ddk/ntddk.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index 36f69cdf9a2..e3c91240231 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -107,6 +107,8 @@ typedef enum _CONFIGURATION_TYPE MaximumType } CONFIGURATION_TYPE, *PCONFIGURATION_TYPE;
+#define IMAGE_ADDRESSING_MODE_32BIT 3 + typedef struct _IMAGE_INFO { union @@ -118,7 +120,11 @@ typedef struct _IMAGE_INFO ULONG SystemModeImage : 1; ULONG ImageMappedToAllPids : 1; ULONG ExtendedInfoPresent : 1; - ULONG Reserved : 21; + ULONG MachineTypeMismatch : 1; + ULONG ImageSignatureLevel : 4; + ULONG ImageSignatureType : 3; + ULONG ImagePartialMap : 1; + ULONG Reserved : 12; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; PVOID ImageBase;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 28 ++++++++++++++++++++++++---- include/ddk/ntddk.h | 1 + 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index e9c35cf7e31..94733ec60a0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -85,6 +85,9 @@ static DWORD client_tid;
static HANDLE ntoskrnl_heap;
+static PLOAD_IMAGE_NOTIFY_ROUTINE load_image_notify_routines[8]; +static unsigned int load_image_notify_routine_count; + struct wine_driver { DRIVER_OBJECT driver_obj; @@ -3001,10 +3004,21 @@ NTSTATUS WINAPI PsRemoveCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE /*********************************************************************** * PsRemoveLoadImageNotifyRoutine (NTOSKRNL.EXE.@) */ - NTSTATUS WINAPI PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) +NTSTATUS WINAPI PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine) { - FIXME( "stub: %p\n", NotifyRoutine ); - return STATUS_SUCCESS; + unsigned int i; + + TRACE("routine %p.\n", routine); + + for (i = 0; i < load_image_notify_routine_count; ++i) + if (load_image_notify_routines[i] == routine) + { + --load_image_notify_routine_count; + memmove(&load_image_notify_routines[i], &load_image_notify_routines[i + 1], + sizeof(*load_image_notify_routines) * (load_image_notify_routine_count - i)); + return STATUS_SUCCESS; + } + return STATUS_PROCEDURE_NOT_FOUND; }
@@ -3160,7 +3174,13 @@ NTSTATUS WINAPI IoWMIOpenBlock(LPCGUID guid, ULONG desired_access, PVOID *data_b */ NTSTATUS WINAPI PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine) { - FIXME("(%p) stub\n", routine); + FIXME("routine %p, semi-stub.\n", routine); + + if (load_image_notify_routine_count == ARRAY_SIZE(load_image_notify_routines)) + return STATUS_INSUFFICIENT_RESOURCES; + + load_image_notify_routines[load_image_notify_routine_count++] = routine; + return STATUS_SUCCESS; }
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index e3c91240231..2b05fda7118 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -231,6 +231,7 @@ BOOLEAN WINAPI MmIsAddressValid(void *); HANDLE WINAPI PsGetProcessId(PEPROCESS); HANDLE WINAPI PsGetThreadId(PETHREAD); HANDLE WINAPI PsGetThreadProcessId(PETHREAD); +NTSTATUS WINAPI PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE); NTSTATUS WINAPI PsSetCreateProcessNotifyRoutine(PCREATE_PROCESS_NOTIFY_ROUTINE,BOOLEAN); NTSTATUS WINAPI PsSetCreateProcessNotifyRoutineEx(PCREATE_PROCESS_NOTIFY_ROUTINE_EX,BOOLEAN); NTSTATUS WINAPI PsSetCreateThreadNotifyRoutine(PCREATE_THREAD_NOTIFY_ROUTINE);
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- include/winternl.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/winternl.h b/include/winternl.h index 652e1dbaf05..633b5fe6114 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2008,6 +2008,9 @@ typedef void (NTAPI *RTL_WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN); /* FIXME: not #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 #define RTL_QUERY_REGISTRY_DIRECT 0x00000020 #define RTL_QUERY_REGISTRY_DELETE 0x00000040 +#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100 + +#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 24
typedef NTSTATUS (WINAPI *PRTL_QUERY_REGISTRY_ROUTINE)( PCWSTR ValueName, ULONG ValueType,
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- 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 94733ec60a0..fbf6262b3eb 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 f6cc442bab0..bfc2db3adbf 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, u".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[] = u"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)