From 26dd1bcf1fa0efda1867cb94cdf527cb616d4f55 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Fri, 29 Sep 2017 10:21:33 +0000 Subject: [PATCH] [FASTFAT_NEW] [FULLFAT] Remove the FullFAT-based "fastfat_new" driver and the third-party FullFAT library itself. Our driver has not seen any development since 2010 and the current fastfat driver has long surpassed it. Even more important, FullFAT is licensed under a modified version of GPLv3 that forbids commercial usage. Shipping it as a ReactOS dependency would render the OS unusable for commercial scenarios. If anybody wants to resurrect the driver, you can always get it from the repository history. svn path=/trunk/; revision=75986 --- reactos/drivers/filesystems/CMakeLists.txt | 1 - .../filesystems/fastfat_new/CMakeLists.txt | 31 - .../drivers/filesystems/fastfat_new/cleanup.c | 443 --- .../drivers/filesystems/fastfat_new/close.c | 651 ---- .../drivers/filesystems/fastfat_new/create.c | 1322 --------- .../drivers/filesystems/fastfat_new/device.c | 76 - reactos/drivers/filesystems/fastfat_new/dir.c | 280 -- reactos/drivers/filesystems/fastfat_new/ea.c | 22 - .../drivers/filesystems/fastfat_new/fastfat.c | 562 ---- .../drivers/filesystems/fastfat_new/fastfat.h | 408 --- .../filesystems/fastfat_new/fastfat.rc | 5 - .../drivers/filesystems/fastfat_new/fastio.c | 288 -- reactos/drivers/filesystems/fastfat_new/fat.c | 266 -- reactos/drivers/filesystems/fastfat_new/fat.h | 289 -- .../filesystems/fastfat_new/fatstruc.h | 453 --- reactos/drivers/filesystems/fastfat_new/fcb.c | 1095 ------- .../drivers/filesystems/fastfat_new/finfo.c | 673 ----- .../drivers/filesystems/fastfat_new/flush.c | 25 - .../drivers/filesystems/fastfat_new/fsctl.c | 514 ---- .../drivers/filesystems/fastfat_new/fullfat.c | 213 -- .../drivers/filesystems/fastfat_new/lock.c | 126 - reactos/drivers/filesystems/fastfat_new/rw.c | 120 - .../filesystems/fastfat_new/shutdown.c | 25 - .../drivers/filesystems/fastfat_new/volume.c | 271 -- reactos/sdk/lib/3rdparty/CMakeLists.txt | 1 - .../sdk/lib/3rdparty/fullfat/CMakeLists.txt | 24 - reactos/sdk/lib/3rdparty/fullfat/ff_blk.c | 85 - reactos/sdk/lib/3rdparty/fullfat/ff_crc.c | 255 -- reactos/sdk/lib/3rdparty/fullfat/ff_dir.c | 2627 ----------------- reactos/sdk/lib/3rdparty/fullfat/ff_error.c | 111 - reactos/sdk/lib/3rdparty/fullfat/ff_fat.c | 844 ------ reactos/sdk/lib/3rdparty/fullfat/ff_file.c | 1767 ----------- reactos/sdk/lib/3rdparty/fullfat/ff_format.c | 132 - reactos/sdk/lib/3rdparty/fullfat/ff_hash.c | 119 - reactos/sdk/lib/3rdparty/fullfat/ff_ioman.c | 1100 ------- reactos/sdk/lib/3rdparty/fullfat/ff_memory.c | 102 - reactos/sdk/lib/3rdparty/fullfat/ff_safety.c | 175 -- reactos/sdk/lib/3rdparty/fullfat/ff_string.c | 456 --- reactos/sdk/lib/3rdparty/fullfat/ff_time.c | 72 - reactos/sdk/lib/3rdparty/fullfat/ff_unicode.c | 294 -- 40 files changed, 16323 deletions(-) delete mode 100644 reactos/drivers/filesystems/fastfat_new/CMakeLists.txt delete mode 100644 reactos/drivers/filesystems/fastfat_new/cleanup.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/close.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/create.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/device.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/dir.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/ea.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fastfat.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fastfat.h delete mode 100644 reactos/drivers/filesystems/fastfat_new/fastfat.rc delete mode 100644 reactos/drivers/filesystems/fastfat_new/fastio.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fat.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fat.h delete mode 100644 reactos/drivers/filesystems/fastfat_new/fatstruc.h delete mode 100644 reactos/drivers/filesystems/fastfat_new/fcb.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/finfo.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/flush.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fsctl.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/fullfat.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/lock.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/rw.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/shutdown.c delete mode 100644 reactos/drivers/filesystems/fastfat_new/volume.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/CMakeLists.txt delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_blk.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_crc.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_dir.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_error.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_fat.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_file.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_format.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_hash.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_ioman.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_memory.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_safety.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_string.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_time.c delete mode 100644 reactos/sdk/lib/3rdparty/fullfat/ff_unicode.c diff --git a/reactos/drivers/filesystems/CMakeLists.txt b/reactos/drivers/filesystems/CMakeLists.txt index 4cb3c5adf3a..7485d433b5a 100644 --- a/reactos/drivers/filesystems/CMakeLists.txt +++ b/reactos/drivers/filesystems/CMakeLists.txt @@ -3,7 +3,6 @@ add_subdirectory(btrfs) add_subdirectory(cdfs) add_subdirectory(ext2) add_subdirectory(fastfat) -#add_subdirectory(fastfat_new) add_subdirectory(ffs) add_subdirectory(fs_rec) add_subdirectory(msfs) diff --git a/reactos/drivers/filesystems/fastfat_new/CMakeLists.txt b/reactos/drivers/filesystems/fastfat_new/CMakeLists.txt deleted file mode 100644 index b16e8ef4c10..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ - -include_directories( - . - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/fullfat) - -list(APPEND SOURCE - cleanup.c - close.c - create.c - device.c - dir.c - ea.c - fastfat.c - fastio.c - fat.c - fcb.c - finfo.c - flush.c - fsctl.c - fullfat.c - lock.c - rw.c - shutdown.c - volume.c - fastfat.h) - -add_library(fastfat_new SHARED ${SOURCE} fastfat.rc) -set_module_type(fastfat_new kernelmodedriver) -target_link_libraries(fastfat_new ${PSEH_LIB} fullfat) -add_importlibs(fastfat_new ntoskrnl hal) -add_pch(fastfat_new fastfat.h SOURCE) diff --git a/reactos/drivers/filesystems/fastfat_new/cleanup.c b/reactos/drivers/filesystems/fastfat_new/cleanup.c deleted file mode 100644 index 3414c97a94a..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/cleanup.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/cleanup.c - * PURPOSE: Cleanup routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -/* Last handle to a file object is closed */ -NTSTATUS -NTAPI -FatiCleanup(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - PFILE_OBJECT FileObject; - TYPE_OF_OPEN TypeOfOpen; - PSHARE_ACCESS ShareAccess; - BOOLEAN SendUnlockNotification = FALSE; - PLARGE_INTEGER TruncateSize = NULL; - //LARGE_INTEGER LocalTruncateSize; - BOOLEAN AcquiredVcb = FALSE, AcquiredFcb = FALSE; - NTSTATUS Status; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - DPRINT("FatiCleanup\n"); - DPRINT("\tIrp = %p\n", Irp); - DPRINT("\t->FileObject = %p\n", IrpSp->FileObject); - - FileObject = IrpSp->FileObject; - TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - - if (TypeOfOpen == UnopenedFileObject) - { - DPRINT1("Unopened File Object\n"); - - FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); - return STATUS_SUCCESS; - } - - if (FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE )) - { - /* Just flush the file */ - - if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && - FlagOn(FileObject->Flags, FO_FILE_MODIFIED) && - !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) && - (TypeOfOpen == UserFileOpen)) - { - //Status = FatFlushFile(IrpContext, Fcb, Flush); - //if (!NT_SUCCESS(Status)) FatNormalizeAndRaiseStatus(IrpContext, Status); - UNIMPLEMENTED; - } - - FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); - return STATUS_SUCCESS; - } - - if (TypeOfOpen == UserFileOpen || - TypeOfOpen == UserDirectoryOpen) - { - ASSERT(Fcb != NULL); - - (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); - - AcquiredFcb = TRUE; - - /* Set FCB flags according to DELETE_ON_CLOSE */ - if (FlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE)) - { - ASSERT(FatNodeType(Fcb) != FAT_NTC_ROOT_DCB); - - SetFlag(Fcb->State, FCB_STATE_DELETE_ON_CLOSE); - - /* Issue a notification */ - if (TypeOfOpen == UserDirectoryOpen) - { - FsRtlNotifyFullChangeDirectory(Vcb->NotifySync, - &Vcb->NotifyList, - FileObject->FsContext, - NULL, - FALSE, - FALSE, - 0, - NULL, - NULL, - NULL); - } - } - - /* If file should be deleted, acquire locks */ - if ((Fcb->UncleanCount == 1) && - FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && - (Fcb->Condition != FcbBad) && - !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) - { - FatReleaseFcb(IrpContext, Fcb); - AcquiredFcb = FALSE; - - (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); - AcquiredVcb = TRUE; - - (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); - AcquiredFcb = TRUE; - } - } - - /* Acquire VCB lock if it was a volume open */ - if (TypeOfOpen == UserVolumeOpen) - { - (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); - AcquiredVcb = TRUE; - } - - /* Cleanup all notifications */ - if (TypeOfOpen == UserDirectoryOpen) - { - FsRtlNotifyCleanup(Vcb->NotifySync, - &Vcb->NotifyList, - Ccb); - } - - if (Fcb) - { - //TODO: FatVerifyFcb - } - - switch (TypeOfOpen) - { - case DirectoryFile: - case VirtualVolumeFile: - DPRINT1("Cleanup VirtualVolumeFile/DirectoryFile\n"); - ShareAccess = NULL; - break; - - case UserVolumeOpen: - DPRINT("Cleanup UserVolumeOpen\n"); - - if (FlagOn(Ccb->Flags, CCB_COMPLETE_DISMOUNT)) - { - FatCheckForDismount( IrpContext, Vcb, TRUE ); - } else if (FileObject->WriteAccess && - FlagOn(FileObject->Flags, FO_FILE_MODIFIED)) - { - UNIMPLEMENTED; - } - - /* Release the volume and send notification */ - if (FlagOn(Vcb->State, VCB_STATE_FLAG_LOCKED) && - (Vcb->FileObjectWithVcbLocked == FileObject)) - { - UNIMPLEMENTED; - SendUnlockNotification = TRUE; - } - - ShareAccess = &Vcb->ShareAccess; - break; - - case EaFile: - DPRINT1("Cleanup EaFileObject\n"); - ShareAccess = NULL; - break; - - case UserDirectoryOpen: - DPRINT("Cleanup UserDirectoryOpen\n"); - - ShareAccess = &Fcb->ShareAccess; - - /* Should it be a delayed close? */ - if ((Fcb->UncleanCount == 1) && - (Fcb->OpenCount == 1) && - (Fcb->Dcb.DirectoryFileOpenCount == 0) && - !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && - Fcb->Condition == FcbGood) - { - /* Yes, a delayed one */ - SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); - } - - if (VcbGood == Vcb->Condition) - { - //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); - //TODO: Actually update dirent - } - - if ((Fcb->UncleanCount == 1) && - (FatNodeType(Fcb) == FAT_NTC_DCB) && - (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) && - (Fcb->Condition != FcbBad) && - !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) - { - UNIMPLEMENTED; - } - - /* Decrement unclean counter */ - ASSERT(Fcb->UncleanCount != 0); - Fcb->UncleanCount--; - break; - - case UserFileOpen: - DPRINT("Cleanup UserFileOpen\n"); - - ShareAccess = &Fcb->ShareAccess; - - /* Should it be a delayed close? */ - if ((FileObject->SectionObjectPointer->DataSectionObject == NULL) && - (FileObject->SectionObjectPointer->ImageSectionObject == NULL) && - (Fcb->UncleanCount == 1) && - (Fcb->OpenCount == 1) && - !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && - Fcb->Condition == FcbGood) - { - /* Yes, a delayed one */ - //SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); - DPRINT1("Setting a delay on close for some reason for FCB %p, FF handle %p, file name '%wZ'\n", Fcb, Fcb->FatHandle, &Fcb->FullFileName); - } - - /* Unlock all file locks */ - FsRtlFastUnlockAll(&Fcb->Fcb.Lock, - FileObject, - IoGetRequestorProcess(Irp), - NULL); - - if (Vcb->Condition == VcbGood) - { - if (Fcb->Condition != FcbBad) - { - //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); - // TODO: Update on-disk structures - } - - if (Fcb->UncleanCount == 1 && - Fcb->Condition != FcbBad) - { - //DELETE_CONTEXT DeleteContext; - - /* Should this file be deleted on close? */ - if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && - !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) - { - UNIMPLEMENTED; - } - else - { - if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) && - (Fcb->Header.ValidDataLength.LowPart < Fcb->Header.FileSize.LowPart)) - { -#if 0 - ULONG ValidDataLength; - - ValidDataLength = Fcb->Header.ValidDataLength.LowPart; - - if (ValidDataLength < Fcb->ValidDataToDisk) { - ValidDataLength = Fcb->ValidDataToDisk; - } - - if (ValidDataLength < Fcb->Header.FileSize.LowPart) - { - FatZeroData( IrpContext, - Vcb, - FileObject, - ValidDataLength, - Fcb->Header.FileSize.LowPart - - ValidDataLength ); - - Fcb->ValidDataToDisk = - Fcb->Header.ValidDataLength.LowPart = - Fcb->Header.FileSize.LowPart; - - if (CcIsFileCached(FileObject)) - { - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); - } - } -#endif - DPRINT1("Zeroing out data is not implemented\n"); - } - } - - /* Should the file be truncated on close? */ - if (FlagOn(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE)) - { - if (Vcb->Condition == VcbGood) - { - // TODO: Actually truncate the file allocation - UNIMPLEMENTED; - } - - /* Remove truncation flag */ - Fcb->State &= ~FCB_STATE_TRUNCATE_ON_CLOSE; - } - - /* Check again if it should be deleted */ - if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && - Fcb->Header.AllocationSize.LowPart == 0) - { - FatNotifyReportChange(IrpContext, - Vcb, - Fcb, - FILE_NOTIFY_CHANGE_FILE_NAME, - FILE_ACTION_REMOVED); - } - - /* Remove the entry from the splay table if the file was deleted */ - if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) - { - FatRemoveNames(IrpContext, Fcb); - } - } - } - - ASSERT(Fcb->UncleanCount != 0); - Fcb->UncleanCount--; - if (!FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) - { - ASSERT(Fcb->NonCachedUncleanCount != 0); - Fcb->NonCachedUncleanCount--; - } - - if (FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) && - (Fcb->NonCachedUncleanCount != 0) && - (Fcb->NonCachedUncleanCount == Fcb->UncleanCount) && - (Fcb->SectionObjectPointers.DataSectionObject != NULL)) - { - CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); - - /* Acquire and release PagingIo to get in sync with lazy writer */ - ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); - ExReleaseResourceLite(Fcb->Header.PagingIoResource); - - CcPurgeCacheSection(&Fcb->SectionObjectPointers, - NULL, - 0, - FALSE); - } - - if (Fcb->Condition == FcbBad) - { - //TruncateSize = &FatLargeZero; - UNIMPLEMENTED; - } - - /* Cleanup the cache map */ - CcUninitializeCacheMap(FileObject, TruncateSize, NULL); - break; - - default: - KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0); - } - - /* Cleanup the share access */ - - if (ShareAccess) - { - DPRINT("Cleaning up the share access\n"); - IoRemoveShareAccess(FileObject, ShareAccess); - } - - if (TypeOfOpen == UserFileOpen) - { - /* Update oplocks */ - FsRtlCheckOplock(&Fcb->Fcb.Oplock, - Irp, - IrpContext, - NULL, - NULL); - - Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb); - } - - /* Set the FO_CLEANUP_COMPLETE flag */ - SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); - - Status = STATUS_SUCCESS; - - // TODO: Unpin repinned BCBs - //FatUnpinRepinnedBcbs(IrpContext); - - /* Flush the volume if necessary */ - if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && - !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) - { - UNIMPLEMENTED; - } - - /* Cleanup */ - if (AcquiredFcb) FatReleaseFcb(IrpContext, Fcb); - if (AcquiredVcb) FatReleaseVcb(IrpContext, Vcb); - - /* Send volume notification */ - if (SendUnlockNotification) - FsRtlNotifyVolumeEvent(FileObject, FSRTL_VOLUME_UNLOCK); - - return Status; -} - -NTSTATUS -NTAPI -FatCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PFAT_IRP_CONTEXT IrpContext; - NTSTATUS Status; - - DPRINT("FatCleanup(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); - - /* FatCleanup works only with a volume device object */ - if (DeviceObject == FatGlobalData.DiskDeviceObject) - { - /* Complete the request and return success */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - - IoCompleteRequest(Irp, IO_DISK_INCREMENT); - - return STATUS_SUCCESS; - } - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, TRUE); - - /* Call internal function */ - Status = FatiCleanup(IrpContext, Irp); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/close.c b/reactos/drivers/filesystems/fastfat_new/close.c deleted file mode 100644 index 69ccf3c8c43..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/close.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/close.c - * PURPOSE: Closing routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -VOID NTAPI -FatQueueClose(IN PCLOSE_CONTEXT CloseContext, - IN BOOLEAN DelayClose); - -PCLOSE_CONTEXT NTAPI -FatRemoveClose(PVCB Vcb OPTIONAL, - PVCB LastVcbHint OPTIONAL); - -const ULONG FatMaxDelayedCloseCount = 16; - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatiCommonClose(IN PVCB Vcb, - IN PFCB Fcb, - IN PCCB Ccb, - IN TYPE_OF_OPEN TypeOfOpen, - IN BOOLEAN Wait, - OUT PBOOLEAN VcbDeleted) -{ - NTSTATUS Status; - PFCB ParentDcb; - BOOLEAN RecursiveClose, VcbDeletedLv = FALSE; - FAT_IRP_CONTEXT IrpContext; - - if (VcbDeleted) *VcbDeleted = FALSE; - - if (TypeOfOpen == UnopenedFileObject) - { - DPRINT1("Closing unopened file object\n"); - Status = STATUS_SUCCESS; - return Status; - } - - RtlZeroMemory(&IrpContext, sizeof(FAT_IRP_CONTEXT)); - - IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT; - IrpContext.NodeByteSize = sizeof(IrpContext); - IrpContext.MajorFunction = IRP_MJ_CLOSE; - - if (Wait) SetFlag(IrpContext.Flags, IRPCONTEXT_CANWAIT); - - if (!ExAcquireResourceExclusiveLite(&Vcb->Resource, Wait)) return STATUS_PENDING; - - if (Vcb->State & VCB_STATE_FLAG_CLOSE_IN_PROGRESS) - { - RecursiveClose = TRUE; - } - else - { - SetFlag(Vcb->State, VCB_STATE_FLAG_CLOSE_IN_PROGRESS); - RecursiveClose = FALSE; - - Vcb->OpenFileCount++; - } - - /* Update on-disk structures */ - switch (TypeOfOpen) - { - case VirtualVolumeFile: - DPRINT1("Close VirtualVolumeFile\n"); - - InterlockedDecrement((PLONG)&(Vcb->InternalOpenCount)); - InterlockedDecrement((PLONG)&(Vcb->ResidualOpenCount)); - - Status = STATUS_SUCCESS; - goto close_done; - break; - - case UserVolumeOpen: - DPRINT1("Close UserVolumeOpen\n"); - - Vcb->DirectAccessOpenCount--; - Vcb->OpenFileCount--; - if (FlagOn(Ccb->Flags, CCB_READ_ONLY)) Vcb->ReadOnlyCount--; - - FatDeleteCcb(&IrpContext, Ccb); - - Status = STATUS_SUCCESS; - goto close_done; - break; - - case EaFile: - UNIMPLEMENTED; - break; - - case DirectoryFile: - DPRINT1("Close DirectoryFile\n"); - - InterlockedDecrement((PLONG)&(Fcb->Dcb.DirectoryFileOpenCount)); - InterlockedDecrement((PLONG)&(Vcb->InternalOpenCount)); - - if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB) - { - InterlockedDecrement((PLONG)&(Vcb->ResidualOpenCount)); - } - - if (RecursiveClose) - { - Status = STATUS_SUCCESS; - goto close_done; - } - else - { - break; - } - - case UserDirectoryOpen: - case UserFileOpen: - DPRINT("Close UserFileOpen/UserDirectoryOpen\n"); - - if ((FatNodeType(Fcb) == FAT_NTC_DCB) && - IsListEmpty(&Fcb->Dcb.ParentDcbList) && - (Fcb->OpenCount == 1) && - (Fcb->Dcb.DirectoryFile != NULL)) - { - PFILE_OBJECT DirectoryFileObject = Fcb->Dcb.DirectoryFile; - - DPRINT1("Uninitialize the stream file object\n"); - - CcUninitializeCacheMap(DirectoryFileObject, NULL, NULL); - - Fcb->Dcb.DirectoryFile = NULL; - ObDereferenceObject(DirectoryFileObject); - } - - Fcb->OpenCount--; - Vcb->OpenFileCount--; - if (FlagOn(Ccb->Flags, CCB_READ_ONLY)) Vcb->ReadOnlyCount --; - - FatDeleteCcb(&IrpContext, Ccb); - break; - - default: - KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0); - } - - /* Update in-memory structures */ - if (((FatNodeType(Fcb) == FAT_NTC_FCB) && - (Fcb->OpenCount == 0)) - || - ((FatNodeType(Fcb) == FAT_NTC_DCB) && - (IsListEmpty(&Fcb->Dcb.ParentDcbList)) && - (Fcb->OpenCount == 0) && - (Fcb->Dcb.DirectoryFileOpenCount == 0))) - { - ParentDcb = Fcb->ParentFcb; - - SetFlag(Vcb->State, VCB_STATE_FLAG_DELETED_FCB); - - FatDeleteFcb(&IrpContext, Fcb); - - while ((FatNodeType(ParentDcb) == FAT_NTC_DCB) && - IsListEmpty(&ParentDcb->Dcb.ParentDcbList) && - (ParentDcb->OpenCount == 0) && - (ParentDcb->Dcb.DirectoryFile != NULL)) - { - PFILE_OBJECT DirectoryFileObject; - - DirectoryFileObject = ParentDcb->Dcb.DirectoryFile; - - DPRINT1("Uninitialize parent Stream Cache Map\n"); - - CcUninitializeCacheMap(DirectoryFileObject, NULL, NULL); - - ParentDcb->Dcb.DirectoryFile = NULL; - - ObDereferenceObject(DirectoryFileObject); - - if (ParentDcb->Dcb.DirectoryFileOpenCount == 0) - { - PFCB CurrentDcb; - - CurrentDcb = ParentDcb; - ParentDcb = CurrentDcb->ParentFcb; - - SetFlag(Vcb->State, VCB_STATE_FLAG_DELETED_FCB); - - FatDeleteFcb(&IrpContext, CurrentDcb); - } - else - { - break; - } - } - } - - Status = STATUS_SUCCESS; - -close_done: - /* Closing is done, check if VCB could be closed too */ - if (!RecursiveClose) - { - /* One open left - yes, VCB can go away */ - if (Vcb->OpenFileCount == 1 && - !FlagOn(Vcb->State, VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS) - && VcbDeleted) - { - FatReleaseVcb(&IrpContext, Vcb ); - - SetFlag(IrpContext.Flags, IRPCONTEXT_CANWAIT); - - FatAcquireExclusiveGlobal(&IrpContext); - - FatAcquireExclusiveVcb(&IrpContext, Vcb); - - Vcb->OpenFileCount--; - - VcbDeletedLv = FatCheckForDismount(&IrpContext, Vcb, FALSE); - - FatReleaseGlobal(&IrpContext); - - if (VcbDeleted) *VcbDeleted = VcbDeletedLv; - } - else - { - /* Remove extra referenec */ - Vcb->OpenFileCount --; - } - - /* Clear recursion flag if necessary */ - if (!VcbDeletedLv) - { - ClearFlag(Vcb->State, VCB_STATE_FLAG_CLOSE_IN_PROGRESS); - } - } - - /* Release VCB if it wasn't deleted */ - if (!VcbDeletedLv) - FatReleaseVcb(&IrpContext, Vcb); - - return Status; -} - -NTSTATUS -NTAPI -FatiClose(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - TYPE_OF_OPEN TypeOfOpen; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - BOOLEAN TopLevel, Wait, VcbDeleted = FALSE, DelayedClose = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - PCLOSE_CONTEXT CloseContext = NULL; - - TopLevel = FatIsTopLevelIrp(Irp); - - /* Get current IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Decode incoming file object */ - TypeOfOpen = FatDecodeFileObject(IrpSp->FileObject, &Vcb, &Fcb, &Ccb); - - /* Set CCB read only flag */ - if (Ccb && IsFileObjectReadOnly(IrpSp->FileObject)) - SetFlag(Ccb->Flags, CCB_READ_ONLY); - - /* It's possible to wait only if we are top level or not a system process */ - Wait = TopLevel && (PsGetCurrentProcess() != FatGlobalData.SystemProcess); - - /* Determine if it's a delayed close, by flags first */ - if ((TypeOfOpen == UserFileOpen || TypeOfOpen == UserDirectoryOpen) && - (Fcb->State & FCB_STATE_DELAY_CLOSE) && - !FatGlobalData.ShutdownStarted) - { - DelayedClose = TRUE; - } - - /* If close is not delayed, try to perform the close operation */ - if (!DelayedClose) - Status = FatiCommonClose(Vcb, Fcb, Ccb, TypeOfOpen, Wait, &VcbDeleted); - - /* We have to delay close if either it's defined by a flag or it was not possible - to perform it synchronously */ - if (DelayedClose || Status == STATUS_PENDING) - { - DPRINT1("Queuing a pending close, Vcb %p, Fcb %p, Ccb %p\n", Vcb, Fcb, Ccb); - - /* Check if a close context should be allocated */ - if (TypeOfOpen == VirtualVolumeFile) - { - ASSERT(Vcb->CloseContext != NULL); - CloseContext = Vcb->CloseContext; - Vcb->CloseContext = NULL; - CloseContext->Free = TRUE; - } - else if (TypeOfOpen == DirectoryFile || - TypeOfOpen == EaFile) - { - UNIMPLEMENTED; - //CloseContext = FatAllocateCloseContext(Vcb); - //ASSERT(CloseContext != NULL); - CloseContext->Free = TRUE; - } - else - { - //TODO: FatDeallocateCcbStrings( Ccb ); - - /* Set CloseContext to a buffer inside Ccb */ - CloseContext = &Ccb->CloseContext; - CloseContext->Free = FALSE; - SetFlag(Ccb->Flags, CCB_CLOSE_CONTEXT); - } - - /* Save all info in the close context */ - CloseContext->Vcb = Vcb; - CloseContext->Fcb = Fcb; - CloseContext->TypeOfOpen = TypeOfOpen; - - /* Queue the close */ - FatQueueClose(CloseContext, (BOOLEAN)(Fcb && FlagOn(Fcb->State, FCB_STATE_DELAY_CLOSE))); - } - else - { - /* Close finished right away */ - if (TypeOfOpen == VirtualVolumeFile || - TypeOfOpen == DirectoryFile || - TypeOfOpen == EaFile) - { - if (TypeOfOpen == VirtualVolumeFile) - { - /* Free close context for the not deleted VCB */ - if (!VcbDeleted) - { - CloseContext = Vcb->CloseContext; - Vcb->CloseContext = NULL; - - ASSERT(CloseContext != NULL); - } - } - else - { - //CloseContext = FatAllocateCloseContext(Vcb); - DPRINT1("TODO: Allocate close context!\n"); - ASSERT(CloseContext != NULL); - } - - /* Free close context */ - if (CloseContext) ExFreePool(CloseContext); - } - } - - /* Complete the request */ - FatCompleteRequest(NULL, Irp, Status); - - /* Reset the top level IRP if necessary */ - if (TopLevel) IoSetTopLevelIrp(NULL); - - return Status; -} - -NTSTATUS -NTAPI -FatClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PFAT_IRP_CONTEXT IrpContext; - NTSTATUS Status; - - DPRINT("FatClose(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); - - /* FatClose works only with a volume device object */ - if (DeviceObject == FatGlobalData.DiskDeviceObject) - { - /* Complete the request and return success */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - - IoCompleteRequest(Irp, IO_DISK_INCREMENT); - - return STATUS_SUCCESS; - } - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, TRUE); - - /* Call internal function */ - Status = FatiClose(IrpContext, Irp); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -VOID -NTAPI -FatPendingClose(IN PVCB Vcb OPTIONAL) -{ - PCLOSE_CONTEXT CloseContext; - PVCB CurrentVcb = NULL; - PVCB LastVcb = NULL; - BOOLEAN FreeContext; - ULONG Loops = 0; - - /* Do the top-level IRP trick */ - if (!Vcb) IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP); - - while ((CloseContext = FatRemoveClose(Vcb, LastVcb))) - { - if (!Vcb) - { - if (!FatGlobalData.ShutdownStarted) - { - if (CloseContext->Vcb != CurrentVcb) - { - Loops = 0; - - /* Release previous VCB */ - if (CurrentVcb) - ExReleaseResourceLite(&CurrentVcb->Resource); - - /* Lock the new VCB */ - CurrentVcb = CloseContext->Vcb; - (VOID)ExAcquireResourceExclusiveLite(&CurrentVcb->Resource, TRUE); - } - else - { - /* Try to lock */ - if (++Loops >= 20) - { - if (ExGetSharedWaiterCount(&CurrentVcb->Resource) + - ExGetExclusiveWaiterCount(&CurrentVcb->Resource)) - { - ExReleaseResourceLite(&CurrentVcb->Resource); - (VOID)ExAcquireResourceExclusiveLite(&CurrentVcb->Resource, TRUE); - } - - Loops = 0; - } - } - - /* Check open count */ - if (CurrentVcb->OpenFileCount <= 1) - { - ExReleaseResourceLite(&CurrentVcb->Resource); - CurrentVcb = NULL; - } - } - else if (CurrentVcb) - { - ExReleaseResourceLite(&CurrentVcb->Resource); - CurrentVcb = NULL; - } - } - - LastVcb = CurrentVcb; - - /* Remember if we should free the context */ - FreeContext = CloseContext->Free; - - FatiCommonClose(CloseContext->Vcb, - CloseContext->Fcb, - (FreeContext ? NULL : CONTAINING_RECORD(CloseContext, CCB, CloseContext)), - CloseContext->TypeOfOpen, - TRUE, - NULL); - - /* Free context if necessary */ - if (FreeContext) ExFreePool(CloseContext); - } - - /* Release VCB if necessary */ - if (CurrentVcb) ExReleaseResourceLite(&CurrentVcb->Resource); - - /* Reset top level IRP */ - if (!Vcb) IoSetTopLevelIrp( NULL ); -} - -VOID -NTAPI -FatCloseWorker(IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - FsRtlEnterFileSystem(); - - FatPendingClose((PVCB)Context); - - FsRtlExitFileSystem(); -} - -VOID -NTAPI -FatQueueClose(IN PCLOSE_CONTEXT CloseContext, - IN BOOLEAN DelayClose) -{ - BOOLEAN RunWorker = FALSE; - - /* Acquire the close lists mutex */ - ExAcquireFastMutexUnsafe(&FatCloseQueueMutex); - - /* Add it to the desired list */ - if (DelayClose) - { - InsertTailList(&FatGlobalData.DelayedCloseList, - &CloseContext->GlobalLinks); - InsertTailList(&CloseContext->Vcb->DelayedCloseList, - &CloseContext->VcbLinks); - - FatGlobalData.DelayedCloseCount++; - - if (FatGlobalData.DelayedCloseCount > FatMaxDelayedCloseCount && - !FatGlobalData.AsyncCloseActive) - { - FatGlobalData.AsyncCloseActive = TRUE; - RunWorker = TRUE; - } - } - else - { - InsertTailList(&FatGlobalData.AsyncCloseList, - &CloseContext->GlobalLinks); - InsertTailList(&CloseContext->Vcb->AsyncCloseList, - &CloseContext->VcbLinks); - - FatGlobalData.AsyncCloseCount++; - - if (!FatGlobalData.AsyncCloseActive) - { - FatGlobalData.AsyncCloseActive = TRUE; - RunWorker = TRUE; - } - } - - /* Release the close lists mutex */ - ExReleaseFastMutexUnsafe(&FatCloseQueueMutex); - - if (RunWorker) - IoQueueWorkItem(FatGlobalData.FatCloseItem, FatCloseWorker, CriticalWorkQueue, NULL); -} - -PCLOSE_CONTEXT -NTAPI -FatRemoveClose(PVCB Vcb OPTIONAL, - PVCB LastVcbHint OPTIONAL) -{ - PLIST_ENTRY Entry; - PCLOSE_CONTEXT CloseContext; - BOOLEAN IsWorker = FALSE; - - /* Acquire the close lists mutex */ - ExAcquireFastMutexUnsafe(&FatCloseQueueMutex); - - if (!Vcb) IsWorker = TRUE; - - if (Vcb == NULL && LastVcbHint != NULL) - { - // TODO: A very special case of overflowing the queue - UNIMPLEMENTED; - } - - /* Usual processing from a worker thread */ - if (!Vcb) - { -TryToCloseAgain: - - /* Is there anything in the async close list */ - if (!IsListEmpty(&FatGlobalData.AsyncCloseList)) - { - Entry = RemoveHeadList(&FatGlobalData.AsyncCloseList); - FatGlobalData.AsyncCloseCount--; - - CloseContext = CONTAINING_RECORD(Entry, - CLOSE_CONTEXT, - GlobalLinks); - - RemoveEntryList(&CloseContext->VcbLinks); - } else if (!IsListEmpty(&FatGlobalData.DelayedCloseList) && - (FatGlobalData.DelayedCloseCount > FatMaxDelayedCloseCount/2 || - FatGlobalData.ShutdownStarted)) - { - /* In case of a shutdown or when delayed queue is filled at half - perform closing */ - Entry = RemoveHeadList(&FatGlobalData.DelayedCloseList); - FatGlobalData.DelayedCloseCount--; - - CloseContext = CONTAINING_RECORD(Entry, - CLOSE_CONTEXT, - GlobalLinks); - RemoveEntryList(&CloseContext->VcbLinks); - } - else - { - /* Nothing to close */ - CloseContext = NULL; - if (IsWorker) FatGlobalData.AsyncCloseActive = FALSE; - } - } - else - { - if (!IsListEmpty(&Vcb->AsyncCloseList)) - { - /* Is there anything in the async close list */ - Entry = RemoveHeadList(&Vcb->AsyncCloseList); - FatGlobalData.AsyncCloseCount--; - - CloseContext = CONTAINING_RECORD(Entry, - CLOSE_CONTEXT, - VcbLinks); - - RemoveEntryList(&CloseContext->GlobalLinks); - } - else if (!IsListEmpty(&Vcb->DelayedCloseList)) - { - /* Process delayed close list */ - Entry = RemoveHeadList(&Vcb->DelayedCloseList); - FatGlobalData.DelayedCloseCount--; - - CloseContext = CONTAINING_RECORD(Entry, - CLOSE_CONTEXT, - VcbLinks); - - RemoveEntryList(&CloseContext->GlobalLinks); - } - else if (LastVcbHint) - { - /* Try again */ - goto TryToCloseAgain; - } - else - { - /* Nothing to close */ - CloseContext = NULL; - } - } - - /* Release the close lists mutex */ - ExReleaseFastMutexUnsafe(&FatCloseQueueMutex); - - return CloseContext; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c deleted file mode 100644 index 3a24010b5b9..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/create.c - * PURPOSE: Create routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS *****************************************************************/ - -IO_STATUS_BLOCK -NTAPI -FatiOpenRootDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG CreateDisposition) -{ - IO_STATUS_BLOCK Iosb; - PFCB Dcb; - NTSTATUS Status; - PCCB Ccb; - - /* Reference our DCB */ - Dcb = Vcb->RootDcb; - - DPRINT("Opening root directory\n"); - - /* Exclusively lock this DCB */ - (VOID)FatAcquireExclusiveFcb(IrpContext, Dcb); - - do - { - /* Validate parameters */ - if (CreateDisposition != FILE_OPEN && - CreateDisposition != FILE_OPEN_IF) - { - Iosb.Status = STATUS_ACCESS_DENIED; - break; - } - - // TODO: Check file access - - /* Is it a first time open? */ - if (Dcb->OpenCount == 0) - { - /* Set share access */ - IoSetShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Dcb->ShareAccess); - } - else - { - /* Check share access */ - Status = IoCheckShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Dcb->ShareAccess, - TRUE); - } - - /* Set file object pointers */ - Ccb = FatCreateCcb(); - FatSetFileObject(FileObject, UserDirectoryOpen, Dcb, Ccb); - - /* Increment counters */ - Dcb->OpenCount++; - Dcb->UncleanCount++; - Vcb->OpenFileCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - - /* Set success statuses */ - Iosb.Status = STATUS_SUCCESS; - Iosb.Information = FILE_OPENED; - } while (FALSE); - - /* Release the DCB lock */ - FatReleaseFcb(IrpContext, Dcb); - - return Iosb; -} - -FF_ERROR -NTAPI -FatiTryToOpen(IN PFILE_OBJECT FileObject, - IN PVCB Vcb) -{ - OEM_STRING AnsiName; - CHAR AnsiNameBuf[512]; - FF_ERROR Error; - NTSTATUS Status; - FF_FILE *FileHandle; - - /* Convert the name to ANSI */ - AnsiName.Buffer = AnsiNameBuf; - AnsiName.Length = 0; - AnsiName.MaximumLength = sizeof(AnsiNameBuf); - RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - /* Open the file with FullFAT */ - FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &Error); - - /* Close the handle */ - if (FileHandle) FF_Close(FileHandle); - - /* Return status */ - return Error; -} - -IO_STATUS_BLOCK -NTAPI -FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext, - PFILE_OBJECT FileObject, - PFCB Fcb, - ULONG AllocationSize, - PFILE_FULL_EA_INFORMATION EaBuffer, - ULONG EaLength, - UCHAR FileAttributes, - ULONG CreateDisposition, - BOOLEAN NoEaKnowledge) -{ - IO_STATUS_BLOCK Iosb = {{0}}; - PCCB Ccb; - LARGE_INTEGER Zero; - ULONG NotifyFilter; - - Zero.QuadPart = 0; - - /* Check Ea mismatch first */ - if (NoEaKnowledge && EaLength > 0) - { - Iosb.Status = STATUS_ACCESS_DENIED; - return Iosb; - } - - do - { - /* Check if it's not still mapped */ - if (!MmCanFileBeTruncated(&Fcb->SectionObjectPointers, - &Zero)) - { - /* Fail */ - Iosb.Status = STATUS_USER_MAPPED_FILE; - break; - } - - /* Set file object pointers */ - Ccb = FatCreateCcb(); - FatSetFileObject(FileObject, - UserFileOpen, - Fcb, - Ccb); - - FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; - - /* Indicate that create is in progress */ - Fcb->Vcb->State |= VCB_STATE_CREATE_IN_PROGRESS; - - /* Purge the cache section */ - CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE); - - /* Add Eas */ - if (EaLength > 0) - { - ASSERT(FALSE); - } - - /* Acquire the paging resource */ - (VOID)ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); - - /* Initialize FCB header */ - Fcb->Header.FileSize.QuadPart = 0; - Fcb->Header.ValidDataLength.QuadPart = 0; - - /* Let CC know about changed file size */ - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); - - // TODO: Actually truncate the file - DPRINT1("TODO: Actually truncate file '%wZ' with a fullfat handle %x\n", &Fcb->FullFileName, Fcb->FatHandle); - - /* Release the paging resource */ - ExReleaseResourceLite(Fcb->Header.PagingIoResource); - - /* Specify truncate on close */ - Fcb->State |= FCB_STATE_TRUNCATE_ON_CLOSE; - - // TODO: Delete previous EA if needed - - /* Send notification about changes */ - NotifyFilter = FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE; - - FsRtlNotifyFullReportChange(Fcb->Vcb->NotifySync, - &Fcb->Vcb->NotifyList, - (PSTRING)&Fcb->FullFileName, - Fcb->FullFileName.Length - Fcb->FileNameLength, - NULL, - NULL, - NotifyFilter, - FILE_ACTION_MODIFIED, - NULL); - - /* Set success status */ - Iosb.Status = STATUS_SUCCESS; - - /* Set correct information code */ - Iosb.Information = (CreateDisposition == FILE_SUPERSEDE) ? FILE_SUPERSEDED : FILE_OVERWRITTEN; - } while (0); - - /* Remove the create in progress flag */ - ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); - - return Iosb; -} - -IO_STATUS_BLOCK -NTAPI -FatiOpenExistingDir(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG AllocationSize, - IN PFILE_FULL_EA_INFORMATION EaBuffer, - IN ULONG EaLength, - IN UCHAR FileAttributes, - IN ULONG CreateDisposition, - IN BOOLEAN DeleteOnClose) -{ - IO_STATUS_BLOCK Iosb = {{0}}; - OEM_STRING AnsiName; - CHAR AnsiNameBuf[512]; - PFCB Fcb; - NTSTATUS Status; - FF_FILE *FileHandle; - - /* Only open is permitted */ - if (CreateDisposition != FILE_OPEN && - CreateDisposition != FILE_OPEN_IF) - { - Iosb.Status = STATUS_OBJECT_NAME_COLLISION; - return Iosb; - } - - // TODO: Check dir access - - /* Convert the name to ANSI */ - AnsiName.Buffer = AnsiNameBuf; - AnsiName.Length = 0; - AnsiName.MaximumLength = sizeof(AnsiNameBuf); - RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - /* Open the dir with FullFAT */ - FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_DIR, NULL); - - if (!FileHandle) - { - Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now - return Iosb; - } - - /* Create a new DCB for this directory */ - Fcb = FatCreateDcb(IrpContext, Vcb, ParentDcb, FileHandle); - - /* Set share access */ - IoSetShareAccess(*DesiredAccess, ShareAccess, FileObject, &Fcb->ShareAccess); - - /* Set context and section object pointers */ - FatSetFileObject(FileObject, - UserDirectoryOpen, - Fcb, - FatCreateCcb()); - - /* Increase counters */ - Fcb->UncleanCount++; - Fcb->OpenCount++; - Vcb->OpenFileCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - - Iosb.Status = STATUS_SUCCESS; - Iosb.Information = FILE_OPENED; - - DPRINT1("Successfully opened dir %s\n", AnsiNameBuf); - - return Iosb; -} - -IO_STATUS_BLOCK -NTAPI -FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG AllocationSize, - IN PFILE_FULL_EA_INFORMATION EaBuffer, - IN ULONG EaLength, - IN UCHAR FileAttributes, - IN ULONG CreateDisposition, - IN BOOLEAN IsPagingFile, - IN BOOLEAN DeleteOnClose, - IN BOOLEAN IsDosName) -{ - IO_STATUS_BLOCK Iosb = {{0}}; - OEM_STRING AnsiName; - CHAR AnsiNameBuf[512]; - PFCB Fcb; - NTSTATUS Status; - FF_FILE *FileHandle; - FF_ERROR FfError; - - /* Check for create file option and fail */ - if (CreateDisposition == FILE_CREATE) - { - Iosb.Status = STATUS_OBJECT_NAME_COLLISION; - return Iosb; - } - - // TODO: Check more params - - /* Convert the name to ANSI */ - AnsiName.Buffer = AnsiNameBuf; - AnsiName.Length = 0; - AnsiName.MaximumLength = sizeof(AnsiNameBuf); - RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - /* Open the file with FullFAT */ - FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &FfError); - - if (!FileHandle) - { - DPRINT1("Failed to open file '%s', error %ld\n", AnsiName.Buffer, FfError); - Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now - return Iosb; - } - DPRINT1("Succeeded opening file '%s'\n", AnsiName.Buffer); - - /* Create a new FCB for this file */ - Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb, FileHandle); - - // TODO: Check if overwrite is needed - - // TODO: This is usual file open branch, without overwriting! - /* Set context and section object pointers */ - FatSetFileObject(FileObject, - UserFileOpen, - Fcb, - FatCreateCcb()); - FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; - - Iosb.Status = STATUS_SUCCESS; - Iosb.Information = FILE_OPENED; - - - /* Increase counters */ - Fcb->UncleanCount++; - Fcb->OpenCount++; - if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) Fcb->NonCachedUncleanCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - - return Iosb; -} - -IO_STATUS_BLOCK -NTAPI -FatiOpenVolume(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG CreateDisposition) -{ - PCCB Ccb; - IO_STATUS_BLOCK Iosb = {{0}}; - BOOLEAN VolumeFlushed = FALSE; - - /* Check parameters */ - if (CreateDisposition != FILE_OPEN && - CreateDisposition != FILE_OPEN_IF) - { - /* Deny access */ - Iosb.Status = STATUS_ACCESS_DENIED; - } - - /* Check if it's exclusive open */ - if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) && - !FlagOn(ShareAccess, FILE_SHARE_DELETE)) - { - // TODO: Check if exclusive read access requested - // and opened handles count is not 0 - //if (!FlagOn(ShareAccess, FILE_SHARE_READ) - - DPRINT1("Exclusive volume open\n"); - - // TODO: Flush the volume - VolumeFlushed = TRUE; - } - else if (FlagOn(*DesiredAccess, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)) - { - DPRINT1("Shared open\n"); - - // TODO: Flush the volume - VolumeFlushed = TRUE; - } - - if (VolumeFlushed && - !FlagOn(Vcb->State, VCB_STATE_MOUNTED_DIRTY) && - FlagOn(Vcb->State, VCB_STATE_FLAG_DIRTY) && - CcIsThereDirtyData(Vcb->Vpb)) - { - UNIMPLEMENTED; - } - - /* Set share access */ - if (Vcb->DirectOpenCount > 0) - { - /* This volume has already been opened */ - Iosb.Status = IoCheckShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Vcb->ShareAccess, - TRUE); - - if (!NT_SUCCESS(Iosb.Status)) - { - ASSERT(FALSE); - } - } - else - { - /* This is the first time open */ - IoSetShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Vcb->ShareAccess); - } - - /* Set file object pointers */ - Ccb = FatCreateCcb(); - FatSetFileObject(FileObject, UserVolumeOpen, Vcb, Ccb); - FileObject->SectionObjectPointer = &Vcb->SectionObjectPointers; - - /* Increase direct open count */ - Vcb->DirectOpenCount++; - Vcb->OpenFileCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - - /* Set no buffering flag */ - FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING; - - // TODO: User's access check - - Iosb.Status = STATUS_SUCCESS; - Iosb.Information = FILE_OPENED; - - return Iosb; -} - -NTSTATUS -NTAPI -FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - /* Boolean options */ - BOOLEAN CreateDirectory; - BOOLEAN SequentialOnly; - BOOLEAN NoIntermediateBuffering; - BOOLEAN OpenDirectory; - BOOLEAN IsPagingFile; - BOOLEAN OpenTargetDirectory; - BOOLEAN IsDirectoryFile; - BOOLEAN NonDirectoryFile; - BOOLEAN NoEaKnowledge; - BOOLEAN DeleteOnClose; - BOOLEAN TemporaryFile; - ULONG CreateDisposition; - - /* Control blocks */ - PVCB Vcb, DecodedVcb, RelatedVcb; - PFCB Fcb, NextFcb, RelatedDcb; - PCCB Ccb, RelatedCcb; - PFCB ParentDcb; - - /* IRP data */ - PFILE_OBJECT FileObject; - PFILE_OBJECT RelatedFO; - UNICODE_STRING FileName; - ULONG AllocationSize; - PFILE_FULL_EA_INFORMATION EaBuffer; - PACCESS_MASK DesiredAccess; - ULONG Options; - UCHAR FileAttributes; - USHORT ShareAccess; - ULONG EaLength; - - /* Misc */ - NTSTATUS Status; - IO_STATUS_BLOCK Iosb; - PIO_STACK_LOCATION IrpSp; - BOOLEAN EndBackslash = FALSE, OpenedAsDos, FirstRun = TRUE; - UNICODE_STRING RemainingPart, FirstName, NextName, FileNameUpcased; - OEM_STRING AnsiFirstName; - FF_ERROR FfError; - TYPE_OF_OPEN TypeOfOpen; - BOOLEAN OplockPostIrp = FALSE; - - Iosb.Status = STATUS_SUCCESS; - - /* Get current IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("FatCommonCreate\n", 0 ); - DPRINT("Irp = %08lx\n", Irp ); - DPRINT("\t->Flags = %08lx\n", Irp->Flags ); - DPRINT("\t->FileObject = %08lx\n", IrpSp->FileObject ); - DPRINT("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject ); - DPRINT("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName ); - DPRINT("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart ); - DPRINT("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart ); - DPRINT("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ); - DPRINT("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - DPRINT("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options ); - DPRINT("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes ); - DPRINT("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess ); - DPRINT("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength ); - - /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */ - if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && - (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && - (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) - { - /* Remove a leading slash */ - IrpSp->FileObject->FileName.Length -= sizeof(WCHAR); - RtlMoveMemory(&IrpSp->FileObject->FileName.Buffer[0], - &IrpSp->FileObject->FileName.Buffer[1], - IrpSp->FileObject->FileName.Length ); - - /* Check again: if there are still two leading slashes, - exit with an error */ - if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && - (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && - (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) - { - FatCompleteRequest( IrpContext, Irp, STATUS_OBJECT_NAME_INVALID ); - - DPRINT1("FatiCreate: STATUS_OBJECT_NAME_INVALID\n"); - return STATUS_OBJECT_NAME_INVALID; - } - } - - /* Make sure we have SecurityContext */ - ASSERT(IrpSp->Parameters.Create.SecurityContext != NULL); - - /* Get necessary data out of IRP */ - FileObject = IrpSp->FileObject; - FileName = FileObject->FileName; - RelatedFO = FileObject->RelatedFileObject; - AllocationSize = Irp->Overlay.AllocationSize.LowPart; - EaBuffer = Irp->AssociatedIrp.SystemBuffer; - DesiredAccess = &IrpSp->Parameters.Create.SecurityContext->DesiredAccess; - Options = IrpSp->Parameters.Create.Options; - FileAttributes = (UCHAR)(IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL); - ShareAccess = IrpSp->Parameters.Create.ShareAccess; - EaLength = IrpSp->Parameters.Create.EaLength; - - /* Set VPB to related object's VPB if it exists */ - if (RelatedFO) - FileObject->Vpb = RelatedFO->Vpb; - - /* Reject open by id */ - if (Options & FILE_OPEN_BY_FILE_ID) - { - FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER); - return STATUS_INVALID_PARAMETER; - } - - /* Prepare file attributes mask */ - FileAttributes &= (FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_ARCHIVE); - - /* Get the volume control object */ - Vcb = &((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Vcb; - - /* Get options */ - IsDirectoryFile = BooleanFlagOn(Options, FILE_DIRECTORY_FILE); - NonDirectoryFile = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE); - SequentialOnly = BooleanFlagOn(Options, FILE_SEQUENTIAL_ONLY); - NoIntermediateBuffering = BooleanFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING); - NoEaKnowledge = BooleanFlagOn(Options, FILE_NO_EA_KNOWLEDGE); - DeleteOnClose = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE); - TemporaryFile = BooleanFlagOn(IrpSp->Parameters.Create.FileAttributes, - FILE_ATTRIBUTE_TEMPORARY ); - IsPagingFile = BooleanFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE); - OpenTargetDirectory = BooleanFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY); - - /* Calculate create disposition */ - CreateDisposition = (Options >> 24) & 0x000000ff; - - /* Get Create/Open directory flags based on it */ - CreateDirectory = (BOOLEAN)(IsDirectoryFile && - ((CreateDisposition == FILE_CREATE) || - (CreateDisposition == FILE_OPEN_IF))); - - OpenDirectory = (BOOLEAN)(IsDirectoryFile && - ((CreateDisposition == FILE_OPEN) || - (CreateDisposition == FILE_OPEN_IF))); - - /* Validate parameters: directory/nondirectory mismatch and - AllocationSize being more than 4GB */ - if ((IsDirectoryFile && NonDirectoryFile) || - Irp->Overlay.AllocationSize.HighPart != 0) - { - FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER); - - DPRINT1("FatiCreate: STATUS_INVALID_PARAMETER\n", 0); - return STATUS_INVALID_PARAMETER; - } - - /* Acquire the VCB lock exclusively */ - if (!FatAcquireExclusiveVcb(IrpContext, Vcb)) - { - // TODO: Postpone the IRP for later processing - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; - } - - // TODO: Verify the VCB - - /* If VCB is locked, then no file openings are possible */ - if (Vcb->State & VCB_STATE_FLAG_LOCKED) - { - DPRINT1("This volume is locked\n"); - Status = STATUS_ACCESS_DENIED; - - /* Set volume dismount status */ - if (Vcb->Condition != VcbGood) - Status = STATUS_VOLUME_DISMOUNTED; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Check if the volume is write protected and disallow DELETE_ON_CLOSE */ - if (DeleteOnClose & FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) - { - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; - } - - // TODO: Make sure EAs aren't supported on FAT32 - - /* Check if it's a volume open request */ - if (FileName.Length == 0) - { - /* Test related FO to be sure */ - if (!RelatedFO || - FatDecodeFileObject(RelatedFO, &DecodedVcb, &Fcb, &Ccb) == UserVolumeOpen) - { - /* Check parameters */ - if (IsDirectoryFile || OpenTargetDirectory) - { - Status = IsDirectoryFile ? STATUS_NOT_A_DIRECTORY : STATUS_INVALID_PARAMETER; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request and return */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* It is indeed a volume open request */ - Iosb = FatiOpenVolume(IrpContext, - FileObject, - Vcb, - DesiredAccess, - ShareAccess, - CreateDisposition); - - /* Set resulting information */ - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request and return */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - return Iosb.Status; - } - } - - /* Check if this is a relative open */ - if (RelatedFO) - { - /* Decode the file object */ - TypeOfOpen = FatDecodeFileObject(RelatedFO, - &RelatedVcb, - &RelatedDcb, - &RelatedCcb); - - /* Check open type */ - if (TypeOfOpen != UserFileOpen && - TypeOfOpen != UserDirectoryOpen) - { - DPRINT1("Invalid file object!\n"); - - Status = STATUS_OBJECT_PATH_NOT_FOUND; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* File path must be relative */ - if (FileName.Length != 0 && - FileName.Buffer[0] == L'\\') - { - Status = STATUS_OBJECT_NAME_INVALID; - - /* The name is absolute, fail */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Make sure volume is the same */ - ASSERT(RelatedVcb == Vcb); - - /* Save VPB */ - FileObject->Vpb = RelatedFO->Vpb; - - /* Set parent DCB */ - ParentDcb = RelatedDcb; - - DPRINT("Opening file '%wZ' relatively to '%wZ'\n", &FileName, &ParentDcb->FullFileName); - } - else - { - /* Absolute open */ - if ((FileName.Length == sizeof(WCHAR)) && - (FileName.Buffer[0] == L'\\')) - { - /* Check if it's ok to open it */ - if (NonDirectoryFile) - { - DPRINT1("Trying to open root dir as a file\n"); - Status = STATUS_FILE_IS_A_DIRECTORY; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Check for target directory on a root dir */ - if (OpenTargetDirectory) - { - Status = STATUS_INVALID_PARAMETER; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Check delete on close on a root dir */ - if (DeleteOnClose) - { - Status = STATUS_CANNOT_DELETE; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Call root directory open routine */ - Iosb = FatiOpenRootDcb(IrpContext, - FileObject, - Vcb, - DesiredAccess, - ShareAccess, - CreateDisposition); - - Irp->IoStatus.Information = Iosb.Information; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - return Iosb.Status; - } - else - { - /* Not a root dir */ - ParentDcb = Vcb->RootDcb; - DPRINT("ParentDcb %p\n", ParentDcb); - } - } - - /* Check for backslash at the end */ - if (FileName.Length && - FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\') - { - /* Cut it out */ - FileName.Length -= sizeof(WCHAR); - - /* Remember we cut it */ - EndBackslash = TRUE; - } - - /* Ensure the name is set */ - if (!ParentDcb->FullFileName.Buffer) - { - /* Set it if it's missing */ - FatSetFullFileNameInFcb(IrpContext, ParentDcb); - } - - /* Check max path length */ - if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length) - { - DPRINT1("Max length is way off\n"); - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - } - - /* Loop through FCBs to find a good one */ - while (TRUE) - { - Fcb = ParentDcb; - - /* Dissect the name */ - RemainingPart = FileName; - while (RemainingPart.Length) - { - FsRtlDissectName(RemainingPart, &FirstName, &NextName); - - /* Check for validity */ - if ((NextName.Length && NextName.Buffer[0] == L'\\') || - (NextName.Length > 255 * sizeof(WCHAR))) - { - /* The name is invalid */ - DPRINT1("Invalid name found\n"); - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - } - - /* Convert the name to ANSI */ - AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); - AnsiFirstName.Length = 0; - AnsiFirstName.MaximumLength = FirstName.Length; - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status); - ASSERT(FALSE); - NextFcb = NULL; - AnsiFirstName.Length = 0; - } - else - { - /* Find the coresponding FCB */ - NextFcb = FatFindFcb(IrpContext, - &Fcb->Dcb.SplayLinksAnsi, - (PSTRING)&AnsiFirstName, - &OpenedAsDos); - } - - /* If nothing found - try with unicode */ - if (!NextFcb && Fcb->Dcb.SplayLinksUnicode) - { - FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length); - FileNameUpcased.Length = 0; - FileNameUpcased.MaximumLength = FirstName.Length; - - /* Downcase and then upcase to normalize it */ - Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE); - Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE); - - /* Try to find FCB again using unicode name */ - NextFcb = FatFindFcb(IrpContext, - &Fcb->Dcb.SplayLinksUnicode, - (PSTRING)&FileNameUpcased, - &OpenedAsDos); - } - - /* Move to the next FCB */ - if (NextFcb) - { - Fcb = NextFcb; - RemainingPart = NextName; - } - - /* Break out of this loop if nothing can be found */ - if (!NextFcb || - NextName.Length == 0 || - FatNodeType(NextFcb) == FAT_NTC_FCB) - { - break; - } - } - - /* Ensure remaining name doesn't start from a backslash */ - if (RemainingPart.Length && - RemainingPart.Buffer[0] == L'\\') - { - /* Cut it */ - RemainingPart.Buffer++; - RemainingPart.Length -= sizeof(WCHAR); - } - - if (Fcb->Condition == FcbGood) - { - /* Good FCB, break out of the loop */ - break; - } - else - { - ASSERT(FALSE); - } - } - - /* Treat page file in a special way */ - if (IsPagingFile) - { - UNIMPLEMENTED; - // FIXME: System file too - } - - /* Make sure there is no pending delete on a higher-level FCB */ - if (Fcb->State & FCB_STATE_DELETE_ON_CLOSE) - { - Iosb.Status = STATUS_DELETE_PENDING; - - /* Cleanup and return */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - - /* We have a valid FCB now */ - if (!RemainingPart.Length) - { - /* Check for target dir open */ - if (OpenTargetDirectory) - { - DPRINT1("Opening target dir is missing\n"); - ASSERT(FALSE); - } - - /* Check this FCB's type */ - if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB || - FatNodeType(Fcb) == FAT_NTC_DCB) - { - /* Open a directory */ - if (NonDirectoryFile) - { - /* Forbidden */ - Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; - ASSERT(FALSE); - return Iosb.Status; - } - - /* Open existing DCB */ - Iosb = FatiOpenExistingDcb(IrpContext, - FileObject, - Vcb, - Fcb, - DesiredAccess, - ShareAccess, - CreateDisposition, - NoEaKnowledge, - DeleteOnClose); - - /* Save information */ - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - else if (FatNodeType(Fcb) == FAT_NTC_FCB) - { - /* Open a file */ - if (OpenDirectory) - { - /* Forbidden */ - Iosb.Status = STATUS_NOT_A_DIRECTORY; - ASSERT(FALSE); - return Iosb.Status; - } - - /* Check for trailing backslash */ - if (EndBackslash) - { - /* Forbidden */ - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - return Iosb.Status; - } - - Iosb = FatiOpenExistingFcb(IrpContext, - FileObject, - Vcb, - Fcb, - DesiredAccess, - ShareAccess, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - NoEaKnowledge, - DeleteOnClose, - OpenedAsDos, - &OplockPostIrp); - - /* Check if it's pending */ - if (Iosb.Status != STATUS_PENDING) - { - /* In case of success set cache supported flag */ - if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) - { - SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); - } - - /* Save information */ - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - else - { - /* Queue this IRP */ - UNIMPLEMENTED; - ASSERT(FALSE); - } - } - else - { - /* Unexpected FCB type */ - KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)Fcb, 0, 0); - } - } - - /* During parsing we encountered a part which has no attached FCB/DCB. - Check that the parent is really DCB and not FCB */ - if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB && - FatNodeType(Fcb) != FAT_NTC_DCB) - { - DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb)); - ASSERT(FALSE); - } - - /* Create additional DCBs for all path items */ - ParentDcb = Fcb; - while (TRUE) - { - if (FirstRun) - { - RemainingPart = NextName; - if (AnsiFirstName.Length) - Status = STATUS_SUCCESS; - else - Status = STATUS_UNMAPPABLE_CHARACTER; - - /* First run init is done */ - FirstRun = FALSE; - } - else - { - FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart); - - /* Check for validity */ - if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') || - (NextName.Length > 255 * sizeof(WCHAR))) - { - /* The name is invalid */ - DPRINT1("Invalid name found\n"); - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - } - - /* Convert the name to ANSI */ - AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); - AnsiFirstName.Length = 0; - AnsiFirstName.MaximumLength = FirstName.Length; - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); - } - - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); - - /* Break if came to the end */ - if (!RemainingPart.Length) break; - - /* Create a DCB for this entry */ - ParentDcb = FatCreateDcb(IrpContext, - Vcb, - ParentDcb, - NULL); - - /* Set its name */ - FatSetFullNameInFcb(ParentDcb, &FirstName); - } - - /* Try to open it and get a result, saying if this is a dir or a file */ - FfError = FatiTryToOpen(FileObject, Vcb); - - /* Check if we need to open target directory */ - if (OpenTargetDirectory) - { - // TODO: Open target directory - UNIMPLEMENTED; - } - - /* Check, if path is a existing directory or file */ - if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR || - FfError == FF_ERR_FILE_ALREADY_OPEN || - FfError == FF_ERR_NONE) - { - if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR) - { - if (NonDirectoryFile) - { - DPRINT1("Can't open dir as a file\n"); - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - return Iosb.Status; - } - - /* Open this directory */ - Iosb = FatiOpenExistingDir(IrpContext, - FileObject, - Vcb, - ParentDcb, - DesiredAccess, - ShareAccess, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - DeleteOnClose); - - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - else - { - /* This is opening an existing file */ - if (OpenDirectory) - { - /* But caller wanted a dir */ - Status = STATUS_NOT_A_DIRECTORY; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Status); - - return Status; - } - - /* If end backslash here, then it's definately not permitted, - since we're opening files here */ - if (EndBackslash) - { - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - return Iosb.Status; - } - - /* Try to open the file */ - Iosb = FatiOpenExistingFile(IrpContext, - FileObject, - Vcb, - ParentDcb, - DesiredAccess, - ShareAccess, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - FALSE, - DeleteOnClose, - OpenedAsDos); - - /* In case of success set cache supported flag */ - if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) - { - SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); - } - - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - } - - /* We come here only in the case when a new file is created */ - //ASSERT(FALSE); - DPRINT1("TODO: Create a new file/directory, called '%wZ'\n", &IrpSp->FileObject->FileName); - - Status = STATUS_NOT_IMPLEMENTED; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Status); - - return Status; -} - -NTSTATUS -NTAPI -FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PFAT_IRP_CONTEXT IrpContext; - NTSTATUS Status; - - /* If it's called with our Disk FS device object - it's always open */ - // TODO: Add check for CDROM FS device object - if (DeviceObject == FatGlobalData.DiskDeviceObject) - { - /* Complete the request and return success */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - - IoCompleteRequest(Irp, IO_DISK_INCREMENT); - - return STATUS_SUCCESS; - } - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, TRUE); - - /* Call internal function */ - Status = FatiCreate(IrpContext, Irp); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/device.c b/reactos/drivers/filesystems/fastfat_new/device.c deleted file mode 100644 index 8499a0bc80a..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/device.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/device.c - * PURPOSE: Device control - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatDeviceControl()\n"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -FatPerformDevIoCtrl(PDEVICE_OBJECT DeviceObject, - ULONG ControlCode, - PVOID InputBuffer, - ULONG InputBufferSize, - PVOID OutputBuffer, - ULONG OutputBufferSize, - BOOLEAN Override) -{ - PIRP Irp; - KEVENT Event; - NTSTATUS Status; - PIO_STACK_LOCATION Stack; - IO_STATUS_BLOCK IoStatus; - - /* Initialize the event for waiting */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - /* Build the device I/O control request */ - Irp = IoBuildDeviceIoControlRequest(ControlCode, - DeviceObject, - InputBuffer, - InputBufferSize, - OutputBuffer, - OutputBufferSize, - FALSE, - &Event, - &IoStatus); - - /* Fail if IRP hasn't been allocated */ - if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; - - /* Set verify override flag if requested */ - if (Override) - { - Stack = IoGetNextIrpStackLocation(Irp); - Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; - } - - /* Call the driver */ - Status = IoCallDriver(DeviceObject, Irp); - - /* Wait if needed */ - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = IoStatus.Status; - } - - return Status; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/dir.c b/reactos/drivers/filesystems/fastfat_new/dir.c deleted file mode 100644 index b1fb747ddad..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/dir.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/dir.c - * PURPOSE: Directory Control - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -NTAPI -FatDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatDirectoryControl()\n"); - return STATUS_NOT_IMPLEMENTED; -} - -VOID -NTAPI -FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb) -{ - PFCB Dcb; - - /* Make sure it's not already created */ - ASSERT(!Vcb->RootDcb); - - /* Allocate the DCB */ - Dcb = FsRtlAllocatePoolWithTag(NonPagedPool, - sizeof(FCB), - TAG_FCB); - - /* Zero it */ - RtlZeroMemory(Dcb, sizeof(FCB)); - - /* Assign it to the VCB */ - Vcb->RootDcb = Dcb; - - /* Set its header */ - Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB; - Dcb->Header.NodeByteSize = sizeof(FCB); - - /* FCB is in a good condition */ - Dcb->Condition = FcbGood; - - /* Initialize FCB's resource */ - Dcb->Header.Resource = &Dcb->Resource; - ExInitializeResourceLite(&Dcb->Resource); - - /* Initialize Paging Io resource*/ - Dcb->Header.PagingIoResource = &Dcb->PagingIoResource; - ExInitializeResourceLite(&Dcb->PagingIoResource); - - /* Initialize a list of parent DCBs*/ - InitializeListHead(&Dcb->ParentDcbLinks); - - /* Set VCB */ - Dcb->Vcb = Vcb; - - /* Initialize parent's DCB list */ - InitializeListHead(&Dcb->Dcb.ParentDcbList); - - /* Initialize the full file name */ - Dcb->FullFileName.Buffer = L"\\"; - Dcb->FullFileName.Length = 1 * sizeof(WCHAR); - Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR); - - Dcb->ShortName.Name.Ansi.Buffer = "\\"; - Dcb->ShortName.Name.Ansi.Length = 1; - Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR); - - /* Fill dirent attribute byte copy */ - Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY; - - /* Initialize advanced FCB header fields */ - ExInitializeFastMutex(&Dcb->HeaderMutex); - FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex); - - /* Set up first cluster field depending on FAT type */ - if (TRUE/*FatIsFat32(Vcb)*/) - { - /* First cluster is really the first cluster of this volume */ - Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster; - - /* Calculate size of FAT32 root dir */ - Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF; - //FatLookupFileAllocationSize(IrpContext, Dcb); - DPRINT1("Calculation of a size of a root dir is missing!\n"); - - Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart; - } - else - { -#if 0 - /* Add MCB entry */ - FatAddMcbEntry(Vcb, - &Dcb->Mcb, - 0, - FatRootDirectoryLbo(&Vcb->Bpb), - FatRootDirectorySize(&Vcb->Bpb)); - - /* Set a real size of the root directory */ - Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb); - Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart; -#endif - UNIMPLEMENTED; - } -} - -PFCB -NTAPI -FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN FF_FILE *FileHandle) -{ - PFCB Fcb; - - /* Allocate it and zero it */ - Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); - RtlZeroMemory(Fcb, sizeof(FCB)); - - /* Set node types */ - Fcb->Header.NodeTypeCode = FAT_NTC_DCB; - Fcb->Header.NodeByteSize = sizeof(FCB); - Fcb->Condition = FcbGood; - - /* Initialize resources */ - Fcb->Header.Resource = &Fcb->Resource; - ExInitializeResourceLite(Fcb->Header.Resource); - - Fcb->Header.PagingIoResource = &Fcb->PagingIoResource; - ExInitializeResourceLite(Fcb->Header.PagingIoResource); - - /* Initialize mutexes */ - Fcb->Header.FastMutex = &Fcb->HeaderMutex; - ExInitializeFastMutex(&Fcb->HeaderMutex); - FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); - - /* Insert into parent's DCB list */ - InsertHeadList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks); - - /* Set backlinks */ - Fcb->ParentFcb = ParentDcb; - Fcb->Vcb = Vcb; - - /* Initialize parent dcb list */ - InitializeListHead(&Fcb->Dcb.ParentDcbList); - - /* Set FullFAT handle */ - Fcb->FatHandle = FileHandle; - - /* Set names */ - if (FileHandle) - { - FatSetFcbNames(IrpContext, Fcb); - - /* Ensure the full name is set */ - FatSetFullFileNameInFcb(IrpContext, Fcb); - } - - return Fcb; -} - -IO_STATUS_BLOCK -NTAPI -FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB Dcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG CreateDisposition, - IN BOOLEAN NoEaKnowledge, - IN BOOLEAN DeleteOnClose) -{ - IO_STATUS_BLOCK Iosb = {{0}}; - PCCB Ccb; - - /* Exclusively lock this FCB */ - FatAcquireExclusiveFcb(IrpContext, Dcb); - - /* Check if it's a delete-on-close of a root DCB */ - if (FatNodeType(Dcb) == FAT_NTC_ROOT_DCB && DeleteOnClose) - { - Iosb.Status = STATUS_CANNOT_DELETE; - - /* Release the lock and return */ - FatReleaseFcb(IrpContext, Dcb); - return Iosb; - } - - /*if (NoEaKnowledge && NodeType(Dcb) != FAT_NTC_ROOT_DCB && - !FatIsFat32(Vcb)) - { - UNIMPLEMENTED; - }*/ - - /* Check the create disposition and desired access */ - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) - { - Iosb.Status = STATUS_OBJECT_NAME_COLLISION; - - /* Release the lock and return */ - FatReleaseFcb(IrpContext, Dcb); - return Iosb; - } - -#if 0 - if (!FatCheckFileAccess(IrpContext, - Dcb->DirentFatFlags, - DesiredAccess)) - { - Iosb.Status = STATUS_ACCESS_DENIED; - try_return( Iosb ); - } -#endif - - /* If it's already opened - check share access */ - if (Dcb->OpenCount > 0) - { - Iosb.Status = IoCheckShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Dcb->ShareAccess, - TRUE); - - if (!NT_SUCCESS(Iosb.Status)) - { - /* Release the lock and return */ - FatReleaseFcb(IrpContext, Dcb); - return Iosb; - } - } - else - { - IoSetShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Dcb->ShareAccess); - } - - /* Set the file object */ - Ccb = FatCreateCcb(); - FatSetFileObject(FileObject, - UserDirectoryOpen, - Dcb, - Ccb); - - /* Increase counters */ - Dcb->UncleanCount++; - Dcb->OpenCount++; - Vcb->OpenFileCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - - /* Set delete on close */ - if (DeleteOnClose) - SetFlag(Ccb->Flags, CCB_DELETE_ON_CLOSE); - - /* Clear delay close flag */ - ClearFlag(Dcb->State, FCB_STATE_DELAY_CLOSE); - - /* That's it */ - Iosb.Status = STATUS_SUCCESS; - Iosb.Information = FILE_OPENED; - - /* Release the lock */ - FatReleaseFcb(IrpContext, Dcb); - - return Iosb; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/ea.c b/reactos/drivers/filesystems/fastfat_new/ea.c deleted file mode 100644 index a7cf0a3d7bf..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/ea.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/ea.c - * PURPOSE: Extended Attributes support - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -VfatSetExtendedAttributes(PFILE_OBJECT FileObject, - PVOID Ea, - ULONG EaLength) -{ - return STATUS_EAS_NOT_SUPPORTED; -} diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.c b/reactos/drivers/filesystems/fastfat_new/fastfat.c deleted file mode 100644 index c469437b152..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fastfat.c - * PURPOSE: Initialization routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* GLOBALS ******************************************************************/ - -FAT_GLOBAL_DATA FatGlobalData; -FAST_MUTEX FatCloseQueueMutex; - -/* FUNCTIONS ****************************************************************/ - - -NTSTATUS -NTAPI -DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) -{ - PDEVICE_OBJECT DeviceObject; - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat"); - NTSTATUS Status; - - /* Create a device object */ - Status = IoCreateDevice(DriverObject, - 0, - &DeviceName, - FILE_DEVICE_DISK_FILE_SYSTEM, - 0, - FALSE, - &DeviceObject); - - if (!NT_SUCCESS(Status)) return Status; - - /* Zero global storage */ - RtlZeroMemory(&FatGlobalData, sizeof(FAT_GLOBAL_DATA)); - FatGlobalData.DriverObject = DriverObject; - FatGlobalData.DiskDeviceObject = DeviceObject; - FatGlobalData.SystemProcess = PsGetCurrentProcess(); - - /* Fill major function handlers */ - DriverObject->MajorFunction[IRP_MJ_CLOSE] = FatClose; - DriverObject->MajorFunction[IRP_MJ_CREATE] = FatCreate; - DriverObject->MajorFunction[IRP_MJ_READ] = FatRead; - DriverObject->MajorFunction[IRP_MJ_WRITE] = FatWrite; - DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FatFileSystemControl; - DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = FatQueryInformation; - DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = FatSetInformation; - DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FatDirectoryControl; - DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FatQueryVolumeInfo; - DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = FatSetVolumeInfo; - DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FatShutdown; - DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FatLockControl; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FatDeviceControl; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FatCleanup; - DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = FatFlushBuffers; - //DriverObject->MajorFunction[IRP_MJ_QUERY_EA] - //DriverObject->MajorFunction[IRP_MJ_SET_EA] - //DriverObject->MajorFunction[IRP_MJ_PNP] - - DriverObject->DriverUnload = NULL; - - /* Initialize cache manager callbacks */ - FatGlobalData.CacheMgrCallbacks.AcquireForLazyWrite = FatAcquireForLazyWrite; - FatGlobalData.CacheMgrCallbacks.ReleaseFromLazyWrite = FatReleaseFromLazyWrite; - FatGlobalData.CacheMgrCallbacks.AcquireForReadAhead = FatAcquireForReadAhead; - FatGlobalData.CacheMgrCallbacks.ReleaseFromReadAhead = FatReleaseFromReadAhead; - - FatGlobalData.CacheMgrNoopCallbacks.AcquireForLazyWrite = FatNoopAcquire; - FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromLazyWrite = FatNoopRelease; - FatGlobalData.CacheMgrNoopCallbacks.AcquireForReadAhead = FatNoopAcquire; - FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromReadAhead = FatNoopRelease; - - /* Initialize Fast I/O dispatchers */ - FatInitFastIoRoutines(&FatGlobalData.FastIoDispatch); - DriverObject->FastIoDispatch = &FatGlobalData.FastIoDispatch; - - /* Initialize lookaside lists */ - ExInitializeNPagedLookasideList(&FatGlobalData.NonPagedFcbList, - NULL, - NULL, - 0, - sizeof(FCB), - TAG_FCB, - 0); - - ExInitializeNPagedLookasideList(&FatGlobalData.ResourceList, - NULL, - NULL, - 0, - sizeof(ERESOURCE), - TAG_CCB, - 0); - - ExInitializeNPagedLookasideList(&FatGlobalData.IrpContextList, - NULL, - NULL, - 0, - sizeof(FAT_IRP_CONTEXT), - TAG_IRP, - 0); - - /* Initialize synchronization resource for the global data */ - ExInitializeResourceLite(&FatGlobalData.Resource); - - /* Initialize queued close stuff */ - InitializeListHead(&FatGlobalData.AsyncCloseList); - InitializeListHead(&FatGlobalData.DelayedCloseList); - FatGlobalData.FatCloseItem = IoAllocateWorkItem(DeviceObject); - ExInitializeFastMutex(&FatCloseQueueMutex); - - /* Initialize global VCB list */ - InitializeListHead(&FatGlobalData.VcbListHead); - - /* Register and reference our filesystem */ - IoRegisterFileSystem(DeviceObject); - ObReferenceObject(DeviceObject); - return STATUS_SUCCESS; -} - -PFAT_IRP_CONTEXT -NTAPI -FatBuildIrpContext(PIRP Irp, - BOOLEAN CanWait) -{ - PIO_STACK_LOCATION IrpSp; - PFAT_IRP_CONTEXT IrpContext; - PVOLUME_DEVICE_OBJECT VolumeObject; - - /* Get current IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Allocate memory for the Irp context */ - IrpContext = ExAllocateFromNPagedLookasideList(&FatGlobalData.IrpContextList); - - /* Zero init memory */ - RtlZeroMemory(IrpContext, sizeof(FAT_IRP_CONTEXT)); - - /* Save IRP, MJ and MN */ - IrpContext->Irp = Irp; - IrpContext->Stack = IrpSp; - IrpContext->MajorFunction = IrpSp->MajorFunction; - IrpContext->MinorFunction = IrpSp->MinorFunction; - - /* Set DeviceObject */ - if (IrpSp->FileObject) - { - IrpContext->DeviceObject = IrpSp->FileObject->DeviceObject; - - /* Save VCB pointer */ - VolumeObject = (PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject; - IrpContext->Vcb = &VolumeObject->Vcb; - - /* TODO: Handle write-through */ - } - else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) - { - /* Handle FSCTRL case */ - IrpContext->DeviceObject = IrpSp->Parameters.MountVolume.Vpb->RealDevice; - } - - /* Set Wait flag */ - if (CanWait) IrpContext->Flags |= IRPCONTEXT_CANWAIT; - - /* Return prepared context */ - return IrpContext; -} - -VOID -NTAPI -FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext) -{ - PAGED_CODE(); - - /* Make sure it has no pinned stuff */ - ASSERT(IrpContext->PinCount == 0); - - /* If there is a FatIo context associated with it - free it */ - if (IrpContext->FatIoContext) - { - if (!(IrpContext->Flags & IRPCONTEXT_STACK_IO_CONTEXT)) - { - /* If a zero mdl was allocated - free it */ - if (IrpContext->FatIoContext->ZeroMdl) - IoFreeMdl(IrpContext->FatIoContext->ZeroMdl); - - /* Free memory of FatIo context */ - ExFreePool(IrpContext->FatIoContext); - } - } - - /* Free memory */ - ExFreeToNPagedLookasideList(&FatGlobalData.IrpContextList, IrpContext); -} - -VOID -NTAPI -FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL, - PIRP Irp OPTIONAL, - NTSTATUS Status) -{ - PAGED_CODE(); - - if (IrpContext) - { - /* TODO: Unpin repinned BCBs */ - //ASSERT(IrpContext->Repinned.Bcb[0] == NULL); - //FatUnpinRepinnedBcbs( IrpContext ); - - /* Destroy IRP context */ - FatDestroyIrpContext(IrpContext); - } - - /* Complete the IRP */ - if (Irp) - { - /* Cleanup IoStatus.Information in case of error input operation */ - if (NT_ERROR(Status) && (Irp->Flags & IRP_INPUT_OPERATION)) - { - Irp->IoStatus.Information = 0; - } - - /* Save status and complete this IRP */ - Irp->IoStatus.Status = Status; - IoCompleteRequest( Irp, IO_DISK_INCREMENT ); - } -} - -VOID -NTAPI -FatDequeueRequest(IN PVOID Context) -{ - PFAT_IRP_CONTEXT IrpContext; - - IrpContext = (PFAT_IRP_CONTEXT) Context; - - /* Enter critical region. */ - FsRtlEnterFileSystem(); - - /* Handle top level IRP Correctly. */ - if (!FlagOn(IrpContext->Flags, IRPCONTEXT_TOPLEVEL)) - IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP); - - /* Enable Synchronous IO. */ - SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT); - - /* Invoke the handler routine. */ - IrpContext->QueuedOperationHandler(IrpContext); - - /* Restore top level IRP. */ - IoSetTopLevelIrp(NULL); - - /* Leave critical region. */ - FsRtlExitFileSystem(); -} - -VOID -NTAPI -FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext, - IN PFAT_OPERATION_HANDLER OperationHandler) -{ - /* Save the worker routine. */ - IrpContext->QueuedOperationHandler = OperationHandler; - - /* Indicate if top level IRP was set. */ - if (IoGetTopLevelIrp() == IrpContext->Irp) - SetFlag(IrpContext->Flags, IRPCONTEXT_TOPLEVEL); - - /* Initialize work item. */ - ExInitializeWorkItem(&IrpContext->WorkQueueItem, - FatDequeueRequest, - IrpContext); - ExQueueWorkItem(&IrpContext->WorkQueueItem, - DelayedWorkQueue); -} - -TYPE_OF_OPEN -NTAPI -FatDecodeFileObject(IN PFILE_OBJECT FileObject, - OUT PVCB *Vcb, - OUT PFCB *FcbOrDcb, - OUT PCCB *Ccb) -{ - TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject; - PVOID FsContext = FileObject->FsContext; - PVOID FsContext2 = FileObject->FsContext2; - - /* If FsContext is NULL, then everything is NULL */ - if (!FsContext) - { - *Ccb = NULL; - *FcbOrDcb = NULL; - *Vcb = NULL; - - return TypeOfOpen; - } - - /* CCB is always stored in FsContext2 */ - *Ccb = FsContext2; - - /* Switch according to the NodeType */ - switch (FatNodeType(FsContext)) - { - /* Volume */ - case FAT_NTC_VCB: - *FcbOrDcb = NULL; - *Vcb = FsContext; - - TypeOfOpen = ( *Ccb == NULL ? VirtualVolumeFile : UserVolumeOpen ); - - break; - - /* Root or normal directory*/ - case FAT_NTC_ROOT_DCB: - case FAT_NTC_DCB: - *FcbOrDcb = FsContext; - *Vcb = (*FcbOrDcb)->Vcb; - - TypeOfOpen = (*Ccb == NULL ? DirectoryFile : UserDirectoryOpen); - - DPRINT("Referencing a directory: %wZ\n", &(*FcbOrDcb)->FullFileName); - break; - - /* File */ - case FAT_NTC_FCB: - *FcbOrDcb = FsContext; - *Vcb = (*FcbOrDcb)->Vcb; - - TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen); - - DPRINT("Referencing a file: %wZ\n", &(*FcbOrDcb)->FullFileName); - - break; - - default: - DPRINT1("Unknown node type %x\n", FatNodeType(FsContext)); - ASSERT(FALSE); - } - - return TypeOfOpen; -} - -VOID -NTAPI -FatSetFileObject(PFILE_OBJECT FileObject, - TYPE_OF_OPEN TypeOfOpen, - PVOID Fcb, - PCCB Ccb) -{ - if (Fcb) - { - /* Check Fcb's type */ - if (FatNodeType(Fcb) == FAT_NTC_VCB) - { - FileObject->Vpb = ((PVCB)Fcb)->Vpb; - } - else - { - FileObject->Vpb = ((PFCB)Fcb)->Vcb->Vpb; - } - } - - /* Set FsContext */ - if (FileObject) - { - FileObject->FsContext = Fcb; - FileObject->FsContext2 = Ccb; - } -} - - -BOOLEAN -NTAPI -FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb) -{ - /* Acquire VCB's resource if possible */ - if (ExAcquireResourceExclusiveLite(&Vcb->Resource, - BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) - { - return TRUE; - } - else - { - return FALSE; - } -} - -BOOLEAN -NTAPI -FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb) -{ - /* Acquire VCB's resource if possible */ - if (ExAcquireResourceSharedLite(&Vcb->Resource, - BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) - { - return TRUE; - } - else - { - return FALSE; - } -} - -VOID -NTAPI -FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb) -{ - /* Release VCB's resource */ - ExReleaseResourceLite(&Vcb->Resource); -} - -BOOLEAN -NTAPI -FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ -RetryLockingE: - /* Try to acquire the exclusive lock*/ - if (ExAcquireResourceExclusiveLite(Fcb->Header.Resource, - BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) - { - /* Wait same way MS's FASTFAT wait, i.e. - checking that there are outstanding async writes, - or someone is waiting on it*/ - if (Fcb->OutstandingAsyncWrites && - ((IrpContext->MajorFunction != IRP_MJ_WRITE) || - !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) || - ExGetSharedWaiterCount(Fcb->Header.Resource) || - ExGetExclusiveWaiterCount(Fcb->Header.Resource))) - { - KeWaitForSingleObject(Fcb->OutstandingAsyncEvent, - Executive, - KernelMode, - FALSE, - NULL); - - /* Release the lock */ - FatReleaseFcb(IrpContext, Fcb); - - /* Retry */ - goto RetryLockingE; - } - - /* Return success */ - return TRUE; - } - - /* Return failure */ - return FALSE; -} - -BOOLEAN -NTAPI -FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ -RetryLockingS: - /* Try to acquire the shared lock*/ - if (ExAcquireResourceSharedLite(Fcb->Header.Resource, - BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) - { - /* Wait same way MS's FASTFAT wait, i.e. - checking that there are outstanding async writes, - or someone is waiting on it*/ - if (Fcb->OutstandingAsyncWrites && - ((IrpContext->MajorFunction != IRP_MJ_WRITE) || - !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) || - ExGetSharedWaiterCount(Fcb->Header.Resource) || - ExGetExclusiveWaiterCount(Fcb->Header.Resource))) - { - KeWaitForSingleObject(Fcb->OutstandingAsyncEvent, - Executive, - KernelMode, - FALSE, - NULL); - - /* Release the lock */ - FatReleaseFcb(IrpContext, Fcb); - - /* Retry */ - goto RetryLockingS; - } - - /* Return success */ - return TRUE; - } - - /* Return failure */ - return FALSE; -} - -VOID -NTAPI -FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ - /* Release FCB's resource */ - ExReleaseResourceLite(Fcb->Header.Resource); -} - -PVOID -FASTCALL -FatMapUserBuffer(PIRP Irp) -{ - if (!Irp->MdlAddress) - return Irp->UserBuffer; - else - return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); -} - -BOOLEAN -NTAPI -FatIsTopLevelIrp(IN PIRP Irp) -{ - if (!IoGetTopLevelIrp()) - { - IoSetTopLevelIrp(Irp); - return TRUE; - } - - return FALSE; -} - -VOID -NTAPI -FatNotifyReportChange(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb, - IN ULONG Filter, - IN ULONG Action) -{ - if (Fcb->FullFileName.Buffer == NULL) - FatSetFullFileNameInFcb(IrpContext, Fcb); - - ASSERT(Fcb->FullFileName.Length != 0 ); - ASSERT(Fcb->FileNameLength != 0 ); - ASSERT(Fcb->FullFileName.Length > Fcb->FileNameLength ); - ASSERT(Fcb->FullFileName.Buffer[(Fcb->FullFileName.Length - Fcb->FileNameLength)/sizeof(WCHAR) - 1] == L'\\' ); - - FsRtlNotifyFullReportChange(Vcb->NotifySync, - &Vcb->NotifyList, - (PSTRING)&Fcb->FullFileName, - (USHORT)(Fcb->FullFileName.Length - - Fcb->FileNameLength), - NULL, - NULL, - Filter, - Action, - NULL); -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h deleted file mode 100644 index f00bca4a832..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ /dev/null @@ -1,408 +0,0 @@ -#include -#include -#include -#include -#include - -#include "fullfat.h" - -#include -#include - -#define Add2Ptr(P,I,T) ((T)((PUCHAR)(P) + (I))) -#define PtrOffset(B,O) ((ULONG)((ULONG_PTR)(O) - (ULONG_PTR)(B))) - -#define TAG_CCB 'BCCV' -#define TAG_FCB 'BCFV' -#define TAG_IRP 'PRIV' -#define TAG_VFAT 'TAFV' -#define TAG_FSD_CLOSE_CONTEXT 'CLCV' - - -/* Global resource acquire/release */ -#define FatAcquireExclusiveGlobal(IrpContext) \ -( \ - ExAcquireResourceExclusiveLite(&FatGlobalData.Resource, \ - (IrpContext)->Flags & IRPCONTEXT_CANWAIT) \ -) - -#define FatAcquireSharedGlobal(IrpContext) \ -( \ - ExAcquireResourceSharedLite(&FatGlobalData.Resource, \ - (IrpContext)->Flags & IRPCONTEXT_CANWAIT) \ -) - -#define FatReleaseGlobal(IrpContext) \ -{ \ - ExReleaseResourceLite(&(FatGlobalData.Resource)); \ -} - -#define FatIsFastIoPossible(FCB) ((BOOLEAN) \ - (((FCB)->Condition != FcbGood || !FsRtlOplockIsFastIoPossible(&(FCB)->Fcb.Oplock)) ? \ - FastIoIsNotPossible \ - : \ - (!FsRtlAreThereCurrentFileLocks(&(FCB)->Fcb.Lock) && \ - ((FCB)->OutstandingAsyncWrites == 0) && \ - !FlagOn((FCB)->Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) ? \ - FastIoIsPossible \ - : \ - FastIoIsQuestionable \ - ) \ - ) \ -) - -#define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess)) -#define IsFileDeleted(FCB) (FlagOn((FCB)->State, FCB_STATE_DELETE_ON_CLOSE) && ((FCB)->UncleanCount == 0)) - -BOOLEAN -FORCEINLINE -FatIsIoRangeValid(IN LARGE_INTEGER Start, IN ULONG Length) -{ - /* Check if it's more than 32bits, or if the length causes 32bit overflow. - FAT-specific! */ - - return !(Start.HighPart || Start.LowPart + Length < Start.LowPart); -} - - -NTSYSAPI -NTSTATUS -NTAPI -RtlUpcaseUnicodeStringToCountedOemString( - IN OUT POEM_STRING DestinationString, - IN PCUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString -); - - -/* ------------------------------------------------------ shutdown.c */ - -DRIVER_DISPATCH FatShutdown; -NTSTATUS NTAPI -FatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* -------------------------------------------------------- volume.c */ - -NTSTATUS NTAPI -FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -NTSTATUS NTAPI -FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -VOID NTAPI -FatReadStreamFile(PVCB Vcb, - ULONGLONG ByteOffset, - ULONG ByteSize, - PBCB *Bcb, - PVOID *Buffer); - -BOOLEAN -NTAPI -FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext, - PVCB Vcb, - IN BOOLEAN Force); - -/* ----------------------------------------------------------- dir.c */ - -NTSTATUS NTAPI -FatDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -VOID NTAPI -FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb); - -PFCB NTAPI -FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN FF_FILE *FileHandle); - -IO_STATUS_BLOCK NTAPI -FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB Dcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG CreateDisposition, - IN BOOLEAN NoEaKnowledge, - IN BOOLEAN DeleteOnClose); - -/* -------------------------------------------------------- create.c */ - -IO_STATUS_BLOCK -NTAPI -FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext, - PFILE_OBJECT FileObject, - PFCB Fcb, - ULONG AllocationSize, - PFILE_FULL_EA_INFORMATION EaBuffer, - ULONG EaLength, - UCHAR FileAttributes, - ULONG CreateDisposition, - BOOLEAN NoEaKnowledge); - -NTSTATUS NTAPI -FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp); - - -/* --------------------------------------------------------- close.c */ - -NTSTATUS NTAPI -FatClose(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* ------------------------------------------------------- cleanup.c */ - -NTSTATUS NTAPI -FatCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* --------------------------------------------------------- fastio.c */ - -VOID -FatInitFastIoRoutines(PFAST_IO_DISPATCH FastIoDispatch); - -BOOLEAN NTAPI -FatAcquireForLazyWrite(IN PVOID Context, - IN BOOLEAN Wait); - -VOID NTAPI -FatReleaseFromLazyWrite(IN PVOID Context); - -BOOLEAN NTAPI -FatAcquireForReadAhead(IN PVOID Context, - IN BOOLEAN Wait); - -VOID NTAPI -FatReleaseFromReadAhead(IN PVOID Context); - -BOOLEAN NTAPI -FatNoopAcquire(IN PVOID Context, - IN BOOLEAN Wait); - -VOID NTAPI -FatNoopRelease(IN PVOID Context); - -/* --------------------------------------------------------- fastfat.c */ - -extern FAST_MUTEX FatCloseQueueMutex; - -PFAT_IRP_CONTEXT NTAPI -FatBuildIrpContext(PIRP Irp, BOOLEAN CanWait); - -VOID NTAPI -FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext); - -VOID -NTAPI -FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext, - IN PFAT_OPERATION_HANDLER OperationHandler); - -VOID NTAPI -FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL, - PIRP Irp OPTIONAL, - NTSTATUS Status); - -BOOLEAN NTAPI -FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb); - -BOOLEAN NTAPI -FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb); - -VOID NTAPI -FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb); - -BOOLEAN NTAPI -FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -BOOLEAN NTAPI -FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -VOID NTAPI -FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -TYPE_OF_OPEN -NTAPI -FatDecodeFileObject(IN PFILE_OBJECT FileObject, - OUT PVCB *Vcb, - OUT PFCB *FcbOrDcb, - OUT PCCB *Ccb); - -VOID NTAPI -FatSetFileObject(PFILE_OBJECT FileObject, - TYPE_OF_OPEN TypeOfOpen, - PVOID Fcb, - PCCB Ccb); - -PVOID FASTCALL -FatMapUserBuffer(PIRP Irp); - -BOOLEAN NTAPI -FatIsTopLevelIrp(IN PIRP Irp); - -VOID NTAPI -FatNotifyReportChange(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb, - IN ULONG Filter, - IN ULONG Action); - -/* --------------------------------------------------------- fullfat.c */ - -FF_T_SINT32 -FatWriteBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam); - -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 -FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -VOID NTAPI -FatOplockComplete(IN PVOID Context, - IN PIRP Irp); - -VOID NTAPI -FatPrePostIrp(IN PVOID Context, - IN PIRP Irp); - -/* --------------------------------------------------------- fsctl.c */ - -NTSTATUS NTAPI -FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* --------------------------------------------------------- finfo.c */ - -NTSTATUS NTAPI FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); -NTSTATUS NTAPI FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* --------------------------------------------------------- fullfat.c */ - -FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError); - -/* --------------------------------------------------------- iface.c */ - -NTSTATUS -NTAPI -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); - -/* ----------------------------------------------------------- fat.c */ -NTSTATUS NTAPI -FatInitializeVcb( - IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PVPB Vpb); - -VOID NTAPI -FatUninitializeVcb( - IN PVCB Vcb); - -/* ------------------------------------------------------ device.c */ - -NTSTATUS NTAPI -FatDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -NTSTATUS -FatPerformDevIoCtrl(PDEVICE_OBJECT DeviceObject, - ULONG ControlCode, - PVOID InputBuffer, - ULONG InputBufferSize, - PVOID OutputBuffer, - ULONG OutputBufferSize, - BOOLEAN Override); - -/* ----------------------------------------------------------- fcb.c */ -PFCB NTAPI -FatCreateFcb( - IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN FF_FILE *FileHandle); - -VOID NTAPI -FatDeleteFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -IO_STATUS_BLOCK NTAPI -FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB Fcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG AllocationSize, - IN PFILE_FULL_EA_INFORMATION EaBuffer, - IN ULONG EaLength, - IN UCHAR FileAttributes, - IN ULONG CreateDisposition, - IN BOOLEAN NoEaKnowledge, - IN BOOLEAN DeleteOnClose, - IN BOOLEAN OpenedAsDos, - OUT PBOOLEAN OplockPostIrp); - -PFCB NTAPI -FatFindFcb(PFAT_IRP_CONTEXT IrpContext, - PRTL_SPLAY_LINKS *RootNode, - PSTRING AnsiName, - PBOOLEAN IsDosName); - -VOID NTAPI -FatInsertName(IN PFAT_IRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PFCB_NAME_LINK Name); - -VOID NTAPI -FatRemoveNames(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -PCCB NTAPI -FatCreateCcb(VOID); - -VOID NTAPI -FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PCCB Ccb); - -VOID NTAPI -FatSetFullNameInFcb(PFCB Fcb, - PUNICODE_STRING Name); - -VOID NTAPI -FatSetFullFileNameInFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -VOID NTAPI -FatSetFcbNames(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb); - -VOID NTAPI -Fati8dot3ToString(IN PCHAR FileName, - IN BOOLEAN DownCase, - OUT POEM_STRING OutString); - -/* ------------------------------------------------------------ rw.c */ - -NTSTATUS NTAPI -FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -NTSTATUS NTAPI -FatWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -/* ------------------------------------------------------------- flush.c */ - -NTSTATUS NTAPI -FatFlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp); - - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.rc b/reactos/drivers/filesystems/fastfat_new/fastfat.rc deleted file mode 100644 index 10e3dbd4b22..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "VFAT IFS Driver" -#define REACTOS_STR_INTERNAL_NAME "vfatfs" -#define REACTOS_STR_ORIGINAL_FILENAME "vfatfs.sys" -#include diff --git a/reactos/drivers/filesystems/fastfat_new/fastio.c b/reactos/drivers/filesystems/fastfat_new/fastio.c deleted file mode 100644 index f6044535328..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fastio.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fastio.c - * PURPOSE: Fast IO routines - * PROGRAMMERS: Herve Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -BOOLEAN -NTAPI -FatFastIoCheckIfPossible(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - IN BOOLEAN CheckForReadOperation, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - /* Prevent all Fast I/O requests */ - DPRINT("FatFastIoCheckIfPossible(): returning FALSE.\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoRead(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoRead()\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoWrite(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoWrite()\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - OUT PFILE_BASIC_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoQueryBasicInfo()\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoQueryStandardInfo(IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - OUT PFILE_STANDARD_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoQueryStandardInfo\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoLock(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - BOOLEAN FailImmediately, - BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoLock\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoUnlockSingle(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoUnlockSingle\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoUnlockAll(IN PFILE_OBJECT FileObject, - PEPROCESS ProcessId, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoUnlockAll\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoUnlockAllByKey(IN PFILE_OBJECT FileObject, - PVOID ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoUnlockAllByKey\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatFastIoQueryNetworkOpenInfo\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatMdlRead(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL* MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatMdlRead\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatMdlReadComplete(IN PFILE_OBJECT FileObject, - IN PMDL MdlChain, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatMdlReadComplete\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatPrepareMdlWrite(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL* MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatPrepareMdlWrite\n"); - return FALSE; -} - -BOOLEAN -NTAPI -FatMdlWriteComplete(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatMdlWriteComplete\n"); - return FALSE; -} - -NTSTATUS -NTAPI -FatAcquireForCcFlush(IN PFILE_OBJECT FileObject, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatAcquireForCcFlush\n"); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -FatReleaseForCcFlush(IN PFILE_OBJECT FileObject, - IN PDEVICE_OBJECT DeviceObject) -{ - DPRINT("FatReleaseForCcFlush\n"); - return STATUS_SUCCESS; -} - -BOOLEAN -NTAPI -FatAcquireForLazyWrite(IN PVOID Context, - IN BOOLEAN Wait) -{ - DPRINT("FatAcquireForLazyWrite()\n"); - return FALSE; -} - -VOID -NTAPI -FatReleaseFromLazyWrite(IN PVOID Context) -{ - DPRINT("FatReleaseFromLazyWrite()\n"); -} - -BOOLEAN -NTAPI -FatAcquireForReadAhead(IN PVOID Context, - IN BOOLEAN Wait) -{ - DPRINT("FatAcquireForReadAhead()\n"); - return FALSE; -} - -VOID -NTAPI -FatReleaseFromReadAhead(IN PVOID Context) -{ - DPRINT("FatReleaseFromReadAhead()\n"); -} - -BOOLEAN -NTAPI -FatNoopAcquire(IN PVOID Context, - IN BOOLEAN Wait) -{ - return TRUE; -} - -VOID -NTAPI -FatNoopRelease(IN PVOID Context) -{ -} - - -VOID -FatInitFastIoRoutines(PFAST_IO_DISPATCH FastIoDispatch) -{ - /* Set Fast I/O dispatcher callbacks */ - FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); - FastIoDispatch->FastIoCheckIfPossible = FatFastIoCheckIfPossible; - FastIoDispatch->FastIoRead = FatFastIoRead; - FastIoDispatch->FastIoWrite = FatFastIoWrite; - FastIoDispatch->FastIoQueryBasicInfo = FatFastIoQueryBasicInfo; - FastIoDispatch->FastIoQueryStandardInfo = FatFastIoQueryStandardInfo; - FastIoDispatch->FastIoLock = FatFastIoLock; - FastIoDispatch->FastIoUnlockSingle = FatFastIoUnlockSingle; - FastIoDispatch->FastIoUnlockAll = FatFastIoUnlockAll; - FastIoDispatch->FastIoUnlockAllByKey = FatFastIoUnlockAllByKey; - FastIoDispatch->FastIoQueryNetworkOpenInfo = FatFastIoQueryNetworkOpenInfo; - FastIoDispatch->MdlRead = FatMdlRead; - FastIoDispatch->MdlReadComplete = FatMdlReadComplete; - FastIoDispatch->PrepareMdlWrite = FatPrepareMdlWrite; - FastIoDispatch->MdlWriteComplete = FatMdlWriteComplete; - FastIoDispatch->AcquireForCcFlush = FatAcquireForCcFlush; - FastIoDispatch->ReleaseForCcFlush = FatReleaseForCcFlush; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fat.c b/reactos/drivers/filesystems/fastfat_new/fat.c deleted file mode 100644 index a6ac9fa9995..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fat.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fat.c - * PURPOSE: FAT support routines - * PROGRAMMERS: Aleksey Bragin - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* PROTOTYPES ***************************************************************/ - -BOOLEAN -NTAPI -FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb); - -/* VARIABLES ****************************************************************/ - -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)); -} - -/** - * 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; - - /* Various characteristics needed for navigation in FAT */ - if ((Vcb->Sectors = Vcb->Bpb.Sectors) == 0) - Vcb->Sectors = Vcb->Bpb.LargeSectors; - if ((Vcb->SectorsPerFat = Vcb->Bpb.SectorsPerFat) == 0) - Vcb->SectorsPerFat = Vcb->Bpb.LargeSectorsPerFat; - Vcb->RootDirent = Vcb->Bpb.ReservedSectors + Vcb->Bpb.Fats * Vcb->SectorsPerFat; - Vcb->RootDirentSectors = BytesToSectors(Vcb, - Vcb->Bpb.RootEntries * sizeof(DIR_ENTRY)); - Vcb->DataArea = Vcb->RootDirent + Vcb->RootDirentSectors; - Vcb->Clusters = (Vcb->Sectors - Vcb->Bpb.ReservedSectors - - Vcb->Bpb.Fats * Vcb->SectorsPerFat - - Vcb->RootDirentSectors) / Vcb->Bpb.SectorsPerCluster; - if (Vcb->BytesPerClusterLog < 4087) - { - Vcb->IndexDepth = 0x0c; - //Vcb->Methods = Fat12Methods; - } - else - { - Vcb->IndexDepth = 0x10; - //Vcb->Methods = Fat16Methods; - } - /* Large Sectors are used for FAT32 */ - if (Vcb->Bpb.Sectors == 0) { - Vcb->IndexDepth = 0x20; - //Vcb->Methods = Fat32Methods; - } - ClustersCapacity = (SectorsToBytes(Vcb, Vcb->Sectors) * 0x8 / Vcb->IndexDepth) - 1; - if (Vcb->Clusters > ClustersCapacity) - Vcb->Clusters = ClustersCapacity; - Vcb->BytesPerCluster = SectorsToBytes(Vcb, Vcb->Bpb.SectorsPerCluster); - Vcb->BytesPerClusterLog = FatPowerOfTwo(Vcb->BytesPerCluster); - Vcb->BeyondLastClusterInFat = ((LONGLONG) Vcb->Clusters) * Vcb->IndexDepth / 0x8; - - /* Update real volume size with the real value. */ - Vcb->Header.FileSize.QuadPart = - Vcb->Header.AllocationSize.QuadPart = SectorsToBytes(Vcb, Vcb->Sectors); -} - -NTSTATUS -NTAPI -FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PVPB Vpb) -{ - NTSTATUS Status; - PBCB Bcb; - PVOID Buffer; - LARGE_INTEGER Offset; - - RtlZeroMemory(Vcb, sizeof(*Vcb)); - - /* Initialize list head, so that it will - * not fail in cleanup. - */ - InitializeListHead(&Vcb->VcbLinks); - - /* Setup FCB Header */ - Vcb->Header.NodeTypeCode = FAT_NTC_VCB; - Vcb->Header.NodeByteSize = sizeof(*Vcb); - - /* Setup Vcb fields */ - Vcb->TargetDeviceObject = TargetDeviceObject; - ObReferenceObject(TargetDeviceObject); - Vcb->Vpb = Vpb; - - /* Setup FCB Header */ - ExInitializeFastMutex(&Vcb->HeaderMutex); - FsRtlSetupAdvancedHeader(&Vcb->Header, &Vcb->HeaderMutex); - - /* Create Volume File Object */ - Vcb->StreamFileObject = IoCreateStreamFileObject(NULL, - Vcb->TargetDeviceObject); - - /* We have to setup all FCB fields needed for CC */ - Vcb->StreamFileObject->FsContext = Vcb; - Vcb->StreamFileObject->SectionObjectPointer = &Vcb->SectionObjectPointers; - - /* At least full boot sector should be available */ - //Vcb->Header.FileSize.QuadPart = sizeof(PACKED_BOOT_SECTOR); - //Vcb->Header.AllocationSize.QuadPart = sizeof(PACKED_BOOT_SECTOR); - Vcb->Header.ValidDataLength.HighPart = MAXLONG; - Vcb->Header.ValidDataLength.LowPart = MAXULONG; - - Vcb->Header.AllocationSize.QuadPart = Int32x32To64(5*1024, 1024*1024); //HACK: 5 Gb - Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; - - /* Set VCB to a good condition */ - Vcb->Condition = VcbGood; - - /* Initialize VCB's resource */ - ExInitializeResourceLite(&Vcb->Resource); - - /* Initialize close queue lists */ - InitializeListHead(&Vcb->AsyncCloseList); - InitializeListHead(&Vcb->DelayedCloseList); - - /* Initialize CC */ - CcInitializeCacheMap(Vcb->StreamFileObject, - (PCC_FILE_SIZES)&Vcb->Header.AllocationSize, - FALSE, - &FatGlobalData.CacheMgrNoopCallbacks, - Vcb); - - /* Read boot sector */ - Offset.QuadPart = 0; - Bcb = NULL; - - /* Note: Volume Read path does not require - * any of the parameters set further - * in this routine. - */ - if (CcMapData(Vcb->StreamFileObject, - &Offset, - sizeof(PACKED_BOOT_SECTOR), - TRUE, - &Bcb, - &Buffer)) - { - PPACKED_BOOT_SECTOR BootSector = (PPACKED_BOOT_SECTOR) Buffer; - FatUnpackBios(&Vcb->Bpb, &BootSector->PackedBpb); - if (!(FatBootSectorJumpValid(BootSector->Jump) && - FatValidBpb(&Vcb->Bpb))) - { - Status = STATUS_UNRECOGNIZED_VOLUME; - } - CopyUchar4(&Vcb->Vpb->SerialNumber, BootSector->Id); - CcUnpinData(Bcb); - } - else - { - Status = STATUS_UNRECOGNIZED_VOLUME; - goto FatInitializeVcbCleanup; - } - - /* Increase internal / residual open counter */ - InterlockedIncrement((PLONG)&(Vcb->InternalOpenCount)); - InterlockedIncrement((PLONG)&(Vcb->ResidualOpenCount)); - - /* Set up notifications */ - FsRtlNotifyInitializeSync(&Vcb->NotifySync); - InitializeListHead(&Vcb->NotifyList); - - /* Call helper function */ - FatiInitializeVcb(Vcb); - - /* Add this Vcb to global Vcb list */ - (VOID)FatAcquireExclusiveGlobal(IrpContext); - InsertTailList(&FatGlobalData.VcbListHead, &Vcb->VcbLinks); - FatReleaseGlobal(IrpContext); - - return STATUS_SUCCESS; - -FatInitializeVcbCleanup: - - /* Unwind the routine actions */ - FatUninitializeVcb(Vcb); - return Status; -} - -VOID -NTAPI -FatUninitializeVcb(IN PVCB Vcb) -{ - LARGE_INTEGER ZeroSize; - - ZeroSize.QuadPart = 0LL; - - /* Close volume file */ - if (Vcb->StreamFileObject != NULL) - { - /* Uninitialize CC. */ - CcUninitializeCacheMap(Vcb->StreamFileObject, &ZeroSize, NULL); - ObDereferenceObject(Vcb->StreamFileObject); - Vcb->StreamFileObject = NULL; - } - - /* Free ContextClose if it's not freed up already */ - if (Vcb->CloseContext) ExFreePool(Vcb->CloseContext); - - /* Free notifications stuff */ - FsRtlNotifyUninitializeSync(&Vcb->NotifySync); - - /* Unlink from global Vcb list. */ - RemoveEntryList(&Vcb->VcbLinks); - - /* Release Target Device */ - ObDereferenceObject(Vcb->TargetDeviceObject); - Vcb->TargetDeviceObject = NULL; -} - -/* EOF */ - - diff --git a/reactos/drivers/filesystems/fastfat_new/fat.h b/reactos/drivers/filesystems/fastfat_new/fat.h deleted file mode 100644 index 222755df5a1..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fat.h +++ /dev/null @@ -1,289 +0,0 @@ -#pragma once - -// -// Might be a good idea to have this as a shared -// header with FS Recognizer. -// -// -// Conversion types and macros taken from internal ntifs headers -// -typedef union _UCHAR1 -{ - UCHAR Uchar[1]; - UCHAR ForceAlignment; -} UCHAR1, *PUCHAR1; - -typedef union _UCHAR2 -{ - UCHAR Uchar[2]; - USHORT ForceAlignment; -} UCHAR2, *PUCHAR2; - -typedef union _UCHAR4 -{ - UCHAR Uchar[4]; - ULONG ForceAlignment; -} UCHAR4, *PUCHAR4; - -#define CopyUchar1(Dst,Src) { \ - *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ -} - -#define CopyUchar2(Dst,Src) { \ - *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ -} - -#define CopyUchar4(Dst,Src) { \ - *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \ -} - -#define FatUnpackBios(Bios,Pbios) { \ - CopyUchar2(&(Bios)->BytesPerSector, &(Pbios)->BytesPerSector[0] ); \ - CopyUchar1(&(Bios)->SectorsPerCluster, &(Pbios)->SectorsPerCluster[0]); \ - CopyUchar2(&(Bios)->ReservedSectors, &(Pbios)->ReservedSectors[0] ); \ - CopyUchar1(&(Bios)->Fats, &(Pbios)->Fats[0] ); \ - CopyUchar2(&(Bios)->RootEntries, &(Pbios)->RootEntries[0] ); \ - CopyUchar2(&(Bios)->Sectors, &(Pbios)->Sectors[0] ); \ - CopyUchar1(&(Bios)->Media, &(Pbios)->Media[0] ); \ - CopyUchar2(&(Bios)->SectorsPerFat, &(Pbios)->SectorsPerFat[0] ); \ - CopyUchar2(&(Bios)->SectorsPerTrack, &(Pbios)->SectorsPerTrack[0] ); \ - CopyUchar2(&(Bios)->Heads, &(Pbios)->Heads[0] ); \ - CopyUchar4(&(Bios)->HiddenSectors, &(Pbios)->HiddenSectors[0] ); \ - CopyUchar4(&(Bios)->LargeSectors, &(Pbios)->LargeSectors[0] ); \ - CopyUchar4(&(Bios)->LargeSectors, &(Pbios)->LargeSectors[0] ); \ - CopyUchar4(&(Bios)->LargeSectorsPerFat,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->LargeSectorsPerFat[0] ); \ - CopyUchar2(&(Bios)->ExtendedFlags, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->ExtendedFlags[0] ); \ - CopyUchar2(&(Bios)->FsVersion, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->FsVersion[0] ); \ - CopyUchar4(&(Bios)->RootDirFirstCluster, \ - &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->RootDirFirstCluster[0] ); \ - CopyUchar2(&(Bios)->FsInfoSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->FsInfoSector[0] ); \ - CopyUchar2(&(Bios)->BackupBootSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->BackupBootSector[0] ); \ -} -// -// Packed versions of the BPB and Boot Sector -// -typedef struct _PACKED_BIOS_PARAMETER_BLOCK -{ - UCHAR BytesPerSector[2]; - UCHAR SectorsPerCluster[1]; - UCHAR ReservedSectors[2]; - UCHAR Fats[1]; - UCHAR RootEntries[2]; - UCHAR Sectors[2]; - UCHAR Media[1]; - UCHAR SectorsPerFat[2]; - UCHAR SectorsPerTrack[2]; - UCHAR Heads[2]; - UCHAR HiddenSectors[4]; - UCHAR LargeSectors[4]; -} PACKED_BIOS_PARAMETER_BLOCK, *PPACKED_BIOS_PARAMETER_BLOCK; -// sizeof = 0x019 - -typedef struct _PACKED_BIOS_PARAMETER_BLOCK_EX -{ - PACKED_BIOS_PARAMETER_BLOCK Block; - UCHAR LargeSectorsPerFat[4]; - UCHAR ExtendedFlags[2]; - UCHAR FsVersion[2]; - UCHAR RootDirFirstCluster[4]; - UCHAR FsInfoSector[2]; - UCHAR BackupBootSector[2]; - UCHAR Reserved[12]; -} PACKED_BIOS_PARAMETER_BLOCK_EX, *PPACKED_BIOS_PARAMETER_BLOCK_EX; -// sizeof = 0x035 53 - -// -// Unpacked version of the BPB -// -typedef struct BIOS_PARAMETER_BLOCK -{ - USHORT BytesPerSector; - UCHAR SectorsPerCluster; - USHORT ReservedSectors; - UCHAR Fats; - USHORT RootEntries; - USHORT Sectors; - UCHAR Media; - USHORT SectorsPerFat; - USHORT SectorsPerTrack; - USHORT Heads; - ULONG HiddenSectors; - ULONG LargeSectors; - ULONG LargeSectorsPerFat; - union - { - USHORT ExtendedFlags; - struct - { - ULONG ActiveFat:4; - ULONG Reserved0:3; - ULONG MirrorDisabled:1; - ULONG Reserved1:8; - }; - }; - USHORT FsVersion; - ULONG RootDirFirstCluster; - USHORT FsInfoSector; - USHORT BackupBootSector; -} BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK; - -#define FatValidBytesPerSector(xBytes) \ - (!((xBytes) & ((xBytes)-1)) && (xBytes)>=0x80 && (xBytes)<=0x1000) - -#define FatValidSectorsPerCluster(xSectors) \ - (!((xSectors) & ((xSectors)-1)) && (xSectors)>0 && (xSectors)<=0x80) - -typedef struct _PACKED_BOOT_SECTOR -{ - UCHAR Jump[3]; - UCHAR Oem[8]; - PACKED_BIOS_PARAMETER_BLOCK PackedBpb; - UCHAR PhysicalDriveNumber; - UCHAR CurrentHead; - UCHAR Signature; - UCHAR Id[4]; - UCHAR VolumeLabel[11]; - UCHAR SystemId[8]; -} PACKED_BOOT_SECTOR, *PPACKED_BOOT_SECTOR; -// sizeof = 0x03E - -typedef struct _PACKED_BOOT_SECTOR_EX -{ - UCHAR Jump[3]; - UCHAR Oem[8]; - PACKED_BIOS_PARAMETER_BLOCK_EX PackedBpb; - UCHAR PhysicalDriveNumber; - UCHAR CurrentHead; - UCHAR Signature; - UCHAR Id[4]; - UCHAR VolumeLabel[11]; - UCHAR SystemId[8]; -} PACKED_BOOT_SECTOR_EX, *PPACKED_BOOT_SECTOR_EX; -// sizeof = 0x060 - -#define FatBootSectorJumpValid(xMagic) \ - ((xMagic)[0] == 0xe9 || (xMagic)[0] == 0xeb || (xMagic)[0] == 0x49) - -typedef struct _FSINFO_SECTOR -{ - ULONG SectorBeginSignature; - UCHAR Reserved[480]; - ULONG FsInfoSignature; - ULONG FreeClusterCount; - ULONG NextFreeCluster; - UCHAR Reserved0[12]; - ULONG SectorEndSignature; -} FSINFO_SECTOR, *PFSINFO_SECTOR; -// sizeof = 0x200 -#define FSINFO_SECTOR_BEGIN_SIGNATURE 0x41615252 -#define FSINFO_SECTOR_END_SIGNATURE 0xaa550000 -#define FSINFO_SIGNATURE 0x61417272 -// -// Cluster Markers: -// -#define FAT_CLUSTER_AVAILABLE 0x00000000 -#define FAT_CLUSTER_RESERVED 0x0ffffff0 -#define FAT_CLUSTER_BAD 0x0ffffff7 -#define FAT_CLUSTER_LAST 0x0fffffff -// -// Directory Structure: -// -typedef struct _FAT_TIME -{ - union { - struct { - USHORT DoubleSeconds : 5; - USHORT Minute : 6; - USHORT Hour : 5; - }; - USHORT Value; - }; -} FAT_TIME, *PFAT_TIME; -// -// -// -typedef struct _FAT_DATE { - union { - struct { - USHORT Day : 5; - USHORT Month : 4; - /* Relative to 1980 */ - USHORT Year : 7; - }; - USHORT Value; - }; -} FAT_DATE, *PFAT_DATE; -// -// -// -typedef struct _FAT_DATETIME { - union { - struct { - FAT_TIME Time; - FAT_DATE Date; - }; - ULONG Value; - }; -} FAT_DATETIME, *PFAT_DATETIME; -// -// -// -typedef struct _DIR_ENTRY -{ - UCHAR FileName[11]; - UCHAR Attributes; - UCHAR Case; - UCHAR CreationTimeTenMs; - FAT_DATETIME CreationDateTime; - FAT_DATE LastAccessDate; - union { - USHORT ExtendedAttributes; - USHORT FirstClusterOfFileHi; - }; - FAT_DATETIME LastWriteDateTime; - USHORT FirstCluster; - ULONG FileSize; -} DIR_ENTRY, *PDIR_ENTRY; -// sizeof = 0x020 - -typedef struct _LONG_FILE_NAME_ENTRY { - UCHAR SeqNum; - UCHAR NameA[10]; - UCHAR Attributes; - UCHAR Type; - UCHAR Checksum; - USHORT NameB[6]; - USHORT Reserved; - USHORT NameC[2]; -} LONG_FILE_NAME_ENTRY, *PLONG_FILE_NAME_ENTRY; -// sizeof = 0x020 - -#define FAT_LFN_NAME_LENGTH \ - (RTL_FIELD_SIZE(LONG_FILE_NAME_ENTRY, NameA) \ - + RTL_FIELD_SIZE(LONG_FILE_NAME_ENTRY, NameB) \ - + RTL_FIELD_SIZE(LONG_FILE_NAME_ENTRY, NameC)) - -#define FAT_FN_DIR_ENTRY_LAST 0x40 -#define FAT_FN_MAX_DIR_ENTIES 0x14 - -#define FAT_BYTES_PER_DIRENT 0x20 -#define FAT_BYTES_PER_DIRENT_LOG 0x05 -#define FAT_DIRENT_NEVER_USED 0x00 -#define FAT_DIRENT_REALLY_0E5 0x05 -#define FAT_DIRENT_DIRECTORY_ALIAS 0x2e -#define FAT_DIRENT_DELETED 0xe5 - -#define FAT_CASE_LOWER_BASE 0x08 -#define FAT_CASE_LOWER_EXT 0x10 - -#define FAT_DIRENT_ATTR_READ_ONLY 0x01 -#define FAT_DIRENT_ATTR_HIDDEN 0x02 -#define FAT_DIRENT_ATTR_SYSTEM 0x04 -#define FAT_DIRENT_ATTR_VOLUME_ID 0x08 -#define FAT_DIRENT_ATTR_DIRECTORY 0x10 -#define FAT_DIRENT_ATTR_ARCHIVE 0x20 -#define FAT_DIRENT_ATTR_DEVICE 0x40 -#define FAT_DIRENT_ATTR_LFN (FAT_DIRENT_ATTR_READ_ONLY | \ - FAT_DIRENT_ATTR_HIDDEN | \ - FAT_DIRENT_ATTR_SYSTEM | \ - FAT_DIRENT_ATTR_VOLUME_ID) diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h deleted file mode 100644 index 9ad1f50b02f..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ /dev/null @@ -1,453 +0,0 @@ -#pragma once - -typedef struct _FAT_SCAN_CONTEXT *PFAT_SCAN_CONTEXT; -typedef struct _FAT_IO_CONTEXT *PFAT_IO_CONTEXT; -typedef struct _FAT_IRP_CONTEXT *PFAT_IRP_CONTEXT; -typedef PVOID PBCB; - -typedef NTSTATUS (*PFAT_OPERATION_HANDLER) (PFAT_IRP_CONTEXT); - -/* Node type stuff */ -typedef CSHORT FAT_NODE_TYPE; -typedef FAT_NODE_TYPE *PFAT_NODE_TYPE; - -#define FatNodeType(Ptr) (*((PFAT_NODE_TYPE)(Ptr))) - -/* Node type codes */ -#define FAT_NTC_VCB (CSHORT) '00VF' -#define FAT_NTC_FCB (CSHORT) 'CF' -#define FAT_NTC_DCB (CSHORT) 'DF' -#define FAT_NTC_ROOT_DCB (CSHORT) 'RFD' -#define FAT_NTC_CCB (CSHORT) 'BCC' -#define FAT_NTC_IRP_CONTEXT (CSHORT) 'PRI' - -typedef struct _FAT_GLOBAL_DATA -{ - ERESOURCE Resource; - PEPROCESS SystemProcess; - PDRIVER_OBJECT DriverObject; - PDEVICE_OBJECT DiskDeviceObject; - LIST_ENTRY VcbListHead; - NPAGED_LOOKASIDE_LIST NonPagedFcbList; - NPAGED_LOOKASIDE_LIST ResourceList; - NPAGED_LOOKASIDE_LIST IrpContextList; - FAST_IO_DISPATCH FastIoDispatch; - CACHE_MANAGER_CALLBACKS CacheMgrCallbacks; - CACHE_MANAGER_CALLBACKS CacheMgrNoopCallbacks; - BOOLEAN Win31FileSystem; - BOOLEAN ShutdownStarted; - /* Jan 1, 1980 System Time */ - LARGE_INTEGER DefaultFileTime; - - /* Queued close */ - ULONG AsyncCloseCount; - ULONG DelayedCloseCount; - LIST_ENTRY AsyncCloseList; - LIST_ENTRY DelayedCloseList; - PIO_WORKITEM FatCloseItem; - - /* Various flags */ - BOOLEAN AsyncCloseActive; - - /* FullFAT integration */ - FF_IOMAN *Ioman; - FF_ERROR FF_Error; -} FAT_GLOBAL_DATA; - -typedef struct _FAT_PAGE_CONTEXT -{ - PFILE_OBJECT FileObject; - LARGE_INTEGER EndOfData; - LARGE_INTEGER Offset; - LARGE_INTEGER EndOfPage; - SIZE_T ValidLength; - PVOID Buffer; - PBCB Bcb; - BOOLEAN CanWait; -} FAT_PAGE_CONTEXT, *PFAT_PAGE_CONTEXT; - -#define FatPinSetupContext(xContext, xFcb, CanWait) \ -{ \ - (xContext)->FileObject = (xFcb)->StreamFileObject; \ - (xContext)->EndOfData = (xFcb)->Header.FileSize; \ - (xContext)->Offset.QuadPart = -1LL; \ - (xContext)->Bcb = NULL; \ - (xContext)->CanWait = CanWait; \ -} - -#define FatPinCleanupContext(xContext) \ - if ((xContext)->Bcb != NULL) { \ - CcUnpinData((xContext)->Bcb); \ - (xContext)->Bcb = NULL; \ - } \ - -#define FatPinEndOfPage(xContext, xType) \ - Add2Ptr((xContext)->Buffer, (xContext)->ValidLength, xType) - -#define FatPinIsLastPage(xContext) \ - ((xContext)->ValidLength != PAGE_SIZE) - -#define IRPCONTEXT_CANWAIT 0x0001 -#define IRPCONTEXT_PENDINGRETURNED 0x0002 -#define IRPCONTEXT_STACK_IO_CONTEXT 0x0004 -#define IRPCONTEXT_WRITETHROUGH 0x0008 -#define IRPCONTEXT_TOPLEVEL 0x0010 - -typedef struct _FAT_IRP_CONTEXT -{ - /* Type and size of this record (must be FAT_NTC_IRP_CONTEXT) */ - FAT_NODE_TYPE NodeTypeCode; - CSHORT NodeByteSize; - - PIRP Irp; - PDEVICE_OBJECT DeviceObject; - UCHAR MajorFunction; - UCHAR MinorFunction; - PFILE_OBJECT FileObject; - ULONG Flags; - struct _VCB *Vcb; - ULONG PinCount; - FAT_PAGE_CONTEXT Page; - struct _FAT_IO_CONTEXT *FatIoContext; - WORK_QUEUE_ITEM WorkQueueItem; - PFAT_OPERATION_HANDLER QueuedOperationHandler; - PIO_STACK_LOCATION Stack; - KEVENT Event; -} FAT_IRP_CONTEXT; - -typedef struct _FAT_IO_CONTEXT -{ - PMDL ZeroMdl; - PIRP Irp; - LONG RunCount; - SIZE_T Length; - LONGLONG Offset; - PFILE_OBJECT FileObject; - - union - { - struct - { - PERESOURCE Resource; - PERESOURCE PagingIoResource; - ERESOURCE_THREAD ResourceThreadId; - } Async; - KEVENT SyncEvent; - } Wait; - PIRP AssociatedIrp[0]; -} FAT_IO_CONTEXT; - -typedef ULONG (*PFAT_SCANFAT_FOR_CONTINOUS_RUN_ROUTINE) (PFAT_PAGE_CONTEXT, PULONG, BOOLEAN); -typedef ULONG (*PFAT_SETFAT_CONTINOUS_RUN_ROUTINE) (PFAT_PAGE_CONTEXT, ULONG, ULONG, BOOLEAN); -typedef ULONG (*PFAT_SCANFAT_FOR_VALUE_RUN_ROUTINE) (PFAT_PAGE_CONTEXT, PULONG, ULONG, BOOLEAN); -typedef ULONG (*PFAT_SETFAT_VALUE_RUN_ROUTINE) (PFAT_PAGE_CONTEXT, ULONG, ULONG, ULONG, BOOLEAN); - -typedef struct _FAT_METHODS { - PFAT_SCANFAT_FOR_CONTINOUS_RUN_ROUTINE ScanContinousRun; - PFAT_SETFAT_CONTINOUS_RUN_ROUTINE SetContinousRun; - PFAT_SCANFAT_FOR_VALUE_RUN_ROUTINE ScanValueRun; - PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun; -} FAT_METHODS, *PFAT_METHODS; - -#define VCB_STATE_FLAG_LOCKED 0x001 -#define VCB_STATE_FLAG_DIRTY 0x002 -#define VCB_STATE_MOUNTED_DIRTY 0x004 -#define VCB_STATE_CREATE_IN_PROGRESS 0x008 -#define VCB_STATE_FLAG_CLOSE_IN_PROGRESS 0x010 -#define VCB_STATE_FLAG_DELETED_FCB 0x020 -#define VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS 0x040 -#define VCB_STATE_FLAG_DEFERRED_FLUSH 0x080 -#define VCB_STATE_FLAG_WRITE_PROTECTED 0x100 - -typedef enum _VCB_CONDITION -{ - VcbGood, - VcbNotMounted, - VcbBad -} VCB_CONDITION; - -/* Volume Control Block */ -typedef struct _VCB -{ - FSRTL_ADVANCED_FCB_HEADER Header; - FAST_MUTEX HeaderMutex; - SECTION_OBJECT_POINTERS SectionObjectPointers; - - PFILE_OBJECT StreamFileObject; - PDEVICE_OBJECT TargetDeviceObject; - LIST_ENTRY VcbLinks; - PVPB Vpb; - ULONG State; - VCB_CONDITION Condition; - ERESOURCE Resource; - struct _CLOSE_CONTEXT *CloseContext; - LIST_ENTRY AsyncCloseList; - LIST_ENTRY DelayedCloseList; - - /* Direct volume access */ - SHARE_ACCESS ShareAccess; - PFILE_OBJECT FileObjectWithVcbLocked; - - /* Notifications support */ - PNOTIFY_SYNC NotifySync; - LIST_ENTRY NotifyList; - - /* Volume Characteristics: */ - ULONG SerialNumber; - BIOS_PARAMETER_BLOCK Bpb; - ULONG BytesPerClusterLog; - ULONG BytesPerCluster; - ULONG SectorsPerFat; - ULONG DataArea; - ULONG Sectors; - ULONG Clusters; - ULONG IndexDepth; - ULONG RootDirent; - ULONG RootDirentSectors; - LONGLONG BeyondLastClusterInFat; - FAT_METHODS Methods; - - /* Root Directory Control block */ - struct _FCB *RootDcb; - - /* Counters */ - ULONG DirectOpenCount; - ULONG OpenFileCount; - ULONG ReadOnlyCount; - ULONG InternalOpenCount; - ULONG ResidualOpenCount; - ULONG DirectAccessOpenCount; - ULONG MediaChangeCount; - - /* FullFAT integration */ - FF_IOMAN *Ioman; -} VCB, *PVCB; - -#define VcbToVolumeDeviceObject(xVcb) \ - CONTAINING_RECORD((xVcb), VOLUME_DEVICE_OBJECT, Vcb)) - -#define VcbToDeviceObject(xVcb) \ - &(VcbToVolumeDeviceObject(xVcb)->DeviceObject) - - -#define SectorsToBytes(xVcb, xSectrors) \ - ((xVcb)->Bpb.BytesPerSector * (xSectrors)) - -#define BytesToSectors(xVcb, xBytes) \ - ((xBytes + (xVcb)->Bpb.BytesPerSector - 1) / (xVcb)->Bpb.BytesPerSector) - -#define SectorsToClusters(xVcb, xSectors) \ - ((xSectors + (xVcb)->Bpb.SectorsPerCluster - 1) / (xVcb)->Bpb.SectorsPerCluster) - -#define VCB_FAT_BITMAP_SIZE 0x10000 -#define VcbFatBitmapIndex(xCluster) ((xCluster)/VCB_FAT_BITMAP_SIZE) - -/* Volume Device Object */ -typedef struct _VOLUME_DEVICE_OBJECT -{ - DEVICE_OBJECT DeviceObject; - union { - FSRTL_COMMON_FCB_HEADER VolumeHeader; - VCB Vcb; /* Must be the last entry! */ - }; -} VOLUME_DEVICE_OBJECT, *PVOLUME_DEVICE_OBJECT; - -typedef enum _TYPE_OF_OPEN -{ - UnopenedFileObject, - UserFileOpen, - UserDirectoryOpen, - UserVolumeOpen, - VirtualVolumeFile, - DirectoryFile, - EaFile -} TYPE_OF_OPEN; - -// -// Short name always exists in FAT -// -enum _FCB_NAME_TYPE { - FcbShortName = 0x0, - FcbLongName -} FCB_NAME_TYPE; - -typedef struct _FCB_NAME_LINK { - struct _FCB *Fcb; - RTL_SPLAY_LINKS Links; - union - { - OEM_STRING Ansi; - UNICODE_STRING String; - } Name; - BOOLEAN IsDosName; -} FCB_NAME_LINK, *PFCB_NAME_LINK; - -typedef enum _FCB_CONDITION -{ - FcbGood, - FcbBad, - FcbNeedsToBeVerified -} FCB_CONDITION; - -#define FCB_STATE_HAS_NAMES 0x01 -#define FCB_STATE_HAS_UNICODE_NAME 0x02 -#define FCB_STATE_PAGEFILE 0x04 -#define FCB_STATE_DELAY_CLOSE 0x08 -#define FCB_STATE_TRUNCATE_ON_CLOSE 0x10 -#define FCB_STATE_DELETE_ON_CLOSE 0x20 - -typedef struct _FCB -{ - FSRTL_ADVANCED_FCB_HEADER Header; - /* - * Later we might want to move the next four fields - * into a separate structureif we decide to split - * FCB into paged and non paged parts - * (as it is done in MS implementation - */ - FAST_MUTEX HeaderMutex; // nonpaged! - SECTION_OBJECT_POINTERS SectionObjectPointers; - ERESOURCE Resource; // nonpaged! - ERESOURCE PagingIoResource; // nonpaged! - - /* First cluster in the fat allocation chain */ - ULONG FirstClusterOfFile; - /* A list of all FCBs of that DCB */ - LIST_ENTRY ParentDcbLinks; - /* Reference to the Parent Dcb*/ - struct _FCB *ParentFcb; - /* Pointer to a Vcb */ - PVCB Vcb; - /* Fcb state */ - ULONG State; - /* Fcb condition */ - FCB_CONDITION Condition; - /* Share access */ - SHARE_ACCESS ShareAccess; - ULONG FirstCluster; - /* Links into FCB Tree */ - FCB_NAME_LINK ShortName; - FCB_NAME_LINK LongName; - /* Buffer for the short name */ - CHAR ShortNameBuffer[0xc]; - /* Full file name */ - UNICODE_STRING FullFileName; - /* Long name with exact case */ - UNICODE_STRING ExactCaseLongName; - /* Hint for the filename length */ - ULONG FileNameLength; - /* A copy of fat attribute byte */ - UCHAR DirentFatFlags; - /* File basic info */ - FILE_BASIC_INFORMATION BasicInfo; - /* FullFAT file handle */ - FF_FILE *FatHandle; - /* The file has outstanding async writes */ - ULONG OutstandingAsyncWrites; - /* The outstanding async writes sync event */ - PKEVENT OutstandingAsyncEvent; - /* Counters */ - ULONG OpenCount; - ULONG UncleanCount; - ULONG NonCachedUncleanCount; - union - { - struct - { - /* File and Op locks */ - FILE_LOCK Lock; - OPLOCK Oplock; - } Fcb; - - struct - { - LIST_ENTRY ParentDcbList; /* A list of all FCBs/DCBs opened under this DCB */ - ULONG DirectoryFileOpenCount; /* Sector-based access to the dir */ - PFILE_OBJECT DirectoryFile; - /* Directory data stream (just handy to have it). */ - //PFILE_OBJECT StreamFileObject; - /* Names */ - PRTL_SPLAY_LINKS SplayLinksAnsi; - PRTL_SPLAY_LINKS SplayLinksUnicode; - } Dcb; - }; -} FCB, *PFCB; - -typedef struct _FAT_ENUM_DIRENT_CONTEXT *PFAT_ENUM_DIRENT_CONTEXT; -typedef struct _FAT_ENUM_DIR_CONTEXT *PFAT_ENUM_DIR_CONTEXT; - -typedef ULONG (*PFAT_COPY_DIRENT_ROUTINE) (PFAT_ENUM_DIR_CONTEXT, PDIR_ENTRY, PVOID); - -typedef struct _FAT_ENUM_DIRENT_CONTEXT -{ - FAT_PAGE_CONTEXT Page; - - /* Copy dirent to dirinfo */ - PFAT_COPY_DIRENT_ROUTINE CopyDirent; - LONGLONG BytesPerClusterMask; - - /* Info buffer characteristics */ - PVOID Buffer; - SIZE_T Offset; - SIZE_T Length; - - /* Criteria */ - PUNICODE_STRING FileName; - UCHAR CcbFlags; - - /* Lfn buffer/length offsets */ - ULONG LengthOffset; - ULONG NameOffset; -} FAT_ENUM_DIRENT_CONTEXT; - -typedef struct _FAT_FIND_DIRENT_CONTEXT -{ - FAT_PAGE_CONTEXT Page; - UNICODE_STRING ShortName; - WCHAR ShortNameBuffer[0x18]; - /* Criteria */ - PUNICODE_STRING FileName; - BOOLEAN Valid8dot3Name; -} FAT_FIND_DIRENT_CONTEXT, *PFAT_FIND_DIRENT_CONTEXT; - -typedef struct _CLOSE_CONTEXT -{ - LIST_ENTRY GlobalLinks; - LIST_ENTRY VcbLinks; - - PVCB Vcb; - PFCB Fcb; - TYPE_OF_OPEN TypeOfOpen; - BOOLEAN Free; -} CLOSE_CONTEXT, *PCLOSE_CONTEXT; - -typedef struct _CCB -{ - CSHORT NodeTypeCode; - CSHORT NodeByteSize; - - LARGE_INTEGER CurrentByteOffset; - ULONG Entry; - UNICODE_STRING SearchPattern; - UCHAR Flags; - CLOSE_CONTEXT CloseContext; -} CCB, *PCCB; - -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 -#define CCB_DASD_IO 0x08 -#define CCB_READ_ONLY 0x10 -#define CCB_DELETE_ON_CLOSE 0x20 -#define CCB_COMPLETE_DISMOUNT 0x40 -#define CCB_CLOSE_CONTEXT 0x80 - -extern FAT_GLOBAL_DATA FatGlobalData; diff --git a/reactos/drivers/filesystems/fastfat_new/fcb.c b/reactos/drivers/filesystems/fastfat_new/fcb.c deleted file mode 100644 index eeb12dd8c17..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fcb.c +++ /dev/null @@ -1,1095 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fcb.c - * PURPOSE: FCB manipulation routines. - * PROGRAMMERS: Aleksey Bragin - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -#define TAG_FILENAME 'fBnF' - -/* FUNCTIONS ****************************************************************/ - -FSRTL_COMPARISON_RESULT -NTAPI -FatiCompareNames(PSTRING NameA, - PSTRING NameB) -{ - ULONG MinimumLen, i; - - /* Calc the minimum length */ - MinimumLen = NameA->Length < NameB->Length ? NameA->Length : - NameB->Length; - - /* Actually compare them */ - i = (ULONG)RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinimumLen ); - - if (i < MinimumLen) - { - /* Compare prefixes */ - if (NameA->Buffer[i] < NameB->Buffer[i]) - return LessThan; - else - return GreaterThan; - } - - /* Final comparison */ - if (NameA->Length < NameB->Length) - return LessThan; - else if (NameA->Length > NameB->Length) - return GreaterThan; - else - return EqualTo; -} - -PFCB -NTAPI -FatFindFcb(PFAT_IRP_CONTEXT IrpContext, - PRTL_SPLAY_LINKS *RootNode, - PSTRING AnsiName, - PBOOLEAN IsDosName) -{ - PFCB_NAME_LINK Node; - FSRTL_COMPARISON_RESULT Comparison; - PRTL_SPLAY_LINKS Links; - - Links = *RootNode; - - while (Links) - { - Node = CONTAINING_RECORD(Links, FCB_NAME_LINK, Links); - - /* Compare the prefix */ - if (*(PUCHAR)Node->Name.Ansi.Buffer != *(PUCHAR)AnsiName->Buffer) - { - if (*(PUCHAR)Node->Name.Ansi.Buffer < *(PUCHAR)AnsiName->Buffer) - Comparison = LessThan; - else - Comparison = GreaterThan; - } - else - { - /* Perform real comparison */ - Comparison = FatiCompareNames(&Node->Name.Ansi, AnsiName); - } - - /* Do they match? */ - if (Comparison == GreaterThan) - { - /* No, it's greater, go to the left child */ - Links = RtlLeftChild(Links); - } - else if (Comparison == LessThan) - { - /* No, it's lesser, go to the right child */ - Links = RtlRightChild(Links); - } - else - { - /* Exact match, balance the tree */ - *RootNode = RtlSplay(Links); - - /* Save type of the name, if needed */ - if (IsDosName) - *IsDosName = Node->IsDosName; - - /* Return the found fcb */ - return Node->Fcb; - } - } - - /* Nothing found */ - return NULL; -} - -PFCB -NTAPI -FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB ParentDcb, - IN FF_FILE *FileHandle) -{ - PFCB Fcb; - - /* Allocate it and zero it */ - Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); - RtlZeroMemory(Fcb, sizeof(FCB)); - - /* Set node types */ - Fcb->Header.NodeTypeCode = FAT_NTC_FCB; - Fcb->Header.NodeByteSize = sizeof(FCB); - Fcb->Condition = FcbGood; - - /* Initialize resources */ - Fcb->Header.Resource = &Fcb->Resource; - ExInitializeResourceLite(Fcb->Header.Resource); - - Fcb->Header.PagingIoResource = &Fcb->PagingIoResource; - ExInitializeResourceLite(Fcb->Header.PagingIoResource); - - /* Initialize mutexes */ - Fcb->Header.FastMutex = &Fcb->HeaderMutex; - ExInitializeFastMutex(&Fcb->HeaderMutex); - FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); - - /* Insert into parent's DCB list */ - InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks); - - /* Set backlinks */ - Fcb->ParentFcb = ParentDcb; - Fcb->Vcb = Vcb; - - /* Set file handle and sizes */ - Fcb->Header.FileSize.LowPart = FileHandle->Filesize; - Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize; - Fcb->FatHandle = FileHandle; - - /* Initialize locks */ - FsRtlInitializeFileLock(&Fcb->Fcb.Lock, NULL, NULL); - FsRtlInitializeOplock(&Fcb->Fcb.Oplock); - - /* Set names */ - FatSetFcbNames(IrpContext, Fcb); - - return Fcb; -} - -VOID -NTAPI -FatDeleteFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ - DPRINT("FatDeleteFcb %p\n", Fcb); - - if (Fcb->OpenCount != 0) - { - DPRINT1("Trying to delete FCB with OpenCount %d\n", Fcb->OpenCount); - ASSERT(FALSE); - } - - if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) || - (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) - { - /* Make sure it's a valid deletion */ - ASSERT(Fcb->Dcb.DirectoryFileOpenCount == 0); - ASSERT(IsListEmpty(&Fcb->Dcb.ParentDcbList)); - ASSERT(Fcb->Dcb.DirectoryFile == NULL); - } - else - { - /* Free locks */ - FsRtlUninitializeFileLock(&Fcb->Fcb.Lock); - FsRtlUninitializeOplock(&Fcb->Fcb.Oplock); - } - - /* Release any possible filter contexts */ - FsRtlTeardownPerStreamContexts(&Fcb->Header); - - /* Remove from parents queue */ - if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) - { - RemoveEntryList(&(Fcb->ParentDcbLinks)); - } - - /* Free FullFAT handle */ - if (Fcb->FatHandle) FF_Close(Fcb->FatHandle); - - /* Remove from the splay table */ - if (FlagOn(Fcb->State, FCB_STATE_HAS_NAMES)) - FatRemoveNames(IrpContext, Fcb); - - /* Free file name buffers */ - if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) - { - if (Fcb->FullFileName.Buffer) - ExFreePool(Fcb->FullFileName.Buffer); - } - - if (Fcb->ExactCaseLongName.Buffer) - ExFreePool(Fcb->ExactCaseLongName.Buffer); - - /* Free this FCB, finally */ - ExFreePool(Fcb); -} - -PCCB -NTAPI -FatCreateCcb() -{ - PCCB Ccb; - - /* Allocate the CCB and zero it */ - Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB); - RtlZeroMemory(Ccb, sizeof(CCB)); - - /* Set mandatory header */ - Ccb->NodeTypeCode = FAT_NTC_FCB; - Ccb->NodeByteSize = sizeof(CCB); - - return Ccb; -} - -VOID -NTAPI -FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PCCB Ccb) -{ - // TODO: Deallocate CCB strings, if any - - /* Free the CCB */ - ExFreePool(Ccb); -} - -IO_STATUS_BLOCK -NTAPI -FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB Fcb, - IN PACCESS_MASK DesiredAccess, - IN USHORT ShareAccess, - IN ULONG AllocationSize, - IN PFILE_FULL_EA_INFORMATION EaBuffer, - IN ULONG EaLength, - IN UCHAR FileAttributes, - IN ULONG CreateDisposition, - IN BOOLEAN NoEaKnowledge, - IN BOOLEAN DeleteOnClose, - IN BOOLEAN OpenedAsDos, - OUT PBOOLEAN OplockPostIrp) -{ - IO_STATUS_BLOCK Iosb = {{0}}; - ACCESS_MASK AddedAccess = 0; - BOOLEAN Hidden; - BOOLEAN System; - PCCB Ccb = NULL; - NTSTATUS Status, StatusPrev; - - /* Acquire exclusive FCB lock */ - (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); - - *OplockPostIrp = FALSE; - - /* Check if there is a batch oplock */ - if (FsRtlCurrentBatchOplock(&Fcb->Fcb.Oplock)) - { - /* Return with a special information field */ - Iosb.Information = FILE_OPBATCH_BREAK_UNDERWAY; - - /* Check the oplock */ - Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, - IrpContext->Irp, - IrpContext, - FatOplockComplete, - FatPrePostIrp); - - if (Iosb.Status != STATUS_SUCCESS && - Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) - { - /* The Irp needs to be queued */ - *OplockPostIrp = TRUE; - - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - } - - /* Validate parameters and modify access */ - if (CreateDisposition == FILE_CREATE) - { - Iosb.Status = STATUS_OBJECT_NAME_COLLISION; - - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - else if (CreateDisposition == FILE_SUPERSEDE) - { - SetFlag(AddedAccess, DELETE & ~(*DesiredAccess)); - *DesiredAccess |= DELETE; - } - else if ((CreateDisposition == FILE_OVERWRITE) || - (CreateDisposition == FILE_OVERWRITE_IF)) - { - SetFlag(AddedAccess, - (FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) - & ~(*DesiredAccess) ); - - *DesiredAccess |= FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES; - } - - // TODO: Check desired access - - // TODO: Check if this file is readonly and DeleteOnClose is set - - /* Validate disposition information */ - if ((CreateDisposition == FILE_SUPERSEDE) || - (CreateDisposition == FILE_OVERWRITE) || - (CreateDisposition == FILE_OVERWRITE_IF)) - { - // TODO: Get this attributes from the dirent - Hidden = FALSE; - System = FALSE; - - if ((Hidden && !FlagOn(FileAttributes, FILE_ATTRIBUTE_HIDDEN)) || - (System && !FlagOn(FileAttributes, FILE_ATTRIBUTE_SYSTEM))) - { - DPRINT1("Hidden/system attributes don't match\n"); - - Iosb.Status = STATUS_ACCESS_DENIED; - - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - - // TODO: Check for write protected volume - } - - /* Check share access */ - Iosb.Status = IoCheckShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Fcb->ShareAccess, - FALSE); - if (!NT_SUCCESS(Iosb.Status)) - { - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - - /* Check the oplock status after checking for share access */ - Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, - IrpContext->Irp, - IrpContext, - FatOplockComplete, - FatPrePostIrp ); - - if (Iosb.Status != STATUS_SUCCESS && - Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) - { - /* The Irp needs to be queued */ - *OplockPostIrp = TRUE; - - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - - /* Set Fast I/O flag */ - Fcb->Header.IsFastIoPossible = FALSE; //FatiIsFastIoPossible(Fcb); - - /* Make sure image is not mapped */ - if (DeleteOnClose || FlagOn(*DesiredAccess, FILE_WRITE_DATA)) - { - /* Try to flush the image section */ - if (!MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForWrite)) - { - /* Yes, image section exists, set correct status code */ - if (DeleteOnClose) - Iosb.Status = STATUS_CANNOT_DELETE; - else - Iosb.Status = STATUS_SHARING_VIOLATION; - - /* Release the FCB and return */ - FatReleaseFcb(IrpContext, Fcb); - return Iosb; - } - } - - /* Flush the cache if it's non-cached non-pagefile access */ - if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING) && - Fcb->SectionObjectPointers.DataSectionObject && - !FlagOn(Fcb->State, FCB_STATE_PAGEFILE)) - { - /* Set the flag that create is in progress */ - SetFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); - - /* Flush the cache */ - CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); - - /* Acquire and release Paging I/O resource before purging the cache section - to let lazy writer finish */ - ExAcquireResourceExclusiveLite( Fcb->Header.PagingIoResource, TRUE); - ExReleaseResourceLite( Fcb->Header.PagingIoResource ); - - /* Delete the cache section */ - CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE); - - /* Clear the flag */ - ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); - } - - /* Check create disposition flags and branch accordingly */ - if (CreateDisposition == FILE_OPEN || - CreateDisposition == FILE_OPEN_IF) - { - DPRINT("Opening a file\n"); - - /* Check if we need to bother with EA */ - if (NoEaKnowledge && FALSE /* FatIsFat32(Vcb)*/) - { - UNIMPLEMENTED; - } - - /* Set up file object */ - Ccb = FatCreateCcb(); - FatSetFileObject(FileObject, - UserFileOpen, - Fcb, - Ccb); - - FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; - - /* The file is opened */ - Iosb.Information = FILE_OPENED; - goto SuccComplete; - } - else if ((CreateDisposition == FILE_SUPERSEDE) || - (CreateDisposition == FILE_OVERWRITE) || - (CreateDisposition == FILE_OVERWRITE_IF)) - { - /* Remember previous status */ - StatusPrev = Iosb.Status; - - // TODO: Check system security access - - /* Perform overwrite operation */ - Iosb = FatiOverwriteFile(IrpContext, - FileObject, - Fcb, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - NoEaKnowledge); - - /* Restore previous status in case of success */ - if (Iosb.Status == STATUS_SUCCESS) - Iosb.Status = StatusPrev; - - /* Fall down to completion */ - } - else - { - /* We can't get here */ - KeBugCheckEx(FAT_FILE_SYSTEM, CreateDisposition, 0, 0, 0); - } - - -SuccComplete: - /* If all is fine */ - if (Iosb.Status != STATUS_PENDING && - NT_SUCCESS(Iosb.Status)) - { - /* Update access if needed */ - if (AddedAccess) - { - /* Remove added access flags from desired access */ - ClearFlag(*DesiredAccess, AddedAccess); - - /* Check share access */ - Status = IoCheckShareAccess(*DesiredAccess, - ShareAccess, - FileObject, - &Fcb->ShareAccess, - TRUE); - - /* Make sure it's success */ - ASSERT(Status == STATUS_SUCCESS); - } - else - { - /* Update the share access */ - IoUpdateShareAccess(FileObject, &Fcb->ShareAccess); - } - - /* Clear the delay close */ - ClearFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); - - /* Increase counters */ - Fcb->UncleanCount++; - Fcb->OpenCount++; - Vcb->OpenFileCount++; - if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; - if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) Fcb->NonCachedUncleanCount++; - - // TODO: Handle DeleteOnClose and OpenedAsDos by storing those flags in CCB - } - - return Iosb; -} - -VOID -NTAPI -FatGetFcbUnicodeName(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - OUT PUNICODE_STRING LongName) -{ - FF_DIRENT DirEnt; - FF_ERROR Err; - OEM_STRING ShortName; - CHAR ShortNameBuf[13]; - UCHAR EntryBuffer[32]; - UCHAR NumLFNs; - OEM_STRING LongNameOem; - NTSTATUS Status; - - /* Make sure this FCB has a FullFAT handle associated with it */ - if (Fcb->FatHandle == NULL && - FatNodeType(Fcb) == FAT_NTC_DCB) - { - /* Open the dir with FullFAT */ - Fcb->FatHandle = FF_OpenW(Fcb->Vcb->Ioman, &Fcb->FullFileName, FF_MODE_DIR, NULL); - if (!Fcb->FatHandle) - { - ASSERT(FALSE); - } - } - - /* Get the dir entry */ - Err = FF_GetEntry(Fcb->Vcb->Ioman, - Fcb->FatHandle->DirEntry, - Fcb->FatHandle->DirCluster, - &DirEnt); - - if (Err != FF_ERR_NONE) - { - DPRINT1("Error %d getting dirent of a file\n", Err); - return; - } - - /* Read the dirent to fetch the raw short name */ - FF_FetchEntry(Fcb->Vcb->Ioman, - Fcb->FatHandle->DirCluster, - Fcb->FatHandle->DirEntry, - EntryBuffer); - NumLFNs = (UCHAR)(EntryBuffer[0] & ~0x40); - - /* Check if we only have a short name. - Convert it to unicode and return if that's the case */ - if (NumLFNs == 0) - { - /* Initialize short name string */ - ShortName.Buffer = ShortNameBuf; - ShortName.Length = 0; - ShortName.MaximumLength = 12; - - /* Convert raw short name to a proper string */ - Fati8dot3ToString((PCHAR)EntryBuffer, FALSE, &ShortName); - - /* Convert it to unicode */ - Status = RtlOemStringToCountedUnicodeString(LongName, - &ShortName, - FALSE); - - /* Ensure conversion was successful */ - ASSERT(Status == STATUS_SUCCESS); - - /* Exit */ - return; - } - - /* Convert LFN from OEM to unicode and return */ - LongNameOem.Buffer = DirEnt.FileName; - LongNameOem.MaximumLength = FF_MAX_FILENAME; - LongNameOem.Length = strlen(DirEnt.FileName); - - /* Convert it to unicode */ - Status = RtlOemStringToUnicodeString(LongName, &LongNameOem, FALSE); - - /* Ensure conversion was successful */ - ASSERT(Status == STATUS_SUCCESS); -} - - -VOID -NTAPI -FatSetFullNameInFcb(PFCB Fcb, - PUNICODE_STRING Name) -{ - PUNICODE_STRING ParentName; - - /* Make sure this FCB's name wasn't already set */ - ASSERT(Fcb->FullFileName.Buffer == NULL); - - /* First of all, check exact case name */ - if (Fcb->ExactCaseLongName.Buffer) - { - ASSERT(Fcb->ExactCaseLongName.Length != 0); - - /* Use exact case name */ - Name = &Fcb->ExactCaseLongName; - } - - /* Treat root dir different */ - if (FatNodeType(Fcb->ParentFcb) == FAT_NTC_ROOT_DCB) - { - /* Set lengths */ - Fcb->FullFileName.MaximumLength = sizeof(WCHAR) + Name->Length; - Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength; - - /* Allocate a buffer */ - Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool, - Fcb->FullFileName.Length, - TAG_FILENAME); - - /* Prefix with a backslash */ - Fcb->FullFileName.Buffer[0] = L'\\'; - - /* Copy the name here */ - RtlCopyMemory(&Fcb->FullFileName.Buffer[1], - &Name->Buffer[0], - Name->Length ); - } - else - { - ParentName = &Fcb->ParentFcb->FullFileName; - - /* Check if parent's name is set */ - if (!ParentName->Buffer) - return; - - /* Set lengths */ - Fcb->FullFileName.MaximumLength = - ParentName->Length + sizeof(WCHAR) + Name->Length; - Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength; - - /* Allocate a buffer */ - Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool, - Fcb->FullFileName.Length, - TAG_FILENAME ); - - /* Copy parent's name here */ - RtlCopyMemory(&Fcb->FullFileName.Buffer[0], - &ParentName->Buffer[0], - ParentName->Length ); - - /* Add a backslash */ - Fcb->FullFileName.Buffer[ParentName->Length / sizeof(WCHAR)] = L'\\'; - - /* Copy given name here */ - RtlCopyMemory(&Fcb->FullFileName.Buffer[(ParentName->Length / sizeof(WCHAR)) + 1], - &Name->Buffer[0], - Name->Length ); - } -} - -VOID -NTAPI -FatSetFullFileNameInFcb(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ - UNICODE_STRING LongName; - PFCB CurFcb = Fcb; - PFCB StopFcb; - PWCHAR TmpBuffer; - ULONG PathLength = 0; - - /* Do nothing if it's already set */ - if (Fcb->FullFileName.Buffer) return; - - /* Allocate a temporary buffer */ - LongName.Length = 0; - LongName.MaximumLength = FF_MAX_FILENAME * sizeof(WCHAR); - LongName.Buffer = - FsRtlAllocatePoolWithTag(PagedPool, - FF_MAX_FILENAME * sizeof(WCHAR), - TAG_FILENAME); - - /* Go through all parents to calculate needed length */ - while (CurFcb != Fcb->Vcb->RootDcb) - { - /* Does current FCB have FullFileName set? */ - if (CurFcb != Fcb && - CurFcb->FullFileName.Buffer) - { - /* Yes, just use it! */ - PathLength += CurFcb->FullFileName.Length; - - Fcb->FullFileName.Buffer = - FsRtlAllocatePoolWithTag(PagedPool, - PathLength, - TAG_FILENAME); - - RtlCopyMemory(Fcb->FullFileName.Buffer, - CurFcb->FullFileName.Buffer, - CurFcb->FullFileName.Length); - - break; - } - - /* Sum up length of a current item */ - PathLength += CurFcb->FileNameLength + sizeof(WCHAR); - - /* Go to the parent */ - CurFcb = CurFcb->ParentFcb; - } - - /* Allocate FullFileName if it wasn't already allocated above */ - if (!Fcb->FullFileName.Buffer) - { - Fcb->FullFileName.Buffer = - FsRtlAllocatePoolWithTag(PagedPool, - PathLength, - TAG_FILENAME); - } - - StopFcb = CurFcb; - - CurFcb = Fcb; - TmpBuffer = Fcb->FullFileName.Buffer + PathLength / sizeof(WCHAR); - - /* Set lengths */ - Fcb->FullFileName.Length = PathLength; - Fcb->FullFileName.MaximumLength = PathLength; - - while (CurFcb != StopFcb) - { - /* Get its unicode name */ - FatGetFcbUnicodeName(IrpContext, - CurFcb, - &LongName); - - /* Copy it */ - TmpBuffer -= LongName.Length / sizeof(WCHAR); - RtlCopyMemory(TmpBuffer, LongName.Buffer, LongName.Length); - - /* Append with a backslash */ - TmpBuffer -= 1; - *TmpBuffer = L'\\'; - - /* Go to the parent */ - CurFcb = CurFcb->ParentFcb; - } - - /* Free the temp buffer */ - ExFreePool(LongName.Buffer); -} - - -VOID -NTAPI -FatSetFcbNames(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ - FF_DIRENT DirEnt; - FF_ERROR Err; - POEM_STRING ShortName; - CHAR ShortNameRaw[13]; - UCHAR EntryBuffer[32]; - UCHAR NumLFNs; - PUNICODE_STRING UnicodeName; - OEM_STRING LongNameOem; - NTSTATUS Status; - - /* Get the dir entry */ - Err = FF_GetEntry(Fcb->Vcb->Ioman, - Fcb->FatHandle->DirEntry, - Fcb->FatHandle->DirCluster, - &DirEnt); - - if (Err != FF_ERR_NONE) - { - DPRINT1("Error %d getting dirent of a file\n", Err); - return; - } - - /* Read the dirent to fetch the raw short name */ - FF_FetchEntry(Fcb->Vcb->Ioman, - Fcb->FatHandle->DirCluster, - Fcb->FatHandle->DirEntry, - EntryBuffer); - NumLFNs = (UCHAR)(EntryBuffer[0] & ~0x40); - RtlCopyMemory(ShortNameRaw, EntryBuffer, 11); - - /* Initialize short name string */ - ShortName = &Fcb->ShortName.Name.Ansi; - ShortName->Buffer = Fcb->ShortNameBuffer; - ShortName->Length = 0; - ShortName->MaximumLength = sizeof(Fcb->ShortNameBuffer); - - /* Convert raw short name to a proper string */ - Fati8dot3ToString(ShortNameRaw, FALSE, ShortName); - - /* Add the short name link */ - FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksAnsi, &Fcb->ShortName); - Fcb->ShortName.Fcb = Fcb; - - /* Get the long file name (if any) */ - if (NumLFNs > 0) - { - /* Prepare the oem string */ - LongNameOem.Buffer = DirEnt.FileName; - LongNameOem.MaximumLength = FF_MAX_FILENAME; - LongNameOem.Length = strlen(DirEnt.FileName); - - /* Prepare the unicode string */ - UnicodeName = &Fcb->LongName.Name.String; - UnicodeName->Length = (LongNameOem.Length + 1) * sizeof(WCHAR); - UnicodeName->MaximumLength = UnicodeName->Length; - UnicodeName->Buffer = FsRtlAllocatePool(PagedPool, UnicodeName->Length); - - /* Convert it to unicode */ - Status = RtlOemStringToUnicodeString(UnicodeName, &LongNameOem, FALSE); - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - /* Set its length */ - Fcb->FileNameLength = UnicodeName->Length; - - /* Save case-preserved copy */ - Fcb->ExactCaseLongName.Length = UnicodeName->Length; - Fcb->ExactCaseLongName.MaximumLength = UnicodeName->Length; - Fcb->ExactCaseLongName.Buffer = - FsRtlAllocatePoolWithTag(PagedPool, UnicodeName->Length, TAG_FILENAME); - - RtlCopyMemory(Fcb->ExactCaseLongName.Buffer, - UnicodeName->Buffer, - UnicodeName->Length); - - /* Perform a trick which is done by MS's FASTFAT driver to monocase - the filename */ - RtlDowncaseUnicodeString(UnicodeName, UnicodeName, FALSE); - RtlUpcaseUnicodeString(UnicodeName, UnicodeName, FALSE); - - DPRINT("Converted long name: %wZ\n", UnicodeName); - - /* Add the long unicode name link */ - FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksUnicode, &Fcb->LongName); - Fcb->LongName.Fcb = Fcb; - - /* Indicate that this FCB has a unicode long name */ - SetFlag(Fcb->State, FCB_STATE_HAS_UNICODE_NAME); - } - else - { - /* No LFN, set exact case name to 0 length */ - Fcb->ExactCaseLongName.Length = 0; - Fcb->ExactCaseLongName.MaximumLength = 0; - - /* Set the length based on the short name */ - Fcb->FileNameLength = RtlOemStringToCountedUnicodeSize(ShortName); - } - - /* Mark the fact that names were added to splay trees*/ - SetFlag(Fcb->State, FCB_STATE_HAS_NAMES); -} - -VOID -NTAPI -Fati8dot3ToString(IN PCHAR FileName, - IN BOOLEAN DownCase, - OUT POEM_STRING OutString) -{ - ULONG BaseLen, ExtLen; - CHAR *cString = OutString->Buffer; - ULONG i; - - /* Calc base and ext lens */ - for (BaseLen = 8; BaseLen > 0; BaseLen--) - { - if (FileName[BaseLen - 1] != ' ') break; - } - - for (ExtLen = 3; ExtLen > 0; ExtLen--) - { - if (FileName[8 + ExtLen - 1] != ' ') break; - } - - /* Process base name */ - if (BaseLen) - { - RtlCopyMemory(cString, FileName, BaseLen); - - /* Substitute the e5 thing */ - if (cString[0] == 0x05) cString[0] = 0xe5; - - /* Downcase if asked to */ - if (DownCase) - { - /* Do it manually */ - for (i = 0; i < BaseLen; i++) - { - if (cString[i] >= 'A' && - cString[i] <= 'Z') - { - /* Lowercase it */ - cString[i] += 'a' - 'A'; - } - - } - } - } - - /* Process extension */ - if (ExtLen) - { - /* Add the dot */ - cString[BaseLen] = '.'; - BaseLen++; - - /* Copy the extension */ - for (i = 0; i < ExtLen; i++) - { - cString[BaseLen + i] = FileName[8 + i]; - } - - /* Lowercase the extension if asked to */ - if (DownCase) - { - /* Do it manually */ - for (i = BaseLen; i < BaseLen + ExtLen; i++) - { - if (cString[i] >= 'A' && - cString[i] <= 'Z') - { - /* Lowercase it */ - cString[i] += 'a' - 'A'; - } - } - } - } - - /* Set the length */ - OutString->Length = BaseLen + ExtLen; - - DPRINT("'%s', len %d\n", OutString->Buffer, OutString->Length); -} - -VOID -NTAPI -FatInsertName(IN PFAT_IRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PFCB_NAME_LINK Name) -{ - PFCB_NAME_LINK NameLink; - FSRTL_COMPARISON_RESULT Comparison; - - /* Initialize the splay links */ - RtlInitializeSplayLinks(&Name->Links); - - /* Is this the first entry? */ - if (*RootNode == NULL) - { - /* Yes, become root and return */ - *RootNode = &Name->Links; - return; - } - - /* Get the name link */ - NameLink = CONTAINING_RECORD(*RootNode, FCB_NAME_LINK, Links); - while (TRUE) - { - /* Compare the prefix */ - if (*(PUCHAR)NameLink->Name.Ansi.Buffer != *(PUCHAR)&Name->Name.Ansi.Buffer) - { - if (*(PUCHAR)NameLink->Name.Ansi.Buffer < *(PUCHAR)&Name->Name.Ansi.Buffer) - Comparison = LessThan; - else - Comparison = GreaterThan; - } - else - { - /* Perform real comparison */ - Comparison = FatiCompareNames(&NameLink->Name.Ansi, &Name->Name.Ansi); - } - - /* Check the bad case first */ - if (Comparison == EqualTo) - { - /* Must not happen */ - ASSERT(FALSE); - } - - /* Check comparison result */ - if (Comparison == GreaterThan) - { - /* Go to the left child */ - if (!RtlLeftChild(&NameLink->Links)) - { - /* It's absent, insert here and break */ - RtlInsertAsLeftChild(&NameLink->Links, &Name->Links); - break; - } - else - { - /* It's present, go inside it */ - NameLink = CONTAINING_RECORD(RtlLeftChild(&NameLink->Links), - FCB_NAME_LINK, - Links); - } - } - else - { - /* Go to the right child */ - if (!RtlRightChild(&NameLink->Links)) - { - /* It's absent, insert here and break */ - RtlInsertAsRightChild(&NameLink->Links, &Name->Links); - break; - } - else - { - /* It's present, go inside it */ - NameLink = CONTAINING_RECORD(RtlRightChild(&NameLink->Links), - FCB_NAME_LINK, - Links); - } - } - } -} - -VOID -NTAPI -FatRemoveNames(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb) -{ - PRTL_SPLAY_LINKS RootNew; - PFCB Parent; - - /* Reference the parent for simplicity */ - Parent = Fcb->ParentFcb; - - /* If this FCB hasn't been added to splay trees - just return */ - if (!FlagOn( Fcb->State, FCB_STATE_HAS_NAMES )) - return; - - /* Delete the short name link */ - RootNew = RtlDelete(&Fcb->ShortName.Links); - - /* Set the new root */ - Parent->Dcb.SplayLinksAnsi = RootNew; - - /* Deal with a unicode name if it exists */ - if (FlagOn( Fcb->State, FCB_STATE_HAS_UNICODE_NAME )) - { - /* Delete the long unicode name link */ - RootNew = RtlDelete(&Fcb->LongName.Links); - - /* Set the new root */ - Parent->Dcb.SplayLinksUnicode = RootNew; - - /* Free the long name string's buffer*/ - RtlFreeUnicodeString(&Fcb->LongName.Name.String); - - /* Clear the "has unicode name" flag */ - ClearFlag(Fcb->State, FCB_STATE_HAS_UNICODE_NAME); - } - - /* This FCB has no names added to splay trees now */ - ClearFlag(Fcb->State, FCB_STATE_HAS_NAMES); -} - - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/finfo.c b/reactos/drivers/filesystems/fastfat_new/finfo.c deleted file mode 100644 index 7e958348787..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/finfo.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/finfo.c - * PURPOSE: File Information support routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -VOID -NTAPI -FatiQueryBasicInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_BASIC_INFORMATION Buffer, - IN OUT PLONG Length) -{ - /* Zero the buffer */ - RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION)); - - /* Deduct the written length */ - *Length -= sizeof(FILE_BASIC_INFORMATION); - - /* Check if it's a dir or a file */ - if (FatNodeType(Fcb) == FAT_NTC_FCB) - { - // FIXME: Read dirent and get times from there - Buffer->LastAccessTime.QuadPart = 0; - Buffer->CreationTime.QuadPart = 0; - Buffer->LastWriteTime.QuadPart = 0; - } - else - { - // FIXME: May not be really correct - Buffer->FileAttributes = 0; - DPRINT1("Basic info of a directory '%wZ' is requested!\n", &Fcb->FullFileName); - } - - - /* If attribute is 0, set normal */ - if (Buffer->FileAttributes == 0) - Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; -} - -VOID -NTAPI -FatiQueryStandardInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_STANDARD_INFORMATION Buffer, - IN OUT PLONG Length) -{ - /* Zero the buffer */ - RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION)); - - /* Deduct the written length */ - *Length -= sizeof(FILE_STANDARD_INFORMATION); - - Buffer->NumberOfLinks = 1; - Buffer->DeletePending = FALSE; // FIXME - - /* Check if it's a dir or a file */ - if (FatNodeType(Fcb) == FAT_NTC_FCB) - { - Buffer->Directory = FALSE; - - Buffer->EndOfFile.LowPart = Fcb->FatHandle->Filesize; - Buffer->AllocationSize = Buffer->EndOfFile; - DPRINT("Filesize %d, chain length %d\n", Fcb->FatHandle->Filesize, Fcb->FatHandle->iChainLength); - } - else - { - Buffer->Directory = TRUE; - } -} - -VOID -NTAPI -FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_INTERNAL_INFORMATION Buffer, - IN OUT PLONG Length) -{ - UNIMPLEMENTED; -} - -VOID -NTAPI -FatiQueryNameInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_NAME_INFORMATION Buffer, - IN OUT PLONG Length) -{ - ULONG ByteSize; - ULONG Trim = 0; - BOOLEAN Overflow = FALSE; - - /* Deduct the minimum written length */ - *Length -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]); - - /* Build full name if needed */ - if (!Fcb->FullFileName.Buffer) - { - FatSetFullFileNameInFcb(IrpContext, Fcb); - } - - DPRINT("FullFileName %wZ\n", &Fcb->FullFileName); - - if (*Length < Fcb->FullFileName.Length - Trim) - { - /* Buffer can't fit all data */ - ByteSize = *Length; - Overflow = TRUE; - } - else - { - /* Deduct the amount of bytes we are going to write */ - ByteSize = Fcb->FullFileName.Length - Trim; - *Length -= ByteSize; - } - - /* Copy the name */ - RtlCopyMemory(Buffer->FileName, - Fcb->FullFileName.Buffer, - ByteSize); - - /* Set the length */ - Buffer->FileNameLength = Fcb->FullFileName.Length - Trim; - - /* Is this a shortname query? */ - if (Trim) - { - /* Yes, not supported atm */ - ASSERT(FALSE); - } - - /* Indicate overflow by passing -1 as the length */ - if (Overflow) *Length = -1; -} - -NTSTATUS -NTAPI -FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - PFILE_OBJECT FileObject; - PIO_STACK_LOCATION IrpSp; - FILE_INFORMATION_CLASS InfoClass; - TYPE_OF_OPEN FileType; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - LONG Length; - PVOID Buffer; - BOOLEAN VcbLocked = FALSE, FcbLocked = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - - /* Get IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Get the file object */ - FileObject = IrpSp->FileObject; - - /* Copy variables to something with shorter names */ - InfoClass = IrpSp->Parameters.QueryFile.FileInformationClass; - Length = IrpSp->Parameters.QueryFile.Length; - Buffer = Irp->AssociatedIrp.SystemBuffer; - - DPRINT("FatiQueryInformation\n", 0); - DPRINT("\tIrp = %08lx\n", Irp); - DPRINT("\tLength = %08lx\n", Length); - DPRINT("\tFileInformationClass = %08lx\n", InfoClass); - DPRINT("\tBuffer = %08lx\n", Buffer); - - FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - - DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); - - /* Acquire VCB lock */ - if (InfoClass == FileNameInformation || - InfoClass == FileAllInformation) - { - if (!FatAcquireExclusiveVcb(IrpContext, Vcb)) - { - ASSERT(FALSE); - } - - /* Remember we locked the VCB */ - VcbLocked = TRUE; - } - - /* Acquire FCB lock */ - // FIXME: If not paging file - if (!FatAcquireSharedFcb(IrpContext, Fcb)) - { - ASSERT(FALSE); - } - FcbLocked = TRUE; - - switch (InfoClass) - { - case FileBasicInformation: - FatiQueryBasicInformation(IrpContext, Fcb, FileObject, Buffer, &Length); - break; - case FileStandardInformation: - FatiQueryStandardInformation(IrpContext, Fcb, FileObject, Buffer, &Length); - break; - case FileInternalInformation: - FatiQueryInternalInformation(IrpContext, Fcb, FileObject, Buffer, &Length); - break; - case FileNameInformation: - FatiQueryNameInformation(IrpContext, Fcb, FileObject, Buffer, &Length); - break; - default: - DPRINT1("Unimplemented information class %d requested\n", InfoClass); - Status = STATUS_INVALID_PARAMETER; - } - - /* Check for buffer overflow */ - if (Length < 0) - { - Status = STATUS_BUFFER_OVERFLOW; - Length = 0; - } - - /* Set IoStatus.Information to amount of filled bytes */ - Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length; - - /* Release FCB locks */ - if (FcbLocked) FatReleaseFcb(IrpContext, Fcb); - if (VcbLocked) FatReleaseVcb(IrpContext, Vcb); - - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; -} - -NTSTATUS -NTAPI -FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - BOOLEAN TopLevel, CanWait; - PFAT_IRP_CONTEXT IrpContext; - - CanWait = TRUE; - TopLevel = FALSE; - Status = STATUS_INVALID_DEVICE_REQUEST; - - /* Get CanWait flag */ - if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) - CanWait = IoIsOperationSynchronous(Irp); - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Set Top Level IRP if not set */ - TopLevel = FatIsTopLevelIrp(Irp); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, CanWait); - - /* Perform the actual read */ - Status = FatiQueryInformation(IrpContext, Irp); - - /* Restore top level Irp */ - if (TopLevel) IoSetTopLevelIrp(NULL); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -NTSTATUS -NTAPI -FatSetEndOfFileInfo(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PFILE_OBJECT FileObject, - IN PVCB Vcb, - IN PFCB Fcb) -{ - PFILE_END_OF_FILE_INFORMATION Buffer; - ULONG NewFileSize; - ULONG InitialFileSize; - ULONG InitialValidDataLength; - //ULONG InitialValidDataToDisk; - BOOLEAN CacheMapInitialized = FALSE; - BOOLEAN ResourceAcquired = FALSE; - NTSTATUS Status; - - Buffer = Irp->AssociatedIrp.SystemBuffer; - - if (FatNodeType(Fcb) != FAT_NTC_FCB) - { - /* Trying to change size of a dir */ - Status = STATUS_INVALID_DEVICE_REQUEST; - return Status; - } - - /* Validate new size */ - if (!FatIsIoRangeValid(Buffer->EndOfFile, 0)) - { - Status = STATUS_DISK_FULL; - return Status; - } - - NewFileSize = Buffer->EndOfFile.LowPart; - - /* Lookup allocation size if needed */ - if (Fcb->Header.AllocationSize.QuadPart == (LONGLONG)-1) - UNIMPLEMENTED;//FatLookupFileAllocationSize(IrpContext, Fcb); - - /* Cache the file if there is a data section */ - if (FileObject->SectionObjectPointer->DataSectionObject && - (FileObject->SectionObjectPointer->SharedCacheMap == NULL) && - !FlagOn(Irp->Flags, IRP_PAGING_IO)) - { - if (FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE)) - { - /* This is a really weird condition */ - UNIMPLEMENTED; - //Raise(STATUS_FILE_CLOSED); - } - - /* Initialize the cache map */ - CcInitializeCacheMap(FileObject, - (PCC_FILE_SIZES)&Fcb->Header.AllocationSize, - FALSE, - &FatGlobalData.CacheMgrCallbacks, - Fcb); - - CacheMapInitialized = TRUE; - } - - /* Lazy write case */ - if (IoGetCurrentIrpStackLocation(Irp)->Parameters.SetFile.AdvanceOnly) - { - if (!IsFileDeleted(Fcb) && - (Fcb->Condition == FcbGood)) - { - /* Clamp the new file size */ - if (NewFileSize >= Fcb->Header.FileSize.LowPart) - NewFileSize = Fcb->Header.FileSize.LowPart; - - ASSERT(NewFileSize <= Fcb->Header.AllocationSize.LowPart); - - /* Never reduce the file size here! */ - - // TODO: Actually change file size - DPRINT1("Actually changing file size is missing\n"); - - /* Notify about file size change */ - FatNotifyReportChange(IrpContext, - Vcb, - Fcb, - FILE_NOTIFY_CHANGE_SIZE, - FILE_ACTION_MODIFIED); - } - else - { - DPRINT1("Cannot set size on deleted file\n"); - } - - Status = STATUS_SUCCESS; - return Status; - } - - if ( NewFileSize > Fcb->Header.AllocationSize.LowPart ) - { - // TODO: Increase file size - DPRINT1("Actually changing file size is missing\n"); - } - - if (Fcb->Header.FileSize.LowPart != NewFileSize) - { - if (NewFileSize < Fcb->Header.FileSize.LowPart) - { - if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer, - &Buffer->EndOfFile)) - { - Status = STATUS_USER_MAPPED_FILE; - - /* Free up resources if necessary */ - if (CacheMapInitialized) - CcUninitializeCacheMap(FileObject, NULL, NULL); - - return Status; - } - - ResourceAcquired = ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); - } - - /* Set new file sizes */ - InitialFileSize = Fcb->Header.FileSize.LowPart; - InitialValidDataLength = Fcb->Header.ValidDataLength.LowPart; - //InitialValidDataToDisk = Fcb->ValidDataToDisk; - - Fcb->Header.FileSize.LowPart = NewFileSize; - - /* Adjust valid data length if new size is less than that */ - if (Fcb->Header.ValidDataLength.LowPart > NewFileSize) - Fcb->Header.ValidDataLength.LowPart = NewFileSize; - - //if (Fcb->ValidDataToDisk > NewFileSize) - // Fcb->ValidDataToDisk = NewFileSize; - - DPRINT1("New file size is 0x%08lx\n", NewFileSize); - - /* Update cache mapping */ - CcSetFileSizes(FileObject, - (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); - - /* Notify about size change */ - FatNotifyReportChange(IrpContext, - Vcb, - Fcb, - FILE_NOTIFY_CHANGE_SIZE, - FILE_ACTION_MODIFIED); - - /* Set truncate on close flag */ - SetFlag(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE); - } - - /* Set modified flag */ - FileObject->Flags |= FO_FILE_MODIFIED; - - /* Free up resources if necessary */ - if (CacheMapInitialized) - CcUninitializeCacheMap(FileObject, NULL, NULL); - - if (ResourceAcquired) - ExReleaseResourceLite(Fcb->Header.PagingIoResource); - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -FatiSetInformation(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - PFILE_OBJECT FileObject; - PIO_STACK_LOCATION IrpSp; - FILE_INFORMATION_CLASS InfoClass; - TYPE_OF_OPEN TypeOfOpen; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - LONG Length; - PVOID Buffer; - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN VcbAcquired = FALSE, FcbAcquired = FALSE; - - /* Get IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Get the file object */ - FileObject = IrpSp->FileObject; - - /* Copy variables to something with shorter names */ - InfoClass = IrpSp->Parameters.SetFile.FileInformationClass; - Length = IrpSp->Parameters.SetFile.Length; - Buffer = Irp->AssociatedIrp.SystemBuffer; - - DPRINT("FatiSetInformation\n", 0); - DPRINT("\tIrp = %08lx\n", Irp); - DPRINT("\tLength = %08lx\n", Length); - DPRINT("\tFileInformationClass = %08lx\n", InfoClass); - DPRINT("\tFileObject = %08lx\n", IrpSp->Parameters.SetFile.FileObject); - DPRINT("\tBuffer = %08lx\n", Buffer); - - TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - - DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, TypeOfOpen); - - switch (TypeOfOpen) - { - case UserVolumeOpen: - Status = STATUS_INVALID_PARAMETER; - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - case UserFileOpen: - /* Check oplocks */ - if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) && - ((InfoClass == FileEndOfFileInformation) || - (InfoClass == FileAllocationInformation))) - { - Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, - Irp, - IrpContext, - NULL, - NULL); - - if (Status != STATUS_SUCCESS) - { - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Update Fast IO flag */ - Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb); - } - break; - - case UserDirectoryOpen: - break; - - default: - Status = STATUS_INVALID_PARAMETER; - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* If it's a root DCB - fail */ - if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB) - { - if (InfoClass == FileDispositionInformation) - Status = STATUS_CANNOT_DELETE; - else - Status = STATUS_INVALID_PARAMETER; - - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; - } - - /* Acquire the volume lock if needed */ - if (InfoClass == FileDispositionInformation || - InfoClass == FileRenameInformation) - { - if (!FatAcquireExclusiveVcb(IrpContext, Vcb)) - { - UNIMPLEMENTED; - } - - VcbAcquired = TRUE; - } - - /* Acquire FCB lock */ - if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE)) - { - if (!FatAcquireExclusiveFcb(IrpContext, Fcb)) - { - UNIMPLEMENTED; - } - - FcbAcquired = TRUE; - } - - // TODO: VerifyFcb - - switch (InfoClass) - { - case FileBasicInformation: - //Status = FatSetBasicInfo(IrpContext, Irp, Fcb, Ccb); - DPRINT1("FileBasicInformation\n"); - break; - - case FileDispositionInformation: - if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && - !FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)) - { - UNIMPLEMENTED; - } - else - { - //Status = FatSetDispositionInfo(IrpContext, Irp, FileObject, Fcb); - DPRINT1("FileDispositionInformation\n"); - } - - break; - - case FileRenameInformation: - if (!FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)) - { - UNIMPLEMENTED; - } - else - { - //Status = FatSetRenameInfo(IrpContext, Irp, Vcb, Fcb, Ccb); - DPRINT1("FileRenameInformation\n"); - - /* NOTE: Request must not be completed here! - That's why Irp/IrpContext are set to NULL */ - if (Status == STATUS_PENDING) - { - Irp = NULL; - IrpContext = NULL; - } - } - break; - - case FilePositionInformation: - //Status = FatSetPositionInfo(IrpContext, Irp, FileObject); - DPRINT1("FilePositionInformation\n"); - break; - - case FileLinkInformation: - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - - case FileAllocationInformation: - //Status = FatSetAllocationInfo(IrpContext, Irp, Fcb, FileObject); - DPRINT1("FileAllocationInformation\n"); - break; - - case FileEndOfFileInformation: - Status = FatSetEndOfFileInfo(IrpContext, Irp, FileObject, Vcb, Fcb); - break; - - default: - Status = STATUS_INVALID_PARAMETER; - } - - /* Release locks */ - if (FcbAcquired) FatReleaseFcb(IrpContext, Fcb); - if (VcbAcquired) FatReleaseVcb(IrpContext, Vcb); - - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; -} - -NTSTATUS -NTAPI -FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - BOOLEAN TopLevel, CanWait; - PFAT_IRP_CONTEXT IrpContext; - - CanWait = TRUE; - TopLevel = FALSE; - Status = STATUS_INVALID_DEVICE_REQUEST; - - /* Get CanWait flag */ - if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) - CanWait = IoIsOperationSynchronous(Irp); - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Set Top Level IRP if not set */ - TopLevel = FatIsTopLevelIrp(Irp); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, CanWait); - - /* Perform the actual read */ - Status = FatiSetInformation(IrpContext, Irp); - - /* Restore top level Irp */ - if (TopLevel) IoSetTopLevelIrp(NULL); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/flush.c b/reactos/drivers/filesystems/fastfat_new/flush.c deleted file mode 100644 index 80b3dca536d..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/flush.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/flush.c - * PURPOSE: Flushing routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatFlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatFlushBuffers()\n"); - return STATUS_NOT_IMPLEMENTED; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fsctl.c b/reactos/drivers/filesystems/fastfat_new/fsctl.c deleted file mode 100644 index fef6b239239..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fsctl.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fsctl.c - * PURPOSE: Filesystem control - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatOplockRequest(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - NTSTATUS Status; - DPRINT1("Oplock request!\n"); - - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - - return Status; -} - -NTSTATUS -NTAPI -FatMarkVolumeDirty(IN PFAT_IRP_CONTEXT IrpContext, - IN PIRP Irp) -{ - NTSTATUS Status; - DPRINT1("Marking volume as dirty\n"); - - Status = STATUS_SUCCESS; - FatCompleteRequest(IrpContext, Irp, Status); - - return Status; -} - -NTSTATUS -NTAPI -FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - ULONG Code; - - /* Get current IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - Code = IrpSp->Parameters.FileSystemControl.FsControlCode; - - /* Set the wait flag */ - if (Irp->RequestorMode != KernelMode && - (Code & 3) == METHOD_NEITHER) - { - SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT); - } - - /* Branch according to the code */ - switch (Code) - { - case FSCTL_REQUEST_OPLOCK_LEVEL_1: - case FSCTL_REQUEST_OPLOCK_LEVEL_2: - case FSCTL_REQUEST_BATCH_OPLOCK: - case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE: - case FSCTL_OPBATCH_ACK_CLOSE_PENDING: - case FSCTL_OPLOCK_BREAK_NOTIFY: - case FSCTL_OPLOCK_BREAK_ACK_NO_2: - case FSCTL_REQUEST_FILTER_OPLOCK : - Status = FatOplockRequest(IrpContext, Irp); - break; - - case FSCTL_LOCK_VOLUME: - //Status = FatLockVolume( IrpContext, Irp ); - DPRINT1("FSCTL_LOCK_VOLUME\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_UNLOCK_VOLUME: - //Status = FatUnlockVolume( IrpContext, Irp ); - DPRINT1("FSCTL_UNLOCK_VOLUME\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_DISMOUNT_VOLUME: - //Status = FatDismountVolume( IrpContext, Irp ); - DPRINT1("FSCTL_DISMOUNT_VOLUME\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_MARK_VOLUME_DIRTY: - Status = FatMarkVolumeDirty(IrpContext, Irp); - break; - - case FSCTL_IS_VOLUME_DIRTY: - //Status = FatIsVolumeDirty( IrpContext, Irp ); - DPRINT1("FSCTL_IS_VOLUME_DIRTY\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_IS_VOLUME_MOUNTED: - //Status = FatIsVolumeMounted( IrpContext, Irp ); - DPRINT1("FSCTL_IS_VOLUME_MOUNTED\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_IS_PATHNAME_VALID: - //Status = FatIsPathnameValid( IrpContext, Irp ); - DPRINT1("FSCTL_IS_PATHNAME_VALID\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_QUERY_RETRIEVAL_POINTERS: - //Status = FatQueryRetrievalPointers( IrpContext, Irp ); - DPRINT1("FSCTL_QUERY_RETRIEVAL_POINTERS\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_QUERY_FAT_BPB: - //Status = FatQueryBpb( IrpContext, Irp ); - DPRINT1("FSCTL_QUERY_FAT_BPB\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_FILESYSTEM_GET_STATISTICS: - //Status = FatGetStatistics( IrpContext, Irp ); - DPRINT1("FSCTL_FILESYSTEM_GET_STATISTICS\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_GET_VOLUME_BITMAP: - //Status = FatGetVolumeBitmap( IrpContext, Irp ); - DPRINT1("FSCTL_GET_VOLUME_BITMAP\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_GET_RETRIEVAL_POINTERS: - //Status = FatGetRetrievalPointers( IrpContext, Irp ); - DPRINT1("FSCTL_GET_RETRIEVAL_POINTERS\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_MOVE_FILE: - //Status = FatMoveFile( IrpContext, Irp ); - DPRINT1("FSCTL_MOVE_FILE\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - case FSCTL_ALLOW_EXTENDED_DASD_IO: - //Status = FatAllowExtendedDasdIo( IrpContext, Irp ); - DPRINT1("FSCTL_ALLOW_EXTENDED_DASD_IO\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - break; - - default: - DPRINT("FatUserFsCtrl(), unhandled fs control code 0x%x\n", Code); - Status = STATUS_INVALID_DEVICE_REQUEST; - FatCompleteRequest(IrpContext, Irp, Status); - } - - //(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) - - // 9c040 - // 1 1 0 0 0 - // 6 4 8 4 0 - // 10011100000001000000 - // DT = 1001 = 9 - // Access = 11 = 3 - // Function = 10000 = 16 - // Method = 0 - - return Status; -} - -NTSTATUS -NTAPI -FatVerifyVolume(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - DPRINT1("FatVerifyVolume()\n"); - FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST); - return STATUS_INVALID_DEVICE_REQUEST; -} - -VOID -NTAPI -FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext) -{ - /* Make sure this IRP is waitable */ - ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT); - - /* Acquire global resource */ - ExAcquireResourceExclusiveLite(&FatGlobalData.Resource, TRUE); - - /* TODO: Go through all VCBs and delete unmounted ones */ - - /* Release global resource */ - ExReleaseResourceLite(&FatGlobalData.Resource); -} - -VOID -NTAPI -FatiUnpackBpb(PBIOS_PARAMETER_BLOCK Bpb, PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) -{ - CopyUchar2(&Bpb->BytesPerSector, &PackedBpb->BytesPerSector[0]); - CopyUchar1(&Bpb->SectorsPerCluster, &PackedBpb->SectorsPerCluster[0]); - CopyUchar2(&Bpb->ReservedSectors, &PackedBpb->ReservedSectors[0]); - CopyUchar1(&Bpb->Fats, &PackedBpb->Fats[0]); - CopyUchar2(&Bpb->RootEntries, &PackedBpb->RootEntries[0]); - CopyUchar2(&Bpb->Sectors, &PackedBpb->Sectors[0]); - CopyUchar1(&Bpb->Media, &PackedBpb->Media[0]); - CopyUchar2(&Bpb->SectorsPerFat, &PackedBpb->SectorsPerFat[0]); - CopyUchar2(&Bpb->SectorsPerTrack, &PackedBpb->SectorsPerTrack[0]); - CopyUchar2(&Bpb->Heads, &PackedBpb->Heads[0]); - CopyUchar4(&Bpb->HiddenSectors, &PackedBpb->HiddenSectors[0]); - CopyUchar4(&Bpb->LargeSectors, &PackedBpb->LargeSectors[0]); - CopyUchar4(&Bpb->LargeSectorsPerFat, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->LargeSectorsPerFat[0]); - CopyUchar2(&Bpb->ExtendedFlags, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->ExtendedFlags[0]); - CopyUchar2(&Bpb->FsVersion, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsVersion[0]); - CopyUchar4(&Bpb->RootDirFirstCluster,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->RootDirFirstCluster[0]); - CopyUchar2(&Bpb->FsInfoSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsInfoSector[0]); - CopyUchar2(&Bpb->BackupBootSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->BackupBootSector[0]); -} - -BOOLEAN -NTAPI -FatiBpbFat32(PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) -{ - return (*(USHORT *)(&PackedBpb->SectorsPerFat) == 0); -} - -NTSTATUS -NTAPI -FatMountVolume(PFAT_IRP_CONTEXT IrpContext, - PDEVICE_OBJECT TargetDeviceObject, - PVPB Vpb, - PDEVICE_OBJECT FsDeviceObject) -{ - NTSTATUS Status; - DISK_GEOMETRY DiskGeometry; - ULONG MediaChangeCount = 0; - PVOLUME_DEVICE_OBJECT VolumeDevice; - VCB *Vcb; - FF_ERROR Error; - PBCB BootBcb; - PPACKED_BOOT_SECTOR BootSector; - - DPRINT1("FatMountVolume()\n"); - - /* Make sure this IRP is waitable */ - ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT); - - /* Request media changes count, mostly useful for removable devices */ - Status = FatPerformDevIoCtrl(TargetDeviceObject, - IOCTL_STORAGE_CHECK_VERIFY, - NULL, - 0, - &MediaChangeCount, - sizeof(ULONG), - TRUE); - - if (!NT_SUCCESS(Status)) return Status; - - /* TODO: Check if data-track present in case of a CD drive */ - /* TODO: IOCTL_DISK_GET_PARTITION_INFO_EX */ - - /* Remove unmounted VCBs */ - FatiCleanVcbs(IrpContext); - - /* Acquire the global exclusive lock */ - FatAcquireExclusiveGlobal(IrpContext); - - /* Create a new volume device object */ - Status = IoCreateDevice(FatGlobalData.DriverObject, - sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT), - NULL, - FILE_DEVICE_DISK_FILE_SYSTEM, - 0, - FALSE, - (PDEVICE_OBJECT *)&VolumeDevice); - - if (!NT_SUCCESS(Status)) - { - /* Release the global lock */ - FatReleaseGlobal(IrpContext); - - return Status; - } - - /* Match alignment requirements */ - if (TargetDeviceObject->AlignmentRequirement > VolumeDevice->DeviceObject.AlignmentRequirement) - { - VolumeDevice->DeviceObject.AlignmentRequirement = TargetDeviceObject->AlignmentRequirement; - } - - /* Init stack size */ - VolumeDevice->DeviceObject.StackSize = TargetDeviceObject->StackSize + 1; - - /* Get sector size */ - Status = FatPerformDevIoCtrl(TargetDeviceObject, - IOCTL_DISK_GET_DRIVE_GEOMETRY, - NULL, - 0, - &DiskGeometry, - sizeof(DISK_GEOMETRY), - TRUE); - - if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup; - - VolumeDevice->DeviceObject.SectorSize = (USHORT) DiskGeometry.BytesPerSector; - - /* Signal we're done with initializing */ - VolumeDevice->DeviceObject.Flags &= ~DO_DEVICE_INITIALIZING; - - /* Save device object in a VPB */ - Vpb->DeviceObject = (PDEVICE_OBJECT)VolumeDevice; - - /* Initialize VCB for this volume */ - Status = FatInitializeVcb(IrpContext, &VolumeDevice->Vcb, TargetDeviceObject, Vpb); - if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup; - - Vcb = &VolumeDevice->Vcb; - - /* Initialize FullFAT library */ - Vcb->Ioman = FF_CreateIOMAN(NULL, - 8192, - VolumeDevice->DeviceObject.SectorSize, - &Error); - - ASSERT(Vcb->Ioman); - - /* Register block device read/write functions */ - Error = FF_RegisterBlkDevice(Vcb->Ioman, - VolumeDevice->DeviceObject.SectorSize, - (FF_WRITE_BLOCKS)FatWriteBlocks, - (FF_READ_BLOCKS)FatReadBlocks, - Vcb); - - if (Error) - { - DPRINT1("Registering block device with FullFAT failed with error %d\n", Error); - FF_DestroyIOMAN(Vcb->Ioman); - goto FatMountVolumeCleanup; - } - - /* Mount the volume using FullFAT */ - if(FF_MountPartition(Vcb->Ioman, 0)) - { - DPRINT1("Partition mounting failed\n"); - FF_DestroyIOMAN(Vcb->Ioman); - goto FatMountVolumeCleanup; - } - - /* Read the boot sector */ - FatReadStreamFile(Vcb, 0, sizeof(PACKED_BOOT_SECTOR), &BootBcb, (PVOID)&BootSector); - - /* Check if it's successful */ - if (!BootBcb) - { - Status = STATUS_UNRECOGNIZED_VOLUME; - goto FatMountVolumeCleanup; - } - - /* Unpack data */ - FatiUnpackBpb(&Vcb->Bpb, &BootSector->PackedBpb); - - /* Verify if sector size matches */ - if (DiskGeometry.BytesPerSector != Vcb->Bpb.BytesPerSector) - { - DPRINT1("Disk geometry BPS %d and bios BPS %d don't match!\n", - DiskGeometry.BytesPerSector, Vcb->Bpb.BytesPerSector); - - /* Fail */ - Status = STATUS_UNRECOGNIZED_VOLUME; - goto FatMountVolumeCleanup; - } - - /* If Sectors value is set, discard the LargeSectors value */ - if (Vcb->Bpb.Sectors) Vcb->Bpb.LargeSectors = 0; - - /* Copy serial number */ - if (FatiBpbFat32(&BootSector->PackedBpb)) - { - CopyUchar4(&Vpb->SerialNumber, ((PPACKED_BOOT_SECTOR_EX)BootSector)->Id); - } - else - { - /* This is FAT12/16 */ - CopyUchar4(&Vpb->SerialNumber, BootSector->Id); - } - - /* Unpin the BCB */ - CcUnpinData(BootBcb); - - /* Create root DCB for it */ - FatCreateRootDcb(IrpContext, &VolumeDevice->Vcb); - - /* Keep trace of media changes */ - VolumeDevice->Vcb.MediaChangeCount = MediaChangeCount; - - //ObDereferenceObject(TargetDeviceObject); - - /* Release the global lock */ - FatReleaseGlobal(IrpContext); - - /* Notify about volume mount */ - //FsRtlNotifyVolumeEvent(VolumeDevice->Vcb.StreamFileObject, FSRTL_VOLUME_MOUNT); - - /* Return success */ - return STATUS_SUCCESS; - - -FatMountVolumeCleanup: - - /* Unwind the routine actions */ - IoDeleteDevice((PDEVICE_OBJECT)VolumeDevice); - - /* Release the global lock */ - FatReleaseGlobal(IrpContext); - - return Status; -} - - - -NTSTATUS -NTAPI -FatiFileSystemControl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - - /* Get current IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Dispatch depending on the minor function */ - switch (IrpSp->MinorFunction) - { - case IRP_MN_KERNEL_CALL: - case IRP_MN_USER_FS_REQUEST: - Status = FatUserFsCtrl(IrpContext, Irp); - break; - - case IRP_MN_MOUNT_VOLUME: - Status = FatMountVolume(IrpContext, - IrpSp->Parameters.MountVolume.DeviceObject, - IrpSp->Parameters.MountVolume.Vpb, - IrpSp->DeviceObject); - - FatCompleteRequest(IrpContext, Irp, Status); - - break; - - case IRP_MN_VERIFY_VOLUME: - Status = FatVerifyVolume(IrpContext, Irp); - break; - - default: - DPRINT1("Unhandled FSCTL minor 0x%x\n", IrpSp->MinorFunction); - FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST); - Status = STATUS_INVALID_DEVICE_REQUEST; - } - - return Status; -} - - -NTSTATUS -NTAPI -FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status = STATUS_SUCCESS; - PFAT_IRP_CONTEXT IrpContext; - BOOLEAN CanWait = TRUE; - - DPRINT("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); - - /* Get CanWait flag */ - if (IoGetCurrentIrpStackLocation(Irp)->FileObject) - { - CanWait = IoIsOperationSynchronous(Irp); - } - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, CanWait); - - /* Call internal function */ - Status = FatiFileSystemControl(IrpContext, Irp); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} diff --git a/reactos/drivers/filesystems/fastfat_new/fullfat.c b/reactos/drivers/filesystems/fastfat_new/fullfat.c deleted file mode 100644 index 652c56741d6..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/fullfat.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/fullfat.c - * PURPOSE: FullFAT integration routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* GLOBALS ******************************************************************/ - -#define TAG_FULLFAT 'FLUF' - -/* FUNCTIONS ****************************************************************/ - -VOID * -FF_Malloc(FF_T_UINT32 allocSize) -{ - return ExAllocatePoolWithTag(PagedPool, allocSize, TAG_FULLFAT); -} - -VOID -FF_Free(VOID *pBuffer) -{ - ExFreePoolWithTag(pBuffer, TAG_FULLFAT); -} - -FF_T_SINT32 -FatWriteBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam) -{ - DPRINT1("FatWriteBlocks %p %d %d %p\n", pBuffer, SectorAddress, Count, pParam); - - return 0; -} - -FF_T_SINT32 -FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam) -{ - LARGE_INTEGER Offset; - //PVOID Buffer; - PVCB Vcb = (PVCB)pParam; - //PBCB Bcb; - ULONG SectorSize = 512; // FIXME: hardcoding 512 is bad - IO_STATUS_BLOCK IoSb; - - DPRINT("FatReadBlocks %p %d %d %p\n", DestBuffer, SectorAddress, Count, pParam); - - /* Calculate the offset */ - Offset.QuadPart = Int32x32To64(SectorAddress, SectorSize); -#if 0 - if (!CcMapData(Vcb->StreamFileObject, - &Offset, - Count * SectorSize, - TRUE, - &Bcb, - &Buffer)) - { - ASSERT(FALSE); - /* Mapping failed */ - return 0; - } - - /* Copy data to the buffer */ - RtlCopyMemory(DestBuffer, Buffer, Count * SectorSize); - - /* Unpin unneeded data */ - CcUnpinData(Bcb); -#else - CcCopyRead(Vcb->StreamFileObject, &Offset, Count * SectorSize, TRUE, DestBuffer, &IoSb); -#endif - - /* Return amount of read data in sectors */ - return Count; -} - -FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError) -{ - OEM_STRING AnsiName; - CHAR AnsiNameBuf[512]; - NTSTATUS Status; - - /* Convert the name to ANSI */ - AnsiName.Buffer = AnsiNameBuf; - AnsiName.Length = 0; - AnsiName.MaximumLength = sizeof(AnsiNameBuf); - RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, pathW, FALSE); - if (!NT_SUCCESS(Status)) - { - ASSERT(FALSE); - } - - DPRINT1("Opening '%s'\n", AnsiName.Buffer); - - /* Call FullFAT's handler */ - 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/lock.c b/reactos/drivers/filesystems/fastfat_new/lock.c deleted file mode 100644 index 509aa50b81c..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/lock.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/lock.c - * PURPOSE: Lock support routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatiLockControl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - TYPE_OF_OPEN TypeOfOpen; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - NTSTATUS Status; - - /* Get IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Determine type of open */ - TypeOfOpen = FatDecodeFileObject(IrpSp->FileObject, &Vcb, &Fcb, &Ccb); - - /* Only user file open is allowed */ - if (TypeOfOpen != UserFileOpen) - { - FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER); - return STATUS_INVALID_PARAMETER; - } - - /* Acquire shared FCB lock */ - if (!FatAcquireSharedFcb(IrpContext, Fcb)) - { - UNIMPLEMENTED; - //Status = FatFsdPostRequest(IrpContext, Irp); - Status = STATUS_NOT_IMPLEMENTED; - return Status; - } - - /* Check oplock state */ - Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, - Irp, - IrpContext, - FatOplockComplete, - NULL); - - if (Status != STATUS_SUCCESS) - { - /* Release FCB lock */ - FatReleaseFcb(IrpContext, Fcb); - - return Status; - } - - /* Process the lock */ - Status = FsRtlProcessFileLock(&Fcb->Fcb.Lock, Irp, NULL); - - /* Update Fast I/O state */ - Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, NULL, 0); - - /* Release FCB lock */ - FatReleaseFcb(IrpContext, Fcb); - - return Status; -} - -NTSTATUS -NTAPI -FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PFAT_IRP_CONTEXT IrpContext; - NTSTATUS Status; - BOOLEAN TopLevel; - - DPRINT1("FatLockControl()\n"); - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Set Top Level IRP if not set */ - TopLevel = FatIsTopLevelIrp(Irp); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, IoIsOperationSynchronous(Irp)); - - /* Call internal function */ - Status = FatiLockControl(IrpContext, Irp); - - /* Reset Top Level IRP */ - if (TopLevel) IoSetTopLevelIrp(NULL); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -VOID -NTAPI -FatOplockComplete(IN PVOID Context, - IN PIRP Irp) -{ - UNIMPLEMENTED; -} - -VOID -NTAPI -FatPrePostIrp(IN PVOID Context, - IN PIRP Irp) -{ - UNIMPLEMENTED; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/rw.c b/reactos/drivers/filesystems/fastfat_new/rw.c deleted file mode 100644 index 1508b0f6239..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/rw.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/rw.c - * PURPOSE: Read/write support - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -NTAPI -FatiRead(PFAT_IRP_CONTEXT IrpContext) -{ - ULONG NumberOfBytes; - LARGE_INTEGER ByteOffset; - PFILE_OBJECT FileObject; - TYPE_OF_OPEN OpenType; - PIO_STACK_LOCATION IrpSp = IrpContext->Stack; - PFCB Fcb; - PVCB Vcb; - PCCB Ccb; - PVOID Buffer; - LONG BytesRead; - - FileObject = IrpSp->FileObject; - NumberOfBytes = IrpSp->Parameters.Read.Length; - ByteOffset = IrpSp->Parameters.Read.ByteOffset; - if (NumberOfBytes == 0) - { - FatCompleteRequest(IrpContext, IrpContext->Irp, STATUS_SUCCESS); - return STATUS_SUCCESS; - } - - OpenType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - - DPRINT("FatiRead() Fcb %p, Name %wZ, Offset %d, Length %d, Handle %p\n", - Fcb, &FileObject->FileName, ByteOffset.LowPart, NumberOfBytes, Fcb->FatHandle); - - /* Perform actual read */ - - if (IrpContext->MinorFunction & IRP_MN_MDL) - { - DPRINT1("MDL read\n"); - } - else - { - Buffer = FatMapUserBuffer(IrpContext->Irp); - DPRINT("Normal cached read, buffer %p\n"); - - /* Set offset */ - FF_Seek(Fcb->FatHandle, ByteOffset.LowPart, FF_SEEK_SET); - - /* Read */ - BytesRead = FF_Read(Fcb->FatHandle, NumberOfBytes, 1, Buffer); - DPRINT("Read %d bytes\n", BytesRead); - - /* Indicate we read requested amount of bytes */ - IrpContext->Irp->IoStatus.Information = BytesRead; - IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS; - } - - /* Complete the request */ - FatCompleteRequest(IrpContext, IrpContext->Irp, STATUS_SUCCESS); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - BOOLEAN TopLevel, CanWait; - PFAT_IRP_CONTEXT IrpContext; - - CanWait = TRUE; - TopLevel = FALSE; - Status = STATUS_INVALID_DEVICE_REQUEST; - /* Get CanWait flag */ - if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) - CanWait = IoIsOperationSynchronous(Irp); - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - if (DeviceObject != FatGlobalData.DiskDeviceObject) - { - /* Set Top Level IRP if not set */ - TopLevel = FatIsTopLevelIrp(Irp); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, CanWait); - - /* Perform the actual read */ - Status = FatiRead(IrpContext); - - /* Restore top level Irp */ - if (TopLevel) - IoSetTopLevelIrp(NULL); - } - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -NTSTATUS -NTAPI -FatWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatWrite()\n"); - return STATUS_NOT_IMPLEMENTED; -} - - diff --git a/reactos/drivers/filesystems/fastfat_new/shutdown.c b/reactos/drivers/filesystems/fastfat_new/shutdown.c deleted file mode 100644 index 4fd545c05c1..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/shutdown.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/shutdown.c - * PURPOSE: Shutdown support routines - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatShutdown(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); - - return STATUS_NOT_IMPLEMENTED; -} - -/* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/volume.c b/reactos/drivers/filesystems/fastfat_new/volume.c deleted file mode 100644 index a6a30abed38..00000000000 --- a/reactos/drivers/filesystems/fastfat_new/volume.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GNU GPLv3 as published by the Free Software Foundation - * FILE: drivers/filesystems/fastfat/volume.c - * PURPOSE: Volume information - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ****************************************************************/ - -NTSTATUS -NTAPI -FatiQueryFsVolumeInfo(PVCB Vcb, - PFILE_FS_VOLUME_INFORMATION Buffer, - PLONG Length) -{ - ULONG ByteSize; - NTSTATUS Status = STATUS_SUCCESS; - - /* Deduct the minimum written length */ - *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]); - - /* Zero it */ - RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION)); - - DPRINT("Serial number 0x%x, label length %d\n", - Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength); - - /* Save serial number */ - Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber; - - /* Set max byte size */ - ByteSize = Vcb->Vpb->VolumeLabelLength; - - /* Check buffer length and reduce byte size if needed */ - if (*Length < Vcb->Vpb->VolumeLabelLength) - { - /* Copy only up to what buffer size was provided */ - ByteSize = *Length; - Status = STATUS_BUFFER_OVERFLOW; - } - - /* Copy volume label */ - Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength; - RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize); - *Length -= ByteSize; - - return Status; -} - -NTSTATUS -NTAPI -FatiQueryFsSizeInfo(PVCB Vcb, - PFILE_FS_SIZE_INFORMATION Buffer, - PLONG Length) -{ - FF_PARTITION *Partition; - NTSTATUS Status = STATUS_SUCCESS; - - /* Deduct the minimum written length */ - *Length -= sizeof(FILE_FS_SIZE_INFORMATION); - - /* Zero it */ - RtlZeroMemory(Buffer, sizeof(FILE_FS_SIZE_INFORMATION)); - - /* Reference FullFAT's partition */ - Partition = Vcb->Ioman->pPartition; - - /* Set values */ - Buffer->AvailableAllocationUnits.LowPart = Partition->FreeClusterCount; - Buffer->TotalAllocationUnits.LowPart = Partition->NumClusters; - Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster; - Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector; - - DPRINT1("Total %d, free %d, SPC %d, BPS %d\n", Partition->NumClusters, - Partition->FreeClusterCount, Vcb->Bpb.SectorsPerCluster, Vcb->Bpb.BytesPerSector); - - return Status; -} - -NTSTATUS -NTAPI -FatiQueryFsDeviceInfo(PVCB Vcb, - PFILE_FS_DEVICE_INFORMATION Buffer, - PLONG Length) -{ - /* Deduct the minimum written length */ - *Length -= sizeof(FILE_FS_DEVICE_INFORMATION); - - /* Zero it */ - RtlZeroMemory(Buffer, sizeof(FILE_FS_DEVICE_INFORMATION)); - - /* Set values */ - Buffer->DeviceType = FILE_DEVICE_DISK; - Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics; - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) -{ - PFILE_OBJECT FileObject; - PIO_STACK_LOCATION IrpSp; - FILE_INFORMATION_CLASS InfoClass; - TYPE_OF_OPEN FileType; - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - LONG Length; - PVOID Buffer; - BOOLEAN VcbLocked = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - - /* Get IRP stack location */ - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - /* Get the file object */ - FileObject = IrpSp->FileObject; - - /* Copy variables to something with shorter names */ - InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass; - Length = IrpSp->Parameters.QueryVolume.Length; - Buffer = Irp->AssociatedIrp.SystemBuffer; - - DPRINT("FatiQueryVolumeInfo\n", 0); - DPRINT("\tIrp = %08lx\n", Irp); - DPRINT("\tLength = %08lx\n", Length); - DPRINT("\tFsInformationClass = %08lx\n", InfoClass); - DPRINT("\tBuffer = %08lx\n", Buffer); - - FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); - - DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); - - switch (InfoClass) - { - case FileFsVolumeInformation: - /* Acquired the shared VCB lock */ - if (!FatAcquireSharedVcb(IrpContext, Vcb)) - { - ASSERT(FALSE); - } - - /* Remember we locked it */ - VcbLocked = TRUE; - - /* Call FsVolumeInfo handler */ - Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length); - break; - - case FileFsSizeInformation: - /* Call FsVolumeInfo handler */ - Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length); - break; - - case FileFsDeviceInformation: - Status = FatiQueryFsDeviceInfo(Vcb, Buffer, &Length); - break; - - case FileFsAttributeInformation: - UNIMPLEMENTED; - //Status = FatiQueryFsAttributeInfo(IrpContext, Vcb, Buffer, &Length); - break; - - case FileFsFullSizeInformation: - UNIMPLEMENTED; - //Status = FatiQueryFsFullSizeInfo(IrpContext, Vcb, Buffer, &Length); - break; - - default: - Status = STATUS_INVALID_PARAMETER; - } - - /* Set IoStatus.Information to amount of filled bytes */ - Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length; - - /* Release VCB lock */ - if (VcbLocked) FatReleaseVcb(IrpContext, Vcb); - - /* Complete request and return status */ - FatCompleteRequest(IrpContext, Irp, Status); - return Status; -} - -NTSTATUS -NTAPI -FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - BOOLEAN TopLevel, CanWait; - PFAT_IRP_CONTEXT IrpContext; - - CanWait = TRUE; - TopLevel = FALSE; - Status = STATUS_INVALID_DEVICE_REQUEST; - - /* Get CanWait flag */ - if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) - CanWait = IoIsOperationSynchronous(Irp); - - /* Enter FsRtl critical region */ - FsRtlEnterFileSystem(); - - /* Set Top Level IRP if not set */ - TopLevel = FatIsTopLevelIrp(Irp); - - /* Build an irp context */ - IrpContext = FatBuildIrpContext(Irp, CanWait); - - /* Call the request handler */ - Status = FatiQueryVolumeInfo(IrpContext, Irp); - - /* Restore top level Irp */ - if (TopLevel) - IoSetTopLevelIrp(NULL); - - /* Leave FsRtl critical region */ - FsRtlExitFileSystem(); - - return Status; -} - -NTSTATUS -NTAPI -FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - DPRINT1("FatSetVolumeInfo()\n"); - return STATUS_NOT_IMPLEMENTED; -} - -VOID -NTAPI -FatReadStreamFile(PVCB Vcb, - ULONGLONG ByteOffset, - ULONG ByteSize, - PBCB *Bcb, - PVOID *Buffer) -{ - LARGE_INTEGER Offset; - - Offset.QuadPart = ByteOffset; - - if (!CcMapData(Vcb->StreamFileObject, - &Offset, - ByteSize, - TRUE, // FIXME: CanWait - Bcb, - Buffer)) - { - ASSERT(FALSE); - } -} - -BOOLEAN -NTAPI -FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext, - PVCB Vcb, - IN BOOLEAN Force) -{ - /* We never allow deletion of a volume for now */ - return FALSE; -} - -/* EOF */ diff --git a/reactos/sdk/lib/3rdparty/CMakeLists.txt b/reactos/sdk/lib/3rdparty/CMakeLists.txt index 0048a9fcdb0..3bcf67656b0 100644 --- a/reactos/sdk/lib/3rdparty/CMakeLists.txt +++ b/reactos/sdk/lib/3rdparty/CMakeLists.txt @@ -3,7 +3,6 @@ add_subdirectory(adns) add_subdirectory(bzip2) add_subdirectory(cardlib) add_subdirectory(freetype) -add_subdirectory(fullfat) add_subdirectory(libmpg123) add_subdirectory(libsamplerate) add_subdirectory(libwine) diff --git a/reactos/sdk/lib/3rdparty/fullfat/CMakeLists.txt b/reactos/sdk/lib/3rdparty/fullfat/CMakeLists.txt deleted file mode 100644 index 0de78c24dff..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ - -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/fullfat) -add_definitions(-D__NTDRIVER__) - -list(APPEND SOURCE - ff_blk.c - ff_crc.c - ff_dir.c - ff_error.c - ff_fat.c - ff_file.c - ff_hash.c - ff_ioman.c - ff_memory.c - ff_safety.c - ff_string.c - ff_time.c) - -add_library(fullfat ${SOURCE}) -add_dependencies(fullfat bugcodes xdk) - -if((NOT MSVC) AND (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")) - add_target_compile_flags(fullfat "-Wno-unused-but-set-variable") -endif() diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_blk.c b/reactos/sdk/lib/3rdparty/fullfat/ff_blk.c deleted file mode 100644 index d97b1a628c4..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_blk.c +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_blk.c - * @author James Walmsley - * @ingroup BLK - * - * @defgroup BLK Block Calculater - * @brief Handle Block Number conversions - * - * Helps calculate block numbers. - **/ - -#include "ff_blk.h" -/** - * @private - **/ -FF_T_UINT32 FF_getClusterChainNumber(FF_IOMAN *pIoman, FF_T_UINT32 nEntry, FF_T_UINT16 nEntrySize) { - FF_PARTITION *pPart = pIoman->pPartition; - FF_T_UINT32 clusterChainNumber = nEntry / (pIoman->BlkSize * (pPart->SectorsPerCluster * pPart->BlkFactor) / nEntrySize); - return clusterChainNumber; -} - -FF_T_UINT32 FF_getClusterPosition(FF_IOMAN *pIoman, FF_T_UINT32 nEntry, FF_T_UINT16 nEntrySize) { - return nEntry % ((pIoman->BlkSize * (pIoman->pPartition->SectorsPerCluster * pIoman->pPartition->BlkFactor)) / nEntrySize); -} -/** - * @private - **/ -FF_T_UINT32 FF_getMajorBlockNumber(FF_IOMAN *pIoman, FF_T_UINT32 nEntry, FF_T_UINT16 nEntrySize) { - FF_PARTITION *pPart = pIoman->pPartition; - FF_T_UINT32 relClusterEntry = nEntry % (pIoman->BlkSize * (pPart->SectorsPerCluster * pPart->BlkFactor) / nEntrySize); - FF_T_UINT32 majorBlockNumber = relClusterEntry / (pPart->BlkSize / nEntrySize); - return majorBlockNumber; -} -/** - * @private - **/ -FF_T_UINT8 FF_getMinorBlockNumber(FF_IOMAN *pIoman, FF_T_UINT32 nEntry, FF_T_UINT16 nEntrySize) { - FF_PARTITION *pPart = pIoman->pPartition; - FF_T_UINT32 relClusterEntry = nEntry % (pIoman->BlkSize * (pPart->SectorsPerCluster * pPart->BlkFactor) / nEntrySize); - FF_T_UINT16 relmajorBlockEntry = (FF_T_UINT16)(relClusterEntry % (pPart->BlkSize / nEntrySize)); - FF_T_UINT8 minorBlockNumber = (FF_T_UINT8) (relmajorBlockEntry / (pIoman->BlkSize / nEntrySize)); - return minorBlockNumber; -} -/** - * @private - **/ -FF_T_UINT32 FF_getMinorBlockEntry(FF_IOMAN *pIoman, FF_T_UINT32 nEntry, FF_T_UINT16 nEntrySize) { - FF_PARTITION *pPart = pIoman->pPartition; - FF_T_UINT32 relClusterEntry = nEntry % (pIoman->BlkSize * (pPart->SectorsPerCluster * pPart->BlkFactor) / nEntrySize); - FF_T_UINT32 relmajorBlockEntry = (FF_T_UINT32)(relClusterEntry % (pPart->BlkSize / nEntrySize)); - FF_T_UINT32 minorBlockEntry = (FF_T_UINT32)(relmajorBlockEntry % (pIoman->BlkSize / nEntrySize)); - return minorBlockEntry; -} - diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_crc.c b/reactos/sdk/lib/3rdparty/fullfat/ff_crc.c deleted file mode 100644 index 2b6f76ba5a2..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_crc.c +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_crc.c - * @author James Walmsley - * @ingroup CRC - * - * @defgroup CRC CRC Checksums for Strings - * @brief Provides fast hashing functions. - * - **/ - -#include "ff_crc.h" - - -static const FF_T_UINT32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -FF_T_UINT32 FF_GetCRC32(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) { - - register FF_T_UINT32 crc = 0xFFFFFFFF; - - while(stLength--) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc^*pbyData++) & 0x000000FF]; - } - - return (crc ^ 0xFFFFFFFF); -} - - - - -static const FF_T_UINT8 crc16_table_low[256] = -{ - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, - 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, -}; - -static const FF_T_UINT8 crc16_table_high[256] = -{ - 0x000, 0x0c0, 0x0c1, 0x001, 0x0c3, 0x003, 0x002, 0x0c2, - 0x0c6, 0x006, 0x007, 0x0c7, 0x005, 0x0c5, 0x0c4, 0x004, - 0x0cc, 0x00c, 0x00d, 0x0cd, 0x00f, 0x0cf, 0x0ce, 0x00e, - 0x00a, 0x0ca, 0x0cb, 0x00b, 0x0c9, 0x009, 0x008, 0x0c8, - 0x0d8, 0x018, 0x019, 0x0d9, 0x01b, 0x0db, 0x0da, 0x01a, - 0x01e, 0x0de, 0x0df, 0x01f, 0x0dd, 0x01d, 0x01c, 0x0dc, - 0x014, 0x0d4, 0x0d5, 0x015, 0x0d7, 0x017, 0x016, 0x0d6, - 0x0d2, 0x012, 0x013, 0x0d3, 0x011, 0x0d1, 0x0d0, 0x010, - 0x0f0, 0x030, 0x031, 0x0f1, 0x033, 0x0f3, 0x0f2, 0x032, - 0x036, 0x0f6, 0x0f7, 0x037, 0x0f5, 0x035, 0x034, 0x0f4, - 0x03c, 0x0fc, 0x0fd, 0x03d, 0x0ff, 0x03f, 0x03e, 0x0fe, - 0x0fa, 0x03a, 0x03b, 0x0fb, 0x039, 0x0f9, 0x0f8, 0x038, - 0x028, 0x0e8, 0x0e9, 0x029, 0x0eb, 0x02b, 0x02a, 0x0ea, - 0x0ee, 0x02e, 0x02f, 0x0ef, 0x02d, 0x0ed, 0x0ec, 0x02c, - 0x0e4, 0x024, 0x025, 0x0e5, 0x027, 0x0e7, 0x0e6, 0x026, - 0x022, 0x0e2, 0x0e3, 0x023, 0x0e1, 0x021, 0x020, 0x0e0, - 0x0a0, 0x060, 0x061, 0x0a1, 0x063, 0x0a3, 0x0a2, 0x062, - 0x066, 0x0a6, 0x0a7, 0x067, 0x0a5, 0x065, 0x064, 0x0a4, - 0x06c, 0x0ac, 0x0ad, 0x06d, 0x0af, 0x06f, 0x06e, 0x0ae, - 0x0aa, 0x06a, 0x06b, 0x0ab, 0x069, 0x0a9, 0x0a8, 0x068, - 0x078, 0x0b8, 0x0b9, 0x079, 0x0bb, 0x07b, 0x07a, 0x0ba, - 0x0be, 0x07e, 0x07f, 0x0bf, 0x07d, 0x0bd, 0x0bc, 0x07c, - 0x0b4, 0x074, 0x075, 0x0b5, 0x077, 0x0b7, 0x0b6, 0x076, - 0x072, 0x0b2, 0x0b3, 0x073, 0x0b1, 0x071, 0x070, 0x0b0, - 0x050, 0x090, 0x091, 0x051, 0x093, 0x053, 0x052, 0x092, - 0x096, 0x056, 0x057, 0x097, 0x055, 0x095, 0x094, 0x054, - 0x09c, 0x05c, 0x05d, 0x09d, 0x05f, 0x09f, 0x09e, 0x05e, - 0x05a, 0x09a, 0x09b, 0x05b, 0x099, 0x059, 0x058, 0x098, - 0x088, 0x048, 0x049, 0x089, 0x04b, 0x08b, 0x08a, 0x04a, - 0x04e, 0x08e, 0x08f, 0x04f, 0x08d, 0x04d, 0x04c, 0x08c, - 0x044, 0x084, 0x085, 0x045, 0x087, 0x047, 0x046, 0x086, - 0x082, 0x042, 0x043, 0x083, 0x041, 0x081, 0x080, 0x040, -}; - -/***************************************************************************** - * Description: Function to 16 bit CRC check a block of memory - - * - * Parameters: pbyData - Pointer to the source data - * stLength - The length to CRC - * - * Return value: The 16 bit CRC value - * - *****************************************************************************/ - -FF_T_UINT16 FF_GetCRC16(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) { - FF_T_UINT8 bTableValue; - FF_T_UINT16 wCRC = 0; - - while (stLength--) { - bTableValue = (FF_T_UINT8)((wCRC & 0x00FF) ^ *pbyData++); - wCRC = (FF_T_UINT16)(((crc16_table_high[bTableValue]) << 8) - + (crc16_table_low[bTableValue] ^ ((wCRC >> 8) & 0x00FF))); - } - - return wCRC; -} - - -static const FF_T_UINT8 crc8_table[256] = -{ - 0, 94, 188, 226, 97, 63, 221, 131, - 194, 156, 126, 32, 163, 253, 31, 65, - 157, 195, 33, 127, 252, 162, 64, 30, - 95, 1, 227, 189, 62, 96, 130, 220, - 35, 125, 159, 193, 66, 28, 254, 160, - 225, 191, 93, 3, 128, 222, 60, 98, - 190, 224, 2, 92, 223, 129, 99, 61, - 124, 34, 192, 158, 29, 67, 161, 255, - 70, 24, 250, 164, 39, 121, 155, 197, - 132, 218, 56, 102, 229, 187, 89, 7, - 219, 133, 103, 57, 186, 228, 6, 88, - 25, 71, 165, 251, 120, 38, 196, 154, - 101, 59, 217, 135, 4, 90, 184, 230, - 167, 249, 27, 69, 198, 152, 122, 36, - 248, 166, 68, 26, 153, 199, 37, 123, - 58, 100, 134, 216, 91, 5, 231, 185, - 140, 210, 48, 110, 237, 179, 81, 15, - 78, 16, 242, 172, 47, 113, 147, 205, - 17, 79, 173, 243, 112, 46, 204, 146, - 211, 141, 111, 49, 178, 236, 14, 80, - 175, 241, 19, 77, 206, 144, 114, 44, - 109, 51, 209, 143, 12, 82, 176, 238, - 50, 108, 142, 208, 83, 13, 239, 177, - 240, 174, 76, 18, 145, 207, 45, 115, - 202, 148, 118, 40, 171, 245, 23, 73, - 8, 86, 180, 234, 105, 55, 213, 139, - 87, 9, 235, 181, 54, 104, 138, 212, - 149, 203, 41, 119, 244, 170, 72, 22, - 233, 183, 85, 11, 136, 214, 52, 106, - 43, 117, 151, 201, 74, 20, 246, 168, - 116, 42, 200, 150, 21, 75, 169, 247, - 182, 232, 10, 84, 215, 137, 107, 53 -}; - -/***************************************************************************** - * Description: Function to CRC check a block of memory - * - * Parameters: pbyData - Pointer to the source data - * stLength - The length to CRC - * - * Return value: The 8 bit CRC value - * - *****************************************************************************/ - -FF_T_UINT8 FF_GetCRC8(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) { - FF_T_UINT8 byCRC = 0, byData; - while (stLength--) { - byData = *pbyData++; - byCRC = crc8_table[(byCRC ^ byData)]; - } - return byCRC; -} diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_dir.c b/reactos/sdk/lib/3rdparty/fullfat/ff_dir.c deleted file mode 100644 index b9767352b8e..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_dir.c +++ /dev/null @@ -1,2627 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_dir.c - * @author James Walmsley - * @ingroup DIR - * - * @defgroup DIR Handles Directory Traversal - * @brief Handles DIR access and traversal. - * - * Provides FindFirst() and FindNext() Interfaces - **/ - -#include "ff_dir.h" -#include "ff_string.h" -#include "ff_unicode.h" -#include - - -#ifdef FF_UNICODE_SUPPORT -#include -#endif - -#ifdef WIN32 -#else -#include // tolower() -int strcasecmp(const char *s1, const char *s2) -{ - unsigned char c1,c2; - do { - c1 = *s1++; - c2 = *s2++; - c1 = (unsigned char) tolower( (unsigned char) c1); - c2 = (unsigned char) tolower( (unsigned char) c2); - } - while((c1 == c2) && (c1 != '\0')); - return (int) c1-c2; -} -#endif - - -#ifdef FF_UNICODE_SUPPORT -static void FF_ProcessShortName(FF_T_WCHAR *name); -#else -static void FF_ProcessShortName(FF_T_INT8 *name); -#endif - -void FF_lockDIR(FF_IOMAN *pIoman) { - FF_PendSemaphore(pIoman->pSemaphore); // Use Semaphore to protect DIR modifications. - { - while((pIoman->Locks & FF_DIR_LOCK)) { - FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_Yield(); // Keep Releasing and Yielding until we have the DIR protector. - FF_PendSemaphore(pIoman->pSemaphore); - } - pIoman->Locks |= FF_DIR_LOCK; - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -} - -void FF_unlockDIR(FF_IOMAN *pIoman) { - FF_PendSemaphore(pIoman->pSemaphore); - { - pIoman->Locks &= ~FF_DIR_LOCK; - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -} - -static FF_T_UINT8 FF_CreateChkSum(const FF_T_UINT8 *pa_pShortName) { - FF_T_UINT8 cNameLen; - FF_T_UINT8 ChkSum = 0; - - for(cNameLen = 11; cNameLen != 0; cNameLen--) { - ChkSum = ((ChkSum & 1) ? 0x80 : 0) + (ChkSum >> 1) + *pa_pShortName++; - } - return ChkSum; -} - - -FF_ERROR FF_FindNextInDir(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_FETCH_CONTEXT *pFetchContext) { - - FF_T_UINT8 numLFNs; - FF_T_UINT8 EntryBuffer[32]; - FF_ERROR Error; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - for(; pDirent->CurrentItem < 0xFFFF; pDirent->CurrentItem += 1) { - - Error = FF_FetchEntryWithContext(pIoman, pDirent->CurrentItem, pFetchContext, EntryBuffer); - - if(Error) { - return Error; - } - - if(EntryBuffer[0] != 0xE5) { - if(FF_isEndOfDir(EntryBuffer)){ - return FF_ERR_DIR_END_OF_DIR; - } - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - if((pDirent->Attrib & FF_FAT_ATTR_LFN) == FF_FAT_ATTR_LFN) { - // LFN Processing - numLFNs = (FF_T_UINT8)(EntryBuffer[0] & ~0x40); - //pDirent->NumLFNs = numLFNs; -#ifdef FF_LFN_SUPPORT - Error = FF_PopulateLongDirent(pIoman, pDirent, pDirent->CurrentItem, pFetchContext); - if(Error) { - return Error; - } - return FF_ERR_NONE; -#else - pDirent->CurrentItem += (numLFNs - 1); -#endif - } else if((pDirent->Attrib & FF_FAT_ATTR_VOLID) == FF_FAT_ATTR_VOLID) { - // Do Nothing - - } else { - FF_PopulateShortDirent(pIoman, pDirent, EntryBuffer); - pDirent->CurrentItem += 1; - return FF_ERR_NONE; - } - } - } - - return FF_ERR_DIR_END_OF_DIR; -} - -#ifdef FF_UNICODE_SUPPORT -static FF_T_BOOL FF_ShortNameExists(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_T_WCHAR *szShortName, FF_ERROR *pError) { -#else -static FF_T_BOOL FF_ShortNameExists(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_T_INT8 *szShortName, FF_ERROR *pError) { -#endif - - FF_T_UINT16 i; - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT8 Attrib; - FF_FETCH_CONTEXT FetchContext; - -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR UTF16EntryBuffer[32]; -#endif - -#ifdef FF_HASH_CACHE - FF_T_UINT32 ulHash; -#endif - - *pError = FF_ERR_NONE; - - -#ifdef FF_HASH_CACHE - if(!FF_DirHashed(pIoman, ulDirCluster)) { - // Hash the directory - FF_HashDir(pIoman, ulDirCluster); - } - -#if FF_HASH_FUNCTION == CRC16 - ulHash = (FF_T_UINT32) FF_GetCRC16((FF_T_UINT8 *) szShortName, strlen(szShortName)); -#elif FF_HASH_FUNCTION == CRC8 - ulHash = (FF_T_UINT32) FF_GetCRC8((FF_T_UINT8 *) szShortName, strlen(szShortName)); -#endif - - if(!FF_CheckDirentHash(pIoman, ulDirCluster, ulHash)) { - return FF_FALSE; - } - -#endif - - *pError = FF_InitEntryFetch(pIoman, ulDirCluster, &FetchContext); - if(*pError) { - return FF_FALSE; - } - - for(i = 0; i < 0xFFFF; i++) { - *pError = FF_FetchEntryWithContext(pIoman, i, &FetchContext, EntryBuffer); - if(*pError) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_FALSE; - } - Attrib = FF_getChar(EntryBuffer, FF_FAT_DIRENT_ATTRIB); - if(FF_getChar(EntryBuffer, 0x00) != 0xE5) { - if(Attrib != FF_FAT_ATTR_LFN) { -#ifdef FF_UNICODE_SUPPORT - // Convert Entry Buffer into UTF16 - FF_cstrntowcs(UTF16EntryBuffer, (FF_T_INT8 *) EntryBuffer, 32); - FF_ProcessShortName(UTF16EntryBuffer); -#else - FF_ProcessShortName((FF_T_INT8 *)EntryBuffer); -#endif - if(FF_isEndOfDir(EntryBuffer)) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_FALSE; - } -#ifdef FF_UNICODE_SUPPORT - if(wcscmp(szShortName, UTF16EntryBuffer) == 0) { -#else - if(strcmp(szShortName, (FF_T_INT8 *)EntryBuffer) == 0) { -#endif - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_TRUE; - } - } - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_FALSE; -} - - -#ifdef FF_UNICODE_SUPPORT -FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_WCHAR *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError) { -#else -FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError) { -#endif - - FF_FETCH_CONTEXT FetchContext; - FF_T_UINT8 *src; // Pointer to read from pBuffer - FF_T_UINT8 *lastSrc; -#ifdef FF_UNICODE_UTF8_SUPPORT - FF_T_SINT32 utf8Error; - FF_T_UINT8 bSurrogate = FF_FALSE; -#endif -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR *ptr; // Pointer to store a LFN -#else - FF_T_INT8 *ptr; // Pointer to store a LFN -#endif -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR *lastPtr = pDirent->FileName + sizeof(pDirent->FileName); -#else - FF_T_INT8 *lastPtr = pDirent->FileName + sizeof(pDirent->FileName); -#endif - FF_T_UINT8 CheckSum = 0; - FF_T_UINT8 lastAttrib; - FF_T_INT8 totalLFNs = 0; - FF_T_INT8 numLFNs = 0; - FF_T_INT32 i; - FF_T_UINT16 lfnItem = 0; - - pError = NULL; - - pDirent->CurrentItem = 0; - pDirent->Attrib = 0; - - FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - - while(pDirent->CurrentItem < 0xFFFF) { - if (FF_FetchEntryWithContext(pIoman, pDirent->CurrentItem, &FetchContext, NULL)) { - break; - } - lastSrc = FetchContext.pBuffer->pBuffer + pIoman->BlkSize; - for (src = FetchContext.pBuffer->pBuffer; src < lastSrc; src += 32, pDirent->CurrentItem++) { - if (FF_isEndOfDir(src)) { // 0x00: end-of-dir - FF_CleanupEntryFetch(pIoman, &FetchContext); - return 0; - } - if (src[0] == 0xE5) { // Entry not used - pDirent->Attrib = 0; - continue; - } - lastAttrib = pDirent->Attrib; - pDirent->Attrib = FF_getChar(src, FF_FAT_DIRENT_ATTRIB); - if((pDirent->Attrib & FF_FAT_ATTR_LFN) == FF_FAT_ATTR_LFN) { - // LFN Processing -#ifdef FF_LFN_SUPPORT - if (numLFNs == 0 || (lastAttrib & FF_FAT_ATTR_LFN) != FF_FAT_ATTR_LFN) { - totalLFNs = numLFNs = (FF_T_UINT8)(src[0] & ~0x40); - lfnItem = pDirent->CurrentItem; - CheckSum = FF_getChar(src, FF_FAT_LFN_CHECKSUM); - lastPtr[-1] = '\0'; - } - if (numLFNs) { - numLFNs--; - ptr = pDirent->FileName + (numLFNs * 13); - - /* - This section needs to extract the name and do the comparison - dependent on UNICODE settings in the ff_config.h file. - */ -#ifdef FF_UNICODE_SUPPORT - // Add UTF-16 Routine here - memcpy(ptr, &src[FF_FAT_LFN_NAME_1], 10); // Copy first 5 UTF-16 chars (10 bytes). - ptr += 5; // Increment Filename pointer 5 utf16 chars. - - memcpy(ptr, &src[FF_FAT_LFN_NAME_2], 12); //Copy next 6 chars (12 bytes). - ptr += 6; - - memcpy(ptr, &src[FF_FAT_LFN_NAME_3], 4); // You're getting the idea by now! - ptr += 2; - -#endif -#ifdef FF_UNICODE_UTF8_SUPPORT - // UTF-8 Routine here - for(i = 0; i < 5 && ptr < lastPtr; i++) { - // Was there a surrogate sequence? -- Add handling here. - utf8Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) ptr, (FF_T_UINT16 *) &src[FF_FAT_LFN_NAME_1 + (2*i)], lastPtr - ptr); - if(utf8Error > 0) { - ptr += utf8Error; - - } else { - if(utf8Error == FF_ERR_UNICODE_INVALID_SEQUENCE) { - // Handle potential surrogate sequence across entries. - - } - } - } - - for(i = 0; i < 6 && ptr < lastPtr; i++) { - // Was there a surrogate sequence? -- To add handling here. - utf8Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) ptr, (FF_T_UINT16 *) &src[FF_FAT_LFN_NAME_2 + (2*i)], lastPtr - ptr); - if(utf8Error > 0) { - ptr += utf8Error; - } else { - if(utf8Error == FF_ERR_UNICODE_INVALID_SEQUENCE) { - // Handle potential surrogate sequence across entries. - } - } - } - - for(i = 0; i < 2 && ptr < lastPtr; i++) { - // Was there a surrogate sequence? -- To add handling here. - utf8Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) ptr, (FF_T_UINT16 *) &src[FF_FAT_LFN_NAME_3 + (2*i)], lastPtr - ptr); - if(utf8Error > 0) { - ptr += utf8Error; - } else { - if(utf8Error == FF_ERR_UNICODE_INVALID_SEQUENCE) { - // Handle potential surrogate sequence across entries. - } - } - } - -#endif -#ifndef FF_UNICODE_SUPPORT -#ifndef FF_UNICODE_UTF8_SUPPORT - for(i = 0; i < 10 && ptr < lastPtr; i += 2) - *(ptr++) = src[FF_FAT_LFN_NAME_1 + i]; - - for(i = 0; i < 12 && ptr < lastPtr; i += 2) - *(ptr++) = src[FF_FAT_LFN_NAME_2 + i]; - - for(i = 0; i < 4 && ptr < lastPtr; i += 2) - *(ptr++) = src[FF_FAT_LFN_NAME_3 + i]; - - if (numLFNs == totalLFNs-1 && ptr < lastPtr) - *ptr = '\0'; // Important when name len is multiple of 13 -#endif -#endif - if (numLFNs == totalLFNs-1 && ptr < lastPtr) - *ptr = '\0'; // Important when name len is multiple of 13 - - } -#endif - continue; - } - if ((pDirent->Attrib & FF_FAT_ATTR_VOLID) == FF_FAT_ATTR_VOLID) { - totalLFNs = 0; - continue; - } -#ifdef FF_LFN_SUPPORT - if(!totalLFNs || CheckSum != FF_CreateChkSum(src)) -#endif - { -#ifdef FF_UNICODE_SUPPORT - for(i = 0; i < 11; i++) { - pDirent->FileName[i] = (FF_T_WCHAR) src[i]; - } - FF_ProcessShortName(pDirent->FileName); -#else - memcpy(pDirent->FileName, src, 11); - FF_ProcessShortName(pDirent->FileName); -#endif - totalLFNs = 0; - } - - if((pDirent->Attrib & pa_Attrib) == pa_Attrib){ -#ifdef FF_UNICODE_SUPPORT - if(!wcsicmp(name, pDirent->FileName)) { -#else - if (!FF_stricmp(name, pDirent->FileName)) { -#endif - // Finally get the complete information -#ifdef FF_LFN_SUPPORT - if (totalLFNs) { - FF_PopulateLongDirent(pIoman, pDirent, lfnItem, &FetchContext); - } else -#endif - { - FF_PopulateShortDirent(pIoman, pDirent, src); - } - // Object found! - FF_CleanupEntryFetch(pIoman, &FetchContext); - return pDirent->ObjectCluster; // Return the cluster number - } - } - totalLFNs = 0; - } - } // for (src = FetchContext.pBuffer->pBuffer; src < lastSrc; src += 32, pDirent->CurrentItem++) - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - return 0; -} - - - -/** - * @private - **/ -#ifdef FF_UNICODE_SUPPORT -FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT16 pathLen, FF_ERROR *pError) { -#else -FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen, FF_ERROR *pError) { -#endif - FF_T_UINT32 dirCluster = pIoman->pPartition->RootDirCluster; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR mytoken[FF_MAX_FILENAME]; - FF_T_WCHAR *token; -#else - FF_T_INT8 mytoken[FF_MAX_FILENAME]; - FF_T_INT8 *token; -#endif - - FF_T_UINT16 it = 0; // Re-entrancy Variables for FF_strtok() - FF_T_BOOL last = FF_FALSE; - FF_DIRENT MyDir; -#ifdef FF_PATH_CACHE - FF_T_UINT32 i; -#endif - - *pError = FF_ERR_NONE; - - if(pathLen <= 1) { // Must be the root dir! (/ or \) - return pIoman->pPartition->RootDirCluster; - } - - if(path[pathLen-1] == '\\' || path[pathLen-1] == '/') { - pathLen--; - } - -#ifdef FF_PATH_CACHE // Is the requested path in the PATH CACHE? - FF_PendSemaphore(pIoman->pSemaphore); // Thread safety on shared object! - { - for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { -#ifdef FF_UNICODE_SUPPORT - if(wcslen(pIoman->pPartition->PathCache[i].Path) == pathLen) { - if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, pathLen)) { -#else - if(strlen(pIoman->pPartition->PathCache[i].Path) == pathLen) { - if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, pathLen)) { -#endif - - FF_ReleaseSemaphore(pIoman->pSemaphore); - return pIoman->pPartition->PathCache[i].DirCluster; - } - } - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -#endif - - token = FF_strtok(path, mytoken, &it, &last, pathLen); - - do{ - MyDir.CurrentItem = 0; - dirCluster = FF_FindEntryInDir(pIoman, dirCluster, token, FF_FAT_ATTR_DIR, &MyDir, pError); - - if(*pError) { - return 0; - } - - /*if(dirCluster == 0 && MyDir.CurrentItem == 2 && MyDir.FileName[0] == '.') { // .. Dir Entry pointing to root dir. - dirCluster = pIoman->pPartition->RootDirCluster; - }*/ - token = FF_strtok(path, mytoken, &it, &last, pathLen); - }while(token != NULL); - -#ifdef FF_PATH_CACHE // Update the PATH CACHE with a new PATH - if(dirCluster) { // Only cache if the dir was actually found! - FF_PendSemaphore(pIoman->pSemaphore); - { - if(pathLen < FF_MAX_PATH) { // Ensure the PATH won't cause a buffer overrun. -#ifdef FF_UNICODE_SUPPORT - memcpy(pIoman->pPartition->PathCache[pIoman->pPartition->PCIndex].Path, path, pathLen * sizeof(FF_T_WCHAR)); -#else - memcpy(pIoman->pPartition->PathCache[pIoman->pPartition->PCIndex].Path, path, pathLen); -#endif - pIoman->pPartition->PathCache[pIoman->pPartition->PCIndex].Path[pathLen] = '\0'; - pIoman->pPartition->PathCache[pIoman->pPartition->PCIndex].DirCluster = dirCluster; -#ifdef FF_HASH_TABLE_SUPPORT - FF_ClearHashTable(pIoman->pPartition->PathCache[pIoman->pPartition->PCIndex].pHashTable); -#endif - pIoman->pPartition->PCIndex += 1; - if(pIoman->pPartition->PCIndex >= FF_PATH_CACHE_DEPTH) { - pIoman->pPartition->PCIndex = 0; - } - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - } -#endif - - return dirCluster; -} - - -#if defined(FF_SHORTNAME_CASE) -/** - * @private - * For short-name entries, NT/XP etc store case information in byte 0x0c - * Use this to show proper case of "README.txt" or "source.H" - **/ -#ifdef FF_UNICODE_SUPPORT -static void FF_CaseShortName(FF_T_WCHAR *name, FF_T_UINT8 attrib) { -#else -static void FF_CaseShortName(FF_T_INT8 *name, FF_T_UINT8 attrib) { -#endif - FF_T_UINT8 testAttrib = FF_FAT_CASE_ATTR_BASE; - for (; *name; name++) { - if (*name == '.') { - testAttrib = FF_FAT_CASE_ATTR_EXT; - } else if ((attrib & testAttrib)) { - if (*name >= 'A' && *name <= 'Z') - *name += 0x20; - } else if (*name >= 'a' && *name <= 'z') { - *name -= 0x20; - } - } -} -#endif - -/** - * @private - **/ - -#ifdef FF_UNICODE_SUPPORT -static void FF_ProcessShortName(FF_T_WCHAR *name) { - FF_T_WCHAR shortName[13]; - FF_T_WCHAR *ptr = name; -#else -static void FF_ProcessShortName(FF_T_INT8 *name) { - FF_T_INT8 shortName[13]; - FF_T_INT8 *ptr = name; -#endif - FF_T_UINT8 i; -#ifdef FF_UNICODE_SUPPORT - memcpy(shortName, name, 11 * sizeof(FF_T_WCHAR)); -#else - memcpy(shortName, name, 11); -#endif - - for(i = 0; i < 11; i++) { - if(shortName[i] == 0x20) { - if (i >= 8) - break; - i = 7; - } else { - if (i == 8) - *(ptr++) = '.'; - *(ptr++) = shortName[i]; - } - } - *ptr = '\0'; -} - -/* -#ifdef FF_UNICODE_SUPPORT -static void FF_ProcessShortName(FF_T_WCHAR *name) { - FF_T_WCHAR shortName[13]; -#else -static void FF_ProcessShortName(FF_T_INT8 *name) { - FF_T_INT8 shortName[13]; -#endif - - FF_T_UINT8 i; -#ifdef FF_UNICODE_SUPPORT - memcpy(shortName, name, 11 * sizeof(FF_T_WCHAR)); -#else - memcpy(shortName, name, 11); -#endif - - for(i = 0; i < 8; i++) { - if(shortName[i] == 0x20) { - name[i] = '\0'; - break; - } - name[i] = shortName[i]; - } - - if(shortName[8] != 0x20){ - name[i] = '.'; - name[i+1] = shortName[8]; - name[i+2] = shortName[9]; - name[i+3] = shortName[10]; - name[i+4] = '\0'; - for(i = 0; i < 11; i++) { - if(name[i] == 0x20) { - name[i] = '\0'; - break; - } - } - } else { - name[i] = '\0'; - } - -}*/ - -#ifdef FF_TIME_SUPPORT -static void FF_PlaceTime(FF_T_UINT8 *EntryBuffer, FF_T_UINT32 Offset) { - FF_T_UINT16 myShort; - FF_SYSTEMTIME str_t; - - FF_GetSystemTime(&str_t); - - myShort = 0; - myShort |= ((str_t.Hour << 11) & 0xF800); - myShort |= ((str_t.Minute << 5) & 0x07E0); - myShort |= ((str_t.Second / 2) & 0x001F); - FF_putShort(EntryBuffer, (FF_T_UINT16) Offset, myShort); -} - -static void FF_PlaceDate(FF_T_UINT8 *EntryBuffer, FF_T_UINT32 Offset) { - FF_T_UINT16 myShort; - FF_SYSTEMTIME str_t; - - FF_GetSystemTime(&str_t); - - myShort = 0; - myShort |= (((str_t.Year- 1980) << 9) & 0xFE00) ; - myShort |= ((str_t.Month << 5) & 0x01E0); - myShort |= (str_t.Day & 0x001F); - FF_putShort(EntryBuffer, (FF_T_UINT16) Offset, myShort); -} - - -static void FF_GetTime(FF_SYSTEMTIME *pTime, FF_T_UINT8 *EntryBuffer, FF_T_UINT32 Offset) { - FF_T_UINT16 myShort; - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16) Offset); - pTime->Hour = (((myShort & 0xF800) >> 11) & 0x001F); - pTime->Minute = (((myShort & 0x07E0) >> 5) & 0x003F); - pTime->Second = 2 * (myShort & 0x01F); -} - -static void FF_GetDate(FF_SYSTEMTIME *pTime, FF_T_UINT8 *EntryBuffer, FF_T_UINT32 Offset) { - FF_T_UINT16 myShort; - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16) Offset); - pTime->Year = 1980 + (((myShort & 0xFE00) >> 9) & 0x07F); - pTime->Month = (((myShort & 0x01E0) >> 5) & 0x000F); - pTime->Day = myShort & 0x01F; -} -#endif - -void FF_PopulateShortDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer) { - FF_T_UINT16 myShort; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR UTF16EntryBuffer[12]; - FF_cstrntowcs(UTF16EntryBuffer, (FF_T_INT8 *) EntryBuffer, 11); - memcpy(pDirent->FileName, UTF16EntryBuffer, 11 * sizeof(FF_T_WCHAR)); -#else - memcpy(pDirent->FileName, EntryBuffer, 11); // Copy the filename into the Dirent object. -#endif -#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME) - memcpy(pDirent->ShortName, EntryBuffer, 11); - pDirent->ShortName[11] = '\0'; - FF_ProcessShortName(pDirent->ShortName); // Format the shortname, for pleasant viewing. - -#endif - FF_ProcessShortName(pDirent->FileName); // Format the shortname, for pleasant viewing. - -#ifdef FF_HASH_TABLE_SUPPORT -/*#if FF_HASH_FUNCTION == CRC16 - FF_AddDirentHash(pIoman, pDirent->DirCluster, (FF_T_UINT32)FF_GetCRC16((FF_T_UINT8 *) pDirent->FileName, strlen(pDirent->FileName))); -#elif FF_HASH_FUNCTION == CRC8 - FF_AddDirentHash(pIoman, pDirent->DirCluster, (FF_T_UINT32)FF_GetCRC8((FF_T_UINT8 *) pDirent->FileName, strlen(pDirent->FileName))); -#endif*/ -#else - pIoman = NULL; // Silence a compiler warning, about not referencing pIoman. -#endif - -#ifdef FF_UNICODE_SUPPORT - FF_tolower(pDirent->FileName, (FF_T_UINT32)wcslen(pDirent->FileName)); -#else - FF_tolower(pDirent->FileName, (FF_T_UINT32)strlen(pDirent->FileName)); -#endif - - // Get the item's Cluster address. - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH)); - pDirent->ObjectCluster = (FF_T_UINT32) (myShort << 16); - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW)); - pDirent->ObjectCluster |= myShort; -#ifdef FF_TIME_SUPPORT - // Get the creation Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_DATE); - // Get the modified Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE); - // Get the last accessed Date. - FF_GetDate(&pDirent->AccessedTime, EntryBuffer, FF_FAT_DIRENT_LASTACC_DATE); - pDirent->AccessedTime.Hour = 0; - pDirent->AccessedTime.Minute = 0; - pDirent->AccessedTime.Second = 0; -#endif - // Get the filesize. - pDirent->Filesize = FF_getLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE)); - // Get the attribute. - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); -} - -/* - Initialises a context object for FF_FetchEntryWithContext() -*/ -FF_ERROR FF_InitEntryFetch(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_FETCH_CONTEXT *pContext) { - - FF_ERROR Error; - - memset(pContext, 0, sizeof(FF_FETCH_CONTEXT)); - - pContext->ulChainLength = FF_GetChainLength(pIoman, ulDirCluster, NULL, &Error); // Get the total length of the chain. - if(Error) { - return Error; - } - pContext->ulDirCluster = ulDirCluster; - pContext->ulCurrentClusterLCN = ulDirCluster; - pContext->ulCurrentClusterNum = 0; - pContext->ulCurrentEntry = 0; - - if(pIoman->pPartition->Type != FF_T_FAT32) { - // Handle Root Dirs that don't have cluster chains! - if(pContext->ulDirCluster == pIoman->pPartition->RootDirCluster) { - // This is a RootDIR, special consideration needs to be made, because it doesn't have a Cluster chain! - pContext->ulChainLength = pIoman->pPartition->RootDirSectors / pIoman->pPartition->SectorsPerCluster; - if(!pContext->ulChainLength) { // Some media has RootDirSectors < SectorsPerCluster. This is wrong, as it should be atleast 1 cluster! - pContext->ulChainLength = 1; - } - } - } - - return FF_ERR_NONE; -} - -void FF_CleanupEntryFetch(FF_IOMAN *pIoman, FF_FETCH_CONTEXT *pContext) { - if(pContext->pBuffer) { - FF_ReleaseBuffer(pIoman, pContext->pBuffer); - pContext->pBuffer = NULL; - } -} - -FF_ERROR FF_FetchEntryWithContext(FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer) { - - FF_T_UINT32 ulItemLBA; - FF_T_UINT32 ulRelItem; - FF_T_UINT32 ulClusterNum; - FF_ERROR Error; - - ulClusterNum = FF_getClusterChainNumber(pIoman, ulEntry, (FF_T_UINT16)32); - ulRelItem = FF_getMinorBlockEntry (pIoman, ulEntry, (FF_T_UINT16)32); - - if(ulClusterNum != pContext->ulCurrentClusterNum) { - // Traverse the fat gently! - if(ulClusterNum > pContext->ulCurrentClusterNum) { - pContext->ulCurrentClusterLCN = FF_TraverseFAT(pIoman, pContext->ulCurrentClusterLCN, (ulClusterNum - pContext->ulCurrentClusterNum), &Error); - if(Error) { - return Error; - } - } else { - pContext->ulCurrentClusterLCN = FF_TraverseFAT(pIoman, pContext->ulDirCluster, ulClusterNum, &Error); - if(Error) { - return Error; - } - } - pContext->ulCurrentClusterNum = ulClusterNum; - } - - if(pIoman->pPartition->Type != FF_T_FAT32) { - // Handle Root Dirs that don't have cluster chains! - if(pContext->ulDirCluster == pIoman->pPartition->RootDirCluster) { - // This is a RootDIR, special consideration needs to be made, because it doesn't have a Cluster chain! - pContext->ulCurrentClusterLCN = pContext->ulDirCluster; - ulClusterNum = 0; - if(ulEntry > ((pIoman->pPartition->RootDirSectors * pIoman->pPartition->BlkSize) / 32)) { - return FF_ERR_DIR_END_OF_DIR; - } - } - } - - if((ulClusterNum + 1) > pContext->ulChainLength) { - return FF_ERR_DIR_END_OF_DIR; // End of Dir was reached! - } - - ulItemLBA = FF_Cluster2LBA (pIoman, pContext->ulCurrentClusterLCN) + FF_getMajorBlockNumber(pIoman, ulEntry, (FF_T_UINT16)32); - ulItemLBA = FF_getRealLBA (pIoman, ulItemLBA) + FF_getMinorBlockNumber(pIoman, ulRelItem, (FF_T_UINT16)32); - - if(!pContext->pBuffer || (pContext->pBuffer->Sector != ulItemLBA)) { - if(pContext->pBuffer) { - FF_ReleaseBuffer(pIoman, pContext->pBuffer); - } - pContext->pBuffer = FF_GetBuffer(pIoman, ulItemLBA, FF_MODE_READ); - if(!pContext->pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - } - - if (pEntryBuffer) { // HT Because it might be called with NULL - memcpy(pEntryBuffer, (pContext->pBuffer->pBuffer + (ulRelItem*32)), 32); - } - - return FF_ERR_NONE; -} - - -FF_ERROR FF_PushEntryWithContext(FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer) { - FF_T_UINT32 ulItemLBA; - FF_T_UINT32 ulRelItem; - FF_T_UINT32 ulClusterNum; - FF_ERROR Error; - - ulClusterNum = FF_getClusterChainNumber(pIoman, ulEntry, (FF_T_UINT16)32); - ulRelItem = FF_getMinorBlockEntry (pIoman, ulEntry, (FF_T_UINT16)32); - - if(ulClusterNum != pContext->ulCurrentClusterNum) { - // Traverse the fat gently! - if(ulClusterNum > pContext->ulCurrentClusterNum) { - pContext->ulCurrentClusterLCN = FF_TraverseFAT(pIoman, pContext->ulCurrentClusterLCN, (ulClusterNum - pContext->ulCurrentClusterNum), &Error); - if(Error) { - return Error; - } - } else { - pContext->ulCurrentClusterLCN = FF_TraverseFAT(pIoman, pContext->ulDirCluster, ulClusterNum, &Error); - if(Error) { - return Error; - } - } - pContext->ulCurrentClusterNum = ulClusterNum; - } - - if(pIoman->pPartition->Type != FF_T_FAT32) { - // Handle Root Dirs that don't have cluster chains! - if(pContext->ulDirCluster == pIoman->pPartition->RootDirCluster) { - // This is a RootDIR, special consideration needs to be made, because it doesn't have a Cluster chain! - pContext->ulCurrentClusterLCN = pContext->ulDirCluster; - ulClusterNum = 0; - if(ulEntry > ((pIoman->pPartition->RootDirSectors * pIoman->pPartition->BlkSize) / 32)) { - return FF_ERR_DIR_END_OF_DIR; - } - } - } - - if((ulClusterNum + 1) > pContext->ulChainLength) { - return FF_ERR_DIR_END_OF_DIR; // End of Dir was reached! - } - - ulItemLBA = FF_Cluster2LBA (pIoman, pContext->ulCurrentClusterLCN) + FF_getMajorBlockNumber(pIoman, ulEntry, (FF_T_UINT16)32); - ulItemLBA = FF_getRealLBA (pIoman, ulItemLBA) + FF_getMinorBlockNumber(pIoman, ulRelItem, (FF_T_UINT16)32); - - if(!pContext->pBuffer || (pContext->pBuffer->Sector != ulItemLBA)) { - if(pContext->pBuffer) { - FF_ReleaseBuffer(pIoman, pContext->pBuffer); - } - pContext->pBuffer = FF_GetBuffer(pIoman, ulItemLBA, FF_MODE_READ); - if(!pContext->pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - } - - memcpy((pContext->pBuffer->pBuffer + (ulRelItem*32)), pEntryBuffer, 32); - pContext->pBuffer->Mode = FF_MODE_WRITE; - pContext->pBuffer->Modified = FF_TRUE; - - return FF_ERR_NONE; -} - - -/** - * @private - **/ -FF_ERROR FF_GetEntry(FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent) { - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT8 numLFNs; - FF_FETCH_CONTEXT FetchContext; - FF_ERROR Error; - - Error = FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - if(Error) { - return Error; - } - - Error = FF_FetchEntryWithContext(pIoman, nEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - if(EntryBuffer[0] != 0xE5) { - if(FF_isEndOfDir(EntryBuffer)){ - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_ERR_DIR_END_OF_DIR; - } - - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - - if((pDirent->Attrib & FF_FAT_ATTR_LFN) == FF_FAT_ATTR_LFN) { - // LFN Processing - numLFNs = (FF_T_UINT8)(EntryBuffer[0] & ~0x40); - #ifdef FF_LFN_SUPPORT - Error = FF_PopulateLongDirent(pIoman, pDirent, nEntry, &FetchContext); - FF_CleanupEntryFetch(pIoman, &FetchContext); - if(Error) { - return Error; - } - return FF_ERR_NONE; - #else - pDirent->CurrentItem += (numLFNs - 1); - #endif - } else if((pDirent->Attrib & FF_FAT_ATTR_VOLID) == FF_FAT_ATTR_VOLID) { - // Do Nothing - - } else { - FF_PopulateShortDirent(pIoman, pDirent, EntryBuffer); - pDirent->CurrentItem += 1; - FF_CleanupEntryFetch(pIoman, &FetchContext); - return 0; - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_ERR_NONE; -} - -FF_T_BOOL FF_isEndOfDir(FF_T_UINT8 *EntryBuffer) { - if(EntryBuffer[0] == 0x00) { - return FF_TRUE; - } - return FF_FALSE; -} - -#ifdef FF_HASH_CACHE -FF_ERROR FF_AddDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_T_UINT32 ulHash) { - FF_T_UINT32 i; - FF_HASH_TABLE pHash = NULL; - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - if(pIoman->HashCache[i].ulDirCluster == ulDirCluster) { - pHash = pIoman->HashCache[i].pHashTable; - break; - } - } - - if(pHash) { - FF_SetHash(pHash, ulHash); - } - - return FF_ERR_NONE; -} - -FF_T_BOOL FF_CheckDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_T_UINT32 ulHash) { - FF_T_UINT32 i; - FF_HASH_TABLE pHash = NULL; - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - if(pIoman->HashCache[i].ulDirCluster == ulDirCluster) { - pHash = pIoman->HashCache[i].pHashTable; - break; - } - } - - if(pHash) { - return FF_isHashSet(pHash, ulHash); - } - - return FF_FALSE; -} - -FF_T_BOOL FF_DirHashed(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster) { - FF_T_UINT32 i; - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - if(pIoman->HashCache[i].ulDirCluster == ulDirCluster) { - return FF_TRUE; - } - } - - return FF_FALSE; -} - -FF_ERROR FF_HashDir(FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster) { - // Find most suitable Hash Table to replace! - FF_T_UINT32 i; - FF_HASHCACHE *pHashCache = NULL; - FF_FETCH_CONTEXT FetchContext; - FF_T_UINT8 EntryBuffer[32], ucAttrib; - FF_T_UINT32 ulHash; - - if(FF_DirHashed(pIoman, ulDirCluster)) { - return FF_ERR_NONE; // Don't wastefully re-hash a dir! - } - - //printf("----- Hashing Directory\n"); - - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - if(!pIoman->HashCache[i].ulNumHandles) { - if(!pHashCache) { - pHashCache = &pIoman->HashCache[i]; - } else { - if((pIoman->HashCache[i].ulMisses > pHashCache->ulMisses)) { - pHashCache = &pIoman->HashCache[i]; - } - } - } - } - - if(pHashCache) { - // Clear the hash table! - FF_ClearHashTable(pHashCache->pHashTable); - pHashCache->ulDirCluster = ulDirCluster; - pHashCache->ulMisses = 0; - - // Hash the directory! - - FF_InitEntryFetch(pIoman, ulDirCluster, &FetchContext); - - for(i = 0; i < 0xFFFF; i++) { - if(FF_FetchEntryWithContext(pIoman, i, &FetchContext, EntryBuffer)) { - break; // HT addition - } - ucAttrib = FF_getChar(EntryBuffer, FF_FAT_DIRENT_ATTRIB); - if(FF_getChar(EntryBuffer, 0x00) != 0xE5) { - if(ucAttrib != FF_FAT_ATTR_LFN) { - FF_ProcessShortName((FF_T_INT8 *)EntryBuffer); - if(FF_isEndOfDir(EntryBuffer)) { - // HT uncommented - FF_CleanupEntryFetch(pIoman, &FetchContext); - return FF_ERR_NONE; - } - - // Generate the Hash -#if FF_HASH_FUNCTION == CRC16 - ulHash = FF_GetCRC16(EntryBuffer, strlen((const FF_T_INT8 *) EntryBuffer)); -#elif FF_HASH_FUNCTION == CRC8 - ulHash = FF_GetCRC8(EntryBuffer, strlen((const FF_T_INT8 *) EntryBuffer)); -#endif - FF_SetHash(pHashCache->pHashTable, ulHash); - - } - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - return FF_ERR_NONE; - } - - return -1; -} - -/*void FF_SetDirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster) { - int i; - for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { - if(pIoman->pPartition->PathCache[i].DirCluster == DirCluster) { - pIoman->pPartition->PathCache[i].bHashed = FF_TRUE; - return; - } - } -}*/ -#endif - -FF_ERROR FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT16 nEntry, FF_FETCH_CONTEXT *pFetchContext) { - // First get the entire name as UTF-16 from the LFN's. - // Then transform into the API's native string format. - - FF_ERROR Error; - FF_T_UINT uiNumLFNs; - FF_T_UINT uiLfnLength = 0; -#ifdef FF_UNICODE_UTF8_SUPPORT - FF_T_UINT i,y; -// FF_T_SINT32 slRetVal; - FF_T_UINT16 nLfnBegin; - FF_T_UINT16 usUtf8Len = 0; -#endif - FF_T_UINT16 myShort; - FF_T_UINT8 ucCheckSum; - - FF_T_UINT8 EntryBuffer[32]; - //FF_T_UINT16 UTF16Name[FF_MAX_FILENAME]; - -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR WCEntryBuffer[32]; - FF_T_WCHAR ShortName[13]; -#else - FF_T_INT8 ShortName[13]; -#endif - - Error = FF_FetchEntryWithContext(pIoman, nEntry++, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - - uiNumLFNs = (FF_T_UINT)(EntryBuffer[0] & ~0x40); - ucCheckSum = FF_getChar(EntryBuffer, FF_FAT_LFN_CHECKSUM); - -#ifdef FF_UNICODE_SUPPORT // UTF-16 Can simply get segments of the UTF-16 sequence going forward - // in the dirents. (I.e. reversed order). - - while(uiNumLFNs) { // Avoid stack intensive use of a UTF-16 buffer. Stream direct to FileName dirent field in correct format. - - // memcopy direct!-UTF-16 support - memcpy(pDirent->FileName + ((uiNumLFNs - 1) * 13) + 0, &EntryBuffer[FF_FAT_LFN_NAME_1], 10); - memcpy(pDirent->FileName + ((uiNumLFNs - 1) * 13) + 5, &EntryBuffer[FF_FAT_LFN_NAME_2], 12); - memcpy(pDirent->FileName + ((uiNumLFNs - 1) * 13) + 11, &EntryBuffer[FF_FAT_LFN_NAME_3], 4); - - - uiLfnLength += 13; - - Error = FF_FetchEntryWithContext(pIoman, nEntry++, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - uiNumLFNs--; - } - - pDirent->FileName[uiLfnLength] = '\0'; -#endif - -#ifdef FF_UNICODE_UTF8_SUPPORT - // UTF-8 Sequence, we can only convert this from the beginning, must receive entries in reverse. - nLfnBegin = nEntry - 1; - - for(i = 0; i < uiNumLFNs; i++) { - Error = FF_FetchEntryWithContext(pIoman, (nLfnBegin + (uiNumLFNs - 1) - i), pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - - // Now have the first part of the UTF-16 sequence. Stream into a UTF-8 sequence. - for(y = 0; y < 5; y++) { - Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) &pDirent->FileName[usUtf8Len], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_1 + (y*2)], sizeof(pDirent->FileName) - usUtf8Len); - if(Error > 0) { - usUtf8Len += (FF_T_UINT16) Error; - } - } - - for(y = 0; y < 6; y++) { - Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) &pDirent->FileName[usUtf8Len], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_2 + (y*2)], sizeof(pDirent->FileName) - usUtf8Len); - if(Error > 0) { - usUtf8Len += (FF_T_UINT16) Error; - } - } - - for(y = 0; y < 2; y++) { - Error = FF_Utf16ctoUtf8c((FF_T_UINT8 *) &pDirent->FileName[usUtf8Len], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_3 + (y*2)], sizeof(pDirent->FileName) - usUtf8Len); - if(Error > 0) { - usUtf8Len += (FF_T_UINT16) Error; - } - } - nEntry++; - } - - pDirent->FileName[usUtf8Len] = '\0'; - - // Put Entry context to correct position. - Error = FF_FetchEntryWithContext(pIoman, nEntry-1, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - -#endif - -#ifndef FF_UNICODE_SUPPORT -#ifndef FF_UNICODE_UTF8_SUPPORT // No Unicode, simple ASCII. - while(uiNumLFNs) { // Avoid stack intensive use of a UTF-16 buffer. Stream direct to FileName dirent field in correct format. - - for(i = 0; i < 5; i++) { - pDirent->FileName[((uiNumLFNs - 1) * 13) + i] = EntryBuffer[FF_FAT_LFN_NAME_1 + (i*2)]; - } - - for(i = 0; i < 6; i++) { - pDirent->FileName[((uiNumLFNs - 1) * 13) + i + 5] = EntryBuffer[FF_FAT_LFN_NAME_2 + (i*2)]; - } - - for(i = 0; i < 2; i++) { - pDirent->FileName[((uiNumLFNs - 1) * 13) + i + 11] = EntryBuffer[FF_FAT_LFN_NAME_3 + (i*2)]; - } - - uiLfnLength += 13; - - Error = FF_FetchEntryWithContext(pIoman, nEntry++, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - uiNumLFNs--; - } - - pDirent->FileName[uiLfnLength] = '\0'; - - -#endif -#endif - // Process the Shortname. -- LFN Transformation is now complete. - // Process the ShortName Entry - - // if SHORTNAMES must be included, simple byte copy into shortname buffer. -#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME) - memcpy(pDirent->ShortName, EntryBuffer, 11); - pDirent->ShortName[11] = '\0'; - FF_ProcessShortName(pDirent->ShortName); -#endif - -#ifdef FF_UNICODE_SUPPORT - FF_cstrntowcs(WCEntryBuffer, (FF_T_INT8 *) EntryBuffer, 32); - memcpy(ShortName, WCEntryBuffer, 11 * sizeof(FF_T_WCHAR)); -#else - memcpy(ShortName, EntryBuffer, 11); -#endif - FF_ProcessShortName(ShortName); - if(ucCheckSum != FF_CreateChkSum(EntryBuffer)) { -#ifdef FF_UNICODE_SUPPORT - wcscpy(pDirent->FileName, ShortName); -#else - strcpy(pDirent->FileName, ShortName); -#endif - } - - // Finally fill in the other details - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH)); - pDirent->ObjectCluster = (FF_T_UINT32) (myShort << 16); - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW)); - pDirent->ObjectCluster |= myShort; - -#ifdef FF_TIME_SUPPORT - // Get the creation Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_DATE); - // Get the modified Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE); - // Get the last accessed Date. - FF_GetDate(&pDirent->AccessedTime, EntryBuffer, FF_FAT_DIRENT_LASTACC_DATE); - pDirent->AccessedTime.Hour = 0; - pDirent->AccessedTime.Minute = 0; - pDirent->AccessedTime.Second = 0; -#endif - - // Get the filesize. - pDirent->Filesize = FF_getLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE)); - // Get the attribute. - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - - pDirent->CurrentItem = nEntry; - //return x; - return FF_ERR_NONE; -} - -/* -FF_ERROR FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT16 nEntry, FF_FETCH_CONTEXT *pFetchContext) { - FF_T_UINT8 EntryBuffer[32]; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR UTF16EntryBuffer[32]; - FF_T_WCHAR ShortName[13]; -#if WCHAR_MAX > 0xFFFF - FF_T_UINT16 i,y; -#endif -#else - FF_T_INT8 ShortName[13]; -#ifdef FF_UNICODE_UTF8_SUPPORT - FF_T_SINT32 i, y; -#else - FF_T_UINT16 i, y; -#endif -#endif - -#ifdef FF_UNICODE_UTF8_SUPPORT - FF_T_UINT16 UTF16Name[FF_MAX_FILENAME]; // Read in the entire UTF-16 name into this buffer. - FF_T_UINT16 *UTF16cptr; -#endif - FF_T_UINT8 numLFNs; - FF_T_UINT8 x; - FF_T_UINT8 CheckSum = 0; - - FF_T_UINT16 lenlfn = 0; - FF_T_UINT16 myShort; - FF_ERROR Error; - - Error = FF_FetchEntryWithContext(pIoman, nEntry++, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - - numLFNs = (FF_T_UINT8)(EntryBuffer[0] & ~0x40); - // Handle the name - CheckSum = FF_getChar(EntryBuffer, FF_FAT_LFN_CHECKSUM); - - x = numLFNs; - while(numLFNs) { - if(numLFNs > 1) { - numLFNs = numLFNs; - } - -#ifdef FF_UNICODE_SUPPORT - // Simply fill the FileName buffer with UTF-16 Filename! -#if WCHAR_MAX <= 0xFFFF // System works in UTF-16 so we can trust it if we just copy the UTF-16 strings directly. - memcpy(pDirent->FileName + ((numLFNs - 1) * 13) + 0, &EntryBuffer[FF_FAT_LFN_NAME_1], (5 * 2)); - memcpy(pDirent->FileName + ((numLFNs - 1) * 13) + 5, &EntryBuffer[FF_FAT_LFN_NAME_2], (6 * 2)); - memcpy(pDirent->FileName + ((numLFNs - 1) * 13) + 11, &EntryBuffer[FF_FAT_LFN_NAME_3], (2 * 2)); - lenlfn += 13; -#else - for(i = 0, y = 0; i < 5; i++, y += 2) { - FF_Utf16ctoUtf32c((FF_T_UINT32 *)&pDirent->FileName[i + ((numLFNs - 1) * 13)], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_1 + y]); - //pDirent->FileName[i + ((numLFNs - 1) * 13)] = (FF_T_WCHAR) ((FF_T_WCHAR) EntryBuffer[FF_FAT_LFN_NAME_1 + y] | ((FF_T_WCHAR) EntryBuffer[FF_FAT_LFN_NAME_1 + y + 1] >> 8)); - lenlfn++; - } - for(i = 0, y = 0; i < 6; i++, y += 2) { - FF_Utf16ctoUtf32c((FF_T_UINT32 *)&pDirent->FileName[i + ((numLFNs - 1) * 13) + 5], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_2 + y]); - //pDirent->FileName[i + ((numLFNs - 1) * 13) + 5] = (FF_T_WCHAR) ((FF_T_WCHAR) EntryBuffer[FF_FAT_LFN_NAME_2 + y] | ((FF_T_WCHAR) EntryBuffer[FF_FAT_LFN_NAME_2 + y + 1] >> 8)); - lenlfn++; - } - for(i = 0, y = 0; i < 2; i++, y += 2) { - FF_Utf16ctoUtf32c((FF_T_UINT32 *)&pDirent->FileName[i + ((numLFNs - 1) * 13) + 11], (FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_3 + y]); - //pDirent->FileName[i + ((numLFNs - 1) * 13) + 11] = (FF_T_WCHAR) ((FF_T_WCHAR) EntryBuffer[FF_FAT_LFN_NAME_3 + y] | ((FF_T_WCHAR)EntryBuffer[FF_FAT_LFN_NAME_3 + y + 1] >> 8)); - lenlfn++; - } -#endif - // Copy each part of the LFNS -#else -#ifdef FF_UNICODE_UTF8_SUPPORT - memcpy(UTF16Name + ((numLFNs - 1) * 13) + 0, &EntryBuffer[FF_FAT_LFN_NAME_1], (5 * 2)); - memcpy(UTF16Name + ((numLFNs - 1) * 13) + 5, &EntryBuffer[FF_FAT_LFN_NAME_2], (6 * 2)); - memcpy(UTF16Name + ((numLFNs - 1) * 13) + 11, &EntryBuffer[FF_FAT_LFN_NAME_3], (2 * 2)); - lenlfn += 13; -#else - // Attempts to pull ASCII from UTF-8 encoding. - for(i = 0, y = 0; i < 5; i++, y += 2) { - pDirent->FileName[i + ((numLFNs - 1) * 13)] = EntryBuffer[FF_FAT_LFN_NAME_1 + y]; - lenlfn++; - } - - for(i = 0, y = 0; i < 6; i++, y += 2) { - pDirent->FileName[i + ((numLFNs - 1) * 13) + 5] = EntryBuffer[FF_FAT_LFN_NAME_2 + y]; - lenlfn++; - } - - for(i = 0, y = 0; i < 2; i++, y += 2) { - pDirent->FileName[i + ((numLFNs - 1) * 13) + 11] = EntryBuffer[FF_FAT_LFN_NAME_3 + y]; - lenlfn++; - } -#endif -#endif - - Error = FF_FetchEntryWithContext(pIoman, nEntry++, pFetchContext, EntryBuffer); - if(Error) { - return Error; - } - numLFNs--; - } - -#ifdef FF_UNICODE_UTF8_SUPPORT - UTF16cptr = UTF16Name; - UTF16Name[lenlfn] = '\0'; - i = 0; // Keep tabs of the current char position in the UTF-8 sequence. - while(*UTF16cptr) { - y = FF_Utf16ctoUtf8c((FF_T_UINT8 *)&pDirent->FileName[i], UTF16cptr, (FF_MAX_FILENAME - i)); - i += y; - if(FF_GetUtf16SequenceLen(*UTF16cptr++) == 2) { // IF this is a surrogate, then bump the UTF16 Pointer. - UTF16cptr++; - } - } - pDirent->FileName[i] = '\0'; -#else - pDirent->FileName[lenlfn] = '\0'; -#endif - - // Process the ShortName Entry -#ifdef FF_UNICODE_SUPPORT - FF_cstrntowcs(UTF16EntryBuffer, (FF_T_INT8 *) EntryBuffer, 32); - memcpy(ShortName, UTF16EntryBuffer, 11 * sizeof(FF_T_WCHAR)); -#else - memcpy(ShortName, EntryBuffer, 11); -#endif - if(CheckSum != FF_CreateChkSum(EntryBuffer)) { - FF_ProcessShortName(ShortName); -#ifdef FF_UNICODE_SUPPORT - wcscpy(pDirent->FileName, ShortName); -#else - strcpy(pDirent->FileName, ShortName); -#endif - } else { - FF_ProcessShortName(ShortName); - } - -#ifdef FF_HASH_TABLE_SUPPORT*/ -/*#if FF_HASH_FUNCTION == CRC16 - FF_AddDirentHash(pIoman, pFetchContext->ulDirCluster, (FF_T_UINT32)FF_GetCRC16((FF_T_UINT8 *) ShortName, strlen(ShortName))); -#elif FF_HASH_FUNCTION == CRC8 - FF_AddDirentHash(pIoman, DirCluster, (FF_T_UINT32)FF_GetCRC8((FF_T_UINT8 *) ShortName, strlen(ShortName))); -#endif*//* -#endif - - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH)); - pDirent->ObjectCluster = (FF_T_UINT32) (myShort << 16); - myShort = FF_getShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW)); - pDirent->ObjectCluster |= myShort; - -#ifdef FF_TIME_SUPPORT - // Get the creation Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_CREATE_DATE); - // Get the modified Time & Date - FF_GetTime(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME); - FF_GetDate(&pDirent->CreateTime, EntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE); - // Get the last accessed Date. - FF_GetDate(&pDirent->AccessedTime, EntryBuffer, FF_FAT_DIRENT_LASTACC_DATE); - pDirent->AccessedTime.Hour = 0; - pDirent->AccessedTime.Minute = 0; - pDirent->AccessedTime.Second = 0; -#endif - - // Get the filesize. - pDirent->Filesize = FF_getLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE)); - // Get the attribute. - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - - pDirent->CurrentItem = nEntry; - //return x; - return FF_ERR_NONE; -} -*/ -/** - * @public - * @brief Find's the first directory entry for the provided path. - * - * All values recorded in pDirent must be preserved to and between calls to - * FF_FindNext(). - * - * If FF_FINDAPI_ALLOW_WILDCARDS is defined, then path will have the following behaviour: - * - * path = "\" - Open the root dir, and iterate through all items. - * path = "\*.c" - Open the root dir, showing only files matching *.c wildcard. - * path = "\sub1\newdir" - Get the DIRENT for the newdir directory in /sub1/ if one exists. - * path = "\sub1\newdir\" - Open the directory /sub1/newdir/ and iterate through all items. - * path = "\sub1\newdir\*.c" - Open the directory /sub1/newdir/ and iterate through all items matching the *.c wildcard. - * - * It is important to distinguish the differences in behaviour between opening a Find operation - * on a path like /sub1 and /sub1/. (/sub1 gets the sub1 dirent from the / dir, whereas /sub/ opens the sub1 dir). - * - * Note, as compatible with other similar APIs, FullFAT also accepts \sub1\* for the same behaviour as - * /sub1/. - * - * For more up-to-date information please see the FullFAT wiki pages. - * - * @param pIoman FF_IOMAN object that was created by FF_CreateIOMAN(). - * @param pDirent FF_DIRENT object to store the entry information. - * @param path String to of the path to the Dir being listed. - * - * @return 0 on success - * @return FF_ERR_DEVICE_DRIVER_FAILED if device access failed. - * @return -2 if Dir was not found. - * - **/ -#ifdef FF_UNICODE_SUPPORT -FF_ERROR FF_FindFirst(FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_WCHAR *path) { -#else -FF_ERROR FF_FindFirst(FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path) { -#endif -#ifdef FF_UNICODE_SUPPORT - FF_T_UINT16 PathLen = (FF_T_UINT16) wcslen(path); -#else - FF_T_UINT16 PathLen = (FF_T_UINT16) strlen(path); -#endif - FF_ERROR Error; - -#ifdef FF_FINDAPI_ALLOW_WILDCARDS - FF_T_UINT16 i = 0; -#ifdef FF_UNICODE_SUPPORT - const FF_T_WCHAR *szWildCard; // Check for a Wild-card. -#else - const FF_T_INT8 *szWildCard; // Check for a Wild-card. -#endif -#endif - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - // Detect a Wild-Card on the End, or Filename, as apposed to a complete path. -#ifndef FF_FINDAPI_ALLOW_WILDCARDS - pDirent->DirCluster = FF_FindDir(pIoman, path, PathLen); // Get the directory cluster, if it exists. -#endif - -#ifdef FF_FINDAPI_ALLOW_WILDCARDS - pDirent->szWildCard[0] = '\0'; // WildCard blank if its not a wildCard. - - szWildCard = &path[PathLen - 1]; - - if(PathLen) { - while(*szWildCard != '\\' && *szWildCard != '/') { // Open the dir of the last token. - i++; - szWildCard--; - if(!(PathLen - i)) { - break; - } - } - } - - pDirent->DirCluster = FF_FindDir(pIoman, path, PathLen - i, &Error); - if(Error) { - return Error; - } - if(pDirent->DirCluster) { - // Valid Dir found, copy the wildCard to filename! -#ifdef FF_UNICODE_SUPPORT - wcsncpy(pDirent->szWildCard, ++szWildCard, FF_MAX_FILENAME); -#else - strncpy(pDirent->szWildCard, ++szWildCard, FF_MAX_FILENAME); -#endif - } -#endif - - if(pDirent->DirCluster == 0) { - return FF_ERR_DIR_INVALID_PATH; - } - - // Initialise the Fetch Context - Error = FF_InitEntryFetch(pIoman, pDirent->DirCluster, &pDirent->FetchContext); - if(Error) { - return Error; - } - - pDirent->CurrentItem = 0; - - return FF_FindNext(pIoman, pDirent); -} - -/** - * @public - * @brief Get's the next Entry based on the data recorded in the FF_DIRENT object. - * - * All values recorded in pDirent must be preserved to and between calls to - * FF_FindNext(). Please see @see FF_FindFirst() for find initialisation. - * - * @param pIoman FF_IOMAN object that was created by FF_CreateIOMAN(). - * @param pDirent FF_DIRENT object to store the entry information. (As initialised by FF_FindFirst()). - * - * @return FF_ERR_DEVICE_DRIVER_FAILED is device access failed. - * - **/ -FF_ERROR FF_FindNext(FF_IOMAN *pIoman, FF_DIRENT *pDirent) { - - FF_ERROR Error; - FF_T_UINT8 numLFNs; - FF_T_UINT8 EntryBuffer[32]; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - for(; pDirent->CurrentItem < 0xFFFF; pDirent->CurrentItem += 1) { - Error = FF_FetchEntryWithContext(pIoman, pDirent->CurrentItem, &pDirent->FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return Error; - } - if(EntryBuffer[0] != FF_FAT_DELETED) { - if(FF_isEndOfDir(EntryBuffer)){ - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return FF_ERR_DIR_END_OF_DIR; - } - pDirent->Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - if((pDirent->Attrib & FF_FAT_ATTR_LFN) == FF_FAT_ATTR_LFN) { - // LFN Processing - numLFNs = (FF_T_UINT8)(EntryBuffer[0] & ~0x40); - // Get the shortname and check if it is marked deleted. -#ifdef FF_LFN_SUPPORT - // Fetch the shortname, and get it's checksum, or for a deleted item with - // orphaned LFN entries. - Error = FF_FetchEntryWithContext(pIoman, (pDirent->CurrentItem + numLFNs), &pDirent->FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return Error; - } - - if(EntryBuffer[0] != FF_FAT_DELETED) { - Error = FF_PopulateLongDirent(pIoman, pDirent, pDirent->CurrentItem, &pDirent->FetchContext); - if(Error) { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return Error; - } -#ifdef FF_INCLUDE_SHORT_NAME - pDirent->Attrib |= FF_FAT_ATTR_IS_LFN; -#endif - -#ifdef FF_FINDAPI_ALLOW_WILDCARDS -#ifdef FF_UNICODE_SUPPORT - if(wcscmp(pDirent->szWildCard, L"")) { -#else - if(strcmp(pDirent->szWildCard, "")) { -#endif - if(FF_wildcompare(pDirent->szWildCard, pDirent->FileName)) { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return FF_ERR_NONE; - } - pDirent->CurrentItem -= 1; - } else { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return FF_ERR_NONE; - } -#else - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - return FF_ERR_NONE; -#endif - } -#else - pDirent->CurrentItem += (numLFNs - 1); -#endif - } else if((pDirent->Attrib & FF_FAT_ATTR_VOLID) == FF_FAT_ATTR_VOLID) { - // Do Nothing - - } else { - FF_PopulateShortDirent(pIoman, pDirent, EntryBuffer); -#if defined(FF_SHORTNAME_CASE) - // Apply NT/XP+ bits to get correct case - FF_CaseShortName(pDirent->FileName, FF_getChar(EntryBuffer, FF_FAT_CASE_OFFS)); -#endif -#ifdef FF_FINDAPI_ALLOW_WILDCARDS -#ifdef FF_UNICODE_SUPPORT - if(wcscmp(pDirent->szWildCard, L"")) { -#else - if(strcmp(pDirent->szWildCard, "")) { -#endif - if(FF_wildcompare(pDirent->szWildCard, pDirent->FileName)) { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - pDirent->CurrentItem += 1; - return FF_ERR_NONE; - } - } else { - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - pDirent->CurrentItem += 1; - return FF_ERR_NONE; - } -#else - - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - pDirent->CurrentItem += 1; - return FF_ERR_NONE; -#endif - } - } - } - - FF_CleanupEntryFetch(pIoman, &pDirent->FetchContext); - - return FF_ERR_DIR_END_OF_DIR; -} - - -FF_T_SINT8 FF_RewindFind(FF_IOMAN *pIoman, FF_DIRENT *pDirent) { - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - pDirent->CurrentItem = 0; - return 0; -} - -/* - Returns >= 0 for a free dirent entry. - Returns < 0 with and Error code if anything goes wrong. -*/ -static FF_T_SINT32 FF_FindFreeDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 Sequential) { - - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT16 i = 0; - FF_T_UINT16 nEntry; - FF_ERROR Error; - FF_T_UINT32 DirLength; - FF_FETCH_CONTEXT FetchContext; - - Error = FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - if(Error) { - return Error; - } - - for(nEntry = 0; nEntry < 0xFFFF; nEntry++) { - Error = FF_FetchEntryWithContext(pIoman, nEntry, &FetchContext, EntryBuffer); - if(Error == FF_ERR_DIR_END_OF_DIR) { - - Error = FF_ExtendDirectory(pIoman, DirCluster); - FF_CleanupEntryFetch(pIoman, &FetchContext); - - if(Error) { - return Error; - } - - return nEntry; - } else { - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - } - if(FF_isEndOfDir(EntryBuffer)) { // If its the end of the Dir, then FreeDirents from here. - // Check Dir is long enough! - DirLength = FetchContext.ulChainLength;//FF_GetChainLength(pIoman, DirCluster, &iEndOfChain); - if((nEntry + Sequential) > (FF_T_UINT16)(((pIoman->pPartition->SectorsPerCluster * pIoman->pPartition->BlkSize) * DirLength) / 32)) { - Error = FF_ExtendDirectory(pIoman, DirCluster); - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - if(Error) { - return Error; - } - - return nEntry; - } - if(EntryBuffer[0] == 0xE5) { - i++; - } else { - i = 0; - } - - if(i == Sequential) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return (nEntry - (Sequential - 1));// Return the beginning entry in the sequential sequence. - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - return FF_ERR_DIR_DIRECTORY_FULL; -} - - - - -FF_ERROR FF_PutEntry(FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent) { - FF_BUFFER *pBuffer; - FF_ERROR Error; - FF_T_UINT32 itemLBA; - FF_T_UINT32 clusterNum = FF_getClusterChainNumber (pIoman, Entry, (FF_T_UINT16)32); - FF_T_UINT32 relItem = FF_getMinorBlockEntry (pIoman, Entry, (FF_T_UINT16)32); - FF_T_UINT32 clusterAddress = FF_TraverseFAT(pIoman, DirCluster, clusterNum, &Error); - - if(Error) { - return Error; - } - - itemLBA = FF_Cluster2LBA(pIoman, clusterAddress) + FF_getMajorBlockNumber(pIoman, Entry, (FF_T_UINT16)32); - itemLBA = FF_getRealLBA (pIoman, itemLBA) + FF_getMinorBlockNumber(pIoman, relItem, (FF_T_UINT16)32); - - pBuffer = FF_GetBuffer(pIoman, itemLBA, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - // Modify the Entry! - //memcpy((pBuffer->pBuffer + (32*relItem)), pDirent->FileName, 11); - relItem *= 32; - FF_putChar(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB + relItem), pDirent->Attrib); - FF_putShort(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH + relItem), (FF_T_UINT16)(pDirent->ObjectCluster >> 16)); - FF_putShort(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW + relItem), (FF_T_UINT16)(pDirent->ObjectCluster)); - FF_putLong(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE + relItem), pDirent->Filesize); -#ifdef FF_TIME_SUPPORT - FF_PlaceDate((pBuffer->pBuffer + relItem), FF_FAT_DIRENT_LASTACC_DATE); // Last accessed date. -#endif - } - FF_ReleaseBuffer(pIoman, pBuffer); - - return 0; -} - -FF_T_BOOL FF_ValidShortChar (FF_T_INT8 Chr) -{ - return (Chr >= 'A' && Chr <= 'Z') || -#if defined(FF_SHORTNAME_CASE) - (Chr >= 'a' && Chr <= 'z') || // lower-case can be stored using NT/XP attribute -#endif - (Chr >= '0' && Chr <= '9') || - strchr ("$%-_@~`!(){}^#&", Chr) != NULL; -} - -FF_T_BOOL FF_ValidLongChar (FF_T_INT8 Chr) -{ - return Chr >= 0x20 && strchr ("/\\:*?\"<>|", Chr) == NULL; -} - -#ifdef FF_UNICODE_SUPPORT -FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *ShortName, FF_T_WCHAR *LongName) { -#else -FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName) { -#endif - FF_T_UINT8 caseAttrib = 0; -#if defined(FF_SHORTNAME_CASE) - FF_T_UINT8 testAttrib = FF_FAT_CASE_ATTR_BASE; -#endif - - FF_T_UINT16 i,x,y,last_dot; - FF_T_UINT16 first_tilde = 6; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR MyShortName[13]; -#else - FF_T_INT8 MyShortName[13]; -#endif - FF_T_UINT16 NameLen; - FF_T_BOOL FitsShort = FF_TRUE; - FF_DIRENT MyDir; - FF_T_BOOL found; - //FF_T_SINT8 RetVal = 0; - FF_T_INT8 NumberBuf[6]; - FF_ERROR Error; - -#ifdef FF_UNICODE_SUPPORT - NameLen = (FF_T_UINT16) wcslen(LongName); -#else - NameLen = (FF_T_UINT16) strlen(LongName); -#endif - - // Does LongName fit a shortname? - - for(i = 0, x = 0, last_dot = NameLen; i < NameLen; i++) { - if(LongName[i] != '.') { - x++; - } else { - last_dot = i; - } - } - - if (NameLen > 12 || NameLen-x > 1 || NameLen-last_dot > 4 || last_dot > 8) { - FitsShort = FF_FALSE; - } - - for(i = 0, x = 0; i < 11; x++) { - FF_T_INT8 ch = (FF_T_INT8) LongName[x]; - if (!ch) - break; - if (x == last_dot) { - while (i < 8) - ShortName[i++] = 0x20; -#if defined(FF_SHORTNAME_CASE) - testAttrib = FF_FAT_CASE_ATTR_EXT; -#endif - } else { - if (i == 8) { - x = last_dot; - ch = (FF_T_INT8) LongName[x]; - if (ch) - ch = (FF_T_INT8) LongName[++x]; -#if defined(FF_SHORTNAME_CASE) - testAttrib = FF_FAT_CASE_ATTR_EXT; -#endif - } - if (!FF_ValidShortChar (ch)) { - FitsShort = FF_FALSE; - continue; - } - if (ch >= 'a' && ch <= 'z') { - ch -= 0x20; -#if defined(FF_SHORTNAME_CASE) - if (testAttrib) - caseAttrib |= testAttrib; - else - FitsShort = FF_FALSE; // We had capital: does not fit - } else if (ch >= 'A' && ch <= 'Z') { - if (caseAttrib & testAttrib) - FitsShort = FF_FALSE; // We had lower-case: does not fit - testAttrib = 0; -#endif - } - ShortName[i++] = ch; - } - } - while (i < 11) - ShortName[i++] = 0x20; - if (last_dot < first_tilde) - first_tilde = last_dot; - if (NameLen < first_tilde) // Names like "Abc" will become "~Abc" - first_tilde = NameLen; - - // Tail : - memcpy(MyShortName, ShortName, 11); - FF_ProcessShortName(MyShortName); - found = (FF_T_BOOL) FF_FindEntryInDir(pIoman, DirCluster, MyShortName, 0x00, &MyDir, &Error); -#ifdef Hein_Tibosch - if (verboseLevel >= 1) logPrintf ("Long Name: %-14.14s Short '%s' (%s) Fit '%d' Found %d\n", LongName, ShortName, MyShortName, FitsShort, found); -#endif - if(FitsShort && !found) { - return caseAttrib | 0x01; - } - if(FitsShort) { - return FF_ERR_DIR_OBJECT_EXISTS; - } - for(i = 1; i < 0x0000FFFF; i++) { // Max Number of Entries in a DIR! - sprintf(NumberBuf, "%d", i); - NameLen = (FF_T_UINT16) strlen(NumberBuf); - x = 7 - NameLen; - if (x > first_tilde) - x = first_tilde; - ShortName[x++] = '~'; - for(y = 0; y < NameLen; y++) { - ShortName[x+y] = NumberBuf[y]; - } - memcpy(MyShortName, ShortName, 11); - FF_ProcessShortName(MyShortName); - found = FF_ShortNameExists(pIoman, DirCluster, MyShortName, &Error); -#ifdef Hein_Tibosch - if (verboseLevel >= 1) logPrintf ("Long Name: %-14.14s Short '%s' (%s) Fit '%d' Found %d\n", LongName, ShortName, MyShortName, FitsShort, found); -#endif - if(!found) { -#ifdef FF_HASH_CACHE -#if FF_HASH_FUNCTION == CRC16 - FF_AddDirentHash(pIoman, DirCluster, (FF_T_UINT32) FF_GetCRC16((FF_T_UINT8*)MyShortName, strlen(MyShortName))); -#elif FF_HASH_FUNCTION == CRC8 - FF_AddDirentHash(pIoman, DirCluster, (FF_T_UINT32) FF_GetCRC8((FF_T_UINT8*)MyShortName, strlen(MyShortName))); -#endif -#endif - return 0; - } - } - // Add a tail and special number until we're happy :D - - return FF_ERR_DIR_DIRECTORY_FULL; -} - - -#ifdef FF_LFN_SUPPORT -static FF_T_SINT8 FF_CreateLFNEntry(FF_T_UINT8 *EntryBuffer, FF_T_UINT16 *Name, FF_T_UINT uiNameLen, FF_T_UINT uiLFN, FF_T_UINT8 CheckSum) { - - FF_T_UINT i, x; - - memset(EntryBuffer, 0, 32); - - FF_putChar(EntryBuffer, FF_FAT_LFN_ORD, (FF_T_UINT8) ((uiLFN & ~0x40))); - FF_putChar(EntryBuffer, FF_FAT_DIRENT_ATTRIB, (FF_T_UINT8) FF_FAT_ATTR_LFN); - FF_putChar(EntryBuffer, FF_FAT_LFN_CHECKSUM, (FF_T_UINT8) CheckSum); - - // Name_1 - for(i = 0, x = 0; i < 5; i++, x += 2) { - if(i < uiNameLen) - { - memcpy(&EntryBuffer[FF_FAT_LFN_NAME_1 + x], &Name[i], sizeof(FF_T_UINT16)); - //bobtntfullfat *((FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_1 + x]) = Name[i]; - } - else - if (i == uiNameLen) - { - EntryBuffer[FF_FAT_LFN_NAME_1 + x] = '\0'; - EntryBuffer[FF_FAT_LFN_NAME_1 + x + 1] = '\0'; - } - else - { - EntryBuffer[FF_FAT_LFN_NAME_1 + x] = 0xFF; - EntryBuffer[FF_FAT_LFN_NAME_1 + x + 1] = 0xFF; - } - } - - // Name_2 - for(i = 0, x = 0; i < 6; i++, x += 2) { - if((i + 5) < uiNameLen) - { - memcpy(&EntryBuffer[FF_FAT_LFN_NAME_2 + x], &Name[i+5], sizeof(FF_T_UINT16)); - //EntryBuffer[FF_FAT_LFN_NAME_2 + x] = Name[i+5]; - //bobtntfullfat *((FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_2 + x]) = Name[i+5]; - } else if ((i + 5) == uiNameLen) { - EntryBuffer[FF_FAT_LFN_NAME_2 + x] = '\0'; - EntryBuffer[FF_FAT_LFN_NAME_2 + x + 1] = '\0'; - }else { - EntryBuffer[FF_FAT_LFN_NAME_2 + x] = 0xFF; - EntryBuffer[FF_FAT_LFN_NAME_2 + x + 1] = 0xFF; - } - } - - // Name_3 - for(i = 0, x = 0; i < 2; i++, x += 2) { - if((i + 11) < uiNameLen) - { - memcpy(&EntryBuffer[FF_FAT_LFN_NAME_3 + x], &Name[i+11], sizeof(FF_T_UINT16)); - //EntryBuffer[FF_FAT_LFN_NAME_3 + x] = Name[i+11]; - //bobtntfullfat *((FF_T_UINT16 *) &EntryBuffer[FF_FAT_LFN_NAME_3 + x]) = Name[i+11]; - } else if ((i + 11) == uiNameLen) { - EntryBuffer[FF_FAT_LFN_NAME_3 + x] = '\0'; - EntryBuffer[FF_FAT_LFN_NAME_3 + x + 1] = '\0'; - }else { - EntryBuffer[FF_FAT_LFN_NAME_3 + x] = 0xFF; - EntryBuffer[FF_FAT_LFN_NAME_3 + x + 1] = 0xFF; - } - } - - return FF_ERR_NONE; -} -#endif - -/* -#ifdef FF_UNICODE_SUPPORT -static FF_ERROR FF_CreateLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *Name, FF_T_UINT8 CheckSum, FF_T_UINT16 nEntry) { -#else -static FF_ERROR FF_CreateLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_T_UINT8 CheckSum, FF_T_UINT16 nEntry) { -#endif - FF_T_UINT8 EntryBuffer[32]; -#ifdef FF_UNICODE_SUPPORT - FF_T_UINT16 NameLen = (FF_T_UINT16) wcslen(Name); -#else - FF_T_UINT16 NameLen = (FF_T_UINT16) strlen(Name); -#endif - FF_T_UINT8 NumLFNs = (FF_T_UINT8) (NameLen / 13); - FF_T_UINT8 i; - FF_T_UINT8 EndPos = (NameLen % 13); - FF_ERROR Error; - - FF_FETCH_CONTEXT FetchContext; - - if(EndPos) { - NumLFNs ++; - } else { - EndPos = 13; - } - - Error = FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - if(Error) { - return Error; - } - - for(i = NumLFNs; i > 0; i--) { - if(i == NumLFNs) { - FF_CreateLFNEntry(EntryBuffer, (Name + (13 * (i - 1))), EndPos, i, CheckSum); - EntryBuffer[0] |= 0x40; - } else { - FF_CreateLFNEntry(EntryBuffer, (Name + (13 * (i - 1))), 13, i, CheckSum); - } - - Error = FF_PushEntryWithContext(pIoman, nEntry + (NumLFNs - i), &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - return FF_ERR_NONE; -} -#endif -*/ - - -#ifdef FF_UNICODE_SUPPORT -static FF_ERROR FF_CreateLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *Name, FF_T_UINT8 CheckSum, FF_T_UINT16 nEntry) { -#else -static FF_ERROR FF_CreateLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_T_UINT8 CheckSum, FF_T_UINT16 nEntry) { -#endif - FF_ERROR Error; - FF_T_UINT uiNumLFNs; - FF_T_UINT uiEndPos; - FF_T_UINT i,y; - -#ifdef FF_UNICODE_UTF8_SUPPORT - FF_T_SINT32 slRetVal; -#endif - -#ifndef FF_UNICODE_SUPPORT -#ifndef FF_UNICODE_UTF8_SUPPORT - FF_T_UINT16 *pUtf16; -#endif -#endif - - FF_FETCH_CONTEXT FetchContext; - - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT16 usUtf16Name[FF_MAX_FILENAME + 1]; - - -#ifdef FF_UNICODE_SUPPORT -#if WCHAR_MAX <= 0xFFFF - y = wcslen(Name); - if(y > FF_MAX_FILENAME) { - return FF_ERR_DIR_NAME_TOO_LONG; - } - wcsncpy(usUtf16Name, Name, FF_MAX_FILENAME); -#else - i = 0; - y = 0; - while(Name[i]) { - FF_Utf32ctoUtf16c(&usUtf16Name[y], (FF_T_UINT32) Name[i], FF_MAX_FILENAME - i); - y += FF_GetUtf16SequenceLen(usUtf16Name[y]); - i++; - if(y > FF_MAX_FILENAME) { - return FF_ERR_DIR_NAME_TOO_LONG; - } - } -#endif -#endif - - // Convert the name into UTF-16 format. -#ifdef FF_UNICODE_UTF8_SUPPORT - // Simply convert the UTF8 to UTF16 and be done with it. - i = 0; - y = 0; - while(Name[i]) { - slRetVal = FF_Utf8ctoUtf16c(&usUtf16Name[y], (FF_T_UINT8 *)&Name[i], FF_MAX_FILENAME - i); - if(slRetVal > 0) { - i += slRetVal; - } else { - break; // No more space in the UTF-16 buffer, simply truncate for safety. - } - y += FF_GetUtf16SequenceLen(usUtf16Name[y]); - if(y > FF_MAX_FILENAME) { - return FF_ERR_DIR_NAME_TOO_LONG; - } - } -#else -#ifndef FF_UNICODE_SUPPORT - i = 0; - y = strlen(Name); - if(y > FF_MAX_FILENAME) { - return FF_ERR_DIR_NAME_TOO_LONG; - } - pUtf16 = usUtf16Name; - while(Name[i]) { - usUtf16Name[i] = (FF_T_UINT16) Name[i]; - i++; - } -#endif -#endif - - // Whole name is now in a valid UTF-16 format. Lets go make thos LFN's. - // i should at this point be the length of the name. - - uiNumLFNs = y / 13; // Number of LFNs is the total number of UTF-16 units, divided by 13 (13 units per LFN). - uiEndPos = y % 13; // The ending position in an LFN, of the last LFN UTF-16 charachter. - - if(uiEndPos) { - uiNumLFNs++; - } else { - uiEndPos = 13; - } - - Error = FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - if(Error) { - return Error; - } - - // After this point, i is no longer the length of the Filename in UTF-16 units. - for(i = uiNumLFNs; i > 0; i--) { - if(i == uiNumLFNs) { - FF_CreateLFNEntry(EntryBuffer, (usUtf16Name + (13 * (i - 1))), uiEndPos, i, CheckSum); - EntryBuffer[0] |= 0x40; - } else { - FF_CreateLFNEntry(EntryBuffer, (usUtf16Name + (13 * (i - 1))), 13, i, CheckSum); - } - - Error = FF_PushEntryWithContext(pIoman, nEntry + (uiNumLFNs - i), &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - return FF_ERR_NONE; -} - -FF_ERROR FF_ExtendDirectory(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster) { - FF_T_UINT32 CurrentCluster; - FF_T_UINT32 NextCluster; - FF_ERROR Error; - - if(pIoman->pPartition->Type != FF_T_FAT32) { - if(DirCluster == pIoman->pPartition->RootDirCluster) { - return FF_ERR_DIR_CANT_EXTEND_ROOT_DIR; - } - } - - if(!pIoman->pPartition->FreeClusterCount) { - pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); - if(Error) { - return Error; - } - if(pIoman->pPartition->FreeClusterCount == 0) { - return FF_ERR_FAT_NO_FREE_CLUSTERS; - } - } - - FF_lockFAT(pIoman); - { - CurrentCluster = FF_FindEndOfChain(pIoman, DirCluster, &Error); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - - NextCluster = FF_FindFreeCluster(pIoman, &Error); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - - Error = FF_putFatEntry(pIoman, CurrentCluster, NextCluster); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - - Error = FF_putFatEntry(pIoman, NextCluster, 0xFFFFFFFF); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - } - FF_unlockFAT(pIoman); - - Error = FF_ClearCluster(pIoman, NextCluster); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - - Error = FF_DecreaseFreeClusters(pIoman, 1); - if(Error) { - FF_unlockFAT(pIoman); - return Error; - } - - return FF_ERR_NONE; -} - -#ifdef FF_UNICODE_SUPPORT -static void FF_MakeNameCompliant(FF_T_WCHAR *Name) { -#else -static void FF_MakeNameCompliant(FF_T_UINT8 *Name) { -#endif - - if((FF_T_UINT8) Name[0] == 0xE5) { // Support Japanese KANJI symbol. - Name[0] = 0x05; - } - - while(*Name) { - if(*Name < 0x20 || *Name == 0x7F || *Name == 0x22 || *Name == 0x7C) { // Leave all extended chars as they are. - *Name = '_'; - } - if(*Name >= 0x2A && *Name <= 0x2F && *Name != 0x2B && *Name != 0x2E && *Name != 0x2D) { - *Name = '_'; - } - if(*Name >= 0x3A && *Name <= 0x3F) { - *Name = '_'; - } - if(*Name >= 0x5B && *Name <= 0x5C) { - *Name = '_'; - } - Name++; - } -} - -FF_ERROR FF_CreateDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent) { - - FF_T_UINT8 EntryBuffer[32]; -#ifdef FF_UNICODE_SUPPORT - FF_T_UINT16 NameLen = (FF_T_UINT16) wcslen(pDirent->FileName); -#else - FF_T_UINT16 NameLen = (FF_T_UINT16) strlen(pDirent->FileName); -#endif - FF_T_UINT8 numLFNs = (FF_T_UINT8) (NameLen / 13); - FF_T_SINT32 FreeEntry; - FF_ERROR RetVal = FF_ERR_NONE; - FF_T_UINT8 Entries; - - FF_FETCH_CONTEXT FetchContext; - -#ifdef FF_LFN_SUPPORT - FF_T_UINT8 CheckSum; -#endif - -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR UTF16EntryBuffer[32]; -#if WCHAR_MAX > 0xFFFF - // Check that the filename won't exceed the max LFN length if converted to UTF-16. - /*if(FF_Utf32GetUtf16Len((FF_T_UINT32 *) pDirent->FileName) > FF_MAX_FILENAME) { - return FF_ERR_UNICODE_CONVERSION_EXCEEDED; - }*/ -#endif - -#endif - -#ifdef FF_UNICODE_SUPPORT - FF_MakeNameCompliant(pDirent->FileName); // Ensure we don't break the Dir tables. -#else - FF_MakeNameCompliant((FF_T_UINT8 *)pDirent->FileName); // Ensure we don't break the Dir tables. -#endif - memset(EntryBuffer, 0, 32); - - if(NameLen % 13) { - numLFNs ++; - } - -#ifdef FF_LFN_SUPPORT - // Create and push the LFN's - Entries = numLFNs + 1; // Find enough places for the LFNs and the ShortName -#else - Entries = 1; -#endif - - // Create the ShortName - FF_lockDIR(pIoman); - { - if((FreeEntry = FF_FindFreeDirent(pIoman, DirCluster, Entries)) >= 0) { -#ifdef FF_UNICODE_SUPPORT - //FF_cstrntowcs(UTF16EntryBuffer, (FF_T_INT8 *) EntryBuffer, 32); - RetVal = FF_CreateShortName(pIoman, DirCluster, UTF16EntryBuffer, pDirent->FileName); -#else - RetVal = FF_CreateShortName(pIoman, DirCluster, (FF_T_INT8 *) EntryBuffer, pDirent->FileName); -#endif - - //if(!RetVal) { -#ifdef FF_LFN_SUPPORT -#ifdef FF_UNICODE_SUPPORT - FF_wcsntocstr((FF_T_INT8 *) EntryBuffer, UTF16EntryBuffer, 11); -#endif - CheckSum = FF_CreateChkSum(EntryBuffer); - FF_CreateLFNs(pIoman, DirCluster, pDirent->FileName, CheckSum, (FF_T_UINT16) FreeEntry); -#else - numLFNs = 0; -#endif - -#ifdef FF_TIME_SUPPORT - FF_PlaceTime(EntryBuffer, FF_FAT_DIRENT_CREATE_TIME); - FF_PlaceDate(EntryBuffer, FF_FAT_DIRENT_CREATE_DATE); - FF_PlaceTime(EntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME); - FF_PlaceDate(EntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE); -#endif - - FF_putChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB), pDirent->Attrib); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH), (FF_T_UINT16)(pDirent->ObjectCluster >> 16)); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW), (FF_T_UINT16)(pDirent->ObjectCluster)); - FF_putLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE), pDirent->Filesize); - - RetVal = FF_InitEntryFetch(pIoman, DirCluster, &FetchContext); - if(RetVal) { - FF_unlockDIR(pIoman); - return RetVal; - } - RetVal = FF_PushEntryWithContext(pIoman, (FF_T_UINT16) (FreeEntry + numLFNs), &FetchContext, EntryBuffer); - FF_CleanupEntryFetch(pIoman, &FetchContext); - if(RetVal) { - FF_unlockDIR(pIoman); - return RetVal; - } - /*} else { - FF_unlockDIR(pIoman); - return RetVal; - }*/ - }else { - FF_unlockDIR(pIoman); - return FreeEntry; - } - } - FF_unlockDIR(pIoman); - - if(RetVal) { - return RetVal; - } - - if(pDirent) { - pDirent->CurrentItem = (FF_T_UINT16) (FreeEntry + numLFNs); - } - - return FF_ERR_NONE; -} - - -#ifdef FF_UNICODE_SUPPORT -FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *FileName, FF_DIRENT *pDirent, FF_ERROR *pError) { -#else -FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent, FF_ERROR *pError) { -#endif - FF_DIRENT MyFile; - *pError = FF_ERR_NONE; -#ifdef FF_UNICODE_SUPPORT - wcsncpy(MyFile.FileName, FileName, FF_MAX_FILENAME); -#else - strncpy(MyFile.FileName, FileName, FF_MAX_FILENAME); -#endif - - MyFile.Attrib = 0x00; - MyFile.Filesize = 0; - MyFile.ObjectCluster = FF_CreateClusterChain(pIoman, pError); - if(*pError) { - FF_UnlinkClusterChain(pIoman, MyFile.ObjectCluster, 0); - FF_FlushCache(pIoman); - return 0; - } - MyFile.CurrentItem = 0; - - *pError = FF_CreateDirent(pIoman, DirCluster, &MyFile); - - if(*pError) { - FF_UnlinkClusterChain(pIoman, MyFile.ObjectCluster, 0); - FF_FlushCache(pIoman); - return 0; - } - - FF_FlushCache(pIoman); - - if(pDirent) { - memcpy(pDirent, &MyFile, sizeof(FF_DIRENT)); - } - - return MyFile.ObjectCluster; -} - - -/** - * @brief Creates a Directory of the specified path. - * - * @param pIoman Pointer to the FF_IOMAN object. - * @param Path Path of the directory to create. - * - * @return FF_ERR_NULL_POINTER if pIoman was NULL. - * @return FF_ERR_DIR_OBJECT_EXISTS if the object specified by path already exists. - * @return FF_ERR_DIR_INVALID_PATH - * @return FF_ERR_NONE on success. - **/ -#ifdef FF_UNICODE_SUPPORT -FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_WCHAR *Path) { -#else -FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_INT8 *Path) { -#endif - FF_DIRENT MyDir; - FF_T_UINT32 DirCluster; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR DirName[FF_MAX_FILENAME]; -#else - FF_T_INT8 DirName[FF_MAX_FILENAME]; -#endif - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT32 DotDotCluster; - FF_T_UINT16 i; - FF_ERROR Error = FF_ERR_NONE; - - FF_FETCH_CONTEXT FetchContext; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - -#ifdef FF_UNICODE_SUPPORT - i = (FF_T_UINT16) wcslen(Path); -#else - i = (FF_T_UINT16) strlen(Path); -#endif - - while(i != 0) { - if(Path[i] == '\\' || Path[i] == '/') { - break; - } - i--; - } - -#ifdef FF_UNICODE_SUPPORT - wcsncpy(DirName, (Path + i + 1), FF_MAX_FILENAME); -#else - strncpy(DirName, (Path + i + 1), FF_MAX_FILENAME); -#endif - - if(i == 0) { - i = 1; - } - - DirCluster = FF_FindDir(pIoman, Path, i, &Error); - - if(Error) { - return Error; - } - - if(DirCluster) { - if(FF_FindEntryInDir(pIoman, DirCluster, DirName, 0x00, &MyDir, &Error)) { - return FF_ERR_DIR_OBJECT_EXISTS; - } - - if(Error && Error != FF_ERR_DIR_END_OF_DIR) { - return Error; - } - -#ifdef FF_UNICODE_SUPPORT - wcsncpy(MyDir.FileName, DirName, FF_MAX_FILENAME); -#else - strncpy(MyDir.FileName, DirName, FF_MAX_FILENAME); -#endif - MyDir.Filesize = 0; - MyDir.Attrib = FF_FAT_ATTR_DIR; - MyDir.ObjectCluster = FF_CreateClusterChain(pIoman, &Error); - if(Error) { - return Error; - } - if(MyDir.ObjectCluster) { - Error = FF_ClearCluster(pIoman, MyDir.ObjectCluster); - if(Error) { - FF_UnlinkClusterChain(pIoman, MyDir.ObjectCluster, 0); - FF_FlushCache(pIoman); - return Error; - } - } else { - // Couldn't allocate any space for the dir! - return FF_ERR_DIR_EXTEND_FAILED; - } - - Error = FF_CreateDirent(pIoman, DirCluster, &MyDir); - - if(Error) { - FF_UnlinkClusterChain(pIoman, MyDir.ObjectCluster, 0); - FF_FlushCache(pIoman); - return Error; - } - - memset(EntryBuffer, 0, 32); - EntryBuffer[0] = '.'; - for(i = 1; i < 11; i++) { - EntryBuffer[i] = 0x20; - } - FF_putChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB), FF_FAT_ATTR_DIR); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH), (FF_T_UINT16)(MyDir.ObjectCluster >> 16)); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW), (FF_T_UINT16) MyDir.ObjectCluster); - FF_putLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE), 0); - - Error = FF_InitEntryFetch(pIoman, MyDir.ObjectCluster, &FetchContext); - if(Error) { - FF_UnlinkClusterChain(pIoman, MyDir.ObjectCluster, 0); - FF_FlushCache(pIoman); - return Error; - } - - Error = FF_PushEntryWithContext(pIoman, 0, &FetchContext, EntryBuffer); - if(Error) { - FF_UnlinkClusterChain(pIoman, MyDir.ObjectCluster, 0); - FF_FlushCache(pIoman); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - - memset(EntryBuffer, 0, 32); - EntryBuffer[0] = '.'; - EntryBuffer[1] = '.'; - for(i = 2; i < 11; i++) { - EntryBuffer[i] = 0x20; - } - - if(DirCluster == pIoman->pPartition->RootDirCluster) { - DotDotCluster = 0; - } else { - DotDotCluster = DirCluster; - } - - FF_putChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB), FF_FAT_ATTR_DIR); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_HIGH), (FF_T_UINT16)(DotDotCluster >> 16)); - FF_putShort(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_CLUS_LOW), (FF_T_UINT16) DotDotCluster); - FF_putLong(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_FILESIZE), 0); - - //FF_PushEntry(pIoman, MyDir.ObjectCluster, 1, EntryBuffer); - Error = FF_PushEntryWithContext(pIoman, 1, &FetchContext, EntryBuffer); - if(Error) { - FF_UnlinkClusterChain(pIoman, MyDir.ObjectCluster, 0); - FF_FlushCache(pIoman); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - FF_CleanupEntryFetch(pIoman, &FetchContext); - - FF_FlushCache(pIoman); // Ensure dir was flushed to the disk! - - return FF_ERR_NONE; - } - - return FF_ERR_DIR_INVALID_PATH; -} - - - -FF_ERROR FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT16 usDirEntry, FF_FETCH_CONTEXT *pContext) { - - FF_ERROR Error; - FF_T_UINT8 EntryBuffer[32]; - - usDirEntry--; - - do { - Error = FF_FetchEntryWithContext(pIoman, usDirEntry, pContext, EntryBuffer); - if(Error) { - return Error; - } - - if(FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)) == FF_FAT_ATTR_LFN) { - FF_putChar(EntryBuffer, (FF_T_UINT16) 0, (FF_T_UINT8) 0xE5); - Error = FF_PushEntryWithContext(pIoman, usDirEntry, pContext, EntryBuffer); - if(Error) { - return Error; - } - } - - if(usDirEntry == 0) { - break; - } - usDirEntry--; - }while(FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)) == FF_FAT_ATTR_LFN); - - return FF_ERR_NONE; -} diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_error.c b/reactos/sdk/lib/3rdparty/fullfat/ff_error.c deleted file mode 100644 index 787c8769aaa..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_error.c +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_error.c - * @author James Walmsley - * @ingroup ERROR - * - * @defgroup ERR Error Message - * @brief Used to return pretty strings for FullFAT error codes. - * - **/ -#include "ff_config.h" -#include "ff_types.h" -#include "ff_error.h" - -#ifdef FF_DEBUG -const struct _FFERRTAB -{ - const FF_T_INT8 * const strErrorString; - const FF_T_SINT32 iErrorCode; - -} gcpFullFATErrorTable[] = -{ - {"Unknown or Generic Error! - Please contact FullFAT DEV - james@worm.me.uk", -1000}, - {"No Error.", FF_ERR_NONE}, - {"Null Pointer provided, (probably for IOMAN).", FF_ERR_NULL_POINTER}, - {"Not enough memory (malloc() returned NULL).", FF_ERR_NOT_ENOUGH_MEMORY}, - {"Device Driver returned a FATAL error!.", FF_ERR_DEVICE_DRIVER_FAILED}, - {"The blocksize is not 512 multiple.", FF_ERR_IOMAN_BAD_BLKSIZE}, - {"The memory size, is not a multiple of the blocksize. (Atleast 2 Blocks).", FF_ERR_IOMAN_BAD_MEMSIZE}, - {"Device is already registered, use FF_UnregisterBlkDevice() first.", FF_ERR_IOMAN_DEV_ALREADY_REGD}, - {"No mountable partition was found on the specified device.", FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION}, - {"The format of the MBR was unrecognised.", FF_ERR_IOMAN_INVALID_FORMAT}, - {"The provided partition number is out-of-range (0 - 3).", FF_ERR_IOMAN_INVALID_PARTITION_NUM}, - {"The selected partition / volume doesn't appear to be FAT formatted.", FF_ERR_IOMAN_NOT_FAT_FORMATTED}, - {"Cannot register device. (BlkSize not a multiple of 512).", FF_ERR_IOMAN_DEV_INVALID_BLKSIZE}, - {"Cannot unregister device, a partition is still mounted.", FF_ERR_IOMAN_PARTITION_MOUNTED}, - {"Cannot unmount the partition while there are active FILE handles.", FF_ERR_IOMAN_ACTIVE_HANDLES}, - {"The GPT partition header appears to be corrupt, refusing to mount.", FF_ERR_IOMAN_GPT_HEADER_CORRUPT}, - {"Cannot open the file, file already in use.", FF_ERR_FILE_ALREADY_OPEN}, - {"The specified file could not be found.", FF_ERR_FILE_NOT_FOUND}, - {"Cannot open a Directory.", FF_ERR_FILE_OBJECT_IS_A_DIR}, - {"Cannot open for writing: File is marked as Read-Only.", FF_ERR_FILE_IS_READ_ONLY}, - {"Path not found.", FF_ERR_FILE_INVALID_PATH}, - {"A file or folder of the same name already exists.", FF_ERR_DIR_OBJECT_EXISTS}, - {"FF_ERR_DIR_DIRECTORY_FULL", FF_ERR_DIR_DIRECTORY_FULL}, - {"FF_ERR_DIR_END_OF_DIR", FF_ERR_DIR_END_OF_DIR}, - {"The directory is not empty.", FF_ERR_DIR_NOT_EMPTY}, - {"Could not extend File or Folder - No Free Space!", FF_ERR_FAT_NO_FREE_CLUSTERS}, - {"Could not find the directory specified by the path.", FF_ERR_DIR_INVALID_PATH}, - {"The Root Dir is full, and cannot be extended on Fat12 or 16 volumes.", FF_ERR_DIR_CANT_EXTEND_ROOT_DIR}, - {"File operation failed - the file was not opened for writing.", FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE}, - {"File operation failed - the file was not opened for reading.", FF_ERR_FILE_NOT_OPENED_IN_READ_MODE}, - {"File operation failed - could not extend file.", FF_ERR_FILE_EXTEND_FAILED}, - {"Destination file already exists.", FF_ERR_FILE_DESTINATION_EXISTS}, - {"Source file was not found.", FF_ERR_FILE_SOURCE_NOT_FOUND}, - {"Destination path (dir) was not found.", FF_ERR_FILE_DIR_NOT_FOUND}, - {"Failed to create the directory Entry.", FF_ERR_FILE_COULD_NOT_CREATE_DIRENT}, - {"Not enough free disk space to complete the disk transaction.", FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE}, - {"Attempted to Read a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_READ}, - {"Attempted to Write a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE}, -}; - -/** - * @public - * @brief Returns a pointer to a string relating to a FullFAT error code. - * - * @param iErrorCode The error code. - * - * @return Pointer to a string describing the error. - * - **/ -const FF_T_INT8 *FF_GetErrMessage(FF_ERROR iErrorCode) { - FF_T_UINT32 stCount = sizeof (gcpFullFATErrorTable) / sizeof ( struct _FFERRTAB); - while (stCount--){ - if (gcpFullFATErrorTable[stCount].iErrorCode == iErrorCode) { - return gcpFullFATErrorTable[stCount].strErrorString; - } - } - return gcpFullFATErrorTable[0].strErrorString; -} -#endif diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_fat.c b/reactos/sdk/lib/3rdparty/fullfat/ff_fat.c deleted file mode 100644 index fb5ac824033..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_fat.c +++ /dev/null @@ -1,844 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_fat.c - * @author James Walmsley - * @ingroup FAT - * - * @defgroup FAT Fat File-System - * @brief Handles FAT access and traversal. - * - * Provides file-system interfaces for the FAT file-system. - **/ - -#include "ff_fat.h" -#include "ff_config.h" -#include - -void FF_lockFAT(FF_IOMAN *pIoman) { - FF_PendSemaphore(pIoman->pSemaphore); // Use Semaphore to protect FAT modifications. - { - while((pIoman->Locks & FF_FAT_LOCK)) { - FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_Yield(); // Keep Releasing and Yielding until we have the Fat protector. - FF_PendSemaphore(pIoman->pSemaphore); - } - pIoman->Locks |= FF_FAT_LOCK; - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -} - -void FF_unlockFAT(FF_IOMAN *pIoman) { - FF_PendSemaphore(pIoman->pSemaphore); - { - pIoman->Locks &= ~FF_FAT_LOCK; - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -} - -/** - * @private - **/ -FF_T_UINT32 FF_getRealLBA(FF_IOMAN *pIoman, FF_T_UINT32 LBA) { - return LBA * pIoman->pPartition->BlkFactor; -} - -/** - * @private - **/ -FF_T_UINT32 FF_Cluster2LBA(FF_IOMAN *pIoman, FF_T_UINT32 Cluster) { - FF_T_UINT32 lba = 0; - FF_PARTITION *pPart; - if(pIoman) { - pPart = pIoman->pPartition; - - if(Cluster > 1) { - lba = ((Cluster - 2) * pPart->SectorsPerCluster) + pPart->FirstDataSector; - } else { - lba = pPart->ClusterBeginLBA; - } - } - return lba; -} - -/** - * @private - **/ -FF_T_UINT32 FF_LBA2Cluster(FF_IOMAN *pIoman, FF_T_UINT32 Address) { - FF_T_UINT32 cluster = 0; - FF_PARTITION *pPart; - if(pIoman) { - pPart = pIoman->pPartition; - if(pPart->Type == FF_T_FAT32) { - cluster = ((Address - pPart->ClusterBeginLBA) / pPart->SectorsPerCluster) + 2; - } else { - cluster = ((Address - pPart->ClusterBeginLBA) / pPart->SectorsPerCluster); - } - } - return cluster; -} - -/** - * @private - **/ -FF_T_UINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_ERROR *pError) { - - FF_BUFFER *pBuffer; - FF_T_UINT32 FatOffset; - FF_T_UINT32 FatSector; - FF_T_UINT32 FatSectorEntry; - FF_T_UINT32 FatEntry; - FF_T_UINT8 LBAadjust; - FF_T_UINT16 relClusterEntry; - -#ifdef FF_FAT12_SUPPORT - FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal. -#endif - - if(pIoman->pPartition->Type == FF_T_FAT32) { - FatOffset = nCluster * 4; - } else if(pIoman->pPartition->Type == FF_T_FAT16) { - FatOffset = nCluster * 2; - }else { - FatOffset = nCluster + (nCluster / 2); - } - - FatSector = pIoman->pPartition->FatBeginLBA + (FatOffset / pIoman->pPartition->BlkSize); - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - - LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); - relClusterEntry = (FF_T_UINT32) (FatSectorEntry % pIoman->BlkSize); - - FatSector = FF_getRealLBA(pIoman, FatSector); - -#ifdef FF_FAT12_SUPPORT - if(pIoman->pPartition->Type == FF_T_FAT12) { - if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) { - // Fat Entry SPANS a Sector! - // First Buffer get the last Byte in buffer (first byte of our address)! - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); - { - if(!pBuffer) { - *pError = FF_ERR_DEVICE_DRIVER_FAILED; - return 0; - } - F12short[0] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1)); - } - FF_ReleaseBuffer(pIoman, pBuffer); - // Second Buffer get the first Byte in buffer (second byte of out address)! - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ); - { - if(!pBuffer) { - *pError = FF_ERR_DEVICE_DRIVER_FAILED; - return 0; - } - F12short[1] = FF_getChar(pBuffer->pBuffer, 0); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - FatEntry = (FF_T_UINT32) FF_getShort((FF_T_UINT8*)&F12short, 0); // Guarantee correct Endianess! - - if(nCluster & 0x0001) { - FatEntry = FatEntry >> 4; - } - FatEntry &= 0x0FFF; - return (FF_T_SINT32) FatEntry; - } - } -#endif - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); - { - if(!pBuffer) { - *pError = FF_ERR_DEVICE_DRIVER_FAILED; - return 0; - } - - switch(pIoman->pPartition->Type) { - case FF_T_FAT32: - FatEntry = FF_getLong(pBuffer->pBuffer, relClusterEntry); - FatEntry &= 0x0fffffff; // Clear the top 4 bits. - break; - - case FF_T_FAT16: - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, relClusterEntry); - break; - -#ifdef FF_FAT12_SUPPORT - case FF_T_FAT12: - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, relClusterEntry); - if(nCluster & 0x0001) { - FatEntry = FatEntry >> 4; - } - FatEntry &= 0x0FFF; - break; -#endif - default: - FatEntry = 0; - break; - } - } - FF_ReleaseBuffer(pIoman, pBuffer); - - return (FF_T_SINT32) FatEntry; -} - -FF_ERROR FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) { - FF_BUFFER *pBuffer; - FF_T_UINT16 i; - FF_T_UINT32 BaseLBA; - - BaseLBA = FF_Cluster2LBA(pIoman, nCluster); - BaseLBA = FF_getRealLBA(pIoman, BaseLBA); - - for(i = 0; i < pIoman->pPartition->SectorsPerCluster; i++) { - pBuffer = FF_GetBuffer(pIoman, BaseLBA++, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - memset(pBuffer->pBuffer, 0x00, 512); - } - FF_ReleaseBuffer(pIoman, pBuffer); - } - - return FF_ERR_NONE; -} - -/** - * @private - * @brief Returns the Cluster address of the Cluster number from the beginning of a chain. - * - * @param pIoman FF_IOMAN Object - * @param Start Cluster address of the first cluster in the chain. - * @param Count Number of Cluster in the chain, - * - * - * - **/ -FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count, FF_ERROR *pError) { - - FF_T_UINT32 i; - FF_T_UINT32 fatEntry = Start, currentCluster = Start; - - *pError = FF_ERR_NONE; - - for(i = 0; i < Count; i++) { - fatEntry = FF_getFatEntry(pIoman, currentCluster, pError); - if(*pError) { - return 0; - } - - if(FF_isEndOfChain(pIoman, fatEntry)) { - return currentCluster; - } else { - currentCluster = fatEntry; - } - } - - return fatEntry; -} - -FF_T_UINT32 FF_FindEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError) { - - FF_T_UINT32 fatEntry = Start, currentCluster = Start; - *pError = FF_ERR_NONE; - - while(!FF_isEndOfChain(pIoman, fatEntry)) { - fatEntry = FF_getFatEntry(pIoman, currentCluster, pError); - if(*pError) { - return 0; - } - - if(FF_isEndOfChain(pIoman, fatEntry)) { - return currentCluster; - } else { - currentCluster = fatEntry; - } - } - - return fatEntry; -} - - -/** - * @private - * @brief Tests if the fatEntry is an End of Chain Marker. - * - * @param pIoman FF_IOMAN Object - * @param fatEntry The fat entry from the FAT table to be checked. - * - * @return FF_TRUE if it is an end of chain, otherwise FF_FALSE. - * - **/ -FF_T_BOOL FF_isEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 fatEntry) { - FF_T_BOOL result = FF_FALSE; - if(pIoman->pPartition->Type == FF_T_FAT32) { - if((fatEntry & 0x0fffffff) >= 0x0ffffff8) { - result = FF_TRUE; - } - } else if(pIoman->pPartition->Type == FF_T_FAT16) { - if(fatEntry >= 0x0000fff8) { - result = FF_TRUE; - } - } else { - if(fatEntry >= 0x00000ff8) { - result = FF_TRUE; - } - } - if(fatEntry == 0x00000000) { - result = FF_TRUE; //Perhaps trying to read a deleted file! - } - return result; -} - - -/** - * @private - * @brief Writes a new Entry to the FAT Tables. - * - * @param pIoman IOMAN object. - * @param nCluster Cluster Number to be modified. - * @param Value The Value to store. - **/ -FF_ERROR FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value) { - - FF_BUFFER *pBuffer; - FF_T_UINT32 FatOffset; - FF_T_UINT32 FatSector; - FF_T_UINT32 FatSectorEntry; - FF_T_UINT32 FatEntry; - FF_T_UINT8 LBAadjust; - FF_T_UINT32 relClusterEntry; -#ifdef FF_FAT12_SUPPORT - FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal. -#endif - - if(pIoman->pPartition->Type == FF_T_FAT32) { - FatOffset = nCluster * 4; - } else if(pIoman->pPartition->Type == FF_T_FAT16) { - FatOffset = nCluster * 2; - }else { - FatOffset = nCluster + (nCluster / 2); - } - - FatSector = pIoman->pPartition->FatBeginLBA + (FatOffset / pIoman->pPartition->BlkSize); - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - - LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); - relClusterEntry = (FF_T_UINT32)(FatSectorEntry % pIoman->BlkSize); - - FatSector = FF_getRealLBA(pIoman, FatSector); - -#ifdef FF_FAT12_SUPPORT - if(pIoman->pPartition->Type == FF_T_FAT12) { - if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) { - // Fat Entry SPANS a Sector! - // First Buffer get the last Byte in buffer (first byte of our address)! - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - F12short[0] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1)); - } - FF_ReleaseBuffer(pIoman, pBuffer); - // Second Buffer get the first Byte in buffer (second byte of out address)! - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - F12short[1] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16) 0x0000); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - - FatEntry = FF_getShort((FF_T_UINT8*)&F12short, (FF_T_UINT16) 0x0000); // Guarantee correct Endianess! - if(nCluster & 0x0001) { - FatEntry &= 0x000F; - Value = (Value << 4); - Value &= 0xFFF0; - } else { - FatEntry &= 0xF000; - Value &= 0x0FFF; - } - - FF_putShort((FF_T_UINT8 *)F12short, 0x0000, (FF_T_UINT16) (FatEntry | Value)); - - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - FF_putChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1), F12short[0]); - } - FF_ReleaseBuffer(pIoman, pBuffer); - // Second Buffer get the first Byte in buffer (second byte of out address)! - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - FF_putChar(pBuffer->pBuffer, 0x0000, F12short[1]); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - return FF_ERR_NONE; - } - } -#endif - - pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - if(pIoman->pPartition->Type == FF_T_FAT32) { - Value &= 0x0fffffff; // Clear the top 4 bits. - FF_putLong(pBuffer->pBuffer, relClusterEntry, Value); - } else if(pIoman->pPartition->Type == FF_T_FAT16) { - FF_putShort(pBuffer->pBuffer, relClusterEntry, (FF_T_UINT16) Value); - } else { - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, relClusterEntry); - if(nCluster & 0x0001) { - FatEntry &= 0x000F; - Value = (Value << 4); - Value &= 0xFFF0; - } else { - FatEntry &= 0xF000; - Value &= 0x0FFF; - } - - FF_putShort(pBuffer->pBuffer, relClusterEntry, (FF_T_UINT16) (FatEntry | Value)); - } - } - FF_ReleaseBuffer(pIoman, pBuffer); - - return FF_ERR_NONE; -} - - - -/** - * @private - * @brief Finds a Free Cluster and returns its number. - * - * @param pIoman IOMAN Object. - * - * @return The number of the cluster found to be free. - * @return 0 on error. - **/ -#ifdef FF_FAT12_SUPPORT -static FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_T_UINT32 nCluster; - FF_T_UINT32 fatEntry; - - *pError = FF_ERR_NONE; - - for(nCluster = pIoman->pPartition->LastFreeCluster; nCluster < pIoman->pPartition->NumClusters; nCluster++) { - fatEntry = FF_getFatEntry(pIoman, nCluster, pError); - if(*pError) { - return 0; - } - if(fatEntry == 0x00000000) { - pIoman->pPartition->LastFreeCluster = nCluster; - return nCluster; - } - } - return 0; -} -#endif - -FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_BUFFER *pBuffer; - FF_T_UINT32 i, x, nCluster = pIoman->pPartition->LastFreeCluster; - FF_T_UINT32 FatOffset; - FF_T_UINT32 FatSector; - FF_T_UINT32 FatSectorEntry; - FF_T_UINT32 EntriesPerSector; - FF_T_UINT32 FatEntry = 1; - - *pError = FF_ERR_NONE; - -#ifdef FF_FAT12_SUPPORT - if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated! - return FF_FindFreeClusterOLD(pIoman, pError); - } -#endif - - if(pIoman->pPartition->Type == FF_T_FAT32) { - EntriesPerSector = pIoman->BlkSize / 4; - FatOffset = nCluster * 4; - } else { - EntriesPerSector = pIoman->BlkSize / 2; - FatOffset = nCluster * 2; - } - - // HT addition: don't use non-existing clusters - if (nCluster >= pIoman->pPartition->NumClusters) { - *pError = FF_ERR_FAT_NO_FREE_CLUSTERS; - return 0; - } - - FatSector = (FatOffset / pIoman->pPartition->BlkSize); - - for(i = FatSector; i < pIoman->pPartition->SectorsPerFAT; i++) { - pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ); - { - if(!pBuffer) { - *pError = FF_ERR_DEVICE_DRIVER_FAILED; - return 0; - } - for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) { - if(pIoman->pPartition->Type == FF_T_FAT32) { - FatOffset = x * 4; - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - FatEntry = FF_getLong(pBuffer->pBuffer, (FF_T_UINT16)FatSectorEntry); - FatEntry &= 0x0fffffff; // Clear the top 4 bits. - } else { - FatOffset = x * 2; - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, (FF_T_UINT16)FatSectorEntry); - } - if(FatEntry == 0x00000000) { - FF_ReleaseBuffer(pIoman, pBuffer); - pIoman->pPartition->LastFreeCluster = nCluster; - - return nCluster; - } - - nCluster++; - } - } - FF_ReleaseBuffer(pIoman, pBuffer); - } - - return 0; -} - -/** - * @private - * @brief Create's a Cluster Chain - **/ -FF_T_UINT32 FF_CreateClusterChain(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_T_UINT32 iStartCluster; - FF_ERROR Error; - *pError = FF_ERR_NONE; - - FF_lockFAT(pIoman); - { - iStartCluster = FF_FindFreeCluster(pIoman, &Error); - if(Error) { - *pError = Error; - FF_unlockFAT(pIoman); - return 0; - } - - if(iStartCluster) { - Error = FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as End-Of-Chain - if(Error) { - *pError = Error; - FF_unlockFAT(pIoman); - return 0; - } - } - } - FF_unlockFAT(pIoman); - - if(iStartCluster) { - Error = FF_DecreaseFreeClusters(pIoman, 1); - if(Error) { - *pError = Error; - return 0; - } - } - - return iStartCluster; -} - -FF_T_UINT32 FF_GetChainLength(FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain, FF_ERROR *pError) { - FF_T_UINT32 iLength = 0; - - *pError = FF_ERR_NONE; - - FF_lockFAT(pIoman); - { - while(!FF_isEndOfChain(pIoman, pa_nStartCluster)) { - pa_nStartCluster = FF_getFatEntry(pIoman, pa_nStartCluster, pError); - if(*pError) { - return 0; - } - iLength++; - } - if(piEndOfChain) { - *piEndOfChain = pa_nStartCluster; - } - } - FF_unlockFAT(pIoman); - - return iLength; -} - -/** - * @private - * @brief Extend a Cluster chain by Count number of Clusters - * - * @param pIoman IOMAN object. - * @param StartCluster Cluster Number that starts the chain. - * @param Count Number of clusters to extend the chain with. - * - **/ -/* -FF_T_UINT32 FF_ExtendClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT32 Count) { - - FF_T_UINT32 currentCluster = StartCluster, nextCluster; - FF_T_UINT32 clusEndOfChain; - FF_T_UINT32 i; - - clusEndOfChain = FF_FindEndOfChain(pIoman, StartCluster); - - nextCluster = FF_FindFreeCluster(pIoman); // Find Free clusters! - - FF_putFatEntry(pIoman, clusEndOfChain, nextCluster); - - for(i = 0; i <= Count; i++) { - currentCluster = nextCluster; - if(i == Count) { - FF_putFatEntry(pIoman, currentCluster, 0xFFFFFFFF); - break; - } - - nextCluster = FF_FindFreeCluster(pIoman); - FF_putFatEntry(pIoman, currentCluster, ++nextCluster); - } - FF_FlushCache(pIoman); - return currentCluster; -}*/ - - -/** - * @private - * @brief Free's Disk space by freeing unused links on Cluster Chains - * - * @param pIoman, IOMAN object. - * @param StartCluster Cluster Number that starts the chain. - * @param Count Number of Clusters from the end of the chain to unlink. - * @param Count 0 Means Free the entire chain (delete file). - * - * @return 0 On Success. - * @return -1 If the device driver failed to provide access. - * - **/ -FF_ERROR FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count) { - - FF_T_UINT32 fatEntry; - FF_T_UINT32 currentCluster, chainLength = 0; - FF_T_UINT32 iLen = 0; - FF_T_UINT32 lastFree = StartCluster; /* HT addition : reset LastFreeCluster */ - FF_ERROR Error; - - fatEntry = StartCluster; - - if(Count == 0) { - // Free all clusters in the chain! - currentCluster = StartCluster; - fatEntry = currentCluster; - do { - fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error); - if(Error) { - return Error; - } - Error = FF_putFatEntry(pIoman, currentCluster, 0x00000000); - if(Error) { - return Error; - } - - if (lastFree > currentCluster) { - lastFree = currentCluster; - } - currentCluster = fatEntry; - iLen ++; - }while(!FF_isEndOfChain(pIoman, fatEntry)); - if (pIoman->pPartition->LastFreeCluster > lastFree) { - pIoman->pPartition->LastFreeCluster = lastFree; - } - Error = FF_IncreaseFreeClusters(pIoman, iLen); - if(Error) { - return Error; - } - } else { - // Truncation - This is quite hard, because we can only do it backwards. - do { - fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error); - if(Error) { - return Error; - } - chainLength++; - }while(!FF_isEndOfChain(pIoman, fatEntry)); - } - - return FF_ERR_NONE; -} - -#ifdef FF_FAT12_SUPPORT -FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_T_UINT32 i; - FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster; - FF_T_UINT32 FatEntry; - FF_T_UINT32 FreeClusters = 0; - - *pError = FF_ERR_NONE; - - for(i = 0; i < TotalClusters; i++) { - FatEntry = FF_getFatEntry(pIoman, i, pError); - if(*pError) { - return 0; - } - if(!FatEntry) { - FreeClusters++; - } - } - - return FreeClusters; -} -#endif - - -FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_BUFFER *pBuffer; - FF_T_UINT32 i, x, nCluster = 0; - FF_T_UINT32 FatOffset; - FF_T_UINT32 FatSector; - FF_T_UINT32 FatSectorEntry; - FF_T_UINT32 EntriesPerSector; - FF_T_UINT32 FatEntry = 1; - FF_T_UINT32 FreeClusters = 0; - - *pError = FF_ERR_NONE; - -#ifdef FF_FAT12_SUPPORT - if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated! - FreeClusters = FF_CountFreeClustersOLD(pIoman, pError); - if(*pError) { - return 0; - } - } -#endif - - if(pIoman->pPartition->Type == FF_T_FAT32) { - EntriesPerSector = pIoman->BlkSize / 4; - FatOffset = nCluster * 4; - } else { - EntriesPerSector = pIoman->BlkSize / 2; - FatOffset = nCluster * 2; - } - - FatSector = (FatOffset / pIoman->pPartition->BlkSize); - - for(i = 0; i < pIoman->pPartition->SectorsPerFAT; i++) { - pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ); - { - if(!pBuffer) { - *pError = FF_ERR_DEVICE_DRIVER_FAILED; - return 0; - } - for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) { - if(pIoman->pPartition->Type == FF_T_FAT32) { - FatOffset = x * 4; - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - FatEntry = FF_getLong(pBuffer->pBuffer, (FF_T_UINT16)FatSectorEntry); - FatEntry &= 0x0fffffff; // Clear the top 4 bits. - } else { - FatOffset = x * 2; - FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; - FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FatSectorEntry); - } - if(FatEntry == 0x00000000) { - FreeClusters += 1; - } - - nCluster++; - } - } - FF_ReleaseBuffer(pIoman, pBuffer); - } - - return FreeClusters <= pIoman->pPartition->NumClusters ? FreeClusters : pIoman->pPartition->NumClusters; -} - -#ifdef FF_64_NUM_SUPPORT -FF_T_UINT64 FF_GetFreeSize(FF_IOMAN *pIoman, FF_ERROR *pError) { - FF_T_UINT32 FreeClusters; - FF_T_UINT64 FreeSize; - FF_ERROR Error; - - if(pIoman) { - FF_lockFAT(pIoman); - { - if(!pIoman->pPartition->FreeClusterCount) { - pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); - if(Error) { - if(pError) { - *pError = Error; - } - FF_unlockFAT(pIoman); - return 0; - } - } - FreeClusters = pIoman->pPartition->FreeClusterCount; - } - FF_unlockFAT(pIoman); - FreeSize = (FF_T_UINT64) ((FF_T_UINT64)FreeClusters * (FF_T_UINT64)((FF_T_UINT64)pIoman->pPartition->SectorsPerCluster * (FF_T_UINT64)pIoman->pPartition->BlkSize)); - return FreeSize; - } - return 0; -} -#else -FF_T_UINT32 FF_GetFreeSize(FF_IOMAN *pIoman) { - FF_T_UINT32 FreeClusters; - FF_T_UINT32 FreeSize; - - if(pIoman) { - FF_lockFAT(pIoman); - { - if(!pIoman->pPartition->FreeClusterCount) { - pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman); - } - FreeClusters = pIoman->pPartition->FreeClusterCount; - } - FF_unlockFAT(pIoman); - FreeSize = (FF_T_UINT32) ((FF_T_UINT32)FreeClusters * (FF_T_UINT32)((FF_T_UINT32)pIoman->pPartition->SectorsPerCluster * (FF_T_UINT32)pIoman->pPartition->BlkSize)); - return FreeSize; - } - return 0; -} -#endif \ No newline at end of file diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_file.c b/reactos/sdk/lib/3rdparty/fullfat/ff_file.c deleted file mode 100644 index 716467a7833..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_file.c +++ /dev/null @@ -1,1767 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_file.c - * @author James Walmsley - * @ingroup FILEIO - * - * @defgroup FILEIO FILE I/O Access - * @brief Provides an interface to allow File I/O on a mounted IOMAN. - * - * Provides file-system interfaces for the FAT file-system. - **/ - -#include "ff_file.h" -#include "ff_string.h" -#include "ff_config.h" - -#ifdef FF_UNICODE_SUPPORT -#include -#endif - -/** - * @public - * @brief Converts STDIO mode strings into the equivalent FullFAT mode. - * - * @param Mode The mode string e.g. "rb" "rb+" "w" "a" "r" "w+" "a+" etc - * - * @return Returns the mode bits that should be passed to the FF_Open function. - **/ -FF_T_UINT8 FF_GetModeBits(FF_T_INT8 *Mode) { - FF_T_UINT8 ModeBits = 0x00; - while(*Mode) { - switch(*Mode) { - case 'r': // Allow Read - case 'R': - ModeBits |= FF_MODE_READ; - break; - - case 'w': // Allow Write - case 'W': - ModeBits |= FF_MODE_WRITE; - ModeBits |= FF_MODE_CREATE; // Create if not exist. - ModeBits |= FF_MODE_TRUNCATE; - break; - - case 'a': // Append new writes to the end of the file. - case 'A': - ModeBits |= FF_MODE_WRITE; - ModeBits |= FF_MODE_APPEND; - ModeBits |= FF_MODE_CREATE; // Create if not exist. - break; - - case '+': // Update the file, don't Append! - ModeBits |= FF_MODE_READ; // RW Mode - ModeBits |= FF_MODE_WRITE; // RW Mode - break; - - /*case 'D': // Internal use only! - ModeBits |= FF_MODE_DIR; - break;*/ - - default: // b|B flags not supported (Binary mode is native anyway). - break; - } - Mode++; - } - - return ModeBits; -} - -/** - * FF_Open() Mode Information - * - FF_MODE_WRITE - * - Allows WRITE access to the file. - * . - * - FF_MODE_READ - * - Allows READ access to the file. - * . - * - FF_MODE_CREATE - * - Create file if it doesn't exist. - * . - * - FF_MODE_TRUNCATE - * - Erase the file if it already exists and overwrite. - * * - * - FF_MODE_APPEND - * - Causes all writes to occur at the end of the file. (Its impossible to overwrite other data in a file with this flag set). - * . - * . - * - * Some sample modes: - * - (FF_MODE_WRITE | FF_MODE_CREATE | FF_MODE_TRUNCATE) - * - Write access to the file. (Equivalent to "w"). - * . - * - (FF_MODE_WRITE | FF_MODE_READ) - * - Read and Write access to the file. (Equivalent to "rb+"). - * . - * - (FF_MODE_WRITE | FF_MODE_READ | FF_MODE_APPEND | FF_MODE_CREATE) - * - Read and Write append mode access to the file. (Equivalent to "a+"). - * . - * . - * Be careful when choosing modes. For those using FF_Open() at the application layer - * its best to use the provided FF_GetModeBits() function, as this complies to the same - * behaviour as the stdio.h fopen() function. - * - **/ - - -/** - * @public - * @brief Opens a File for Access - * - * @param pIoman FF_IOMAN object that was created by FF_CreateIOMAN(). - * @param path Path to the File or object. - * @param Mode Access Mode required. Modes are a little complicated, the function FF_GetModeBits() - * @param Mode will convert a stdio Mode string into the equivalent Mode bits for this parameter. - * @param pError Pointer to a signed byte for error checking. Can be NULL if not required. - * @param pError To be checked when a NULL pointer is returned. - * - * @return NULL pointer on Error, in which case pError should be checked for more information. - * @return pError can be: - **/ -#ifdef FF_UNICODE_SUPPORT -FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT8 Mode, FF_ERROR *pError) { -#else -FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError) { -#endif - FF_FILE *pFile; - FF_FILE *pFileChain; - FF_DIRENT Object; - FF_T_UINT32 DirCluster, FileCluster; - FF_T_UINT32 nBytesPerCluster; -#ifdef FF_UNICODE_SUPPORT - FF_T_WCHAR filename[FF_MAX_FILENAME]; -#else - FF_T_INT8 filename[FF_MAX_FILENAME]; -#endif - FF_ERROR Error; - - FF_T_UINT16 i; - - if(pError) { - *pError = 0; - } - - if(!pIoman) { - if(pError) { - *pError = FF_ERR_NULL_POINTER; - } - return (FF_FILE *)NULL; - } - pFile = FF_MALLOC(sizeof(FF_FILE)); - if(!pFile) { - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY; - } - return (FF_FILE *)NULL; - } - - // Get the Mode Bits. - pFile->Mode = Mode; - -#ifdef FF_UNICODE_SUPPORT - i = (FF_T_UINT16) wcslen(path); -#else - i = (FF_T_UINT16) strlen(path); -#endif - - while(i != 0) { - if(path[i] == '\\' || path[i] == '/') { - break; - } - i--; - } -#ifdef FF_UNICODE_SUPPORT - wcsncpy(filename, (path + i + 1), FF_MAX_FILENAME); -#else - strncpy(filename, (path + i + 1), FF_MAX_FILENAME); -#endif - - if(i == 0) { - i = 1; - } - - - DirCluster = FF_FindDir(pIoman, path, i, &Error); - if(Error) { - if(pError) { - *pError = Error; - } - FF_FREE(pFile); - return (FF_FILE *) NULL; - } - - if(DirCluster) { - - FileCluster = FF_FindEntryInDir(pIoman, DirCluster, filename, 0x00, &Object, &Error); - if(Error) { - if(pError) { - *pError = Error; - } - FF_FREE(pFile); - return (FF_FILE *) NULL; - } - - if(!FileCluster) { // If 0 was returned, it might be because the file has no allocated cluster -#ifdef FF_UNICODE_SUPPORT - if(wcslen(filename) == wcslen(Object.FileName)) { - if(Object.Filesize == 0 && FF_strmatch(filename, Object.FileName, (FF_T_UINT16) wcslen(filename)) == FF_TRUE) { -#else - if(strlen(filename) == strlen(Object.FileName)) { - if(Object.Filesize == 0 && FF_strmatch(filename, Object.FileName, (FF_T_UINT16) strlen(filename)) == FF_TRUE) { -#endif - // The file really was found! - FileCluster = 1; - } - } - } - - if(!FileCluster) { - if((pFile->Mode & FF_MODE_CREATE)) { - FileCluster = FF_CreateFile(pIoman, DirCluster, filename, &Object, &Error); - if(Error) { - if(pError) { - *pError = Error; - } - FF_FREE(pFile); - return (FF_FILE *) NULL; - } - Object.CurrentItem += 1; - } - } - - if(FileCluster) { - if(Object.Attrib == FF_FAT_ATTR_DIR) { - if(!(pFile->Mode & FF_MODE_DIR)) { - // Not the object, File Not Found! - FF_FREE(pFile); - if(pError) { - *pError = FF_ERR_FILE_OBJECT_IS_A_DIR; - } - return (FF_FILE *) NULL; - } - } - - //---------- Ensure Read-Only files don't get opened for Writing. - if((pFile->Mode & FF_MODE_WRITE) || (pFile->Mode & FF_MODE_APPEND)) { - if((Object.Attrib & FF_FAT_ATTR_READONLY)) { - FF_FREE(pFile); - if(pError) { - *pError = FF_ERR_FILE_IS_READ_ONLY; - } - return (FF_FILE *) NULL; - } - } - pFile->pIoman = pIoman; - pFile->FilePointer = 0; - pFile->ObjectCluster = Object.ObjectCluster; - pFile->Filesize = Object.Filesize; - pFile->CurrentCluster = 0; - pFile->AddrCurrentCluster = pFile->ObjectCluster; - //pFile->Mode = Mode; - pFile->Next = NULL; - pFile->DirCluster = DirCluster; - pFile->DirEntry = Object.CurrentItem - 1; - nBytesPerCluster = pFile->pIoman->pPartition->SectorsPerCluster / pIoman->BlkSize; - pFile->iChainLength = 0; - pFile->iEndOfChain = 0; - pFile->FileDeleted = FF_FALSE; - - // File Permission Processing - // Only "w" and "w+" mode strings can erase a file's contents. - // Any other combinations will not cause an erase. - if((pFile->Mode & FF_MODE_TRUNCATE)) { - pFile->Filesize = 0; - pFile->FilePointer = 0; - } - - /* - Add pFile onto the end of our linked list of FF_FILE objects. - */ - FF_PendSemaphore(pIoman->pSemaphore); - { - if(!pIoman->FirstFile) { - pIoman->FirstFile = pFile; - } else { - pFileChain = (FF_FILE *) pIoman->FirstFile; - do { - if(pFileChain->ObjectCluster == pFile->ObjectCluster) { - // File is already open! DON'T ALLOW IT! - FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_FREE(pFile); - if(pError) { - *pError = FF_ERR_FILE_ALREADY_OPEN; - } - return (FF_FILE *) NULL; - } - if(!pFileChain->Next) { - pFileChain->Next = pFile; - break; - } - pFileChain = (FF_FILE *) pFileChain->Next; - }while(pFileChain != NULL); - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - - return pFile; - }else { - FF_FREE(pFile); - if(pError) { - *pError = FF_ERR_FILE_NOT_FOUND; - } - return (FF_FILE *) NULL; - } - } - if(pError) { - *pError = FF_ERR_FILE_INVALID_PATH; - } - - FF_FREE(pFile); - - return (FF_FILE *)NULL; -} - - -/** - * @public - * @brief Tests if a Directory contains any other files or folders. - * - * @param pIoman FF_IOMAN object returned from the FF_CreateIOMAN() function. - * - **/ -#ifdef FF_UNICODE_SUPPORT -FF_T_BOOL FF_isDirEmpty(FF_IOMAN *pIoman, const FF_T_WCHAR *Path) { -#else -FF_T_BOOL FF_isDirEmpty(FF_IOMAN *pIoman, const FF_T_INT8 *Path) { -#endif - - FF_DIRENT MyDir; - FF_ERROR RetVal = FF_ERR_NONE; - FF_T_UINT8 i = 0; - - if(!pIoman) { - return FF_FALSE; - } - - RetVal = FF_FindFirst(pIoman, &MyDir, Path); - while(RetVal == 0) { - i++; - RetVal = FF_FindNext(pIoman, &MyDir); - if(i > 2) { - return FF_FALSE; - } - } - - return FF_TRUE; -} - -#ifdef FF_UNICODE_SUPPORT -FF_ERROR FF_RmDir(FF_IOMAN *pIoman, const FF_T_WCHAR *path) { -#else -FF_ERROR FF_RmDir(FF_IOMAN *pIoman, const FF_T_INT8 *path) { -#endif - FF_FILE *pFile; - FF_ERROR Error = FF_ERR_NONE; - FF_T_UINT8 EntryBuffer[32]; - FF_FETCH_CONTEXT FetchContext; - FF_T_SINT8 RetVal = FF_ERR_NONE; -#ifdef FF_PATH_CACHE - FF_T_UINT32 i; -#endif - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - pFile = FF_Open(pIoman, path, FF_MODE_DIR, &Error); - - if(!pFile) { - return Error; // File in use or File not found! - } - - pFile->FileDeleted = FF_TRUE; - - FF_lockDIR(pIoman); - { - if(FF_isDirEmpty(pIoman, path)) { - FF_lockFAT(pIoman); - { - Error = FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! - } - FF_unlockFAT(pIoman); - - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - - // Initialise the dirent Fetch Context object for faster removal of dirents. - - Error = FF_InitEntryFetch(pIoman, pFile->DirCluster, &FetchContext); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - - // Edit the Directory Entry! (So it appears as deleted); - Error = FF_RmLFNs(pIoman, pFile->DirEntry, &FetchContext); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - Error = FF_FetchEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - EntryBuffer[0] = 0xE5; - Error = FF_PushEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } -#ifdef FF_PATH_CACHE - FF_PendSemaphore(pIoman->pSemaphore); // Thread safety on shared object! - { - for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { -#ifdef FF_UNICODE_SUPPORT - if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, (FF_T_UINT16)wcslen(path))) { -#else - if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, (FF_T_UINT16)strlen(path))) { -#endif - pIoman->pPartition->PathCache[i].Path[0] = '\0'; - pIoman->pPartition->PathCache[i].DirCluster = 0; - FF_ReleaseSemaphore(pIoman->pSemaphore); - } - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -#endif - - Error = FF_IncreaseFreeClusters(pIoman, pFile->iChainLength); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - - Error = FF_FlushCache(pIoman); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - } else { - RetVal = FF_ERR_DIR_NOT_EMPTY; - } - } - FF_unlockDIR(pIoman); - Error = FF_Close(pFile); // Free the file pointer resources - - if(Error) { - return Error; - } - - // File is now lost! - return RetVal; -} - -#ifdef FF_UNICODE_SUPPORT -FF_ERROR FF_RmFile(FF_IOMAN *pIoman, const FF_T_WCHAR *path) { -#else -FF_ERROR FF_RmFile(FF_IOMAN *pIoman, const FF_T_INT8 *path) { -#endif - FF_FILE *pFile; - FF_ERROR Error = FF_ERR_NONE; - FF_T_UINT8 EntryBuffer[32]; - FF_FETCH_CONTEXT FetchContext; - - pFile = FF_Open(pIoman, path, FF_MODE_READ, &Error); - - if(!pFile) { - return Error; // File in use or File not found! - } - - pFile->FileDeleted = FF_TRUE; - - if(pFile->ObjectCluster) { // Ensure there is actually a cluster chain to delete! - FF_lockFAT(pIoman); // Lock the FAT so its thread-safe. - { - Error = FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! - } - FF_unlockFAT(pIoman); - - if(Error) { - FF_Close(pFile); - return Error; - } - } - - // Edit the Directory Entry! (So it appears as deleted); - FF_lockDIR(pIoman); - { - Error = FF_InitEntryFetch(pIoman, pFile->DirCluster, &FetchContext); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - Error = FF_RmLFNs(pIoman, pFile->DirEntry, &FetchContext); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - Error = FF_FetchEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - EntryBuffer[0] = 0xE5; - - Error = FF_PushEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_CleanupEntryFetch(pIoman, &FetchContext); - FF_unlockDIR(pIoman); - FF_Close(pFile); - return Error; - } - - FF_CleanupEntryFetch(pIoman, &FetchContext); - } - FF_unlockDIR(pIoman); - - Error = FF_FlushCache(pIoman); - if(Error) { - FF_Close(pFile); - return Error; - } - - Error = FF_Close(pFile); // Free the file pointer resources - return Error; -} - -/** - * @public - * @brief Moves a file or directory from source to destination. - * - * @param pIoman The FF_IOMAN object pointer. - * @param szSourceFile String of the source file to be moved or renamed. - * @param szDestinationFile String of the destination file to where the source should be moved or renamed. - * - * @return FF_ERR_NONE on success. - * @return FF_ERR_FILE_DESTINATION_EXISTS if the destination file exists. - * @return FF_ERR_FILE_COULD_NOT_CREATE_DIRENT if dirent creation failed (fatal error!). - * @return FF_ERR_FILE_DIR_NOT_FOUND if destination directory was not found. - * @return FF_ERR_FILE_SOURCE_NOT_FOUND if the source file was not found. - * - **/ -#ifdef FF_UNICODE_SUPPORT -FF_ERROR FF_Move(FF_IOMAN *pIoman, const FF_T_WCHAR *szSourceFile, const FF_T_WCHAR *szDestinationFile) { -#else -FF_ERROR FF_Move(FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile) { -#endif - FF_ERROR Error; - FF_FILE *pSrcFile, *pDestFile; - FF_DIRENT MyFile; - FF_T_UINT8 EntryBuffer[32]; - FF_T_UINT16 i; - FF_T_UINT32 DirCluster; - FF_FETCH_CONTEXT FetchContext; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - // Check destination file doesn't exist! - pDestFile = FF_Open(pIoman, szDestinationFile, FF_MODE_READ, &Error); - - if(pDestFile || (Error == FF_ERR_FILE_OBJECT_IS_A_DIR)) { - FF_Close(pDestFile); - return FF_ERR_FILE_DESTINATION_EXISTS; // YES -- FAIL - } - - pSrcFile = FF_Open(pIoman, szSourceFile, FF_MODE_READ, &Error); - - if(Error == FF_ERR_FILE_OBJECT_IS_A_DIR) { - // Open a directory for moving! - pSrcFile = FF_Open(pIoman, szSourceFile, FF_MODE_DIR, &Error); - } - - if(!pSrcFile) { - return Error; - } - - if(pSrcFile) { - // Create the new dirent. - Error = FF_InitEntryFetch(pIoman, pSrcFile->DirCluster, &FetchContext); - if(Error) { - FF_Close(pSrcFile); - return Error; - } - Error = FF_FetchEntryWithContext(pIoman, pSrcFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - //FF_FetchEntry(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry, EntryBuffer); - MyFile.Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); - MyFile.Filesize = pSrcFile->Filesize; - MyFile.ObjectCluster = pSrcFile->ObjectCluster; - MyFile.CurrentItem = 0; - -#ifdef FF_UNICODE_SUPPORT - i = (FF_T_UINT16) wcslen(szDestinationFile); -#else - i = (FF_T_UINT16) strlen(szDestinationFile); -#endif - - while(i != 0) { - if(szDestinationFile[i] == '\\' || szDestinationFile[i] == '/') { - break; - } - i--; - } - -#ifdef FF_UNICODE_SUPPORT - wcsncpy(MyFile.FileName, (szDestinationFile + i + 1), FF_MAX_FILENAME); -#else - strncpy(MyFile.FileName, (szDestinationFile + i + 1), FF_MAX_FILENAME); -#endif - - if(i == 0) { - i = 1; - } - - - DirCluster = FF_FindDir(pIoman, szDestinationFile, i, &Error); - if(Error) { - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - - if(DirCluster) { - - // Destination Dir was found, we can now create the new entry. - Error = FF_CreateDirent(pIoman, DirCluster, &MyFile); - if(Error) { - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; // FAILED - } - - // Edit the Directory Entry! (So it appears as deleted); - FF_lockDIR(pIoman); - { - - Error = FF_RmLFNs(pIoman, pSrcFile->DirEntry, &FetchContext); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - Error = FF_FetchEntryWithContext(pIoman, pSrcFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - EntryBuffer[0] = 0xE5; - //FF_PushEntry(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry, EntryBuffer); - Error = FF_PushEntryWithContext(pIoman, pSrcFile->DirEntry, &FetchContext, EntryBuffer); - if(Error) { - FF_unlockDIR(pIoman); - FF_Close(pSrcFile); - FF_CleanupEntryFetch(pIoman, &FetchContext); - return Error; - } - FF_CleanupEntryFetch(pIoman, &FetchContext); - } - FF_unlockDIR(pIoman); - FF_Close(pSrcFile); - - FF_FlushCache(pIoman); - - return FF_ERR_NONE; - } - - return FF_ERR_FILE_DIR_NOT_FOUND; - - } - - return FF_ERR_FILE_SOURCE_NOT_FOUND; // Source not found! -} - - -/** - * @public - * @brief Get's the next Entry based on the data recorded in the FF_DIRENT object. - * - * @param pFile FF_FILE object that was created by FF_Open(). - * - * @return FF_TRUE if End of File was reached. FF_FALSE if not. - * @return FF_FALSE if a null pointer was provided. - * - **/ -FF_T_BOOL FF_isEOF(FF_FILE *pFile) { - if(!pFile) { - return FF_FALSE; - } - if(pFile->FilePointer >= pFile->Filesize) { - return FF_TRUE; - } else { - return FF_FALSE; - } -} - -static FF_T_UINT32 FF_GetSequentialClusters(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT32 Limit, FF_ERROR *pError) { - FF_T_UINT32 CurrentCluster; - FF_T_UINT32 NextCluster = StartCluster; - FF_T_UINT32 i = 0; - - *pError = FF_ERR_NONE; - - do { - CurrentCluster = NextCluster; - NextCluster = FF_getFatEntry(pIoman, CurrentCluster, pError); - if(*pError) { - return 0; - } - if(NextCluster == (CurrentCluster + 1)) { - i++; - } else { - break; - } - - if(Limit) { - if(i == Limit) { - break; - } - } - }while(NextCluster == (CurrentCluster + 1)); - - return i; -} - -static FF_ERROR FF_ReadClusters(FF_FILE *pFile, FF_T_UINT32 Count, FF_T_UINT8 *buffer) { - FF_T_UINT32 ulSectors; - FF_T_UINT32 SequentialClusters = 0; - FF_T_UINT32 nItemLBA; - FF_T_SINT32 slRetVal; - FF_ERROR Error; - - while(Count != 0) { - if((Count - 1) > 0) { - SequentialClusters = FF_GetSequentialClusters(pFile->pIoman, pFile->AddrCurrentCluster, (Count - 1), &Error); - if(Error) { - return Error; - } - } - ulSectors = (SequentialClusters + 1) * pFile->pIoman->pPartition->SectorsPerCluster; - nItemLBA = FF_Cluster2LBA(pFile->pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pFile->pIoman, nItemLBA); - - slRetVal = FF_BlockRead(pFile->pIoman, nItemLBA, ulSectors, buffer); - if(slRetVal < 0) { - return slRetVal; - } - - Count -= (SequentialClusters + 1); - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->AddrCurrentCluster, (SequentialClusters + 1), &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += (SequentialClusters + 1); - buffer += ulSectors * pFile->pIoman->BlkSize; - SequentialClusters = 0; - } - - return FF_ERR_NONE; -} - - -static FF_ERROR FF_ExtendFile(FF_FILE *pFile, FF_T_UINT32 Size) { - FF_IOMAN *pIoman = pFile->pIoman; - FF_T_UINT32 nBytesPerCluster = pIoman->pPartition->BlkSize * pIoman->pPartition->SectorsPerCluster; - FF_T_UINT32 nTotalClustersNeeded = Size / nBytesPerCluster; - FF_T_UINT32 nClusterToExtend; - FF_T_UINT32 CurrentCluster, NextCluster; - FF_T_UINT32 i; - FF_DIRENT OriginalEntry; - FF_ERROR Error; - - if((pFile->Mode & FF_MODE_WRITE) != FF_MODE_WRITE) { - return FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE; - } - - if(pFile->Filesize == 0 && pFile->ObjectCluster == 0) { // No Allocated clusters. - // Create a Cluster chain! - pFile->AddrCurrentCluster = FF_CreateClusterChain(pFile->pIoman, &Error); - - if(Error) { - return Error; - } - - Error = FF_GetEntry(pIoman, pFile->DirEntry, pFile->DirCluster, &OriginalEntry); - - if(!Error) { - OriginalEntry.ObjectCluster = pFile->AddrCurrentCluster; - Error = FF_PutEntry(pIoman, pFile->DirEntry, pFile->DirCluster, &OriginalEntry); - } else { - return Error; - } - - if(Error) { - return Error; - } - - pFile->ObjectCluster = pFile->AddrCurrentCluster; - pFile->iChainLength = 1; - pFile->CurrentCluster = 0; - pFile->iEndOfChain = pFile->AddrCurrentCluster; - } - - if(Size % nBytesPerCluster) { - nTotalClustersNeeded += 1; - } - - if(pFile->iChainLength == 0) { // First extension requiring the chain length, - pFile->iChainLength = FF_GetChainLength(pIoman, pFile->ObjectCluster, &pFile->iEndOfChain, &Error); - if(Error) { - return Error; - } - } - - nClusterToExtend = (nTotalClustersNeeded - pFile->iChainLength); - - if(nTotalClustersNeeded > pFile->iChainLength) { - - NextCluster = pFile->AddrCurrentCluster; - FF_lockFAT(pIoman); - { - for(i = 0; i <= nClusterToExtend; i++) { - CurrentCluster = FF_FindEndOfChain(pIoman, NextCluster, &Error); - if(Error) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return Error; - } - NextCluster = FF_FindFreeCluster(pIoman, &Error); - if(Error) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return Error; - } - if(!NextCluster) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return FF_ERR_FAT_NO_FREE_CLUSTERS; - } - - Error = FF_putFatEntry(pIoman, CurrentCluster, NextCluster); - if(Error) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return Error; - } - Error = FF_putFatEntry(pIoman, NextCluster, 0xFFFFFFFF); - if(Error) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return Error; - } - } - - pFile->iEndOfChain = FF_FindEndOfChain(pIoman, NextCluster, &Error); - if(Error) { - FF_unlockFAT(pIoman); - FF_DecreaseFreeClusters(pIoman, i); - return Error; - } - } - FF_unlockFAT(pIoman); - - pFile->iChainLength += i; - Error = FF_DecreaseFreeClusters(pIoman, i); // Keep Tab of Numbers for fast FreeSize() - if(Error) { - return Error; - } - } - - return FF_ERR_NONE; -} - -static FF_ERROR FF_WriteClusters(FF_FILE *pFile, FF_T_UINT32 Count, FF_T_UINT8 *buffer) { - FF_T_UINT32 ulSectors; - FF_T_UINT32 SequentialClusters = 0; - FF_T_UINT32 nItemLBA; - FF_T_SINT32 slRetVal; - FF_ERROR Error; - - while(Count != 0) { - if((Count - 1) > 0) { - SequentialClusters = FF_GetSequentialClusters(pFile->pIoman, pFile->AddrCurrentCluster, (Count - 1), &Error); - if(Error) { - return Error; - } - } - ulSectors = (SequentialClusters + 1) * pFile->pIoman->pPartition->SectorsPerCluster; - nItemLBA = FF_Cluster2LBA(pFile->pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pFile->pIoman, nItemLBA); - - slRetVal = FF_BlockWrite(pFile->pIoman, nItemLBA, ulSectors, buffer); - - if(slRetVal < 0) { - return slRetVal; - } - - Count -= (SequentialClusters + 1); - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->AddrCurrentCluster, (SequentialClusters + 1), &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += (SequentialClusters + 1); - buffer += ulSectors * pFile->pIoman->BlkSize; - SequentialClusters = 0; - } - - return 0; -} - -/** - * @public - * @brief Equivalent to fread() - * - * @param pFile FF_FILE object that was created by FF_Open(). - * @param ElementSize The size of an element to read. - * @param Count The number of elements to read. - * @param buffer A pointer to a buffer of adequate size to be filled with the requested data. - * - * @return Number of bytes read. - * - **/ -FF_T_SINT32 FF_Read(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer) { - FF_T_UINT32 nBytes = ElementSize * Count; - FF_T_UINT32 nBytesRead = 0; - FF_T_UINT32 nBytesToRead; - FF_IOMAN *pIoman; - FF_BUFFER *pBuffer; - FF_T_UINT32 nRelBlockPos; - FF_T_UINT32 nItemLBA; - FF_T_SINT32 RetVal = 0; - FF_T_UINT16 sSectors; - FF_T_UINT32 nRelClusterPos; - FF_T_UINT32 nBytesPerCluster; - FF_T_UINT32 nClusterDiff; - FF_ERROR Error; - - if(!pFile) { - return FF_ERR_NULL_POINTER; - } - - if(!(pFile->Mode & FF_MODE_READ)) { - return FF_ERR_FILE_NOT_OPENED_IN_READ_MODE; - } - - pIoman = pFile->pIoman; - - if(pFile->FilePointer == pFile->Filesize) { - return 0; - } - - if((pFile->FilePointer + nBytes) > pFile->Filesize) { - nBytes = pFile->Filesize - pFile->FilePointer; - } - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nRelBlockPos = FF_getMinorBlockEntry(pIoman, pFile->FilePointer, 1); // Get the position within a block. - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - if((nRelBlockPos + nBytes) < pIoman->BlkSize) { // Bytes to read are within a block and less than a block size. - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - memcpy(buffer, (pBuffer->pBuffer + nRelBlockPos), nBytes); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - pFile->FilePointer += nBytes; - - return nBytes; // Return the number of bytes read. - - } else { - - //---------- Read (memcpy) to a Sector Boundary - if(nRelBlockPos != 0) { // Not on a sector boundary, at this point the LBA is known. - nBytesToRead = pIoman->BlkSize - nRelBlockPos; - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - // Here we copy to the sector boudary. - memcpy(buffer, (pBuffer->pBuffer + nRelBlockPos), nBytesToRead); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - nBytes -= nBytesToRead; - nBytesRead += nBytesToRead; - pFile->FilePointer += nBytesToRead; - buffer += nBytesToRead; - - } - - //---------- Read to a Cluster Boundary - - nRelClusterPos = FF_getClusterPosition(pIoman, pFile->FilePointer, 1); - nBytesPerCluster = (pIoman->pPartition->SectorsPerCluster * pIoman->BlkSize); - if(nRelClusterPos != 0 && nBytes >= nBytesPerCluster) { // Need to get to cluster boundary - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - sSectors = (FF_T_UINT16) (pIoman->pPartition->SectorsPerCluster - (nRelClusterPos / pIoman->BlkSize)); - - RetVal = FF_BlockRead(pIoman, nItemLBA, (FF_T_UINT32) sSectors, buffer); - - nBytesToRead = sSectors * pIoman->BlkSize; - nBytes -= nBytesToRead; - buffer += nBytesToRead; - nBytesRead += nBytesToRead; - pFile->FilePointer += nBytesToRead; - - } - - //---------- Read Clusters - if(nBytes >= nBytesPerCluster) { - //----- Thanks to Christopher Clark of DigiPen Institute of Technology in Redmond, US adding this traversal check. - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - //----- End of Contributor fix. - - RetVal = FF_ReadClusters(pFile, (nBytes / nBytesPerCluster), buffer); - if(RetVal < 0) { - return RetVal; - } - nBytesToRead = (nBytesPerCluster * (nBytes / nBytesPerCluster)); - - pFile->FilePointer += nBytesToRead; - - nBytes -= nBytesToRead; - buffer += nBytesToRead; - nBytesRead += nBytesToRead; - } - - //---------- Read Remaining Blocks - if(nBytes >= pIoman->BlkSize) { - sSectors = (FF_T_UINT16) (nBytes / pIoman->BlkSize); - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - RetVal = FF_BlockRead(pIoman, nItemLBA, (FF_T_UINT32) sSectors, buffer); - - if(RetVal < 0) { - return RetVal; - } - - nBytesToRead = sSectors * pIoman->BlkSize; - pFile->FilePointer += nBytesToRead; - nBytes -= nBytesToRead; - buffer += nBytesToRead; - nBytesRead += nBytesToRead; - } - - //---------- Read (memcpy) Remaining Bytes - if(nBytes > 0) { - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - memcpy(buffer, pBuffer->pBuffer, nBytes); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - nBytesToRead = nBytes; - pFile->FilePointer += nBytesToRead; - nBytes -= nBytesToRead; - buffer += nBytesToRead; - nBytesRead += nBytesToRead; - - } - } - - return nBytesRead; -} - - - - -/** - * @public - * @brief Equivalent to fgetc() - * - * @param pFile FF_FILE object that was created by FF_Open(). - * - * @return The character that was read (cast as a 32-bit interger). -1 on EOF. - * @return -2 If a null file pointer was provided. - * @return -3 Device access failed. - * - **/ -FF_T_SINT32 FF_GetC(FF_FILE *pFile) { - FF_T_UINT32 fileLBA; - FF_BUFFER *pBuffer; - FF_T_UINT8 retChar; - FF_T_UINT32 relMinorBlockPos; - FF_T_UINT32 clusterNum; - FF_T_UINT32 nClusterDiff; - FF_ERROR Error; - - - if(!pFile) { - return FF_ERR_NULL_POINTER; - } - - if(!(pFile->Mode & FF_MODE_READ)) { - return FF_ERR_FILE_NOT_OPENED_IN_READ_MODE; - } - - if(pFile->FilePointer >= pFile->Filesize) { - return -1; // EOF! - } - - relMinorBlockPos = FF_getMinorBlockEntry(pFile->pIoman, pFile->FilePointer, 1); - clusterNum = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1); - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - - fileLBA = FF_Cluster2LBA(pFile->pIoman, pFile->AddrCurrentCluster) + FF_getMajorBlockNumber(pFile->pIoman, pFile->FilePointer, (FF_T_UINT16) 1); - fileLBA = FF_getRealLBA (pFile->pIoman, fileLBA) + FF_getMinorBlockNumber(pFile->pIoman, pFile->FilePointer, (FF_T_UINT16) 1); - - pBuffer = FF_GetBuffer(pFile->pIoman, fileLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - retChar = pBuffer->pBuffer[relMinorBlockPos]; - } - FF_ReleaseBuffer(pFile->pIoman, pBuffer); - - pFile->FilePointer += 1; - - return (FF_T_INT32) retChar; -} - - -/** - * @public - * @brief Gets a Line from a Text File, but no more than ulLimit charachters. The line will be NULL terminated. - * - * The behaviour of this function is undefined when called on a binary file. - * It should just read in ulLimit bytes of binary, and ZERO terminate the line. - * - * This function works for both UNIX line feeds, and Windows CRLF type files. - * - * @param pFile The FF_FILE object pointer. - * @param szLine The charachter buffer where the line should be stored. - * @param ulLimit This should be the max number of charachters that szLine can hold. - * - * @return The number of charachters read from the line, on success. - * @return 0 when no more lines are available, or when ulLimit is 0. - * @return FF_ERR_NULL_POINTER if pFile or szLine are NULL; - * - **/ -FF_T_SINT32 FF_GetLine(FF_FILE *pFile, FF_T_INT8 *szLine, FF_T_UINT32 ulLimit) { - FF_T_SINT32 c; - FF_T_UINT32 i; - - if(!pFile || !szLine) { - return FF_ERR_NULL_POINTER; - } - - for(i = 0; i < (ulLimit - 1) && (c=FF_GetC(pFile)) >= 0 && c != '\n'; ++i) { - if(c == '\r') { - i--; - } else { - szLine[i] = (FF_T_INT8) c; - } - } - - szLine[i] = '\0'; - return i; -} - -FF_T_UINT32 FF_Tell(FF_FILE *pFile) { - return pFile->FilePointer; -} - - -/** - * @public - * @brief Writes data to a File. - * - * @param pFile FILE Pointer. - * @param ElementSize Size of an Element of Data to be copied. (in bytes). - * @param Count Number of Elements of Data to be copied. (ElementSize * Count must not exceed ((2^31)-1) bytes. (2GB). For best performance, multiples of 512 bytes or Cluster sizes are best. - * @param buffer Byte-wise buffer containing the data to be written. - * - * @return - **/ -FF_T_SINT32 FF_Write(FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer) { - FF_T_UINT32 nBytes = ElementSize * Count; - FF_T_UINT32 nBytesWritten = 0; - FF_T_UINT32 nBytesToWrite; - FF_IOMAN *pIoman; - FF_BUFFER *pBuffer; - FF_T_UINT32 nRelBlockPos; - FF_T_UINT32 nItemLBA; - FF_T_SINT32 slRetVal = 0; - FF_T_UINT16 sSectors; - FF_T_UINT32 nRelClusterPos; - FF_T_UINT32 nBytesPerCluster, nClusterDiff, nClusters; - FF_ERROR Error; - - if(!pFile) { - return FF_ERR_NULL_POINTER; - } - - if(!(pFile->Mode & FF_MODE_WRITE)) { - return FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE; - } - - // Make sure a write is after the append point. - if((pFile->Mode & FF_MODE_APPEND)) { - if(pFile->FilePointer < pFile->Filesize) { - FF_Seek(pFile, 0, FF_SEEK_END); - } - } - - pIoman = pFile->pIoman; - - nBytesPerCluster = (pIoman->pPartition->SectorsPerCluster * pIoman->BlkSize); - - // Extend File for atleast nBytes! - // Handle file-space allocation - Error = FF_ExtendFile(pFile, pFile->FilePointer + nBytes); - - if(Error) { - return Error; - } - - nRelBlockPos = FF_getMinorBlockEntry(pIoman, pFile->FilePointer, 1); // Get the position within a block. - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster != FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - if((nRelBlockPos + nBytes) < pIoman->BlkSize) { // Bytes to read are within a block and less than a block size. - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - memcpy((pBuffer->pBuffer + nRelBlockPos), buffer, nBytes); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - pFile->FilePointer += nBytes; - nBytesWritten = nBytes; - //return nBytes; // Return the number of bytes read. - - } else { - - //---------- Write (memcpy) to a Sector Boundary - if(nRelBlockPos != 0) { // Not on a sector boundary, at this point the LBA is known. - nBytesToWrite = pIoman->BlkSize - nRelBlockPos; - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - // Here we copy to the sector boudary. - memcpy((pBuffer->pBuffer + nRelBlockPos), buffer, nBytesToWrite); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - nBytes -= nBytesToWrite; - nBytesWritten += nBytesToWrite; - pFile->FilePointer += nBytesToWrite; - buffer += nBytesToWrite; - } - - //---------- Write to a Cluster Boundary - - nRelClusterPos = FF_getClusterPosition(pIoman, pFile->FilePointer, 1); - if(nRelClusterPos != 0 && nBytes >= nBytesPerCluster) { // Need to get to cluster boundary - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - sSectors = (FF_T_UINT16) (pIoman->pPartition->SectorsPerCluster - (nRelClusterPos / pIoman->BlkSize)); - - slRetVal = FF_BlockWrite(pFile->pIoman, nItemLBA, sSectors, buffer); - if(slRetVal < 0) { - return slRetVal; - } - - nBytesToWrite = sSectors * pIoman->BlkSize; - nBytes -= nBytesToWrite; - buffer += nBytesToWrite; - nBytesWritten += nBytesToWrite; - pFile->FilePointer += nBytesToWrite; - - } - - //---------- Write Clusters - if(nBytes >= nBytesPerCluster) { - //----- Thanks to Christopher Clark of DigiPen Institute of Technology in Redmond, US adding this traversal check. - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - //----- End of Contributor fix. - - nClusters = (nBytes / nBytesPerCluster); - - slRetVal = FF_WriteClusters(pFile, nClusters, buffer); - if(slRetVal < 0) { - return slRetVal; - } - - nBytesToWrite = (nBytesPerCluster * nClusters); - - pFile->FilePointer += nBytesToWrite; - - nBytes -= nBytesToWrite; - buffer += nBytesToWrite; - nBytesWritten += nBytesToWrite; - } - - //---------- Write Remaining Blocks - if(nBytes >= pIoman->BlkSize) { - sSectors = (FF_T_UINT16) (nBytes / pIoman->BlkSize); - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - - slRetVal = FF_BlockWrite(pFile->pIoman, nItemLBA, sSectors, buffer); - if(slRetVal < 0) { - return slRetVal; - } - - nBytesToWrite = sSectors * pIoman->BlkSize; - pFile->FilePointer += nBytesToWrite; - nBytes -= nBytesToWrite; - buffer += nBytesToWrite; - nBytesWritten += nBytesToWrite; - } - - //---------- Write (memcpy) Remaining Bytes - if(nBytes > 0) { - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - nItemLBA = FF_Cluster2LBA(pIoman, pFile->AddrCurrentCluster); - nItemLBA = FF_getRealLBA(pIoman, nItemLBA + FF_getMajorBlockNumber(pIoman, pFile->FilePointer, 1)) + FF_getMinorBlockNumber(pIoman, pFile->FilePointer, 1); - pBuffer = FF_GetBuffer(pIoman, nItemLBA, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - memcpy(pBuffer->pBuffer, buffer, nBytes); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - nBytesToWrite = nBytes; - pFile->FilePointer += nBytesToWrite; - nBytes -= nBytesToWrite; - buffer += nBytesToWrite; - nBytesWritten += nBytesToWrite; - - } - } - - if(pFile->FilePointer > pFile->Filesize) { - pFile->Filesize = pFile->FilePointer; - } - - return nBytesWritten; -} - - -/** - * @public - * @brief Writes a char to a FILE. - * - * @param pFile FILE Pointer. - * @param pa_cValue Char to be placed in the file. - * - * @return Returns the value written to the file, or a value less than 0. - * - **/ -FF_T_SINT32 FF_PutC(FF_FILE *pFile, FF_T_UINT8 pa_cValue) { - FF_BUFFER *pBuffer; - FF_T_UINT32 iItemLBA; - FF_T_UINT32 iRelPos; - FF_T_UINT32 nClusterDiff; - FF_ERROR Error; - - if(!pFile) { // Ensure we don't have a Null file pointer on a Public interface. - return FF_ERR_NULL_POINTER; - } - - if(!(pFile->Mode & FF_MODE_WRITE)) { - return FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE; - } - - // Make sure a write is after the append point. - if((pFile->Mode & FF_MODE_APPEND)) { - if(pFile->FilePointer < pFile->Filesize) { - FF_Seek(pFile, 0, FF_SEEK_END); - } - } - - iRelPos = FF_getMinorBlockEntry(pFile->pIoman, pFile->FilePointer, 1); - - // Handle File Space Allocation. - Error = FF_ExtendFile(pFile, pFile->FilePointer + 1); - if(Error) { - return Error; - } - - nClusterDiff = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1) - pFile->CurrentCluster; - if(nClusterDiff) { - if(pFile->CurrentCluster < FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1)) { - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->AddrCurrentCluster, nClusterDiff, &Error); - if(Error) { - return Error; - } - pFile->CurrentCluster += nClusterDiff; - } - } - - iItemLBA = FF_Cluster2LBA(pFile->pIoman, pFile->AddrCurrentCluster) + FF_getMajorBlockNumber(pFile->pIoman, pFile->FilePointer, (FF_T_UINT16) 1); - iItemLBA = FF_getRealLBA (pFile->pIoman, iItemLBA) + FF_getMinorBlockNumber(pFile->pIoman, pFile->FilePointer, (FF_T_UINT16) 1); - - pBuffer = FF_GetBuffer(pFile->pIoman, iItemLBA, FF_MODE_WRITE); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - FF_putChar(pBuffer->pBuffer, (FF_T_UINT16) iRelPos, pa_cValue); - } - FF_ReleaseBuffer(pFile->pIoman, pBuffer); - - pFile->FilePointer += 1; - if(pFile->Filesize < (pFile->FilePointer)) { - pFile->Filesize += 1; - } - return pa_cValue; -} - - - -/** - * @public - * @brief Equivalent to fseek() - * - * @param pFile FF_FILE object that was created by FF_Open(). - * @param Offset An integer (+/-) to seek to, from the specified origin. - * @param Origin Where to seek from. (FF_SEEK_SET seek from start, FF_SEEK_CUR seek from current position, or FF_SEEK_END seek from end of file). - * - * @return 0 on Sucess, - * @return -2 if offset results in an invalid position in the file. - * @return FF_ERR_NULL_POINTER if a FF_FILE pointer was not recieved. - * @return -3 if an invalid origin was provided. - * - **/ -FF_ERROR FF_Seek(FF_FILE *pFile, FF_T_SINT32 Offset, FF_T_INT8 Origin) { - - FF_ERROR Error; - - if(!pFile) { - return FF_ERR_NULL_POINTER; - } - - Error = FF_FlushCache(pFile->pIoman); - if(Error) { - return Error; - } - - switch(Origin) { - case FF_SEEK_SET: - if((FF_T_UINT32) Offset <= pFile->Filesize && Offset >= 0) { - pFile->FilePointer = Offset; - pFile->CurrentCluster = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1); - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->ObjectCluster, pFile->CurrentCluster, &Error); - if(Error) { - return Error; - } - } else { - return -2; - } - break; - - case FF_SEEK_CUR: - if((Offset + pFile->FilePointer) <= pFile->Filesize && (Offset + (FF_T_SINT32) pFile->FilePointer) >= 0) { - pFile->FilePointer = Offset + pFile->FilePointer; - pFile->CurrentCluster = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1); - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->ObjectCluster, pFile->CurrentCluster, &Error); - if(Error) { - return Error; - } - } else { - return -2; - } - break; - - case FF_SEEK_END: - if((Offset + (FF_T_SINT32) pFile->Filesize) >= 0 && (Offset + pFile->Filesize) <= pFile->Filesize) { - pFile->FilePointer = Offset + pFile->Filesize; - pFile->CurrentCluster = FF_getClusterChainNumber(pFile->pIoman, pFile->FilePointer, 1); - pFile->AddrCurrentCluster = FF_TraverseFAT(pFile->pIoman, pFile->ObjectCluster, pFile->CurrentCluster, &Error); - if(Error) { - return Error; - } - } else { - return -2; - } - break; - - default: - return -3; - - } - - return 0; -} - - -/** - * @public - * @brief Equivalent to fclose() - * - * @param pFile FF_FILE object that was created by FF_Open(). - * - * @return 0 on sucess. - * @return -1 if a null pointer was provided. - * - **/ -FF_ERROR FF_Close(FF_FILE *pFile) { - - FF_FILE *pFileChain; - FF_DIRENT OriginalEntry; - FF_ERROR Error; - - if(!pFile) { - return FF_ERR_NULL_POINTER; - } - // UpDate Dirent if File-size has changed? - - // Update the Dirent! - Error = FF_GetEntry(pFile->pIoman, pFile->DirEntry, pFile->DirCluster, &OriginalEntry); - if(Error) { - return Error; - } - - if(!pFile->FileDeleted) { - if(pFile->Filesize != OriginalEntry.Filesize) { - OriginalEntry.Filesize = pFile->Filesize; - Error = FF_PutEntry(pFile->pIoman, pFile->DirEntry, pFile->DirCluster, &OriginalEntry); - if(Error) { - return Error; - } - } - } - - Error = FF_FlushCache(pFile->pIoman); // Ensure all modfied blocks are flushed to disk! - - // Handle Linked list! - FF_PendSemaphore(pFile->pIoman->pSemaphore); - { // Semaphore is required, or linked list could become corrupted. - if(pFile->pIoman->FirstFile == pFile) { - pFile->pIoman->FirstFile = pFile->Next; - } else { - pFileChain = (FF_FILE *) pFile->pIoman->FirstFile; - while(pFileChain->Next != pFile) { - pFileChain = pFileChain->Next; - } - pFileChain->Next = pFile->Next; - } - } // Semaphore released, linked list was shortened! - FF_ReleaseSemaphore(pFile->pIoman->pSemaphore); - - // If file written, flush to disk - FF_FREE(pFile); - - if(Error) { - return Error; - } - - // Simply free the pointer! - return FF_ERR_NONE; -} diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_format.c b/reactos/sdk/lib/3rdparty/fullfat/ff_format.c deleted file mode 100644 index 8799f9a204e..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_format.c +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_format.c - * @author James Walmsley - * @ingroup FORMAT - * - * @defgroup FORMAT Independent FAT Formatter - * @brief Provides an interface to format a partition with FAT. - * - * - * - **/ - - -#include "ff_format.h" -#include "ff_types.h" -#include "ff_ioman.h" -#include "ff_fatdef.h" - -static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer) -{ - FF_T_SINT8 count = 0; - FF_T_SINT8 part; - // Check PBR or MBR signature - if (FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0x55 && - FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0xAA ) { - // No MBR, but is it a PBR ? - if (FF_getChar(pBuffer, 0) == 0xEB && // PBR Byte 0 - FF_getChar(pBuffer, 2) == 0x90 && // PBR Byte 2 - (FF_getChar(pBuffer, 21) & 0xF0) == 0xF0) {// PBR Byte 21 : Media byte - return 1; // No MBR but PBR exist then only one partition - } - return 0; // No MBR and no PBR then no partition found - } - for (part = 0; part < 4; part++) { - FF_T_UINT8 active = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ACTIVE + (16 * part)); - FF_T_UINT8 part_id = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID + (16 * part)); - // The first sector must be a MBR, then check the partition entry in the MBR - if (active != 0x80 && (active != 0 || part_id == 0)) { - break; - } - count++; - } - return count; -} - -FF_ERROR FF_FormatPartition(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber, FF_T_UINT32 ulClusterSize) { - - FF_BUFFER *pBuffer; - FF_T_UINT8 ucPartitionType; - FF_T_SINT8 scPartitionCount; - - FF_T_UINT32 /*ulPartitionBeginLBA, ulPartitionLength,*/ ulPnum; - - FF_ERROR Error = FF_ERR_NONE; - - ulClusterSize = 0; - - // Get Partition Metrics, and pass on to FF_Format() function - - pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - - scPartitionCount = FF_PartitionCount(pBuffer->pBuffer); - - ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID); - - if(ucPartitionType == 0xEE) { - // Handle Extended Partitions - ulPnum = 0; - } else { - if(ulPartitionNumber > (FF_T_UINT32) scPartitionCount) { - FF_ReleaseBuffer(pIoman, pBuffer); - return FF_ERR_IOMAN_INVALID_PARTITION_NUM; - } - ulPnum = ulPartitionNumber; - } - - } - FF_ReleaseBuffer(pIoman, pBuffer); - - - - return Error; - -} - -FF_ERROR FF_Format(FF_IOMAN *pIoman, FF_T_UINT32 ulStartLBA, FF_T_UINT32 ulEndLBA, FF_T_UINT32 ulClusterSize) { - FF_T_UINT32 ulTotalSectors; - FF_T_UINT32 ulTotalClusters; - - ulTotalSectors = ulEndLBA - ulStartLBA; - ulTotalClusters = ulTotalSectors / (ulClusterSize / pIoman->BlkSize); - - - return -1; - - -} \ No newline at end of file diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_hash.c b/reactos/sdk/lib/3rdparty/fullfat/ff_hash.c deleted file mode 100644 index 6357987b313..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_hash.c +++ /dev/null @@ -1,119 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_hash.c - * @author James Walmsley - * @ingroup HASH - * - * @defgroup HASH HASH Table - * @brief Provides a simple HASH lookup table. - * - **/ - -#include "ff_hash.h" -#include -#include - -#ifdef FF_HASH_CACHE -struct _FF_HASH_TABLE { - FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE]; -}; - -/** - * - * - **/ -FF_HASH_TABLE FF_CreateHashTable() { - FF_HASH_TABLE pHash = (FF_HASH_TABLE) FF_MALLOC(sizeof(struct _FF_HASH_TABLE)); - - if(pHash) { - FF_ClearHashTable(pHash); - return pHash; - } - - return NULL; -} - -FF_ERROR FF_ClearHashTable(FF_HASH_TABLE pHash) { - if(pHash) { - memset(pHash->bitTable, 0, FF_HASH_TABLE_SIZE); - return FF_ERR_NONE; - } - - return FF_ERR_NULL_POINTER; -} - -FF_ERROR FF_SetHash(FF_HASH_TABLE pHash, FF_T_UINT32 nHash) { - FF_T_UINT32 tblIndex = ((nHash / 8) % FF_HASH_TABLE_SIZE); - FF_T_UINT32 tblBit = nHash % 8; - - if(pHash) { - pHash->bitTable[tblIndex] |= (0x80 >> tblBit); - return FF_ERR_NONE; - } - - return FF_ERR_NULL_POINTER; -} - -FF_ERROR FF_ClearHash(FF_HASH_TABLE pHash, FF_T_UINT32 nHash) { - FF_T_UINT32 tblIndex = ((nHash / 8) % FF_HASH_TABLE_SIZE); - FF_T_UINT32 tblBit = nHash % 8; - - if(pHash) { - pHash->bitTable[tblIndex] &= ~(0x80 >> tblBit); - return FF_ERR_NONE; - } - - return FF_ERR_NULL_POINTER; -} - -FF_T_BOOL FF_isHashSet(FF_HASH_TABLE pHash, FF_T_UINT32 nHash) { - FF_T_UINT32 tblIndex = ((nHash / 8) % FF_HASH_TABLE_SIZE); - FF_T_UINT32 tblBit = nHash % 8; - - if(pHash) { - if(pHash->bitTable[tblIndex] & (0x80 >> tblBit)) { - return FF_TRUE; - } - } - return FF_FALSE; -} - -FF_ERROR FF_DestroyHashTable(FF_HASH_TABLE pHash) { - if(pHash) { - FF_FREE(pHash); - return FF_ERR_NONE; - } - return FF_ERR_NULL_POINTER; -} - -#endif diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_ioman.c b/reactos/sdk/lib/3rdparty/fullfat/ff_ioman.c deleted file mode 100644 index 8e8fc32d418..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_ioman.c +++ /dev/null @@ -1,1100 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_ioman.c - * @author James Walmsley - * @ingroup IOMAN - * - * @defgroup IOMAN I/O Manager - * @brief Handles IO buffers for FullFAT safely. - * - * Provides a simple static interface to the rest of FullFAT to manage - * buffers. It also defines the public interfaces for Creating and - * Destroying a FullFAT IO object. - **/ - -#include - -#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, -#include "ff_fatdef.h" -#include "ff_crc.h" - -//extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman); -extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman, FF_ERROR *pError); - -static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman); - -/** - * @public - * @brief Creates an FF_IOMAN object, to initialise FullFAT - * - * @param pCacheMem Pointer to a buffer for the cache. (NULL if ok to Malloc). - * @param Size The size of the provided buffer, or size of the cache to be created. (Must be atleast 2 * BlkSize). Always a multiple of BlkSize. - * @param BlkSize The block size of devices to be attached. If in doubt use 512. - * @param pError Pointer to a signed byte for error checking. Can be NULL if not required. - * @param pError To be checked when a NULL pointer is returned. - * - * @return Returns a pointer to an FF_IOMAN type object. NULL on Error, check the contents of - * @return pError - **/ -FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 BlkSize, FF_ERROR *pError) { - - FF_IOMAN *pIoman = NULL; - FF_T_UINT32 *pLong = NULL; // Force malloc to malloc memory on a 32-bit boundary. -#ifdef FF_PATH_CACHE - FF_T_UINT32 i; -#endif - - if(pError) { - *pError = FF_ERR_NONE; - } - - if((BlkSize % 512) != 0 || BlkSize == 0) { - if(pError) { - *pError = FF_ERR_IOMAN_BAD_BLKSIZE | FF_CREATEIOMAN; - } - return NULL; // BlkSize Size not a multiple of 512 > 0 - } - - if((Size % BlkSize) != 0 || Size == 0 || Size == BlkSize) { // Size must now be atleast 2 * BlkSize (or a deadlock will occur). - if(pError) { - *pError = FF_ERR_IOMAN_BAD_MEMSIZE | FF_CREATEIOMAN; - } - return NULL; // Memory Size not a multiple of BlkSize > 0 - } - - pIoman = (FF_IOMAN *) FF_MALLOC(sizeof(FF_IOMAN)); - - if(!pIoman) { // Ensure malloc() succeeded. - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN; - } - return NULL; - } - - memset (pIoman, '\0', sizeof(FF_IOMAN)); - - // This is just a bit-mask, to use a byte to keep track of memory. - // pIoman->MemAllocation = 0x00; // Unset all allocation identifiers. - pIoman->pPartition = (FF_PARTITION *) FF_MALLOC(sizeof(FF_PARTITION)); - if(!pIoman->pPartition) { - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN; - } - FF_DestroyIOMAN(pIoman); - return NULL; - } - memset (pIoman->pPartition, '\0', sizeof(FF_PARTITION)); - - pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART; // If succeeded, flag that allocation. - pIoman->pPartition->LastFreeCluster = 0; - pIoman->pPartition->PartitionMounted = FF_FALSE; // This should be checked by FF_Open(); -#ifdef FF_PATH_CACHE - pIoman->pPartition->PCIndex = 0; - for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { - pIoman->pPartition->PathCache[i].DirCluster = 0; - pIoman->pPartition->PathCache[i].Path[0] = '\0'; -/*#ifdef FF_HASH_TABLE_SUPPORT - pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable(); - pIoman->pPartition->PathCache[i].bHashed = FF_FALSE; -#endif*/ - } -#endif - -#ifdef FF_HASH_CACHE - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - pIoman->HashCache[i].pHashTable = FF_CreateHashTable(); - pIoman->HashCache[i].ulDirCluster = 0; - pIoman->HashCache[i].ulMisses = 100; - } -#endif - - pIoman->pBlkDevice = (FF_BLK_DEVICE *) FF_MALLOC(sizeof(FF_BLK_DEVICE)); - if(!pIoman->pBlkDevice) { // If succeeded, flag that allocation. - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN; - } - FF_DestroyIOMAN(pIoman); - return NULL; - } - memset (pIoman->pBlkDevice, '\0', sizeof(FF_BLK_DEVICE)); - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV; - - // Make sure all pointers are NULL - pIoman->pBlkDevice->fnpReadBlocks = NULL; - pIoman->pBlkDevice->fnpWriteBlocks = NULL; - pIoman->pBlkDevice->pParam = NULL; - - // Organise the memory provided, or create our own! - if(pCacheMem) { - pIoman->pCacheMem = pCacheMem; - }else { // No-Cache buffer provided (malloc) - pLong = (FF_T_UINT32 *) FF_MALLOC(Size); - pIoman->pCacheMem = (FF_T_UINT8 *) pLong; - if(!pIoman->pCacheMem) { - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN; - } - FF_DestroyIOMAN(pIoman); - return NULL; - } - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS; - - } - memset (pIoman->pCacheMem, '\0', Size); - - pIoman->BlkSize = BlkSize; - pIoman->CacheSize = (FF_T_UINT16) (Size / BlkSize); - pIoman->FirstFile = NULL; - pIoman->Locks = 0; - - /* Malloc() memory for buffer objects. (FullFAT never refers to a buffer directly - but uses buffer objects instead. Allows us to provide thread safety. - */ - pIoman->pBuffers = (FF_BUFFER *) FF_MALLOC(sizeof(FF_BUFFER) * pIoman->CacheSize); - - if(!pIoman->pBuffers) { - if(pError) { - *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN; - } - FF_DestroyIOMAN(pIoman); - return NULL; // HT added - } - memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize); - - pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR; - FF_IOMAN_InitBufferDescriptors(pIoman); - - // Finally create a Semaphore for Buffer Description modifications. - pIoman->pSemaphore = FF_CreateSemaphore(); - -#ifdef FF_BLKDEV_USES_SEM - pIoman->pBlkDevSemaphore = FF_CreateSemaphore(); -#endif - - return pIoman; // Sucess, return the created object. -} - -/** - * @public - * @brief Destroys an FF_IOMAN object, and frees all assigned memory. - * - * @param pIoman Pointer to an FF_IOMAN object, as returned from FF_CreateIOMAN. - * - * @return FF_ERR_NONE on sucess, or a documented error code on failure. (FF_ERR_NULL_POINTER) - * - **/ -FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) { - -#ifdef FF_HASH_CACHE - FF_T_UINT32 i; -#endif - - // Ensure no NULL pointer was provided. - if(!pIoman) { - return FF_ERR_NULL_POINTER | FF_DESTROYIOMAN; - } - - // Ensure pPartition pointer was allocated. - if((pIoman->MemAllocation & FF_IOMAN_ALLOC_PART)) { - FF_FREE(pIoman->pPartition); - } - - // Ensure pBlkDevice pointer was allocated. - if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BLKDEV)) { - FF_FREE(pIoman->pBlkDevice); - } - - // Ensure pBuffers pointer was allocated. - if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFDESCR)) { - FF_FREE(pIoman->pBuffers); - } - - // Ensure pCacheMem pointer was allocated. - if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFFERS)) { - FF_FREE(pIoman->pCacheMem); - } - - // Destroy any Semaphore that was created. - if(pIoman->pSemaphore) { - FF_DestroySemaphore(pIoman->pSemaphore); - } -#ifdef FF_BLKDEV_USES_SEM - if(pIoman->pBlkDevSemaphore) { - FF_DestroySemaphore(pIoman->pBlkDevSemaphore); - } -#endif - - // Destroy HashCache -#ifdef FF_HASH_CACHE - for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) { - FF_DestroyHashTable(pIoman->HashCache[i].pHashTable); - } -#endif - - // Finally free the FF_IOMAN object. - FF_FREE(pIoman); - - return FF_ERR_NONE; -} - -/** - * @private - * @brief Initialises Buffer Descriptions as part of the FF_IOMAN object initialisation. - * - * @param pIoman IOMAN Object. - * - **/ -static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) { - FF_T_UINT16 i; - FF_BUFFER *pBuffer = pIoman->pBuffers; - pIoman->LastReplaced = 0; - // HT : it is assmued that pBuffer was cleared by memset () - for(i = 0; i < pIoman->CacheSize; i++) { - pBuffer->pBuffer = (FF_T_UINT8 *)((pIoman->pCacheMem) + (pIoman->BlkSize * i)); - pBuffer++; - } -} - - -/** - * @private - * @brief Flushes all Write cache buffers with no active Handles. - * - * @param pIoman IOMAN Object. - * - * @return FF_ERR_NONE on Success. - **/ -FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) { - - FF_T_UINT16 i,x; - - if(!pIoman) { - return FF_ERR_NULL_POINTER | FF_FLUSHCACHE; - } - - FF_PendSemaphore(pIoman->pSemaphore); - { - for(i = 0; i < pIoman->CacheSize; i++) { - if((pIoman->pBuffers + i)->NumHandles == 0 && (pIoman->pBuffers + i)->Modified == FF_TRUE) { - - FF_BlockWrite(pIoman, (pIoman->pBuffers + i)->Sector, 1, (pIoman->pBuffers + i)->pBuffer); - - // Buffer has now been flushed, mark it as a read buffer and unmodified. - (pIoman->pBuffers + i)->Mode = FF_MODE_READ; - (pIoman->pBuffers + i)->Modified = FF_FALSE; - - // Search for other buffers that used this sector, and mark them as modified - // So that further requests will result in the new sector being fetched. - for(x = 0; x < pIoman->CacheSize; x++) { - if(x != i) { - if((pIoman->pBuffers + x)->Sector == (pIoman->pBuffers + i)->Sector && (pIoman->pBuffers + x)->Mode == FF_MODE_READ) { - (pIoman->pBuffers + x)->Modified = FF_TRUE; - } - } - } - } - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - - return FF_ERR_NONE; -} - -FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) { - FF_BUFFER *pBuffer; - FF_BUFFER *pBufLRU = NULL; - FF_BUFFER *pBufLHITS = NULL; - FF_BUFFER *pBufMatch = NULL; - - FF_T_UINT32 i; - - while(!pBufMatch) { - FF_PendSemaphore(pIoman->pSemaphore); - { - pBuffer = pIoman->pBuffers; - // HT if a perfect match has priority, find that first - for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) { - pBuffer = (pIoman->pBuffers + i); - if(pBuffer->Sector == Sector && pBuffer->Valid == FF_TRUE) { - pBufMatch = pBuffer; - break; // Why look further if you found a perfect match? - } - } - - if(pBufMatch) { - // A Match was found process! - if(Mode == FF_MODE_READ && pBufMatch->Mode == FF_MODE_READ) { - pBufMatch->NumHandles += 1; - pBufMatch->Persistance += 1; - FF_ReleaseSemaphore(pIoman->pSemaphore); - return pBufMatch; - } - - if(pBufMatch->Mode == FF_MODE_WRITE && pBufMatch->NumHandles == 0) { // This buffer has no attached handles. - pBufMatch->Mode = Mode; - pBufMatch->NumHandles = 1; - pBufMatch->Persistance += 1; - FF_ReleaseSemaphore(pIoman->pSemaphore); - return pBufMatch; - } - - if(pBufMatch->Mode == FF_MODE_READ && Mode == FF_MODE_WRITE && pBufMatch->NumHandles == 0) { - pBufMatch->Mode = Mode; - pBufMatch->Modified = FF_TRUE; - pBufMatch->NumHandles = 1; - pBufMatch->Persistance += 1; - FF_ReleaseSemaphore(pIoman->pSemaphore); - return pBufMatch; - } - - pBufMatch = NULL; // Sector is already in use, keep yielding until its available! - - } else { - pBuffer = pIoman->pBuffers; - for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) { - if(pBuffer->NumHandles == 0) { - pBuffer->LRU += 1; - - if(!pBufLRU) { - pBufLRU = pBuffer; - } - if(!pBufLHITS) { - pBufLHITS = pBuffer; - } - - if(pBuffer->LRU >= pBufLRU->LRU) { - if(pBuffer->LRU == pBufLRU->LRU) { - if(pBuffer->Persistance > pBufLRU->Persistance) { - pBufLRU = pBuffer; - } - } else { - pBufLRU = pBuffer; - } - } - - if(pBuffer->Persistance < pBufLHITS->Persistance) { - pBufLHITS = pBuffer; - } - } - } - - if(pBufLRU) { - // Process the suitable candidate. - if(pBufLRU->Modified == FF_TRUE) { - FF_BlockWrite(pIoman, pBufLRU->Sector, 1, pBufLRU->pBuffer); - } - pBufLRU->Mode = Mode; - pBufLRU->Persistance = 1; - pBufLRU->LRU = 0; - pBufLRU->NumHandles = 1; - pBufLRU->Sector = Sector; - - if(Mode == FF_MODE_WRITE) { - pBufLRU->Modified = FF_TRUE; - } else { - pBufLRU->Modified = FF_FALSE; - } - - FF_BlockRead(pIoman, Sector, 1, pBufLRU->pBuffer); - pBufLRU->Valid = FF_TRUE; - FF_ReleaseSemaphore(pIoman->pSemaphore); - return pBufLRU; - } - - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_Yield(); // Better to go asleep to give low-priority task a chance to release buffer(s) - } - - return pBufMatch; // Return the Matched Buffer! -} - - -/** - * @private - * @brief Releases a buffer resource. - * - * @param pIoman Pointer to an FF_IOMAN object. - * @param pBuffer Pointer to an FF_BUFFER object. - * - **/ -void FF_ReleaseBuffer(FF_IOMAN *pIoman, FF_BUFFER *pBuffer) { - // Protect description changes with a semaphore. - FF_PendSemaphore(pIoman->pSemaphore); - { - if (pBuffer->NumHandles) { - pBuffer->NumHandles--; - } else { - //printf ("FF_ReleaseBuffer: buffer not claimed\n"); - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); -} - -/** - * @public - * @brief Registers a device driver with FullFAT - * - * The device drivers must adhere to the specification provided by - * FF_WRITE_BLOCKS and FF_READ_BLOCKS. - * - * @param pIoman FF_IOMAN object. - * @param BlkSize Block Size that the driver deals in. (Minimum 512, larger values must be a multiple of 512). - * @param fnWriteBlocks Pointer to the Write Blocks to device function, as described by FF_WRITE_BLOCKS. - * @param fnReadBlocks Pointer to the Read Blocks from device function, as described by FF_READ_BLOCKS. - * @param pParam Pointer to a parameter for use in the functions. - * - * @return 0 on success, FF_ERR_IOMAN_DEV_ALREADY_REGD if a device was already hooked, FF_ERR_IOMAN_NULL_POINTER if a pIoman object wasn't provided. - **/ -FF_ERROR FF_RegisterBlkDevice(FF_IOMAN *pIoman, FF_T_UINT16 BlkSize, FF_WRITE_BLOCKS fnWriteBlocks, FF_READ_BLOCKS fnReadBlocks, void *pParam) { - if(!pIoman) { // We can't do anything without an IOMAN object. - return FF_ERR_NULL_POINTER | FF_REGISTERBLKDEVICE; - } - - if((BlkSize % 512) != 0 || BlkSize == 0) { - return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0 - } - - if((BlkSize % pIoman->BlkSize) != 0 || BlkSize == 0) { - return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0 - } - - // Ensure that a device cannot be re-registered "mid-flight" - // Doing so would corrupt the context of FullFAT - if(pIoman->pBlkDevice->fnpReadBlocks) { - return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE; - } - if(pIoman->pBlkDevice->fnpWriteBlocks) { - return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE; - } - if(pIoman->pBlkDevice->pParam) { - return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE; - } - - // Here we shall just set the values. - // FullFAT checks before using any of these values. - pIoman->pBlkDevice->devBlkSize = BlkSize; - pIoman->pBlkDevice->fnpReadBlocks = fnReadBlocks; - pIoman->pBlkDevice->fnpWriteBlocks = fnWriteBlocks; - pIoman->pBlkDevice->pParam = pParam; - - return FF_ERR_NONE; // Success -} - -/* - New Interface for FullFAT to read blocks. -*/ - -FF_T_SINT32 FF_BlockRead(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) { - FF_T_SINT32 slRetVal = 0; - - if(pIoman->pPartition->TotalSectors) { - if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) { - return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_BLOCKREAD); - } - } - - if(pIoman->pBlkDevice->fnpReadBlocks) { // Make sure we don't execute a NULL. -#ifdef FF_BLKDEV_USES_SEM - FF_PendSemaphore(pIoman->pBlkDevSemaphore); -#endif - slRetVal = pIoman->pBlkDevice->fnpReadBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam); -#ifdef FF_BLKDEV_USES_SEM - FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore); -#endif - if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) { - FF_Sleep(FF_DRIVER_BUSY_SLEEP); - } - } while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY); - - return slRetVal; -} - -FF_T_SINT32 FF_BlockWrite(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) { - FF_T_SINT32 slRetVal = 0; - - if(pIoman->pPartition->TotalSectors) { - if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) { - return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_BLOCKWRITE); - } - } - - if(pIoman->pBlkDevice->fnpWriteBlocks) { // Make sure we don't execute a NULL. -#ifdef FF_BLKDEV_USES_SEM - FF_PendSemaphore(pIoman->pBlkDevSemaphore); -#endif - slRetVal = pIoman->pBlkDevice->fnpWriteBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam); -#ifdef FF_BLKDEV_USES_SEM - FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore); -#endif - if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) { - FF_Sleep(FF_DRIVER_BUSY_SLEEP); - } - } while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY); - - return slRetVal; -} - - -/** - * @private - **/ -static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) { - - FF_PARTITION *pPart; - FF_BUFFER *pBuffer; - FF_T_UINT32 testLong; - if(pIoman) { - pPart = pIoman->pPartition; - - if(pPart->NumClusters < 4085) { - // FAT12 - pPart->Type = FF_T_FAT12; -#ifdef FF_FAT_CHECK -#ifdef FF_FAT12_SUPPORT - pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - testLong = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, 0x0000); - } - FF_ReleaseBuffer(pIoman, pBuffer); - if((testLong & 0x3FF) != 0x3F8) { - return FF_ERR_IOMAN_NOT_FAT_FORMATTED; - } -#else - return FF_ERR_IOMAN_NOT_FAT_FORMATTED; -#endif -#endif -#ifdef FF_FAT12_SUPPORT - return FF_ERR_NONE; -#endif - - } else if(pPart->NumClusters < 65525) { - // FAT 16 - pPart->Type = FF_T_FAT16; -#ifdef FF_FAT_CHECK - pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - testLong = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, 0x0000); - } - FF_ReleaseBuffer(pIoman, pBuffer); - if(testLong != 0xFFF8) { - return FF_ERR_IOMAN_NOT_FAT_FORMATTED; - } -#endif - return FF_ERR_NONE; - } - else { - // FAT 32! - pPart->Type = FF_T_FAT32; -#ifdef FF_FAT_CHECK - pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - testLong = FF_getLong(pBuffer->pBuffer, 0x0000); - } - FF_ReleaseBuffer(pIoman, pBuffer); - if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8 && (testLong & 0x0FFFFFF8) != 0x0FFFFFF0) { - return FF_ERR_IOMAN_NOT_FAT_FORMATTED; - } -#endif - return FF_ERR_NONE; - } - } - - return FF_ERR_IOMAN_NOT_FAT_FORMATTED; -} - -static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer) -{ - FF_T_SINT8 count = 0; - FF_T_SINT8 part; - // Check PBR or MBR signature - if (FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0x55 && - FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0xAA ) { - // No MBR, but is it a PBR ? - if (FF_getChar(pBuffer, 0) == 0xEB && // PBR Byte 0 - FF_getChar(pBuffer, 2) == 0x90 && // PBR Byte 2 - (FF_getChar(pBuffer, 21) & 0xF0) == 0xF0) {// PBR Byte 21 : Media byte - return 1; // No MBR but PBR exist then only one partition - } - return 0; // No MBR and no PBR then no partition found - } - for (part = 0; part < 4; part++) { - FF_T_UINT8 active = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ACTIVE + (16 * part)); - FF_T_UINT8 part_id = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID + (16 * part)); - // The first sector must be a MBR, then check the partition entry in the MBR - if (active != 0x80 && (active != 0 || part_id == 0)) { - break; - } - count++; - } - return count; -} - -/* - Mount GPT Partition Tables -*/ - -#define FF_GPT_HEAD_ENTRY_SIZE 0x54 -#define FF_GPT_HEAD_TOTAL_ENTRIES 0x50 -#define FF_GPT_HEAD_PART_ENTRY_LBA 0x48 -#define FF_GPT_ENTRY_FIRST_SECTOR_LBA 0x20 -#define FF_GPT_HEAD_CRC 0x10 -#define FF_GPT_HEAD_LENGTH 0x0C - -static FF_ERROR FF_GetEfiPartitionEntry(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber) { - // Continuing on from FF_MountPartition() pPartition->BeginLBA should be the sector of the GPT Header - FF_BUFFER *pBuffer; - FF_PARTITION *pPart = pIoman->pPartition; - - FF_T_UINT32 ulBeginGPT; - FF_T_UINT32 ulEntrySector; - FF_T_UINT32 ulSectorOffset; - FF_T_UINT32 ulTotalPartitionEntries; - FF_T_UINT32 ulPartitionEntrySize; - FF_T_UINT32 ulGPTHeadCRC, ulGPTCrcCheck, ulGPTHeadLength; - - if(ulPartitionNumber >= 128) { - return FF_ERR_IOMAN_INVALID_PARTITION_NUM; - } - - pBuffer = FF_GetBuffer(pIoman, pPart->BeginLBA, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - - // Verify this is an EFI header - if(memcmp(pBuffer->pBuffer, "EFI PART", 8) != 0) { - FF_ReleaseBuffer(pIoman, pBuffer); - return FF_ERR_IOMAN_INVALID_FORMAT; - } - - ulBeginGPT = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_PART_ENTRY_LBA); - ulTotalPartitionEntries = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_TOTAL_ENTRIES); - ulPartitionEntrySize = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_ENTRY_SIZE); - ulGPTHeadCRC = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC); - ulGPTHeadLength = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_LENGTH); - - // Calculate Head CRC - - // Blank CRC field - FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, 0x00000000); - - // Calculate CRC - ulGPTCrcCheck = FF_GetCRC32(pBuffer->pBuffer, ulGPTHeadLength); - - // Restore The CRC field - FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, ulGPTHeadCRC); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - // Check CRC - if(ulGPTHeadCRC != ulGPTCrcCheck) { - return FF_ERR_IOMAN_GPT_HEADER_CORRUPT; - } - - // Calculate Sector Containing the Partition Entry we want to use. - - ulEntrySector = ((ulPartitionNumber * ulPartitionEntrySize) / pIoman->BlkSize) + ulBeginGPT; - ulSectorOffset = (ulPartitionNumber % (pIoman->BlkSize / ulPartitionEntrySize)) * ulPartitionEntrySize; - - pBuffer = FF_GetBuffer(pIoman, ulEntrySector, FF_MODE_READ); - { - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - - pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, ulSectorOffset + FF_GPT_ENTRY_FIRST_SECTOR_LBA); - } - FF_ReleaseBuffer(pIoman, pBuffer); - - if(!pPart->BeginLBA) { - return FF_ERR_IOMAN_INVALID_PARTITION_NUM; - } - - return FF_ERR_NONE; -} - -/** - * @public - * @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided. - * - * The device drivers must adhere to the specification provided by - * FF_WRITE_BLOCKS and FF_READ_BLOCKS. - * - * @param pIoman FF_IOMAN object. - * @param PartitionNumber The primary partition number to be mounted. (0 - 3). - * - * @return 0 on success. - * @return FF_ERR_NULL_POINTER if a pIoman object wasn't provided. - * @return FF_ERR_IOMAN_INVALID_PARTITION_NUM if the partition number is out of range. - * @return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION if no partition was found. - * @return FF_ERR_IOMAN_INVALID_FORMAT if the master boot record or partition boot block didn't provide sensible data. - * @return FF_ERR_IOMAN_NOT_FAT_FORMATTED if the volume or partition couldn't be determined to be FAT. (@see ff_config.h) - * - **/ -FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { - FF_PARTITION *pPart; - FF_BUFFER *pBuffer = 0; - FF_ERROR Error; - - FF_T_UINT8 ucPartitionType; - - int partCount; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - /*if(PartitionNumber > 3) { - return FF_ERR_IOMAN_INVALID_PARTITION_NUM; - }*/ - - pPart = pIoman->pPartition; - - memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize); - memset (pIoman->pCacheMem, '\0', pIoman->BlkSize * pIoman->CacheSize); - - FF_IOMAN_InitBufferDescriptors(pIoman); - pIoman->FirstFile = 0; - - pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ); - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - - partCount = FF_PartitionCount (pBuffer->pBuffer); - - pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); - - if (partCount == 0) { //(pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) { - // Volume is not partitioned (MBR Found) - pPart->BeginLBA = 0; - } else { - - ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID); // Ensure its not an EFI partition! - - if(ucPartitionType != 0xEE) { - - if(PartitionNumber > 3) { - FF_ReleaseBuffer(pIoman, pBuffer); - return FF_ERR_IOMAN_INVALID_PARTITION_NUM; - } - - // Primary Partitions to deal with! - pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber)); - } - - FF_ReleaseBuffer(pIoman, pBuffer); - - if(ucPartitionType == 0xEE) { - - pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA); - Error = FF_GetEfiPartitionEntry(pIoman, PartitionNumber); - - if(Error) { - return Error; - } - } - - if(!pPart->BeginLBA) { - return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION; - } - // Now we get the Partition sector. - pBuffer = FF_GetBuffer(pIoman, pPart->BeginLBA, FF_MODE_READ); - if(!pBuffer) { - return FF_ERR_DEVICE_DRIVER_FAILED; - } - pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); - if((pPart->BlkSize % 512) != 0 || pPart->BlkSize == 0) { - FF_ReleaseBuffer(pIoman, pBuffer); - return FF_ERR_IOMAN_INVALID_FORMAT; - } - } - - // Assume FAT16, then we'll adjust if its FAT32 - pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS); - pPart->FatBeginLBA = pPart->BeginLBA + pPart->ReservedSectors; - - pPart->NumFATS = (FF_T_UINT8) FF_getShort(pBuffer->pBuffer, FF_FAT_NUMBER_OF_FATS); - pPart->SectorsPerFAT = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_SECTORS_PER_FAT); - - pPart->SectorsPerCluster = FF_getChar(pBuffer->pBuffer, FF_FAT_SECTORS_PER_CLUS); - - pPart->BlkFactor = (FF_T_UINT8) (pPart->BlkSize / pIoman->BlkSize); // Set the BlockFactor (How many real-blocks in a fake block!). - - if(pPart->SectorsPerFAT == 0) { // FAT32 - pPart->SectorsPerFAT = FF_getLong(pBuffer->pBuffer, FF_FAT_32_SECTORS_PER_FAT); - pPart->RootDirCluster = FF_getLong(pBuffer->pBuffer, FF_FAT_ROOT_DIR_CLUSTER); - pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); - pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); - if(pPart->TotalSectors == 0) { - pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); - } - memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_32_VOL_LABEL, sizeof pPart->VolLabel); - } else { // FAT16 - pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); - pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); - pPart->RootDirCluster = 1; // 1st Cluster is RootDir! - if(pPart->TotalSectors == 0) { - pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); - } - memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_16_VOL_LABEL, sizeof pPart->VolLabel); - } - - FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally! - - if(!pPart->BlkSize) { - return FF_ERR_IOMAN_INVALID_FORMAT; - } - - pPart->RootDirSectors = ((FF_getShort(pBuffer->pBuffer, FF_FAT_ROOT_ENTRY_COUNT) * 32) + pPart->BlkSize - 1) / pPart->BlkSize; - pPart->FirstDataSector = pPart->ClusterBeginLBA + pPart->RootDirSectors; - pPart->DataSectors = pPart->TotalSectors - (pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT) + pPart->RootDirSectors); - - if(!pPart->SectorsPerCluster) { - return FF_ERR_IOMAN_INVALID_FORMAT; - } - - pPart->NumClusters = pPart->DataSectors / pPart->SectorsPerCluster; - - Error = FF_DetermineFatType(pIoman); - - if(Error) { - return Error; - } - -#ifdef FF_MOUNT_FIND_FREE - pPart->LastFreeCluster = FF_FindFreeCluster(pIoman); - pPart->FreeClusterCount = FF_CountFreeClusters(pIoman); -#else - pPart->LastFreeCluster = 0; - pPart->FreeClusterCount = 0; -#endif - - return FF_ERR_NONE; -} - -/** - * @public - * @brief Unregister a Blockdevice, so that the IOMAN can be re-used for another device. - * - * Any active partitions must be Unmounted first. - * - * @param pIoman FF_IOMAN object. - * - * @return FF_ERR_NONE on success. - **/ -FF_ERROR FF_UnregisterBlkDevice(FF_IOMAN *pIoman) { - - FF_T_SINT8 RetVal = FF_ERR_NONE; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - FF_PendSemaphore(pIoman->pSemaphore); - { - if(pIoman->pPartition->PartitionMounted == FF_FALSE) { - pIoman->pBlkDevice->devBlkSize = 0; - pIoman->pBlkDevice->fnpReadBlocks = NULL; - pIoman->pBlkDevice->fnpWriteBlocks = NULL; - pIoman->pBlkDevice->pParam = NULL; - } else { - RetVal = FF_ERR_IOMAN_PARTITION_MOUNTED; - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - - return RetVal; -} - -/** - * @private - * @brief Checks the cache for Active Handles - * - * @param pIoman FF_IOMAN Object. - * - * @return FF_TRUE if an active handle is found, else FF_FALSE. - * - * @pre This function must be wrapped with the cache handling semaphore. - **/ -static FF_T_BOOL FF_ActiveHandles(FF_IOMAN *pIoman) { - FF_T_UINT32 i; - FF_BUFFER *pBuffer; - - for(i = 0; i < pIoman->CacheSize; i++) { - pBuffer = (pIoman->pBuffers + i); - if(pBuffer->NumHandles) { - return FF_TRUE; - } - } - - return FF_FALSE; -} - - -/** - * @public - * @brief Unmounts the active partition. - * - * @param pIoman FF_IOMAN Object. - * - * @return FF_ERR_NONE on success. - **/ -FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) { - FF_T_SINT8 RetVal = FF_ERR_NONE; - - if(!pIoman) { - return FF_ERR_NULL_POINTER; - } - - FF_PendSemaphore(pIoman->pSemaphore); // Ensure that there are no File Handles - { - if(!FF_ActiveHandles(pIoman)) { - if(pIoman->FirstFile == NULL) { - // Release Semaphore to call this function! - FF_ReleaseSemaphore(pIoman->pSemaphore); - FF_FlushCache(pIoman); // Flush any unwritten sectors to disk. - // Reclaim Semaphore - FF_PendSemaphore(pIoman->pSemaphore); - pIoman->pPartition->PartitionMounted = FF_FALSE; - } else { - RetVal = FF_ERR_IOMAN_ACTIVE_HANDLES; - } - } else { - RetVal = FF_ERR_IOMAN_ACTIVE_HANDLES; // Active handles found on the cache. - } - } - FF_ReleaseSemaphore(pIoman->pSemaphore); - - return RetVal; -} - - -FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { - - FF_ERROR Error; - //FF_PendSemaphore(pIoman->pSemaphore); - //{ - if(!pIoman->pPartition->FreeClusterCount) { - pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); - if(Error) { - return Error; - } - } else { - pIoman->pPartition->FreeClusterCount += Count; - } - //} - //FF_ReleaseSemaphore(pIoman->pSemaphore); - - return FF_ERR_NONE; -} - -FF_ERROR FF_DecreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { - - FF_ERROR Error; - - //FF_lockFAT(pIoman); - //{ - if(!pIoman->pPartition->FreeClusterCount) { - pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); - if(Error) { - return Error; - } - } else { - pIoman->pPartition->FreeClusterCount -= Count; - } - //} - //FF_unlockFAT(pIoman); - - return FF_ERR_NONE; -} - - -/** - * @brief Returns the Block-size of a mounted Partition - * - * The purpose of this function is to provide API access to information - * that might be useful in special cases. Like USB sticks that require a sector - * knocking sequence for security. After the sector knock, some secure USB - * sticks then present a different BlockSize. - * - * @param pIoman FF_IOMAN Object returned from FF_CreateIOMAN() - * - * @return The blocksize of the partition. A value less than 0 when an error occurs. - * @return Any negative value can be cast to the FF_ERROR type. - **/ -FF_T_SINT32 FF_GetPartitionBlockSize(FF_IOMAN *pIoman) { - - if(pIoman) { - return (FF_T_SINT32) pIoman->pPartition->BlkSize; - } - - return FF_ERR_NULL_POINTER; -} - -#ifdef FF_64_NUM_SUPPORT -/** - * @brief Returns the number of bytes contained within the mounted partition or volume. - * - * @param pIoman FF_IOMAN Object returned from FF_CreateIOMAN() - * - * @return The total number of bytes that the mounted partition or volume contains. - * - **/ -FF_T_UINT64 FF_GetVolumeSize(FF_IOMAN *pIoman) { - if(pIoman) { - FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster; - return (FF_T_UINT64) ((FF_T_UINT64)TotalClusters * (FF_T_UINT64)((FF_T_UINT64)pIoman->pPartition->SectorsPerCluster * (FF_T_UINT64)pIoman->pPartition->BlkSize)); - } - return 0; -} - -#else -FF_T_UINT32 FF_GetVolumeSize(FF_IOMAN *pIoman) { - FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster; - return (FF_T_UINT32) (TotalClusters * (pIoman->pPartition->SectorsPerCluster * pIoman->pPartition->BlkSize)); -} -#endif - diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_memory.c b/reactos/sdk/lib/3rdparty/fullfat/ff_memory.c deleted file mode 100644 index 2d6913d64d7..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_memory.c +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_memory.c - * @author James Walmsley - * @ingroup MEMORY - * - * @defgroup MEMORY FullFAT Memory Access Routines - * @brief Handles memory access in a portable way. - * - * Provides simple, fast, and portable access to memory routines. - * These are only used to read data from buffers. That are LITTLE ENDIAN - * due to the FAT specification. - * - * These routines may need to be modified to your platform. - * - **/ - -#include "ff_memory.h" -#include "ff_config.h" - -/* - * HT inlined these functions - * - * Not much left for the C-module - */ - - -#ifndef FF_INLINE_MEMORY_ACCESS -FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { - return (FF_T_UINT8) (pBuffer[aOffset]); -} - -FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { - FF_T_UN16 u16; - pBuffer += aOffset; - u16.bytes.u8_1 = pBuffer[1]; - u16.bytes.u8_0 = pBuffer[0]; - return u16.u16; -} - -FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) { - FF_T_UN32 u32; - pBuffer += aOffset; - u32.bytes.u8_3 = pBuffer[3]; - u32.bytes.u8_2 = pBuffer[2]; - u32.bytes.u8_1 = pBuffer[1]; - u32.bytes.u8_0 = pBuffer[0]; - return u32.u32; -} - -void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) { - pBuffer[aOffset] = Value; -} - -void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value) { - FF_T_UN16 u16; - u16.u16 = Value; - pBuffer += aOffset; - pBuffer[0] = u16.bytes.u8_0; - pBuffer[1] = u16.bytes.u8_1; -} - -void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value) { - FF_T_UN32 u32; - u32.u32 = Value; - pBuffer += aOffset; - pBuffer[0] = u32.bytes.u8_0; - pBuffer[1] = u32.bytes.u8_1; - pBuffer[2] = u32.bytes.u8_2; - pBuffer[3] = u32.bytes.u8_3; -} -#endif diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_safety.c b/reactos/sdk/lib/3rdparty/fullfat/ff_safety.c deleted file mode 100644 index 685185c07b8..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_safety.c +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_safety.c - * @author James Walmsley - * @ingroup SAFETY - * - * @defgroup SAFETY Process Safety for FullFAT - * @brief Provides semaphores, and thread-safety for FullFAT. - * - * This module aims to be as portable as possible. It is necessary to modify - * the functions FF_CreateSemaphore, FF_PendSemaphore, FF_ReleaseSemaphore, - * and FF_DestroySemaphore, as appropriate for your platform. - * - * If your application has no OS and is therefore single threaded, simply - * have: - * - * FF_CreateSemaphore() return NULL. - * - * FF_PendSemaphore() should do nothing. - * - * FF_ReleaseSemaphore() should do nothing. - * - * FF_DestroySemaphore() should do nothing. - * - **/ - -#include "ff_safety.h" // Íncludes ff_types.h -#include - -#define TAG_FULLFAT 'FLUF' - -// Call your OS's CreateSemaphore function -// -void *FF_CreateSemaphore(void) { - PKSEMAPHORE ProcessSemaphore; - - /* Allocate some memory to store the semaphore */ - ProcessSemaphore = ExAllocatePoolWithTag(NonPagedPool, - sizeof(KSEMAPHORE), - TAG_FULLFAT); - if (ProcessSemaphore) - { - /* Initialize it */ - KeInitializeSemaphore(ProcessSemaphore, - 0, - MAXLONG); - } - - return ProcessSemaphore; -} - -// Call your OS's PendSemaphore with the provided pSemaphore pointer. -// -// This should block indefinitely until the Semaphore -// becomes available. (No timeout!) -// If your OS doesn't do it for you, you should sleep -// this thread until the Semaphore is available. -void FF_PendSemaphore(void *pSemaphore) { - NTSTATUS Status; - - /* Sanity check */ - if (pSemaphore) - { - /* Wait for the sempaphore to become signaled */ - Status = KeWaitForSingleObject(pSemaphore, - Executive, - KernelMode, - FALSE, - NULL); - if (NT_SUCCESS(Status)) - { - if (Status != STATUS_SUCCESS) - { - // log an error? - } - } - else - { - // log an error? - } - } -} - -// Call your OS's ReleaseSemaphore with the provided pSemaphore pointer. -// -void FF_ReleaseSemaphore(void *pSemaphore) { - - /* Sanity check */ - if (pSemaphore) - { - /* Increment the semaphore */ - KeReleaseSemaphore(pSemaphore, - 0, - 1, - FALSE); - } -} - -// Call your OS's DestroySemaphore with the provided pSemaphore pointer. -// -void FF_DestroySemaphore(void *pSemaphore) { - - /* Sanity check */ - if (pSemaphore) - { - /* Free the semaphore memory */ - ExFreePoolWithTag(pSemaphore, - TAG_FULLFAT); - } -} - -// FIXME: what do we do with this? -void FF_Yield(void) { - // Call your OS's thread Yield function. - // If this doesn't work, then a deadlock will occur -} - -// Call your OS's thread sleep function, -// Sleep for TimeMs milliseconds -void FF_Sleep(FF_T_UINT32 TimeMs) { - LARGE_INTEGER Interval; - NTSTATUS Status; - - /* Calculate the interval */ - Interval.QuadPart = -((LONGLONG)TimeMs * 10000); - - /* Do the wait */ - Status = KeDelayExecutionThread(KernelMode, - FALSE, - &Interval); - if (!NT_SUCCESS(Status)) - { - // log an error? - } -} - - -/** - * Notes on implementation. - * - * - * - **/ - - diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_string.c b/reactos/sdk/lib/3rdparty/fullfat/ff_string.c deleted file mode 100644 index b6c06790ea9..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_string.c +++ /dev/null @@ -1,456 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_string.c - * @author James Walmsley - * @ingroup STRING - * - * @defgroup STRING FullFAT String Library - * @brief Portable String Library for FullFAT - * - * - **/ - -#include -#include -#include -#include "ff_string.h" -#include "ff_error.h" - -#ifdef FF_UNICODE_SUPPORT -#include -#include -#endif - -/* - * These will eventually be moved into a platform independent string - * library. Which will be optional. (To allow the use of system specific versions). - */ - -#ifdef FF_UNICODE_SUPPORT - -void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len) { - while(*szpSource && len--) { - *wcsDest++ = *szpSource++; - } - *wcsDest = '\0'; -} - -void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource) { - while(*szpSource) { - *wcsDest++ = (FF_T_WCHAR) *szpSource++; - } - *wcsDest = '\0'; -} - -void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource) { - while(*wcsSource) { - *szpDest++ = (FF_T_INT8) *wcsSource++; - } - *szpDest = '\0'; -} - -void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len) { - while(*wcsSource && len--) { - *szpDest++ = (FF_T_INT8) *wcsSource++; - } - *szpDest = '\0'; -} - -#endif - -/** - * @private - * @brief Converts an ASCII string to lowercase. - **/ -#ifndef FF_UNICODE_SUPPORT -/** - * @private - * @brief Converts an ASCII string to uppercase. - **/ -void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) { - FF_T_UINT32 i; - for(i = 0; i < strLen; i++) { - if(string[i] >= 'a' && string[i] <= 'z') - string[i] -= 32; - if(string[i] == '\0') - break; - } -} -void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) { - FF_T_UINT32 i; - for(i = 0; i < strLen; i++) { - if(string[i] >= 'A' && string[i] <= 'Z') - string[i] += 32; - if(string[i] == '\0') - break; - } -} - -#else -void FF_toupper(FF_T_WCHAR *string, FF_T_UINT32 strLen) { - FF_T_UINT32 i; - for(i = 0; i < strLen; i++) { - string[i] = towupper(string[i]); - } -} -void FF_tolower(FF_T_WCHAR *string, FF_T_UINT32 strLen) { - FF_T_UINT32 i; - for(i = 0; i < strLen; i++) { - string[i] = towlower(string[i]); - } -} -#endif - - - - -/** - * @private - * @brief Compares 2 strings for the specified length, and returns FF_TRUE is they are identical - * otherwise FF_FALSE is returned. - * - **/ - -#ifndef FF_UNICODE_SUPPORT -FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) { - register FF_T_UINT16 i; - register FF_T_INT8 char1, char2; - - if(!len) { - if(strlen(str1) != strlen(str2)) { - return FF_FALSE; - } - len = (FF_T_UINT16) strlen(str1); - } - - for(i = 0; i < len; i++) { - char1 = str1[i]; - char2 = str2[i]; - if(char1 >= 'A' && char1 <= 'Z') { - char1 += 32; - } - if(char2 >= 'A' && char2 <= 'Z') { - char2 += 32; - } - - if(char1 != char2) { - return FF_FALSE; - } - } - - return FF_TRUE; -} -#else - -FF_T_BOOL FF_strmatch(const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len) { - register FF_T_UINT16 i; - register FF_T_WCHAR char1, char2; - - if(!len) { - if(wcslen(str1) != wcslen(str2)) { - return FF_FALSE; - } - len = (FF_T_UINT16) wcslen(str1); - } - - for(i = 0; i < len; i++) { - char1 = towlower(str1[i]); - char2 = towlower(str2[i]); - if(char1 != char2) { - return FF_FALSE; - } - } - - return FF_TRUE; -} -#endif - -/** - * @private - * @brief A re-entrant Strtok function. No documentation is provided :P - * Use at your own risk. (This is for FullFAT's use only). - **/ - -#ifndef FF_UNICODE_SUPPORT -FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) { - FF_T_UINT16 strLen = Length; - FF_T_UINT16 i,y, tokenStart, tokenEnd = 0; - - i = 0; - y = 0; - - if(string[i] == '\\' || string[i] == '/') { - i++; - } - - tokenStart = i; - - while(i < strLen) { - if(string[i] == '\\' || string[i] == '/') { - y++; - if(y == *tokenNumber) { - tokenStart = (FF_T_UINT16)(i + 1); - } - if(y == (*tokenNumber + 1)) { - tokenEnd = i; - break; - } - } - i++; - } - - if(!tokenEnd) { - if(*last == FF_TRUE) { - return NULL; - } else { - *last = FF_TRUE; - } - tokenEnd = i; - } - if((tokenEnd - tokenStart) < FF_MAX_FILENAME) { - memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart)); - token[tokenEnd - tokenStart] = '\0'; - } else { - memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME)); - token[FF_MAX_FILENAME-1] = '\0'; - } - //token[tokenEnd - tokenStart] = '\0'; - *tokenNumber += 1; - - return token; -} - -#else -FF_T_WCHAR *FF_strtok(const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) { - FF_T_UINT16 strLen = Length; - FF_T_UINT16 i,y, tokenStart, tokenEnd = 0; - - i = 0; - y = 0; - - if(string[i] == '\\' || string[i] == '/') { - i++; - } - - tokenStart = i; - - while(i < strLen) { - if(string[i] == '\\' || string[i] == '/') { - y++; - if(y == *tokenNumber) { - tokenStart = (FF_T_UINT16)(i + 1); - } - if(y == (*tokenNumber + 1)) { - tokenEnd = i; - break; - } - } - i++; - } - - if(!tokenEnd) { - if(*last == FF_TRUE) { - return NULL; - } else { - *last = FF_TRUE; - } - tokenEnd = i; - } - if((tokenEnd - tokenStart) < FF_MAX_FILENAME) { - memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart) * sizeof(FF_T_WCHAR)); - token[tokenEnd - tokenStart] = '\0'; - } else { - memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME) * sizeof(FF_T_WCHAR)); - token[FF_MAX_FILENAME-1] = '\0'; - } - //token[tokenEnd - tokenStart] = '\0'; - *tokenNumber += 1; - - return token; -} -#endif - -/* - A Wild-Card Comparator Library function, Provided by Adam Fullerton. - This can be extended or altered to improve or advance wildCard matching - of the FF_FindFirst() and FF_FindNext() API's. -*/ -#ifdef FF_FINDAPI_ALLOW_WILDCARDS -/*FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) { - // Check to see if the string contains the wild card - if (!memchr(pszWildCard, '*', strlen(pszWildCard))) - { - // if it does not then do a straight string compare - if (strcmp(pszWildCard, pszString)) - { - return FF_FALSE; - } - } - else - { - while ((*pszWildCard) - && (*pszString)) - { - // Test for the wild card - if (*pszWildCard == '*') - { - // Eat more than one - while (*pszWildCard == '*') - { - pszWildCard++; - } - // If there are more chars in the string - if (*pszWildCard) - { - // Search for the next char - pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString)); - // if it does not exist then the strings don't match - if (!pszString) - { - return FF_FALSE; - } - - } - else - { - if (*pszWildCard) - { - // continue - break; - } - else - { - return FF_TRUE; - } - } - } - else - { - // Fail if they don't match - if (*pszWildCard != *pszString) - { - return FF_FALSE; - } - } - // Bump both pointers - pszWildCard++; - pszString++; - } - // fail if different lengths - if (*pszWildCard != *pszString) - { - return FF_FALSE; - } - } - - return FF_TRUE; -}*/ -/* - This is a better Wild-card compare function, that works perfectly, and is much more efficient. - This function was contributed by one of our commercial customers. -*/ -#ifdef FF_UNICODE_SUPPORT -FF_T_BOOL FF_wildcompare(const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString) { - register const FF_T_WCHAR *pszWc = NULL; - register const FF_T_WCHAR *pszStr = NULL; // Encourage the string pointers to be placed in memory. - do { - if ( *pszWildCard == '*' ) { - while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s - pszWc = (pszWildCard - 1); - pszStr = pszString; - } - if (*pszWildCard == '?' && !*pszString) { - return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded. - } -#ifdef FF_WILDCARD_CASE_INSENSITIVE - if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) { -#else - if (*pszWildCard != '?' && *pszWildCard != *pszString) { -#endif - if (pszWc == NULL) { - return FF_FALSE; - } - pszWildCard = pszWc; - pszString = pszStr++; - } - } while ( *pszWildCard++ && *pszString++ ); - - while(*pszWildCard == '*') { - pszWildCard++; - } - - if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated) - return FF_TRUE; // Therefore this must be a match. - } - - return FF_FALSE; // If not, then return FF_FALSE! -} -#else -FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) { - register const FF_T_INT8 *pszWc = NULL; - register const FF_T_INT8 *pszStr = NULL; // Encourage the string pointers to be placed in memory. - do { - if ( *pszWildCard == '*' ) { - while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s - pszWc = (pszWildCard - 1); - pszStr = pszString; - } - if (*pszWildCard == '?' && !*pszString) { - return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded. - } -#ifdef FF_WILDCARD_CASE_INSENSITIVE - if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) { -#else - if (*pszWildCard != '?' && *pszWildCard != *pszString) { -#endif - if (pszWc == NULL) { - return FF_FALSE; - } - pszWildCard = pszWc; - pszString = pszStr++; - } - } while ( *pszWildCard++ && *pszString++ ); - - while(*pszWildCard == '*') { - pszWildCard++; - } - - if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated) - return FF_TRUE; // Therefore this must be a match. - } - - return FF_FALSE; // If not, then return FF_FALSE! -} -#endif - -#endif diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_time.c b/reactos/sdk/lib/3rdparty/fullfat/ff_time.c deleted file mode 100644 index b3749354e77..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_time.c +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - - -#include "ff_time.h" - - -/** - * @file ff_time.c - * @author James Walmsley - * @ingroup TIME - * - * @defgroup TIME Real-Time Clock Interface - * @brief Allows FullFAT to time-stamp files. - * - * Provides a means for receiving the time on any platform. - **/ - -#ifdef FF_TIME_SUPPORT -/** - * @public - * @brief Populates an FF_SYSTEMTIME object with the current time from the system. - * - * The developer must modify this function so that it is suitable for their platform. - * The function must return with 0, and if the time is not available all elements of the - * FF_SYSTEMTIME object must be zero'd, as in the examples provided. - * - * @param pTime Pointer to an FF_TIME object. - * - * @return Always returns 0. - **/ -FF_T_SINT32 FF_GetSystemTime(FF_SYSTEMTIME *pTime) { - - pTime->Hour = 0; - pTime->Minute = 0; - pTime->Second = 0; - pTime->Day = 0; - pTime->Month = 0; - pTime->Year = 0; - - return 0; -} - -#endif diff --git a/reactos/sdk/lib/3rdparty/fullfat/ff_unicode.c b/reactos/sdk/lib/3rdparty/fullfat/ff_unicode.c deleted file mode 100644 index 24fffd420d4..00000000000 --- a/reactos/sdk/lib/3rdparty/fullfat/ff_unicode.c +++ /dev/null @@ -1,294 +0,0 @@ -/***************************************************************************** - * FullFAT - High Performance, Thread-Safe Embedded FAT File-System * - * Copyright (C) 2009 James Walmsley (james@worm.me.uk) * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * IMPORTANT NOTICE: * - * ================= * - * Alternative Licensing is available directly from the Copyright holder, * - * (James Walmsley). For more information consult LICENSING.TXT to obtain * - * a Commercial license. * - * * - * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. * - * * - * Removing the above notice is illegal and will invalidate this license. * - ***************************************************************************** - * See http://worm.me.uk/fullfat for more information. * - * Or http://fullfat.googlecode.com/ for latest releases and the wiki. * - *****************************************************************************/ - -/** - * @file ff_unicode.c - * @author James Walmsley - * @ingroup UNICODE - * - * @defgroup UNICODE FullFAT UNICODE Library - * @brief Portable UNICODE Transformation Library for FullFAT - * - **/ - -#include "ff_unicode.h" -#include "string.h" - -// UTF-8 Routines - -/* - UCS-4 range (hex.) UTF-8 octet sequence (binary) - 0000 0000-0000 007F 0xxxxxxx - 0000 0080-0000 07FF 110xxxxx 10xxxxxx - 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - - 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE). - 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE). -*/ - -FF_T_UINT FF_GetUtf16SequenceLen(FF_T_UINT16 usLeadChar) { - if((usLeadChar & 0xFC00) == 0xD800) { - return 2; - } - return 1; -} - -/* - Returns the number of UTF-8 units read. - Will not exceed ulSize UTF-16 units. (ulSize * 2 bytes). -*/ -/* - UCS-4 range (hex.) UTF-8 octet sequence (binary) - 0000 0000-0000 007F 0xxxxxxx - 0000 0080-0000 07FF 110xxxxx 10xxxxxx - 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - - 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE). - 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE). -*/ -FF_T_SINT32 FF_Utf8ctoUtf16c(FF_T_UINT16 *utf16Dest, const FF_T_UINT8 *utf8Source, FF_T_UINT32 ulSize) { - FF_T_UINT32 ulUtf32char; - FF_T_UINT16 utf16Source = 0; - register FF_T_INT uiSequenceNumber = 0; - - while((*utf8Source & (0x80 >> (uiSequenceNumber)))) { // Count number of set bits before a zero. - uiSequenceNumber++; - } - - if(!uiSequenceNumber) { - uiSequenceNumber++; - } - - if(!ulSize) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - - switch(uiSequenceNumber) { - case 1: - utf16Source = (FF_T_UINT16) *utf8Source; - memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16)); - //bobtntfullfat *utf16Dest = (FF_T_UINT16) *utf8Source; - break; - - case 2: - utf16Source =(FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F)); - memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16)); - //bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F)); - break; - - case 3: - utf16Source =(FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F)); - memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16)); - //bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F)); - break; - - case 4: - // Convert to UTF-32 and then into UTF-16 - if(ulSize < 2) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - ulUtf32char = (FF_T_UINT16) ((*utf8Source & 0x0F) << 18) | ((*(utf8Source + 1) & 0x3F) << 12) | ((*(utf8Source + 2) & 0x3F) << 6) | ((*(utf8Source + 3) & 0x3F)); - - utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800; - memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16)); - utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00; - memcpy(utf16Dest+1,&utf16Source,sizeof(FF_T_UINT16)); - //bobtntfullfat *(utf16Dest + 0) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800; - //bobtntfullfat *(utf16Dest + 1) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00; - break; - - default: - break; - } - - return uiSequenceNumber; -} - - -/* - Returns the number of UTF-8 units required to encode the UTF-16 sequence. - Will not exceed ulSize UTF-8 units. (ulSize * 1 bytes). -*/ -FF_T_SINT32 FF_Utf16ctoUtf8c(FF_T_UINT8 *utf8Dest, const FF_T_UINT16 *utf16Source, FF_T_UINT32 ulSize) { - FF_T_UINT32 ulUtf32char; - FF_T_UINT16 ulUtf16char; - - if(!ulSize) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - - memcpy(&ulUtf16char, utf16Source, sizeof(FF_T_UINT16)); - if((/*bobtntfullfat *utf16Source*/ulUtf16char & 0xF800) == 0xD800) { // A surrogate sequence was encountered. Must transform to UTF32 first. - ulUtf32char = ((FF_T_UINT32) (ulUtf16char & 0x003FF) << 10) + 0x10000; - //bobtntfullfat ulUtf32char = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000; - - memcpy(&ulUtf16char, utf16Source + 1, sizeof(FF_T_UINT16)); - if((/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0xFC00) != 0xDC00) { - return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence. - } - ulUtf32char |= ((FF_T_UINT32) (/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0x003FF)); - - } else { - ulUtf32char = (FF_T_UINT32) /*bobtntfullfat *utf16Source*/ulUtf16char; - } - - // Now convert to the UTF-8 sequence. - if(ulUtf32char < 0x00000080) { // Single byte UTF-8 sequence. - *(utf8Dest + 0) = (FF_T_UINT8) ulUtf32char; - return 1; - } - - if(ulUtf32char < 0x00000800) { // Double byte UTF-8 sequence. - if(ulSize < 2) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - *(utf8Dest + 0) = (FF_T_UINT8) (0xC0 | ((ulUtf32char >> 6) & 0x1F)); - *(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0) & 0x3F)); - return 2; - } - - if(ulUtf32char < 0x00010000) { // Triple byte UTF-8 sequence. - if(ulSize < 3) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - *(utf8Dest + 0) = (FF_T_UINT8) (0xE0 | ((ulUtf32char >> 12) & 0x0F)); - *(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F)); - *(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F)); - return 3; - } - - if(ulUtf32char < 0x00200000) { // Quadruple byte UTF-8 sequence. - if(ulSize < 4) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; - } - *(utf8Dest + 0) = (FF_T_UINT8) (0xF0 | ((ulUtf32char >> 18) & 0x07)); - *(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 12) & 0x3F)); - *(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F)); - *(utf8Dest + 3) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F)); - return 4; - } - - return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter -} - - -// UTF-16 Support Functions - -// Converts a UTF-32 Charachter into its equivalent UTF-16 sequence. -FF_T_SINT32 FF_Utf32ctoUtf16c(FF_T_UINT16 *utf16Dest, FF_T_UINT32 utf32char, FF_T_UINT32 ulSize) { - - // Check that its a valid UTF-32 wide-char! - - if(utf32char >= 0xD800 && utf32char <= 0xDFFF) { // This range is not a valid Unicode code point. - return FF_ERR_UNICODE_INVALID_CODE; // Invalid charachter. - } - - if(utf32char < 0x10000) { - *utf16Dest = (FF_T_UINT16) utf32char; // Simple conversion! Char comes within UTF-16 space (without surrogates). - return 1; - } - - if(ulSize < 2) { - return FF_ERR_UNICODE_DEST_TOO_SMALL; // Not enough UTF-16 units to record this charachter. - } - - if(utf32char < 0x00200000) { - // Conversion to a UTF-16 Surrogate pair! - //valueImage = utf32char - 0x10000; - - *(utf16Dest + 0) = (FF_T_UINT16) (((utf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800; - *(utf16Dest + 1) = (FF_T_UINT16) (((utf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00; - - return 2; // Surrogate pair encoded value. - } - - return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter -} - -// Converts a UTF-16 sequence into its equivalent UTF-32 code point. -FF_T_SINT32 FF_Utf16ctoUtf32c(FF_T_UINT32 *utf32Dest, const FF_T_UINT16 *utf16Source) { - - if((*utf16Source & 0xFC00) != 0xD800) { // Not a surrogate sequence. - *utf32Dest = (FF_T_UINT32) *utf16Source; - return 1; // A single UTF-16 item was used to represent the charachter. - } - - *utf32Dest = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000; - - if((*(utf16Source + 1) & 0xFC00) != 0xDC00) { - return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence. - } - *utf32Dest |= ((FF_T_UINT32) (*(utf16Source + 1) & 0x003FF)); - return 2; // 2 utf-16 units make up the Unicode code-point. -} - - -/* - Returns the total number of UTF-16 items required to represent - the provided UTF-32 string in UTF-16 form. -*/ -/* -FF_T_UINT FF_Utf32GetUtf16Len(const FF_T_UINT32 *utf32String) { - FF_T_UINT utf16len = 0; - - while(*utf32String) { - if(*utf32String++ <= 0xFFFF) { - utf16len++; - } else { - utf16len += 2; - } - } - - return utf16len; -}*/ - - -// String conversions - -FF_T_SINT32 FF_Utf32stoUtf8s(FF_T_UINT8 *Utf8String, FF_T_UINT32 *Utf32String) { - int i = 0,y = 0; - - FF_T_UINT16 utf16buffer[2]; - - while(Utf32String[i]) { - // Convert to a UTF16 char. - FF_Utf32ctoUtf16c(utf16buffer, Utf32String[i], 2); - // Now convert the UTF16 to UTF8 sequence. - y += FF_Utf16ctoUtf8c(&Utf8String[y], utf16buffer, 4); - i++; - } - - Utf8String[y] = '\0'; - - return 0; -} -- 2.17.1