mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 17:00:31 +00:00
[CLASS2] Drop the drive letter hack
This commit is contained in:
parent
2b39b42a0a
commit
887200703c
1 changed files with 7 additions and 322 deletions
|
@ -13,10 +13,6 @@
|
|||
#include <include/class2.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Part of the drive letter hack */
|
||||
#include <ntifs.h>
|
||||
#include <ketypes.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -135,315 +131,28 @@ DriverEntry(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* The following hack to assign drive letters with a non-PnP storage stack */
|
||||
|
||||
typedef struct _CLASS_DEVICE_INFO {
|
||||
ULONG Signature;
|
||||
ULONG DeviceType;
|
||||
ULONG Partitions;
|
||||
ULONG DeviceNumber;
|
||||
ULONG DriveNumber;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
} CLASS_DEVICE_INFO, *PCLASS_DEVICE_INFO;
|
||||
|
||||
typedef struct _CLASS_DRIVER_EXTENSION {
|
||||
ULONG PortNumber;
|
||||
UNICODE_STRING RegistryPath;
|
||||
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
|
||||
ScsiClassAssignDriveLetter(PCLASS_DEVICE_INFO DeviceInfo)
|
||||
{
|
||||
WCHAR Buffer1[100];
|
||||
WCHAR Buffer2[100];
|
||||
UNICODE_STRING DriveLetterU, PartitionU;
|
||||
NTSTATUS Status;
|
||||
ULONG Index, PartitionNumber, DeviceNumber, DriveNumber;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
HANDLE PartitionHandle;
|
||||
|
||||
/* We assume this device does not current have a drive letter */
|
||||
|
||||
Index = 0;
|
||||
DeviceNumber = 0;
|
||||
DriveNumber = 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 */
|
||||
if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\HardDisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
|
||||
}
|
||||
else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\CdRom%d", 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);
|
||||
|
||||
/* Determine the correct drive number */
|
||||
do
|
||||
{
|
||||
/* Check that the drive exists */
|
||||
if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\??\\PhysicalDrive%d", DriveNumber) * sizeof(WCHAR);
|
||||
}
|
||||
else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\??\\%C:", ('C' + 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);
|
||||
|
||||
if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\Harddisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
|
||||
DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\PhysicalDrive%d", DriveNumber) * sizeof(WCHAR);
|
||||
}
|
||||
else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
|
||||
{
|
||||
PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\CdRom%d", DeviceNumber) * sizeof(WCHAR);
|
||||
DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\%C:", ('C' + DriveNumber)) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Create the symbolic link to PhysicalDriveX */
|
||||
Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed to create symbolic link */
|
||||
DbgPrint("Failed to create symbolic link %wZ -> %wZ with %lx\n", &PartitionU, &DriveLetterU, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU, &DriveLetterU);
|
||||
|
||||
DeviceInfo->DeviceNumber = DeviceNumber;
|
||||
DeviceInfo->DriveNumber = DriveNumber;
|
||||
|
||||
if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
|
||||
{
|
||||
/* done for cdroms */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
DeviceInfo->Partitions |= (1 << (Index - 1));
|
||||
|
||||
DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU, &DriveLetterU);
|
||||
PartitionNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ScsiClassPlugPlay(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
if (IrpSp->MinorFunction == IRP_MN_START_DEVICE)
|
||||
{
|
||||
ASSERT(DeviceInfo->Signature == '2slc');
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceInfo->LowerDevice, Irp);
|
||||
}
|
||||
else if (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE)
|
||||
{
|
||||
ASSERT(DeviceInfo->Signature == '2slc');
|
||||
ScsiClassRemoveDriveLetter(DeviceInfo);
|
||||
|
||||
IoForwardIrpSynchronously(DeviceInfo->LowerDevice, Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
IoDetachDevice(DeviceInfo->LowerDevice);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DeviceInfo->Signature == '2slc')
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceInfo->LowerDevice, Irp);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ScsiClassAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
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, &DriverExtension->RegistryPath, &DriverExtension->InitializationData,
|
||||
PhysicalDeviceObject, DriverExtension->PortNumber))
|
||||
{
|
||||
/* Create a device object */
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(CLASS_DEVICE_INFO),
|
||||
NULL,
|
||||
DriverExtension->InitializationData.DeviceType,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceInfo = DeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(DeviceInfo, sizeof(CLASS_DEVICE_INFO));
|
||||
DeviceInfo->Signature = '2slc';
|
||||
|
||||
/* Attach it to the PDO */
|
||||
DeviceInfo->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
||||
DeviceInfo->DeviceType = DriverExtension->InitializationData.DeviceType;
|
||||
|
||||
/* Check that the kernel has already assigned drive letters */
|
||||
if (KeLoaderBlock == NULL)
|
||||
{
|
||||
/* Assign a drive letter */
|
||||
ScsiClassAssignDriveLetter(DeviceInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The kernel will handle it */
|
||||
}
|
||||
|
||||
/* Move to the next port number */
|
||||
DriverExtension->PortNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to find device */
|
||||
DbgPrint("FAILED TO FIND DEVICE!\n");
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* ---- End hack ---- */
|
||||
|
||||
|
||||
|
||||
ULONG
|
||||
|
@ -477,15 +186,14 @@ Return Value:
|
|||
|
||||
|
||||
PDRIVER_OBJECT DriverObject = Argument1;
|
||||
ULONG portNumber = 0;
|
||||
PDEVICE_OBJECT portDeviceObject;
|
||||
NTSTATUS status;
|
||||
STRING deviceNameString;
|
||||
UNICODE_STRING unicodeDeviceName;
|
||||
PFILE_OBJECT fileObject;
|
||||
CCHAR deviceNameBuffer[256];
|
||||
/* BOOLEAN deviceFound = FALSE; See note at the end */
|
||||
PCLASS_DRIVER_EXTENSION DriverExtension;
|
||||
PUNICODE_STRING RegistryPath = Argument2;
|
||||
BOOLEAN deviceFound = FALSE;
|
||||
|
||||
DebugPrint((3,"\n\nSCSI Class Driver\n"));
|
||||
|
||||
|
@ -516,27 +224,6 @@ Return Value:
|
|||
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;
|
||||
|
||||
DriverExtension->RegistryPath.Buffer = ExAllocatePool(PagedPool, RegistryPath->MaximumLength);
|
||||
if (!DriverExtension->RegistryPath.Buffer)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
DriverExtension->RegistryPath.Length = RegistryPath->Length;
|
||||
DriverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
|
||||
|
||||
RtlCopyMemory(DriverExtension->RegistryPath.Buffer,
|
||||
RegistryPath->Buffer,
|
||||
RegistryPath->Length);
|
||||
|
||||
//
|
||||
// Update driver object with entry points.
|
||||
//
|
||||
|
@ -550,7 +237,6 @@ Return Value:
|
|||
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;
|
||||
|
@ -562,7 +248,7 @@ Return Value:
|
|||
|
||||
do {
|
||||
|
||||
sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", DriverExtension->PortNumber);
|
||||
sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", portNumber);
|
||||
|
||||
DebugPrint((2, "ScsiClassInitialize: Open Port %s\n", deviceNameBuffer));
|
||||
|
||||
|
@ -588,9 +274,9 @@ Return Value:
|
|||
//
|
||||
|
||||
if (InitializationData->ClassFindDevices(DriverObject, Argument2, InitializationData,
|
||||
portDeviceObject, DriverExtension->PortNumber)) {
|
||||
portDeviceObject, portNumber)) {
|
||||
|
||||
/* deviceFound = TRUE; See note at the end */
|
||||
deviceFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,12 +284,11 @@ Return Value:
|
|||
// Check next SCSI adapter.
|
||||
//
|
||||
|
||||
DriverExtension->PortNumber++;
|
||||
portNumber++;
|
||||
|
||||
} while(NT_SUCCESS(status));
|
||||
|
||||
/* We don't want to fail init just because we don't have devices right now */
|
||||
return STATUS_SUCCESS; /*deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;*/
|
||||
return deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue