Aric Stewart : hidclass.sys: Unload all devices before unloading a minidriver.

Alexandre Julliard julliard at winehq.org
Wed Aug 15 14:39:54 CDT 2018


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Aug  6 09:21:12 2018 -0500

hidclass.sys: Unload all devices before unloading a minidriver.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/hid.h  |  8 ++++++++
 dlls/hidclass.sys/main.c |  8 ++++++++
 dlls/hidclass.sys/pnp.c  | 35 +++++++++++++++++++++++++++++++----
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 1829319..4e8ba3c 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -70,6 +70,12 @@ void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
 struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
 NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *buffer, UINT size) DECLSPEC_HIDDEN;
 
+typedef struct _hiddevice
+{
+    struct list entry;
+    DEVICE_OBJECT *device;
+} hid_device;
+
 typedef struct _minidriver
 {
     struct list entry;
@@ -80,6 +86,7 @@ typedef struct _minidriver
 
     pAddDevice AddDevice;
     PDRIVER_DISPATCH PNPDispatch;
+    struct list device_list;
 } minidriver;
 
 NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in_size, void *out_buff, ULONG out_size) DECLSPEC_HIDDEN;
@@ -100,6 +107,7 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDE
 
 /* Pseudo-Plug and Play support*/
 NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN;
+NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT* device, IRP* irp) DECLSPEC_HIDDEN;
 
 /* Parsing HID Report Descriptors into preparsed data */
 WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length) DECLSPEC_HIDDEN;
diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c
index 1742cfe..8bb423b 100644
--- a/dlls/hidclass.sys/main.c
+++ b/dlls/hidclass.sys/main.c
@@ -49,6 +49,12 @@ static VOID WINAPI UnloadDriver(DRIVER_OBJECT *driver)
     md = find_minidriver(driver);
     if (md)
     {
+        hid_device *device, *next;
+        TRACE("%i devices to unload\n", list_count(&md->device_list));
+        LIST_FOR_EACH_ENTRY_SAFE(device, next, &md->device_list, hid_device, entry)
+        {
+            PNP_RemoveDevice(md, device->device, NULL);
+        }
         if (md->DriverUnload)
             md->DriverUnload(md->minidriver.DriverObject);
         list_remove(&md->entry);
@@ -82,6 +88,8 @@ NTSTATUS WINAPI HidRegisterMinidriver(HID_MINIDRIVER_REGISTRATION *registration)
     driver->minidriver = *registration;
     list_add_tail(&minidriver_list, &driver->entry);
 
+    list_init(&driver->device_list);
+
     return STATUS_SUCCESS;
 }
 
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 30d1045..6ee89c1 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -75,6 +75,7 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH
 
 NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
 {
+    hid_device *hiddev;
     DEVICE_OBJECT *device = NULL;
     NTSTATUS status;
     minidriver *minidriver;
@@ -96,13 +97,19 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
     TRACE("PDO add device(%p:%s)\n", PDO, debugstr_w(PDO_id));
     minidriver = find_minidriver(driver);
 
-    status = HID_CreateDevice(PDO, &minidriver->minidriver, &device);
+    hiddev = HeapAlloc(GetProcessHeap(), 0, sizeof(*hiddev));
+    if (!hiddev)
+        return STATUS_NO_MEMORY;
+
+    status = HID_CreateDevice(PDO, &minidriver->minidriver, &hiddev->device);
     if (status != STATUS_SUCCESS)
     {
         ERR("Failed to create HID object (%x)\n",status);
         HeapFree(GetProcessHeap(), 0, PDO_id);
+        HeapFree(GetProcessHeap(), 0, hiddev);
         return status;
     }
+    device = hiddev->device;
 
     ext = device->DeviceExtension;
     InitializeListHead(&ext->irp_queue);
@@ -177,6 +184,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
         return STATUS_NOT_SUPPORTED;
     }
 
+    list_add_tail(&(minidriver->device_list), &hiddev->entry);
+
     ext->information.DescriptorSize = ext->preparseData->dwSize;
 
     lstrcpyW(ext->instance_id, device_enumeratorW);
@@ -200,6 +209,26 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
     return STATUS_SUCCESS;
 }
 
+NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT *device, IRP *irp)
+{
+    hid_device *hiddev;
+    NTSTATUS rc = STATUS_NOT_SUPPORTED;
+
+    if (irp)
+        rc = minidriver->PNPDispatch(device, irp);
+    HID_DeleteDevice(&minidriver->minidriver, device);
+    LIST_FOR_EACH_ENTRY(hiddev,  &minidriver->device_list, hid_device, entry)
+    {
+        if (hiddev->device == device)
+        {
+            list_remove(&hiddev->entry);
+            HeapFree(GetProcessHeap(), 0, hiddev);
+            break;
+        }
+    }
+    return rc;
+}
+
 NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
 {
     NTSTATUS rc = STATUS_NOT_SUPPORTED;
@@ -255,9 +284,7 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
         }
         case IRP_MN_REMOVE_DEVICE:
         {
-            rc = minidriver->PNPDispatch(device, irp);
-            HID_DeleteDevice(&minidriver->minidriver, device);
-            return rc;
+            return PNP_RemoveDevice(minidriver, device, irp);
         }
         default:
         {




More information about the wine-cvs mailing list