The code expects synchronous behaviour here, so until a better solution exists, IoSyn...
[reactos.git] / reactos / ntoskrnl / io / pnpmgr / pnpmgr.c
index 9d66485..77a470d 100644 (file)
@@ -28,9 +28,6 @@ PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList = NULL;
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, PnpInit)
 #pragma alloc_text(INIT, PnpInit2)
-#pragma alloc_text(INIT, IopUpdateRootKey)
-#pragma alloc_text(INIT, IopEnumerateDetectedDevices)
-#pragma alloc_text(INIT, IopIsAcpiComputer)
 #endif
 
 typedef struct _INVALIDATE_DEVICE_RELATION_DATA
@@ -41,11 +38,18 @@ typedef struct _INVALIDATE_DEVICE_RELATION_DATA
     NTSTATUS Status;
 } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
 
-static VOID CALLBACK
+static VOID NTAPI
 IopInvalidateDeviceRelations(
     IN PDEVICE_OBJECT DeviceObject,
     IN PVOID InvalidateContext);
 
+VOID
+NTAPI
+IoSynchronousInvalidateDeviceRelations(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN DEVICE_RELATION_TYPE Type);
+
+
 /* FUNCTIONS *****************************************************************/
 
 PDEVICE_NODE
@@ -147,7 +151,9 @@ IopStartDevice(
          if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY))
       {
          DPRINT("Device needs enumeration, invalidating bus relations\n");
-         IoInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations);
+         /* Invalidate device relations synchronously
+            (otherwise there will be dirty read of DeviceNode) */
+         IoSynchronousInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations);
          IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
       }
    }
@@ -596,7 +602,7 @@ IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
       return STATUS_INSUFFICIENT_RESOURCES;
 
    KeyName.Length = 0;
-   KeyName.MaximumLength = KeyNameLength;
+   KeyName.MaximumLength = (USHORT)KeyNameLength;
    KeyName.Buffer = KeyNameBuffer;
 
    /*
@@ -622,7 +628,7 @@ IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
          ExFreePool(KeyNameBuffer);
          return Status;
       }
-      KeyName.Length += DriverKeyLength - sizeof(UNICODE_NULL);
+      KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
    }
    else
    {
@@ -753,7 +759,7 @@ IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
                  sizeof(GUID));
 
    /* The new entry is the index */
-   FoundIndex = IopBusTypeGuidList->GuidCount;
+   FoundIndex = (USHORT)IopBusTypeGuidList->GuidCount;
    IopBusTypeGuidList->GuidCount++;
 
 Quickie:
@@ -931,11 +937,11 @@ IopInitiatePnpIrp(PDEVICE_OBJECT DeviceObject,
    Irp->IoStatus.Information = 0;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
-   IrpSp->MinorFunction = MinorFunction;
+   IrpSp->MinorFunction = (UCHAR)MinorFunction;
 
    if (Stack)
    {
-      RtlMoveMemory(&IrpSp->Parameters,
+      RtlCopyMemory(&IrpSp->Parameters,
                     &Stack->Parameters,
                     sizeof(Stack->Parameters));
    }
@@ -1621,14 +1627,14 @@ IopGetParentIdPrefix(PDEVICE_NODE DeviceNode,
          Status = STATUS_UNSUCCESSFUL;
       else
       {
-         KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+         KeyValue.Length = KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
          KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
       }
       goto cleanup;
    }
    if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
    {
-      KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+      KeyValue.Length = KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
       KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
       goto cleanup;
    }
@@ -2324,6 +2330,10 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
       PLDR_DATA_TABLE_ENTRY ModuleObject;
       PDRIVER_OBJECT DriverObject;
 
+      /* FIXME: Remove this once the bug is fixed */
+      if (DeviceNode->ServiceName.Buffer == NULL)
+          DPRINT1("Weird DeviceNode %p having ServiceName->Buffer==NULL. Probable stack corruption or memory overwrite.\n", DeviceNode);
+
       Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
       if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED)
       {
@@ -2456,7 +2466,7 @@ IopInitializePnpServices(IN PDEVICE_NODE DeviceNode,
  * The call can be make synchronous by defining the Event field
  * of the INVALIDATE_DEVICE_RELATION_DATA structure
  */
-static VOID CALLBACK
+static VOID NTAPI
 IopInvalidateDeviceRelations(
     IN PDEVICE_OBJECT DeviceObject,
     IN PVOID InvalidateContext) /* PINVALIDATE_DEVICE_RELATION_DATA */
@@ -2476,7 +2486,7 @@ IopInvalidateDeviceRelations(
     NTSTATUS Status;
     ULONG i;
 
-    DPRINT("DeviceObject 0x%p, Type %d\n", DeviceObject, Type);
+    DPRINT("DeviceObject 0x%p\n", DeviceObject);
 
     DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
 
@@ -2613,73 +2623,6 @@ cleanup:
         ExFreePool(Data);
 }
 
-VOID INIT_FUNCTION
-PnpInit(VOID)
-{
-   PDEVICE_OBJECT Pdo;
-   NTSTATUS Status;
-
-   DPRINT("PnpInit()\n");
-
-   KeInitializeSpinLock(&IopDeviceTreeLock);
-
-   /* Initialize the Bus Type GUID List */
-   IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
-   RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
-   ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
-
-   /* Initialize PnP-Event notification support */
-   Status = IopInitPlugPlayEvents();
-   if (!NT_SUCCESS(Status))
-   {
-      CPRINT("IopInitPlugPlayEvents() failed\n");
-      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-   }
-
-   /*
-    * Create root device node
-    */
-
-   Status = IopCreateDriverObject(&IopRootDriverObject, NULL, 0, FALSE, NULL, 0);
-   if (!NT_SUCCESS(Status))
-   {
-      CPRINT("IoCreateDriverObject() failed\n");
-      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-   }
-
-   Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
-      0, FALSE, &Pdo);
-   if (!NT_SUCCESS(Status))
-   {
-      CPRINT("IoCreateDevice() failed\n");
-      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-   }
-
-   Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode);
-   if (!NT_SUCCESS(Status))
-   {
-      CPRINT("Insufficient resources\n");
-      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-   }
-
-   if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
-       L"HTREE\\ROOT\\0"))
-   {
-     CPRINT("Failed to create the instance path!\n");
-     KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
-   }
-
-   /* Report the device to the user-mode pnp manager */
-   IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
-                             &IopRootDeviceNode->InstancePath);
-
-   IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
-   PnpRootDriverEntry(IopRootDriverObject, NULL);
-   IopRootDriverObject->DriverExtension->AddDevice(
-      IopRootDriverObject,
-      IopRootDeviceNode->PhysicalDeviceObject);
-}
-
 static NTSTATUS INIT_FUNCTION
 IopEnumerateDetectedDevices(
    IN HANDLE hBaseKey,
@@ -2722,10 +2665,10 @@ IopEnumerateDetectedDevices(
    const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
    UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
    static ULONG DeviceIndexSerial = 0;
-   const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardPeripheral");
+   const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
    UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
    static ULONG DeviceIndexKeyboard = 0;
-   const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerPeripheral");
+   const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
    UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
    static ULONG DeviceIndexMouse = 0;
    PUNICODE_STRING pHardwareId;
@@ -2781,12 +2724,12 @@ IopEnumerateDetectedDevices(
       IndexDevice++;
 
       /* Open device key */
-      DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
+      DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
       DeviceName.Buffer = pDeviceInformation->Name;
       InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, hDevicesKey, NULL);
       Status = ZwOpenKey(
          &hDeviceKey,
-         KEY_QUERY_VALUE + EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0,
+         KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0),
          &ObjectAttributes);
       if (!NT_SUCCESS(Status))
       {
@@ -2902,7 +2845,7 @@ IopEnumerateDetectedDevices(
                goto cleanup;
             }
             IndexSubKey++;
-            DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
+            DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
             DeviceName.Buffer = pDeviceInformation->Name;
 
             Status = IopEnumerateDetectedDevices(
@@ -2948,7 +2891,7 @@ IopEnumerateDetectedDevices(
       else
       {
          /* Assign hardware id to this device */
-         ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength;
+         ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
          ValueName.Buffer = (PWCHAR)pValueInformation->Data;
          if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
             ValueName.Length -= sizeof(WCHAR);
@@ -3300,17 +3243,79 @@ IopUpdateRootKey(VOID)
 }
 
 VOID INIT_FUNCTION
-PnpInit2(VOID)
+PnpInit(VOID)
 {
-   NTSTATUS Status;
+    PDEVICE_OBJECT Pdo;
+    NTSTATUS Status;
 
-   /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
-   Status = IopUpdateRootKey();
-   if (!NT_SUCCESS(Status))
-   {
-      CPRINT("IopUpdateRootKey() failed\n");
-      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-   }
+    DPRINT("PnpInit()\n");
+
+    KeInitializeSpinLock(&IopDeviceTreeLock);
+
+    /* Initialize the Bus Type GUID List */
+    IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
+    RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
+    ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
+
+    /* Initialize PnP-Event notification support */
+    Status = IopInitPlugPlayEvents();
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("IopInitPlugPlayEvents() failed\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /*
+    * Create root device node
+    */
+
+    Status = IopCreateDriverObject(&IopRootDriverObject, NULL, 0, FALSE, NULL, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("IoCreateDriverObject() failed\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
+        0, FALSE, &Pdo);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("IoCreateDevice() failed\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("Insufficient resources\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
+        L"HTREE\\ROOT\\0"))
+    {
+        CPRINT("Failed to create the instance path!\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
+    }
+
+    /* Report the device to the user-mode pnp manager */
+    IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
+        &IopRootDeviceNode->InstancePath);
+
+    IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
+    PnpRootDriverEntry(IopRootDriverObject, NULL);
+    IopRootDriverObject->DriverExtension->AddDevice(
+        IopRootDriverObject,
+        IopRootDeviceNode->PhysicalDeviceObject);
+
+    /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
+    Status = IopUpdateRootKey();
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("IopUpdateRootKey() failed\n");
+        KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
 }
 
+
 /* EOF */