blob: c7b145dd082431375b2483b5afd883310375578e [file] [log] [blame]
package org.apache.flex.utilities.converter.retrievers.download.utils.utils;
import org.apache.flex.utilities.converter.retrievers.download.utils.DmgExtractor;
import java.io.DataInputStream;
import java.io.IOException;
/**
* https://en.wikipedia.org/wiki/Apple_Partition_Map
*
* Created by christoferdutz on 25.02.16.
*/
public class ApplePartitionMap {
public static final int STATUS_ENTRY_IS_VALID = 0x00000001;
public static final int STATUS_ENTRY_IS_ALLOCATED = 0x00000002;
public static final int STATUS_ENTRY_IN_USE = 0x00000004;
public static final int STATUS_ENTRY_CONTAINS_BOOT_INFORMATION = 0x00000008;
public static final int STATUS_PARTITION_IS_READABLE = 0x00000010;
public static final int STATUS_PARTITION_IS_WRITABLE = 0x00000020;
public static final int STATUS_BOOT_CODE_IS_POSITION_INDEPENDENT = 0x00000040;
public static final int STATUS_PARTITION_CONTAINS_CHAIN_COMPATIBLE_DRIVER = 0x00000100;
public static final int STATUS_PARTITION_CONTAINS_A_REAL_DRIVER = 0x00000200;
public static final int STATUS_PARTITION_CONTAINS_A_CHAIN_DRIVER = 0x00000400;
public static final int STATUS_AUTOMATICALLY_MOUNT_AT_STARTUP = 0x40000000;
public static final int STATUS_THE_STARTUP_PARTITION = 0x80000000;
private int numPartitions;
private int startingSectorOfPartition;
private int sizeOfPartitionInSectors;
private String nameOfPartition;
private String typeOfPartition;
private int startingSectorOfDataAreaInPartition;
private int sizeOfDataAreaInPartitionInSectors;
private int statusOfPartition;
private int startingSectorOfBootCode;
private int sizeOfBootCodeInSectors;
private int addressOfBootloaderCode;
private int bootCodeEntryPoint;
private int bootCodeChecksum;
private String processorType;
public ApplePartitionMap(DataInputStream dis) {
// Initialize the fields by parsing the input bytes.
try {
if(dis.readShort() != 0x504D) {
throw new IllegalArgumentException("Invalid ApplePartitionMap data. Expected magic number 0x504D");
}
dis.skipBytes(2);
numPartitions = dis.readInt();
startingSectorOfPartition = dis.readInt();
sizeOfPartitionInSectors = dis.readInt();
byte[] buffer = new byte[32];
int readBytes = dis.read(buffer);
if(readBytes != 32) {
throw new IllegalArgumentException(
"Invalid ApplePartitionMap data. Expected to read 32 bytes for 'nameOfPartition'");
}
nameOfPartition = DmgExtractor.getStringFromZeroTerminatedByteArray(buffer);
buffer = new byte[32];
readBytes = dis.read(buffer);
if(readBytes != 32) {
throw new IllegalArgumentException(
"Invalid ApplePartitionMap data. Expected to read 32 bytes for 'typeOfPartition'");
}
typeOfPartition = DmgExtractor.getStringFromZeroTerminatedByteArray(buffer);
startingSectorOfDataAreaInPartition = dis.readInt();
sizeOfDataAreaInPartitionInSectors = dis.readInt();
statusOfPartition = dis.readInt();
startingSectorOfBootCode = dis.readInt();
sizeOfBootCodeInSectors = dis.readInt();
addressOfBootloaderCode = dis.readInt();
dis.skipBytes(4);
bootCodeEntryPoint = dis.readInt();
dis.skipBytes(4);
bootCodeChecksum = dis.readInt();
buffer = new byte[16];
readBytes = dis.read(buffer);
if(readBytes != 16) {
throw new IllegalArgumentException(
"Invalid ApplePartitionMap data. Expected to read 16 bytes for 'processorType'");
}
processorType = DmgExtractor.getStringFromZeroTerminatedByteArray(buffer);
dis.skipBytes(376);
} catch (IOException e) {
throw new IllegalArgumentException("Invalid DmgPropertyListMishBlock data.");
}
}
public int getNumPartitions() {
return numPartitions;
}
public int getStartingSectorOfPartition() {
return startingSectorOfPartition;
}
public int getSizeOfPartitionInSectors() {
return sizeOfPartitionInSectors;
}
public String getNameOfPartition() {
return nameOfPartition;
}
public String getTypeOfPartition() {
return typeOfPartition;
}
public int getStartingSectorOfDataAreaInPartition() {
return startingSectorOfDataAreaInPartition;
}
public int getSizeOfDataAreaInPartitionInSectors() {
return sizeOfDataAreaInPartitionInSectors;
}
public int getStatusOfPartition() {
return statusOfPartition;
}
public String getStatusOfPartitionName() {
StringBuilder sb = new StringBuilder();
if((statusOfPartition & STATUS_ENTRY_IS_VALID) != 0) {
sb.append(", Entry is valid");
}
if((statusOfPartition & STATUS_ENTRY_IS_ALLOCATED) != 0) {
sb.append(", Entry is allocated");
}
if((statusOfPartition & STATUS_ENTRY_IN_USE) != 0) {
sb.append(", Entry in use");
}
if((statusOfPartition & STATUS_ENTRY_CONTAINS_BOOT_INFORMATION) != 0) {
sb.append(", Entry contains boot information");
}
if((statusOfPartition & STATUS_PARTITION_IS_READABLE) != 0) {
sb.append(", Partition is readable");
}
if((statusOfPartition & STATUS_PARTITION_IS_WRITABLE) != 0) {
sb.append(", Partition is writable");
}
if((statusOfPartition & STATUS_BOOT_CODE_IS_POSITION_INDEPENDENT) != 0) {
sb.append(", Boot code is position independent");
}
if((statusOfPartition & STATUS_PARTITION_CONTAINS_CHAIN_COMPATIBLE_DRIVER) != 0) {
sb.append(", Partition contains chain-compatible driver");
}
if((statusOfPartition & STATUS_PARTITION_CONTAINS_A_REAL_DRIVER) != 0) {
sb.append(", Partition contains a real driver");
}
if((statusOfPartition & STATUS_PARTITION_CONTAINS_A_CHAIN_DRIVER) != 0) {
sb.append(", Partition contains a chain driver");
}
if((statusOfPartition & STATUS_AUTOMATICALLY_MOUNT_AT_STARTUP) != 0) {
sb.append(", Automatically mount at startup");
}
if((statusOfPartition & STATUS_THE_STARTUP_PARTITION) != 0) {
sb.append(", The startup partition");
}
if(sb.length() > 0) {
return sb.toString().substring(2);
}
return "- none -";
}
public int getStartingSectorOfBootCode() {
return startingSectorOfBootCode;
}
public int getSizeOfBootCodeInSectors() {
return sizeOfBootCodeInSectors;
}
public int getAddressOfBootloaderCode() {
return addressOfBootloaderCode;
}
public int getBootCodeEntryPoint() {
return bootCodeEntryPoint;
}
public int getBootCodeChecksum() {
return bootCodeChecksum;
}
public String getProcessorType() {
return processorType;
}
@Override
public String toString() {
return "ApplePartitionMap{" +
"numPartitions=" + numPartitions +
", startingSectorOfPartition=" + startingSectorOfPartition +
", sizeOfPartitionInSectors=" + sizeOfPartitionInSectors +
", nameOfPartition='" + nameOfPartition + '\'' +
", typeOfPartition='" + typeOfPartition + '\'' +
", startingSectorOfDataAreaInPartition=" + startingSectorOfDataAreaInPartition +
", sizeOfDataAreaInPartitionInSectors=" + sizeOfDataAreaInPartitionInSectors +
", statusOfPartition=" + statusOfPartition +
", startingSectorOfBootCode=" + startingSectorOfBootCode +
", sizeOfBootCodeInSectors=" + sizeOfBootCodeInSectors +
", addressOfBootloaderCode=" + addressOfBootloaderCode +
", bootCodeEntryPoint=" + bootCodeEntryPoint +
", bootCodeChecksum=" + bootCodeChecksum +
", processorType='" + processorType + '\'' +
'}';
}
}