mirror of
https://github.com/reactos/reactos.git
synced 2024-07-03 03:04:22 +00:00
- 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
This commit is contained in:
parent
861184aa18
commit
c4a2e2e22b
|
@ -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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject,
|
RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -851,9 +1010,89 @@ NTAPI
|
||||||
RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
|
RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PRAMDISK_DRIVE_EXTENSION DeviceExtension;
|
||||||
while (TRUE);
|
ULONG Length;
|
||||||
return STATUS_SUCCESS;
|
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
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue