summaryrefslogtreecommitdiff
path: root/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java')
-rw-r--r--src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java b/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java
new file mode 100644
index 0000000..eded7ee
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+
+/**
+ * Contains the FAT32 specific parts of the boot sector.
+ *
+ * @author Matthias Treydte &lt;matthias.treydte at meetwise.com&gt;
+ */
+final class Fat32BootSector extends BootSector {
+
+ /**
+ * The offset to the entry specifying the first cluster of the FAT32
+ * root directory.
+ */
+ public final static int ROOT_DIR_FIRST_CLUSTER_OFFSET = 0x2c;
+
+ /**
+ * The offset to the 4 bytes specifying the sectors per FAT value.
+ */
+ public static final int SECTORS_PER_FAT_OFFSET = 0x24;
+
+ /**
+ * Offset to the file system type label.
+ */
+ public static final int FILE_SYSTEM_TYPE_OFFSET = 0x52;
+
+ public static final int VERSION_OFFSET = 0x2a;
+ public static final int VERSION = 0;
+
+ public static final int FS_INFO_SECTOR_OFFSET = 0x30;
+ public static final int BOOT_SECTOR_COPY_OFFSET = 0x32;
+ public static final int EXTENDED_BOOT_SIGNATURE_OFFSET = 0x42;
+
+ /*
+ * TODO: make this constructor private
+ */
+ public Fat32BootSector(BlockDevice device) throws IOException {
+ super(device);
+ }
+
+ @Override
+ public void init() throws IOException {
+ super.init();
+
+ set16(VERSION_OFFSET, VERSION);
+
+ setBootSectorCopySector(6); /* as suggested by M$ */
+ }
+
+ /**
+ * Returns the first cluster in the FAT that contains the root directory.
+ *
+ * @return the root directory's first cluster
+ */
+ public long getRootDirFirstCluster() {
+ return get32(ROOT_DIR_FIRST_CLUSTER_OFFSET);
+ }
+
+ /**
+ * Sets the first cluster of the root directory.
+ *
+ * @param value the root directory's first cluster
+ */
+ public void setRootDirFirstCluster(long value) {
+ if (getRootDirFirstCluster() == value) return;
+
+ set32(ROOT_DIR_FIRST_CLUSTER_OFFSET, value);
+ }
+
+ /**
+ * Sets the sectur number that contains a copy of the boot sector.
+ *
+ * @param sectNr the sector that contains a boot sector copy
+ */
+ public void setBootSectorCopySector(int sectNr) {
+ if (getBootSectorCopySector() == sectNr) return;
+ if (sectNr < 0) throw new IllegalArgumentException(
+ "boot sector copy sector must be >= 0");
+
+ set16(BOOT_SECTOR_COPY_OFFSET, sectNr);
+ }
+
+ /**
+ * Returns the sector that contains a copy of the boot sector, or 0 if
+ * there is no copy.
+ *
+ * @return the sector number of the boot sector copy
+ */
+ public int getBootSectorCopySector() {
+ return get16(BOOT_SECTOR_COPY_OFFSET);
+ }
+
+ /**
+ * Sets the 11-byte volume label stored at offset 0x47.
+ *
+ * @param label the new volume label, may be {@code null}
+ */
+ public void setVolumeLabel(String label) {
+ for (int i=0; i < 11; i++) {
+ final byte c =
+ (label == null) ? 0 :
+ (label.length() > i) ? (byte) label.charAt(i) : 0x20;
+
+ set8(0x47 + i, c);
+ }
+ }
+
+ public int getFsInfoSectorNr() {
+ return get16(FS_INFO_SECTOR_OFFSET);
+ }
+
+ public void setFsInfoSectorNr(int offset) {
+ if (getFsInfoSectorNr() == offset) return;
+
+ set16(FS_INFO_SECTOR_OFFSET, offset);
+ }
+
+ @Override
+ public void setSectorsPerFat(long v) {
+ if (getSectorsPerFat() == v) return;
+
+ set32(SECTORS_PER_FAT_OFFSET, v);
+ }
+
+ @Override
+ public long getSectorsPerFat() {
+ return get32(SECTORS_PER_FAT_OFFSET);
+ }
+
+ @Override
+ public FatType getFatType() {
+ return FatType.FAT32;
+ }
+
+ @Override
+ public void setSectorCount(long count) {
+ super.setNrTotalSectors(count);
+ }
+
+ @Override
+ public long getSectorCount() {
+ return super.getNrTotalSectors();
+ }
+
+ /**
+ * This is always 0 for FAT32.
+ *
+ * @return always 0
+ */
+ @Override
+ public int getRootDirEntryCount() {
+ return 0;
+ }
+
+ public void setFileSystemId(int id) {
+ super.set32(0x43, id);
+ }
+
+ public int getFileSystemId() {
+ return (int) super.get32(0x43);
+ }
+
+ /**
+ * Writes a copy of this boot sector to the specified device, if a copy
+ * is requested.
+ *
+ * @param device the device to write the boot sector copy to
+ * @throws IOException on write error
+ * @see #getBootSectorCopySector()
+ */
+ public void writeCopy(BlockDevice device) throws IOException {
+ if (getBootSectorCopySector() > 0) {
+ final long offset = getBootSectorCopySector() * SIZE;
+ buffer.rewind();
+ buffer.limit(buffer.capacity());
+ device.write(offset, buffer);
+ }
+ }
+
+ @Override
+ public int getFileSystemTypeLabelOffset() {
+ return FILE_SYSTEM_TYPE_OFFSET;
+ }
+
+ @Override
+ public int getExtendedBootSignatureOffset() {
+ return EXTENDED_BOOT_SIGNATURE_OFFSET;
+ }
+}