[project] Don't use mini IRP handling for IRP_MJ_PNP
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 13 Dec 2010 21:50:08 +0000 (16:50 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 13 Dec 2010 21:50:08 +0000 (16:50 -0500)
Use device::irp_mj.pnp(), instead.

This is the last of the IRP_MJ_* major functions that were
previously handled with the mini IRP handling scheme.

WinVBlock.dev
src/include/bus_pnp.h [deleted file]
src/include/device.h
src/include/disk_pnp.h [deleted file]
src/winvblock/bus/bus.c
src/winvblock/bus/pnp.c
src/winvblock/device.c
src/winvblock/disk/disk.c
src/winvblock/disk/pnp.c
src/winvblock/driver.c

index 8eaad79..36cd41e 100644 (file)
@@ -1,7 +1,7 @@
 [Project]\r
 FileName=WinVBlock.dev\r
 Name=WinVBlock\r
-UnitCount=66\r
+UnitCount=64\r
 PchHead=-1\r
 PchSource=-1\r
 Ver=3\r
@@ -164,16 +164,6 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit30]\r
-FileName=src\include\debug.h\r
-CompileCpp=1\r
-Folder=Include\r
-Compile=1\r
-Link=1\r
-Priority=1000\r
-OverrideBuildCmd=0\r
-BuildCmd=\r
-\r
-[Unit31]\r
 FileName=src\include\disk.h\r
 CompileCpp=1\r
 Folder=Include\r
@@ -184,7 +174,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit34]\r
-FileName=src\include\filedisk.h\r
+FileName=src\include\httpdisk.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -194,7 +184,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit35]\r
-FileName=src\include\grub4dos.h\r
+FileName=src\include\irp.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -204,7 +194,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit36]\r
-FileName=src\include\httpdisk.h\r
+FileName=src\include\mdi.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -224,7 +214,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit37]\r
-FileName=src\include\irp.h\r
+FileName=src\include\memdisk.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -234,7 +224,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit38]\r
-FileName=src\include\mdi.h\r
+FileName=src\include\mount.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -244,7 +234,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit39]\r
-FileName=src\include\memdisk.h\r
+FileName=src\include\portable.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -254,7 +244,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit40]\r
-FileName=src\include\mount.h\r
+FileName=src\include\probe.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -264,7 +254,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit41]\r
-FileName=src\include\portable.h\r
+FileName=src\include\protocol.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -274,7 +264,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit42]\r
-FileName=src\include\probe.h\r
+FileName=src\include\ramdisk.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -284,7 +274,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit43]\r
-FileName=src\include\protocol.h\r
+FileName=src\include\registry.h\r
 Folder=Include\r
 Compile=1\r
 Link=1\r
@@ -294,7 +284,7 @@ BuildCmd=
 CompileCpp=1\r
 \r
 [Unit44]\r
-FileName=src\include\ramdisk.h\r
+FileName=src\include\resource.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -304,7 +294,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit45]\r
-FileName=src\include\registry.h\r
+FileName=src\include\winvblock.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -314,9 +304,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit46]\r
-FileName=src\include\resource.h\r
+FileName=src\util\mount.c\r
 CompileCpp=1\r
-Folder=Include\r
+Folder=Util\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -324,19 +314,19 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit47]\r
-FileName=src\include\winvblock.h\r
-Folder=Include\r
+FileName=src\aoe\aoe.rc\r
+Folder=AoE\r
 Compile=1\r
-Link=1\r
+Link=0\r
 Priority=1000\r
 OverrideBuildCmd=0\r
 BuildCmd=\r
 CompileCpp=1\r
 \r
 [Unit48]\r
-FileName=src\util\mount.c\r
+FileName=src\include\device.h\r
 CompileCpp=1\r
-Folder=Util\r
+Folder=Include\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -344,19 +334,19 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit49]\r
-FileName=src\aoe\aoe.rc\r
+FileName=src\winvblock\device.c\r
 CompileCpp=1\r
-Folder=AoE\r
+Folder=WinVBlock\r
 Compile=1\r
-Link=0\r
+Link=1\r
 Priority=1000\r
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
 [Unit50]\r
-FileName=src\include\device.h\r
+FileName=src\winvblock\filedisk\filedisk.c\r
 CompileCpp=1\r
-Folder=Include\r
+Folder=WinVBlock/FileDisk\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -364,8 +354,8 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit51]\r
-FileName=src\winvblock\device.c\r
-Folder=WinVBlock\r
+FileName=src\winvblock\filedisk\grub4dos.c\r
+Folder=WinVBlock/FileDisk\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -374,9 +364,9 @@ BuildCmd=
 CompileCpp=1\r
 \r
 [Unit52]\r
-FileName=src\winvblock\filedisk\filedisk.c\r
+FileName=src\include\byte.h\r
 CompileCpp=1\r
-Folder=WinVBlock/FileDisk\r
+Folder=Include\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -562,8 +552,8 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit53]\r
-FileName=src\winvblock\filedisk\grub4dos.c\r
-Folder=WinVBlock/FileDisk\r
+FileName=src\include\msvhd.h\r
+Folder=Include\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -572,17 +562,17 @@ BuildCmd=
 CompileCpp=1\r
 \r
 [Unit54]\r
-FileName=src\include\byte.h\r
+FileName=src\util\winvblock.rc\r
 CompileCpp=1\r
-Folder=Include\r
+Folder=Util\r
 Compile=1\r
-Link=1\r
+Link=0\r
 Priority=1000\r
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
 [Unit55]\r
-FileName=src\include\msvhd.h\r
+FileName=src\include\wv_stdlib.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -602,17 +592,17 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit56]\r
-FileName=src\util\winvblock.rc\r
+FileName=src\winvblock\wv_stdlib.c\r
 CompileCpp=1\r
-Folder=Util\r
+Folder=WinVBlock\r
 Compile=1\r
-Link=0\r
+Link=1\r
 Priority=1000\r
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
 [Unit57]\r
-FileName=src\include\wv_stdlib.h\r
+FileName=src\include\wv_stddef.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -622,9 +612,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit58]\r
-FileName=src\winvblock\wv_stdlib.c\r
+FileName=src\aoe\wv_stdlib.c\r
 CompileCpp=1\r
-Folder=WinVBlock\r
+Folder=AoE\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -632,7 +622,7 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit59]\r
-FileName=src\include\wv_stddef.h\r
+FileName=src\include\wv_string.h\r
 Folder=Include\r
 Compile=1\r
 Link=1\r
@@ -642,7 +632,7 @@ BuildCmd=
 CompileCpp=1\r
 \r
 [Unit61]\r
-FileName=src\include\wv_string.h\r
+FileName=src\include\wv_stdbool.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -652,9 +642,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit60]\r
-FileName=src\aoe\wv_stdlib.c\r
+FileName=src\winvblock\wv_string.c\r
 CompileCpp=1\r
-Folder=AoE\r
+Folder=WinVBlock\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -662,9 +652,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit62]\r
-FileName=src\winvblock\wv_string.c\r
+FileName=src\aoe\wv_string.c\r
 CompileCpp=1\r
-Folder=WinVBlock\r
+Folder=AoE\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -672,9 +662,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit63]\r
-FileName=src\include\wv_stdbool.h\r
+FileName=src\aoe\bus.c\r
 CompileCpp=1\r
-Folder=Include\r
+Folder=AoE\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -682,9 +672,9 @@ OverrideBuildCmd=0
 BuildCmd=\r
 \r
 [Unit64]\r
-FileName=src\aoe\wv_string.c\r
+FileName=src\include\aoe_bus.h\r
 CompileCpp=1\r
-Folder=AoE\r
+Folder=Include\r
 Compile=1\r
 Link=1\r
 Priority=1000\r
@@ -741,8 +731,8 @@ Priority=1000
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
-[Unit29]\r
-FileName=src\include\bus_pnp.h\r
+[Unit32]\r
+FileName=src\include\filedisk.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -751,8 +741,8 @@ Priority=1000
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
-[Unit32]\r
-FileName=src\include\disk_pnp.h\r
+[Unit33]\r
+FileName=src\include\grub4dos.h\r
 CompileCpp=1\r
 Folder=Include\r
 Compile=1\r
@@ -761,7 +751,17 @@ Priority=1000
 OverrideBuildCmd=0\r
 BuildCmd=\r
 \r
-[Unit33]\r
+[Unit29]\r
+FileName=src\include\debug.h\r
+CompileCpp=1\r
+Folder=Include\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit31]\r
 FileName=src\include\driver.h\r
 CompileCpp=1\r
 Folder=Include\r
diff --git a/src/include/bus_pnp.h b/src/include/bus_pnp.h
deleted file mode 100644 (file)
index 8996f1d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
- * Copyright 2006-2008, V.
- * For WinAoE contact information, see http://winaoe.org/
- *
- * This file is part of WinVBlock, derived from WinAoE.
- *
- * WinVBlock is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * WinVBlock is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _BUS_PNP_H
-#  define _BUS_PNP_H
-
-/**
- * @file
- *
- * Bus PnP IRP handling.
- */
-
-extern irp__handler bus_pnp__start_dev;
-extern irp__handler bus_pnp__remove_dev;
-extern irp__handler bus_pnp__query_dev_relations;
-extern irp__handler bus_pnp__simple;
-
-#endif                         /* _BUS_PNP_H */
index 7a3a90e..845b5dd 100644 (file)
@@ -138,7 +138,6 @@ typedef NTSTATUS STDCALL device__dev_ctl_func(
  * @v dev               Points to the device.
  * @v irp               Points to the IRP.
  * @v code              The SCSI function.
- * @v srb               The SCSI request block.
  * @ret NTSTATUS        The status of processing the IRP for the device.
  */
 typedef NTSTATUS STDCALL device__scsi_func(
@@ -147,12 +146,27 @@ typedef NTSTATUS STDCALL device__scsi_func(
     IN UCHAR
   );
 
+/**
+ * The prototype for a device IRP_MJ_PNP dispatch.
+ *
+ * @v dev               Points to the device.
+ * @v irp               Points to the IRP.
+ * @v code              The minor function.
+ * @ret NTSTATUS        The status of processing the IRP for the device.
+ */
+typedef NTSTATUS STDCALL device__pnp_func(
+    IN struct device__type *,
+    IN PIRP,
+    IN UCHAR
+  );
+
 /* IRP major function handler table. */
 struct device__irp_mj {
     device__dispatch_func * power;
     device__dispatch_func * sys_ctl;
     device__dev_ctl_func * dev_ctl;
     device__scsi_func * scsi;
+    device__pnp_func * pnp;
   };
 
 /* Details common to all devices this driver works with */
@@ -200,6 +214,6 @@ extern winvblock__lib_func void device__set(
     PDEVICE_OBJECT,
     struct device__type *
   );
-extern irp__handler device__pnp_query_id;
+extern device__dispatch_func device__pnp_query_id;
 
 #endif  /* _DEVICE_H */
diff --git a/src/include/disk_pnp.h b/src/include/disk_pnp.h
deleted file mode 100644 (file)
index 15d112f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
- * Copyright 2006-2008, V.
- * For WinAoE contact information, see http://winaoe.org/
- *
- * This file is part of WinVBlock, derived from WinAoE.
- *
- * WinVBlock is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * WinVBlock is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _DISK_PNP_H
-#  define _DISK_PNP_H
-
-/**
- * @file
- *
- * Disk PnP IRP handling.
- */
-
-extern irp__handler disk_pnp__query_id;
-extern irp__handler disk_pnp__query_dev_text;
-extern irp__handler disk_pnp__query_dev_relations;
-extern irp__handler disk_pnp__query_bus_info;
-extern irp__handler disk_pnp__query_capabilities;
-extern irp__handler disk_pnp__simple;
-
-#endif                         /* _DISK_PNP_H */
index 3a0bc2c..8507c76 100644 (file)
 #include "driver.h"
 #include "device.h"
 #include "bus.h"
-#include "bus_pnp.h"
 #include "debug.h"
 
 /* IRP_MJ_DEVICE_CONTROL dispatcher from bus/dev_ctl.c */
 extern device__dev_ctl_func bus_dev_ctl__dispatch;
+/* IRP_MJ_PNP dispatcher from bus/pnp.c */
+extern device__pnp_func bus_pnp__dispatch;
 
 /* Forward declarations. */
 static device__free_func bus__free_;
 static device__create_pdo_func bus__create_pdo_;
 static device__dispatch_func bus__power_;
 static device__dispatch_func bus__sys_ctl_;
+static device__pnp_func bus__pnp_dispatch_;
 
 /* Globals. */
 struct device__irp_mj bus__irp_mj_ = {
@@ -52,6 +54,7 @@ struct device__irp_mj bus__irp_mj_ = {
     bus__sys_ctl_,
     bus_dev_ctl__dispatch,
     (device__scsi_func *) 0,
+    bus_pnp__dispatch,
   };
 
 /**
@@ -218,58 +221,6 @@ NTSTATUS STDCALL bus__get_dev_capabilities(
     return status;
   }
 
-/* Bus dispatch routine. */
-static NTSTATUS STDCALL bus_dispatch(
-    IN PDEVICE_OBJECT dev,
-    IN PIRP irp
-  ) {
-    NTSTATUS status;
-    winvblock__bool completion = FALSE;
-    static const irp__handling handling_table[] = {
-        /*
-         * Major, minor, any major?, any minor?, handler
-         * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-         * Note that the fall-through case must come FIRST!
-         * Why? It sets completion to true, so others won't be called.
-         */
-        {                     0, 0,  TRUE, TRUE, driver__not_supported },
-        {            IRP_MJ_PNP, 0, FALSE, TRUE,       bus_pnp__simple },
-        {            IRP_MJ_PNP,
-               IRP_MN_START_DEVICE, FALSE, FALSE,   bus_pnp__start_dev },
-        {            IRP_MJ_PNP,
-              IRP_MN_REMOVE_DEVICE, FALSE, FALSE,  bus_pnp__remove_dev },
-        {            IRP_MJ_PNP,
-     IRP_MN_QUERY_DEVICE_RELATIONS, FALSE, FALSE,
-                                          bus_pnp__query_dev_relations },
-        {            IRP_MJ_PNP,
-                   IRP_MN_QUERY_ID, FALSE, FALSE, device__pnp_query_id },
-      };
-
-    /* Try registered mini IRP handling tables first.  Deprecated. */
-    status = irp__process(
-        dev,
-        irp,
-        IoGetCurrentIrpStackLocation(irp),
-        device__get(dev),
-        &completion
-      );
-    /* Fall through to the bus defaults, if needed. */
-    if (status == STATUS_NOT_SUPPORTED && !completion)
-      status = irp__process_with_table(
-          dev,
-          irp,
-          handling_table,
-          sizeof handling_table,
-          &completion
-        );
-    #ifdef DEBUGIRPS
-    if (status != STATUS_PENDING)
-      Debug_IrpEnd(irp, status);
-    #endif
-
-    return status;
-  }
-
 /* Initialize a bus. */
 static winvblock__bool STDCALL bus__init_(IN struct device__type * dev) {
     return TRUE;
@@ -303,7 +254,6 @@ winvblock__lib_func struct bus__type * bus__create(void) {
     /* Populate non-zero device defaults. */
     bus_ptr->device = dev_ptr;
     bus_ptr->prev_free = dev_ptr->ops.free;
-    dev_ptr->dispatch = bus_dispatch;
     dev_ptr->ops.create_pdo = bus__create_pdo_;
     dev_ptr->ops.init = bus__init_;
     dev_ptr->ops.free = bus__free_;
index c1480e6..357296e 100644 (file)
 #include "debug.h"
 #include "probe.h"
 
+/* Forward declarations. */
+static device__dispatch_func bus_pnp__start_dev_;
+static device__dispatch_func bus_pnp__remove_dev_;
+static device__dispatch_func bus_pnp__query_dev_relations_;
+static device__pnp_func bus_pnp__simple_;
+device__pnp_func bus_pnp__dispatch;
+
 static NTSTATUS STDCALL bus_pnp__io_completion_(
     IN PDEVICE_OBJECT dev_obj,
     IN PIRP irp,
@@ -47,22 +54,17 @@ static NTSTATUS STDCALL bus_pnp__io_completion_(
     return STATUS_MORE_PROCESSING_REQUIRED;
   }
 
-NTSTATUS STDCALL bus_pnp__start_dev(
-    IN PDEVICE_OBJECT dev_obj,
-    IN PIRP irp,
-    IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__start_dev_(
     IN struct device__type * dev,
-    OUT winvblock__bool_ptr completion
+    IN PIRP irp
   ) {
     NTSTATUS status;
     KEVENT event;
     struct bus__type * bus = bus__get(dev);
     PDEVICE_OBJECT lower = bus->LowerDeviceObject;
 
-    if (!lower) {
-        *completion = TRUE;
-        return STATUS_SUCCESS;
-      }
+    if (!lower)
+      return driver__complete_irp(irp, 0, STATUS_SUCCESS);
     KeInitializeEvent(&event, NotificationEvent, FALSE);
     IoCopyCurrentIrpStackLocationToNext(irp);
     IoSetCompletionRoutine(
@@ -82,32 +84,32 @@ NTSTATUS STDCALL bus_pnp__start_dev(
         dev->old_state = dev->state;
         dev->state = device__state_started;
       }
-    status = STATUS_SUCCESS;
-    irp->IoStatus.Status = status;
-    IoCompleteRequest(irp, IO_NO_INCREMENT);
-    *completion = TRUE;
-    return status;
+    return driver__complete_irp(
+        irp,
+        irp->IoStatus.Information,
+        STATUS_SUCCESS
+      );
   }
 
-NTSTATUS STDCALL bus_pnp__remove_dev(
-    IN PDEVICE_OBJECT dev_obj,
-    IN PIRP irp,
-    IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__remove_dev_(
     IN struct device__type * dev,
-    OUT winvblock__bool_ptr completion
+    IN PIRP irp
   ) {
-    NTSTATUS status;
-    struct bus__type * bus;
+    NTSTATUS status = STATUS_SUCCESS;
+    struct bus__type * bus = bus__get(dev);
+    PDEVICE_OBJECT lower = bus->LowerDeviceObject;
     struct device__type * walker, * next;
-    PDEVICE_OBJECT lower;
 
     dev->old_state = dev->state;
     dev->state = device__state_deleted;
-    irp->IoStatus.Information = 0;
-    irp->IoStatus.Status = STATUS_SUCCESS;
-    IoSkipCurrentIrpStackLocation(irp);
-    bus = bus__get(dev);
-    status = IoCallDriver(bus->LowerDeviceObject, irp);
+    /* Pass the IRP on to any lower DEVICE_OBJECT */
+    if (lower) {
+        irp->IoStatus.Information = 0;
+        irp->IoStatus.Status = STATUS_SUCCESS;
+        IoSkipCurrentIrpStackLocation(irp);
+        status = IoCallDriver(lower, irp);
+      }
+    /* Remove all children. */
     walker = bus->first_child;
     while (walker != NULL) {
         next = walker->next_sibling_ptr;
@@ -116,44 +118,43 @@ NTSTATUS STDCALL bus_pnp__remove_dev(
         device__free(walker);
         walker = next;
       }
+    /* Somewhat redundant, since the bus will be freed shortly. */
     bus->Children = 0;
     bus->first_child = NULL;
-    lower = bus->LowerDeviceObject;
+    /* Detach from any lower DEVICE_OBJECT */
     if (lower)
       IoDetachDevice(lower);
+    /* Delete and free. */
     IoDeleteDevice(dev->Self);
     device__free(dev);
-    *completion = TRUE;
     return status;
   }
 
-NTSTATUS STDCALL bus_pnp__query_dev_relations(
-    IN PDEVICE_OBJECT dev_obj,
-    IN PIRP irp,
-    IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__query_dev_relations_(
     IN struct device__type * dev,
-    OUT winvblock__bool_ptr completion
+    IN PIRP irp
   ) {
     NTSTATUS status;
-    struct bus__type * bus;
+    struct bus__type * bus = bus__get(dev);
+    PDEVICE_OBJECT lower = bus->LowerDeviceObject;
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
     winvblock__uint32 count;
     struct device__type * walker;
     PDEVICE_RELATIONS dev_relations;
-    PDEVICE_OBJECT lower;
 
-    bus = bus__get(dev);
-    lower = bus->LowerDeviceObject;
     if (
         io_stack_loc->Parameters.QueryDeviceRelations.Type != BusRelations ||
         irp->IoStatus.Information
       ) {
-        status = irp->IoStatus.Status;
         if (lower) {
             IoSkipCurrentIrpStackLocation(irp);
-            status = IoCallDriver(lower, irp);
+            return IoCallDriver(lower, irp);
           }
-        *completion = TRUE;
-        return status;
+        return driver__complete_irp(
+            irp,
+            irp->IoStatus.Information,
+            irp->IoStatus.Status
+          );
       }
     probe__disks();
     count = 0;
@@ -166,15 +167,12 @@ NTSTATUS STDCALL bus_pnp__query_dev_relations(
         sizeof *dev_relations + (sizeof (PDEVICE_OBJECT) * count)
       );
     if (dev_relations == NULL) {
-        irp->IoStatus.Information = 0;
-        status = STATUS_SUCCESS;
-        irp->IoStatus.Status = status;
+        /* Couldn't allocate dev_relations, but silently succeed. */
         if (lower) {
             IoSkipCurrentIrpStackLocation(irp);
-            status = IoCallDriver(lower, irp);
+            return IoCallDriver(lower, irp);
           }
-        *completion = TRUE;
-        return status;
+        return driver__complete_irp(irp, 0, STATUS_SUCCESS);
       }
     dev_relations->Count = count;
 
@@ -187,30 +185,24 @@ NTSTATUS STDCALL bus_pnp__query_dev_relations(
         walker = walker->next_sibling_ptr;
       }
     irp->IoStatus.Information = (ULONG_PTR) dev_relations;
-    status = STATUS_SUCCESS;
-    irp->IoStatus.Status = status;
+    irp->IoStatus.Status = status = STATUS_SUCCESS;
     if (lower) {
         IoSkipCurrentIrpStackLocation(irp);
-        status = IoCallDriver(lower, irp);
+        return IoCallDriver(lower, irp);
       }
-    *completion = TRUE;
-    return status;
+    return driver__complete_irp(irp, irp->IoStatus.Information, status);
   }
 
-NTSTATUS STDCALL bus_pnp__simple(
-    IN PDEVICE_OBJECT dev_obj,
-    IN PIRP irp,
-    IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__simple_(
     IN struct device__type * dev,
-    OUT winvblock__bool_ptr completion
+    IN PIRP irp,
+    IN UCHAR code
   ) {
     NTSTATUS status;
-    struct bus__type * bus;
-    PDEVICE_OBJECT lower;
+    struct bus__type * bus = bus__get(dev);
+    PDEVICE_OBJECT lower = bus->LowerDeviceObject;
 
-    bus = bus__get(dev);
-    lower = bus->LowerDeviceObject;
-    switch (io_stack_loc->MinorFunction) {
+    switch (code) {
         case IRP_MN_QUERY_PNP_DEVICE_STATE:
           irp->IoStatus.Information = 0;
           status = STATUS_SUCCESS;
@@ -257,8 +249,31 @@ NTSTATUS STDCALL bus_pnp__simple(
     irp->IoStatus.Status = status;
     if (lower) {
         IoSkipCurrentIrpStackLocation(irp);
-        status = IoCallDriver(lower, irp);
+        return IoCallDriver(lower, irp);
+      }
+    return driver__complete_irp(irp, irp->IoStatus.Information, status);
+  }
+
+/* Bus PnP dispatch routine. */
+NTSTATUS STDCALL bus_pnp__dispatch(
+    IN struct device__type * dev,
+    IN PIRP irp,
+    IN UCHAR code
+  ) {
+    switch (code) {
+        case IRP_MN_QUERY_ID:
+          return device__pnp_query_id(dev, irp);
+
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+          return bus_pnp__query_dev_relations_(dev, irp);
+
+        case IRP_MN_REMOVE_DEVICE:
+          return bus_pnp__remove_dev_(dev, irp);
+
+        case IRP_MN_START_DEVICE:
+          return bus_pnp__start_dev_(dev, irp);
+
+        default:
+          return bus_pnp__simple_(dev, irp, code);
       }
-    *completion = TRUE;
-    return status;
   }
index 8b86749..c852ec6 100644 (file)
@@ -112,15 +112,13 @@ winvblock__uint32 STDCALL device__pnp_id(
 
 /* An IRP handler for a PnP ID query. */
 NTSTATUS STDCALL device__pnp_query_id(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
     IN struct device__type * dev,
-    OUT winvblock__bool_ptr completion
+    IN PIRP irp
   ) {
     NTSTATUS status;
     WCHAR (*str)[512];
     winvblock__uint32 str_len;
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
 
     /* Allocate the working buffer. */
     str = wv_mallocz(sizeof *str);
@@ -132,39 +130,36 @@ NTSTATUS STDCALL device__pnp_query_id(
     /* Invoke the specific device's ID query. */
     str_len = device__pnp_id(
         dev,
-        Stack->Parameters.QueryId.IdType,
+        io_stack_loc->Parameters.QueryId.IdType,
         str
       );
     if (str_len == 0) {
-        Irp->IoStatus.Information = 0;
+        irp->IoStatus.Information = 0;
         status = STATUS_NOT_SUPPORTED;
         goto alloc_info;
       }
     /* Allocate the return buffer. */
-    Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str);
-    if (Irp->IoStatus.Information == 0) {
+    irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str);
+    if (irp->IoStatus.Information == 0) {
         DBG("wv_palloc failed.\n");
         status = STATUS_INSUFFICIENT_RESOURCES;
         goto alloc_info;
       }
     /* Copy the working buffer to the return buffer. */
     RtlCopyMemory(
-        (void *) Irp->IoStatus.Information,
+        (void *) irp->IoStatus.Information,
         str,
         str_len * sizeof **str
       );
     status = STATUS_SUCCESS;
 
-    /* Irp->IoStatus.Information not freed. */
+    /* irp->IoStatus.Information not freed. */
     alloc_info:
 
     wv_free(str);
     alloc_str:
 
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    *completion = TRUE;
-    return status;
+    return driver__complete_irp(irp, irp->IoStatus.Information, status);
   }
 
 /**
index 91b53d4..365c847 100644 (file)
@@ -34,7 +34,6 @@
 #include "driver.h"
 #include "device.h"
 #include "disk.h"
-#include "disk_pnp.h"
 #include "debug.h"
 
 #ifndef _MSC_VER
@@ -52,6 +51,8 @@ __divdi3 (
 extern device__dev_ctl_func disk_dev_ctl__dispatch;
 /* IRP_MJ_SCSI dispatcher from disk/scsi.c */
 extern device__scsi_func disk_scsi__dispatch;
+/* IRP_MJ_PNP dispatcher from disk/pnp.c */
+extern device__pnp_func disk_pnp__dispatch;
 
 /* Forward declarations. */
 static device__free_func free_disk;
@@ -69,6 +70,7 @@ struct device__irp_mj disk__irp_mj_ = {
     disk__sys_ctl_,
     disk_dev_ctl__dispatch,
     disk_scsi__dispatch,
+    disk_pnp__dispatch,
   };
 
 static
@@ -344,53 +346,6 @@ disk__guess_geometry (
     disk_ptr->Cylinders = disk_ptr->LBADiskSize / ( heads * sects_per_track );
 }
 
-/* Disk dispatch routine. */
-static NTSTATUS STDCALL (disk_dispatch)(
-    IN PDEVICE_OBJECT (dev),
-    IN PIRP (irp)
-  ) {
-    NTSTATUS (status);
-    winvblock__bool (completion) = FALSE;
-    static const irp__handling (handling_table)[] = {
-        /*
-         * Major, minor, any major?, any minor?, handler
-         * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-         * Note that the fall-through case must come FIRST!
-         * Why? It sets completion to true, so others won't be called.
-         */
-        {                     0, 0,  TRUE,  TRUE,  driver__not_supported },
-        {            IRP_MJ_PNP, 0, FALSE,  TRUE,       disk_pnp__simple },
-        {            IRP_MJ_PNP,
-         IRP_MN_QUERY_CAPABILITIES, FALSE, FALSE,
-                                            disk_pnp__query_capabilities },
-        {            IRP_MJ_PNP,
-      IRP_MN_QUERY_BUS_INFORMATION, FALSE, FALSE,
-                                                disk_pnp__query_bus_info },
-        {            IRP_MJ_PNP,
-     IRP_MN_QUERY_DEVICE_RELATIONS, FALSE, FALSE,
-                                           disk_pnp__query_dev_relations },
-        {            IRP_MJ_PNP,
-          IRP_MN_QUERY_DEVICE_TEXT, FALSE, FALSE,
-                                                disk_pnp__query_dev_text },
-        {            IRP_MJ_PNP,
-                   IRP_MN_QUERY_ID, FALSE, FALSE,   device__pnp_query_id },
-      };
-
-    status = irp__process_with_table(
-        dev,
-        irp,
-        handling_table,
-        sizeof handling_table,
-        &completion
-      );
-    #ifdef DEBUGIRPS
-    if (status != STATUS_PENDING)
-      Debug_IrpEnd(irp, status);
-    #endif
-
-    return status;
-  }
-
 /**
  * Create a new disk
  *
@@ -432,7 +387,6 @@ disk__create (
   disk_ptr->disk_ops.max_xfer_len = default_max_xfer_len;
   disk_ptr->disk_ops.init = default_init;
   disk_ptr->disk_ops.close = default_close;
-  dev_ptr->dispatch = disk_dispatch;
   dev_ptr->ops.close = disk__close_;
   dev_ptr->ops.create_pdo = create_pdo;
   dev_ptr->ops.free = free_disk;
index ac913ec..323503f 100644 (file)
 #include "bus.h"
 #include "debug.h"
 
-NTSTATUS STDCALL disk_pnp__query_dev_text(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  PWCHAR string;
-  NTSTATUS status;
-  winvblock__uint32 string_length;
-  disk__type_ptr disk_ptr;
-
-  string = wv_mallocz(512 * sizeof *string);
-  disk_ptr = disk__get_ptr ( dev_ptr );
-
-  if ( string == NULL )
-    {
-      DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
-      status = STATUS_INSUFFICIENT_RESOURCES;
-      goto alloc_string;
-    }
-
-  switch ( Stack->Parameters.QueryDeviceText.DeviceTextType )
-    {
-      case DeviceTextDescription:
-       string_length = swprintf ( string, winvblock__literal_w L" Disk" ) + 1;
-  Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(
-      string_length * sizeof *string
-    );
-       if ( Irp->IoStatus.Information == 0 )
-         {
-      DBG("wv_palloc DeviceTextDescription\n");
-           status = STATUS_INSUFFICIENT_RESOURCES;
-           goto alloc_info;
-         }
-       RtlCopyMemory(
-      (PWCHAR) Irp->IoStatus.Information,
-      (WCHAR (*)[512]) string,
-                       string_length * sizeof (WCHAR)
-    );
-       status = STATUS_SUCCESS;
-       goto alloc_info;
-
-      case DeviceTextLocationInformation:
-        string_length = device__pnp_id(
-            dev_ptr,
-            BusQueryInstanceID,
-            (WCHAR (*)[512]) string
+/* Forward declarations. */
+static device__dispatch_func disk_pnp__query_dev_text_;
+static device__dispatch_func disk_pnp__query_dev_relations_;
+static device__dispatch_func disk_pnp__query_bus_info_;
+static device__dispatch_func disk_pnp__query_capabilities_;
+static device__pnp_func disk_pnp__simple_;
+device__pnp_func disk_pnp__dispatch;
+
+static NTSTATUS STDCALL disk_pnp__query_dev_text_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    disk__type_ptr disk;
+    WCHAR (*str)[512];
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    NTSTATUS status;
+    winvblock__uint32 str_len;
+
+    disk = disk__get_ptr(dev);
+    /* Allocate a string buffer. */
+    str = wv_mallocz(sizeof *str);
+    if (str == NULL) {
+        DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto alloc_str;
+      }
+    /* Determine the query type. */
+    switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) {
+        case DeviceTextDescription:
+          str_len = swprintf(*str, winvblock__literal_w L" Disk") + 1;
+          irp->IoStatus.Information =
+            (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+          if (irp->IoStatus.Information == 0) {
+              DBG("wv_palloc DeviceTextDescription\n");
+              status = STATUS_INSUFFICIENT_RESOURCES;
+              goto alloc_info;
+            }
+          RtlCopyMemory(
+              (PWCHAR) irp->IoStatus.Information,
+              str,
+              str_len * sizeof (WCHAR)
+            );
+          status = STATUS_SUCCESS;
+          goto alloc_info;
+
+        case DeviceTextLocationInformation:
+          str_len = device__pnp_id(
+              dev,
+              BusQueryInstanceID,
+              str
+            );
+          irp->IoStatus.Information =
+            (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+          if (irp->IoStatus.Information == 0) {
+              DBG("wv_palloc DeviceTextLocationInformation\n");
+              status = STATUS_INSUFFICIENT_RESOURCES;
+              goto alloc_info;
+            }
+          RtlCopyMemory(
+              (PWCHAR) irp->IoStatus.Information,
+              str,
+              str_len * sizeof (WCHAR)
+            );
+          status = STATUS_SUCCESS;
+          goto alloc_info;
+
+        default:
+          irp->IoStatus.Information = 0;
+          status = STATUS_NOT_SUPPORTED;
+      }
+    /* irp->IoStatus.Information not freed. */
+    alloc_info:
+
+    wv_free(str);
+    alloc_str:
+
+    return driver__complete_irp(irp, irp->IoStatus.Information, status);
+  }
+
+static NTSTATUS STDCALL disk_pnp__query_dev_relations_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    NTSTATUS status;
+    PDEVICE_RELATIONS dev_relations;
+
+    if (io_stack_loc->Parameters.QueryDeviceRelations.Type !=
+        TargetDeviceRelation
+      ) {
+        status = irp->IoStatus.Status;
+        goto out;
+      }
+    dev_relations = wv_palloc(sizeof *dev_relations + sizeof dev->Self);
+    if (dev_relations == NULL) {
+        DBG("wv_palloc IRP_MN_QUERY_DEVICE_RELATIONS\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto alloc_dev_relations;
+      }
+    dev_relations->Objects[0] = dev->Self;
+    dev_relations->Count = 1;
+    ObReferenceObject(dev->Self);
+    irp->IoStatus.Information = (ULONG_PTR) dev_relations;
+    status = STATUS_SUCCESS;
+
+    /* irp->IoStatus.Information (dev_relations) not freed. */
+    alloc_dev_relations:
+
+    out:
+
+    irp->IoStatus.Status = status;
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+  }
+
+DEFINE_GUID(
+    GUID_BUS_TYPE_INTERNAL,
+    0x2530ea73L,
+    0x086b,
+    0x11d1,
+    0xa0,
+    0x9f,
+    0x00,
+    0xc0,
+    0x4f,
+    0xc3,
+    0x40,
+    0xb1
+  );
+
+static NTSTATUS STDCALL disk_pnp__query_bus_info_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    PPNP_BUS_INFORMATION pnp_bus_info;
+    NTSTATUS status;
+
+    pnp_bus_info = wv_palloc(sizeof *pnp_bus_info);
+    if (pnp_bus_info == NULL) {
+        DBG("wv_palloc IRP_MN_QUERY_BUS_INFORMATION\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto alloc_pnp_bus_info;
+      }
+    pnp_bus_info->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
+    pnp_bus_info->LegacyBusType = PNPBus;
+    pnp_bus_info->BusNumber = 0;
+    irp->IoStatus.Information = (ULONG_PTR) pnp_bus_info;
+    status = STATUS_SUCCESS;
+
+    /* irp-IoStatus.Information (pnp_bus_info) not freed. */
+    alloc_pnp_bus_info:
+
+    irp->IoStatus.Status = status;
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+  }
+
+static NTSTATUS STDCALL disk_pnp__query_capabilities_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    PDEVICE_CAPABILITIES DeviceCapabilities =
+      io_stack_loc->Parameters.DeviceCapabilities.Capabilities;
+    NTSTATUS status;
+    disk__type_ptr disk;
+    struct bus__type * bus;
+    DEVICE_CAPABILITIES ParentDeviceCapabilities;
+    PDEVICE_OBJECT bus_lower;
+
+    if (DeviceCapabilities->Version != 1 ||
+        DeviceCapabilities->Size < sizeof (DEVICE_CAPABILITIES)
+      ) {
+        status = STATUS_UNSUCCESSFUL;
+        goto out;
+      }
+    disk = disk__get_ptr(dev);
+    bus = bus__get(device__get(dev->Parent));
+    bus_lower = bus->LowerDeviceObject;
+    if (bus_lower) {
+        status = bus__get_dev_capabilities(
+            bus_lower,
+            &ParentDeviceCapabilities
           );
-        Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(
-            string_length * sizeof *string
+      } else {
+        status = bus__get_dev_capabilities(
+            bus->device->Self,
+            &ParentDeviceCapabilities
           );
-       if ( Irp->IoStatus.Information == 0 )
-         {
-      DBG("wv_palloc DeviceTextLocationInformation\n");
-           status = STATUS_INSUFFICIENT_RESOURCES;
-           goto alloc_info;
-         }
-       RtlCopyMemory ( ( PWCHAR ) Irp->IoStatus.Information, string,
-                       string_length * sizeof ( WCHAR ) );
-       status = STATUS_SUCCESS;
-       goto alloc_info;
-
-      default:
-       Irp->IoStatus.Information = 0;
-       status = STATUS_NOT_SUPPORTED;
-    }
-  /*
-   * Irp->IoStatus.Information not freed 
-   */
-alloc_info:
-
-  wv_free(string);
-alloc_string:
-
-  Irp->IoStatus.Status = status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
-
-NTSTATUS STDCALL disk_pnp__query_dev_relations(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  NTSTATUS status;
-  PDEVICE_RELATIONS dev_relations;
-
-  if ( Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation )
-    {
-      status = Irp->IoStatus.Status;
-      goto ret_path;
-    }
-  dev_relations = wv_palloc(sizeof *dev_relations + sizeof dev_ptr->Self);
-  if ( dev_relations == NULL )
-    {
-      DBG("wv_palloc IRP_MN_QUERY_DEVICE_RELATIONS\n");
-      status = STATUS_INSUFFICIENT_RESOURCES;
-      goto alloc_dev_relations;
-    }
-  dev_relations->Objects[0] = dev_ptr->Self;
-  dev_relations->Count = 1;
-  ObReferenceObject ( dev_ptr->Self );
-  Irp->IoStatus.Information = ( ULONG_PTR ) dev_relations;
-  status = STATUS_SUCCESS;
-
-  /*
-   * Irp->IoStatus.Information (dev_relations) not freed 
-   */
-alloc_dev_relations:
-
-ret_path:
-  Irp->IoStatus.Status = status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
-
-DEFINE_GUID ( GUID_BUS_TYPE_INTERNAL, 0x2530ea73L, 0x086b, 0x11d1, 0xa0, 0x9f,
-             0x00, 0xc0, 0x4f, 0xc3, 0x40, 0xb1 );
-
-NTSTATUS STDCALL disk_pnp__query_bus_info(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  PPNP_BUS_INFORMATION pnp_bus_info;
-  NTSTATUS status;
-
-  pnp_bus_info = wv_palloc(sizeof *pnp_bus_info);
-  if ( pnp_bus_info == NULL )
-    {
-      DBG("wv_palloc IRP_MN_QUERY_BUS_INFORMATION\n");
-      status = STATUS_INSUFFICIENT_RESOURCES;
-      goto alloc_pnp_bus_info;
-    }
-  pnp_bus_info->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
-  pnp_bus_info->LegacyBusType = PNPBus;
-  pnp_bus_info->BusNumber = 0;
-  Irp->IoStatus.Information = ( ULONG_PTR ) pnp_bus_info;
-  status = STATUS_SUCCESS;
-
-  /*
-   * Irp-IoStatus.Information (pnp_bus_info) not freed 
-   */
-alloc_pnp_bus_info:
-
-  Irp->IoStatus.Status = status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
-
-NTSTATUS STDCALL disk_pnp__query_capabilities(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  PDEVICE_CAPABILITIES DeviceCapabilities =
-    Stack->Parameters.DeviceCapabilities.Capabilities;
-  NTSTATUS status;
-  disk__type_ptr disk_ptr;
-  struct bus__type * bus_ptr;
-  DEVICE_CAPABILITIES ParentDeviceCapabilities;
-  PDEVICE_OBJECT bus_lower;
-
-  if ( DeviceCapabilities->Version != 1
-       || DeviceCapabilities->Size < sizeof ( DEVICE_CAPABILITIES ) )
-    {
-      status = STATUS_UNSUCCESSFUL;
-      goto ret_path;
-    }
-  disk_ptr = disk__get_ptr ( dev_ptr );
-  bus_ptr = bus__get(device__get(dev_ptr->Parent));
-  bus_lower = bus_ptr->LowerDeviceObject;
-  if (bus_lower) {
-      status = bus__get_dev_capabilities(
-          bus_lower,
-                       &ParentDeviceCapabilities
-        );
-    } else {
-      status = bus__get_dev_capabilities(
-          bus_ptr->device->Self,
-                       &ParentDeviceCapabilities
-        );
-    }      
-  if ( !NT_SUCCESS ( status ) )
-    goto ret_path;
-
-  RtlCopyMemory ( DeviceCapabilities->DeviceState,
-                 ParentDeviceCapabilities.DeviceState,
-                 ( PowerSystemShutdown +
-                   1 ) * sizeof ( DEVICE_POWER_STATE ) );
-  DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
-  if ( DeviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0 )
-    DeviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
-  if ( DeviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0 )
-    DeviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
-#if 0
-  if ( DeviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0 )
-    DeviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
-#endif
-  DeviceCapabilities->DeviceWake = PowerDeviceD1;
-  DeviceCapabilities->DeviceD1 = TRUE;
-  DeviceCapabilities->DeviceD2 = FALSE;
-  DeviceCapabilities->WakeFromD0 = FALSE;
-  DeviceCapabilities->WakeFromD1 = FALSE;
-  DeviceCapabilities->WakeFromD2 = FALSE;
-  DeviceCapabilities->WakeFromD3 = FALSE;
-  DeviceCapabilities->D1Latency = 0;
-  DeviceCapabilities->D2Latency = 0;
-  DeviceCapabilities->D3Latency = 0;
-  DeviceCapabilities->EjectSupported = FALSE;
-  DeviceCapabilities->HardwareDisabled = FALSE;
-  DeviceCapabilities->Removable = disk__removable[disk_ptr->media];
-  DeviceCapabilities->SurpriseRemovalOK = FALSE;
-  DeviceCapabilities->UniqueID = FALSE;
-  DeviceCapabilities->SilentInstall = FALSE;
-#if 0
-  DeviceCapabilities->Address = DeviceObject->SerialNo;
-  DeviceCapabilities->UINumber = DeviceObject->SerialNo;
-#endif
-  status = STATUS_SUCCESS;
-
-ret_path:
-  Irp->IoStatus.Status = status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
-
-NTSTATUS STDCALL disk_pnp__simple(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  NTSTATUS status;
-  disk__type_ptr disk_ptr;
-
-  disk_ptr = disk__get_ptr ( dev_ptr );
-  switch ( Stack->MinorFunction )
-    {
-      case IRP_MN_DEVICE_USAGE_NOTIFICATION:
-       if ( Stack->Parameters.UsageNotification.InPath )
-         {
-           disk_ptr->SpecialFileCount++;
-         }
-       else
-         {
-           disk_ptr->SpecialFileCount--;
-         }
-       Irp->IoStatus.Information = 0;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_QUERY_PNP_DEVICE_STATE:
-       Irp->IoStatus.Information = 0;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_START_DEVICE:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_started;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_QUERY_STOP_DEVICE:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_stop_pending;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_CANCEL_STOP_DEVICE:
-       dev_ptr->state = dev_ptr->old_state;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_STOP_DEVICE:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_stopped;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_QUERY_REMOVE_DEVICE:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_remove_pending;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_REMOVE_DEVICE:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_not_started;
-       if ( disk_ptr->Unmount )
-         {
-           device__close ( dev_ptr );
-           IoDeleteDevice ( dev_ptr->Self );
-           device__free ( dev_ptr );
-           status = STATUS_NO_SUCH_DEVICE;
-         }
-       else
-         {
-           status = STATUS_SUCCESS;
-         }
-       break;
-      case IRP_MN_CANCEL_REMOVE_DEVICE:
-       dev_ptr->state = dev_ptr->old_state;
-       status = STATUS_SUCCESS;
-       break;
-      case IRP_MN_SURPRISE_REMOVAL:
-       dev_ptr->old_state = dev_ptr->state;
-       dev_ptr->state = device__state_surprise_remove_pending;
-       status = STATUS_SUCCESS;
-       break;
-      default:
-       status = Irp->IoStatus.Status;
-    }
-
-  Irp->IoStatus.Status = status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
+      }      
+    if (!NT_SUCCESS(status))
+      goto out;
+
+    RtlCopyMemory(
+        DeviceCapabilities->DeviceState,
+        ParentDeviceCapabilities.DeviceState,
+        (PowerSystemShutdown + 1) * sizeof (DEVICE_POWER_STATE)
+      );
+    DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+    if (DeviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
+      DeviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
+    if (DeviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
+      DeviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
+    #if 0
+    if (DeviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
+      DeviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+    #endif
+    DeviceCapabilities->DeviceWake = PowerDeviceD1;
+    DeviceCapabilities->DeviceD1 = TRUE;
+    DeviceCapabilities->DeviceD2 = FALSE;
+    DeviceCapabilities->WakeFromD0 = FALSE;
+    DeviceCapabilities->WakeFromD1 = FALSE;
+    DeviceCapabilities->WakeFromD2 = FALSE;
+    DeviceCapabilities->WakeFromD3 = FALSE;
+    DeviceCapabilities->D1Latency = 0;
+    DeviceCapabilities->D2Latency = 0;
+    DeviceCapabilities->D3Latency = 0;
+    DeviceCapabilities->EjectSupported = FALSE;
+    DeviceCapabilities->HardwareDisabled = FALSE;
+    DeviceCapabilities->Removable = disk__removable[disk->media];
+    DeviceCapabilities->SurpriseRemovalOK = FALSE;
+    DeviceCapabilities->UniqueID = FALSE;
+    DeviceCapabilities->SilentInstall = FALSE;
+    #if 0
+    DeviceCapabilities->Address = dev->Self->SerialNo;
+    DeviceCapabilities->UINumber = dev->Self->SerialNo;
+    #endif
+    status = STATUS_SUCCESS;
+
+    out:
+    irp->IoStatus.Status = status;
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+  }
+
+static NTSTATUS STDCALL disk_pnp__simple_(
+    IN struct device__type * dev,
+    IN PIRP irp,
+    IN UCHAR code
+  ) {
+    disk__type_ptr disk = disk__get_ptr(dev);
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    NTSTATUS status;
+
+    switch (code) {
+        case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+          if (io_stack_loc->Parameters.UsageNotification.InPath) {
+              disk->SpecialFileCount++;
+            } else {
+              disk->SpecialFileCount--;
+            }
+          irp->IoStatus.Information = 0;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_QUERY_PNP_DEVICE_STATE:
+          irp->IoStatus.Information = 0;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_START_DEVICE:
+          dev->old_state = dev->state;
+          dev->state = device__state_started;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_QUERY_STOP_DEVICE:
+          dev->old_state = dev->state;
+          dev->state = device__state_stop_pending;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_CANCEL_STOP_DEVICE:
+          dev->state = dev->old_state;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_STOP_DEVICE:
+          dev->old_state = dev->state;
+          dev->state = device__state_stopped;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+          dev->old_state = dev->state;
+          dev->state = device__state_remove_pending;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_REMOVE_DEVICE:
+          dev->old_state = dev->state;
+          dev->state = device__state_not_started;
+          if (disk->Unmount) {
+              device__close(dev);
+              IoDeleteDevice(dev->Self);
+              device__free(dev);
+              status = STATUS_NO_SUCH_DEVICE;
+            } else {
+              status = STATUS_SUCCESS;
+            }
+          break;
+
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+          dev->state = dev->old_state;
+          status = STATUS_SUCCESS;
+          break;
+
+        case IRP_MN_SURPRISE_REMOVAL:
+          dev->old_state = dev->state;
+          dev->state = device__state_surprise_remove_pending;
+          status = STATUS_SUCCESS;
+          break;
+
+        default:
+          status = irp->IoStatus.Status;
+      }
+
+    irp->IoStatus.Status = status;
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+  }
+
+/* Disk PnP dispatch routine. */
+NTSTATUS STDCALL disk_pnp__dispatch(
+    IN struct device__type * dev,
+    IN PIRP irp,
+    IN UCHAR code
+  ) {
+    switch (code) {
+        case IRP_MN_QUERY_ID:
+          return device__pnp_query_id(dev, irp);
+
+        case IRP_MN_QUERY_DEVICE_TEXT:
+          return disk_pnp__query_dev_text_(dev, irp);
+
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+          return disk_pnp__query_dev_relations_(dev, irp);
+
+        case IRP_MN_QUERY_BUS_INFORMATION:
+          return disk_pnp__query_bus_info_(dev, irp);
+
+        case IRP_MN_QUERY_CAPABILITIES:
+          return disk_pnp__query_capabilities_(dev, irp);
+
+        default:
+          return disk_pnp__simple_(dev, irp, code);
+      }
+  }
index 7f5e4ee..588d09b 100644 (file)
@@ -62,6 +62,7 @@ static driver__dispatch_func driver__dispatch_create_close_;
 static driver__dispatch_func driver__dispatch_sys_ctl_;
 static driver__dispatch_func driver__dispatch_dev_ctl_;
 static driver__dispatch_func driver__dispatch_scsi_;
+static driver__dispatch_func driver__dispatch_pnp_;
 static driver__dispatch_func driver__dispatch_;
 static void STDCALL driver__unload_(IN PDRIVER_OBJECT);
 
@@ -309,7 +310,7 @@ NTSTATUS STDCALL DriverEntry(
      */
     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
       DriverObject->MajorFunction[i] = driver__dispatch_not_supported_;
-    DriverObject->MajorFunction[IRP_MJ_PNP] = driver__dispatch_;
+    DriverObject->MajorFunction[IRP_MJ_PNP] = driver__dispatch_pnp_;
     DriverObject->MajorFunction[IRP_MJ_POWER] = driver__dispatch_power_;
     DriverObject->MajorFunction[IRP_MJ_CREATE] = driver__dispatch_create_close_;
     DriverObject->MajorFunction[IRP_MJ_CLOSE] = driver__dispatch_create_close_;
@@ -510,6 +511,33 @@ static NTSTATUS driver__dispatch_scsi_(
     return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
   }
 
+/* Handle an IRP_MJ_PNP IRP. */
+static NTSTATUS driver__dispatch_pnp_(
+    IN PDEVICE_OBJECT dev_obj,
+    IN PIRP irp
+  ) {
+    /* device__get() checks for a NULL dev_obj */
+    struct device__type * dev = device__get(dev_obj);
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+
+    #ifdef DEBUGIRPS
+    Debug_IrpStart(dev_obj, irp);
+    #endif
+    /* Check that the device exists. */
+    if (!dev || dev->state == device__state_deleted)
+      return driver__complete_irp(irp, 0, STATUS_NO_SUCH_DEVICE);
+    /* Call the particular device's power handler. */
+    if (dev->irp_mj && dev->irp_mj->pnp) {
+        return dev->irp_mj->pnp(
+            dev,
+            irp,
+            io_stack_loc->MinorFunction
+          );
+      }
+    /* Otherwise, we don't support the IRP. */
+    return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
+  }
+
 static NTSTATUS STDCALL driver__dispatch_(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp