From 4f4bec88a513a3cfb2d039a0c52f969e650dcd29 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 20 Oct 2009 10:02:27 +0000 Subject: [PATCH] [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. svn path=/trunk/; revision=43641 --- .../filesystems/fastfat_new/blockdev.c | 447 ---------- .../filesystems/fastfat_new/direntry.c | 775 ------------------ .../drivers/filesystems/fastfat_new/fastfat.h | 69 +- .../filesystems/fastfat_new/fastfat.rbuild | 2 - reactos/drivers/filesystems/fastfat_new/fat.c | 388 +-------- .../filesystems/fastfat_new/fatstruc.h | 8 + .../drivers/filesystems/fastfat_new/fullfat.c | 110 +++ reactos/drivers/filesystems/fastfat_new/rw.c | 1 - 8 files changed, 151 insertions(+), 1649 deletions(-) delete mode 100644 reactos/drivers/filesystems/fastfat_new/blockdev.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/direntry.c diff --git a/reactos/drivers/filesystems/fastfat_new/blockdev.c b/reactos/drivers/filesystems/fastfat_new/blockdev.c deleted file mode 100644 index 8e1d0fbe8c0..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/blockdev.c +++ /dev/null @@ -1,447 +0,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 */ diff --git a/reactos/drivers/filesystems/fastfat_new/direntry.c b/reactos/drivers/filesystems/fastfat_new/direntry.c deleted file mode 100644 index d50d2682c48..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/direntry.c +++ /dev/null @@ -1,775 +0,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 */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index 2b843df45f6..7b5f250821c 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -66,21 +66,6 @@ FatReadStreamFile(PVCB Vcb, 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 */ NTSTATUS NTAPI @@ -215,6 +200,10 @@ FatWriteBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count 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,34 +238,17 @@ NTAPI 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 */ NTSTATUS NTAPI @@ -291,36 +263,7 @@ FatPerformDevIoCtrl(PDEVICE_OBJECT DeviceObject, 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, diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild b/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild index f29c915dc56..bd8f6c8fb67 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild @@ -8,13 +8,11 @@ ntoskrnl hal pseh - blockdev.c cleanup.c close.c create.c device.c dir.c - direntry.c ea.c fastfat.c fat.c diff --git a/reactos/drivers/filesystems/fastfat_new/fat.c b/reactos/drivers/filesystems/fastfat_new/fat.c index db6d517394d..e483e67455c 100644 --- a/reactos/drivers/filesystems/fastfat_new/fat.c +++ b/reactos/drivers/filesystems/fastfat_new/fat.c @@ -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 */ /* INCLUDES *****************************************************************/ @@ -12,147 +12,34 @@ #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) +BOOLEAN +NTAPI +FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb) { - 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; + return (FatValidBytesPerSector(Bpb->BytesPerSector) + && FatValidSectorsPerCluster(Bpb->SectorsPerCluster) + && Bpb->ReservedSectors > 0 + && Bpb->Fats > 0 + && (Bpb->Sectors > 0 || Bpb->LargeSectors > 0) + && (Bpb->SectorsPerFat > 0 + || (Bpb->LargeSectorsPerFat > 0 && Bpb->FsVersion == 0)) + && (Bpb->Media == 0xf0 + || Bpb->Media == 0xf8 + || Bpb->Media == 0xf9 + || Bpb->Media == 0xfb + || Bpb->Media == 0xfc + || Bpb->Media == 0xfd + || Bpb->Media == 0xfe + || Bpb->Media == 0xff) + && (Bpb->SectorsPerFat == 0 || Bpb->RootEntries > 0) + && (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled)); } /** @@ -176,231 +63,8 @@ FatPowerOfTwo( 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 -FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb) -{ - return (FatValidBytesPerSector(Bpb->BytesPerSector) - && FatValidSectorsPerCluster(Bpb->SectorsPerCluster) - && Bpb->ReservedSectors > 0 - && Bpb->Fats > 0 - && (Bpb->Sectors > 0 || Bpb->LargeSectors > 0) - && (Bpb->SectorsPerFat > 0 - || (Bpb->LargeSectorsPerFat > 0 && Bpb->FsVersion == 0)) - && (Bpb->Media == 0xf0 - || Bpb->Media == 0xf8 - || Bpb->Media == 0xf9 - || Bpb->Media == 0xfb - || Bpb->Media == 0xfc - || Bpb->Media == 0xfd - || Bpb->Media == 0xfe - || Bpb->Media == 0xff) - && (Bpb->SectorsPerFat == 0 || Bpb->RootEntries > 0) - && (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled)); -} - VOID +NTAPI FatiInitializeVcb(PVCB Vcb) { ULONG ClustersCapacity; @@ -420,17 +84,17 @@ FatiInitializeVcb(PVCB Vcb) 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 @@ FatiInitializeVcb(PVCB Vcb) } NTSTATUS +NTAPI FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, @@ -558,6 +223,7 @@ FatInitializeVcbCleanup: } VOID +NTAPI FatUninitializeVcb(IN PVCB Vcb) { LARGE_INTEGER ZeroSize; diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h index fbf6bdb3bd4..4f8d6845295 100644 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ b/reactos/drivers/filesystems/fastfat_new/fatstruc.h @@ -388,6 +388,14 @@ typedef enum _TYPE_OF_OPEN 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 diff --git a/reactos/drivers/filesystems/fastfat_new/fullfat.c b/reactos/drivers/filesystems/fastfat_new/fullfat.c index f140706808f..5ab95721689 100644 --- a/reactos/drivers/filesystems/fastfat_new/fullfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fullfat.c @@ -100,4 +100,114 @@ FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_E 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 */ diff --git a/reactos/drivers/filesystems/fastfat_new/rw.c b/reactos/drivers/filesystems/fastfat_new/rw.c index a6a2120148f..44eb9d07b18 100644 --- a/reactos/drivers/filesystems/fastfat_new/rw.c +++ b/reactos/drivers/filesystems/fastfat_new/rw.c @@ -4,7 +4,6 @@ * FILE: drivers/filesystems/fastfat/rw.c * PURPOSE: Read/write support * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - * Alexey Vlasov */ /* INCLUDES *****************************************************************/ -- 2.17.1