From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/hidclass.sys/hid.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index ff2e7eff47..b9bf13579f 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -34,8 +34,6 @@ #define DEFAULT_POLL_INTERVAL 200 #define MAX_POLL_INTERVAL_MSEC 10000
-typedef NTSTATUS (WINAPI *pAddDevice)(DRIVER_OBJECT *DriverObject, DEVICE_OBJECT *PhysicalDeviceObject); - /* Ring buffer functions */ struct ReportRingBuffer;
@@ -85,7 +83,7 @@ typedef struct _minidriver
PDRIVER_UNLOAD DriverUnload;
- pAddDevice AddDevice; + PDRIVER_ADD_DEVICE AddDevice; PDRIVER_DISPATCH PNPDispatch; struct list device_list; } minidriver;
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/hidclass.sys/device.c | 3 +-- dlls/hidclass.sys/hid.h | 2 +- dlls/hidclass.sys/pnp.c | 14 +++++++------- 3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 93187b54ac..e96177225b 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -174,8 +174,7 @@ static void WINAPI read_cancel_routine(DEVICE_OBJECT *device, IRP *irp) IoCompleteRequest(irp, IO_NO_INCREMENT); }
- -void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device) +void HID_DeleteDevice(DEVICE_OBJECT *device) { BASE_DEVICE_EXTENSION *ext; IRP *irp; diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index b9bf13579f..0f82323dfb 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -94,7 +94,7 @@ minidriver* find_minidriver(DRIVER_OBJECT* driver) DECLSPEC_HIDDEN; /* Internal device functions */ NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT **device) DECLSPEC_HIDDEN; NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; -void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device) DECLSPEC_HIDDEN; +void HID_DeleteDevice(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; void HID_StartDeviceThread(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 826ade92a4..8265efd9b4 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -122,7 +122,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Minidriver AddDevice failed (%x)\n",status); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); return status; }
@@ -132,7 +132,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Minidriver failed to get Attributes(%x)\n",status); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); return status; }
@@ -146,7 +146,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Cannot get Device Descriptor(%x)\n",status); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); return status; } for (i = 0; i < descriptor.bNumDescriptors; i++) @@ -156,7 +156,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (i >= descriptor.bNumDescriptors) { ERR("No Report Descriptor found in reply\n"); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); return status; }
@@ -166,7 +166,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Cannot get Report Descriptor(%x)\n",status); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); HeapFree(GetProcessHeap(), 0, reportDescriptor); return status; } @@ -177,7 +177,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (!ext->preparseData) { ERR("Cannot parse Report Descriptor\n"); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); return STATUS_NOT_SUPPORTED; }
@@ -217,7 +217,7 @@ NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT *device, IRP *ir
if (irp) rc = minidriver->PNPDispatch(device, irp); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DeleteDevice(device); LIST_FOR_EACH_ENTRY(hiddev, &minidriver->device_list, hid_device, entry) { if (hiddev->device == device)
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 12 ++++---- dlls/ntoskrnl.exe/tests/driver.c | 44 ++++++++++++++++++++++++------ dlls/ntoskrnl.exe/tests/driver.h | 1 + dlls/ntoskrnl.exe/tests/ntoskrnl.c | 11 ++++++-- include/ddk/ntifs.h | 1 + 5 files changed, 53 insertions(+), 16 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index cf4d8cbdbd..ec24e08618 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -516,6 +516,8 @@ static NTSTATUS dispatch_create( struct dispatch_context *context ) file->Size = sizeof(*file); file->DeviceObject = device;
+ device = IoGetAttachedDevice( device ); + if (!(irp = IoAllocateIrp( device->StackSize, FALSE ))) return STATUS_NO_MEMORY;
irpsp = IoGetNextIrpStackLocation( irp ); @@ -550,7 +552,7 @@ static NTSTATUS dispatch_close( struct dispatch_context *context )
if (!file) return STATUS_INVALID_HANDLE;
- device = file->DeviceObject; + device = IoGetAttachedDevice( file->DeviceObject );
TRACE( "device %p file %p\n", device, file );
@@ -590,7 +592,7 @@ static NTSTATUS dispatch_read( struct dispatch_context *context )
if (!file) return STATUS_INVALID_HANDLE;
- device = file->DeviceObject; + device = IoGetAttachedDevice( file->DeviceObject );
TRACE( "device %p file %p size %u\n", device, file, out_size );
@@ -630,7 +632,7 @@ static NTSTATUS dispatch_write( struct dispatch_context *context )
if (!file) return STATUS_INVALID_HANDLE;
- device = file->DeviceObject; + device = IoGetAttachedDevice( file->DeviceObject );
TRACE( "device %p file %p size %u\n", device, file, context->in_size );
@@ -665,7 +667,7 @@ static NTSTATUS dispatch_flush( struct dispatch_context *context )
if (!file) return STATUS_INVALID_HANDLE;
- device = file->DeviceObject; + device = IoGetAttachedDevice( file->DeviceObject );
TRACE( "device %p file %p\n", device, file );
@@ -697,7 +699,7 @@ static NTSTATUS dispatch_ioctl( struct dispatch_context *context )
if (!file) return STATUS_INVALID_HANDLE;
- device = file->DeviceObject; + device = IoGetAttachedDevice( file->DeviceObject );
TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n", context->params.ioctl.code, device, file, context->in_size, out_size ); diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 468b183637..f5801a5162 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -34,12 +34,15 @@
#include "driver.h"
-static const WCHAR driver_device[] = {'\','D','e','v','i','c','e', - '\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0}; +static const WCHAR device_name[] = {'\','D','e','v','i','c','e', + '\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0}; +static const WCHAR upper_name[] = {'\','D','e','v','i','c','e', + '\','W','i','n','e','T','e','s','t','U','p','p','e','r',0}; 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 DEVICE_OBJECT *lower_device, *upper_device;
static HANDLE okfile; static LONG successes; @@ -234,10 +237,11 @@ static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+ ok(device == upper_device, "Expected device %p, got %p.\n", upper_device, device); ok(last_created_file != NULL, "last_created_file = NULL\n"); ok(irpsp->FileObject == last_created_file, "FileObject != last_created_file\n"); - ok(irpsp->DeviceObject == device, "unexpected DeviceObject\n"); - ok(irpsp->FileObject->DeviceObject == device, "unexpected FileObject->DeviceObject\n"); + ok(irpsp->DeviceObject == upper_device, "unexpected DeviceObject\n"); + ok(irpsp->FileObject->DeviceObject == lower_device, "unexpected FileObject->DeviceObject\n"); ok(!irp->UserEvent, "UserEvent = %p\n", irp->UserEvent); ok(irp->Tail.Overlay.Thread == (PETHREAD)KeGetCurrentThread(), "IRP thread is not the current thread\n"); @@ -1591,7 +1595,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
- main_test_work_item = IoAllocateWorkItem(device); + main_test_work_item = IoAllocateWorkItem(lower_device); ok(main_test_work_item != NULL, "main_test_work_item = NULL\n");
IoQueueWorkItem(main_test_work_item, main_test_task, DelayedWorkQueue, irp); @@ -1687,6 +1691,10 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp) case IOCTL_WINETEST_GET_CANCEL_COUNT: status = get_cancel_count(irp, stack, &irp->IoStatus.Information); break; + case IOCTL_WINETEST_DETACH: + IoDetachDevice(lower_device); + status = STATUS_SUCCESS; + break; default: break; } @@ -1703,6 +1711,7 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); + ok(device == lower_device, "Expected device %p, got %p.\n", lower_device, device); ok(irpsp->DeviceObject == device, "device != DeviceObject\n"); ok(irp->Tail.Overlay.Thread == (PETHREAD)KeGetCurrentThread(), "IRP thread is not the current thread\n"); @@ -1726,13 +1735,13 @@ static VOID WINAPI driver_Unload(DRIVER_OBJECT *driver) RtlInitUnicodeString(&linkW, driver_link); IoDeleteSymbolicLink(&linkW);
- IoDeleteDevice(driver->DeviceObject); + IoDeleteDevice(upper_device); + IoDeleteDevice(lower_device); }
NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) { UNICODE_STRING nameW, linkW; - DEVICE_OBJECT *device; NTSTATUS status;
DbgPrint("loading driver\n"); @@ -1748,12 +1757,29 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) driver->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = driver_FlushBuffers; driver->MajorFunction[IRP_MJ_CLOSE] = driver_Close;
- RtlInitUnicodeString(&nameW, driver_device); + RtlInitUnicodeString(&nameW, device_name); RtlInitUnicodeString(&linkW, driver_link);
if (!(status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN, - FILE_DEVICE_SECURE_OPEN, FALSE, &device))) + FILE_DEVICE_SECURE_OPEN, FALSE, &lower_device))) + { status = IoCreateSymbolicLink(&linkW, &nameW); + lower_device->Flags &= ~DO_DEVICE_INITIALIZING; + } + + if (!status) + { + RtlInitUnicodeString(&nameW, upper_name); + + status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, FALSE, &upper_device); + } + + if (!status) + { + IoAttachDeviceToDeviceStack(upper_device, lower_device); + upper_device->Flags &= ~DO_DEVICE_INITIALIZING; + }
return status; } diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index 1e7552996b..d5ff09ac42 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -28,6 +28,7 @@ #define IOCTL_WINETEST_RESET_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_TEST_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_GET_CANCEL_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_DETACH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
static const char teststr[] = "Wine is not an emulator";
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 43418f3bb2..19eeca20bc 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -63,8 +63,6 @@ static void unload_driver(SC_HANDLE service) { SERVICE_STATUS status;
- CloseHandle(device); - ControlService(service, SERVICE_CONTROL_STOP, &status); while (status.dwCurrentState == SERVICE_STOP_PENDING) { @@ -343,6 +341,8 @@ START_TEST(ntoskrnl) { char filename[MAX_PATH], filename2[MAX_PATH]; SC_HANDLE service, service2; + DWORD written; + BOOL ret;
HMODULE hntdll = GetModuleHandleA("ntdll.dll"); pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); @@ -368,6 +368,13 @@ START_TEST(ntoskrnl) test_overlapped(); test_load_driver(service2);
+ /* We need a separate ioctl to call IoDetachDevice(); calling it in the + * driver unload routine causes a live-lock. */ + ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL); + ok(ret, "DeviceIoControl failed: %u\n", GetLastError()); + + CloseHandle(device); + unload_driver(service2); unload_driver(service); ok(DeleteFileA(filename), "DeleteFile failed: %u\n", GetLastError()); diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index acdd232720..b287b06799 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -130,6 +130,7 @@ typedef struct _FS_FILTER_CALLBACKS } FS_FILTER_CALLBACKS, *PFS_FILTER_CALLBACKS;
BOOLEAN WINAPI FsRtlIsNameInExpression(PUNICODE_STRING, PUNICODE_STRING, BOOLEAN, PWCH); +DEVICE_OBJECT * WINAPI IoGetAttachedDevice(DEVICE_OBJECT*); NTSTATUS WINAPI ObOpenObjectByPointer(void*,ULONG,PACCESS_STATE,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE,HANDLE*); NTSTATUS WINAPI ObQueryNameString(PVOID,POBJECT_NAME_INFORMATION,ULONG,PULONG); BOOLEAN WINAPI PsIsSystemThread(PETHREAD);
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/pnp.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 20e1538c1a..e7303b6100 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -176,6 +176,8 @@ static NTSTATUS get_device_id( DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WC IO_STATUS_BLOCK irp_status; IRP *irp;
+ device = IoGetAttachedDevice( device ); + if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, device, NULL, 0, NULL, NULL, &irp_status ))) return STATUS_NO_MEMORY;
@@ -192,6 +194,8 @@ static NTSTATUS send_pnp_irp( DEVICE_OBJECT *device, UCHAR minor ) IO_STATUS_BLOCK irp_status; IRP *irp;
+ device = IoGetAttachedDevice( device ); + if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, device, NULL, 0, NULL, NULL, &irp_status ))) return STATUS_NO_MEMORY;
@@ -291,6 +295,8 @@ static NTSTATUS send_power_irp( DEVICE_OBJECT *device, DEVICE_POWER_STATE power IO_STACK_LOCATION *irpsp; IRP *irp;
+ device = IoGetAttachedDevice( device ); + if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_POWER, device, NULL, 0, NULL, NULL, &irp_status ))) return STATUS_NO_MEMORY;
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index ec24e08618..a0812dc7c9 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -1466,9 +1466,12 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, ULONG characteristics, BOOLEAN exclusive, DEVICE_OBJECT **ret_device ) { + static const WCHAR auto_format[] = {'\','D','e','v','i','c','e','\','%','0','8','x',0}; NTSTATUS status; DEVICE_OBJECT *device; HANDLE manager = get_device_manager(); + static unsigned int auto_idx = 0; + WCHAR autoW[17];
TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n", driver, ext_size, debugstr_us(name), type, characteristics, exclusive, ret_device ); @@ -1481,15 +1484,34 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, device->DeviceType = type; device->StackSize = 1;
- SERVER_START_REQ( create_device ) + if (characteristics & FILE_AUTOGENERATED_DEVICE_NAME) { - req->rootdir = 0; - req->manager = wine_server_obj_handle( manager ); - req->user_ptr = wine_server_client_ptr( device ); - if (name) wine_server_add_data( req, name->Buffer, name->Length ); - status = wine_server_call( req ); + do + { + sprintfW( autoW, auto_format, auto_idx++ ); + SERVER_START_REQ( create_device ) + { + req->rootdir = 0; + req->manager = wine_server_obj_handle( manager ); + req->user_ptr = wine_server_client_ptr( device ); + wine_server_add_data( req, autoW, strlenW(autoW) * sizeof(WCHAR) ); + status = wine_server_call( req ); + } + SERVER_END_REQ; + } while (status == STATUS_OBJECT_NAME_COLLISION); + } + else + { + SERVER_START_REQ( create_device ) + { + req->rootdir = 0; + req->manager = wine_server_obj_handle( manager ); + req->user_ptr = wine_server_client_ptr( device ); + if (name) wine_server_add_data( req, name->Buffer, name->Length ); + status = wine_server_call( req ); + } + SERVER_END_REQ; } - SERVER_END_REQ;
if (status) {