source: trunk/eraser6/Eraser.Util.FileSystem/Fat12Api.cpp @ 1239

Revision 1239, 3.2 KB checked in by lowjoel, 5 years ago (diff)

Got rid of the SectorSize? and ClusterSize? fields in the FatApi? class, replacing them with the values straight from the BootSector? field. For the rest of the protected fields, place them into properties to allow ABI compatibility.

  • 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    Fat12Api::Fat12Api(VolumeInfo^ info) : Fat12Or16Api(info)
31    {
32        //Sanity checks: check that this volume is FAT16!
33        if (!IsFat12() || info->VolumeFormat == L"FAT16")
34            throw gcnew ArgumentException(L"The volume provided is not a FAT12 volume.");
35    }
36
37    Fat12Api::Fat12Api(VolumeInfo^ info, IO::Stream^ stream) : Fat12Or16Api(info, stream)
38    {
39        //Sanity checks: check that this volume is FAT16!
40        if (!IsFat12() || info->VolumeFormat == L"FAT16")
41            throw gcnew ArgumentException(L"The volume provided is not a FAT12 volume.");
42    }
43
44    bool Fat12Api::IsClusterAllocated(unsigned cluster)
45    {
46        unsigned nextCluster = GetFatValue(cluster);
47
48        if (
49            nextCluster <= 0x001 ||
50            (nextCluster >= 0xFF0 && nextCluster <= 0xFF6) ||
51            nextCluster == 0xFF7
52        )
53            return false;
54
55        return true;
56    }
57
58    unsigned Fat12Api::GetNextCluster(unsigned cluster)
59    {
60        unsigned nextCluster = GetFatValue(cluster);
61        if (nextCluster <= 0x001 || (nextCluster >= 0xFF0 && nextCluster <= 0xFF6))
62            throw gcnew ArgumentException(L"Invalid FAT cluster: cluster is marked free.");
63        else if (nextCluster == 0xFF7)
64            throw gcnew ArgumentException(L"Invalid FAT cluster: cluster is marked bad.");
65        else if (nextCluster >= 0xFF8)
66            return 0xFFFFFFFF;
67        else
68            return nextCluster;
69    }
70
71    unsigned Fat12Api::FileSize(unsigned cluster)
72    {
73        for (unsigned result = 1; ; ++result)
74        {
75            unsigned nextCluster = GetFatValue(cluster);
76            if (nextCluster <= 0x001 || (nextCluster >= 0xFFF0 && nextCluster <= 0xFF6))
77                throw gcnew ArgumentException(L"Invalid FAT cluster: cluster is marked free.");
78            else if (nextCluster == 0xFF7)
79                throw gcnew ArgumentException(L"Invalid FAT cluster: cluster is marked bad.");
80            else if (nextCluster >= 0xFF8)
81                return ClusterSizeToSize(result);
82            else
83                cluster = nextCluster;
84        }
85    }
86
87    unsigned Fat12Api::GetFatValue(unsigned cluster)
88    {
89        //Get the pointer to the FAT entry. Round the cluster value down to the nearest
90        //even number (since 2 clusters share 3 bytes)
91        char* fatEntry = Fat + ((cluster & ~1) / 2) * 3;
92        unsigned fatValue = 0;
93        for (size_t i = 0; i < 3; ++i)
94            fatValue |= static_cast<unsigned>(static_cast<unsigned char>(*(fatEntry + i))) << (i * 8);
95
96        //Get the correct half of the 24 bits. If the cluster is odd we take the 12 least significant bits
97        if (cluster & 1)
98            fatValue >>= 12;
99        else
100            fatValue &= 0xFFF;
101
102        //Return the result.
103        return fatValue;
104    }
105}
106}
Note: See TracBrowser for help on using the repository browser.