Author: cgutman Date: Tue Jan 24 03:25:52 2012 New Revision: 55136
URL: http://svn.reactos.org/svn/reactos?rev=55136&view=rev Log: [CLASS2] - Add more black magic to remove symbolic links when a drive is removed
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/storag... ============================================================================== --- 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] Tue Jan 24 03:25:52 2012 @@ -130,38 +130,57 @@ return STATUS_SUCCESS; }
+/* The following hack to assign drive letters with a non-PnP storage stack */ + +typedef struct _CLASS_DEVICE_INFO { + ULONG Partitions; + ULONG DeviceNumber; + ULONG DriveNumber; + PDEVICE_OBJECT LowerDevice; +} CLASS_DEVICE_INFO, *PCLASS_DEVICE_INFO; + +typedef struct _CLASS_DRIVER_EXTENSION { + ULONG PortNumber; + CLASS_INIT_DATA InitializationData; +} CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION; + +VOID +NTAPI +ScsiClassRemoveDriveLetter(PCLASS_DEVICE_INFO DeviceInfo) +{ + WCHAR Buffer1[100]; + UNICODE_STRING DriveLetterU; + ULONG Index; + + DriveLetterU.Buffer = Buffer1; + DriveLetterU.MaximumLength = sizeof(Buffer1); + + /* Delete the symbolic link to PhysicalDriveX */ + DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\??\PhysicalDrive%d", DeviceInfo->DriveNumber) * sizeof(WCHAR); + IoDeleteSymbolicLink(&DriveLetterU); + + DbgPrint("HACK: Deleted symbolic link %wZ\n", &DriveLetterU); + + for (Index = 0; Index < sizeof(ULONG) * 8; Index++) + { + if (DeviceInfo->Partitions & (1 << Index)) + { + DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\??\%C:", ('C' + Index)) * sizeof(WCHAR); + IoDeleteSymbolicLink(&DriveLetterU); + DbgPrint("HACK: Deleted symbolic link %wZ\n", &DriveLetterU); + } + } +} + 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) +ScsiClassAssignDriveLetter(PCLASS_DEVICE_INFO DeviceInfo) { WCHAR Buffer1[100]; WCHAR Buffer2[100]; UNICODE_STRING DriveLetterU, PartitionU; NTSTATUS Status; - ULONG Index, PartitionNumber, DeviceNumber; + ULONG Index, PartitionNumber, DeviceNumber, DriveNumber; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK Iosb; HANDLE PartitionHandle; @@ -170,6 +189,7 @@
Index = 0; DeviceNumber = 0; + DriveNumber = 0; PartitionNumber = 1; DriveLetterU.Buffer = Buffer1; DriveLetterU.MaximumLength = sizeof(Buffer1); @@ -204,9 +224,32 @@ } } while (Status == STATUS_SUCCESS);
+ /* Determine the correct drive number */ + do + { + /* Check that the drive exists */ + PartitionU.Length = swprintf(PartitionU.Buffer, L"\??\PhysicalDrive%d", DriveNumber) * 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)) + { + ZwClose(PartitionHandle); + DriveNumber++; + } + } 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); + DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\??\PhysicalDrive%d", DriveNumber) * sizeof(WCHAR);
Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU); if (!NT_SUCCESS(Status)) @@ -248,18 +291,52 @@ Index++; } while (Status != STATUS_SUCCESS);
+ DeviceInfo->Partitions |= (1 << (Index - 1)); + DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU, &DriveLetterU); PartitionNumber++; } }
+ DeviceInfo->DeviceNumber = DeviceNumber; + DeviceInfo->DriveNumber = DriveNumber; + return STATUS_SUCCESS; }
-typedef struct _CLASS_DRIVER_EXTENSION { - ULONG PortNumber; - CLASS_INIT_DATA InitializationData; -} CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION; +NTSTATUS +NTAPI +ScsiClassPlugPlay( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + + if (IrpSp->MinorFunction == IRP_MN_START_DEVICE) + { + IoSkipCurrentIrpStackLocation(Irp); + return STATUS_SUCCESS; + } + else if (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE) + { + PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension; + + ScsiClassRemoveDriveLetter(DeviceInfo); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + IoDetachDevice(DeviceInfo->LowerDevice); + IoDeleteDevice(DeviceObject); + return STATUS_SUCCESS; + } + else + { + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_SUPPORTED; + } +}
NTSTATUS NTAPI @@ -268,15 +345,34 @@ IN PDEVICE_OBJECT PhysicalDeviceObject) { PCLASS_DRIVER_EXTENSION DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + PCLASS_DEVICE_INFO DeviceInfo; + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status;
if (DriverExtension->InitializationData.ClassFindDevices(DriverObject, NULL, &DriverExtension->InitializationData, PhysicalDeviceObject, DriverExtension->PortNumber)) { + /* Create a device object */ + Status = IoCreateDevice(DriverObject, + sizeof(CLASS_DEVICE_INFO), + NULL, + FILE_DEVICE_DISK, + 0, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + DeviceInfo = DeviceObject->DeviceExtension; + RtlZeroMemory(DeviceInfo, sizeof(CLASS_DEVICE_INFO)); + + /* Attach it to the PDO */ + DeviceInfo->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); + /* Assign a drive letter */ - ScsiClassAssignDriveLetter(); - - /* Increment the port number */ - DriverExtension->PortNumber++; + ScsiClassAssignDriveLetter(DeviceInfo); } else { @@ -286,6 +382,7 @@
return STATUS_SUCCESS; } +/* ---- End hack ---- */