Author: fireball
Date: Tue Oct 20 12:02:27 2009
New Revision: 43641
URL:
http://svn.reactos.org/svn/reactos?rev=43641&view=rev
Log:
[fastfat_new]
- Cleanup the source code from parts which aren't needed anymore (after switching to
FullFAT library usage). About 40kb of source code removed.
Removed:
trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c
trunk/reactos/drivers/filesystems/fastfat_new/direntry.c
Modified:
trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild
trunk/reactos/drivers/filesystems/fastfat_new/fat.c
trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c
trunk/reactos/drivers/filesystems/fastfat_new/rw.c
Removed: trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c (removed)
@@ -1,447 +1,0 @@
-/*
- * PROJECT: ReactOS FAT file system driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/filesystems/fastfat/blockdev.c
- * PURPOSE: Temporary sector reading support
- * PROGRAMMERS: Alexey Vlasov
- */
-
-/* INCLUDES *****************************************************************/
-
-#define NDEBUG
-#include "fastfat.h"
-
-/* FUNCTIONS ***************************************************************/
-//FIXME: There is a conflicting function FatPerformDevIoCtrl doing same thing!
-NTSTATUS
-FatDiskIoControl_(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG IoCtlCode,
- IN PVOID InputBuffer,
- IN ULONG InputBufferSize,
- IN OUT PVOID OutputBuffer,
- IN OUT PULONG OutputBufferSize OPTIONAL)
-{
- PIRP Irp;
- KEVENT Event;
- NTSTATUS Status;
- ULONG OutBufferSize;
- IO_STATUS_BLOCK IoStatus;
-
- /* Set out buffer size if it was supplied. */
- OutBufferSize = (ARGUMENT_PRESENT(OutputBufferSize)
- ? 0 : *OutputBufferSize);
-
- /* Initialize event if the operation will be pended. */
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- /* Build the Irp. */
- Irp = IoBuildDeviceIoControlRequest(IoCtlCode, DeviceObject,
- InputBuffer, InputBufferSize, OutputBuffer, OutBufferSize,
- FALSE, &Event, &IoStatus);
- if (Irp == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Send IRP to Disk Device */
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- Status = IoStatus.Status;
- }
-
- /* Return output buffer length if required. */
- if (ARGUMENT_PRESENT(OutputBufferSize))
- *OutputBufferSize = IoStatus.Information;
- return Status;
-}
-
-NTSTATUS
-FatLockUserBuffer (
- IN PFAT_IRP_CONTEXT IrpContext,
- IN LOCK_OPERATION Operation,
- IN ULONG BufferLength)
-/*
- * FUNCTION:
- *
- *
- * ARGUMENTS:
- * IrpContext = Pointer to FCB structure for the file.
- * Operation = Type of lock operation.
- * BufferLength = Buffer length to be locked.
- * RETURNS: Status Value.
- * NOTES:
- */
-{
- PMDL Mdl;
- PIRP Irp;
- NTSTATUS Status;
-
- Mdl = NULL;
- Irp = IrpContext->Irp;
- Status = STATUS_SUCCESS;
- if (Irp->MdlAddress == NULL)
- {
- NTSTATUS Status;
- Mdl = IoAllocateMdl(Irp->UserBuffer,
- BufferLength, FALSE, FALSE, Irp);
- if (Mdl == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
- _SEH2_TRY
- {
- MmProbeAndLockPages(Mdl,
- Irp->RequestorMode, Operation);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- IoFreeMdl( Mdl );
- Irp->MdlAddress = NULL;
- } _SEH2_END
- }
- return Status;
-}
-
-NTSTATUS
-FatIoSyncCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
-{
- PFAT_IO_CONTEXT IoContext;
-
- IoContext = (PFAT_IO_CONTEXT) Context;
-
- /* Check if this is an associated irp. */
- if (Irp != IoContext->Irp)
- {
- if (!NT_SUCCESS(Irp->IoStatus.Status))
- IoContext->Irp->IoStatus = Irp->IoStatus;
- IoFreeMdl(Irp->MdlAddress);
- IoFreeIrp(Irp);
- if (InterlockedDecrement(&IoContext->RunCount) != 0)
- return STATUS_MORE_PROCESSING_REQUIRED;
- /* This was the last run, update master irp. */
- if (NT_SUCCESS(IoContext->Irp->IoStatus.Status))
- IoContext->Irp->IoStatus.Information = IoContext->Length;
- }
-
- /* This is the last associated irp or a single irp IO. */
- if (NT_SUCCESS(IoContext->Irp->IoStatus.Status) &&
- !FlagOn(IoContext->Irp->Flags, IRP_PAGING_IO))
- {
- /* Maintain FileObject CurrentByteOffset */
- IoContext->FileObject->CurrentByteOffset.QuadPart =
- IoContext->Offset + IoContext->Irp->IoStatus.Information;
- }
-
- /* Signal about completion. */
- KeSetEvent(&IoContext->Wait.SyncEvent, 0, FALSE);
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-FatIoAsyncCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
-{
- PFAT_IO_CONTEXT IoContext;
-
- IoContext = (PFAT_IO_CONTEXT) Context;
-
- /* Check if this is an associated irp. */
- if (Irp != IoContext->Irp)
- {
- if (!NT_SUCCESS(Irp->IoStatus.Status))
- IoContext->Irp->IoStatus = Irp->IoStatus;
- IoFreeMdl(Irp->MdlAddress);
- IoFreeIrp(Irp);
- if (InterlockedDecrement(&IoContext->RunCount) != 0)
- return STATUS_MORE_PROCESSING_REQUIRED;
- /* This was the last run, update master irp. */
- if (NT_SUCCESS(IoContext->Irp->IoStatus.Status))
- IoContext->Irp->IoStatus.Information = IoContext->Length;
- }
-
-
- /* This is the last associated irp or a single irp IO. */
- if (NT_SUCCESS(IoContext->Irp->IoStatus.Status) &&
- !FlagOn(IoContext->Irp->Flags, IRP_PAGING_IO))
- {
- /* Maintain FileObject Flags */
- if (IoGetCurrentIrpStackLocation(IoContext->Irp)->MajorFunction
- == IRP_MJ_READ)
- {
- SetFlag(IoContext->FileObject->Flags, FO_FILE_FAST_IO_READ);
- }
- else
- {
- SetFlag(IoContext->FileObject->Flags, FO_FILE_MODIFIED);
- }
- }
- if (IoContext->Wait.Async.Resource != NULL)
- ExReleaseResourceForThreadLite(
- IoContext->Wait.Async.Resource,
- IoContext->Wait.Async.ResourceThreadId);
-
- if (IoContext->Wait.Async.PagingIoResource != NULL)
- ExReleaseResourceForThreadLite(
- IoContext->Wait.Async.PagingIoResource,
- IoContext->Wait.Async.ResourceThreadId);
-
- IoMarkIrpPending(Irp);
- ExFreePool(Context);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-FatPerformLboIo(
- IN PFAT_IRP_CONTEXT IrpContext,
- IN PLARGE_INTEGER Offset,
- IN SIZE_T Length)
-{
- BOOLEAN CanWait, ReadOperation;
- PIO_STACK_LOCATION IoStack;
-
- CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT);
- ReadOperation = (IrpContext->Stack->MajorFunction == IRP_MJ_READ);
-
- /* Allocate completion context */
- IrpContext->FatIoContext = FsRtlAllocatePoolWithTag(
- NonPagedPool, sizeof(FAT_IO_CONTEXT), (ULONG) 'xCoI');
-
- if (IrpContext->FatIoContext == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlZeroMemory(IrpContext->FatIoContext,
- sizeof(FAT_IO_CONTEXT));
-
- /* Initialize event if we are supposed to wait. */
- if (CanWait)
- {
- KeInitializeEvent(
- &IrpContext->FatIoContext->Wait.SyncEvent,
- NotificationEvent, FALSE);
- }
-
- /* Set the completion routine depending on wait semantics. */
- IoSetCompletionRoutine(IrpContext->Irp,
- (CanWait
- ? FatIoSyncCompletionRoutine
- : FatIoAsyncCompletionRoutine),
- IrpContext->FatIoContext, TRUE, TRUE, TRUE);
-
- /* Setup stack location. */
- IoStack = IoGetNextIrpStackLocation(IrpContext->Irp);
- IoStack->MajorFunction = IrpContext->MajorFunction;
- IoStack->Parameters.Read.Length = (ULONG) Length;
- IoStack->Parameters.Read.ByteOffset = *Offset;
- if (FlagOn(IrpContext->Flags, IRPCONTEXT_WRITETHROUGH))
- SetFlag(IoStack->Flags, SL_WRITE_THROUGH);
-
- IoCallDriver(
- IrpContext->Vcb->TargetDeviceObject,
- IrpContext->Irp);
- if (CanWait)
- {
- KeWaitForSingleObject(
- &IrpContext->FatIoContext->Wait.SyncEvent,
- Executive, KernelMode, FALSE, NULL);
- return IrpContext->Irp->IoStatus.Status;
- }
- SetFlag(IrpContext->Flags, IRPCONTEXT_STACK_IO_CONTEXT);
- return STATUS_PENDING;
-}
-
-
-
-NTSTATUS
-FatPerformVirtualNonCachedIo(
- IN PFAT_IRP_CONTEXT IrpContext,
- IN PFCB Fcb,
- IN PLARGE_INTEGER Offset,
- IN SIZE_T Length)
-{
- NTSTATUS Status;
- PIO_STACK_LOCATION IoStack;
- LONGLONG Vbo, Lbo, RunLength;
- ULONG RunCount, CleanupIndex, FirstIndex, BeyoundLastIndex;
- BOOLEAN CanWait, ReadOperation;
- PIRP* RunIrp;
- PMDL Mdl;
-
- ASSERT(IrpContext->FatIoContext == NULL);
-
-
- FirstIndex = CleanupIndex = 0;
- CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT);
- ReadOperation = (IrpContext->Stack->MajorFunction == IRP_MJ_READ);
- Status = FatLockUserBuffer(IrpContext,
- (ReadOperation ? IoWriteAccess : IoReadAccess),
- Length);
- if (!NT_SUCCESS(Status))
- goto FatIoPerformNonCachedCleanup;
- Vbo = Offset->QuadPart;
- RunLength = Length;
- _SEH2_TRY
- {
- BeyoundLastIndex = FatScanFat(Fcb, Vbo,
- &Lbo, &RunLength, &FirstIndex, CanWait);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- _SEH2_YIELD(goto FatIoPerformNonCachedCleanup;)
- }_SEH2_END
- RunCount = BeyoundLastIndex - FirstIndex;
- if (RunCount == 0)
- {
- Status = STATUS_END_OF_FILE;
- goto FatIoPerformNonCachedCleanup;
- }
- Length = sizeof(FAT_IO_CONTEXT);
- if (RunCount > 0x1)
- Length += RunCount * sizeof(PIRP);
- IrpContext->FatIoContext = FsRtlAllocatePoolWithTag(
- NonPagedPool, Length, (ULONG) 'xCoI');
- if (IrpContext->FatIoContext == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto FatIoPerformNonCachedCleanup;
- }
- RtlZeroMemory(IrpContext->FatIoContext, Length);
- if (CanWait)
- {
- KeInitializeEvent(
- &IrpContext->FatIoContext->Wait.SyncEvent,
- NotificationEvent, FALSE);
- }
- if (RunCount == 0x1)
- {
- IoSetCompletionRoutine(IrpContext->Irp,
- (CanWait ? FatIoSyncCompletionRoutine
- : FatIoAsyncCompletionRoutine),
- IrpContext->FatIoContext, TRUE, TRUE, TRUE);
- IoStack = IoGetNextIrpStackLocation(IrpContext->Irp);
- IoStack->MajorFunction = IrpContext->Stack->MajorFunction;
- IoStack->Parameters.Read.Length = (ULONG) RunLength;
- IoStack->Parameters.Read.ByteOffset.QuadPart = Lbo;
- IoStack->Flags = FlagOn(
- IrpContext->Stack->Flags,
- SL_WRITE_THROUGH);
- Status = IoCallDriver(
- IrpContext->Vcb->TargetDeviceObject,
- IrpContext->Irp);
- goto FatIoPerformNonCachedComplete;
- }
- /*
- * We already have the first run retrieved by FatiScanFat.
- */
- for (RunIrp = &IrpContext->FatIoContext->Irp,
- CleanupIndex = FirstIndex;
- CleanupIndex < BeyoundLastIndex;
- CleanupIndex ++, RunIrp ++)
- {
-#if DBG
- LONGLONG NextVbo = Vbo + RunLength;
- BOOLEAN RunExists;
-#endif
- /*
- * Allocate Irp for the run.
- */
- *RunIrp = IoMakeAssociatedIrp(IrpContext->Irp,
- (CCHAR)(IrpContext->Vcb->TargetDeviceObject->StackSize + 1));
- if (*RunIrp == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto FatIoPerformNonCachedCleanup;
- }
- CleanupIndex ++;
- /*
- * Build Mdl for the run range.
- */
- Mdl = IoAllocateMdl(
- Add2Ptr(IrpContext->Irp->UserBuffer, Vbo, PVOID),
- (ULONG) RunLength, FALSE, FALSE, *RunIrp);
- if (Mdl == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto FatIoPerformNonCachedCleanup;
- }
- IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Mdl,
- Add2Ptr(IrpContext->Irp->UserBuffer, Vbo, PVOID),
- (ULONG) RunLength);
- /*
- * Setup IRP for each run.
- */
- IoSetCompletionRoutine(IrpContext->Irp,
- (CanWait ? FatIoSyncCompletionRoutine
- : FatIoAsyncCompletionRoutine),
- IrpContext->FatIoContext, TRUE, TRUE, TRUE);
- IoStack = IoGetNextIrpStackLocation(*RunIrp);
- IoStack->MajorFunction = IrpContext->Stack->MajorFunction;
- IoStack->Parameters.Read.Length = (ULONG) RunLength;
- IoStack->Parameters.Read.ByteOffset.QuadPart = Lbo;
-
- /*
- * Propagate write-through to the associated IRPs
- */
- if (FlagOn(IrpContext->Flags, IRPCONTEXT_WRITETHROUGH))
- SetFlag(IoStack->Flags, SL_WRITE_THROUGH);
- /*
- * Prepare for next iteration:
- */
- #if DBG
- RunExists =
- #endif
- FsRtlGetNextLargeMcbEntry(&Fcb->Mcb, CleanupIndex, &Vbo, &Lbo,
&RunLength);
- ASSERT(RunExists);
- ASSERT(NextVbo == Vbo);
- }
- /*
- * Send all IRPs to the volume device, we don't need to check
- * status code because cleanup will be done
- * by the completion routine in any case.
- */
- for (RunIrp = &IrpContext->FatIoContext->Irp,
- CleanupIndex = FirstIndex;
- CleanupIndex < BeyoundLastIndex;
- CleanupIndex ++, RunIrp ++)
- {
- IoCallDriver(IrpContext->Vcb->TargetDeviceObject, *RunIrp);
- }
-
-FatIoPerformNonCachedComplete:
- if (CanWait)
- {
- KeWaitForSingleObject(
- &IrpContext->FatIoContext->Wait.SyncEvent,
- Executive, KernelMode, FALSE, NULL);
- return IrpContext->Irp->IoStatus.Status;
- }
- SetFlag(IrpContext->Flags, IRPCONTEXT_STACK_IO_CONTEXT);
- return STATUS_PENDING;
- /*
- * The following block of code implements unwind logic
- */
-FatIoPerformNonCachedCleanup:
- if (IrpContext->FatIoContext != NULL)
- {
- RunIrp = &IrpContext->FatIoContext->Irp;
- while (FirstIndex < CleanupIndex)
- {
- if ((*RunIrp)->MdlAddress != NULL)
- IoFreeMdl((*RunIrp)->MdlAddress);
- IoFreeIrp(*RunIrp);
- FirstIndex ++;
- RunIrp ++;
- }
- ExFreePool(IrpContext->FatIoContext);
- IrpContext->FatIoContext = NULL;
- }
- return Status;
-}
-
-/* EOF */
Removed: trunk/reactos/drivers/filesystems/fastfat_new/direntry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/direntry.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/direntry.c (removed)
@@ -1,775 +1,0 @@
-/*
- * PROJECT: ReactOS FAT file system driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/filesystems/fastfat/direntry.c
- * PURPOSE: Directory entries
- * PROGRAMMERS: Alexey Vlasov
- */
-
-/* INCLUDES *****************************************************************/
-
-#define NDEBUG
-#include "fastfat.h"
-
-/* PROTOTYPES ***************************************************************/
-
-typedef enum _FILE_TIME_INDEX
-{
- FileCreationTime = 0,
- FileLastAccessTime,
- FileLastWriteTime,
- FileChangeTime
-} FILE_TIME_INDEX;
-
-
-VOID
-Fat8dot3ToUnicodeString(OUT PUNICODE_STRING FileName,
- IN PUCHAR ShortName,
- IN UCHAR Flags);
-
-ULONG
-FatDirentToDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToIdFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToIdBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToNamesInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-ULONG
-FatDirentToObjectIdInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer);
-
-/* FUNCTIONS *****************************************************************/
-
-#define FatQueryFileName(xInfo, xDirent) \
-{ \
- UNICODE_STRING FileName; \
- if (Info->FileNameLength == 0) \
- { \
- FileName.Buffer = Info->FileName; \
- FileName.MaximumLength = 0x18; \
- Fat8dot3ToUnicodeString(&FileName, \
- (xDirent)->FileName, (xDirent)->Case); \
- Info->FileNameLength = FileName.Length; \
- } \
-}
-
-#define FatQueryBothFileName(xInfo, xDirent) \
-{ \
- UNICODE_STRING FileName; \
- FileName.MaximumLength = 0x18; \
- if (Info->FileNameLength == 0) \
- { \
- FileName.Buffer = Info->FileName; \
- Fat8dot3ToUnicodeString(&FileName, \
- (xDirent)->FileName, (xDirent)->Case); \
- Info->FileNameLength = FileName.Length; \
- Info->ShortNameLength = 0; \
- } \
- else \
- { \
- FileName.Buffer = Info->ShortName; \
- Fat8dot3ToUnicodeString(&FileName, \
- (xDirent)->FileName, (xDirent)->Case); \
- Info->ShortNameLength = (CCHAR) FileName.Length; \
- } \
-}
-
-FORCEINLINE
-UCHAR
-FatLfnChecksum(
- PUCHAR Buffer
-)
-{
- UCHAR Index, Chksum;
-
- for (Index = 0x1, Chksum = *Buffer;
- Index < RTL_FIELD_SIZE(DIR_ENTRY, FileName);
- Index ++)
- {
- Chksum = (((Chksum & 0x1) << 0x7) | (Chksum >> 0x1))
- + Buffer[Index];
- }
- return Chksum;
-}
-
-VOID
-FatFindDirent(IN OUT PFAT_FIND_DIRENT_CONTEXT Context,
- OUT PDIR_ENTRY* Dirent,
- OUT PUNICODE_STRING LongFileName OPTIONAL)
-{
- PDIR_ENTRY Entry, EndOfPage;
- UCHAR SeqNum = 0, Checksum = 0;
- PUNICODE_STRING FileName;
-
- /* Pin first page. */
- Entry = (PDIR_ENTRY) FatPinPage(&Context->Page, 0);
- EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY);
-
- /* Run dirents. */
- FileName = NULL;
- while (TRUE)
- {
- /* Check if we have entered the area of never used dirents */
- if (Entry->FileName[0] == FAT_DIRENT_NEVER_USED)
- ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND);
-
- /* Just ignore entries marked as deleted */
- if (Entry->FileName[0] == FAT_DIRENT_DELETED)
- goto FatFindDirentNext;
-
- /* Check if it's an lfn */
- if (Entry->Attributes == FAT_DIRENT_ATTR_LFN)
- {
- PLONG_FILE_NAME_ENTRY LfnEntry;
-
- FileName = LongFileName;
- LfnEntry = (PLONG_FILE_NAME_ENTRY) Entry;
-
- /* Run lfns and collect file name if required */
- do {
- PWSTR Lfn;
-
- /* Check if we just running lfn */
- if (FileName == NULL)
- goto FatFindDirentRunLfn;
-
- /* Check for cluster index to be zero. */
- if (LfnEntry->Reserved != 0)
- {
- FileName = NULL;
- goto FatFindDirentRunLfn;
- }
-
- /* Check if this is the last lfn entry. */
- if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST))
- {
- SeqNum = (LfnEntry->SeqNum & ~FAT_FN_DIR_ENTRY_LAST);
- Checksum = LfnEntry->Checksum;
-
- /* Check if we exceed max number of lfns */
- if (SeqNum > (FAT_FN_MAX_DIR_ENTIES + 1))
- {
- FileName = NULL;
- goto FatFindDirentRunLfn;
- }
-
- /* Setup maximal expected lfn length */
- FileName->Length = (SeqNum * FAT_LFN_NAME_LENGTH);
-
- /* Extend lfn buffer if needed */
- if (FileName->Length > FileName->MaximumLength)
- {
- Lfn = ExAllocatePoolWithTag(PagedPool,
- LongFileName->Length, TAG_VFAT);
- if (Lfn == NULL)
- ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
- if (FileName->Buffer != NULL)
- ExFreePool(FileName->Buffer);
- FileName->Buffer = Lfn;
- FileName->MaximumLength = FileName->Length;
- }
- }
- else if (!(LfnEntry->SeqNum == SeqNum
- && LfnEntry->Checksum == Checksum))
- {
- /* Wrong SeqNum or CheckSum. */
- FileName = NULL;
- goto FatFindDirentRunLfn;
- }
- /* Gather file name */
- Lfn = Add2Ptr(FileName->Buffer, (SeqNum * FAT_LFN_NAME_LENGTH)
- - sizeof(LfnEntry->NameC), PWSTR);
- RtlCopyMemory(Lfn, LfnEntry->NameC, sizeof(LfnEntry->NameC));
- Lfn -= (sizeof(LfnEntry->NameB) / sizeof(WCHAR));
- RtlCopyMemory(Lfn, LfnEntry->NameB, sizeof(LfnEntry->NameB));
- Lfn -= (sizeof(LfnEntry->NameA) / sizeof(WCHAR));
- RtlCopyMemory(Lfn, LfnEntry->NameA, sizeof(LfnEntry->NameA));
-
- /* If last lfn determine exact lfn length. */
- if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST))
- {
- PWSTR LfnEnd = Add2Ptr(FileName->Buffer,
- (FileName->Length - sizeof(WCHAR)), PWSTR);
-
- /* Trim trailing 0xffff's */
- while (LfnEnd > Lfn && *LfnEnd == 0xffff) --LfnEnd;
-
- /* Trim 0 terminator is the one is there. */
- if (*LfnEnd == 0x0) --LfnEnd;
-
- /* Set correct lfn size */
- FileName->Length = (USHORT)PtrOffset(FileName->Buffer,
LfnEnd);
- }
- /* Setup validation for the next iteration */
- SeqNum = LfnEntry->SeqNum - 0x1;
- Checksum = LfnEntry->Checksum;
-
-FatFindDirentRunLfn:
- /* Get next dirent */
- LfnEntry ++;
- if (LfnEntry > (PLONG_FILE_NAME_ENTRY) EndOfPage)
- {
- if (FatPinIsLastPage(&Context->Page))
- ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND);
- LfnEntry = (PLONG_FILE_NAME_ENTRY)
FatPinNextPage(&Context->Page);
- EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY);
- }
- }
- while (LfnEntry->Attributes == FAT_DIRENT_ATTR_LFN);
- Entry = (PDIR_ENTRY) LfnEntry;
- continue;
- }
-
- /* If we've got here then this is a normal dirent */
- if (FileName != NULL && FileName->Length > 0)
- {
- /* Check if we have a correct lfn collected. */
- if (FatLfnChecksum(Entry->FileName) != Checksum)
- {
- FileName = NULL;
- }
- else
- {
- /* See if we were looking for this dirent. */
- if (!Context->Valid8dot3Name &&
- FsRtlAreNamesEqual(FileName, Context->FileName, TRUE, NULL))
- {
- Fat8dot3ToUnicodeString(&Context->ShortName,
Entry->FileName, Entry->Case);
- *Dirent = Entry;
- return;
- }
- }
- }
-
- /* We surely have a short name, check if we were looking for that. */
- if (Context->Valid8dot3Name)
- {
- Fat8dot3ToUnicodeString(&Context->ShortName,
- Entry->FileName, Entry->Case);
- if (FsRtlAreNamesEqual(&Context->ShortName, Context->FileName,
TRUE, NULL))
- {
- if (ARGUMENT_PRESENT(LongFileName) && FileName == NULL)
- LongFileName->Length = 0;
- *Dirent = Entry;
- return;
- }
- }
- FileName = NULL;
-
-FatFindDirentNext:
- Entry ++;
- if (Entry > EndOfPage)
- {
- if (FatPinIsLastPage(&Context->Page))
- ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND);
- Entry = (PDIR_ENTRY) FatPinNextPage(&Context->Page);
- EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY);
- }
- }
- /* Should never get here! */
- ASSERT(TRUE);
-}
-
-VOID
-FatEnumerateDirents(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN SIZE_T Offset)
-{
- PUCHAR Entry, EndOfPage;
- PWSTR FileName;
- USHORT FileNameLength;
- USHORT FileNameMaximumLength;
- PVOID InfoEntry;
- UCHAR SeqNum = 0;
- UCHAR Checksum = 0;
-
- /* Pin first page. */
- Entry = (PUCHAR)FatPinPage(&Context->Page, Offset);
- EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR);
-
- /* Iterate dirents. */
- while (TRUE)
- {
- /* Check if we have entered the area of never used dirents */
- if (*Entry == FAT_DIRENT_NEVER_USED)
- ExRaiseStatus(STATUS_NO_MORE_FILES);
-
- /* Just ignore entries marked as deleted */
- if (*Entry == FAT_DIRENT_DELETED)
- goto FatEnumerateDirentsNext;
-
- /* Get info pointer. */
- InfoEntry = Add2Ptr(Context->Buffer, Context->Offset, PVOID);
-
- /* Check if info class has file name */
- if (Context->NameOffset == Context->LengthOffset)
- {
- FileName = NULL;
- FileNameMaximumLength = 0;
- }
- else
- {
- FileName = Add2Ptr(InfoEntry, Context->NameOffset, PWSTR);
- FileNameMaximumLength = (USHORT) (Context->Length
- - Context->Offset + Context->NameOffset);
- }
- FileNameLength = 0;
-
- /* Check if it's an lfn */
- while (Entry[0xb] == FAT_DIRENT_ATTR_LFN)
- {
- PWSTR Lfn;
- PLONG_FILE_NAME_ENTRY LfnEntry;
-
- /* Check if we just running lfn */
- if (FileNameMaximumLength == 0)
- goto FatEnumerateDirentsRunLfn;
-
- LfnEntry = (PLONG_FILE_NAME_ENTRY) Entry;
-
- /* Check for cluster index to be zero. */
- if (LfnEntry->Reserved != 0)
- {
- FileNameMaximumLength = 0;
- goto FatEnumerateDirentsRunLfn;
- }
-
- /* Check if this is the last lfn entry. */
- if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST))
- {
- SeqNum = (LfnEntry->SeqNum & ~FAT_FN_DIR_ENTRY_LAST);
- Checksum = LfnEntry->Checksum;
-
- /* Check if we exceed max number of lfns */
- if (SeqNum > (FAT_FN_MAX_DIR_ENTIES + 1))
- {
- FileNameMaximumLength = 0;
- goto FatEnumerateDirentsRunLfn;
- }
-
- /* Setup maximal expected lfn length */
- FileNameLength = SeqNum * FAT_LFN_NAME_LENGTH;
-
- /* Validate the maximal expected lfn length */
- if (FileNameLength > FileNameMaximumLength)
- goto FatEnumerateDirentsRunLfn;
- }
- else if (!(LfnEntry->SeqNum == SeqNum
- && LfnEntry->Checksum == Checksum))
- {
- /* Wrong SeqNum or CheckSum. */
- FileNameMaximumLength = 0;
- goto FatEnumerateDirentsRunLfn;
- }
- /* Gather file name */
- Lfn = Add2Ptr(FileName, (SeqNum * FAT_LFN_NAME_LENGTH)
- - sizeof(LfnEntry->NameC), PWSTR);
- RtlCopyMemory(Lfn, LfnEntry->NameC, sizeof(LfnEntry->NameC));
- Lfn -= (sizeof(LfnEntry->NameB) / sizeof(WCHAR));
- RtlCopyMemory(Lfn, LfnEntry->NameB, sizeof(LfnEntry->NameB));
- Lfn -= (sizeof(LfnEntry->NameA) / sizeof(WCHAR));
- RtlCopyMemory(Lfn, LfnEntry->NameA, sizeof(LfnEntry->NameA));
-
- /* If last lfn determine exact lfn length. */
- if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST))
- {
- PWSTR LfnEnd = Add2Ptr(FileName, FileNameLength
- - sizeof(WCHAR), PWSTR);
-
- /* Trim trailing 0xffff's */
- while (LfnEnd > Lfn && *LfnEnd == 0xffff) --LfnEnd;
-
- /* Trim 0 terminator is the one is there. */
- if (*LfnEnd == 0x0) --LfnEnd;
-
- /* Set correct lfn size */
- FileNameLength = (USHORT)PtrOffset(FileName, LfnEnd);
- }
- /* Setup vaidation for the next iteration */
- SeqNum = LfnEntry->SeqNum - 0x1;
- Checksum = LfnEntry->Checksum;
-FatEnumerateDirentsRunLfn:
- Entry = Add2Ptr(Entry, sizeof(DIR_ENTRY), PUCHAR);
- if (Entry > EndOfPage)
- {
- if (FatPinIsLastPage(&Context->Page))
- ExRaiseStatus(STATUS_NO_MORE_FILES);
- Entry = (PUCHAR) FatPinNextPage(&Context->Page);
- EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR);
- }
- }
-
- /* if lfn was found, validate and commit. */
- if (FileNameLength > 0 && FatLfnChecksum(Entry) == Checksum)
- {
- *Add2Ptr(InfoEntry, Context->LengthOffset, PULONG) = FileNameLength;
- }
- else
- {
- *Add2Ptr(InfoEntry, Context->LengthOffset, PULONG) = 0;
- }
- /* TODO: Implement Filtering using Context->FileName &
Context->CcbFlags. */
-
- /* Copy the entry values. */
- Context->Offset += Context->CopyDirent((PFAT_ENUM_DIR_CONTEXT)Context,
(PDIR_ENTRY) Entry, InfoEntry);
-
-FatEnumerateDirentsNext:
- /* Get next entry */
- Entry = Add2Ptr(Entry, sizeof(DIR_ENTRY), PUCHAR);
- if (Entry > EndOfPage)
- {
- if (FatPinIsLastPage(&Context->Page))
- ExRaiseStatus(STATUS_NO_MORE_FILES);
- Entry = (PUCHAR) FatPinNextPage(&Context->Page);
- EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR);
- }
- }
-}
-
-FORCEINLINE
-VOID
-FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime,
- IN PFAT_DATETIME FatDateTime,
- IN UCHAR TenMs OPTIONAL)
-{
- TIME_FIELDS TimeFields;
-
- /* Setup time fields */
- TimeFields.Year = FatDateTime->Date.Year + 1980;
- TimeFields.Month = FatDateTime->Date.Month;
- TimeFields.Day = FatDateTime->Date.Day;
- TimeFields.Hour = FatDateTime->Time.Hour;
- TimeFields.Minute = FatDateTime->Time.Minute;
- TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1);
-
- /* Adjust up to 10 milliseconds
- * if the parameter was supplied
- */
- if (ARGUMENT_PRESENT(TenMs))
- {
- TimeFields.Second += TenMs / 100;
- TimeFields.Milliseconds = (TenMs % 100) * 10;
- }
- else
- {
- TimeFields.Milliseconds = 0;
- }
-
- /* Fix seconds value that might get beyoud the bound */
- if (TimeFields.Second > 59) TimeFields.Second = 0;
-
- /* Perform ceonversion to system time if possible */
- if (RtlTimeFieldsToTime(&TimeFields, SystemTime))
- {
- /* Convert to system time */
- ExLocalTimeToSystemTime(SystemTime, SystemTime);
- }
- else
- {
- /* Set to default time if conversion failed */
- *SystemTime = FatGlobalData.DefaultFileTime;
- }
-}
-
-VOID
-FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
- IN PDIR_ENTRY Dirent)
-{
- /* Convert LastWriteTime */
- FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime],
- &Dirent->LastWriteDateTime,
- 0);
- /* All other time fileds are valid (according to MS)
- * only if Win31 compatability mode is set.
- */
- if (FatGlobalData.Win31FileSystem)
- {
- /* We can avoid calling conversion routine
- * if time in dirent is 0 or equals to already
- * known time (LastWriteTime).
- */
- if (Dirent->CreationDateTime.Value == 0)
- {
- /* Set it to default time */
- FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime;
- }
- else if (Dirent->CreationDateTime.Value
- == Dirent->LastWriteDateTime.Value)
- {
- /* Assign the already known time */
- FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime];
- /* Adjust milliseconds from extra dirent field */
- FileTimes[FileCreationTime].QuadPart
- += (ULONG) Dirent->CreationTimeTenMs * 100000;
- }
- else
- {
- /* Perform conversion */
- FatDateTimeToSystemTime(&FileTimes[FileCreationTime],
- &Dirent->CreationDateTime,
- Dirent->CreationTimeTenMs);
- }
- if (Dirent->LastAccessDate.Value == 0)
- {
- /* Set it to default time */
- FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime;
- }
- else if (Dirent->LastAccessDate.Value
- == Dirent->LastWriteDateTime.Date.Value)
- {
- /* Assign the already known time */
- FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime];
- }
- else
- {
- /* Perform conversion */
- FAT_DATETIME LastAccessDateTime;
-
- LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value;
- LastAccessDateTime.Time.Value = 0;
- FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime],
- &LastAccessDateTime,
- 0);
- }
- }
-}
-
-VOID
-Fat8dot3ToUnicodeString(OUT PUNICODE_STRING FileName,
- IN PUCHAR ShortName,
- IN UCHAR Flags)
-{
- PCHAR Name;
- UCHAR Index, Ext = 0;
- OEM_STRING Oem;
-
- Name = Add2Ptr(FileName->Buffer, 0x0c, PCHAR);
- RtlCopyMemory(Name, ShortName, 0x0b);
-
- /* Restore the name byte used to mark deleted entries */
- if (Name[0] == 0x05)
- Name[0] |= 0xe0;
-
- /* Locate the end of name part */
- for (Index = 0; Index < 0x08
- && Name[Index] != 0x20; Index++);
-
- /* Locate the end of extension part */
- if (Name[0x08] != 0x20)
- {
- Ext = 0x2;
- Name[Index++] = 0x2e;
- Name[Index++] = Name[0x08];
- if ((Name[Index] = Name[0x09]) != 0x20)
- {
- Index ++; Ext ++;
- }
- if ((Name[Index] = Name[0x0a]) != 0x20)
- {
- Index ++; Ext ++;
- }
- }
-
- /* Perform Oem to Unicode conversion. */
- Oem.Buffer = Name;
- Oem.Length = Index;
- Oem.MaximumLength = Index;
- RtlOemStringToUnicodeString(FileName, &Oem, FALSE);
- Index = FlagOn(Flags, FAT_CASE_LOWER_BASE|FAT_CASE_LOWER_EXT);
- if (Index > 0)
- {
- /* Downcase the whole name */
- if (Index == (FAT_CASE_LOWER_BASE|FAT_CASE_LOWER_EXT))
- {
- RtlUpcaseUnicodeString(FileName, FileName, FALSE);
- }
- else
- {
- if (Index == FAT_CASE_LOWER_EXT)
- {
- /* Set extension for downcase */
- Oem.Length = Ext * sizeof(WCHAR);
- Oem.Buffer = Add2Ptr(FileName->Buffer,
- FileName->Length - Oem.Length,
- PSTR);
- }
- else
- {
- /* Set base name for downcase */
- Oem.Buffer = (PSTR) FileName->Buffer;
- Oem.Length = FileName->Length - Ext * sizeof(WCHAR);
- }
- Oem.MaximumLength = Oem.Length;
- RtlUpcaseUnicodeString((PUNICODE_STRING)&Oem,
- (PUNICODE_STRING)&Oem,
- FALSE);
- }
- }
-}
-
-ULONG
-FatDirentToDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_DIRECTORY_INFORMATION Info;
- Info = (PFILE_DIRECTORY_INFORMATION) Buffer;
- Info->FileIndex = 0;
- /* Setup Attributes */
- Info->FileAttributes = Dirent->Attributes;
- /* Setup times */
- FatQueryFileTimes(&Info->CreationTime, Dirent);
- /* Setup sizes */
- Info->EndOfFile.QuadPart = Dirent->FileSize;
- Info->AllocationSize.QuadPart =
- (Context->BytesPerClusterMask + Dirent->FileSize)
- & ~(Context->BytesPerClusterMask);
- FatQueryFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_FULL_DIR_INFORMATION Info;
- Info = (PFILE_FULL_DIR_INFORMATION) Buffer;
- Info->FileIndex = 0;
- Info->EaSize = 0;
- /* Setup Attributes */
- Info->FileAttributes = Dirent->Attributes;
- /* Setup times */
- FatQueryFileTimes(&Info->CreationTime, Dirent);
- /* Setup sizes */
- Info->EndOfFile.QuadPart = Dirent->FileSize;
- Info->AllocationSize.QuadPart =
- (Context->BytesPerClusterMask + Dirent->FileSize)
- & ~(Context->BytesPerClusterMask);
- FatQueryFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToIdFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_ID_FULL_DIR_INFORMATION Info;
- Info = (PFILE_ID_FULL_DIR_INFORMATION) Buffer;
- Info->FileId.QuadPart = 0;
- Info->FileIndex = 0;
- Info->EaSize = 0;
- /* Setup Attributes */
- Info->FileAttributes = Dirent->Attributes;
- /* Setup times */
- FatQueryFileTimes(&Info->CreationTime, Dirent);
- /* Setup sizes */
- Info->EndOfFile.QuadPart = Dirent->FileSize;
- Info->AllocationSize.QuadPart =
- (Context->BytesPerClusterMask + Dirent->FileSize)
- & ~(Context->BytesPerClusterMask);
- FatQueryFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_BOTH_DIR_INFORMATION Info;
- Info = (PFILE_BOTH_DIR_INFORMATION) Buffer;
- Info->FileIndex = 0;
- Info->EaSize = 0;
- /* Setup Attributes */
- Info->FileAttributes = Dirent->Attributes;
- /* Setup times */
- FatQueryFileTimes(&Info->CreationTime, Dirent);
- /* Setup sizes */
- Info->EndOfFile.QuadPart = Dirent->FileSize;
- Info->AllocationSize.QuadPart =
- (Context->BytesPerClusterMask + Dirent->FileSize)
- & ~(Context->BytesPerClusterMask);
- FatQueryBothFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToIdBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_ID_BOTH_DIR_INFORMATION Info;
- Info = (PFILE_ID_BOTH_DIR_INFORMATION) Buffer;
- Info->FileId.QuadPart = 0;
- Info->FileIndex = 0;
- Info->EaSize = 0;
- /* Setup Attributes */
- Info->FileAttributes = Dirent->Attributes;
- /* Setup times */
- FatQueryFileTimes(&Info->CreationTime, Dirent);
- /* Setup sizes */
- Info->EndOfFile.QuadPart = Dirent->FileSize;
- Info->AllocationSize.QuadPart =
- (Context->BytesPerClusterMask + Dirent->FileSize)
- & ~(Context->BytesPerClusterMask);
- FatQueryBothFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToNamesInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_NAMES_INFORMATION Info;
- Info = (PFILE_NAMES_INFORMATION) Buffer;
- Info->FileIndex = 0;
- FatQueryFileName(Info, Dirent);
- Info->NextEntryOffset = sizeof(*Info);
- return Info->NextEntryOffset + Info->FileNameLength;
-}
-
-ULONG
-FatDirentToObjectIdInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN PDIR_ENTRY Dirent,
- IN PVOID Buffer)
-{
- PFILE_OBJECTID_INFORMATION Info;
- Info = (PFILE_OBJECTID_INFORMATION) Buffer;
- Info->FileReference = 0;
- ((PLONGLONG)Info->ObjectId)[0] = 0LL;
- ((PLONGLONG)Info->ObjectId)[1] = 0LL;
- return sizeof(*Info);
-}
-
-/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] Tue Oct 20
12:02:27 2009
@@ -65,21 +65,6 @@
ULONG ByteSize,
PBCB *Bcb,
PVOID *Buffer);
-
-/* ------------------------------------------------------ blockdev.c */
-NTSTATUS
-NTAPI
-FatPerformLboIo(
- IN PFAT_IRP_CONTEXT IrpContext,
- IN PLARGE_INTEGER Offset,
- IN SIZE_T Length);
-
-NTSTATUS
-FatPerformVirtualNonCachedIo(
- IN PFAT_IRP_CONTEXT IrpContext,
- IN PFCB Fcb,
- IN PLARGE_INTEGER Offset,
- IN SIZE_T Length);
/* ----------------------------------------------------------- dir.c */
@@ -215,6 +200,10 @@
FF_T_SINT32
FatReadBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void
*pParam);
+VOID NTAPI
+FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
+ IN PDIR_ENTRY Dirent);
+
/* --------------------------------------------------------- lock.c */
NTSTATUS NTAPI
@@ -249,33 +238,16 @@
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
/* ----------------------------------------------------------- fat.c */
-PVOID
-FatPinPage(
- PFAT_PAGE_CONTEXT Context,
- LONGLONG ByteOffset);
-
-PVOID
-FatPinNextPage(
- PFAT_PAGE_CONTEXT Context);
-
-NTSTATUS
+NTSTATUS NTAPI
FatInitializeVcb(
IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PDEVICE_OBJECT TargetDeviceObject,
IN PVPB Vpb);
-VOID
+VOID NTAPI
FatUninitializeVcb(
IN PVCB Vcb);
-
-ULONG
-FatScanFat(
- IN PFCB Fcb,
- IN LONGLONG Vbo, OUT PLONGLONG Lbo,
- IN OUT PLONGLONG Length,
- OUT PULONG Index,
- IN BOOLEAN CanWait);
/* ------------------------------------------------------ device.c */
@@ -291,36 +263,7 @@
ULONG OutputBufferSize,
BOOLEAN Override);
-/* ------------------------------------------------------ direntry.c */
-VOID
-FatFindDirent(IN OUT PFAT_FIND_DIRENT_CONTEXT Context,
- OUT PDIR_ENTRY* Dirent,
- OUT PUNICODE_STRING LongFileName OPTIONAL);
-
-VOID
-FatEnumerateDirents(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context,
- IN SIZE_T Offset);
-
-VOID
-FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
- IN PDIR_ENTRY Dirent);
-
/* ----------------------------------------------------------- fcb.c */
-PFCB
-FatLookupFcbByName(
- IN PFCB ParentFcb,
- IN PUNICODE_STRING Name);
-
-BOOLEAN
-FatLinkFcbNames(
- IN PFCB ParentFcb,
- IN PFCB Fcb);
-
-VOID
-FatUnlinkFcbNames(
- IN PFCB ParentFcb,
- IN PFCB Fcb);
-
PFCB NTAPI
FatCreateFcb(
IN PFAT_IRP_CONTEXT IrpContext,
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild [iso-8859-1] Tue Oct 20
12:02:27 2009
@@ -8,13 +8,11 @@
<library>ntoskrnl</library>
<library>hal</library>
<library>pseh</library>
- <file>blockdev.c</file>
<file>cleanup.c</file>
<file>close.c</file>
<file>create.c</file>
<file>device.c</file>
<file>dir.c</file>
- <file>direntry.c</file>
<file>ea.c</file>
<file>fastfat.c</file>
<file>fat.c</file>
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] Tue Oct 20 12:02:27
2009
@@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/filesystems/fastfat/fat.c
* PURPOSE: FAT support routines
- * PROGRAMMERS: Alexey Vlasov
+ * PROGRAMMERS: Aleksey Bragin <aleksey(a)reactos.org>
*/
/* INCLUDES *****************************************************************/
@@ -12,370 +12,12 @@
#include "fastfat.h"
/* PROTOTYPES ***************************************************************/
-typedef struct _FAT_SCAN_CONTEXT
-{
- PFILE_OBJECT FileObject;
- LARGE_INTEGER PageOffset;
- LONGLONG BeyondLastEntryOffset;
- PVOID PageBuffer;
- PBCB PageBcb;
-} FAT_SCAN_CONTEXT;
-
-#define FatEntryToDataOffset(xEntry, xVcb) \
- ((xVcb)->DataArea + (((LONGLONG) ((xEntry) - 0x02)) <<
(xVcb)->BytesPerClusterLog))
-
-#define FatDataOffsetToEntry(xOffset, xVcb) \
- ((ULONG) ((xOffset - (xVcb)->DataArea) >> (xVcb)->BytesPerClusterLog) +
0x02)
-
-ULONG
-FatScanFat32ForContinousRun(IN OUT PFAT_PAGE_CONTEXT Context,
- IN OUT PULONG Index,
- IN BOOLEAN CanWait);
BOOLEAN
NTAPI
FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb);
/* VARIABLES ****************************************************************/
-FAT_METHODS Fat12Methods = {
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-FAT_METHODS Fat16Methods = {
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-FAT_METHODS Fat32Methods = {
- FatScanFat32ForContinousRun,
- NULL,
- NULL,
- NULL
-};
-
-/* FUNCTIONS ****************************************************************/
-
-/**
- * Pins the page containing ByteOffset byte.
- *
- * @param Context
- * Keeps current BCB, Buffer pointer
- * and maintains current and next page offset.
- *
- * @param ByteOffset
- * Offset from the beginning of the data stream to be pinned.
- *
- * @return
- * Pointer to the buffer starting with the specified ByteOffset.
- */
-PVOID
-FatPinPage(
- PFAT_PAGE_CONTEXT Context,
- LONGLONG ByteOffset)
-{
- SIZE_T OffsetWithinPage;
-
- OffsetWithinPage = (SIZE_T) (ByteOffset & (PAGE_SIZE - 1));
- ByteOffset -= OffsetWithinPage;
- if (ByteOffset != Context->Offset.QuadPart)
- {
- Context->Offset.QuadPart = ByteOffset;
- if (Context->Bcb != NULL)
- {
- CcUnpinData(Context->Bcb);
- Context->Bcb = NULL;
- }
- if (!CcMapData(Context->FileObject,
- &Context->Offset,
- PAGE_SIZE,
- Context->CanWait,
- &Context->Bcb,
- &Context->Buffer))
- {
- Context->Offset.QuadPart = 0LL;
- ExRaiseStatus(STATUS_CANT_WAIT);
- }
- }
- Context->EndOfPage.QuadPart =
- Context->Offset.QuadPart + PAGE_SIZE;
- if (Context->EndOfPage.QuadPart
- > Context->EndOfData.QuadPart)
- {
- Context->ValidLength = (SIZE_T)
- (Context->EndOfData.QuadPart
- - Context->Offset.QuadPart);
- }
- else
- {
- Context->ValidLength = PAGE_SIZE;
- }
- return Add2Ptr(Context->Buffer, OffsetWithinPage, PVOID);
-}
-
-/**
- * Pins the next page of data stream.
- *
- * @param Context
- * Keeps current BCB, Buffer pointer
- * and maintains current and next page offset.
- *
- * @return
- * Pointer to the buffer starting with the beginning of the next page.
- */
-PVOID
-FatPinNextPage(
- PFAT_PAGE_CONTEXT Context)
-{
- ASSERT ((Context->Offset.QuadPart % PAGE_SIZE)
- != (Context->EndOfPage.QuadPart % PAGE_SIZE)
- && Context->Bcb != NULL);
-
- ASSERT (Context->ValidLength == PAGE_SIZE);
-
- Context->Offset = Context->EndOfPage;
- CcUnpinData(Context->Bcb);
- if (!CcMapData(Context->FileObject,
- &Context->Offset,
- PAGE_SIZE,
- Context->CanWait,
- &Context->Bcb,
- &Context->Buffer))
- {
- Context->Bcb = NULL;
- Context->Offset.QuadPart = 0LL;
- ExRaiseStatus(STATUS_CANT_WAIT);
- }
- Context->EndOfPage.QuadPart =
- Context->Offset.QuadPart + PAGE_SIZE;
- return Context->Buffer;
-}
-
-/**
- * Determines the index of the set bit.
- *
- * @param Number
- * Number having a single bit set.
- *
- * @return
- * Index of the set bit.
- */
-FORCEINLINE
-ULONG
-FatPowerOfTwo(
- ULONG Number)
-{
- ULONG Temp;
- Temp = Number
- - ((Number >> 1) & 033333333333)
- - ((Number >> 2) & 011111111111);
- return (((Temp + (Temp >> 3)) & 030707070707) % 63);
-}
-
-/**
- * Scans FAT32 for continous chain of clusters
- *
- * @param Context
- * Pointer to FAT_PAGE_CONTEXT.
- *
- * @param Index
- * Supplies the Index of the first cluster
- * and receves the last index after the last
- * cluster in the chain.
- *
- * @param CanWait
- * Indicates if the context allows blocking.
- *
- * @return
- * Value of the last claster terminated the scan.
- *
- * @note
- * Raises STATUS_CANT_WAIT race condition.
- */
-ULONG
-FatScanFat32ForContinousRun(IN OUT PFAT_PAGE_CONTEXT Context,
- IN OUT PULONG Index,
- IN BOOLEAN CanWait)
-{
- PULONG Entry, EndOfPage;
-
- Entry = FatPinPage(Context, ((LONGLONG) *Index) << 0x2);
- EndOfPage = FatPinEndOfPage(Context, PULONG);
- while (TRUE)
- {
- do
- {
- if ((*Entry & FAT_CLUSTER_LAST) != ++(*Index))
- return (*Entry & FAT_CLUSTER_LAST);
- } while (++Entry < EndOfPage);
- /* Check if this is the last available entry */
- if (FatPinIsLastPage(Context))
- break;
- Entry = (PULONG) FatPinNextPage(Context);
- EndOfPage = FatPinEndOfPage(Context, PULONG);
- }
- return (*Index - 1);
-}
-
-ULONG
-FatSetFat32ContinousRun(IN OUT PFAT_SCAN_CONTEXT Context,
- IN ULONG Index,
- IN ULONG Length,
- IN BOOLEAN CanWait)
-{
- ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
-}
-
-ULONG
-FatScanFat32ForValueRun(IN OUT PFAT_SCAN_CONTEXT Context,
- IN OUT PULONG Index,
- IN ULONG IndexValue,
- IN BOOLEAN CanWait)
-{
- ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
-}
-
-ULONG
-FatSetFat32ValueRun(IN OUT PFAT_SCAN_CONTEXT Context,
- IN ULONG Index,
- IN ULONG Length,
- IN ULONG IndexValue,
- IN BOOLEAN CanWait)
-{
- ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
-}
-
-/**
- * Queries file MCB for the specified region [Vbo, Vbo + Length],
- * returns the number of runs in the region as well as the first
- * run of the range itself.
- * If the specified region is not fully cached in MCB the routine
- * scans FAT for the file and fills the MCB until the file offset
- * (defined as Vbo + Length) is reached.
- *
- * @param Fcb
- * Pointer to FCB structure for the file.
- *
- * @param Vbo
- * Virtual Byte Offset in the file.
- *
- * @param Lbo
- * Receives the Value of Logical Byte offset corresponding
- * to supplied Vbo Value.
- *
- * @param Length
- * Supplies file range length to be examined and receives
- * the length of first run.
- *
- * @param OutIndex
- * Receives the index (in MCB cache) of first run.
- *
- * @return
- * Incremented index of the last run (+1).
- *
- * @note
- * Should be called by I/O routines to split the I/O operation
- * into sequential or parallel I/O operations.
- */
-ULONG
-FatScanFat(IN PFCB Fcb,
- IN LONGLONG Vbo,
- OUT PLONGLONG Lbo,
- IN OUT PLONGLONG Length,
- OUT PULONG Index,
- IN BOOLEAN CanWait)
-{
- LONGLONG CurrentLbo, CurrentVbo, BeyondLastVbo, CurrentLength;
- ULONG Entry, NextEntry, NumberOfEntries, CurrentIndex;
- FAT_PAGE_CONTEXT Context;
- PVCB Vcb;
-
- /* Some often used values */
- Vcb = Fcb->Vcb;
- CurrentIndex = 0;
- BeyondLastVbo = Vbo + *Length;
- CurrentLength = ((LONGLONG) Vcb->Clusters) << Vcb->BytesPerClusterLog;
- if (BeyondLastVbo > CurrentLength)
- BeyondLastVbo = CurrentLength;
- /* Try to locate first run */
- if (FsRtlLookupLargeMcbEntry(&Fcb->Mcb, Vbo, Lbo, Length, NULL, NULL, Index))
- {
- /* Check if we have a single mapped run */
- if (Vbo >= BeyondLastVbo)
- goto FatScanFcbFatExit;
- } else {
- *Length = 0L;
- }
- /* Get the first scan startup values */
- if (FsRtlLookupLastLargeMcbEntryAndIndex(
- &Fcb->Mcb, &CurrentVbo, &CurrentLbo, &CurrentIndex))
- {
- Entry = FatDataOffsetToEntry(CurrentLbo, Vcb);
- }
- else
- {
- /* Map is empty, set up initial values */
- Entry = Fcb->FirstCluster;
- if (Entry <= 0x2)
- ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
- if (Entry >= Vcb->Clusters)
- {
- if (Entry < FAT_CLUSTER_LAST)
- ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
- BeyondLastVbo = 0LL;
- }
- CurrentIndex = 0L;
- CurrentVbo = 0LL;
- }
- /* Initialize Context */
- RtlZeroMemory(&Context, sizeof(Context));
- Context.FileObject = Vcb->StreamFileObject;
- Context.EndOfData.QuadPart = Vcb->BeyondLastClusterInFat;
-
- while (CurrentVbo < BeyondLastVbo)
- {
- /* Locate Continous run starting with the current entry */
- NumberOfEntries = Entry;
- NextEntry = Vcb->Methods.ScanContinousRun(
- &Context, &NumberOfEntries, CanWait);
- NumberOfEntries -= Entry;
- /* Check value that terminated the for being valid for FAT */
- if (NextEntry <= 0x2)
- ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
- if (NextEntry >= Vcb->Clusters)
- {
- if (NextEntry < FAT_CLUSTER_LAST)
- ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
- break;
- }
- /* Add new run */
- CurrentLength = ((LONGLONG) NumberOfEntries)
- << Vcb->BytesPerClusterLog;
- FsRtlAddLargeMcbEntry(&Fcb->Mcb,
- CurrentVbo,
- FatEntryToDataOffset(Entry, Vcb),
- CurrentLength);
- /* Setup next iteration */
- Entry = NextEntry;
- CurrentVbo += CurrentLength;
- CurrentIndex ++;
- }
- if (*Length == 0LL && CurrentIndex > 0)
- {
- if (!FsRtlLookupLargeMcbEntry(&Fcb->Mcb,
- Vbo, Lbo, Length, NULL, NULL, Index))
- {
- *Index = 0L;
- *Lbo = 0LL;
- }
- }
-FatScanFcbFatExit:
- return CurrentIndex;
-}
BOOLEAN
NTAPI
@@ -400,7 +42,29 @@
&& (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled));
}
+/**
+ * Determines the index of the set bit.
+ *
+ * @param Number
+ * Number having a single bit set.
+ *
+ * @return
+ * Index of the set bit.
+ */
+FORCEINLINE
+ULONG
+FatPowerOfTwo(
+ ULONG Number)
+{
+ ULONG Temp;
+ Temp = Number
+ - ((Number >> 1) & 033333333333)
+ - ((Number >> 2) & 011111111111);
+ return (((Temp + (Temp >> 3)) & 030707070707) % 63);
+}
+
VOID
+NTAPI
FatiInitializeVcb(PVCB Vcb)
{
ULONG ClustersCapacity;
@@ -420,17 +84,17 @@
if (Vcb->BytesPerClusterLog < 4087)
{
Vcb->IndexDepth = 0x0c;
- Vcb->Methods = Fat12Methods;
+ //Vcb->Methods = Fat12Methods;
}
else
{
Vcb->IndexDepth = 0x10;
- Vcb->Methods = Fat16Methods;
+ //Vcb->Methods = Fat16Methods;
}
/* Large Sectors are used for FAT32 */
if (Vcb->Bpb.Sectors == 0) {
Vcb->IndexDepth = 0x20;
- Vcb->Methods = Fat32Methods;
+ //Vcb->Methods = Fat32Methods;
}
ClustersCapacity = (SectorsToBytes(Vcb, Vcb->Sectors) * 0x8 / Vcb->IndexDepth)
- 1;
if (Vcb->Clusters > ClustersCapacity)
@@ -445,6 +109,7 @@
}
NTSTATUS
+NTAPI
FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PDEVICE_OBJECT TargetDeviceObject,
@@ -558,6 +223,7 @@
}
VOID
+NTAPI
FatUninitializeVcb(IN PVCB Vcb)
{
LARGE_INTEGER ZeroSize;
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] Tue Oct 20
12:02:27 2009
@@ -388,6 +388,14 @@
EaFile
} TYPE_OF_OPEN;
+typedef enum _FILE_TIME_INDEX
+{
+ FileCreationTime = 0,
+ FileLastAccessTime,
+ FileLastWriteTime,
+ FileChangeTime
+} FILE_TIME_INDEX;
+
#define CCB_SEARCH_RETURN_SINGLE_ENTRY 0x01
#define CCB_SEARCH_PATTERN_LEGAL_8DOT3 0x02
#define CCB_SEARCH_PATTERN_HAS_WILD_CARD 0x04
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] Tue Oct 20
12:02:27 2009
@@ -100,4 +100,114 @@
return FF_Open(pIoman, AnsiName.Buffer, Mode, pError);
}
+FORCEINLINE
+VOID
+FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime,
+ IN PFAT_DATETIME FatDateTime,
+ IN UCHAR TenMs OPTIONAL)
+{
+ TIME_FIELDS TimeFields;
+
+ /* Setup time fields */
+ TimeFields.Year = FatDateTime->Date.Year + 1980;
+ TimeFields.Month = FatDateTime->Date.Month;
+ TimeFields.Day = FatDateTime->Date.Day;
+ TimeFields.Hour = FatDateTime->Time.Hour;
+ TimeFields.Minute = FatDateTime->Time.Minute;
+ TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1);
+
+ /* Adjust up to 10 milliseconds
+ * if the parameter was supplied
+ */
+ if (ARGUMENT_PRESENT(TenMs))
+ {
+ TimeFields.Second += TenMs / 100;
+ TimeFields.Milliseconds = (TenMs % 100) * 10;
+ }
+ else
+ {
+ TimeFields.Milliseconds = 0;
+ }
+
+ /* Fix seconds value that might get beyoud the bound */
+ if (TimeFields.Second > 59) TimeFields.Second = 0;
+
+ /* Perform ceonversion to system time if possible */
+ if (RtlTimeFieldsToTime(&TimeFields, SystemTime))
+ {
+ /* Convert to system time */
+ ExLocalTimeToSystemTime(SystemTime, SystemTime);
+ }
+ else
+ {
+ /* Set to default time if conversion failed */
+ *SystemTime = FatGlobalData.DefaultFileTime;
+ }
+}
+
+// TODO: Make it a helper around FullFAT library
+VOID
+NTAPI
+FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
+ IN PDIR_ENTRY Dirent)
+{
+ /* Convert LastWriteTime */
+ FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime],
+ &Dirent->LastWriteDateTime,
+ 0);
+ /* All other time fileds are valid (according to MS)
+ * only if Win31 compatability mode is set.
+ */
+ if (FatGlobalData.Win31FileSystem)
+ {
+ /* We can avoid calling conversion routine
+ * if time in dirent is 0 or equals to already
+ * known time (LastWriteTime).
+ */
+ if (Dirent->CreationDateTime.Value == 0)
+ {
+ /* Set it to default time */
+ FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime;
+ }
+ else if (Dirent->CreationDateTime.Value
+ == Dirent->LastWriteDateTime.Value)
+ {
+ /* Assign the already known time */
+ FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime];
+ /* Adjust milliseconds from extra dirent field */
+ FileTimes[FileCreationTime].QuadPart
+ += (ULONG) Dirent->CreationTimeTenMs * 100000;
+ }
+ else
+ {
+ /* Perform conversion */
+ FatDateTimeToSystemTime(&FileTimes[FileCreationTime],
+ &Dirent->CreationDateTime,
+ Dirent->CreationTimeTenMs);
+ }
+ if (Dirent->LastAccessDate.Value == 0)
+ {
+ /* Set it to default time */
+ FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime;
+ }
+ else if (Dirent->LastAccessDate.Value
+ == Dirent->LastWriteDateTime.Date.Value)
+ {
+ /* Assign the already known time */
+ FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime];
+ }
+ else
+ {
+ /* Perform conversion */
+ FAT_DATETIME LastAccessDateTime;
+
+ LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value;
+ LastAccessDateTime.Time.Value = 0;
+ FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime],
+ &LastAccessDateTime,
+ 0);
+ }
+ }
+}
+
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/rw.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] Tue Oct 20 12:02:27
2009
@@ -4,7 +4,6 @@
* FILE: drivers/filesystems/fastfat/rw.c
* PURPOSE: Read/write support
* PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
- * Alexey Vlasov
*/
/* INCLUDES *****************************************************************/