Author: cgutman
Date: Sat Jan 21 22:08:33 2012
New Revision: 55056
URL:
http://svn.reactos.org/svn/reactos?rev=55056&view=rev
Log:
[USB-BRINGUP-TRUNK]
- Add a class2 hack to recognize and assign drive letters to storage devices added while
the system is running
Modified:
branches/usb-bringup-trunk/drivers/storage/class/class2/class2.c
Modified: branches/usb-bringup-trunk/drivers/storage/class/class2/class2.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/stora…
==============================================================================
--- branches/usb-bringup-trunk/drivers/storage/class/class2/class2.c [iso-8859-1]
(original)
+++ branches/usb-bringup-trunk/drivers/storage/class/class2/class2.c [iso-8859-1] Sat Jan
21 22:08:33 2012
@@ -130,6 +130,164 @@
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+ScsiClassPlugPlay(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IrpSp->MinorFunction == IRP_MN_START_DEVICE)
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NOT_SUPPORTED;
+ }
+}
+
+/* This is a hack to assign drive letters with a non-PnP storage stack */
+NTSTATUS
+NTAPI
+ScsiClassAssignDriveLetter(VOID)
+{
+ WCHAR Buffer1[100];
+ WCHAR Buffer2[100];
+ UNICODE_STRING DriveLetterU, PartitionU;
+ NTSTATUS Status;
+ ULONG Index, PartitionNumber, DeviceNumber;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK Iosb;
+ HANDLE PartitionHandle;
+
+ /* We assume this device does not current have a drive letter */
+
+ Index = 0;
+ DeviceNumber = 0;
+ PartitionNumber = 1;
+ DriveLetterU.Buffer = Buffer1;
+ DriveLetterU.MaximumLength = sizeof(Buffer1);
+ PartitionU.Buffer = Buffer2;
+ PartitionU.MaximumLength = sizeof(Buffer2);
+
+ /* Determine the correct disk number */
+ do
+ {
+ /* Check that the disk exists */
+ PartitionU.Length = swprintf(PartitionU.Buffer,
L"\\Device\\HardDisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &PartitionU,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwOpenFile(&PartitionHandle,
+ FILE_READ_ATTRIBUTES,
+ &ObjectAttributes,
+ &Iosb,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Return the last one that worked */
+ DeviceNumber--;
+ }
+ else
+ {
+ ZwClose(PartitionHandle);
+ DeviceNumber++;
+ }
+ } while (Status == STATUS_SUCCESS);
+
+ /* Create the symbolic link to PhysicalDriveX */
+ PartitionU.Length = swprintf(PartitionU.Buffer,
L"\\Device\\Harddisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
+ DriveLetterU.Length = swprintf(DriveLetterU.Buffer,
L"\\??\\PhysicalDrive%d", DeviceNumber) * sizeof(WCHAR);
+
+ Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed to create symbolic link */
+ return Status;
+ }
+
+ DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU,
&DriveLetterU);
+
+ while (TRUE)
+ {
+ /* Check that the disk exists */
+ PartitionU.Length = swprintf(PartitionU.Buffer,
L"\\Device\\Harddisk%d\\Partition%d", DeviceNumber, PartitionNumber) *
sizeof(WCHAR);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &PartitionU,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwOpenFile(&PartitionHandle,
+ FILE_READ_ATTRIBUTES,
+ &ObjectAttributes,
+ &Iosb,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ break;
+ else
+ {
+ ZwClose(PartitionHandle);
+
+ /* Assign it a drive letter */
+ do
+ {
+ DriveLetterU.Length = swprintf(DriveLetterU.Buffer,
L"\\??\\%C:", ('C' + Index)) * sizeof(WCHAR);
+
+ Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU);
+
+ Index++;
+ } while (Status != STATUS_SUCCESS);
+
+ DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n",
&PartitionU, &DriveLetterU);
+ PartitionNumber++;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+typedef struct _CLASS_DRIVER_EXTENSION {
+ ULONG PortNumber;
+ CLASS_INIT_DATA InitializationData;
+} CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
+
+NTSTATUS
+NTAPI
+ScsiClassAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ PCLASS_DRIVER_EXTENSION DriverExtension = IoGetDriverObjectExtension(DriverObject,
DriverObject);
+
+ if (DriverExtension->InitializationData.ClassFindDevices(DriverObject, NULL,
&DriverExtension->InitializationData,
+ PhysicalDeviceObject,
DriverExtension->PortNumber))
+ {
+ /* Assign a drive letter */
+ ScsiClassAssignDriveLetter();
+
+ /* Increment the port number */
+ DriverExtension->PortNumber++;
+ }
+ else
+ {
+ /* Failed to find device */
+ DbgPrint("FAILED TO FIND DEVICE!\n");
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
ULONG
NTAPI
@@ -162,7 +320,6 @@
PDRIVER_OBJECT DriverObject = Argument1;
- ULONG portNumber = 0;
PDEVICE_OBJECT portDeviceObject;
NTSTATUS status;
STRING deviceNameString;
@@ -170,6 +327,7 @@
PFILE_OBJECT fileObject;
CCHAR deviceNameBuffer[256];
BOOLEAN deviceFound = FALSE;
+ PCLASS_DRIVER_EXTENSION DriverExtension;
DebugPrint((3,"\n\nSCSI Class Driver\n"));
@@ -200,6 +358,16 @@
return (ULONG) STATUS_REVISION_MISMATCH;
}
+ status = IoAllocateDriverObjectExtension(DriverObject,
+ DriverObject,
+ sizeof(CLASS_DRIVER_EXTENSION),
+ (PVOID *)&DriverExtension);
+ if (!NT_SUCCESS(status))
+ return status;
+
+ RtlCopyMemory(&DriverExtension->InitializationData, InitializationData,
sizeof(CLASS_INIT_DATA));
+ DriverExtension->PortNumber = 0;
+
//
// Update driver object with entry points.
//
@@ -208,10 +376,12 @@
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScsiClassCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = ScsiClassReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScsiClassReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = ScsiClassPlugPlay;
DriverObject->MajorFunction[IRP_MJ_SCSI] = ScsiClassInternalIoControl;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
ScsiClassDeviceControlDispatch;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ScsiClassShutdownFlush;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ScsiClassShutdownFlush;
+ DriverObject->DriverExtension->AddDevice = ScsiClassAddDevice;
if (InitializationData->ClassStartIo) {
DriverObject->DriverStartIo = InitializationData->ClassStartIo;
@@ -223,7 +393,7 @@
do {
- sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", portNumber);
+ sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu",
DriverExtension->PortNumber);
DebugPrint((2, "ScsiClassInitialize: Open Port %s\n",
deviceNameBuffer));
@@ -249,7 +419,7 @@
//
if (InitializationData->ClassFindDevices(DriverObject, Argument2,
InitializationData,
- portDeviceObject, portNumber)) {
+ portDeviceObject,
DriverExtension->PortNumber)) {
deviceFound = TRUE;
}
@@ -259,7 +429,7 @@
// Check next SCSI adapter.
//
- portNumber++;
+ DriverExtension->PortNumber++;
} while(NT_SUCCESS(status));