reactos/rosapps/ext2/rw.c

220 lines
5 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ntddk.h>
#include <string.h>
#define NDEBUG
#include <debug.h>
#include "ext2fs.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt,
PEXT2_FCB Fcb,
PVOID Buffer,
ULONG Offset)
{
ULONG block, i;
for (i=0; i<4; i++)
{
block = Ext2BlockMap(DeviceExt,
Fcb->i.inode,
Offset + i);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
Buffer + (i*BLOCKSIZE));
}
return(STATUS_SUCCESS);
}
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
LARGE_INTEGER OffsetL)
{
PVOID BaseAddress;
BOOLEAN Uptodate = FALSE;
PCACHE_SEGMENT CacheSeg;
ULONG Offset = (ULONG)OffsetL.u.LowPart;
PEXT2_FCB Fcb;
ULONG block, i, Delta;
DPRINT("Ext2ReadFile(DeviceExt %x, FileObject %x, Buffer %x, Length %d, \n"
"OffsetL %d)\n",DeviceExt,FileObject,Buffer,Length,(ULONG)OffsetL);
Fcb = (PEXT2_FCB)FileObject->FsContext;
Ext2LoadInode(DeviceExt,
Fcb->inode,
&Fcb->i);
if (Offset >= Fcb->i.inode->i_size)
{
DPRINT("Returning end of file\n");
return(STATUS_END_OF_FILE);
}
if ((Offset + Length) > Fcb->i.inode->i_size)
{
Length = Fcb->i.inode->i_size - Offset;
}
Ext2ReleaseInode(DeviceExt,
&Fcb->i);
if ((Offset % PAGE_SIZE) != 0)
{
Delta = min(PAGE_SIZE - (Offset % PAGE_SIZE),Length);
CcRequestCachePage(Fcb->Bcb,
Offset,
&BaseAddress,
&Uptodate,
&CacheSeg);
if (Uptodate == FALSE)
{
Ext2ReadPage(DeviceExt,
Fcb,
BaseAddress,
Offset / BLOCKSIZE);
}
memcpy(Buffer, BaseAddress + (Offset % PAGE_SIZE), Delta);
CcReleaseCachePage(Fcb->Bcb,
CacheSeg,
TRUE);
Length = Length - Delta;
Offset = Offset + Delta;
Buffer = Buffer + Delta;
}
CHECKPOINT;
for (i=0; i<(Length/PAGE_SIZE); i++)
{
CcRequestCachePage(Fcb->Bcb,
Offset,
&BaseAddress,
&Uptodate,
&CacheSeg);
if (Uptodate == FALSE)
{
Ext2ReadPage(DeviceExt,
Fcb,
BaseAddress,
(Offset / BLOCKSIZE));
}
memcpy(Buffer, BaseAddress, PAGE_SIZE);
CcReleaseCachePage(Fcb->Bcb,
CacheSeg,
TRUE);
Length = Length - PAGE_SIZE;
Offset = Offset + PAGE_SIZE;
Buffer = Buffer + PAGE_SIZE;
}
CHECKPOINT;
if ((Length % PAGE_SIZE) != 0)
{
CcRequestCachePage(Fcb->Bcb,
Offset,
&BaseAddress,
&Uptodate,
&CacheSeg);
if (Uptodate == FALSE)
{
Ext2ReadPage(DeviceExt,
Fcb,
BaseAddress,
(Offset / BLOCKSIZE));
}
DPRINT("Copying %x to %x Length %d\n",BaseAddress,Buffer,Length);
memcpy(Buffer,BaseAddress,Length);
CcReleaseCachePage(Fcb->Bcb,
CacheSeg,
TRUE);
}
CHECKPOINT;
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("Ext2Write(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS STDCALL
Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("Ext2FlushBuffers(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS STDCALL
Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("Ext2Shutdown(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS STDCALL
Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DbgPrint("Ext2Cleanup(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
DbgPrint("Ext2Cleanup() finished\n");
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS STDCALL
Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
ULONG Length;
PVOID Buffer;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT("Ext2Read(DeviceObject %x, FileObject %x, Irp %x)\n",
DeviceObject, FileObject, Irp);
Length = Stack->Parameters.Read.Length;
CHECKPOINT;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
CHECKPOINT;
CHECKPOINT;
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,
Stack->Parameters.Read.ByteOffset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}