[httpdisk] Handle IOCTL_HTTP_DISK_DISCONNECT
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sun, 16 Jan 2011 17:42:26 +0000 (12:42 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sun, 16 Jan 2011 17:44:13 +0000 (12:44 -0500)
For disconnecting HTTPDisk PDOs from the bus.

Also added a check during disk thread termination to
disconnect the HTTPDisk.

Also moved HttpDiskCreateDevice() out of INIT-section
code, so it would be available at all times.

src/httpdisk/bus.c
src/httpdisk/httpdisk.c

index 987c060..dd32a19 100644 (file)
@@ -41,7 +41,8 @@ extern NTSTATUS STDCALL HttpdiskCreateDevice(
     IN PDEVICE_OBJECT *
   );
 extern NTSTATUS HttpDiskConnect(IN PDEVICE_OBJECT, IN PIRP);
-extern NTSTATUS HttpDiskDisconnect(IN PDEVICE_OBJECT, IN PIRP);
+extern PDEVICE_OBJECT HttpDiskDeleteDevice(IN PDEVICE_OBJECT);
+
 /** Exports. */
 NTSTATUS STDCALL HttpdiskBusEstablish(void);
 VOID HttpdiskBusCleanup(void);
@@ -54,6 +55,7 @@ static NTSTATUS STDCALL HttpdiskBusCreatePdo_(void);
 static VOID HttpdiskBusDeleteFdo_(void);
 static NTSTATUS STDCALL HttpdiskBusDevCtl_(IN PIRP);
 static NTSTATUS STDCALL HttpdiskBusAdd_(IN PIRP);
+static NTSTATUS STDCALL HttpdiskBusRemove_(IN PIRP);
 
 /* The HTTPDisk bus. */
 static WVL_S_BUS_T HttpdiskBus_ = {0};
@@ -270,7 +272,7 @@ static NTSTATUS STDCALL HttpdiskBusDevCtl_(IN PIRP irp) {
           return HttpdiskBusAdd_(irp);
 
         case IOCTL_HTTP_DISK_DISCONNECT:
-          break;
+          return HttpdiskBusRemove_(irp);
       }
     return WvlIrpComplete(irp, 0, STATUS_NOT_SUPPORTED);
   }
@@ -329,13 +331,62 @@ static NTSTATUS STDCALL HttpdiskBusAdd_(IN PIRP irp) {
     WvlBusRemoveNode(&dev->BusNode);
     err_add_node:
 
-    HttpDiskDisconnect(pdo, irp);
     err_connect:
 
-    IoDeleteDevice(pdo);
+    HttpDiskDeleteDevice(pdo);
     err_pdo:
 
     err_buf:
 
     return WvlIrpComplete(irp, 0, status);
   }
+
+static NTSTATUS STDCALL HttpdiskBusRemove_(IN PIRP irp) {
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    PUINT32 unit_num;
+    NTSTATUS status;
+    WVL_SP_BUS_NODE walker;
+    PDEVICE_OBJECT pdo = NULL;
+
+    /* Validate buffer size. */
+    if (
+        io_stack_loc->Parameters.DeviceIoControl.InputBufferLength <
+        sizeof *unit_num
+      ) {
+        DBG("Buffer too small.\n");
+        status = STATUS_INVALID_PARAMETER;
+        goto err_buf;
+      }
+    unit_num = irp->AssociatedIrp.SystemBuffer;
+
+    DBG("Request to detach unit %d...\n", *unit_num);
+
+    walker = NULL;
+    /* For each node on the bus... */
+    WvlBusLock(&HttpdiskBus_);
+    while (walker = WvlBusGetNextNode(&HttpdiskBus_, walker)) {
+        /* If the unit number matches... */
+        if (WvlBusGetNodeNum(walker) == *unit_num) {
+            pdo = WvlBusGetNodePdo(walker);
+            break;
+          }
+      }
+    WvlBusUnlock(&HttpdiskBus_);
+    if (!pdo) {
+        DBG("Unit %d not found.\n", *unit_num);
+        status = STATUS_INVALID_PARAMETER;
+        goto err_unit;
+      }
+    /* Detach and destroy the node. */
+    WvlBusRemoveNode(walker);
+    HttpDiskDeleteDevice(pdo);
+    DBG("Removed unit %d.\n", *unit_num);
+
+    return WvlIrpComplete(irp, 0, irp->IoStatus.Status);
+
+    err_unit:
+
+    err_buf:
+
+    return WvlIrpComplete(irp, 0, status);
+  }
index 12b0447..b7bbe9a 100644 (file)
@@ -327,6 +327,8 @@ DriverEntry (
     return status;
 }
 
+#pragma code_seg("PAGE")
+
 NTSTATUS STDCALL HttpdiskCreateDevice(
     IN WVL_E_DISK_MEDIA_TYPE Type,
     IN PDEVICE_OBJECT * Pdo
@@ -436,8 +438,6 @@ NTSTATUS STDCALL HttpdiskCreateDevice(
     return STATUS_SUCCESS;
   }
 
-#pragma code_seg("PAGE")
-
 VOID
 HttpDiskUnload (
     IN PDRIVER_OBJECT DriverObject
@@ -602,27 +602,6 @@ static NTSTATUS HttpdiskIrpDevCtl_(
 
     switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
     {
-    case IOCTL_HTTP_DISK_DISCONNECT:
-        {
-            IoMarkIrpPending(Irp);
-
-            ExInterlockedInsertTailList(
-                &device_extension->list_head,
-                &Irp->Tail.Overlay.ListEntry,
-                &device_extension->list_lock
-                );
-
-            KeSetEvent(
-                &device_extension->request_event,
-                (KPRIORITY) 0,
-                FALSE
-                );
-
-            status = STATUS_PENDING;
-
-            break;
-        }
-
     case IOCTL_DISK_CHECK_VERIFY:
     case IOCTL_CDROM_CHECK_VERIFY:
     case IOCTL_STORAGE_CHECK_VERIFY:
@@ -1035,6 +1014,12 @@ HttpDiskThread (
 
         if (device_extension->terminate_thread)
         {
+            /* Do we need to disconnect? */
+            if (device_extension->media_in_device) {
+                IRP dummy;
+
+                HttpDiskDisconnect(device_object, &dummy);
+              }
             PsTerminateSystemThread(STATUS_SUCCESS);
         }
 
@@ -1083,15 +1068,7 @@ HttpDiskThread (
                 break;
 
             case IRP_MJ_DEVICE_CONTROL:
-                switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
-                {
-                case IOCTL_HTTP_DISK_DISCONNECT:
-                    irp->IoStatus.Status = HttpDiskDisconnect(device_object, irp);
-                    break;
-
-                default:
-                    irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
-                }
+                irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                 break;
 
             case IRP_MJ_SCSI: