Пример #1
0
static NTSTATUS
FdoQueryBusRelations(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp,
  PIO_STACK_LOCATION IrpSp)
{
  PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
  PFDO_DEVICE_EXTENSION DeviceExtension;
  PDEVICE_RELATIONS Relations;
  PLIST_ENTRY CurrentEntry;
  PPCI_DEVICE Device;
  NTSTATUS Status;
  BOOLEAN ErrorOccurred;
  NTSTATUS ErrorStatus;
  ULONG Size;
  ULONG i;

  UNREFERENCED_PARAMETER(IrpSp);

  DPRINT("Called\n");

  ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;

  Status = STATUS_SUCCESS;

  ErrorOccurred = FALSE;

  FdoEnumerateDevices(DeviceObject);

  DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  if (Irp->IoStatus.Information) {
    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
              structure so we must merge this structure with our own */
  }

  Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
    (DeviceExtension->DeviceListCount - 1);
  Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
  if (!Relations)
    return STATUS_INSUFFICIENT_RESOURCES;

  Relations->Count = DeviceExtension->DeviceListCount;

  i = 0;
  CurrentEntry = DeviceExtension->DeviceListHead.Flink;
  while (CurrentEntry != &DeviceExtension->DeviceListHead) {
    Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);

    PdoDeviceExtension = NULL;

    if (!Device->Pdo) {
      /* Create a physical device object for the
         device as it does not already have one */
      Status = IoCreateDevice(
        DeviceObject->DriverObject,
        sizeof(PDO_DEVICE_EXTENSION),
        NULL,
        FILE_DEVICE_CONTROLLER,
        FILE_AUTOGENERATED_DEVICE_NAME,
        FALSE,
        &Device->Pdo);
      if (!NT_SUCCESS(Status)) {
        DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;

      //Device->Pdo->Flags |= DO_POWER_PAGABLE;

      PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;

      RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));

      PdoDeviceExtension->Common.IsFDO = FALSE;

      PdoDeviceExtension->Common.DeviceObject = Device->Pdo;

      PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;

      PdoDeviceExtension->Fdo = DeviceObject;

      PdoDeviceExtension->PciDevice = Device;

      /* Add Device ID string */
      Status = PciCreateDeviceIDString(&PdoDeviceExtension->DeviceID, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);

      /* Add Instance ID string */
      Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceID, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      /* Add Hardware IDs string */
      Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIDs, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      /* Add Compatible IDs string */
      Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIDs, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      /* Add device description string */
      Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }

      /* Add device location string */
      Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
      if (!NT_SUCCESS(Status))
      {
        ErrorStatus = Status;
        ErrorOccurred = TRUE;
        break;
      }
    }

    /* Reference the physical device object. The PnP manager
       will dereference it again when it is no longer needed */
    ObReferenceObject(Device->Pdo);

    Relations->Objects[i] = Device->Pdo;

    i++;

    CurrentEntry = CurrentEntry->Flink;
  }

  if (ErrorOccurred) {
    /* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */
    /* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */
    if (PdoDeviceExtension) {
      RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID);
      RtlFreeUnicodeString(&PdoDeviceExtension->InstanceID);
      RtlFreeUnicodeString(&PdoDeviceExtension->HardwareIDs);
      RtlFreeUnicodeString(&PdoDeviceExtension->CompatibleIDs);
      RtlFreeUnicodeString(&PdoDeviceExtension->DeviceDescription);
      RtlFreeUnicodeString(&PdoDeviceExtension->DeviceLocation);
    }

    ExFreePool(Relations);
    return ErrorStatus;
  }

  Irp->IoStatus.Information = (ULONG_PTR)Relations;

  DPRINT("Done\n");

  return Status;
}
Пример #2
0
static
NTSTATUS
FdcFdoQueryBusRelations(
    IN PDEVICE_OBJECT DeviceObject,
    OUT PDEVICE_RELATIONS *DeviceRelations)
{
    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
    INTERFACE_TYPE InterfaceType = Isa;
    CONFIGURATION_TYPE ControllerType = DiskController;
    CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
    PDEVICE_RELATIONS Relations;
    PDRIVE_INFO DriveInfo;
    PDEVICE_OBJECT Pdo;
    WCHAR DeviceNameBuffer[80];
    UNICODE_STRING DeviceName;
    ULONG DeviceNumber = 0;
    ULONG Size;
    ULONG i;
    NTSTATUS Status;

    DPRINT1("FdcFdoQueryBusRelations() called\n");

    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    Status = IoQueryDeviceDescription(&InterfaceType,
                                      NULL,
                                      &ControllerType,
                                      NULL,
                                      &PeripheralType,
                                      NULL,
                                      FdcFdoConfigCallback,
                                      FdoDeviceExtension);
    if (!NT_SUCCESS(Status) && (Status != STATUS_NO_MORE_ENTRIES))
        return Status;

    Size = sizeof(DEVICE_RELATIONS) +
           sizeof(Relations->Objects) * (FdoDeviceExtension->ControllerInfo.NumberOfDrives - 1);
    Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
    if (Relations == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Relations->Count = FdoDeviceExtension->ControllerInfo.NumberOfDrives;

    for (i = 0; i < FdoDeviceExtension->ControllerInfo.NumberOfDrives; i++)
    {
        DriveInfo = &FdoDeviceExtension->ControllerInfo.DriveInfo[i];

        if (DriveInfo->DeviceObject == NULL)
        {
            do
            {
                swprintf(DeviceNameBuffer, L"\\Device\\FloppyPDO%lu", DeviceNumber++);
                RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
                DPRINT1("Device name: %S\n", DeviceNameBuffer);

                /* Create physical device object */
                Status = IoCreateDevice(FdoDeviceExtension->Common.DeviceObject->DriverObject,
                                        sizeof(PDO_DEVICE_EXTENSION),
                                        &DeviceName,
                                        FILE_DEVICE_MASS_STORAGE,
                                        FILE_DEVICE_SECURE_OPEN,
                                        FALSE,
                                        &Pdo);
            }
            while (Status == STATUS_OBJECT_NAME_COLLISION);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("PDO creation failed (Status 0x%08lx)\n", Status);
                goto done;
            }

            DPRINT1("PDO created: %S\n", DeviceNameBuffer);

            DriveInfo->DeviceObject = Pdo;

            PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
            RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));

            PdoDeviceExtension->Common.IsFDO = FALSE;
            PdoDeviceExtension->Common.DeviceObject = Pdo;

            PdoDeviceExtension->Fdo = FdoDeviceExtension->Common.DeviceObject;
            PdoDeviceExtension->DriveInfo = DriveInfo;

            Pdo->Flags |= DO_DIRECT_IO;
            Pdo->Flags |= DO_POWER_PAGABLE;
            Pdo->Flags &= ~DO_DEVICE_INITIALIZING;

            /* Add Device ID string */
            RtlCreateUnicodeString(&PdoDeviceExtension->DeviceId,
                                   L"FDC\\GENERIC_FLOPPY_DRIVE");
            DPRINT1("DeviceID: %S\n", PdoDeviceExtension->DeviceId.Buffer);

            /* Add Hardware IDs string */
            Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIds);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add Compatible IDs string */
            Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIds);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add Instance ID string */
            Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceId,
                                               DriveInfo->PeripheralNumber);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

#if 0
             /* Add device description string */
            Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add device location string */
            Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }
#endif
        }

        ObReferenceObject(DriveInfo->DeviceObject);
        Relations->Objects[i] = DriveInfo->DeviceObject;
    }

done:
    if (NT_SUCCESS(Status))
    {
        *DeviceRelations = Relations;
    }
    else
    {
        if (Relations != NULL)
            ExFreePool(Relations);
    }

    return Status;
}