2025-10-21 22:27:08 +02:00

393 lines
30 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// FAT filesystem implementation (FAT12/16 and FAT32)
// FAT filesystem implementation (FAT12/16 and FAT32 split)
import { BaseFilesystem } from './base.js';
import { checkDependencies, updateResultItem } from '../utils.js';
export class FAT12_16Filesystem extends BaseFilesystem {
calculate(variantId) {
if (variantId !== 'fat1216') return;
const values = {};
const results = {};
// Gather all input values for this variant
const variant = this.variants.find(v => v.id === variantId);
if (!variant) return;
[...variant.constants, ...variant.inputs].forEach(field => {
const el = document.getElementById(field.id);
if (el) {
let val = el.value;
if (val && val.startsWith('0x')) {
values[field.id] = parseInt(val, 16);
} else {
values[field.id] = Number(val) || 0;
}
}
});
this.calculateFAT1216(values, results);
}
constructor() {
super('FAT12/16', [
{
id: 'fat1216',
name: 'FAT12/16',
constants: [
{ id: 'baseOffset1216', label: 'Basis-Offset', unit: 'Bytes', default: '0x0' },
{ id: 'sectorSize1216', label: 'Sektor-Größe (Boot-Offset 0x0B)', unit: 'Bytes', default: '0x200' }
],
inputs: [
{ id: 'reservedSektoren1216', label: 'Reservierte Sektoren (Boot-Offset 0x0E)', unit: 'Anzahl', placeholder: '0x1' },
{ id: 'numFATs1216', label: 'Anzahl FATs (Boot-Offset 0x10)', unit: 'Anzahl', placeholder: '0x2' },
{ id: 'fatSizeSectors1216', label: 'FAT-Größe (Boot-Offset 0x16)', unit: 'Sektoren', placeholder: '0x4000' },
{ id: 'maxRootEntries1216', label: 'Max. Root-Einträge (Boot-Offset 0x11)', unit: 'Anzahl', placeholder: '0x200' },
{ id: 'partitionSizeInSectors1216', label: 'Partitionsgröße (Boot-Offset 0x13 oder 0x20)', unit: 'Sektoren', placeholder: '0x4015' },
{ id: 'clusterSizeSectors1216', label: 'Clustergröße (Boot-Offset 0x0D)', unit: 'Sektoren', placeholder: '0x2' },
{ id: 'clusterNumber1216', label: 'Cluster-Nummer', unit: 'Nummer', placeholder: '0x2' }
],
resultGroups: [
{
name: 'FAT-Struktur',
results: [
{ id: 'fatStart1216', label: 'FAT-Bereich Anfang', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216'], formula: 'reservedSektoren × sectorSize + baseOffset' },
{ id: 'fatSize1216', label: 'FAT-Bereich Größe', dependencies: ['numFATs1216', 'fatSizeSectors1216', 'sectorSize1216'], formula: 'numFATs × fatSizeSectors × sectorSize' },
{ id: 'fat2Start1216', label: 'FAT2 Anfang', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'fatSizeSectors1216'], formula: 'fatStart + (fatSizeSectors × sectorSize)' },
{ id: 'fatEnd1216', label: 'FAT-Bereich Ende', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216'], formula: 'fatStart + fatSize' }
]
},
{
name: 'Root-Directory',
results: [
{ id: 'rootDirStart1216', label: 'Root-Directory Anfang', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216'], formula: 'fatEnd' },
{ id: 'rootDirSize1216', label: 'Root-Directory Größe', dependencies: ['maxRootEntries1216'], formula: 'maxRootEntries × 0x20' }
]
},
{
name: 'Daten-Bereich',
results: [
{ id: 'dataStart1216', label: 'Daten-Bereich Anfang', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'], formula: 'fatEnd + rootDirSize' },
{ id: 'dataSize1216', label: 'Daten-Bereich Größe', dependencies: ['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSektoren1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'], formula: '(partitionSizeInSectors × sectorSize) - (dataStart - baseOffset)' },
{ id: 'clusterSize1216', label: 'Cluster-Größe', dependencies: ['sectorSize1216', 'clusterSizeSectors1216'], formula: 'sectorSize × clusterSizeSectors' },
{ id: 'numClusters1216', label: 'Anzahl Cluster', dependencies: ['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSektoren1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216'], formula: 'dataSize ÷ clusterSize' }
]
},
{
name: 'Spezifischer Cluster',
results: [
{ id: 'clusterStart1216', label: 'Cluster Anfang', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216', 'clusterNumber1216'], formula: 'dataStart + (clusterNumber - 0x2) × clusterSize' },
{ id: 'fatEntryPos1216', label: 'FAT-Eintrag Position (nur FAT16)', dependencies: ['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'clusterNumber1216'], formula: 'fatStart + (clusterNumber × 2) für FAT16' }
]
}
],
formulas: [
{ name: 'FAT-Bereich Anfang', expression: 'Reservierte Sektoren × Sektorgröße + Basis-Offset' },
{ name: 'FAT-Bereich Größe', expression: 'Anzahl FATs × FAT-Größe in Sektoren × Sektorgröße' },
{ name: 'FAT2 Anfang', expression: 'FAT-Bereich Anfang + FAT-Größe in Bytes' },
{ name: 'FAT-Bereich Ende', expression: 'FAT-Bereich Anfang + FAT-Bereich Größe' },
{ name: 'Root-Directory Größe', expression: 'Max. Root-Einträge × 0x20' },
{ name: 'Daten-Bereich Anfang', expression: 'FAT-Bereich Ende + Root-Directory Größe' },
{ name: 'Daten-Bereich Größe', expression: '(Partitionsgröße × Sektorgröße) - (Daten-Bereich Anfang - Basis-Offset)' },
{ name: 'Cluster-Größe', expression: 'Sektorgröße × Cluster-Größe in Sektoren' },
{ name: 'Anzahl Cluster', expression: 'Daten-Bereich Größe ÷ Cluster-Größe' },
{ name: 'Cluster Anfang', expression: 'Daten-Bereich Anfang + (Cluster-Nummer - 0x2) × Cluster-Größe' },
{ name: 'FAT-Eintrag Position', expression: 'FAT-Bereich Anfang + (Cluster-Nummer × Eintraggröße)' }
]
}
]);
}
calculateFAT1216(values, results) {
const suffix = '1216';
// FAT Start (show both bytes and sector in one row)
if (checkDependencies([`reservedSektoren${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`])) {
results.fatStart = values.reservedSektoren1216 * values.sectorSize1216 + values.baseOffset1216;
results.fatStartSector = Math.floor(results.fatStart / values.sectorSize1216);
updateResultItem(`fatStart${suffix}`, { bytes: results.fatStart, sectors: results.fatStartSector }, true,
`0x${values.reservedSektoren1216.toString(16)} × 0x${values.sectorSize1216.toString(16)} + 0x${values.baseOffset1216.toString(16)} = 0x${results.fatStart.toString(16)}`);
} else {
updateResultItem(`fatStart${suffix}`, 0, false);
}
// FAT Size (bytes and sectors)
if (checkDependencies([`numFATs${suffix}`, `fatSizeSectors${suffix}`, `sectorSize${suffix}`])) {
results.fatSize = values.numFATs1216 * values.fatSizeSectors1216 * values.sectorSize1216;
results.fatSizeSectors = values.numFATs1216 * values.fatSizeSectors1216;
updateResultItem(`fatSize${suffix}`, { bytes: results.fatSize, sectors: results.fatSizeSectors }, true,
`0x${values.numFATs1216.toString(16)} × 0x${values.fatSizeSectors1216.toString(16)} × 0x${values.sectorSize1216.toString(16)} = 0x${results.fatSize.toString(16)}`);
} else {
updateResultItem(`fatSize${suffix}`, 0, false);
}
// FAT2 Start (bytes and sector)
if (checkDependencies([`reservedSektoren${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `fatSizeSectors${suffix}`]) && results.fatStart !== undefined) {
results.fat2Start = results.fatStart + (values.fatSizeSectors1216 * values.sectorSize1216);
results.fat2StartSector = Math.floor(results.fat2Start / values.sectorSize1216);
updateResultItem(`fat2Start${suffix}`, { bytes: results.fat2Start, sectors: results.fat2StartSector }, true,
`0x${results.fatStart.toString(16)} + 0x${(values.fatSizeSectors1216 * values.sectorSize1216).toString(16)} = 0x${results.fat2Start.toString(16)}`);
} else {
updateResultItem(`fat2Start${suffix}`, 0, false);
}
// FAT End (bytes and sector)
if (results.fatStart !== undefined && results.fatSize !== undefined) {
results.fatEnd = results.fatStart + results.fatSize;
results.fatEndSector = Math.floor(results.fatEnd / values.sectorSize1216);
updateResultItem(`fatEnd${suffix}`, { bytes: results.fatEnd, sectors: results.fatEndSector }, true,
`0x${results.fatStart.toString(16)} + 0x${results.fatSize.toString(16)} = 0x${results.fatEnd.toString(16)}`);
} else {
updateResultItem(`fatEnd${suffix}`, 0, false);
}
// Root Directory Size
if (checkDependencies(['maxRootEntries1216'])) {
results.rootDirSize = values.maxRootEntries1216 * 0x20;
updateResultItem('rootDirSize1216', results.rootDirSize, true,
`0x${values.maxRootEntries1216.toString(16)} × 0x20 = 0x${results.rootDirSize.toString(16)}`);
} else {
updateResultItem('rootDirSize1216', 0, false);
}
// Root Directory Start (bytes and sector)
if (results.fatEnd !== undefined) {
results.rootDirStart = results.fatEnd;
results.rootDirStartSector = Math.floor(results.rootDirStart / values.sectorSize1216);
updateResultItem('rootDirStart1216', { bytes: results.rootDirStart, sectors: results.rootDirStartSector }, true,
`0x${results.fatEnd.toString(16)}`);
} else {
updateResultItem('rootDirStart1216', 0, false);
}
// Data Start (bytes and sector)
if (results.fatEnd !== undefined && results.rootDirSize !== undefined) {
results.dataStart = results.fatEnd + results.rootDirSize;
results.dataStartSector = Math.floor(results.dataStart / values.sectorSize1216);
updateResultItem('dataStart1216', { bytes: results.dataStart, sectors: results.dataStartSector }, true,
`0x${results.fatEnd.toString(16)} + 0x${results.rootDirSize.toString(16)} = 0x${results.dataStart.toString(16)}`);
} else {
updateResultItem('dataStart1216', 0, false);
}
// Data Size (Daten-Bereich Größe)
if (checkDependencies(['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSektoren1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216'])) {
// RootDirGröße in Sektoren = Math.ceil(maxRootEntries × 32 / sectorSize)
const rootDirSectors = Math.ceil((values.maxRootEntries1216 * 32) / values.sectorSize1216);
const dataAreaSectors = values.partitionSizeInSectors1216 - (values.reservedSektoren1216 + (values.numFATs1216 * values.fatSizeSectors1216) + rootDirSectors);
results.dataSize = dataAreaSectors * values.sectorSize1216;
results.dataAreaSectors = dataAreaSectors;
updateResultItem('dataSize1216', results.dataSize, true,
`(${values.partitionSizeInSectors1216} - (${values.reservedSektoren1216} + (${values.numFATs1216} × ${values.fatSizeSectors1216}) + ${rootDirSectors})) × ${values.sectorSize1216} = ${results.dataSize}`);
} else {
updateResultItem('dataSize1216', 0, false);
}
// Cluster Size
if (checkDependencies(['sectorSize1216', 'clusterSizeSectors1216'])) {
results.clusterSize = values.sectorSize1216 * values.clusterSizeSectors1216;
updateResultItem('clusterSize1216', results.clusterSize, true,
`0x${values.sectorSize1216.toString(16)} × 0x${values.clusterSizeSectors1216.toString(16)} = 0x${results.clusterSize.toString(16)}`);
} else {
updateResultItem('clusterSize1216', 0, false);
}
// Number of Clusters (Anzahl Cluster)
if (checkDependencies(['partitionSizeInSectors1216', 'sectorSize1216', 'reservedSektoren1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216']) && results.dataAreaSectors !== undefined && values.clusterSizeSectors1216 > 0) {
results.numClusters = Math.floor(results.dataAreaSectors / values.clusterSizeSectors1216);
updateResultItem('numClusters1216', results.numClusters, true,
`${results.dataAreaSectors} ÷ ${values.clusterSizeSectors1216} = ${results.numClusters}`);
} else {
updateResultItem('numClusters1216', 0, false);
}
// Specific Cluster Start (bytes and sector)
if (checkDependencies(['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'numFATs1216', 'fatSizeSectors1216', 'maxRootEntries1216', 'clusterSizeSectors1216', 'clusterNumber1216']) && results.dataStart !== undefined && results.clusterSize !== undefined) {
results.clusterStart = results.dataStart + (values.clusterNumber1216 - 0x2) * results.clusterSize;
results.clusterStartSector = Math.floor(results.clusterStart / values.sectorSize1216);
updateResultItem('clusterStart1216', { bytes: results.clusterStart, sectors: results.clusterStartSector }, true,
`0x${results.dataStart.toString(16)} + (0x${values.clusterNumber1216.toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.clusterStart.toString(16)}`);
} else {
updateResultItem('clusterStart1216', 0, false);
}
// FAT Entry Position (FAT16 only)
if (checkDependencies(['reservedSektoren1216', 'sectorSize1216', 'baseOffset1216', 'clusterNumber1216']) && results.fatStart !== undefined) {
const entrySize = 2; // FAT16 uses 2 bytes per entry
results.fatEntryPos = results.fatStart + (values.clusterNumber1216 * entrySize);
updateResultItem('fatEntryPos1216', results.fatEntryPos, true,
`0x${results.fatStart.toString(16)} + (0x${values.clusterNumber1216.toString(16)} × ${entrySize}) = 0x${results.fatEntryPos.toString(16)}`);
} else {
updateResultItem('fatEntryPos1216', 0, false);
}
}
}
export class FAT32Filesystem extends BaseFilesystem {
calculate(variantId) {
if (variantId !== 'fat32') return;
const values = {};
const results = {};
// Gather all input values for this variant
const variant = this.variants.find(v => v.id === variantId);
if (!variant) return;
[...variant.constants, ...variant.inputs].forEach(field => {
const el = document.getElementById(field.id);
if (el) {
let val = el.value;
if (val && val.startsWith('0x')) {
values[field.id] = parseInt(val, 16);
} else {
values[field.id] = Number(val) || 0;
}
}
});
this.calculateFAT32(values, results);
}
constructor() {
super('FAT32', [
{
id: 'fat32',
name: 'FAT32',
constants: [
{ id: 'baseOffset32', label: 'Basis-Offset', unit: 'Bytes', default: '0x0' },
{ id: 'sectorSize32', label: 'Sektor-Größe (Boot-Offset 0x0B)', unit: 'Bytes', default: '0x200' }
],
inputs: [
{ id: 'reservedSectors32', label: 'Reservierte Sektoren (Boot-Offset 0x0E)', unit: 'Anzahl', placeholder: '0x20' },
{ id: 'numFATs32', label: 'Anzahl FATs (Boot-Offset 0x10)', unit: 'Anzahl', placeholder: '0x2' },
{ id: 'fatSizeSectors32', label: 'FAT-Größe (Boot-Offset 0x24)', unit: 'Sektoren', placeholder: '0x20000' },
{ id: 'rootDirCluster32', label: 'Root-Directory Cluster (Boot-Offset 0x2C)', unit: 'Nummer', placeholder: '0x2' },
{ id: 'partitionSizeInSectors32', label: 'Partitionsgröße (Boot-Offset 0x20)', unit: 'Sektoren', placeholder: '0x100000' },
{ id: 'clusterSizeSectors32', label: 'Clustergröße (Boot-Offset 0x0D)', unit: 'Sektoren', placeholder: '0x8' },
{ id: 'clusterNumber32', label: 'Cluster-Nummer', unit: 'Nummer', placeholder: '0x2' }
],
resultGroups: [
{
name: 'FAT-Struktur',
results: [
{ id: 'fatStart32', label: 'FAT-Bereich Anfang', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32'], formula: 'reservedSectors × sectorSize + baseOffset' },
{ id: 'fatSize32', label: 'FAT-Bereich Größe', dependencies: ['numFATs32', 'fatSizeSectors32', 'sectorSize32'], formula: 'numFATs × fatSizeSectors × sectorSize' },
{ id: 'fat2Start32', label: 'FAT2 Anfang', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'fatSizeSectors32'], formula: 'fatStart + (fatSizeSectors × sectorSize)' },
{ id: 'fatEnd32', label: 'FAT-Bereich Ende', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: 'fatStart + fatSize' }
]
},
{
name: 'Daten-Bereich',
results: [
{ id: 'dataStart32', label: 'Daten-Bereich Anfang', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: 'fatEnd' },
{ id: 'dataSize32', label: 'Daten-Bereich Größe', dependencies: ['partitionSizeInSectors32', 'sectorSize32', 'reservedSectors32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32'], formula: '(partitionSizeInSectors × sectorSize) - (dataStart - baseOffset)' },
{ id: 'clusterSize32', label: 'Cluster-Größe', dependencies: ['sectorSize32', 'clusterSizeSectors32'], formula: 'sectorSize × clusterSizeSectors' },
{ id: 'numClusters32', label: 'Anzahl Cluster', dependencies: ['partitionSizeInSectors32', 'sectorSize32', 'reservedSectors32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32'], formula: 'dataSize ÷ clusterSize' }
]
},
{
name: 'Spezifischer Cluster',
results: [
{ id: 'clusterStart32', label: 'Cluster Anfang', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32', 'clusterNumber32'], formula: 'dataStart + (clusterNumber - 0x2) × clusterSize' },
{ id: 'fatEntryPos32', label: 'FAT-Eintrag Position', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'clusterNumber32'], formula: 'fatStart + (clusterNumber × 4)' },
{ id: 'rootDirPos32', label: 'Root-Directory Position', dependencies: ['reservedSectors32', 'sectorSize32', 'baseOffset32', 'numFATs32', 'fatSizeSectors32', 'clusterSizeSectors32', 'rootDirCluster32'], formula: 'dataStart + (rootDirCluster - 0x2) × clusterSize' }
]
}
],
formulas: [
{ name: 'FAT-Bereich Anfang', expression: 'Reservierte Sektoren × Sektorgröße + Basis-Offset' },
{ name: 'FAT-Bereich Größe', expression: 'Anzahl FATs × FAT-Größe in Sektoren × Sektorgröße' },
{ name: 'FAT2 Anfang', expression: 'FAT-Bereich Anfang + FAT-Größe in Bytes' },
{ name: 'FAT-Bereich Ende', expression: 'FAT-Bereich Anfang + FAT-Bereich Größe' },
{ name: 'Daten-Bereich Anfang', expression: 'FAT-Bereich Ende (kein festes Root Directory)' },
{ name: 'Daten-Bereich Größe', expression: '(Partitionsgröße × Sektorgröße) - (Daten-Bereich Anfang - Basis-Offset)' },
{ name: 'Cluster-Größe', expression: 'Sektorgröße × Cluster-Größe in Sektoren' },
{ name: 'Anzahl Cluster', expression: 'Daten-Bereich Größe ÷ Cluster-Größe' },
{ name: 'Cluster Anfang', expression: 'Daten-Bereich Anfang + (Cluster-Nummer - 0x2) × Cluster-Größe' },
{ name: 'FAT-Eintrag Position', expression: 'FAT-Bereich Anfang + (Cluster-Nummer × 4)' },
{ name: 'Root-Directory Position', expression: 'Daten-Bereich Anfang + (Root-Directory Cluster - 0x2) × Cluster-Größe' }
]
}
]);
}
calculateFAT32(values, results) {
const suffix = '32';
// FAT Start (show both bytes and sector in one row)
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`])) {
results.fatStart = values[`reservedSectors${suffix}`] * values[`sectorSize${suffix}`] + values[`baseOffset${suffix}`];
results.fatStartSector = Math.floor(results.fatStart / values[`sectorSize${suffix}`]);
updateResultItem(`fatStart${suffix}`, { bytes: results.fatStart, sectors: results.fatStartSector }, true,
`0x${values[`reservedSectors${suffix}`].toString(16)} × 0x${values[`sectorSize${suffix}`].toString(16)} + 0x${values[`baseOffset${suffix}`].toString(16)} = 0x${results.fatStart.toString(16)}`);
} else {
updateResultItem(`fatStart${suffix}`, 0, false);
}
// FAT Size (bytes and sectors)
if (checkDependencies([`numFATs${suffix}`, `fatSizeSectors${suffix}`, `sectorSize${suffix}`])) {
results.fatSize = values[`numFATs${suffix}`] * values[`fatSizeSectors${suffix}`] * values[`sectorSize${suffix}`];
results.fatSizeSectors = values[`numFATs${suffix}`] * values[`fatSizeSectors${suffix}`];
updateResultItem(`fatSize${suffix}`, { bytes: results.fatSize, sectors: results.fatSizeSectors }, true,
`0x${values[`numFATs${suffix}`].toString(16)} × 0x${values[`fatSizeSectors${suffix}`].toString(16)} × 0x${values[`sectorSize${suffix}`].toString(16)} = 0x${results.fatSize.toString(16)}`);
} else {
updateResultItem(`fatSize${suffix}`, 0, false);
}
// FAT2 Start (bytes and sector)
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `fatSizeSectors${suffix}`]) && results.fatStart !== undefined) {
results.fat2Start = results.fatStart + (values[`fatSizeSectors${suffix}`] * values[`sectorSize${suffix}`]);
results.fat2StartSector = Math.floor(results.fat2Start / values[`sectorSize${suffix}`]);
updateResultItem(`fat2Start${suffix}`, { bytes: results.fat2Start, sectors: results.fat2StartSector }, true,
`0x${results.fatStart.toString(16)} + 0x${(values[`fatSizeSectors${suffix}`] * values[`sectorSize${suffix}`]).toString(16)} = 0x${results.fat2Start.toString(16)}`);
} else {
updateResultItem(`fat2Start${suffix}`, 0, false);
}
// FAT End (bytes and sector)
if (results.fatStart !== undefined && results.fatSize !== undefined) {
results.fatEnd = results.fatStart + results.fatSize;
results.fatEndSector = Math.floor(results.fatEnd / values[`sectorSize${suffix}`]);
updateResultItem(`fatEnd${suffix}`, { bytes: results.fatEnd, sectors: results.fatEndSector }, true,
`0x${results.fatStart.toString(16)} + 0x${results.fatSize.toString(16)} = 0x${results.fatEnd.toString(16)}`);
} else {
updateResultItem(`fatEnd${suffix}`, 0, false);
}
// Data Start (bytes and sector)
if (results.fatEnd !== undefined) {
results.dataStart = results.fatEnd;
results.dataStartSector = Math.floor(results.dataStart / values[`sectorSize${suffix}`]);
updateResultItem(`dataStart${suffix}`, { bytes: results.dataStart, sectors: results.dataStartSector }, true,
`0x${results.fatEnd.toString(16)}`);
} else {
updateResultItem(`dataStart${suffix}`, 0, false);
}
// Data Size
if (checkDependencies([`partitionSizeInSectors${suffix}`, `sectorSize${suffix}`, `reservedSectors${suffix}`, `baseOffset${suffix}`, `numFATs${suffix}`, `fatSizeSectors${suffix}`]) && results.dataStart !== undefined) {
results.dataSize = (values[`partitionSizeInSectors${suffix}`] * values[`sectorSize${suffix}`]) - (results.dataStart - values[`baseOffset${suffix}`]);
updateResultItem(`dataSize${suffix}`, results.dataSize, true,
`(0x${values[`partitionSizeInSectors${suffix}`].toString(16)} × 0x${values[`sectorSize${suffix}`].toString(16)}) - (0x${results.dataStart.toString(16)} - 0x${values[`baseOffset${suffix}`].toString(16)}) = 0x${results.dataSize.toString(16)}`);
} else {
updateResultItem(`dataSize${suffix}`, 0, false);
}
// Cluster Size
if (checkDependencies([`sectorSize${suffix}`, `clusterSizeSectors${suffix}`])) {
results.clusterSize = values[`sectorSize${suffix}`] * values[`clusterSizeSectors${suffix}`];
updateResultItem(`clusterSize${suffix}`, results.clusterSize, true,
`0x${values[`sectorSize${suffix}`].toString(16)} × 0x${values[`clusterSizeSectors${suffix}`].toString(16)} = 0x${results.clusterSize.toString(16)}`);
} else {
updateResultItem(`clusterSize${suffix}`, 0, false);
}
// Number of Clusters
if (checkDependencies([`partitionSizeInSectors${suffix}`, `sectorSize${suffix}`, `reservedSectors${suffix}`, `baseOffset${suffix}`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, `clusterSizeSectors${suffix}`]) && results.dataSize !== undefined && results.clusterSize !== undefined) {
results.numClusters = Math.floor(results.dataSize / results.clusterSize);
updateResultItem(`numClusters${suffix}`, results.numClusters, true,
`0x${results.dataSize.toString(16)} ÷ 0x${results.clusterSize.toString(16)} = 0x${results.numClusters.toString(16)}`);
} else {
updateResultItem(`numClusters${suffix}`, 0, false);
}
// Specific Cluster Start (bytes and sector)
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, `clusterSizeSectors${suffix}`, `clusterNumber${suffix}`]) && results.dataStart !== undefined && results.clusterSize !== undefined) {
results.clusterStart = results.dataStart + (values[`clusterNumber${suffix}`] - 0x2) * results.clusterSize;
results.clusterStartSector = Math.floor(results.clusterStart / values[`sectorSize${suffix}`]);
updateResultItem(`clusterStart${suffix}`, { bytes: results.clusterStart, sectors: results.clusterStartSector }, true,
`0x${results.dataStart.toString(16)} + (0x${values[`clusterNumber${suffix}`].toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.clusterStart.toString(16)}`);
} else {
updateResultItem(`clusterStart${suffix}`, 0, false);
}
// FAT Entry Position
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `clusterNumber${suffix}`]) && results.fatStart !== undefined) {
const entrySize = 4; // FAT32 uses 4 bytes per entry
results.fatEntryPos = results.fatStart + (values[`clusterNumber${suffix}`] * entrySize);
updateResultItem(`fatEntryPos${suffix}`, results.fatEntryPos, true,
`0x${results.fatStart.toString(16)} + (0x${values[`clusterNumber${suffix}`].toString(16)} × ${entrySize}) = 0x${results.fatEntryPos.toString(16)}`);
} else {
updateResultItem(`fatEntryPos${suffix}`, 0, false);
}
// Root Directory Position (FAT32 specific)
if (checkDependencies([`reservedSectors${suffix}`, `sectorSize${suffix}`, `baseOffset${suffix}`, `numFATs${suffix}`, `fatSizeSectors${suffix}`, `clusterSizeSectors${suffix}`, `rootDirCluster${suffix}`]) && results.dataStart !== undefined && results.clusterSize !== undefined) {
results.rootDirPos = results.dataStart + (values[`rootDirCluster${suffix}`] - 0x2) * results.clusterSize;
updateResultItem(`rootDirPos${suffix}`, results.rootDirPos, true,
`0x${results.dataStart.toString(16)} + (0x${values[`rootDirCluster${suffix}`].toString(16)} - 0x2) × 0x${results.clusterSize.toString(16)} = 0x${results.rootDirPos.toString(16)}`);
} else {
updateResultItem(`rootDirPos${suffix}`, 0, false);
}
}
}