Fixed root directory check to ensure we don't select a disk format with too few root directory entries
This commit is contained in:
parent
fb57561660
commit
4e0d3d46da
2 changed files with 23 additions and 27 deletions
|
|
@ -961,13 +961,13 @@ DiskDump.updateManifest = function(disk, sManifestFile, sDiskPath, sOutputFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sIDDisk) {
|
if (!sIDDisk) {
|
||||||
for (i = 1; i < 1000; i++) {
|
for (i = 1; i < 10000; i++) {
|
||||||
sIDDisk = i.toString();
|
sIDDisk = i.toString();
|
||||||
if (sIDDisk.length < 2) sIDDisk = '0' + sIDDisk;
|
if (sIDDisk.length < 2) sIDDisk = '0' + sIDDisk;
|
||||||
sIDDisk = "disk" + sIDDisk;
|
sIDDisk = "disk" + sIDDisk;
|
||||||
if (sXML.indexOf(' id="' + sIDDisk + '"') < 0) break;
|
if (sXML.indexOf(' id="' + sIDDisk + '"') < 0) break;
|
||||||
}
|
}
|
||||||
if (i == 1000) {
|
if (i == 10000) {
|
||||||
err = new Error("manifest already contains " + i + " disks");
|
err = new Error("manifest already contains " + i + " disks");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2408,24 +2408,25 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
*/
|
*/
|
||||||
for (var iBPB = 0; iBPB < DiskDump.aDefaultBPBs.length; iBPB++) {
|
for (var iBPB = 0; iBPB < DiskDump.aDefaultBPBs.length; iBPB++) {
|
||||||
/*
|
/*
|
||||||
* Use slice() to copy the default BPB, as a precaution (to avoid any changes to the default).
|
* Use slice() to copy the BPB, to ensure we don't alter the original.
|
||||||
*/
|
*/
|
||||||
abBoot = DiskDump.aDefaultBPBs[iBPB].slice();
|
abBoot = DiskDump.aDefaultBPBs[iBPB].slice();
|
||||||
/*
|
/*
|
||||||
* If this BPB is for a hard drive but a disk size was not specified, skip it.
|
* If this BPB is for a hard drive but a disk size was not specified, skip it.
|
||||||
*/
|
*/
|
||||||
if ((abBoot[0x15] == 0xF8) != (this.kbTarget >= 10000)) continue;
|
if ((abBoot[DiskAPI.BPB.MEDIA_TYPE] == DiskAPI.FAT.MEDIA_FIXED) != (this.kbTarget >= 10000)) continue;
|
||||||
cbSector = abBoot[0x0B] | (abBoot[0x0C] << 8);
|
cRootEntries = abBoot[DiskAPI.BPB.ROOT_DIRENTS] | (abBoot[DiskAPI.BPB.ROOT_DIRENTS + 1] << 8);
|
||||||
cSectorsPerCluster = abBoot[0x0D];
|
if (aFiles.length > cRootEntries) continue;
|
||||||
|
cbSector = abBoot[DiskAPI.BPB.SECTOR_BYTES] | (abBoot[DiskAPI.BPB.SECTOR_BYTES + 1] << 8);
|
||||||
|
cSectorsPerCluster = abBoot[DiskAPI.BPB.CLUSTER_SECS];
|
||||||
cbCluster = cbSector * cSectorsPerCluster;
|
cbCluster = cbSector * cSectorsPerCluster;
|
||||||
cFATs = abBoot[0x10];
|
cFATs = abBoot[DiskAPI.BPB.TOTAL_FATS];
|
||||||
cFATSectors = abBoot[0x16] | (abBoot[0x17] << 8);
|
cFATSectors = abBoot[DiskAPI.BPB.FAT_SECS] | (abBoot[DiskAPI.BPB.FAT_SECS + 1] << 8);
|
||||||
cRootEntries = abBoot[0x11] | (abBoot[0x12] << 8);
|
cRootSectors = (((cRootEntries * DiskAPI.DIRENT.LENGTH) + cbSector - 1) / cbSector) | 0;
|
||||||
cRootSectors = (((cRootEntries * 0x20) + cbSector - 1) / cbSector) | 0;
|
cTotalSectors = abBoot[DiskAPI.BPB.TOTAL_SECS] | (abBoot[DiskAPI.BPB.TOTAL_SECS + 1] << 8);
|
||||||
cTotalSectors = abBoot[0x13] | (abBoot[0x14] << 8);
|
cSectorsPerTrack = abBoot[DiskAPI.BPB.TRACK_SECS] | (abBoot[DiskAPI.BPB.TRACK_SECS + 1] << 8);
|
||||||
cSectorsPerTrack = abBoot[0x18] | (abBoot[0x19] << 8);
|
cHeads = abBoot[DiskAPI.BPB.TOTAL_HEADS] | (abBoot[DiskAPI.BPB.TOTAL_HEADS + 1] << 8);
|
||||||
cHeads = abBoot[0x1A] | (abBoot[0x1B] << 8);
|
cDataSectors = cTotalSectors - (cRootSectors + cFATs * cFATSectors + 1);
|
||||||
cDataSectors = cTotalSectors - cRootSectors - cFATs * cFATSectors + 1;
|
|
||||||
cbAvail = cDataSectors * cbSector;
|
cbAvail = cDataSectors * cbSector;
|
||||||
if (!nTargetSectors) {
|
if (!nTargetSectors) {
|
||||||
if (cbTotal <= cbAvail) {
|
if (cbTotal <= cbAvail) {
|
||||||
|
|
@ -2441,13 +2442,7 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iBPB == DiskDump.aDefaultBPBs.length) {
|
if (iBPB == DiskDump.aDefaultBPBs.length) {
|
||||||
err = new Error("file(s) too large for disk image (" + cbTotal + " vs. " + cbAvail + " bytes)");
|
err = new Error("too many file(s) for disk image (" + aFiles.length + " files, " + cbTotal + " bytes)");
|
||||||
done(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFiles.length > cRootEntries) {
|
|
||||||
err = new Error("too many files for disk image (" + aFiles.length + " vs. " + cRootEntries + " max)");
|
|
||||||
done(err);
|
done(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2481,8 +2476,8 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
/*
|
/*
|
||||||
* Output a boot sector.
|
* Output a boot sector.
|
||||||
*/
|
*/
|
||||||
abBoot[DiskAPI.BOOT.SIG_OFFSET] = 0x55;
|
abBoot[DiskAPI.BOOT.SIG_OFFSET] = DiskAPI.BOOT.SIGNATURE & 0xff; // 0x55
|
||||||
abBoot[DiskAPI.BOOT.SIG_OFFSET + 1] = 0xAA;
|
abBoot[DiskAPI.BOOT.SIG_OFFSET + 1] = (DiskAPI.BOOT.SIGNATURE >> 8) & 0xff; // 0xAA
|
||||||
abSector = this.buildData(cbSector, abBoot);
|
abSector = this.buildData(cbSector, abBoot);
|
||||||
offDisk += this.copyData(offDisk, abSector);
|
offDisk += this.copyData(offDisk, abSector);
|
||||||
|
|
||||||
|
|
@ -2493,7 +2488,7 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
* BPB at offset 0x15. For old BPB-less diskettes, this is where you must look for the media type.
|
* BPB at offset 0x15. For old BPB-less diskettes, this is where you must look for the media type.
|
||||||
*/
|
*/
|
||||||
var abFAT = [];
|
var abFAT = [];
|
||||||
this.buildFATEntry(abFAT, 0, abBoot[0x15] | 0xF00);
|
this.buildFATEntry(abFAT, 0, abBoot[DiskAPI.BPB.MEDIA_TYPE] | 0xF00);
|
||||||
this.buildFATEntry(abFAT, 1, 0xFFF);
|
this.buildFATEntry(abFAT, 1, 0xFFF);
|
||||||
this.buildFAT(abFAT, aFiles, 2, cbCluster);
|
this.buildFAT(abFAT, aFiles, 2, cbCluster);
|
||||||
|
|
||||||
|
|
@ -2516,10 +2511,10 @@ DiskDump.prototype.buildImageFromFiles = function(aFiles, done)
|
||||||
* PC-DOS 1.0 requires ALL unused directory entries to start with 0xE5; 0x00 isn't good enough,
|
* PC-DOS 1.0 requires ALL unused directory entries to start with 0xE5; 0x00 isn't good enough,
|
||||||
* so we must loop through all the remaining directory entries and zap them with 0xE5.
|
* so we must loop through all the remaining directory entries and zap them with 0xE5.
|
||||||
*/
|
*/
|
||||||
var offRoot = cEntries * 32;
|
var offRoot = cEntries * DiskAPI.DIRENT.LENGTH;
|
||||||
while (cEntries++ < cRootEntries) {
|
while (cEntries++ < cRootEntries) {
|
||||||
abRoot[offRoot] = 0xE5;
|
abRoot[offRoot] = DiskAPI.DIRENT.INVALID; // 0xE5
|
||||||
offRoot += 32;
|
offRoot += DiskAPI.DIRENT.LENGTH; // 0x20 (32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@ DiskAPI.FAT = {
|
||||||
MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track
|
MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track
|
||||||
MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track
|
MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track
|
||||||
MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track
|
MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track
|
||||||
|
MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)
|
||||||
MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track
|
MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track
|
||||||
MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track
|
MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue