Allow partial unpacking of corrupt NuFX disks

This commit is contained in:
Denis Molony 2021-05-13 14:56:56 +10:00
parent 90f8657722
commit a72bdff81d
7 changed files with 70 additions and 31 deletions

View File

@ -19,6 +19,7 @@ import com.bytezone.diskbrowser.nib.WozFile;
import com.bytezone.diskbrowser.utilities.Binary2; import com.bytezone.diskbrowser.utilities.Binary2;
import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.NuFX; import com.bytezone.diskbrowser.utilities.NuFX;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
public class AppleDisk implements Disk public class AppleDisk implements Disk
@ -42,6 +43,8 @@ public class AppleDisk implements Disk
private NuFX nuFX; private NuFX nuFX;
private Binary2 bin2; private Binary2 bin2;
private WozFile wozFile; private WozFile wozFile;
private PrefixDiskCopy prefixDiskCopy;
private Prefix2mg prefix2mg;
private int interleave = 0; private int interleave = 0;
private static int[][] interleaveSector = // private static int[][] interleaveSector = //
@ -119,7 +122,7 @@ public class AppleDisk implements Disk
{ {
if ("2IMG".equals (prefix)) if ("2IMG".equals (prefix))
{ {
Prefix2mg prefix2mg = new Prefix2mg (buffer); prefix2mg = new Prefix2mg (buffer);
if (debug) if (debug)
System.out.println (prefix2mg); System.out.println (prefix2mg);
@ -145,7 +148,7 @@ public class AppleDisk implements Disk
} }
else if ("img".equals (suffix) || "dimg".equals (suffix)) else if ("img".equals (suffix) || "dimg".equals (suffix))
{ {
PrefixDiskCopy prefixDiskCopy = new PrefixDiskCopy (buffer); prefixDiskCopy = new PrefixDiskCopy (buffer);
blocks = prefixDiskCopy.getBlocks (); blocks = prefixDiskCopy.getBlocks ();
this.sectorSize = 512; this.sectorSize = 512;
@ -741,25 +744,20 @@ public class AppleDisk implements Disk
text.append (String.format ("Blocks............... %,d%n", blocks)); text.append (String.format ("Blocks............... %,d%n", blocks));
text.append (String.format ("Track size........... %,d%n", trackSize)); text.append (String.format ("Track size........... %,d%n", trackSize));
text.append (String.format ("Sector size.......... %d%n", sectorSize)); text.append (String.format ("Sector size.......... %d%n", sectorSize));
text.append (String.format ("Interleave........... %d", interleave)); text.append (String.format ("Interleave........... %d%n%n", interleave));
if (wozFile != null) if (wozFile != null)
{
text.append ("\n\n");
text.append (wozFile); text.append (wozFile);
}
else if (nuFX != null) else if (nuFX != null)
{
text.append ("\n\n");
text.append (nuFX); text.append (nuFX);
}
else if (bin2 != null) else if (bin2 != null)
{
text.append ("\n\n");
text.append (bin2); text.append (bin2);
} else if (prefixDiskCopy != null)
text.append (prefixDiskCopy);
else if (prefix2mg != null)
text.append (prefix2mg);
return text.toString (); return Utility.rtrim (text).toString ();
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -140,8 +140,9 @@ public class DiskFactory
} }
} }
if ("sdk".equals (suffix) || "shk".equals (suffix) // shrinkit disk/file archive if ("sdk".equals (suffix) // NuFX disk
|| "bxy".equals (suffix)) || "shk".equals (suffix) // NuFX files or disk
|| "bxy".equals (suffix)) // NuFX in Binary2
{ {
if (debug) if (debug)
System.out.println (" ** sdk/shk/bxy **"); System.out.println (" ** sdk/shk/bxy **");
@ -169,10 +170,11 @@ public class DiskFactory
// e.printStackTrace (); // e.printStackTrace ();
System.out.println (e.getMessage ()); System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ()); System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
System.out.println (nuFX);
return null; return null;
} }
} }
else if ("bny".equals (suffix)) else if ("bny".equals (suffix)) // Binary2 uncompressed files
{ {
if (debug) if (debug)
System.out.println (" ** bny **"); System.out.println (" ** bny **");
@ -196,6 +198,7 @@ public class DiskFactory
// e.printStackTrace (); // e.printStackTrace ();
System.out.println (e.getMessage ()); System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ()); System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
System.out.println (binary2);
return null; return null;
} }
} }

View File

@ -4,6 +4,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility; import com.bytezone.diskbrowser.utilities.Utility;
// https://www.discferret.com/wiki/Apple_DiskCopy_4.2 // https://www.discferret.com/wiki/Apple_DiskCopy_4.2
// Apple II File Type Notes $E0/0005 (macintosh)
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
public class PrefixDiskCopy public class PrefixDiskCopy
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
@ -11,9 +12,11 @@ public class PrefixDiskCopy
private String name; private String name;
private int dataSize; private int dataSize;
private int tagSize; private int tagSize;
private int encoding; private int dataChecksum;
private int tagChecksum;
private int diskFormat;
private int format; private int format;
private int id; private int id; // should be 0x0100
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public PrefixDiskCopy (byte[] buffer) public PrefixDiskCopy (byte[] buffer)
@ -24,7 +27,9 @@ public class PrefixDiskCopy
name = HexFormatter.getPascalString (buffer, 0); name = HexFormatter.getPascalString (buffer, 0);
dataSize = Utility.getLongBigEndian (buffer, 0x40); dataSize = Utility.getLongBigEndian (buffer, 0x40);
tagSize = Utility.getLongBigEndian (buffer, 0x44); tagSize = Utility.getLongBigEndian (buffer, 0x44);
encoding = buffer[0x50] & 0xFF; dataChecksum = Utility.getLongBigEndian (buffer, 0x48);
tagChecksum = Utility.getLongBigEndian (buffer, 0x4C);
diskFormat = buffer[0x50] & 0xFF;
format = buffer[0x51] & 0xFF; format = buffer[0x51] & 0xFF;
id = Utility.getWordBigEndian (buffer, 0x52); id = Utility.getWordBigEndian (buffer, 0x52);
} }
@ -43,12 +48,14 @@ public class PrefixDiskCopy
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append (String.format ("Name : %s%n", name)); text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize)); text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize)); text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Encoding : %02X%n", encoding)); text.append (String.format ("Data checksum : %08X (%<,d)%n", dataChecksum));
text.append (String.format ("Format : %02X%n", format)); text.append (String.format ("Tag checksum : %08X (%<,d)%n", tagChecksum));
text.append (String.format ("ID : %04X%n", id)); text.append (String.format ("Disk format : %02X%n", diskFormat));
text.append (String.format ("Format byte : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
return text.toString (); return text.toString ();
} }

View File

@ -26,6 +26,7 @@ public class ProdosDisk
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
static final String UNDERLINE = "------------------------------------------------\n"; static final String UNDERLINE = "------------------------------------------------\n";
static final String message = "DiskBrowser";
private static final int CATALOG_SIZE = 4; private static final int CATALOG_SIZE = 4;
private static final int BITS_PER_BLOCK = 8 * BLOCK_SIZE; private static final int BITS_PER_BLOCK = 8 * BLOCK_SIZE;
@ -82,6 +83,7 @@ public class ProdosDisk
allocateNextBlock (); allocateNextBlock ();
System.arraycopy (bootSector, 0, buffer, 0, 512); System.arraycopy (bootSector, 0, buffer, 0, 512);
System.arraycopy (message.getBytes (), 0, buffer, 768, message.length ());
// write 4 catalog blocks // write 4 catalog blocks
for (int i = 0, prevBlockNo = 0; i < CATALOG_SIZE; i++) for (int i = 0, prevBlockNo = 0; i < CATALOG_SIZE; i++)

View File

@ -98,6 +98,7 @@ public class Binary2Header
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Binary2 Header\n==============\n");
text.append (String.format ("Access ................ %02X%n", accessCode)); text.append (String.format ("Access ................ %02X%n", accessCode));
text.append (String.format ("File type ............. %02X%n", fileType)); text.append (String.format ("File type ............. %02X%n", fileType));
text.append (String.format ("Aux type .............. %04X%n", auxType)); text.append (String.format ("Aux type .............. %04X%n", auxType));

View File

@ -38,13 +38,22 @@ class MasterHeader
// bin2 = true; // bin2 = true;
// break; // break;
// } // }
if (isBin2 (buffer, ptr)) if (isBin2 (buffer, ptr))
{ {
binary2Header = new Binary2Header (buffer, 0); binary2Header = new Binary2Header (buffer, 0);
ptr += 128; if (binary2Header.fileType == (byte) 0xE0
bin2 = true; && (binary2Header.auxType == 0x8000 || binary2Header.auxType == 0x8002))
continue; {
ptr += 128;
bin2 = true;
continue;
}
else
{
System.out.printf ("Not NuFX: %02X %04X%n", binary2Header.fileType,
binary2Header.auxType);
System.out.println (binary2Header);
}
} }
throw new FileFormatException ("NuFile not found"); throw new FileFormatException ("NuFile not found");

View File

@ -155,7 +155,17 @@ public class NuFX
int auxType = record.getAuxType (); int auxType = record.getAuxType ();
LocalDateTime created = record.getCreated (); LocalDateTime created = record.getCreated ();
LocalDateTime modified = record.getModified (); LocalDateTime modified = record.getModified ();
byte[] buffer = record.getData (); byte[] buffer;
try
{
buffer = record.getData ();
}
catch (Exception e)
{
System.out.println (e.getMessage ());
System.out.printf ("Failed to unpack: %s%n", fileName);
continue;
}
if (debug) if (debug)
System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count, System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count,
@ -175,7 +185,16 @@ public class NuFX
if (record.hasResource ()) if (record.hasResource ())
{ {
buffer = record.getResourceData (); try
{
buffer = record.getResourceData ();
}
catch (Exception e)
{
System.out.println (e.getMessage ());
System.out.printf ("Failed to unpack resource fork: %s%n", fileName);
continue;
}
disk.addResourceFork (fileEntry, buffer, buffer.length); disk.addResourceFork (fileEntry, buffer, buffer.length);
} }
} }