source: trunk/eraser6/Eraser.Util.FileSystem/Fat12Or16Api.cpp @ 1226

Revision 1226, 3.6 KB checked in by lowjoel, 5 years ago (diff)

-Abstract the FatDirectory? class to a FatDirectoryBase? class which contains interfaces to parse the given FatDirectory? list, but no capability to read/write from disk since the Root directory in FAT12 and FAT16 are different from the Root directory in FAT32.
-Rename ::FatDirectory? to ::FatDirectoryEntry? since that's what it really is.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2009 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22#include <stdafx.h>
23#include "FatApi.h"
24
25using namespace System::IO;
26using namespace System::Runtime::InteropServices;
27
28namespace Eraser {
29namespace Util {
30    Fat12Or16Api::Fat12Or16Api(VolumeInfo^ info) : FatApi(info)
31    {
32        //Sanity checks: check that this volume is FAT12 or FAT16!
33        if (info->VolumeFormat != L"FAT")
34            throw gcnew ArgumentException(L"The volume provided is not a FAT12 or FAT16 volume.");
35    }
36
37    Fat12Or16Api::Fat12Or16Api(VolumeInfo^ info, IO::Stream^ stream) : FatApi(info, stream)
38    {
39        //Sanity checks: check that this volume is FAT12 or FAT16!
40        if (info->VolumeFormat != L"FAT")
41            throw gcnew ArgumentException(L"The volume provided is not a FAT12 or FAT16 volume.");
42    }
43
44    void Fat12Or16Api::LoadFat()
45    {
46        Fat = new char[SectorSizeToSize(BootSector->SectorsPerFat)];
47
48        //Seek to the FAT
49        VolumeStream->Seek(SectorToOffset(BootSector->ReservedSectorCount), SeekOrigin::Begin);
50
51        //Read the FAT
52        array<Byte>^ buffer = gcnew array<Byte>(SectorSizeToSize(BootSector->SectorsPerFat));
53        VolumeStream->Read(buffer, 0, SectorSizeToSize(BootSector->SectorsPerFat));
54        Marshal::Copy(buffer, 0, static_cast<IntPtr>(Fat), buffer->Length);
55    }
56
57    FatDirectoryBase^ Fat12Or16Api::LoadDirectory(unsigned cluster, String^ name,
58        FatDirectoryBase^ parent)
59    {
60        return gcnew Directory(name, parent, cluster, this);
61    }
62
63    long long Fat12Or16Api::ClusterToOffset(unsigned cluster)
64    {
65        unsigned long long sector = BootSector->ReservedSectorCount +                                           //Reserved area
66            BootSector->FatCount * BootSector->SectorsPerFat +                                                  //FAT area
67            (BootSector->RootDirectoryEntryCount * sizeof(::FatDirectoryEntry) / (ClusterSize / SectorSize)) +  //Root directory area
68            (static_cast<unsigned long long>(cluster) - 2) * (ClusterSize / SectorSize);
69        return SectorToOffset(sector);
70    }
71
72    unsigned Fat12Or16Api::DirectoryToCluster(String^ path)
73    {
74        throw gcnew NotImplementedException();
75    }
76
77    bool Fat12Or16Api::IsFat12()
78    {
79        unsigned long long numberOfSectors = (BootSector->SectorCount16 == 0 ?
80            BootSector->SectorCount32 : BootSector->SectorCount16);
81        unsigned long long availableSectors = numberOfSectors - (
82            BootSector->ReservedSectorCount +                                                               //Reserved area
83            BootSector->FatCount * BootSector->SectorsPerFat +                                              //FAT area
84            (BootSector->RootDirectoryEntryCount * sizeof(::FatDirectoryEntry) / (ClusterSize / SectorSize))    //Root directory area
85        );
86        unsigned long long numberOfClusters = availableSectors / (ClusterSize / SectorSize);
87
88        return numberOfClusters < 0xFF0;
89    }
90
91    Fat12Or16Api::Directory::Directory(String^ name, FatDirectoryBase^ parent, unsigned cluster,
92        Fat12Or16Api^ api) : FatDirectory(name, parent, cluster, api)
93    {
94    }
95
96    unsigned Fat12Or16Api::Directory::GetStartCluster(::FatDirectoryEntry& directory)
97    {
98        if (directory.Short.Attributes == 0x0F)
99            throw gcnew ArgumentException(L"The provided directory is a long file name.");
100        return directory.Short.StartClusterLow;
101    }
102}
103}
Note: See TracBrowser for help on using the repository browser.