[ros-diffs] [fireball] 39033: Alex Vlasov - Implement FAT operations (scanning, finding continuous runs). - Implement and plug in VCB initialization.

fireball at svn.reactos.org fireball at svn.reactos.org
Fri Jan 23 11:19:58 CET 2009


Author: fireball
Date: Fri Jan 23 04:19:57 2009
New Revision: 39033

URL: http://svn.reactos.org/svn/reactos?rev=39033&view=rev
Log:
Alex Vlasov
- Implement FAT operations (scanning, finding continuous runs).
- Implement and plug in VCB initialization.

Modified:
    trunk/reactos/drivers/filesystems/fastfat_new/fat.c
    trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c

Modified: trunk/reactos/drivers/filesystems/fastfat_new/fat.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat_new/fat.c?rev=39033&r1=39032&r2=39033&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] Fri Jan 23 04:19:57 2009
@@ -3,7 +3,7 @@
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            drivers/filesystems/fastfat/fat.c
  * PURPOSE:         FAT support routines
- * PROGRAMMERS:     
+ * PROGRAMMERS:     Alexey Vlasov
  */
 
 /* INCLUDES *****************************************************************/
@@ -11,7 +11,678 @@
 #define NDEBUG
 #include "fastfat.h"
 
+/* PROTOTYPES ***************************************************************/
+typedef struct _FAT_SCAN_CONTEXT
+{
+    PFILE_OBJECT FileObject;
+    LARGE_INTEGER PageOffset;
+    LONGLONG BeyoundLastEntryOffset;
+    PVOID PageBuffer;
+    PBCB PageBcb;
+} FAT_SCAN_CONTEXT;
+
+#define FatEntryToDataOffset(xEntry, xVcb) \
+    ((xVcb)->DataArea + (((LONGLONG) ((xEntry) - 0x02)) << (xVcb)->BytesPerClusterLog))
+
+#define FatDataOffsetToEntry(xOffset, xVcb) \
+    ((ULONG) ((xOffset - (xVcb)->DataArea) >> (xVcb)->BytesPerClusterLog) + 0x02)
+
+ULONG
+FatScanFat12ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat12ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatScanFat12ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat12ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatScanFat16ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat16ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatScanFat16ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat16ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatScanFat32ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat32ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatScanFat32ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+ULONG
+FatSetFat32ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait);
+
+BOOLEAN
+NTAPI
+FatValidBpb(
+    IN PBIOS_PARAMETER_BLOCK Bpb);
+
+/* VARIABLES ****************************************************************/
+FAT_METHODS Fat12Methods = {
+    FatScanFat12ForContinousRun,
+    FatSetFat12ContinousRun,
+    FatScanFat16ForValueRun,
+    FatSetFat12ValueRun
+};
+
+FAT_METHODS Fat16Methods = {
+    FatScanFat16ForContinousRun,
+    FatSetFat16ContinousRun,
+    FatScanFat16ForValueRun,
+    FatSetFat16ValueRun
+};
+
+FAT_METHODS Fat32Methods = {
+    FatScanFat32ForContinousRun,
+    FatSetFat32ContinousRun,
+    FatScanFat32ForValueRun,
+    FatSetFat32ValueRun
+};
+
 /* FUNCTIONS ****************************************************************/
-
+FORCEINLINE
+ULONG
+FatPowerOfTwo(
+    ULONG Number)
+/*
+ * FUNCTION:
+ *      Determines the index of the set bit.
+ * ARGUMENTS:
+ *      Number = Number having a single bit set.
+ * RETURNS: Index of the set bit.
+ */
+{
+    ULONG Temp;
+    Temp = Number
+        - ((Number >> 1) & 033333333333)
+        - ((Number >> 2) & 011111111111);
+    return (((Temp + (Temp >> 3)) & 030707070707) % 63);
+}
+
+ULONG
+FatScanFat12ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatSetFat12ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat12ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatSetFat12ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat16ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatSetFat16ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat16ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatSetFat16ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat32ForContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN BOOLEAN CanWait)
+/*
+ * FUNCTION:
+ *       Scans FAT32 for continous chain of clusters
+ * ARGUMENTS:
+ *       Context = Pointer to FAT_SCAN_CONTEXT.
+ *       Index = Supplies the Index of the first cluster
+ *          and receves the last index after the last
+ *          cluster in the chain.
+ *       CanWait = Indicates if the context allows blocking.
+ * RETURNS: Value of the last claster terminated the scan.
+ * NOTES: Raises STATUS_CANT_WAIT race condition.
+ */
+{
+    LONGLONG PageOffset;
+    SIZE_T OffsetWithinPage, PageValidLength;
+    PULONG Entry, BeyoudLastEntry;
+   /*
+    * Determine page offset and the offset within page
+    * for the first cluster.
+    */
+    PageValidLength = PAGE_SIZE;
+    PageOffset = ((LONGLONG) *Index) << 0x2;
+    OffsetWithinPage = (SIZE_T) (PageOffset & (PAGE_SIZE - 1));
+    PageOffset -= OffsetWithinPage;
+   /*
+    * Check if the context already has the required page mapped.
+    * Map the first page is necessary.
+    */
+    if (PageOffset != Context->PageOffset.QuadPart)
+    {
+        Context->PageOffset.QuadPart = PageOffset;
+        if (Context->PageBcb != NULL)
+        {
+            CcUnpinData(Context->PageBcb);
+            Context->PageBcb = NULL;
+        }
+        if (!CcMapData(Context->FileObject, &Context->PageOffset,
+            PAGE_SIZE, CanWait, &Context->PageBcb, &Context->PageBuffer))
+        {        
+            Context->PageOffset.QuadPart = 0LL;
+            ExRaiseStatus(STATUS_CANT_WAIT);
+        }
+    }
+    Entry = Add2Ptr(Context->PageBuffer, OffsetWithinPage, PULONG);
+   /*
+    * Next Page Offset.
+    */
+    PageOffset = Context->PageOffset.QuadPart + PAGE_SIZE;
+    if (PageOffset > Context->BeyoundLastEntryOffset)
+        PageValidLength = (SIZE_T) (Context->BeyoundLastEntryOffset
+            - Context->PageOffset.QuadPart);
+    BeyoudLastEntry = Add2Ptr(Context->PageBuffer, PageValidLength, PULONG);
+    while (TRUE)
+    {
+        do
+        {
+            if ((*Entry & FAT_CLUSTER_LAST) != ++(*Index) )
+                return (*Entry & FAT_CLUSTER_LAST);
+        }
+        while (++Entry < BeyoudLastEntry);
+       /*
+        * Check if this is the last available entry.
+        */
+        if (PageValidLength < PAGE_SIZE)
+            break;
+       /*
+        * We are getting beyound current page and
+        * are still in the continous run, map the next page.
+        */
+        Context->PageOffset.QuadPart = PageOffset;
+        CcUnpinData(Context->PageBcb);
+        if (!CcMapData(Context->FileObject,
+            &Context->PageOffset, PAGE_SIZE, CanWait,
+            &Context->PageBcb, &Context->PageBuffer))
+        {
+            Context->PageBcb = NULL;
+            Context->PageOffset.QuadPart = 0LL;
+            ExRaiseStatus(STATUS_CANT_WAIT);
+        }
+        Entry = (PULONG) Context->PageBuffer;
+       /*
+        * Next Page Offset.
+        */
+        PageOffset = Context->PageOffset.QuadPart + PAGE_SIZE;
+        if (PageOffset > Context->BeyoundLastEntryOffset)
+            PageValidLength = (SIZE_T) (Context->BeyoundLastEntryOffset
+                - Context->PageOffset.QuadPart);
+        BeyoudLastEntry = Add2Ptr(Context->PageBuffer, PageValidLength, PULONG);
+    }
+    return (*Index - 1);
+}
+
+ULONG
+FatSetFat32ContinousRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat32ForValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN OUT PULONG Index,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatSetFat32ValueRun(
+    IN OUT PFAT_SCAN_CONTEXT Context,
+    IN ULONG Index,
+    IN ULONG Length,
+    IN ULONG IndexValue,
+    IN BOOLEAN CanWait)
+{
+    ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
+}
+
+ULONG
+FatScanFat(
+    IN PFCB Fcb,
+    IN LONGLONG Vbo,
+    OUT PLONGLONG Lbo,
+    IN OUT PLONGLONG Length,
+    OUT PULONG Index,
+    IN BOOLEAN CanWait
+)
+/*
+ * FUNCTION:
+ *      Queries file MCB for the specified region [Vbo, Vbo + Length],
+ *      returns the number of runs in the region as well as the first
+ *      run of the range itself.
+ *      If the specified region is not fully cached in MCB the routine
+ *      scans FAT for the file and fills the MCB until the file offset
+ *      (defined as Vbo + Length) is reached.
+ * ARGUMENTS:
+ *      Fcb = Pointer to FCB structure for the file.
+ *      Vbo = Virtual Byte Offset in the file.
+ *      Lbo = Receives the Value of Logical Byte offset corresponding
+ *            to supplied Vbo Value.
+ *      Length = Supplies file range length to be examined and recieves
+ *            the length of first run.
+ *      OutIndex = Recieves the index (in MCB cache) of first run.
+ * RETURNS: Incremented index of the last run (+1).
+ * NOTES: Should be called by I/O routines to split the I/O operation
+ *      into sequential or parallel I/O operations.
+ */
+{
+    LONGLONG CurrentLbo, CurrentVbo, BeyoundLastVbo, CurrentLength;
+    ULONG Entry, NextEntry, NumberOfEntries, CurrentIndex;
+    FAT_SCAN_CONTEXT Context;
+    PVCB Vcb;
+
+   /*
+    * Some often used values
+    */
+    Vcb = Fcb->Vcb;
+    CurrentIndex = 0;
+    BeyoundLastVbo = Vbo + *Length;
+    CurrentLength = ((LONGLONG) Vcb->Clusters) << Vcb->BytesPerClusterLog;
+    if (BeyoundLastVbo > CurrentLength) 
+        BeyoundLastVbo = CurrentLength;
+   /*
+    * Try to locate first run.
+    */
+    if (FsRtlLookupLargeMcbEntry(&Fcb->Mcb, Vbo, Lbo, Length, NULL, NULL, Index))
+    {
+       /*
+        * Check if we have a single mapped run.
+        */
+        if (Vbo >= BeyoundLastVbo)
+            goto FatScanFcbFatExit;
+    } else {
+        *Length = 0L;
+    }
+   /*
+    * Get the first scan startup values.
+    */
+    if (FsRtlLookupLastLargeMcbEntryAndIndex(
+        &Fcb->Mcb, &CurrentVbo, &CurrentLbo, &CurrentIndex))
+    {
+        Entry = FatDataOffsetToEntry(CurrentLbo, Vcb);
+    }
+    else
+    {
+       /*
+        * Map is empty, set up initial values.
+        */
+        Entry = Fcb->FirstCluster;
+        if (Entry <= 0x2)
+            ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
+        if (Entry >= Vcb->Clusters)
+        {
+            if (Entry < FAT_CLUSTER_LAST)
+                ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
+                BeyoundLastVbo = 0LL;
+        }
+        CurrentIndex = 0L;
+        CurrentVbo = 0LL;
+    }
+    RtlZeroMemory(&Context, sizeof(Context));
+    Context.FileObject = Vcb->VolumeFileObject;
+    while (CurrentVbo < BeyoundLastVbo)
+    {
+       /*
+        * Locate Continous run starting with the current entry.
+        */
+        NumberOfEntries = Entry;
+        NextEntry = Vcb->Methods.ScanContinousRun(
+        &Context, &NumberOfEntries, CanWait);
+        NumberOfEntries -= Entry;
+       /*
+        * Check value that terminated the for being valid for FAT.
+        */
+        if (NextEntry <= 0x2)
+            ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
+        if (NextEntry >= Vcb->Clusters)
+        {
+            if (NextEntry < FAT_CLUSTER_LAST)
+            ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR);
+            break;
+        }
+       /*
+        * Add new run.
+        */
+        CurrentLength = ((LONGLONG) NumberOfEntries) 
+            << Vcb->BytesPerClusterLog;
+        FsRtlAddLargeMcbEntry(&Fcb->Mcb,
+            CurrentVbo,
+            FatEntryToDataOffset(Entry, Vcb),
+            CurrentLength);
+       /*
+        * Setup next iteration.
+        */
+        Entry = NextEntry;
+        CurrentVbo += CurrentLength;
+        CurrentIndex ++;
+    }
+    if (*Length == 0LL && CurrentIndex > 0)
+    {
+        if (!FsRtlLookupLargeMcbEntry(&Fcb->Mcb,
+            Vbo, Lbo, Length, NULL, NULL, Index))
+        {
+            *Index = 0L;
+            *Lbo = 0LL;
+        }
+    }
+FatScanFcbFatExit:
+    return CurrentIndex;
+}
+
+BOOLEAN
+NTAPI
+FatValidBpb(
+    IN PBIOS_PARAMETER_BLOCK Bpb)
+{
+    return (FatValidBytesPerSector(Bpb->BytesPerSector)
+        && FatValidSectorsPerCluster(Bpb->SectorsPerCluster)
+        && Bpb->ReservedSectors > 0
+        && Bpb->Fats > 0
+        && (Bpb->Sectors > 0 || Bpb->LargeSectors > 0)
+        && (Bpb->SectorsPerFat > 0
+            || (Bpb->LargeSectorsPerFat > 0 && Bpb->FsVersion == 0))
+        && (Bpb->Media == 0xf0
+            || Bpb->Media == 0xf8
+            || Bpb->Media == 0xf9
+            || Bpb->Media == 0xfb
+            || Bpb->Media == 0xfc
+            || Bpb->Media == 0xfd
+            || Bpb->Media == 0xfe
+            || Bpb->Media == 0xff)
+        && (Bpb->SectorsPerFat == 0 || Bpb->RootEntries > 0)
+        && (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled));
+}
+
+VOID
+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->BeyoundLastClusterInFat = ((LONGLONG) Vcb->Clusters) * Vcb->IndexDepth / 0x8;
+}
+
+NTSTATUS
+FatInitializeVcb(
+    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);
+
+    /* Setup FCB Header. */
+    ExInitializeFastMutex(&Vcb->HeaderMutex);
+    FsRtlSetupAdvancedHeader(&Vcb->Header, &Vcb->HeaderMutex);
+
+    /* Create Volume File Object. */
+    Vcb->VolumeFileObject = IoCreateStreamFileObject(NULL,
+        Vcb->TargetDeviceObject);
+
+    /* We have to setup all FCB fields needed for CC. */
+    Vcb->VolumeFileObject->FsContext = Vcb;
+    Vcb->VolumeFileObject->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;
+
+    /* Initialize CC. */
+    CcInitializeCacheMap(Vcb->VolumeFileObject,
+        (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->VolumeFileObject,
+            &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( &Vpb->SerialNumber, BootSector->Id );
+        CcUnpinData(Bcb);
+    }
+    else
+    {
+        Status = STATUS_UNRECOGNIZED_VOLUME;
+        goto FatInitializeVcbCleanup;
+    }
+    FatiInitializeVcb(Vcb);
+    /* Add this Vcb to grobal Vcb list. */
+    InsertTailList(&FatGlobalData.VcbListHead, &Vcb->VcbLinks);
+    return STATUS_SUCCESS;
+
+FatInitializeVcbCleanup:
+
+    /* Unwind the routine actions */
+    FatUninitializeVcb(Vcb);
+    return Status;
+}
+
+VOID
+FatUninitializeVcb(
+    IN PVCB Vcb)
+{
+    LARGE_INTEGER ZeroSize;
+
+    ZeroSize.QuadPart = 0LL;
+
+    /* Close volume file */
+    if (Vcb->VolumeFileObject != NULL)
+    {
+        /* Uninitialize CC. */
+        CcUninitializeCacheMap(Vcb->VolumeFileObject, &ZeroSize, NULL);
+        ObDereferenceObject(Vcb->VolumeFileObject);
+        Vcb->VolumeFileObject = NULL;
+    }
+    /* Unlink from global Vcb list. */
+    RemoveEntryList(&Vcb->VcbLinks);
+
+    /* Release Target Device */
+    ObReferenceObject(Vcb->TargetDeviceObject);
+    Vcb->TargetDeviceObject = NULL;
+}
 
 /* EOF */
+
+

Modified: trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c?rev=39033&r1=39032&r2=39033&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c [iso-8859-1] Fri Jan 23 04:19:57 2009
@@ -109,10 +109,20 @@
     /* Save device object in a VPB */
     Vpb->DeviceObject = (PDEVICE_OBJECT)VolumeDevice;
 
-    /* TODO: Initialize VCB for this volume */
+    /* Initialize VCB for this volume */
+    Status = FatInitializeVcb(&VolumeDevice->Vcb, TargetDeviceObject, Vpb);
+    if (!NT_SUCCESS(Status))
+        goto FatMountVolumeCleanup;
 
     /* Return success */
     return STATUS_SUCCESS;
+
+
+FatMountVolumeCleanup:
+
+    /* Unwind the routine actions */
+    IoDeleteDevice((PDEVICE_OBJECT)VolumeDevice);
+    return Status;
 }
 
 



More information about the Ros-diffs mailing list