Example #1
0
        public unsafe void Open(FileAccess desiredAccess)
        {
            string fileName = String.Format(@"\\.\{0}", mFileName);

              mDiskHandle = CreateFile(fileName,
            desiredAccess,
            FileShare.ReadWrite, // drives must be opened with read and write share access
            0,
            FileMode.Open,
            FileAttributes.Normal,
            IntPtr.Zero);

              if (mDiskHandle.IsInvalid)
              throw new Win32Exception(Marshal.GetLastWin32Error());

              if (desiredAccess.HasFlag(FileAccess.Write))
              {
            // Unmount & lock the drive
            uint pByteReturned = 0;
            bool ret = DeviceIoControl(mDiskHandle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out pByteReturned, IntPtr.Zero);

            if (!ret)
              throw new Win32Exception(Marshal.GetLastWin32Error());

            ret = DeviceIoControl(mDiskHandle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out pByteReturned, IntPtr.Zero);
            if (!ret)
              throw new Win32Exception(Marshal.GetLastWin32Error());
              }

              InStream = new FileStream(mDiskHandle, desiredAccess);
              {
            binaryReader = new BinaryReader(InStream);
            {
              bootSector = Utils.ByteToType<FATBS>(binaryReader);
              //TODO: Check jmpSector for valid FAT

              ulong rootDirSectors = (ulong)((bootSector.root_entry_count * 32) + (bootSector.bytes_per_sector - 1)) / bootSector.bytes_per_sector;

              if (rootDirSectors == 0)
            type = Type.FAT32;

              if (type == Type.FAT32)
            fat32ExtBS = Utils.ByteToType<FAT32ExtBS>(binaryReader);
              else
            fat16ExtBS = Utils.ByteToType<FAT16ExtBS>(binaryReader);

              uint tableSize = 0;
              if (bootSector.table_size_16 != 0)
            tableSize = bootSector.table_size_16;
              else
            tableSize = fat32ExtBS.table_size_32;

              ulong firstDataSector = (ulong)(bootSector.reserved_sector_count + (bootSector.table_count * tableSize) + rootDirSectors);

              uint totalSectors;
              if (bootSector.total_sectors_16 != 0)
            totalSectors = bootSector.total_sectors_16;
              else
            totalSectors = bootSector.total_sectors_32;

              ulong dataSectors = (ulong)totalSectors - (bootSector.reserved_sector_count + (bootSector.table_count * tableSize) + rootDirSectors);

              ulong totalClusters = (ulong)(dataSectors / bootSector.sectors_per_cluster);

              if (totalClusters < 4085)
            type = Type.FAT12;
              else if (totalClusters < 65525)
            type = Type.FAT16;
              else
            type = Type.FAT32;

              if (type == Type.FAT12)
            throw new NotSupportedException("FAT12 is not supported");

              logger.Log("Detected new partition: {0}", new object[] { type });

              if (type == Type.FAT16)
            fatImplementation = new FAT16(mFileName, bootSector, fat16ExtBS, binaryReader, InStream, logger);
              else
            fatImplementation = new FAT32(mFileName, bootSector, fat32ExtBS, binaryReader, InStream, logger);

              fatImplementation.rootDirSectors = rootDirSectors;
              fatImplementation.tableSize = tableSize;
              fatImplementation.totalClusters = totalClusters;
              fatImplementation.totalSectors = totalSectors;
              fatImplementation.dataSectors = dataSectors;
              fatImplementation.firstDataSector = firstDataSector;
              fatImplementation.mbrOffsetInByte = 0;

              logger.Log("Table size: {0}", new object[] { tableSize });
              logger.Log("Clusters: {0}", new object[] { totalClusters });
              logger.Log("Sectors: {0}", new object[] { totalSectors });
              logger.Log("");
              logger.Log("Reading FAT...");

              fatImplementation.ReadRootDirectory();

              logger.Log("Reading done.");
            }
              }
        }
Example #2
0
File: FAT.cs Project: blinkseb/FMS
 public FAT(string drive, FATBS bootSector, BinaryReader reader, Stream stream, ILogger logger)
 {
     this.bootSector = bootSector;
       this.reader = reader;
       this.stream = stream;
       this.logger = logger;
       rootDirectory = new Directory()
       {
     name = drive
       };
 }