📄 treeblockdevice.java
字号:
/* JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine Release Version 2.0 A project from the Physics Dept, The University of Oxford Copyright (C) 2007 Isis Innovation Limited This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Details (including contact information) can be found at: www.physics.ox.ac.uk/jpc*/package org.jpc.support;import java.io.*;import java.util.regex.*; //this is used to extract filenames for directory entriesimport java.util.*;public class TreeBlockDevice implements BlockDevice{ public int numberOfOpenFiles = 0; private File source; private boolean locked; private byte[] MBR, header, header2, FAT, start, empty; private long rootSize; // Size in sectors of root directory private int startingHead; //0-255 private int startingSector; //1 - 63 private int startingCylinder; //0-1023 private int endingHead; //0-255 private int endingSector; //1 - 63 private int endingCylinder; //0-1023 private long relativeSectors; // counts from 0 private int totalSectors, totalClusters, bytesPerSector, sectorsPerCluster, reservedSectors, sectorsPerTrack, hiddenSectors, sectorsPerFAT,fsinfoSector, backupBootSector,cylinders, heads; private long rootStartCluster,freeClusters, lastAllocatedCluster,rootSizeClusters,dataSizeClusters; private Map dataMap = new HashMap(); private Map FATMap = new HashMap(); private Map writeMap = new HashMap(); private Vector bufferedClusters = new Vector(); private int fileReads; private rafReads[] openFiles; private Map hashFAT; //not used unless writeNewTree is invoked public boolean bufferWrites = false; private int maxNumberOfFiles = 5000; /* notes: Write Tree: to write a copy of the entire directory tree to disk, create a new folder and pass it as a File to writeNewTree(File file) Synchronise: to continuously try to synchronise the virtual tree with the underlying tree set bufferWrites to false, otherwise all writes are buffered in an array */ public TreeBlockDevice() {} public TreeBlockDevice(File filename, boolean sync) throws IOException { String specs = ""; if (sync) specs += "sync:"; specs += filename.getAbsolutePath(); this.configure(specs); } public void configure(String specs) throws IOException { boolean syncWrites = false; String fname = specs; if (specs.startsWith("sync:")) { syncWrites = true; fname = specs.substring(5); } File source = new File(fname); openFiles = new rafReads[10]; fileReads = 0; bufferWrites = !syncWrites; bytesPerSector = 512; sectorsPerCluster = 8; this.source = source; System.out.println("start"); //read in directory structure MyDir root = buildTree(source,2); System.out.println("end"); dataSizeClusters=root.getdirSubClusters(); rootSize=root.getSizeSectors(); locked = false; //set Drive Geometry sectorsPerTrack = 63; heads = 16;//there are subtle issues here with bios remapping, refer to http://www.storagereview.com/guide2000/ref/hdd/bios/modesECHS.html if (dataSizeClusters*sectorsPerCluster+rootSize+95 < 1067*sectorsPerTrack*heads) //this needs fixing to a suitable size cylinders=1067; // Size of drive in sectors else cylinders = (int) (200 + (dataSizeClusters*sectorsPerCluster+rootSize+95)/sectorsPerTrack/heads); //set specifications for disk which go in partition table startingHead = 1; startingSector = 1; startingCylinder = 0; endingHead = heads; endingSector = sectorsPerTrack; endingCylinder = cylinders; relativeSectors = 63; totalSectors = cylinders*sectorsPerTrack*heads-1;// -1 for the MBR which isn't counted //set specifications for disk which go in partition boot sector totalClusters = totalSectors/sectorsPerCluster; reservedSectors = 32; hiddenSectors=63; //what's not in the partition itself sectorsPerFAT = totalClusters*4/bytesPerSector; //add 1 to ensure rounding up FAT = new byte[sectorsPerFAT*bytesPerSector]; mapToFAT(95+2*sectorsPerFAT); mapToData(95+2*sectorsPerFAT); rootStartCluster = 2; fsinfoSector = 1; backupBootSector = 6; //set specifications for disk which go in FSINFO Sector rootSizeClusters = (int) (rootSize-1)/sectorsPerCluster + 1; freeClusters = totalClusters-1-rootSizeClusters-dataSizeClusters; lastAllocatedCluster = 2; //***********************************************************************************************// //set up the master boot record with partition table MBR = new byte[512]; int pos = 0; //where mbrcode was pos = 446; //partition table MBR[pos++] = (byte) 0x80;// 80 means system partition, 00 means do not use for booting MBR[pos++] = (byte) startingHead; // starting Sector (bits 0-5) and high starting cylinder bits int data = (startingCylinder & 0xC0) | (0x3F & startingSector); MBR[pos++] = (byte) data; //low 8 bits of starting Cylinder MBR[pos++] = (byte) startingCylinder; MBR[pos++]=(byte)0x0C;//System ID MBR[pos++] = (byte) endingHead; // ending Sector (bits 0-5) and high ending cylinder bits data = (endingCylinder & 0xC0) | (0x3F & endingSector); MBR[pos++] = (byte) data; //low 8 bits of ending Cylinder MBR[pos++] = (byte) endingCylinder; //relative sectors MBR[pos++] = (byte) (relativeSectors); MBR[pos++] = (byte) (relativeSectors >>> 8); MBR[pos++] = (byte) (relativeSectors >>> 16); MBR[pos++] = (byte) (relativeSectors >>> 24); // N.B. remaining sectors on first track after MBR are empty //total sectors MBR[pos++] = (byte) (totalSectors); MBR[pos++] = (byte) (totalSectors >>> 8); MBR[pos++] = (byte) (totalSectors >>> 16); MBR[pos++] = (byte) (totalSectors >>> 24); //fill 3 empty partition entries for(int i=0; i< 16*3; i++) MBR[pos++]=0x00; MBR[0x1FE] = (byte) 0x55;// end of sector marker MBR[0x1FF] = (byte) 0xAA; //******************************************************************// //set up the partition boot sector header = new byte[512]; pos = 0; // write header data into this array - don't see www.ntfs.com - it is wrong! header[pos++] = (byte) 0xEB; header[pos++] = (byte) 0x3C; header[pos++] = (byte) 0x90; String myOEM = "JPCFS1.0"; System.arraycopy(myOEM.getBytes(), 0, header, 3, 8); pos += 8; //BIOS Parameter block header[pos++] = (byte) (bytesPerSector); header[pos++] = (byte) (bytesPerSector >>> 8); header[pos++] = (byte) sectorsPerCluster; header[pos++] = (byte) (reservedSectors); header[pos++] = (byte) (reservedSectors >>> 8); header[pos++] = (byte) 0x02;//number of copies of FAT byte offset 0x10 header[pos++] = (byte) 0x00;//this and following 3 bytes are irrelevant for FAT32 (N/A) header[pos++] = (byte) 0x00; header[pos++] = (byte) 0x00; header[pos++] = (byte) 0x00; header[pos++] = (byte) 0xF8;//do not change header[pos++] = (byte) 0x00;//N/A header[pos++] = (byte) 0x00;//N/A header[pos++] = (byte) sectorsPerTrack; header[pos++] = (byte) 0x00;// byte offset 0x19 header[pos++] = (byte) heads; header[pos++] = (byte) 0x00;// byte offset 0x1B header[pos++] = (byte) (hiddenSectors); header[pos++] = (byte) (hiddenSectors >>> 8); header[pos++] = (byte) (hiddenSectors >>> 16); header[pos++] = (byte) (hiddenSectors >>> 24); //byte offset 0x20 = total number of sectors in partition header[pos++] = (byte) (totalSectors); header[pos++] = (byte) (totalSectors >>> 8); header[pos++] = (byte) (totalSectors >>> 16); header[pos++] = (byte) (totalSectors >>> 24); //byte offset 0x24 -- number of sectors per FAT = 520 for 520MB drive (4 bytes) header[pos++] = (byte) (sectorsPerFAT); header[pos++] = (byte) (sectorsPerFAT >>> 8); header[pos++] = (byte) (sectorsPerFAT >>> 16); header[pos++] = (byte) (sectorsPerFAT >>> 24); header[pos++] = (byte) 0x00;//byte offset 0x28 -- *****this could be wrong, tells which FAT is active (http://home.teleport.com/~brainy/fat32.htm) header[pos++] = (byte) 0x00;//byte offset 0x29 header[pos++] = (byte) 0x00;//byte offset 0x2A -- this and the next seem irrelevant (FAT32 version) header[pos++] = (byte) 0x00;//byte offset 0x2B //byte offset 0x2C -- cluster number of the start of the root directory (4 bytes) header[pos++] = (byte) (rootStartCluster); header[pos++] = (byte) (rootStartCluster >>> 8); header[pos++] = (byte) (rootStartCluster >>> 16); header[pos++] = (byte) (rootStartCluster >>> 24); //byte offset 0x30 -- sector number of FSINFO sector (is this 1 or two bytes??? although it doesn't matter) header[pos++] = (byte) fsinfoSector; header[pos++] = (byte) 0x00;//byte offset 0x31 //byte offset 0x32 -- sector number of backup boot sector header[pos++] = (byte) backupBootSector; for (int i=1;i<14;i++) header[pos++] = (byte) 0x00; header[pos++] = (byte) 0x80;//byte offset 0x40 header[pos++] = (byte) 0x00; header[pos++] = (byte) 0x29;//do not change (extended signature) header[pos++] = (byte) 0x26;//these four are the serial number of the partition header[pos++] = (byte) 0x59; header[pos++] = (byte) 0x41; header[pos++] = (byte) 0x31; header[pos++] = (byte) 0x49; header[pos++] = (byte) 0x41; header[pos++] = (byte) 0x4E; header[pos++] = (byte) 0x52; header[pos++] = (byte) 0x4F; header[pos++] = (byte) 0x43; header[pos++] = (byte) 0x4B; header[pos++] = (byte) 0x53; header[pos++] = (byte) 0x46; header[pos++] = (byte) 0x33; header[pos++] = (byte) 0x32; header[pos++] = (byte) 0x46;//byte offset 0x52 F header[pos++] = (byte) 0x41;//byte offset 0x37 A header[pos++] = (byte) 0x54;//byte offset 0x38 T header[pos++] = (byte) 0x33;//byte offset 0x39 3 header[pos++] = (byte) 0x32;//byte offset 0x3A 2 header[pos++] = (byte) 0x20;//byte offset 0x3B header[pos++] = (byte) 0x20;//byte offset 0x3C header[pos++] = (byte) 0x20;//byte offset 0x3D header[0x1FE] = (byte) 0x55; header[0x1FE + 1] = (byte) 0xAA; //***************************************************// //Now do the second sector, the FSINFO sector header2 = new byte[512]; pos=0; header2[pos++] = (byte) 0x52; header2[pos++] = (byte) 0x52; header2[pos++] = (byte) 0x61; header2[pos++] = (byte) 0x41; for(int i=0;i<480;i++) header2[pos++] = (byte) 0x00; header2[pos++] = (byte) 0x72; header2[pos++] = (byte) 0x72; header2[pos++] = (byte) 0x41; header2[pos++] = (byte) 0x61; //number of free clusters (4 bytes) set to FFFFFFFF if unknown header2[pos++] = (byte) (freeClusters); header2[pos++] = (byte) (freeClusters >>> 8); header2[pos++] = (byte) (freeClusters >>> 16); header2[pos++] = (byte) (freeClusters >>> 24); //cluster number of most recently allocated cluster (4 bytes) header2[pos++] = (byte) (lastAllocatedCluster); header2[pos++] = (byte) (lastAllocatedCluster >>> 8); header2[pos++] = (byte) (lastAllocatedCluster >>> 16); header2[pos++] = (byte) (lastAllocatedCluster >>> 24); for(int i=0;i<14;i++) header2[pos++] = (byte) 0x00; header2[0x1FE] = (byte) 0x55; header2[0x1FE + 1] = (byte) 0xAA; //*************************************************************************************// //Pad out the first 32 sectors and include copy of bootsector and FSINFO sector empty = new byte[512]; for(int i=0; i<512; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -