Пример #1
0
        private static unsafe FileStream createNewFloppyImage(FileInfo image)
        {
            FileStream fStream = image.Create();

            FAT12_BOOT_SECTOR bootSector = new FAT12_BOOT_SECTOR();
            bootSector.Bpb.OEMName[0] = (byte)'T';
            bootSector.Bpb.OEMName[1] = (byte)'i';
            bootSector.Bpb.OEMName[2] = (byte)'m';
            bootSector.Bpb.OEMName[3] = 0;
            bootSector.Bpb.OEMName[4] = 0;
            bootSector.Bpb.OEMName[5] = 0;
            bootSector.Bpb.OEMName[6] = 0;
            bootSector.Bpb.OEMName[7] = 0;

            bootSector.Bpb.BytesPerSector = 512;
            bootSector.Bpb.SectorsPerCluster = 1;
            bootSector.Bpb.ReservedSectors = 1;
            bootSector.Bpb.NumberOfFats = 2;
            bootSector.Bpb.NumDirEntries = 224;
            bootSector.Bpb.NumSectors = 2880;
            bootSector.Bpb.Media = 0xf0;
            bootSector.Bpb.SectorsPerFat = 9;
            bootSector.Bpb.SectorsPerTrack = 12;
            bootSector.Bpb.HeadsPerCyl = 2;
            bootSector.Bpb.HiddenSectors = 0;

            byte[] buf = new byte[sizeof(FAT12_BOOT_SECTOR)];
            GCHandle pinnedBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
            Marshal.StructureToPtr(bootSector, pinnedBuf.AddrOfPinnedObject(), true);
            fStream.Write(buf, 0, buf.Length);

            fStream.Seek(510, SeekOrigin.Begin);
            fStream.WriteByte(0x55);
            fStream.WriteByte(0xAA);

            fStream.Seek(1474559, SeekOrigin.Begin);
            fStream.WriteByte(0);

            return fStream;
        }
Пример #2
0
        private static void DeleteFile(string fileName, FileStream fStream, FAT12_BOOT_SECTOR bootSector, FAT12_MOUNT_INFO mountInfo)
        {
            byte[] buf = new byte[512];
            FAT12_FILE_ENTRY fat12FileEntry;

            /* Get 8.3 directory name */
            char[] DosFileName = new char[12];
            ToDosFileName(fileName, ref DosFileName);
            DosFileName[11] = '\0';

            /* 16 entries per sector, 14 sectors total */
            for (int sector = 0; sector < 14; sector++)
            {
                /* Read in sector */
                fStream.Seek((mountInfo.rootOffset + sector) * 512, SeekOrigin.Begin);
                fStream.Read(buf, 0, 512);

                /* Get file info */
                GCHandle pinnedBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
                int count = 0;
                unsafe
                {
                    fat12FileEntry = (FAT12_FILE_ENTRY)Marshal.PtrToStructure(pinnedBuf.AddrOfPinnedObject() + (count * sizeof(FAT12_FILE_ENTRY)), typeof(FAT12_FILE_ENTRY));
                }

                for (int i = 0; i < 16; i++)
                {
                    /* Get current filename */
                    char[] name = new char[12];
                    unsafe
                    {
                        for (int j = 0; j < 11; j++)
                            name[j] = (char)fat12FileEntry.Filename[j];
                    }
                    name[11] = '\0';

                    /* Find a match? */
                    if (String.Compare(String.Concat(DosFileName), String.Concat(name)) == 0)
                    {
                        FreeClusterChain(fat12FileEntry.FirstCluster, fStream);

                        unsafe
                        {
                            fat12FileEntry.Filename[0] = 0xE5;
                            fStream.Seek((mountInfo.rootOffset + sector) * 512 + (count * sizeof(FAT12_FILE_ENTRY)), SeekOrigin.Begin);
                            Marshal.StructureToPtr(fat12FileEntry, pinnedBuf.AddrOfPinnedObject(), true);
                            fStream.Write(buf, 0, sizeof(FAT12_FILE_ENTRY));
                        }

                        return;
                    }

                    count++;
                    unsafe
                    {
                        fat12FileEntry = (FAT12_FILE_ENTRY)Marshal.PtrToStructure(pinnedBuf.AddrOfPinnedObject() + (count * sizeof(FAT12_FILE_ENTRY)), typeof(FAT12_FILE_ENTRY));
                    }
                }

                pinnedBuf.Free();
            }

            return;
        }
Пример #3
0
        static void SaveFileToDiskImage(string fileName, FileStream fStream, FAT12_BOOT_SECTOR bootSector, FAT12_MOUNT_INFO mountInfo)
        {
            /* First delete the file if it exists */
            DeleteFile(fileName, fStream, bootSector, mountInfo);

            byte[] buf = new byte[512];
            FAT12_FILE_ENTRY fat12FileEntry;

            /* Get 8.3 directory name */
            char[] DosFileName = new char[12];
            ToDosFileName(fileName, ref DosFileName);
            DosFileName[11] = '\0';

            /* 16 entries per sector, 14 sectors total */
            for (int sector = 0; sector < 14; sector++)
            {
                /* Read in sector */
                fStream.Seek((mountInfo.rootOffset + sector) * 512, SeekOrigin.Begin);
                fStream.Read(buf, 0, 512);

                /* Get file info */
                GCHandle pinnedBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
                int count = 0;
                unsafe
                {
                    fat12FileEntry = (FAT12_FILE_ENTRY)Marshal.PtrToStructure(pinnedBuf.AddrOfPinnedObject() + (count * sizeof(FAT12_FILE_ENTRY)), typeof(FAT12_FILE_ENTRY));
                }

                for (int i = 0; i < 16; i++)
                {
                    /* I'm looking for an entry beginning with \0 or 0xE5 */
                    unsafe
                    {
                        if (fat12FileEntry.Filename[0] == '\0' || fat12FileEntry.Filename[0] == 0xE5)
                        {
                            /* Found a blank file entry */
                            for (int j = 0; j < 8; j++)
                                fat12FileEntry.Filename[j] = (byte)DosFileName[j];
                            for (int j = 0; j < 3; j++)
                                fat12FileEntry.Ext[j] = (byte)DosFileName[j + 8];

                            fat12FileEntry.Attrib = 0;
                            /* TODO: Set the date and times */
                            fat12FileEntry.DateCreated = 0;
                            fat12FileEntry.DateLastAccessed = 0;
                            fat12FileEntry.LastModDate = 0;
                            fat12FileEntry.LastModTime = 0;
                            fat12FileEntry.TimeCreated = 0;
                            fat12FileEntry.TimeCreatedMs = 0;
                            fat12FileEntry.FileSize = 0;

                            fat12FileEntry.FirstCluster = GetFirstFreeCluster(fStream, 2);

                            UInt16 currentCluster = fat12FileEntry.FirstCluster;
                            FileStream inputFile = new FileStream(fileName, FileMode.Open);
                            byte[] inputBuffer = new byte[512];
                            int readBytes = 0;
                            while ((readBytes = inputFile.Read(inputBuffer, 0, 512)) > 0)
                            {
                                fat12FileEntry.FileSize += (uint)readBytes;
                                fStream.Seek((31 + currentCluster) * 512, SeekOrigin.Begin);
                                fStream.Write(inputBuffer, 0, readBytes);

                                if (fStream.Length > fat12FileEntry.FileSize)
                                { /* Allocate next block */
                                    UInt16 nextBlock = GetFirstFreeCluster(fStream, (UInt16)(currentCluster + 1));
                                    MarkBlockChain(fStream, currentCluster, nextBlock);
                                    currentCluster = nextBlock;
                                }
                            }

                            MarkBlockChain(fStream, currentCluster, 0xFFF);

                            fStream.Seek((mountInfo.rootOffset + sector) * 512 + (count * sizeof(FAT12_FILE_ENTRY)), SeekOrigin.Begin);
                            Marshal.StructureToPtr(fat12FileEntry, pinnedBuf.AddrOfPinnedObject(), true);
                            fStream.Write(buf, 0, sizeof(FAT12_FILE_ENTRY));

                            return;
                        }

                        count++;
                        unsafe
                        {
                            fat12FileEntry = (FAT12_FILE_ENTRY)Marshal.PtrToStructure(pinnedBuf.AddrOfPinnedObject() + (count * sizeof(FAT12_FILE_ENTRY)), typeof(FAT12_FILE_ENTRY));
                        }
                    }
                }

                pinnedBuf.Free();
            }
        }
Пример #4
0
        private static FAT12_BOOT_SECTOR LoadBootSector(FileStream fStream)
        {
            FAT12_BOOT_SECTOR retVal = new FAT12_BOOT_SECTOR();

            fStream.Seek(0, SeekOrigin.Begin);
            unsafe
            {
                byte[] buf = new byte[sizeof(FAT12_BOOT_SECTOR)];
                fStream.Read(buf, 0, sizeof(FAT12_BOOT_SECTOR));
                GCHandle pinnedBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
                retVal = (FAT12_BOOT_SECTOR)Marshal.PtrToStructure(pinnedBuf.AddrOfPinnedObject(), typeof(FAT12_BOOT_SECTOR));
                pinnedBuf.Free();
            }

            return retVal;
        }