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; }
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; }