From c4a2e2e22bb3d920e47fadde54dda562036fc74a Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Mon, 21 Jul 2008 06:35:39 +0000 Subject: [PATCH] - Implement RamdiskReadWrite. - Implement RamdiskReadWriteReal. - We now have a working copy loop for both read and write operations. - Need to implement RamdiskMapPages and RamdiskUnmapPages -- then we'll nearly be done! svn path=/trunk/; revision=34625 --- .../drivers/storage/class/ramdisk/ramdisk.c | 245 +++++++++++++++++- 1 file changed, 242 insertions(+), 3 deletions(-) diff --git a/reactos/drivers/storage/class/ramdisk/ramdisk.c b/reactos/drivers/storage/class/ramdisk/ramdisk.c index 1ca15cd89f6..5aa3a4e09dd 100644 --- a/reactos/drivers/storage/class/ramdisk/ramdisk.c +++ b/reactos/drivers/storage/class/ramdisk/ramdisk.c @@ -832,6 +832,165 @@ SendIrpToThread(IN PDEVICE_OBJECT DeviceObject, } } +PVOID +NTAPI +RamdiskMapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension, + IN LARGE_INTEGER Offset, + IN ULONG Length, + OUT PULONG OutputLength) +{ + DPRINT1("Mapping %lx bytes at %I64x\n", Length, Offset.QuadPart); + UNIMPLEMENTED; + while (TRUE); + return NULL; +} + +PVOID +NTAPI +RamdiskUnmapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension, + IN PVOID BaseAddress, + IN LARGE_INTEGER Offset, + IN ULONG Length) +{ + UNIMPLEMENTED; + while (TRUE); + return NULL; +} + +NTSTATUS +NTAPI +RamdiskReadWriteReal(IN PIRP Irp, + IN PRAMDISK_DRIVE_EXTENSION DeviceExtension) +{ + PMDL Mdl; + PVOID CurrentBase, SystemVa, BaseAddress; + PIO_STACK_LOCATION IoStackLocation; + LARGE_INTEGER CurrentOffset; + ULONG BytesRead, BytesLeft, CopyLength; + PVOID Source, Destination; + NTSTATUS Status; + + // + // Get the MDL and check if it's mapped + // + Mdl = Irp->MdlAddress; + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + { + // + // Use the mapped address + // + SystemVa = Mdl->MappedSystemVa; + } + else + { + // + // Map it ourselves + // + SystemVa = MmMapLockedPagesSpecifyCache(Mdl, + 0, + MmCached, + NULL, + 0, + NormalPagePriority); + } + + // + // Make sure we were able to map it + // + CurrentBase = SystemVa; + if (!SystemVa) return STATUS_INSUFFICIENT_RESOURCES; + + // + // Initialize default + // + Irp->IoStatus.Information = 0; + + // + // Get the I/O Stack Location and capture the data + // + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + CurrentOffset = IoStackLocation->Parameters.Read.ByteOffset; + BytesLeft = IoStackLocation->Parameters.Read.Length; + if (!BytesLeft) return STATUS_INVALID_PARAMETER; + + // + // Do the copy loop + // + DPRINT1("Initiating copy loop for %lx bytes at %p\n", BytesLeft, SystemVa); + while (TRUE) + { + // + // Map the pages + // + BaseAddress = RamdiskMapPages(DeviceExtension, + CurrentOffset, + BytesLeft, + &BytesRead); + if (!BaseAddress) return STATUS_INSUFFICIENT_RESOURCES; + + // + // Update our lengths + // + Irp->IoStatus.Information += BytesRead; + CopyLength = BytesRead; + + // + // Check if this was a read or write + // + Status = STATUS_SUCCESS; + if (IoStackLocation->MajorFunction == IRP_MJ_READ) + { + // + // Set our copy parameters + // + Destination = CurrentBase; + Source = BaseAddress; + goto DoCopy; + } + else if (IoStackLocation->MajorFunction == IRP_MJ_WRITE) + { + // + // Set our copy parameters + // + Destination = BaseAddress; + Source = CurrentBase; +DoCopy: + // + // Copy the data + // + RtlCopyMemory(Destination, Source, CopyLength); + } + else + { + // + // Prepare us for failure + // + BytesLeft = CopyLength; + Status = STATUS_INVALID_PARAMETER; + } + + // + // Unmap the pages + // + RamdiskUnmapPages(DeviceExtension, + BaseAddress, + CurrentOffset, + BytesRead); + + // + // Update offset and bytes left + // + BytesLeft -= BytesRead; + CurrentOffset.QuadPart += BytesRead; + CurrentBase = (PVOID)((ULONG_PTR)CurrentBase + BytesRead); + + // + // Check if we're done + // + if (!BytesLeft) return Status; + } +} + NTSTATUS NTAPI RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject, @@ -851,9 +1010,89 @@ NTAPI RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_SUCCESS; + PRAMDISK_DRIVE_EXTENSION DeviceExtension; + ULONG Length; + LARGE_INTEGER ByteOffset; + PIO_STACK_LOCATION IoStackLocation; + NTSTATUS Status, ReturnStatus; + + // + // Get the device extension and make sure this isn't a bus + // + DeviceExtension = DeviceObject->DeviceExtension; + if (DeviceExtension->Type == RamdiskBus) + { + // + // Fail + // + Status = STATUS_INVALID_DEVICE_REQUEST; + goto Complete; + } + + // + // Capture parameters + // + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + Length = IoStackLocation->Parameters.Read.Length; + ByteOffset = IoStackLocation->Parameters.Read.ByteOffset; + + // + // FIXME: Validate offset + // + + // + // FIXME: Validate sector + // + + // + // Validate write + // + if ((IoStackLocation->MajorFunction == IRP_MJ_WRITE) && + (DeviceExtension->DiskOptions.Readonly)) + { + // + // Fail, this is read-only + // + Status = STATUS_MEDIA_WRITE_PROTECTED; + goto Complete; + } + + // + // See if we want to do this sync or async + // + if (DeviceExtension->DiskType > FILE_DEVICE_CD_ROM) + { + // + // Do it sync + // + Status = RamdiskReadWriteReal(Irp, DeviceExtension); + goto Complete; + } + + // + // Queue it to the worker + // + Status = SendIrpToThread(DeviceObject, Irp); + ReturnStatus = STATUS_PENDING; + + // + // Check if we're pending or not + // + if (Status != STATUS_PENDING) + { +Complete: + // + // Complete the IRP + // + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_DISK_INCREMENT); + ReturnStatus = Status; + } + + // + // Return to caller + // + return ReturnStatus; } NTSTATUS