Changeset 1226
- Timestamp:
- 9/30/2009 2:40:17 AM (4 years ago)
- Location:
- trunk/eraser6/Eraser.Util.FileSystem
- Files:
-
- 7 edited
-
Fat.h (modified) (2 diffs)
-
Fat12Or16Api.cpp (modified) (5 diffs)
-
Fat16Api.cpp (modified) (1 diff)
-
Fat32Api.cpp (modified) (5 diffs)
-
FatApi.cpp (modified) (6 diffs)
-
FatApi.h (modified) (9 diffs)
-
Stdafx.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser6/Eraser.Util.FileSystem/Fat.h
r1225 r1226 89 89 90 90 /// Represents a short (8.3) directory entry. 91 struct Fat DirectoryEntry91 struct Fat8Dot3DirectoryEntry 92 92 { 93 93 /// Base name. If Name[0] is: … … 189 189 190 190 /// The collection of Fat Directory entries. 191 union FatDirectory 191 union FatDirectoryEntry 192 192 { 193 Fat DirectoryEntry Short;193 Fat8Dot3DirectoryEntry Short; 194 194 FatLfnDirectoryEntry LongFileName; 195 195 }; 196 196 197 typedef FatDirectory * FatDirectoryFile;197 typedef FatDirectoryEntry* FatDirectory; 198 198 199 199 #pragma pack(pop) -
trunk/eraser6/Eraser.Util.FileSystem/Fat12Or16Api.cpp
r1225 r1226 21 21 22 22 #include <stdafx.h> 23 #include <windows.h>24 #include <atlstr.h>25 26 23 #include "FatApi.h" 27 24 … … 58 55 } 59 56 60 FatDirectory^ Fat12Or16Api::LoadDirectory(unsigned cluster, String^ name, FatDirectory^ parent) 57 FatDirectoryBase^ Fat12Or16Api::LoadDirectory(unsigned cluster, String^ name, 58 FatDirectoryBase^ parent) 61 59 { 62 60 return gcnew Directory(name, parent, cluster, this); … … 65 63 long long Fat12Or16Api::ClusterToOffset(unsigned cluster) 66 64 { 67 unsigned long long sector = BootSector->ReservedSectorCount + //Reserved area68 BootSector->FatCount * BootSector->SectorsPerFat + //FAT area69 (BootSector->RootDirectoryEntryCount * sizeof(::FatDirectory ) / (ClusterSize / SectorSize)) + //Root directory area65 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 70 68 (static_cast<unsigned long long>(cluster) - 2) * (ClusterSize / SectorSize); 71 69 return SectorToOffset(sector); … … 82 80 BootSector->SectorCount32 : BootSector->SectorCount16); 83 81 unsigned long long availableSectors = numberOfSectors - ( 84 BootSector->ReservedSectorCount + //Reserved area85 BootSector->FatCount * BootSector->SectorsPerFat + //FAT area86 (BootSector->RootDirectoryEntryCount * sizeof(::FatDirectory ) / (ClusterSize / SectorSize)) //Root directory area82 BootSector->ReservedSectorCount + //Reserved area 83 BootSector->FatCount * BootSector->SectorsPerFat + //FAT area 84 (BootSector->RootDirectoryEntryCount * sizeof(::FatDirectoryEntry) / (ClusterSize / SectorSize)) //Root directory area 87 85 ); 88 86 unsigned long long numberOfClusters = availableSectors / (ClusterSize / SectorSize); … … 91 89 } 92 90 93 Fat12Or16Api::Directory::Directory(String^ name, FatDirectory ^ parent, unsigned cluster,91 Fat12Or16Api::Directory::Directory(String^ name, FatDirectoryBase^ parent, unsigned cluster, 94 92 Fat12Or16Api^ api) : FatDirectory(name, parent, cluster, api) 95 93 { 96 94 } 97 95 98 unsigned Fat12Or16Api::Directory::GetStartCluster(::FatDirectory & directory)96 unsigned Fat12Or16Api::Directory::GetStartCluster(::FatDirectoryEntry& directory) 99 97 { 100 98 if (directory.Short.Attributes == 0x0F) -
trunk/eraser6/Eraser.Util.FileSystem/Fat16Api.cpp
r1225 r1226 21 21 22 22 #include <stdafx.h> 23 #include <windows.h>24 #include <atlstr.h>25 26 23 #include "FatApi.h" 27 24 -
trunk/eraser6/Eraser.Util.FileSystem/Fat32Api.cpp
r1222 r1226 21 21 22 22 #include <stdafx.h> 23 #include <windows.h>24 #include <atlstr.h>25 26 23 #include "FatApi.h" 27 24 … … 50 47 51 48 //Seek to the FAT 52 VolumeStream->Seek(Sector SizeToSize(BootSector->ReservedSectorCount), SeekOrigin::Begin);49 VolumeStream->Seek(SectorToOffset(BootSector->ReservedSectorCount), SeekOrigin::Begin); 53 50 54 51 //Read the FAT … … 58 55 } 59 56 60 FatDirectory^ Fat32Api::LoadDirectory(unsigned cluster, String^ name, FatDirectory^ parent) 57 FatDirectoryBase^ Fat32Api::LoadDirectory(unsigned cluster, String^ name, 58 FatDirectoryBase^ parent) 61 59 { 62 60 return gcnew Directory(name, parent, cluster, this); … … 126 124 //Traverse the directories until we get the cluster we want. 127 125 unsigned cluster = BootSector->Fat32ParameterBlock.RootDirectoryCluster; 128 FatDirectory ^ parentDir = nullptr;126 FatDirectoryBase^ parentDir = nullptr; 129 127 for each (String^ component in components) 130 128 { … … 140 138 } 141 139 142 Fat32Api::Directory::Directory(String^ name, FatDirectory ^ parent, unsigned cluster, Fat32Api^ api)140 Fat32Api::Directory::Directory(String^ name, FatDirectoryBase^ parent, unsigned cluster, Fat32Api^ api) 143 141 : FatDirectory(name, parent, cluster, api) 144 142 { 145 143 } 146 144 147 unsigned Fat32Api::Directory::GetStartCluster(::FatDirectory & directory)145 unsigned Fat32Api::Directory::GetStartCluster(::FatDirectoryEntry& directory) 148 146 { 149 147 if (directory.Short.Attributes == 0x0F) -
trunk/eraser6/Eraser.Util.FileSystem/FatApi.cpp
r1222 r1226 22 22 #include <stdafx.h> 23 23 #include <windows.h> 24 #include <atlstr.h>25 24 26 25 #include "FatApi.h" … … 42 41 43 42 //Open the handle to the drive 44 CString volumeName(info->VolumeId);45 volumeName.Truncate(volumeName.GetLength() - 1);46 43 VolumeStream = info->Open(FileAccess::Read); 47 44 … … 78 75 } 79 76 80 FatDirectory ^ FatApi::LoadDirectory(String^ directory)77 FatDirectoryBase^ FatApi::LoadDirectory(String^ directory) 81 78 { 82 79 //Return the root directory if nothing is specified … … 152 149 } 153 150 154 FatDirectoryEntry::FatDirectoryEntry(String^ name, FatDirectory ^ parent,151 FatDirectoryEntry::FatDirectoryEntry(String^ name, FatDirectoryBase^ parent, 155 152 FatDirectoryEntryTypes type, unsigned cluster) 156 153 { … … 175 172 } 176 173 177 FatDirectory ::FatDirectory(String^ name, FatDirectory^ parent, unsigned cluster, FatApi^ api)174 FatDirectoryBase::FatDirectoryBase(String^ name, FatDirectoryBase^ parent, unsigned cluster) 178 175 : FatDirectoryEntry(name, parent, FatDirectoryEntryTypes::Directory, cluster) 179 176 { 180 System::Diagnostics::Debug::Print(FullName);181 177 Entries = gcnew Dictionary<String^, FatDirectoryEntry^>(); 182 Api = api; 183 184 //Get the size of the directory list and read it to memory 185 std::vector<char> dir = api->GetFileContents(cluster); 186 const size_t dirCount = dir.size() / sizeof(::FatDirectory); 187 Directory = new ::FatDirectory[dirCount]; 188 memcpy(Directory, &dir.front(), dir.size()); 178 ReadDirectory(); 179 } 180 181 void FatDirectoryBase::ClearDeletedEntries() 182 { 183 std::vector<::FatDirectoryEntry> validEntries; 189 184 190 185 //Parse the directory structures 191 for (::FatDirectory* i = Directory; i != Directory + dirCount; ++i) 186 for (::FatDirectoryEntry* i = Directory; i != Directory + DirectorySize; ++i) 187 { 188 //Check if we have checked the last valid entry 189 if (i->Short.Name[0] == 0x00) 190 break; 191 192 //Skip deleted entries. 193 if (static_cast<unsigned char>(i->Short.Name[0]) == 0xE5) 194 continue; 195 196 if (i->Short.Attributes == 0x0F) 197 { 198 //This is a long file name. 199 ::FatDirectoryEntry* longFileNameBegin = i; 200 for (unsigned char sequence = 0; i->Short.Attributes == 0x0F; ++i) 201 { 202 if (!(i->LongFileName.Sequence & 0x40)) //Second entry onwards 203 { 204 //Check that the checksum of the file name is the same as the previous 205 //long file name entry, to ensure no corruption has taken place 206 if ((i - 1)->LongFileName.Checksum != i->LongFileName.Checksum) 207 continue; 208 209 //Check that the sequence is one less than the previous one. 210 if (sequence != i->LongFileName.Sequence + 1) 211 throw gcnew ArgumentException(L"Invalid directory entry."); 212 } 213 214 sequence = i->LongFileName.Sequence & ~0x40; 215 } 216 217 //Checksum the string 218 unsigned char sum = 0; 219 char* shortFileName = i->Short.Name; 220 for (int j = 11; j; --j) 221 sum = ((sum & 1) << 7) + (sum >> 1) + *shortFileName++; 222 223 if (sum == (i - 1)->LongFileName.Checksum) 224 { 225 //The previous few entries contained the correct file name. Save these entries 226 validEntries.insert(validEntries.end(), longFileNameBegin, i); 227 } 228 } 229 230 validEntries.push_back(*i); 231 } 232 233 //validEntries now contains the compacted list of directory entries. Zero 234 //the memory used. 235 memset(Directory, 0, DirectorySize * sizeof(::FatDirectoryEntry)); 236 memcpy(Directory, &validEntries.front(), validEntries.size() * sizeof(::FatDirectory)); 237 238 //Write the entries to disk 239 WriteDirectory(); 240 } 241 242 void FatDirectoryBase::ParseDirectory() 243 { 244 //Clear the list of entries 245 Entries->Clear(); 246 247 //Parse the directory structures 248 for (::FatDirectoryEntry* i = Directory; i != Directory + DirectorySize; ++i) 192 249 { 193 250 //Check if we have checked the last valid entry … … 275 332 } 276 333 277 void FatDirectory::ClearDeletedEntries() 278 { 279 std::vector<::FatDirectory> validEntries; 280 size_t entryCount = Api->FileSize(Cluster) / sizeof(::FatDirectory); 281 282 //Parse the directory structures 283 for (::FatDirectory* i = Directory; i != Directory + entryCount; ++i) 284 { 285 //Check if we have checked the last valid entry 286 if (i->Short.Name[0] == 0x00) 287 break; 288 289 //Skip deleted entries. 290 if (static_cast<unsigned char>(i->Short.Name[0]) == 0xE5) 291 continue; 292 293 if (i->Short.Attributes == 0x0F) 294 { 295 //This is a long file name. 296 ::FatDirectory* longFileNameBegin = i; 297 for (unsigned char sequence = 0; i->Short.Attributes == 0x0F; ++i) 298 { 299 if (!(i->LongFileName.Sequence & 0x40)) //Second entry onwards 300 { 301 //Check that the checksum of the file name is the same as the previous 302 //long file name entry, to ensure no corruption has taken place 303 if ((i - 1)->LongFileName.Checksum != i->LongFileName.Checksum) 304 continue; 305 306 //Check that the sequence is one less than the previous one. 307 if (sequence != i->LongFileName.Sequence + 1) 308 throw gcnew ArgumentException(L"Invalid directory entry."); 309 } 310 311 sequence = i->LongFileName.Sequence & ~0x40; 312 } 313 314 //Checksum the string 315 unsigned char sum = 0; 316 char* shortFileName = i->Short.Name; 317 for (int j = 11; j; --j) 318 sum = ((sum & 1) << 7) + (sum >> 1) + *shortFileName++; 319 320 if (sum == (i - 1)->LongFileName.Checksum) 321 { 322 //The previous few entries contained the correct file name. Save these entries 323 validEntries.insert(validEntries.end(), longFileNameBegin, i); 324 } 325 } 326 327 validEntries.push_back(*i); 328 } 329 330 //validEntries now contains the compacted list of directory entries. Zero 331 //the memory used. 332 memset(Directory, 0, Api->FileSize(Cluster)); 333 memcpy(Directory, &validEntries.front(), validEntries.size() * sizeof(::FatDirectory)); 334 335 //Write the entries to disk 334 FatDirectory::FatDirectory(String^ name, FatDirectoryBase^ parent, unsigned cluster, FatApi^ api) 335 : Api(api), 336 FatDirectoryBase(name, parent, cluster) 337 { 338 } 339 340 void FatDirectory::ReadDirectory() 341 { 342 std::vector<char> dir = Api->GetFileContents(Cluster); 343 DirectorySize = dir.size() / sizeof(::FatDirectoryEntry); 344 Directory = new ::FatDirectoryEntry[DirectorySize]; 345 memcpy(Directory, &dir.front(), dir.size()); 346 347 ParseDirectory(); 348 } 349 350 void FatDirectory::WriteDirectory() 351 { 336 352 Api->SetFileContents(Directory, Api->FileSize(Cluster), Cluster); 337 353 } -
trunk/eraser6/Eraser.Util.FileSystem/FatApi.h
r1225 r1226 29 29 namespace Eraser { 30 30 namespace Util { 31 ref class FatDirectory; 31 ref class FatDirectoryBase; 32 33 /// Represents an abstract API to interface with FAT file systems. 32 34 public ref class FatApi abstract 33 35 { … … 49 51 virtual void LoadFat() = 0; 50 52 51 /// Loads the directory structure representing the directory with the given 52 /// volume-relative path. 53 FatDirectory^ LoadDirectory(String^ directory); 53 /// Helper function to loads the directory structure representing the 54 /// directory with the given volume-relative path. 55 /// 56 /// \overload LoadDirectory 57 FatDirectoryBase^ LoadDirectory(String^ directory); 54 58 55 59 /// Loads the directory structure at the given cluster. 56 virtual FatDirectory^ LoadDirectory(unsigned cluster, String^ name, FatDirectory^ parent) = 0; 60 virtual FatDirectoryBase^ LoadDirectory(unsigned cluster, String^ name, 61 FatDirectoryBase^ parent) = 0; 57 62 58 63 internal: … … 143 148 144 149 /// Gets the parent directory of this entry. 145 property FatDirectory ^ Parent146 { 147 FatDirectory ^ get() { return parent; }150 property FatDirectoryBase^ Parent 151 { 152 FatDirectoryBase^ get() { return parent; } 148 153 private: 149 void set(FatDirectory ^ value) { parent = value; }154 void set(FatDirectoryBase^ value) { parent = value; } 150 155 } 151 156 … … 173 178 /// \param[in] type The type of this entry. 174 179 /// \param[in] cluster The first cluster of the file. 175 FatDirectoryEntry(String^ name, FatDirectory ^ parent, FatDirectoryEntryTypes type,180 FatDirectoryEntry(String^ name, FatDirectoryBase^ parent, FatDirectoryEntryTypes type, 176 181 unsigned cluster); 177 182 178 183 private: 179 184 String^ name; 180 FatDirectory ^ parent;185 FatDirectoryBase^ parent; 181 186 FatDirectoryEntryTypes type; 182 187 unsigned cluster; 183 188 }; 184 189 185 /// Represents a FAT directory list. 186 public ref class FatDirectory abstract : FatDirectoryEntry 190 /// Represents an abstract FAT directory (can also represent the root directory of 191 /// FAT12 and FAT16 volumes.) 192 public ref class FatDirectoryBase abstract : FatDirectoryEntry 193 { 194 public: 195 /// Constructor. 196 /// 197 /// \param[in] name The name of the current directory. 198 /// \param[in] parent The parent directory containing this directory. 199 /// \param[in] cluster The cluster at which the directory list starts. 200 FatDirectoryBase(String^ name, FatDirectoryBase^ parent, unsigned cluster); 201 202 /// Compacts the directory structure, updating the structure on-disk as well. 203 void ClearDeletedEntries(); 204 205 /// The list of files and subfolders in this directory. 206 property Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ Items 207 { 208 Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ get() 209 { 210 return Entries; 211 } 212 } 213 214 protected: 215 /// Reads the directory structures from disk. 216 /// 217 /// \remarks This function must set the \see Directory instance as well as the 218 /// \see DirectorySize fields. Furthermore, call the \see ParseDirectory 219 /// function to initialise the directory entries on-disk. 220 virtual void ReadDirectory() = 0; 221 222 /// Writes the directory to disk. 223 virtual void WriteDirectory() = 0; 224 225 /// This function reads the raw directory structures in \see Directory and 226 /// sets the \see Entries field for easier access to the directory entries. 227 void ParseDirectory(); 228 229 /// Gets the start cluster from the given directory entry. 230 virtual unsigned GetStartCluster(::FatDirectoryEntry& directory) = 0; 231 232 protected: 233 /// A pointer to the directory structure. 234 ::FatDirectory Directory; 235 236 /// The number of entries in the directory 237 size_t DirectorySize; 238 239 private: 240 /// The list of parsed entries in the folder. 241 Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ Entries; 242 }; 243 244 /// Represents a FAT directory file. 245 public ref class FatDirectory abstract : FatDirectoryBase 187 246 { 188 247 public: … … 193 252 /// \param[in] cluster The cluster at which the directory list starts. 194 253 /// \param[in] api The FAT API object which is creating this object. 195 FatDirectory(String^ name, FatDirectory^ parent, unsigned cluster, FatApi^ api); 196 197 /// Compacts the directory structure. 198 void ClearDeletedEntries(); 199 200 /// The list of files and subfolders in this directory. 201 property Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ Items 202 { 203 Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ get() 204 { 205 return Entries; 206 } 207 } 208 209 protected: 210 /// Gets the start cluster from the given directory entry. 211 virtual unsigned GetStartCluster(::FatDirectory& directory) = 0; 254 FatDirectory(String^ name, FatDirectoryBase^ parent, unsigned cluster, FatApi^ api); 255 256 protected: 257 virtual void ReadDirectory() override; 258 virtual void WriteDirectory() override; 212 259 213 260 private: 214 FatDirectoryFile Directory;215 Collections::Generic::Dictionary<String^, FatDirectoryEntry^>^ Entries;216 217 261 FatApi^ Api; 218 262 }; … … 225 269 226 270 virtual void LoadFat() override; 227 virtual FatDirectory^ LoadDirectory(unsigned cluster, String^ name, FatDirectory^ parent) override; 271 virtual FatDirectoryBase^ LoadDirectory(unsigned cluster, String^ name, 272 FatDirectoryBase^ parent) override; 228 273 229 274 internal: … … 235 280 { 236 281 public: 237 Directory(String^ name, FatDirectory ^ parent, unsigned cluster, Fat12Or16Api^ api);282 Directory(String^ name, FatDirectoryBase^ parent, unsigned cluster, Fat12Or16Api^ api); 238 283 239 284 protected: 240 virtual unsigned GetStartCluster(::FatDirectory & directory) override;285 virtual unsigned GetStartCluster(::FatDirectoryEntry& directory) override; 241 286 }; 242 287 … … 265 310 public: 266 311 virtual void LoadFat() override; 267 virtual FatDirectory^ LoadDirectory(unsigned cluster, String^ name, FatDirectory^ parent) override; 312 virtual FatDirectoryBase^ LoadDirectory(unsigned cluster, String^ name, 313 FatDirectoryBase^ parent) override; 268 314 269 315 internal: … … 278 324 { 279 325 public: 280 Directory(String^ name, FatDirectory ^ parent, unsigned cluster, Fat32Api^ api);326 Directory(String^ name, FatDirectoryBase^ parent, unsigned cluster, Fat32Api^ api); 281 327 282 328 protected: 283 virtual unsigned GetStartCluster(::FatDirectory & directory) override;329 virtual unsigned GetStartCluster(::FatDirectoryEntry& directory) override; 284 330 }; 285 331 }; -
trunk/eraser6/Eraser.Util.FileSystem/Stdafx.h
r1206 r1226 22 22 #pragma once 23 23 #include <windows.h> 24 #include <atlstr.h>
Note: See TracChangeset
for help on using the changeset viewer.
