mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[FLOPPY] Make floppy drives letters being handled by the MountMgr
This involves many changes/fixes in the floppy driver: - Stop creating ourselves our DOS device, it's up to the MountMgr or to the kernel; - Report each new floppy drive to the MountMgr (this is a hack for now); - As a consequence, stop storing the symlink name into the DRIVE_INFO structure; - Store the device name instead; - On IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, don't return DOS device, but device name; - On IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, properly return if buffer is way too small; - Hackplement IOCTL_MOUNTDEV_QUERY_UNIQUE_ID so that it returns device name.
This commit is contained in:
parent
e133817811
commit
6889cff5b5
3 changed files with 143 additions and 35 deletions
|
@ -406,9 +406,6 @@ Unload(PDRIVER_OBJECT DriverObject)
|
|||
{
|
||||
UNICODE_STRING Link;
|
||||
|
||||
RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
|
||||
IoDeleteSymbolicLink(&Link);
|
||||
|
||||
RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
|
||||
IoDeassignArcName(&Link);
|
||||
|
||||
|
@ -811,6 +808,98 @@ InitController(PCONTROLLER_INFO ControllerInfo)
|
|||
}
|
||||
|
||||
|
||||
static VOID NTAPI
|
||||
ReportToMountMgr(UCHAR ControlerId, UCHAR DriveId)
|
||||
/*
|
||||
* FUNCTION: Called to report a new controler to the MountMgr
|
||||
* ARGUMENTS:
|
||||
* ControlerId: ID of the controler
|
||||
* DriveId: ID of the device for the controler
|
||||
* RETURNS:
|
||||
* Nothing
|
||||
* NOTES:
|
||||
* - This is a hack to allow MountMgr handling our devices
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING MountMgrDevice;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PFILE_OBJECT FileObject;
|
||||
PMOUNTMGR_TARGET_NAME MountTarget;
|
||||
ULONG DeviceLen;
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
/* First, get MountMgr DeviceObject */
|
||||
RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
|
||||
Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
|
||||
&FileObject, &DeviceObject);
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
WARN_(FLOPPY, "ReportToMountMgr: Can't get MountMgr pointers %lx\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceLen = wcslen(&gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer[0]) * sizeof(WCHAR);
|
||||
|
||||
/* Allocate input buffer to report our floppy device */
|
||||
MountTarget = ExAllocatePool(NonPagedPool,
|
||||
sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen);
|
||||
|
||||
if(!MountTarget)
|
||||
{
|
||||
WARN_(FLOPPY, "ReportToMountMgr: Allocation of mountTarget failed\n");
|
||||
ObDereferenceObject(FileObject);
|
||||
return;
|
||||
}
|
||||
|
||||
MountTarget->DeviceNameLength = DeviceLen;
|
||||
RtlCopyMemory(MountTarget->DeviceName,
|
||||
gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer,
|
||||
DeviceLen);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* Build the IRP used to communicate with the MountMgr */
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
|
||||
DeviceObject,
|
||||
MountTarget,
|
||||
sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
|
||||
if(!Irp)
|
||||
{
|
||||
WARN_(FLOPPY, "ReportToMountMgr: Allocation of irp failed\n");
|
||||
ExFreePool(MountTarget);
|
||||
ObDereferenceObject(FileObject);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the MountMgr */
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING) {
|
||||
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
/* We're done */
|
||||
|
||||
INFO_(FLOPPY, "Reported to the MountMgr: %lx\n", Status);
|
||||
|
||||
ExFreePool(MountTarget);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
AddControllers(PDRIVER_OBJECT DriverObject)
|
||||
/*
|
||||
|
@ -912,9 +1001,7 @@ AddControllers(PDRIVER_OBJECT DriverObject)
|
|||
/* 3: per-drive setup */
|
||||
for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
|
||||
{
|
||||
WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING LinkName;
|
||||
UNICODE_STRING ArcPath;
|
||||
UCHAR DriveNumber;
|
||||
|
||||
|
@ -936,9 +1023,8 @@ AddControllers(PDRIVER_OBJECT DriverObject)
|
|||
|
||||
DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */
|
||||
|
||||
RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR));
|
||||
swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuf);
|
||||
swprintf(gControllerInfo[i].DriveInfo[j].DeviceNameBuffer, L"\\Device\\Floppy%d", DriveNumber);
|
||||
RtlInitUnicodeString(&DeviceName, gControllerInfo[i].DriveInfo[j].DeviceNameBuffer);
|
||||
|
||||
if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName,
|
||||
FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE, FALSE,
|
||||
|
@ -949,7 +1035,9 @@ AddControllers(PDRIVER_OBJECT DriverObject)
|
|||
continue; /* continue on to next drive */
|
||||
}
|
||||
|
||||
INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n", DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject);
|
||||
INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n",
|
||||
gControllerInfo[i].DriveInfo[j].DeviceNameBuffer,
|
||||
gControllerInfo[i].DriveInfo[j].DeviceObject);
|
||||
|
||||
/* 3b.5: Create an ARC path in case we're booting from this drive */
|
||||
swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer,
|
||||
|
@ -961,38 +1049,30 @@ AddControllers(PDRIVER_OBJECT DriverObject)
|
|||
/* 3c: Set flags up */
|
||||
gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
|
||||
|
||||
/* 3d: Create a symlink */
|
||||
swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer, L"\\DosDevices\\%c:", DriveNumber + 'A');
|
||||
RtlInitUnicodeString(&LinkName, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
|
||||
if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS)
|
||||
{
|
||||
WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive %d\n", DriveNumber);
|
||||
IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
|
||||
IoDeassignArcName(&ArcPath);
|
||||
continue; /* continue to next drive */
|
||||
}
|
||||
|
||||
/* 3e: Increase global floppy drives count */
|
||||
/* 3d: Increase global floppy drives count */
|
||||
IoGetConfigurationInformation()->FloppyCount++;
|
||||
|
||||
/* 3f: Set up the DPC */
|
||||
/* 3e: Set up the DPC */
|
||||
IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject, (PIO_DPC_ROUTINE)DpcForIsr);
|
||||
|
||||
/* 3g: Point the device extension at our DriveInfo struct */
|
||||
/* 3f: Point the device extension at our DriveInfo struct */
|
||||
gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension = &gControllerInfo[i].DriveInfo[j];
|
||||
|
||||
/* 3h: neat comic strip */
|
||||
/* 3g: neat comic strip */
|
||||
|
||||
/* 3i: set the initial media type to unknown */
|
||||
/* 3h: set the initial media type to unknown */
|
||||
memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
|
||||
gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown;
|
||||
|
||||
/* 3j: Now that we're done, set the Initialized flag so we know to free this in Unload */
|
||||
/* 3i: Now that we're done, set the Initialized flag so we know to free this in Unload */
|
||||
gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
|
||||
|
||||
/* 3k: Clear the DO_DEVICE_INITIALIZING flag */
|
||||
/* 3j: Clear the DO_DEVICE_INITIALIZING flag */
|
||||
gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
/* 3k: Report to the MountMgr */
|
||||
ReportToMountMgr(i, j);
|
||||
|
||||
/* 3l: Attempt to get drive info - if a floppy is already present */
|
||||
StartMotor(&gControllerInfo[i].DriveInfo[j]);
|
||||
RWDetermineMediaType(&gControllerInfo[i].DriveInfo[j], TRUE);
|
||||
|
|
|
@ -48,8 +48,8 @@ typedef struct _DRIVE_INFO
|
|||
CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
UCHAR BytesPerSectorCode;
|
||||
WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
|
||||
WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
|
||||
WCHAR DeviceNameBuffer[MAX_DEVICE_NAME];
|
||||
ULONG DiskChangeCount;
|
||||
BOOLEAN Initialized;
|
||||
} DRIVE_INFO, *PDRIVE_INFO;
|
||||
|
|
|
@ -75,6 +75,7 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
|
|||
ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
|
||||
BOOLEAN DiskChanged;
|
||||
PMOUNTDEV_NAME Name;
|
||||
PMOUNTDEV_UNIQUE_ID UniqueId;
|
||||
|
||||
TRACE_(FLOPPY, "DeviceIoctl called\n");
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
@ -256,27 +257,54 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
|
|||
Irp->IoStatus.Information = 0;
|
||||
break;
|
||||
|
||||
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
|
||||
if (OutputLength < sizeof(MOUNTDEV_NAME)) {
|
||||
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
|
||||
if(OutputLength < sizeof(MOUNTDEV_UNIQUE_ID))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
|
||||
Irp->IoStatus.Information = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
UniqueId = Irp->AssociatedIrp.SystemBuffer;
|
||||
UniqueId->UniqueIdLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
|
||||
|
||||
if(OutputLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
RtlCopyMemory(UniqueId->UniqueId, &DriveInfo->DeviceNameBuffer[0],
|
||||
UniqueId->UniqueIdLength);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength;
|
||||
break;
|
||||
|
||||
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
|
||||
if(OutputLength < sizeof(MOUNTDEV_NAME))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Name = Irp->AssociatedIrp.SystemBuffer;
|
||||
Name->NameLength = wcslen(&DriveInfo->SymLinkBuffer[0]) * sizeof(WCHAR);
|
||||
Name->NameLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
|
||||
|
||||
if (OutputLength < sizeof(USHORT) + Name->NameLength) {
|
||||
if(OutputLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
|
||||
break;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Name->Name, &DriveInfo->SymLinkBuffer[0],
|
||||
RtlCopyMemory(Name->Name, &DriveInfo->DeviceNameBuffer[0],
|
||||
Name->NameLength);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(USHORT) + Name->NameLength;
|
||||
Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue