Piotr Caban : ntoskrnl.exe: Fix IoAttachDeviceToDeviceStack implementation.

Alexandre Julliard julliard at winehq.org
Mon May 27 14:50:21 CDT 2019


Module: wine
Branch: master
Commit: 294cfaf077308891689b0738a47ac67b5edfd61d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=294cfaf077308891689b0738a47ac67b5edfd61d

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon May 27 14:37:49 2019 +0200

ntoskrnl.exe: Fix IoAttachDeviceToDeviceStack implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/ntoskrnl.c     | 32 +++++++++++-----------
 dlls/ntoskrnl.exe/tests/driver.c | 58 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 08353b2..10cf2e2 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1222,6 +1222,21 @@ void WINAPI IoQueueWorkItem( PIO_WORKITEM work_item, PIO_WORKITEM_ROUTINE worker
     TrySubmitThreadpoolCallback( run_work_item_worker, work_item, NULL );
 }
 
+/***********************************************************************
+ *           IoGetAttachedDevice   (NTOSKRNL.EXE.@)
+ */
+DEVICE_OBJECT* WINAPI IoGetAttachedDevice( DEVICE_OBJECT *device )
+{
+    DEVICE_OBJECT *result = device;
+
+    TRACE( "(%p)\n", device );
+
+    while (result->AttachedDevice)
+        result = result->AttachedDevice;
+
+    return result;
+}
+
 void WINAPI IoDetachDevice( DEVICE_OBJECT *device )
 {
     device->AttachedDevice = NULL;
@@ -1234,6 +1249,7 @@ PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
                                                    DEVICE_OBJECT *target )
 {
     TRACE( "%p, %p\n", source, target );
+    target = IoGetAttachedDevice( target );
     target->AttachedDevice = source;
     source->StackSize = target->StackSize + 1;
     return target;
@@ -1799,22 +1815,6 @@ NTSTATUS  WINAPI IoGetDeviceObjectPointer( UNICODE_STRING *name, ACCESS_MASK acc
 }
 
 /***********************************************************************
- *           IoGetAttachedDevice   (NTOSKRNL.EXE.@)
- */
-DEVICE_OBJECT* WINAPI IoGetAttachedDevice( DEVICE_OBJECT *device )
-{
-    DEVICE_OBJECT *result = device;
-
-    TRACE( "(%p)\n", device );
-
-    while (result->AttachedDevice)
-        result = result->AttachedDevice;
-
-    return result;
-}
-
-
-/***********************************************************************
  *           IoGetDeviceProperty   (NTOSKRNL.EXE.@)
  */
 NTSTATUS WINAPI IoGetDeviceProperty( DEVICE_OBJECT *device, DEVICE_REGISTRY_PROPERTY device_property,
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 688c608..73fc2fb 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -39,6 +39,8 @@ static const WCHAR driver_device[] = {'\\','D','e','v','i','c','e',
 static const WCHAR driver_link[] = {'\\','D','o','s','D','e','v','i','c','e','s',
                                     '\\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0};
 
+static DRIVER_OBJECT *driver_obj;
+
 static HANDLE okfile;
 static LONG successes;
 static LONG failures;
@@ -1424,6 +1426,59 @@ static void test_lookup_thread(void)
        "PsLookupThreadByThreadId returned %#x\n", status);
 }
 
+static void test_IoAttachDeviceToDeviceStack(void)
+{
+    DEVICE_OBJECT *dev1, *dev2, *dev3, *ret;
+    NTSTATUS status;
+
+    status = IoCreateDevice(driver_obj, 0, NULL, FILE_DEVICE_UNKNOWN,
+            FILE_DEVICE_SECURE_OPEN, FALSE, &dev1);
+    ok(status == STATUS_SUCCESS, "IoCreateDevice failed\n");
+    status = IoCreateDevice(driver_obj, 0, NULL, FILE_DEVICE_UNKNOWN,
+            FILE_DEVICE_SECURE_OPEN, FALSE, &dev2);
+    ok(status == STATUS_SUCCESS, "IoCreateDevice failed\n");
+    status = IoCreateDevice(driver_obj, 0, NULL, FILE_DEVICE_UNKNOWN,
+            FILE_DEVICE_SECURE_OPEN, FALSE, &dev3);
+    ok(status == STATUS_SUCCESS, "IoCreateDevice failed\n");
+
+    /* TODO: initialize devices properly */
+    dev1->Flags &= ~DO_DEVICE_INITIALIZING;
+    dev2->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    ret = IoAttachDeviceToDeviceStack(dev2, dev1);
+    ok(ret == dev1, "IoAttachDeviceToDeviceStack returned %p, expected %p\n", ret, dev1);
+    ok(dev1->AttachedDevice == dev2, "dev1->AttachedDevice = %p, expected %p\n",
+            dev1->AttachedDevice, dev2);
+    ok(!dev2->AttachedDevice, "dev2->AttachedDevice = %p\n", dev2->AttachedDevice);
+    ok(dev1->StackSize == 1, "dev1->StackSize = %d\n", dev1->StackSize);
+    ok(dev2->StackSize == 2, "dev2->StackSize = %d\n", dev2->StackSize);
+
+    ret = IoAttachDeviceToDeviceStack(dev3, dev1);
+    ok(ret == dev2, "IoAttachDeviceToDeviceStack returned %p, expected %p\n", ret, dev2);
+    ok(dev1->AttachedDevice == dev2, "dev1->AttachedDevice = %p, expected %p\n",
+            dev1->AttachedDevice, dev2);
+    ok(dev2->AttachedDevice == dev3, "dev2->AttachedDevice = %p, expected %p\n",
+            dev2->AttachedDevice, dev3);
+    ok(!dev3->AttachedDevice, "dev3->AttachedDevice = %p\n", dev3->AttachedDevice);
+    ok(dev1->StackSize == 1, "dev1->StackSize = %d\n", dev1->StackSize);
+    ok(dev2->StackSize == 2, "dev2->StackSize = %d\n", dev2->StackSize);
+    ok(dev3->StackSize == 3, "dev3->StackSize = %d\n", dev3->StackSize);
+
+    IoDetachDevice(dev1);
+    ok(!dev1->AttachedDevice, "dev1->AttachedDevice = %p\n", dev1->AttachedDevice);
+    ok(dev2->AttachedDevice == dev3, "dev2->AttachedDevice = %p\n", dev2->AttachedDevice);
+
+    IoDetachDevice(dev2);
+    ok(!dev2->AttachedDevice, "dev2->AttachedDevice = %p\n", dev2->AttachedDevice);
+    ok(dev1->StackSize == 1, "dev1->StackSize = %d\n", dev1->StackSize);
+    ok(dev2->StackSize == 2, "dev2->StackSize = %d\n", dev2->StackSize);
+    ok(dev3->StackSize == 3, "dev3->StackSize = %d\n", dev3->StackSize);
+
+    IoDeleteDevice(dev1);
+    IoDeleteDevice(dev2);
+    IoDeleteDevice(dev3);
+}
+
 static PIO_WORKITEM main_test_work_item;
 
 static void WINAPI main_test_task(DEVICE_OBJECT *device, void *context)
@@ -1501,6 +1556,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
     test_ob_reference(test_input->path);
     test_resource();
     test_lookup_thread();
+    test_IoAttachDeviceToDeviceStack();
 
     if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
 
@@ -1647,6 +1703,8 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry)
 
     DbgPrint("loading driver\n");
 
+    driver_obj = driver;
+
     /* Allow unloading of the driver */
     driver->DriverUnload = driver_Unload;
 




More information about the wine-cvs mailing list