fdiskcommand.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 840 行 · 第 1/2 页
JAVA
840 行
/*
* $Id: FdiskCommand.java,v 1.3 2004/01/24 23:43:38 gbin Exp $
*/
package org.jnode.fs.partitions.command;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.naming.NameNotFoundException;
import org.jnode.driver.ApiNotFoundException;
import org.jnode.driver.Device;
import org.jnode.driver.DeviceManager;
import org.jnode.driver.DeviceNotFoundException;
import org.jnode.driver.block.BlockDeviceAPI;
import org.jnode.driver.ide.IDEConstants;
import org.jnode.driver.ide.IDEDevice;
import org.jnode.driver.ide.IDEDriveDescriptor;
import org.jnode.fs.fat.BootSector;
import org.jnode.fs.fat.GrubBootSector;
import org.jnode.fs.partitions.ibm.IBMPartitionTable;
import org.jnode.fs.partitions.ibm.IBMPartitionTableEntry;
import org.jnode.fs.partitions.ibm.IBMPartitionTypes;
import org.jnode.naming.InitialNaming;
import org.jnode.shell.help.DeviceArgument;
import org.jnode.shell.help.Help;
import org.jnode.shell.help.OptionArgument;
import org.jnode.shell.help.Parameter;
import org.jnode.shell.help.ParsedArguments;
import org.jnode.shell.help.StringArgument;
import org.jnode.shell.help.Syntax;
/**
* @author gbin
*/
public class FdiskCommand {
static final OptionArgument INITMBR =
new OptionArgument(
"init. MBR",
"Type parameter",
new OptionArgument.Option[] {
new OptionArgument.Option("--initmbr", "initialize the Master Boot Record of the device")});
static final OptionArgument ACTION =
new OptionArgument(
"action",
"Action on a specified partition",
new OptionArgument.Option[] {
new OptionArgument.Option("-d", "Delete a partition"),
new OptionArgument.Option("-b", "Switch the bootable flag of a partition"),
new OptionArgument.Option("-m", "Modify/create a partition")});
static final StringArgument PARTITION = new StringArgument("partition number or description", "Targeted partition");
static final DeviceArgument ARG_DEVICE =
new DeviceArgument("device-id", "the device on which you want to change the partition");
static final Parameter PARAM_INITMBR = new Parameter(INITMBR, Parameter.MANDATORY);
static final Parameter PARAM_ACTION = new Parameter(ACTION, Parameter.MANDATORY);
static final Parameter PARAM_DEVICE = new Parameter(ARG_DEVICE, Parameter.MANDATORY);
static final Parameter PARAM_PARTITION = new Parameter(PARTITION, Parameter.MANDATORY);
public static Help.Info HELP_INFO =
new Help.Info(
"fdisk",
new Syntax[] {
new Syntax("Lists the available devices"),
new Syntax("Print the partition table of a device", new Parameter[] { PARAM_DEVICE }),
new Syntax("Initialize the MBR of a device", new Parameter[] { PARAM_INITMBR, PARAM_DEVICE }),
new Syntax(
"Create / Delete / change bootable flag of a partition",
new Parameter[] { PARAM_ACTION, PARAM_PARTITION, PARAM_DEVICE })
});
/*
* public static Help.Info HELP_INFO = new Help.Info( "fdisk", "With no
* argument, it lists the available devices\n" + "With only the device, it
* lists the current partitions on the device\n" + "--initmbr initialize the
* Master Boot Record of the device\n" + "-m add or modify the id partition
* with first sector at start, size of size sectors and fs id fs\n" + "-d
* delete the partition with id id" + "-b switch boot flag on parition id",
*/
public static void main(String[] args) {
ParsedArguments cmdLine = HELP_INFO.parse(args);
DeviceManager dm;
try {
dm = (DeviceManager)InitialNaming.lookup(DeviceManager.NAME);
boolean isAction = PARAM_ACTION.isSet(cmdLine);
boolean isInitMBR = PARAM_INITMBR.isSet(cmdLine);
boolean isDevice = PARAM_DEVICE.isSet(cmdLine);
// no parameters
if (!isDevice) {
listAvailableDevice(dm);
return;
}
// only device is set
if (!isAction && !isInitMBR && isDevice) {
printTable(ARG_DEVICE.getValue(cmdLine), dm);
return;
}
// initMBR
if (isInitMBR) {
initMbr(ARG_DEVICE.getValue(cmdLine), dm);
return;
}
// now it is a change on a specific partition so read the table
IDEDevice current = (IDEDevice)dm.getDevice(ARG_DEVICE.getValue(cmdLine));
BlockDeviceAPI api = (BlockDeviceAPI)current.getAPI(BlockDeviceAPI.class);
byte[] mbr = new byte[IDEConstants.SECTOR_SIZE];
api.read(0, mbr, 0, IDEConstants.SECTOR_SIZE);
if (!IBMPartitionTable.containsPartitionTable(mbr))
throw new IOException("This device doesn't contain a valid MBR, use --initmbr.");
BootSector bs = new BootSector(mbr);
if (ACTION.getValue(cmdLine).intern() == "-m") {
modifyPartition(PARTITION.getValue(cmdLine), api, bs);
bs.write(api);
return;
}
// it is not a modify so the PARTITION parameter is only a partition
// number
int partNumber;
try {
partNumber = Integer.parseInt(PARTITION.getValue(cmdLine));
} catch (NumberFormatException f) {
throw new IllegalArgumentException("Partition number is invalid");
}
if (partNumber > 3 || partNumber < 0)
throw new IllegalArgumentException("Partition number is invalid");
if (ACTION.getValue(cmdLine).intern() == "-d") {
deletePartition(bs, partNumber);
bs.write(api);
return;
}
if (ACTION.getValue(cmdLine).intern() == "-b") {
toggleBootable(bs, partNumber);
bs.write(api);
}
} catch (IOException e) {
e.printStackTrace();
} catch (NameNotFoundException e) {
e.printStackTrace();
} catch (ApiNotFoundException e) {
e.printStackTrace();
} catch (DeviceNotFoundException e) {
e.printStackTrace();
}
}
private static void toggleBootable(BootSector bs, int partNumber) {
// save the current state for the targeted partition
boolean currentStatus = bs.getPartition(partNumber).getBootIndicator();
// erase all the states
for (int i = 0; i < 4; i++) {
bs.getPartition(i).setBootIndicator(false);
}
// put back the reversed state for the targeted partition
bs.getPartition(partNumber).setBootIndicator(!currentStatus);
}
private static void deletePartition(BootSector bs, int partNumber) {
bs.getPartition(partNumber).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
}
private static void modifyPartition(String description, BlockDeviceAPI api, BootSector bs) throws IOException {
// arg 1 should be in the form id:start:size:fs
StringTokenizer st = new StringTokenizer(description, ":");
int id = Integer.parseInt(st.nextToken());
//BUG in long
//long start = Long.parseLong(st.nextToken());
//long size = Long.parseLong(st.nextToken());
int start = Integer.parseInt(st.nextToken());
int size = Integer.parseInt(st.nextToken());
int fs = Integer.parseInt(st.nextToken(), 16);
System.out.println(
"Init " + id + " with start = " + start + ", size = " + size + ", fs = " + Integer.toHexString(fs & 0xff));
IBMPartitionTableEntry entry = bs.getPartition(id);
entry.setBootIndicator(false);
entry.setSystemIndicator(fs);
entry.setStartLba(start);
entry.setNrSectors(size);
bs.write(api);
return;
}
private static void initMbr(String device, DeviceManager dm)
throws DeviceNotFoundException, ApiNotFoundException, IOException {
IDEDevice current = (IDEDevice)dm.getDevice(device);
BlockDeviceAPI api = (BlockDeviceAPI)current.getAPI(BlockDeviceAPI.class);
byte[] MBR = new byte[IDEConstants.SECTOR_SIZE];
api.read(0, MBR, 0, IDEConstants.SECTOR_SIZE);
System.out.println("Initialize MBR ...");
GrubBootSector newMBR = new GrubBootSector(PLAIN_MASTER_BOOT_SECTOR);
if (IBMPartitionTable.containsPartitionTable(MBR)) {
BootSector oldMBR = new BootSector(MBR);
System.out.println("This device already contains a partition table. Copy the already existing partitions.");
for (int i = 0; i < 4; i++) {
IBMPartitionTableEntry entry = newMBR.getPartition(i);
entry.setBootIndicator(oldMBR.getPartition(i).getBootIndicator());
entry.setStartLba(oldMBR.getPartition(i).getStartLba());
entry.setNrSectors(oldMBR.getPartition(i).getNrSectors());
entry.setSystemIndicator(oldMBR.getPartition(i).getSystemIndicator());
}
} else {
newMBR.getPartition(0).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
newMBR.getPartition(1).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
newMBR.getPartition(2).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
newMBR.getPartition(3).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
}
newMBR.write(api);
}
private static void printTable(String deviceName, DeviceManager dm)
throws DeviceNotFoundException, ApiNotFoundException, IOException {
{
IDEDevice current = (IDEDevice)dm.getDevice(deviceName);
BlockDeviceAPI api = (BlockDeviceAPI)current.getAPI(BlockDeviceAPI.class);
IDEDriveDescriptor descriptor = current.getDescriptor();
byte[] MBR = new byte[IDEConstants.SECTOR_SIZE];
api.read(0, MBR, 0, IDEConstants.SECTOR_SIZE);
if (IBMPartitionTable.containsPartitionTable(MBR)) {
IBMPartitionTable partitionTable = new IBMPartitionTable(MBR, current);
int nbPartitions = partitionTable.getLength();
System.out.println(
"Disk : " + current.getId() + ": " + descriptor.getSectorsIn28bitAddressing() * 512 + " bytes");
System.out.println("Device Boot Start End Blocks System");
for (int i = 0; i < nbPartitions; i++) {
IBMPartitionTableEntry entry = (IBMPartitionTableEntry)partitionTable.getEntry(i);
int si = entry.getSystemIndicator();
if (si != 0)
System.out.println(
"ID "
+ i
+ " "
+ (entry.getBootIndicator() ? "Boot" : "No")
+ " "
+ entry.getStartLba()
+ " "
+ (entry.getStartLba() + entry.getNrSectors())
+ " "
+ entry.getNrSectors()
+ " "
+ Integer.toHexString(si));
if(entry.isExtended()) {
final Vector exPartitions = partitionTable.getExtendedPartitions();
Iterator itter = exPartitions.iterator();
int j = 0;
while(itter.hasNext()) {
IBMPartitionTableEntry exEntry = (IBMPartitionTableEntry)itter.next();
si = exEntry.getSystemIndicator();
System.out.println(
"ID "
+ i
+ " "
+ (exEntry.getBootIndicator() ? "Boot" : "No")
+ " "
+ exEntry.getStartLba()
+ " "
+ "-----"//(exEntry.getStartLba() + entry.getNrSectors())
+ " "
+ "-----"//exEntry.getNrSectors()
+ " "
+ Integer.toHexString(si));
j++;
}
}
}
} else {
System.out.println(" No valid MBR found on this device. Use --initmbr to initialize it.");
}
}
}
private static void listAvailableDevice(DeviceManager dm) {
Iterator allDevices = dm.getDevicesByAPI(BlockDeviceAPI.class).iterator();
while (allDevices.hasNext()) {
Device current = (Device)allDevices.next();
System.out.println("Found device : " + current.getId() + "[" + current.getClass() + "]");
if (current instanceof IDEDevice) {
IDEDevice ideDevice = (IDEDevice)current;
IDEDriveDescriptor currentDescriptor = ideDevice.getDescriptor();
if (currentDescriptor.isDisk()) {
System.out.println(
" IDE Disk : "
+ ideDevice.getId()
+ "("
+ currentDescriptor.getModel()
+ " "
+ currentDescriptor.getSectorsIn28bitAddressing() * IDEConstants.SECTOR_SIZE
+ ")");
}
}
}
}
private static final byte PLAIN_MASTER_BOOT_SECTOR[] =
{
(byte)0xEB,
(byte)0x48,
(byte)0x90,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x03,
(byte)0x02,
(byte)0xFF,
(byte)0x00,
(byte)0x00,
(byte)0x80,
(byte)0x01,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x08,
(byte)0xFA,
(byte)0xEA,
(byte)0x50,
(byte)0x7C,
(byte)0x00,
(byte)0x00,
(byte)0x31,
(byte)0xC0,
(byte)0x8E,
(byte)0xD8,
(byte)0x8E,
(byte)0xD0,
(byte)0xBC,
(byte)0x00,
(byte)0x20,
(byte)0xFB,
(byte)0xA0,
(byte)0x40,
(byte)0x7C,
(byte)0x3C,
(byte)0xFF,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?