1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- /*++
- Copyright (c) 2012 Minoca Corp. All Rights Reserved
- Module Name:
- fatio.c
- Abstract:
- This module implements the underlying device support for the FAT library
- when running as a kernel-mode driver.
- Author:
- Evan Green 25-Sep-2012
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/driver.h>
- #include <minoca/lib/fat/fat.h>
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- /*++
- Structure Description:
- This structure stores information about a block device backing a FAT file
- system.
- Members:
- BlockDevice - Stores the block device parameters for the device.
- --*/
- typedef struct _FAT_DEVICE {
- BLOCK_DEVICE_PARAMETERS BlockDevice;
- } FAT_DEVICE, *PFAT_DEVICE;
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- PFAT_IO_BUFFER
- FatAllocateIoBuffer (
- PVOID DeviceToken,
- UINTN Size
- )
- /*++
- Routine Description:
- This routine allocates memory for device I/O use.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- Size - Supplies the size of the required allocation, in bytes.
- Return Value:
- Returns a pointer to the FAT I/O buffer, or NULL on failure.
- --*/
- {
- PIO_BUFFER IoBuffer;
- IoBuffer = MmAllocateUninitializedIoBuffer(Size, 0);
- return (PFAT_IO_BUFFER)IoBuffer;
- }
- PFAT_IO_BUFFER
- FatCreateIoBuffer (
- PVOID Buffer,
- UINTN Size
- )
- /*++
- Routine Description:
- This routine creates a FAT I/O buffer from the given buffer.
- Arguments:
- Buffer - Supplies a pointer to the memory buffer on which to base the FAT
- I/O buffer.
- Size - Supplies the size of the memory buffer, in bytes.
- Return Value:
- Returns an pointer to the FAT I/O buffer, or NULL on failure.
- --*/
- {
- PIO_BUFFER IoBuffer;
- KSTATUS Status;
- Status = MmCreateIoBuffer(Buffer,
- Size,
- IO_BUFFER_FLAG_KERNEL_MODE_DATA,
- &IoBuffer);
- if (!KSUCCESS(Status)) {
- return NULL;
- }
- return (PFAT_IO_BUFFER)IoBuffer;
- }
- VOID
- FatIoBufferUpdateOffset (
- PFAT_IO_BUFFER FatIoBuffer,
- UINTN OffsetUpdate,
- BOOL Decrement
- )
- /*++
- Routine Description:
- This routine increments the given FAT I/O buffer's current offset by the
- given amount.
- Arguments:
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
- OffsetUpdate - Supplies the number of bytes by which the offset will be
- updated.
- Decrement - Supplies a boolean indicating whether the update will be a
- decrement (TRUE) or an increment (FALSE).
- Return Value:
- None.
- --*/
- {
- if (Decrement == FALSE) {
- MmIoBufferIncrementOffset((PIO_BUFFER)FatIoBuffer, OffsetUpdate);
- } else {
- MmIoBufferDecrementOffset((PIO_BUFFER)FatIoBuffer, OffsetUpdate);
- }
- return;
- }
- VOID
- FatIoBufferSetOffset (
- PFAT_IO_BUFFER FatIoBuffer,
- UINTN Offset
- )
- /*++
- Routine Description:
- This routine sets the given FAT I/O buffer's current offset.
- Arguments:
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
- Offset - Supplies the new offset to set.
- Return Value:
- None.
- --*/
- {
- MmSetIoBufferCurrentOffset((PIO_BUFFER)FatIoBuffer, Offset);
- return;
- }
- KSTATUS
- FatZeroIoBuffer (
- PFAT_IO_BUFFER FatIoBuffer,
- UINTN Offset,
- UINTN ByteCount
- )
- /*++
- Routine Description:
- This routine zeros the contents of the FAT I/O buffer starting at the
- offset for the given number of bytes.
- Arguments:
- FatIoBuffer - Supplies a pointer to the FAT I/O buffer that is to be zeroed.
- Offset - Supplies the offset within the I/O buffer where the zeroing should
- begin.
- ByteCount - Supplies the number of bytes to zero.
- Return Value:
- Status code.
- --*/
- {
- return MmZeroIoBuffer((PIO_BUFFER)FatIoBuffer, Offset, ByteCount);
- }
- KSTATUS
- FatCopyIoBuffer (
- PFAT_IO_BUFFER Destination,
- UINTN DestinationOffset,
- PFAT_IO_BUFFER Source,
- UINTN SourceOffset,
- UINTN ByteCount
- )
- /*++
- Routine Description:
- This routine copies the contents of the source I/O buffer starting at the
- source offset to the destination I/O buffer starting at the destination
- offset. It assumes that the arguments are correct such that the copy can
- succeed.
- Arguments:
- Destination - Supplies a pointer to the destination I/O buffer that is to
- be copied into.
- DestinationOffset - Supplies the offset into the destination I/O buffer
- where the copy should begin.
- Source - Supplies a pointer to the source I/O buffer whose contents will be
- copied to the destination.
- SourceOffset - Supplies the offset into the source I/O buffer where the
- copy should begin.
- ByteCount - Supplies the size of the requested copy in bytes.
- Return Value:
- Status code.
- --*/
- {
- KSTATUS Status;
- Status = MmCopyIoBuffer((PIO_BUFFER)Destination,
- DestinationOffset,
- (PIO_BUFFER)Source,
- SourceOffset,
- ByteCount);
- return Status;
- }
- KSTATUS
- FatCopyIoBufferData (
- PFAT_IO_BUFFER FatIoBuffer,
- PVOID Buffer,
- UINTN Offset,
- UINTN Size,
- BOOL ToIoBuffer
- )
- /*++
- Routine Description:
- This routine copies from a buffer into the given I/O buffer or out of the
- given I/O buffer.
- Arguments:
- FatIoBuffer - Supplies a pointer to the FAT I/O buffer to copy in or out of.
- Buffer - Supplies a pointer to the regular linear buffer to copy to or from.
- Offset - Supplies an offset in bytes from the beginning of the I/O buffer
- to copy to or from.
- Size - Supplies the number of bytes to copy.
- ToIoBuffer - Supplies a boolean indicating whether data is copied into the
- I/O buffer (TRUE) or out of the I/O buffer (FALSE).
- Return Value:
- Status code.
- --*/
- {
- KSTATUS Status;
- Status = MmCopyIoBufferData((PIO_BUFFER)FatIoBuffer,
- Buffer,
- Offset,
- Size,
- ToIoBuffer);
- return Status;
- }
- PVOID
- FatMapIoBuffer (
- PFAT_IO_BUFFER FatIoBuffer
- )
- /*++
- Routine Description:
- This routine maps the given FAT I/O buffer and returns the base of the
- virtually contiguous mapping.
- Arguments:
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
- Return Value:
- Returns a pointer to the virtual address of the mapping on success, or
- NULL on failure.
- --*/
- {
- PIO_BUFFER IoBuffer;
- KSTATUS Status;
- IoBuffer = (PFAT_IO_BUFFER)FatIoBuffer;
- Status = MmMapIoBuffer(IoBuffer, FALSE, FALSE, TRUE);
- if (!KSUCCESS(Status)) {
- return NULL;
- }
- return IoBuffer->Fragment[0].VirtualAddress;
- }
- VOID
- FatFreeIoBuffer (
- PFAT_IO_BUFFER FatIoBuffer
- )
- /*++
- Routine Description:
- This routine frees a FAT I/O buffer.
- Arguments:
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
- Return Value:
- None.
- --*/
- {
- MmFreeIoBuffer((PIO_BUFFER)FatIoBuffer);
- return;
- }
- PVOID
- FatAllocatePagedMemory (
- PVOID DeviceToken,
- ULONG SizeInBytes
- )
- /*++
- Routine Description:
- This routine allocates paged memory for the FAT library.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- SizeInBytes - Supplies the number of bytes to allocate.
- Return Value:
- Returns a pointer to the allocated memory, or NULL on failure.
- --*/
- {
- return MmAllocatePagedPool(SizeInBytes, FAT_ALLOCATION_TAG);
- }
- PVOID
- FatAllocateNonPagedMemory (
- PVOID DeviceToken,
- ULONG SizeInBytes
- )
- /*++
- Routine Description:
- This routine allocates non-paged memory for the FAT library.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- SizeInBytes - Supplies the number of bytes to allocate.
- Return Value:
- Returns a pointer to the allocated memory, or NULL on failure.
- --*/
- {
- return MmAllocateNonPagedPool(SizeInBytes, FAT_ALLOCATION_TAG);
- }
- VOID
- FatFreePagedMemory (
- PVOID DeviceToken,
- PVOID Allocation
- )
- /*++
- Routine Description:
- This routine frees paged memory for the FAT library.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- Allocation - Supplies a pointer to the allocation to free.
- Return Value:
- None.
- --*/
- {
- MmFreePagedPool(Allocation);
- return;
- }
- VOID
- FatFreeNonPagedMemory (
- PVOID DeviceToken,
- PVOID Allocation
- )
- /*++
- Routine Description:
- This routine frees memory for the FAT library.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- Allocation - Supplies a pointer to the allocation to free.
- Return Value:
- None.
- --*/
- {
- MmFreeNonPagedPool(Allocation);
- return;
- }
- KSTATUS
- FatCreateLock (
- PVOID *Lock
- )
- /*++
- Routine Description:
- This routine creates a lock.
- Arguments:
- Lock - Supplies a pointer where an opaque pointer will be returned
- representing the lock.
- Return Value:
- STATUS_SUCCESS on success.
- STATUS_INSUFFICIENT_RESOURCES if the lock could not be allocated.
- --*/
- {
- PQUEUED_LOCK NewLock;
- NewLock = KeCreateQueuedLock();
- if (NewLock == NULL) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- *Lock = NewLock;
- return STATUS_SUCCESS;
- }
- VOID
- FatDestroyLock (
- PVOID Lock
- )
- /*++
- Routine Description:
- This routine destroys a created lock.
- Arguments:
- Lock - Supplies a the opaque pointer returned upon creation.
- Return Value:
- None.
- --*/
- {
- KeDestroyQueuedLock(Lock);
- return;
- }
- VOID
- FatAcquireLock (
- PVOID Lock
- )
- /*++
- Routine Description:
- This routine acquires a lock.
- Arguments:
- Lock - Supplies a the opaque pointer returned upon creation.
- Return Value:
- None.
- --*/
- {
- KeAcquireQueuedLock(Lock);
- return;
- }
- VOID
- FatReleaseLock (
- PVOID Lock
- )
- /*++
- Routine Description:
- This routine releases a lock.
- Arguments:
- Lock - Supplies a the opaque pointer returned upon creation.
- Return Value:
- None.
- --*/
- {
- KeReleaseQueuedLock(Lock);
- return;
- }
- KSTATUS
- FatOpenDevice (
- PBLOCK_DEVICE_PARAMETERS BlockParameters
- )
- /*++
- Routine Description:
- This routine opens the underlying device that the FAT file system reads
- and writes blocks to.
- Arguments:
- BlockParameters - Supplies the initial block device parameters for the
- device. These parameters may be modified by this call.
- Return Value:
- STATUS_SUCCESS on success.
- STATUS_INSUFFICIENT_RESOURCES if there were not enough resources to open
- the device.
- --*/
- {
- PFAT_DEVICE FatDevice;
- FatDevice = MmAllocateNonPagedPool(sizeof(FAT_DEVICE), FAT_ALLOCATION_TAG);
- if (FatDevice == NULL) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- FatDevice->BlockDevice = *BlockParameters;
- //
- // Overwrite the device token so this layer gets this pointer.
- //
- BlockParameters->DeviceToken = FatDevice;
- return STATUS_SUCCESS;
- }
- VOID
- FatCloseDevice (
- PVOID DeviceToken
- )
- /*++
- Routine Description:
- This routine closes the device backing the FAT file system.
- Arguments:
- DeviceToken - Supplies a pointer to the device token returned upon opening
- the underlying device.
- Return Value:
- None.
- --*/
- {
- MmFreeNonPagedPool(DeviceToken);
- return;
- }
- KSTATUS
- FatReadDevice (
- PVOID DeviceToken,
- ULONGLONG BlockAddress,
- UINTN BlockCount,
- ULONG Flags,
- PVOID Irp,
- PFAT_IO_BUFFER FatIoBuffer
- )
- /*++
- Routine Description:
- This routine reads data from the underlying disk.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- BlockAddress - Supplies the block index to read (for physical disks, this is
- the LBA).
- BlockCount - Supplies the number of blocks to read.
- Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
- definitions.
- Irp - Supplies an optional pointer to the IRP to pass to the read file
- function.
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer where the data from
- the disk will be returned.
- Return Value:
- Status code.
- --*/
- {
- ULONG BlockSize;
- UINTN BytesCompleted;
- PFAT_DEVICE FatDevice;
- PIO_BUFFER IoBuffer;
- UINTN SizeInBytes;
- KSTATUS Status;
- IoBuffer = (PIO_BUFFER)FatIoBuffer;
- FatDevice = (PFAT_DEVICE)DeviceToken;
- BlockSize = FatDevice->BlockDevice.BlockSize;
- SizeInBytes = BlockCount * BlockSize;
- ASSERT(IoBuffer != NULL);
- Status = IoReadAtOffset(FatDevice->BlockDevice.DeviceToken,
- IoBuffer,
- BlockAddress * BlockSize,
- SizeInBytes,
- Flags,
- WAIT_TIME_INDEFINITE,
- &BytesCompleted,
- Irp);
- if (!KSUCCESS(Status)) {
- goto ReadDeviceEnd;
- }
- if (BytesCompleted != SizeInBytes) {
- ASSERT(FALSE);
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto ReadDeviceEnd;
- }
- ReadDeviceEnd:
- return Status;
- }
- KSTATUS
- FatWriteDevice (
- PVOID DeviceToken,
- ULONGLONG BlockAddress,
- UINTN BlockCount,
- ULONG Flags,
- PVOID Irp,
- PFAT_IO_BUFFER FatIoBuffer
- )
- /*++
- Routine Description:
- This routine writes data to the underlying disk.
- Arguments:
- DeviceToken - Supplies an opaque token identifying the underlying device.
- BlockAddress - Supplies the block index to write to (for physical disks,
- this is the LBA).
- BlockCount - Supplies the number of blocks to write.
- Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
- definitions.
- Irp - Supplies an optional pointer to an IRP to use for the disk operation.
- FatIoBuffer - Supplies a pointer to a FAT I/O buffer containing the data to
- write.
- Return Value:
- Status code.
- --*/
- {
- ULONG BlockSize;
- UINTN BytesCompleted;
- PFAT_DEVICE FatDevice;
- KSTATUS Status;
- FatDevice = (PFAT_DEVICE)DeviceToken;
- BlockSize = FatDevice->BlockDevice.BlockSize;
- Status = IoWriteAtOffset(FatDevice->BlockDevice.DeviceToken,
- (PIO_BUFFER)FatIoBuffer,
- BlockAddress * BlockSize,
- BlockCount * BlockSize,
- Flags,
- WAIT_TIME_INDEFINITE,
- &BytesCompleted,
- Irp);
- if (!KSUCCESS(Status)) {
- goto WriteDeviceEnd;
- }
- if (BytesCompleted != (BlockCount * BlockSize)) {
- ASSERT(FALSE);
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto WriteDeviceEnd;
- }
- WriteDeviceEnd:
- return Status;
- }
- KSTATUS
- FatGetDeviceBlockInformation (
- PVOID DeviceToken,
- PFILE_BLOCK_INFORMATION BlockInformation
- )
- /*++
- Routine Description:
- This routine converts a file's block information into disk level block
- information by modifying the offsets of each contiguous run.
- Arguments:
- DeviceToken - Supplies an opaque token identify the underlying device.
- BlockInformation - Supplies a pointer to the block information to be
- updated.
- Return Value:
- Status code.
- --*/
- {
- PFAT_DEVICE FatDevice;
- KSTATUS Status;
- ASSERT(BlockInformation != NULL);
- FatDevice = (PFAT_DEVICE)DeviceToken;
- Status = IoGetFileBlockInformation(FatDevice->BlockDevice.DeviceToken,
- &BlockInformation);
- return Status;
- }
- ULONG
- FatGetIoCacheEntryDataSize (
- VOID
- )
- /*++
- Routine Description:
- This routine returns the size of data stored in each cache entry.
- Arguments:
- None.
- Return Value:
- Returns the size of the data stored in each cache entry, or 0 if there is
- no cache.
- --*/
- {
- return IoGetCacheEntryDataSize();
- }
- ULONG
- FatGetPageSize (
- VOID
- )
- /*++
- Routine Description:
- This routine returns the size of a physical memory page for the current FAT
- environment.
- Arguments:
- None.
- Return Value:
- Returns the size of a page in the current environment. Returns 0 if the
- size is not known.
- --*/
- {
- return MmPageSize();
- }
- VOID
- FatGetCurrentSystemTime (
- PSYSTEM_TIME SystemTime
- )
- /*++
- Routine Description:
- This routine returns the current system time.
- Arguments:
- SystemTime - Supplies a pointer where the current system time will be
- returned.
- Return Value:
- None.
- --*/
- {
- KeGetSystemTime(SystemTime);
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|