[driver,aoe] Use WV_S_DRIVER_DUMMY_IDS for PnP ID queries
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 31 Dec 2010 08:59:20 +0000 (03:59 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 31 Dec 2010 08:59:20 +0000 (03:59 -0500)
Fix sizeof usage with WCHAR (oops).

Change WvDriverAddDummy() to take a WV_S_DRIVER_DUMMY_IDS
instead of a function pointer.

The AoE sub-bus is starting to behave better.  Now it's
time to address the challenge of duplicate PDO creation.

src/aoe/bus.c
src/include/driver.h
src/winvblock/driver.c

index 2132d1a..8d64b3d 100644 (file)
@@ -134,6 +134,14 @@ NTSTATUS STDCALL AoeBusDevCtl(
       }
   }
 
+/* Generate dummy IDs for the AoE bus PDO. */
+#define AOE_M_BUS_IDS(X_, Y_)                       \
+  X_(Y_, Dev,      winvblock__literal_w L"\\AoE"  ) \
+  X_(Y_, Instance, L"0"                           ) \
+  X_(Y_, Hardware, winvblock__literal_w L"\\AoE\0") \
+  X_(Y_, Compat,   winvblock__literal_w L"\\AoE\0")
+WV_M_DRIVER_DUMMY_ID_GEN(AoeBusDummyIds_, AOE_M_BUS_IDS);
+
 /**
  * Create the AoE bus.
  *
@@ -144,7 +152,7 @@ winvblock__bool AoeBusCreate(void) {
 
     /* Create the PDO for the sub-bus on the WinVBlock bus. */
     status = WvDriverAddDummy(
-        AoeBusPnpId_,
+        &AoeBusDummyIds_,
         FILE_DEVICE_CONTROLLER,
         FILE_DEVICE_SECURE_OPEN
       );
@@ -164,14 +172,6 @@ void AoeBusFree(void) {
     return;
   }
 
-/* Generate dummy IDs for the AoE bus PDO. */
-#define AOE_M_BUS_IDS(X_, Y_)                       \
-  X_(Y_, Dev,      winvblock__literal_w L"\\AoE"  ) \
-  X_(Y_, Instance, L"0"                           ) \
-  X_(Y_, Hardware, winvblock__literal_w L"\\AoE\0") \
-  X_(Y_, Compat,   winvblock__literal_w L"\\AoE\0")
-WV_M_DRIVER_DUMMY_ID_GEN(AoeBusDummyIds_, AOE_M_BUS_IDS);
-
 static winvblock__uint32 STDCALL AoeBusPnpId_(
     IN WV_SP_DEV_T dev,
     IN BUS_QUERY_ID_TYPE query_type,
index 4c626d0..cc1962c 100644 (file)
@@ -70,14 +70,16 @@ typedef struct WV_DRIVER_DUMMY_IDS {
     winvblock__uint32 HardwareLen;
     winvblock__uint32 CompatOffset;
     winvblock__uint32 CompatLen;
+    winvblock__uint32 Len;
     const WCHAR * Ids;
+    WCHAR Text[1];
   } WV_S_DRIVER_DUMMY_IDS, * WV_SP_DRIVER_DUMMY_IDS;
 
 /* Macro support for dummy ID generation. */
-#define WV_M_DRIVER_DUMMY_IDS_X_ENUM(prefix_, name_, literal_)  \
-  prefix_ ## name_ ## Offset_,                                  \
-  prefix_ ## name_ ## Len_ = sizeof (literal_),                 \
-  prefix_ ## name_ ## End_ =                                    \
+#define WV_M_DRIVER_DUMMY_IDS_X_ENUM(prefix_, name_, literal_)    \
+  prefix_ ## name_ ## Offset_,                                    \
+  prefix_ ## name_ ## Len_ = sizeof (literal_) / sizeof (WCHAR),  \
+  prefix_ ## name_ ## End_ =                                      \
     prefix_ ## name_ ## Offset_ + prefix_ ## name_ ## Len_ - 1,
 
 #define WV_M_DRIVER_DUMMY_IDS_X_LITERALS(prefix_, name_, literal_) \
@@ -125,6 +127,7 @@ static const WCHAR DummyIds ## String_[] =            \
                                                       \
 static const WV_S_DRIVER_DUMMY_IDS DummyIds = {       \
     XMacro(WV_M_DRIVER_DUMMY_IDS_X_FILL, DummyIds)    \
+    DummyIds ## Len_,                                 \
     DummyIds ## String_                               \
   }
 
@@ -141,7 +144,7 @@ extern NTSTATUS STDCALL WvDriverGetDevCapabilities(
     IN PDEVICE_CAPABILITIES
   );
 extern winvblock__lib_func NTSTATUS STDCALL WvDriverAddDummy(
-    IN WV_FP_DEV_PNP_ID,
+    IN const WV_S_DRIVER_DUMMY_IDS *,
     IN DEVICE_TYPE,
     IN ULONG
   );
index 6e41a1e..dc305f7 100644 (file)
@@ -845,11 +845,12 @@ static NTSTATUS STDCALL WvDriverDummyPnp_(
     if (code != IRP_MN_QUERY_ID)
       return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
 
-    return WvDevPnpQueryId(dev, irp);
+    /* The WV_S_DEV_T extension points to the dummy IDs. */
+    return WvDriverDummyIds(irp, dev->ext);
   }
 
 typedef struct WV_DRIVER_ADD_DUMMY_ {
-    WV_FP_DEV_PNP_ID PnpIdFunc;
+    const WV_S_DRIVER_DUMMY_IDS * DummyIds;
     DEVICE_TYPE DevType;
     ULONG DevCharacteristics;
     PKEVENT Event;
@@ -868,6 +869,8 @@ static void STDCALL WvDriverAddDummy_(void * context) {
     NTSTATUS status;
     PDEVICE_OBJECT pdo = NULL;
     WV_SP_DEV_T dev;
+    wv_size_t dummy_ids_size;
+    WV_SP_DRIVER_DUMMY_IDS dummy_ids;
     static WV_S_DEV_IRP_MJ irp_mj = {
         (WV_FP_DEV_DISPATCH) 0,
         (WV_FP_DEV_DISPATCH) 0,
@@ -888,20 +891,41 @@ static void STDCALL WvDriverAddDummy_(void * context) {
     if (!NT_SUCCESS(status) || !pdo) {
         DBG("Couldn't create dummy device.\n");
         dummy_context->Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto out;
+        goto err_create_pdo;
       }
 
     dev = wv_malloc(sizeof *dev);
     if (!dev) {
         DBG("Couldn't allocate dummy device.\n");
         dummy_context->Status = STATUS_INSUFFICIENT_RESOURCES;
-        IoDeleteDevice(pdo);
-        goto out;
+        goto err_dev;
       }
 
+    dummy_ids_size =
+      sizeof *dummy_ids +
+      dummy_context->DummyIds->Len * sizeof dummy_ids->Text[0] -
+      sizeof dummy_ids->Text[0];        /* The struct hack uses a WCHAR[1]. */
+    dummy_ids = wv_malloc(dummy_ids_size);
+    if (!dummy_ids) {
+        DBG("Couldn't allocate dummy IDs.\n");
+        dummy_context->Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto err_dummy_ids;
+      }
+    /* Copy the IDs offsets and lengths. */
+    RtlCopyMemory(dummy_ids, dummy_context->DummyIds, sizeof *dummy_ids);
+    /* Copy the text of the IDs. */
+    RtlCopyMemory(
+        &dummy_ids->Text,
+        dummy_context->DummyIds->Ids,
+        dummy_context->DummyIds->Len * sizeof dummy_ids->Text[0]
+      );
+    /* Point to the copy of the text. */
+    dummy_ids->Ids = dummy_ids->Text;
+
+    /* Ok! */
     WvDevInit(dev);
     dev->IrpMj = &irp_mj;
-    dev->Ops.PnpId = dummy_context->PnpIdFunc;
+    dev->ext = dummy_ids;       /* TODO: Implement a dummy free.  Leaking. */
     dev->Self = pdo;
     WvDevForDevObj(pdo, dev);
     WvBusInitNode(&dev->BusNode, pdo);
@@ -911,9 +935,20 @@ static void STDCALL WvDriverAddDummy_(void * context) {
     WvBusAddNode(&WvDriverBus_, &dev->BusNode);
     dev->DevNum = WvBusGetNodeNum(&dev->BusNode);
     pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
     dummy_context->Status = STATUS_SUCCESS;
+    KeSetEvent(dummy_context->Event, 0, FALSE);
+    return;
+
+    wv_free(dummy_ids);
+    err_dummy_ids:
+
+    wv_free(dev);
+    err_dev:
+
+    IoDeleteDevice(pdo);
+    err_create_pdo:
 
-    out:
     KeSetEvent(dummy_context->Event, 0, FALSE);
     return;
   }
@@ -921,19 +956,19 @@ static void STDCALL WvDriverAddDummy_(void * context) {
 /**
  * Produce a dummy PDO node on the main bus.
  *
- * @v PnpIdFunc                 The PnP ID query handler for the dummy.
+ * @v DummyIds                  The PnP IDs for the dummy.
  * @v DevType                   The type for the dummy device.
  * @v DevCharacteristics        The dummy device characteristics.
  * @ret NTSTATUS                The status of the operation.
  */
 winvblock__lib_func NTSTATUS STDCALL WvDriverAddDummy(
-    IN WV_FP_DEV_PNP_ID PnpIdFunc,
+    IN const WV_S_DRIVER_DUMMY_IDS * DummyIds,
     IN DEVICE_TYPE DevType,
     IN ULONG DevCharacteristics
   ) {
     KEVENT event;
     WV_S_DRIVER_ADD_DUMMY_ context = {
-        PnpIdFunc,
+        DummyIds,
         DevType,
         DevCharacteristics,
         &event,
@@ -945,7 +980,7 @@ winvblock__lib_func NTSTATUS STDCALL WvDriverAddDummy(
       };
     NTSTATUS status;
 
-    if (!PnpIdFunc)
+    if (!DummyIds)
       return STATUS_INVALID_PARAMETER;
 
     KeInitializeEvent(&event, SynchronizationEvent, FALSE);