mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 12:06:52 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
435
drivers/filesystems/fastfat/blockdev.c
Normal file
435
drivers/filesystems/fastfat/blockdev.c
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/fs/vfat/blockdev.c
|
||||
* PURPOSE: Temporary sector reading support
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "vfat.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatReadWritePartialCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PVFAT_IRP_CONTEXT IrpContext;
|
||||
PMDL Mdl;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
DPRINT("VfatReadWritePartialCompletion() called\n");
|
||||
|
||||
IrpContext = (PVFAT_IRP_CONTEXT)Context;
|
||||
|
||||
while ((Mdl = Irp->MdlAddress))
|
||||
{
|
||||
Irp->MdlAddress = Mdl->Next;
|
||||
IoFreeMdl(Mdl);
|
||||
}
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
|
||||
}
|
||||
else
|
||||
{
|
||||
IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Irp->IoStatus.Status))
|
||||
{
|
||||
IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
|
||||
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_PENDINGRETURNED))
|
||||
{
|
||||
KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
IoFreeIrp(Irp);
|
||||
|
||||
DPRINT("VfatReadWritePartialCompletion() done\n");
|
||||
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatReadDisk(
|
||||
IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN PLARGE_INTEGER ReadOffset,
|
||||
IN ULONG ReadLength,
|
||||
IN OUT PUCHAR Buffer,
|
||||
IN BOOLEAN Override)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
|
||||
again:
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
|
||||
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
|
||||
|
||||
DPRINT ("Building synchronous FSD Request...\n");
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||
pDeviceObject,
|
||||
Buffer,
|
||||
ReadLength,
|
||||
ReadOffset,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoBuildSynchronousFsdRequest failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (Override)
|
||||
{
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
|
||||
}
|
||||
|
||||
DPRINT("Calling IO Driver... with irp %p\n", Irp);
|
||||
Status = IoCallDriver (pDeviceObject, Irp);
|
||||
|
||||
DPRINT("Waiting for IO Operation for %p\n", Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Operation pending\n");
|
||||
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
DPRINT("Getting IO Status... for %p\n", Irp);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
|
||||
DPRINT1 ("Media change detected!\n");
|
||||
|
||||
/* Find the device to verify and reset the thread field to empty value again. */
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
Status = IoVerifyVolume(DeviceToVerify,
|
||||
FALSE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Volume verification successful; Reissuing read request\n");
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
|
||||
DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
|
||||
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
|
||||
return Status;
|
||||
}
|
||||
DPRINT("Block request succeeded for %p\n", Irp);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatReadDiskPartial(
|
||||
IN PVFAT_IRP_CONTEXT IrpContext,
|
||||
IN PLARGE_INTEGER ReadOffset,
|
||||
IN ULONG ReadLength,
|
||||
ULONG BufferOffset,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
NTSTATUS Status;
|
||||
PVOID Buffer;
|
||||
|
||||
DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
|
||||
IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
|
||||
|
||||
DPRINT("Building asynchronous FSD Request...\n");
|
||||
|
||||
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
|
||||
|
||||
again:
|
||||
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoAllocateIrp failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
Irp->UserIosb = NULL;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = IRP_MJ_READ;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->CompletionRoutine = NULL;
|
||||
StackPtr->Parameters.Read.Length = ReadLength;
|
||||
StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
|
||||
|
||||
if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
|
||||
{
|
||||
DPRINT("IoAllocateMdl failed\n");
|
||||
IoFreeIrp(Irp);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
|
||||
|
||||
IoSetCompletionRoutine(Irp,
|
||||
VfatReadWritePartialCompletion,
|
||||
IrpContext,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
if (Wait)
|
||||
{
|
||||
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
|
||||
IrpContext->RefCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedIncrement((PLONG)&IrpContext->RefCount);
|
||||
}
|
||||
|
||||
DPRINT("Calling IO Driver... with irp %p\n", Irp);
|
||||
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
|
||||
|
||||
if (Wait && Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IrpContext->Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
|
||||
DPRINT1("Media change detected!\n");
|
||||
|
||||
/* Find the device to verify and reset the thread field to empty value again. */
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
Status = IoVerifyVolume(DeviceToVerify,
|
||||
FALSE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Volume verification successful; Reissuing read request\n");
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
VfatWriteDiskPartial(
|
||||
IN PVFAT_IRP_CONTEXT IrpContext,
|
||||
IN PLARGE_INTEGER WriteOffset,
|
||||
IN ULONG WriteLength,
|
||||
IN ULONG BufferOffset,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
NTSTATUS Status;
|
||||
PVOID Buffer;
|
||||
|
||||
DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
|
||||
IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
|
||||
|
||||
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
|
||||
|
||||
again:
|
||||
DPRINT("Building asynchronous FSD Request...\n");
|
||||
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoAllocateIrp failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
Irp->UserIosb = NULL;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = IRP_MJ_WRITE;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->CompletionRoutine = NULL;
|
||||
StackPtr->Parameters.Read.Length = WriteLength;
|
||||
StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
|
||||
|
||||
if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
|
||||
{
|
||||
DPRINT("IoAllocateMdl failed\n");
|
||||
IoFreeIrp(Irp);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
|
||||
|
||||
IoSetCompletionRoutine(Irp,
|
||||
VfatReadWritePartialCompletion,
|
||||
IrpContext,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
if (Wait)
|
||||
{
|
||||
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
|
||||
IrpContext->RefCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedIncrement((PLONG)&IrpContext->RefCount);
|
||||
}
|
||||
|
||||
DPRINT("Calling IO Driver...\n");
|
||||
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
|
||||
if (Wait && Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IrpContext->Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
|
||||
DPRINT1("Media change detected!\n");
|
||||
|
||||
/* Find the device to verify and reset the thread field to empty value again. */
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
Status = IoVerifyVolume(DeviceToVerify,
|
||||
FALSE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Volume verification successful; Reissuing write request\n");
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatBlockDeviceIoControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG CtlCode,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferSize,
|
||||
IN OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN OUT PULONG OutputBufferSize,
|
||||
IN BOOLEAN Override)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
KEVENT Event;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
|
||||
"InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
|
||||
"OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
|
||||
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
|
||||
OutputBufferSize ? *OutputBufferSize : 0);
|
||||
|
||||
again:
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
DPRINT("Building device I/O control request ...\n");
|
||||
Irp = IoBuildDeviceIoControlRequest(CtlCode,
|
||||
DeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferSize,
|
||||
OutputBuffer,
|
||||
(OutputBufferSize) ? *OutputBufferSize : 0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoBuildDeviceIoControlRequest failed\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (Override)
|
||||
{
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
|
||||
}
|
||||
|
||||
DPRINT("Calling IO Driver... with irp %p\n", Irp);
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
DPRINT("Waiting for IO Operation for %p\n", Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Operation pending\n");
|
||||
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
DPRINT("Getting IO Status... for %p\n", Irp);
|
||||
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
|
||||
DPRINT1("Media change detected!\n");
|
||||
|
||||
/* Find the device to verify and reset the thread field to empty value again. */
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
Status = IoVerifyVolume(DeviceToVerify,
|
||||
FALSE);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputBufferSize)
|
||||
{
|
||||
*OutputBufferSize = IoStatus.Information;
|
||||
}
|
||||
|
||||
DPRINT("Returning Status %x\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue