subq.l #4,d2
bne.s .cp1
+ jsr -$0078(a6)
move.l a6,a1
move.w #-$48,a0 ;InitCode
move.l a2,d0
lea myafterdos(pc),a0
move.l a0,residentcodejump1-residentcodestart+2(a2)
jsr -$27C(a6) ;CacheClearU
+ jsr -$007e(a6)
.rsh
movem.l (sp)+,d0-d2/a0-a2/a6
rts
myafterdos
move.l (sp),a0
move.l 2(a0),a0
+ move.l a0,-(sp)
+ jsr (a0) ;jump to original InitCode
+ move.l (sp)+,a0
+ addq.l #4,sp ;remove return address
movem.l d0-d7/a1-a6,-(sp)
move.l a6,a1
move.l a0,d0
- move.w #-$48,a0 ;InitResident
- jsr -$01a4(a6) ;SetFunction
+ move.w #-$48,a0 ;InitCode
+ jsr -$01a4(a6) ;SetFunction (restore original)
bsr.w clipboard_init
movem.l (sp)+,d0-d7/a1-a6
- rts
+ rts ;return directly to caller
cnop 0,4
residentcodestart:
CLIP_POINTER_PREFS = (CLIP_POINTER_NOTIFY+48)
CLIP_END = (CLIP_POINTER_PREFS+32)
-;clipboard_resident:
-; dc.w $4afc
-; dc.l 0
-; dc.l 26
-; dc.b 4 ; RTF_AFTERDOS
-; dc.b 1
-; dc.b 0 ; NT_UNKNOWN
-; dc.b -125
-; dc.l clname-clipboard_resident
-; dc.l clname-clipboard_resident
-; dc.l clipboard_init-clipboard_resident
-
clipboard_init:
movem.l a5/a6,-(sp)
move.l 4.w,a6
db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0x12);
- db(0x00); db(0x00); db(0x07); db(0xf4); db(0x00); db(0x00); db(0x00); db(0xc0);
- db(0x00); db(0x00); db(0x02); db(0x1c); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x00); db(0x00); db(0x02); db(0xd8); db(0x00); db(0x00); db(0x0d); db(0xe4);
- db(0x00); db(0x00); db(0x12); db(0x74); db(0x43); db(0xfa); db(0x16); db(0xcb);
+ db(0x00); db(0x00); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0x22);
+ db(0x00); db(0x00); db(0x08); db(0x04); db(0x00); db(0x00); db(0x00); db(0xd0);
+ db(0x00); db(0x00); db(0x02); db(0x2c); db(0x00); db(0x00); db(0x00); db(0x24);
+ db(0x00); db(0x00); db(0x02); db(0xe8); db(0x00); db(0x00); db(0x0d); db(0xf4);
+ db(0x00); db(0x00); db(0x12); db(0x84); db(0x43); db(0xfa); db(0x16); db(0xdb);
db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
db(0x48); db(0xe7); db(0xe0); db(0xe2); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x3c);
+ db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x44);
db(0x70); db(0x14); db(0x24); db(0x00); db(0x22); db(0x3c); db(0x00); db(0x01);
db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
- db(0x67); db(0x2a); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x43); db(0xfa);
- db(0x00); db(0x4c); db(0x20); db(0xd9); db(0x59); db(0x82); db(0x66); db(0xfa);
- db(0x22); db(0x4e); db(0x30); db(0x7c); db(0xff); db(0xb8); db(0x20); db(0x0a);
- db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x25); db(0x40); db(0x00); db(0x0e);
- db(0x41); db(0xfa); db(0x00); db(0x10); db(0x25); db(0x48); db(0x00); db(0x08);
- db(0x4e); db(0xae); db(0xfd); db(0x84); db(0x4c); db(0xdf); db(0x47); db(0x07);
+ db(0x67); db(0x32); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x43); db(0xfa);
+ db(0x00); db(0x5c); db(0x20); db(0xd9); db(0x59); db(0x82); db(0x66); db(0xfa);
+ db(0x4e); db(0xae); db(0xff); db(0x88); db(0x22); db(0x4e); db(0x30); db(0x7c);
+ db(0xff); db(0xb8); db(0x20); db(0x0a); db(0x4e); db(0xae); db(0xfe); db(0x5c);
+ db(0x25); db(0x40); db(0x00); db(0x0e); db(0x41); db(0xfa); db(0x00); db(0x14);
+ db(0x25); db(0x48); db(0x00); db(0x08); db(0x4e); db(0xae); db(0xfd); db(0x84);
+ db(0x4e); db(0xae); db(0xff); db(0x82); db(0x4c); db(0xdf); db(0x47); db(0x07);
db(0x4e); db(0x75); db(0x20); db(0x57); db(0x20); db(0x68); db(0x00); db(0x02);
+ db(0x2f); db(0x08); db(0x4e); db(0x90); db(0x20); db(0x5f); db(0x58); db(0x8f);
db(0x48); db(0xe7); db(0xff); db(0x7e); db(0x22); db(0x4e); db(0x20); db(0x08);
db(0x30); db(0x7c); db(0xff); db(0xb8); db(0x4e); db(0xae); db(0xfe); db(0x5c);
db(0x61); db(0x00); db(0x11); db(0xd2); db(0x4c); db(0xdf); db(0x7e); db(0xff);
db(0x60); db(0x00); db(0xff); db(0x74); db(0x30); db(0x3c); db(0xff); db(0x50);
db(0x61); db(0x00); db(0x09); db(0x86); db(0x70); db(0x04); db(0x4e); db(0x90);
db(0x70); db(0x01); db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x5a);
+ db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x4a);
db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa);
db(0x13); db(0xc6); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
db(0xff); db(0x18); db(0x61); db(0x00); db(0x03); db(0x9c); db(0x4e); db(0x90);
db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80);
db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x17); db(0x70);
- db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x30); db(0x20); db(0x08);
+ db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x20); db(0x20); db(0x08);
db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x70); db(0xff);
db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07); db(0x00); db(0x00);
db(0x67); db(0x3a); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14);
db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e);
db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a);
db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0xf3); db(0xa2); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0x41); db(0xfa); db(0xf3); db(0x92); db(0x02); db(0x80); db(0x00); db(0x00);
db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x20); db(0x88);
db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x21); db(0x48);
db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
*psectorspertrack = spt;
}
-static void pl(uae_u8 *p, int off, uae_u32 v)
+static void pl (uae_u8 *p, int off, uae_u32 v)
{
p += off * 4;
p[0] = v >> 24;
p[3] = v >> 0;
}
-static void rdb_crc(uae_u8 *p)
+static void rdb_crc (uae_u8 *p)
{
uae_u32 sum;
int i, blocksize;
return ret;
}
-
static uae_u64 vhd_read (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
{
uae_u32 bamoffset;
extern struct zfile *archive_access_lzx (struct znode *zn);
extern struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id);
extern struct zfile *archive_access_arcacc (struct znode *zn);
-extern struct zvolume *archive_directory_adf (struct zfile *z);
+extern struct zvolume *archive_directory_adf (struct znode *zn, struct zfile *z);
extern struct zfile *archive_access_adf (struct znode *zn);
extern struct zvolume *archive_directory_rdb (struct zfile *z);
extern struct zfile *archive_access_rdb (struct znode *zn);
-extern struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int doselect);
+extern struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int doselect);
extern struct zfile *archive_access_arcacc_select (struct zfile *zf, unsigned int id);
extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsigned int id);
extern int zfile_isdiskimage (const TCHAR *name);
extern int iszip (struct zfile *z);
extern int zfile_convertimage (const TCHAR *src, const TCHAR *dst);
-extern struct zfile *zuncompress (struct zfile *z, int dodefault, int imgonly);
+extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int imgonly);
extern void zfile_seterror (const TCHAR *format, ...);
extern TCHAR *zfile_geterror (void);
static void unacquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt)
{
+ HRESULT hr;
if (lpdi) {
- HRESULT hr = IDirectInputDevice8_Unacquire (lpdi);
+ hr = IDirectInputDevice8_Unacquire (lpdi);
if (FAILED (hr) && hr != DI_NOEFFECT)
write_log (L"unacquire %s failed, %s\n", txt, DXError (hr));
}
}
+
static int acquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt)
{
HRESULT hr = DI_OK;
}
}
+
+static int acquire_kb (int num, int flags)
+{
+ LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
+
+ unacquire (lpdi, L"keyboard");
+ if (currprefs.keyboard_leds_in_use) {
+#ifdef WINDDK
+ if (!currprefs.win32_kbledmode) {
+ if (DefineDosDevice (DDD_RAW_TARGET_PATH, L"Kbd", L"\\Device\\KeyboardClass0")) {
+ kbhandle = CreateFile (L"\\\\.\\Kbd", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (kbhandle == INVALID_HANDLE_VALUE) {
+ write_log (L"kbled: CreateFile failed, error %d\n", GetLastError());
+ currprefs.win32_kbledmode = 1;
+ }
+ } else {
+ currprefs.win32_kbledmode = 1;
+ write_log (L"kbled: DefineDosDevice failed, error %d\n", GetLastError());
+ }
+ }
+#else
+ currprefs.kbledmode = 1;
+#endif
+ oldleds = get_leds ();
+ if (oldusedleds < 0)
+ oldusedleds = newleds = oldleds;
+ set_leds (oldusedleds);
+ }
+
+ setcoop (&di_keyboard[num], DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_EXCLUSIVE, L"keyboard");
+ kb_do_refresh = ~0;
+ di_keyboard[num].acquired = -1;
+ if (acquire (lpdi, L"keyboard")) {
+ if (di_keyboard[num].rawinput)
+ rawkb++;
+ else if (di_keyboard[num].superdevice)
+ superkb++;
+ else
+ normalkb++;
+ di_keyboard[num].acquired = 1;
+ }
+ register_rawinput ();
+ return di_keyboard[num].acquired > 0 ? 1 : 0;
+}
+
+static void unacquire_kb (int num)
+{
+ LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
+
+ unacquire (lpdi, L"keyboard");
+ if (di_keyboard[num].acquired > 0) {
+ if (di_keyboard[num].rawinput)
+ rawkb--;
+ else if (di_keyboard[num].superdevice)
+ superkb--;
+ else
+ normalkb--;
+ di_keyboard[num].acquired = 0;
+ }
+ release_keys ();
+
+ if (currprefs.keyboard_leds_in_use) {
+ if (oldusedleds >= 0) {
+ set_leds (oldleds);
+ oldusedleds = oldleds;
+ }
+#ifdef WINDDK
+ if (kbhandle != INVALID_HANDLE_VALUE) {
+ CloseHandle (kbhandle);
+ DefineDosDevice (DDD_REMOVE_DEFINITION, L"Kbd", NULL);
+ kbhandle = INVALID_HANDLE_VALUE;
+ }
+#endif
+ }
+}
+
static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
{
HRESULT hr;
}
}
} else if (hr == DIERR_INPUTLOST) {
- acquire (lpdi, L"keyboard");
+ acquire_kb (num, 0);
IDirectInputDevice8_Poll (lpdi);
return 0;
}
return 1;
}
-
static void read_kb (void)
{
DIDEVICEOBJECTDATA didod[DI_KBBUFFER];
struct didata *did = &di_keyboard[i];
if (!did->acquired)
continue;
+ if (isfocus () == 0) {
+ if (did->acquired > 0)
+ unacquire_kb (i);
+ continue;
+ }
lpdi = did->lpdi;
if (!lpdi)
continue;
}
}
} else if (hr == DIERR_INPUTLOST) {
- acquire (lpdi, L"keyboard");
+ acquire_kb (i, 0);
kb_do_refresh |= 1 << i;
- } else if (did->acquired && hr == DIERR_NOTACQUIRED) {
- acquire (lpdi, L"keyboard");
+ } else if (did->acquired && hr == DIERR_NOTACQUIRED) {
+ acquire_kb (i, 0);
}
IDirectInputDevice8_Poll (lpdi);
}
#ifdef CATWEASEL
- {
+ if (isfocus ()) {
uae_u8 kc;
if (stopoutput == 0 && catweasel_read_keyboard (&kc))
inputdevice_do_keyboard (kc & 0x7f, kc & 0x80);
stopoutput--;
}
-static int acquire_kb (int num, int flags)
-{
- LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
-
- unacquire (lpdi, L"keyboard");
- if (currprefs.keyboard_leds_in_use) {
-#ifdef WINDDK
- if (!currprefs.win32_kbledmode) {
- if (DefineDosDevice (DDD_RAW_TARGET_PATH, L"Kbd", L"\\Device\\KeyboardClass0")) {
- kbhandle = CreateFile (L"\\\\.\\Kbd", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (kbhandle == INVALID_HANDLE_VALUE) {
- write_log (L"kbled: CreateFile failed, error %d\n", GetLastError());
- currprefs.win32_kbledmode = 1;
- }
- } else {
- currprefs.win32_kbledmode = 1;
- write_log (L"kbled: DefineDosDevice failed, error %d\n", GetLastError());
- }
- }
-#else
- currprefs.kbledmode = 1;
-#endif
- oldleds = get_leds ();
- if (oldusedleds < 0)
- oldusedleds = newleds = oldleds;
- set_leds (oldusedleds);
- }
-
- setcoop (&di_keyboard[num], DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_EXCLUSIVE, L"keyboard");
- kb_do_refresh = ~0;
- di_keyboard[num].acquired = -1;
- if (acquire (lpdi, L"keyboard")) {
- if (di_keyboard[num].rawinput)
- rawkb++;
- else if (di_keyboard[num].superdevice)
- superkb++;
- else
- normalkb++;
- di_keyboard[num].acquired = 1;
- }
- register_rawinput ();
- return di_keyboard[num].acquired > 0 ? 1 : 0;
-}
-
-static void unacquire_kb (int num)
-{
- LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
-
- unacquire (lpdi, L"keyboard");
- if (di_keyboard[num].acquired > 0) {
- if (di_keyboard[num].rawinput)
- rawkb--;
- else if (di_keyboard[num].superdevice)
- superkb--;
- else
- normalkb--;
- di_keyboard[num].acquired = 0;
- }
- release_keys ();
-
- if (currprefs.keyboard_leds_in_use) {
- if (oldusedleds >= 0) {
- set_leds (oldleds);
- oldusedleds = oldleds;
- }
-#ifdef WINDDK
- if (kbhandle != INVALID_HANDLE_VALUE) {
- CloseHandle (kbhandle);
- DefineDosDevice (DDD_REMOVE_DEFINITION, L"Kbd", NULL);
- kbhandle = INVALID_HANDLE_VALUE;
- }
-#endif
- }
-}
-
static int get_kb_flags (int kb)
{
return 0;
static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWORD *index2, uae_u8 *buffer, int ignoreduplicates)
{
- int i, nosp;
+ int i, nosp, geom_ok;
int ret = -1;
STORAGE_PROPERTY_QUERY query;
DRIVE_LAYOUT_INFORMATION *dli;
}
_tcscpy (orgname, udi->device_name);
udi->bytespersector = 512;
+ geom_ok = 1;
if (!DeviceIoControl (hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, (void*)&dg, sizeof (dg), &returnedLength, NULL)) {
DWORD err = GetLastError();
if (isnomediaerr (err)) {
goto amipartfound;
}
write_log (L"IOCTL_DISK_GET_DRIVE_GEOMETRY failed with error code %d.\n", err);
- ret = 1;
- goto end;
+ dg.BytesPerSector = 512;
+ geom_ok = 0;
}
udi->readonly = 0;
if (!DeviceIoControl (hDevice, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, &returnedLength, NULL)) {
if (!nosp)
write_log (L"IOCTL_DISK_GET_LENGTH_INFO not supported, detected disk size may not be correct.\n");
}
- udi->bytespersector = dg.BytesPerSector;
- if (dg.BytesPerSector < 512) {
- write_log (L"unsupported blocksize < 512 (%d)\n", dg.BytesPerSector);
- ret = 1;
- goto end;
- }
- if (dg.BytesPerSector > 2048) {
- write_log (L"unsupported blocksize > 2048 (%d)\n", dg.BytesPerSector);
+ if (geom_ok == 0 && gli_ok == 0) {
+ write_log (L"Can't detect size of device\n");
ret = 1;
goto end;
}
+
udi->offset = 0;
- write_log (L"BPS=%d Cyls=%I64d TPC=%d SPT=%d MediaType=%d\n",
- dg.BytesPerSector, dg.Cylinders.QuadPart, dg.TracksPerCylinder, dg.SectorsPerTrack, dg.MediaType);
- udi->size = (uae_u64)dg.BytesPerSector * (uae_u64)dg.Cylinders.QuadPart *
- (uae_u64)dg.TracksPerCylinder * (uae_u64)dg.SectorsPerTrack;
+ if (geom_ok) {
+ udi->bytespersector = dg.BytesPerSector;
+ if (dg.BytesPerSector < 512) {
+ write_log (L"unsupported blocksize < 512 (%d)\n", dg.BytesPerSector);
+ ret = 1;
+ goto end;
+ }
+ if (dg.BytesPerSector > 2048) {
+ write_log (L"unsupported blocksize > 2048 (%d)\n", dg.BytesPerSector);
+ ret = 1;
+ goto end;
+ }
+ write_log (L"BPS=%d Cyls=%I64d TPC=%d SPT=%d MediaType=%d\n",
+ dg.BytesPerSector, dg.Cylinders.QuadPart, dg.TracksPerCylinder, dg.SectorsPerTrack, dg.MediaType);
+ udi->size = (uae_u64)dg.BytesPerSector * (uae_u64)dg.Cylinders.QuadPart *
+ (uae_u64)dg.TracksPerCylinder * (uae_u64)dg.SectorsPerTrack;
+ }
if (gli_ok)
udi->size = gli.Length.QuadPart;
write_log (L"device size %I64d (0x%I64x) bytes\n", udi->size, udi->size);
#define WINUAEPUBLICBETA 1
-#define WINUAEBETA L"22"
-#define WINUAEDATE MAKEBD(2009, 4, 8)
+#define WINUAEBETA L"23"
+#define WINUAEDATE MAKEBD(2009, 4, 10)
#define WINUAEEXTRA L""
#define WINUAEREV L""
}
for (i = 0; i < ah * scale; i++) {
int w = aw * scale * (dst_depth / 8);
+ if (dptr + w > enddptr)
+ break;
memcpy (dptr, sptr2, w);
sptr2 += w;
dptr += pitch;
+Beta 23:
+
+- archives (zip etc) didn't unpack
+- directinput keyboard was not always unacquired when focus was lost
+- hq2x/3x/4x crash in specific situations (old random bug)
+- clipboard initialization changed again, now initialized after all
+ residents have been initialized (previously it was after dos)
+
Beta 22:
- do not change priority if current priority is HIGH or REALTIME
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
struct uae_prefs currprefs;
-static int debug = 0;
+static int debug = 1;
#define WRITE_LOG_BUF_SIZE 4096
void write_log (const TCHAR *format, ...)
break;
}
}
+ geterror ();
if (!found && !level) {
_tprintf (L"'%s' not found\n", fn);
}
zfile_fclose (s);
}
}
+ geterror ();
if (!found && !level) {
_tprintf (L"'%s' not matched\n", match);
}
ok = 1;
}
if (!ok) {
- _tprintf (L"UAE unpacker uaeunp 0.4c by Toni Wilen (c)2009\n");
+ _tprintf (L"UAE unpacker uaeunp 0.5b by Toni Wilen (c)2009\n");
_tprintf (L"\n");
_tprintf (L"List: \"uaeunp (-l) <path>\"\n");
_tprintf (L"List all recursively: \"uaeunp -l <path> **\"\n");
_tprintf (L"Output to console: \"uaeunp (-x) -o <path> <filename>\"\n");
_tprintf (L"\n");
_tprintf (L"Supported disk image formats:\n");
- _tprintf (L" ADF and HDF (OFS/FFS), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+ _tprintf (L" ADF and HDF (OFS/FFS/SFS/SFS2), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
_tprintf (L"Supported archive formats:\n");
_tprintf (L" 7ZIP, LHA, LZX, RAR (unrar.dll), ZIP, ArchiveAccess.DLL\n");
_tprintf (L"Miscellaneous formats:\n");
}
return 0;
}
+
+/*
+ 0.5:
+
+ - adf protection flags fixed
+ - sfs support added
+ - >512 block sizes supported (rdb hardfiles only)
+
+ 0.5b:
+
+ - SFS file extraction fixed
+ - SFS2 supported
+ - block size autodetection implemented (if non-rdb hardfile)
+
+
+*/
\ No newline at end of file
if (!strcasecmp (ext, L".hdf")) {
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
return ArchiveFormatADF;
+ if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
+ return ArchiveFormatADF;
if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
return ArchiveFormatRDB;
return 0;
return 0;
}
-struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
+struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask)
{
TCHAR *name = z->name;
TCHAR *ext = NULL;
if (ext != NULL) {
if (mask & ZFD_ARCHIVE) {
if (strcasecmp (ext, L"7z") == 0)
- return archive_access_select (z, ArchiveFormat7Zip, dodefault);
+ return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault);
if (strcasecmp (ext, L"zip") == 0)
- return archive_access_select (z, ArchiveFormatZIP, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatZIP, dodefault);
if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
- return archive_access_select (z, ArchiveFormatLHA, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatLHA, dodefault);
if (strcasecmp (ext, L"lzx") == 0)
- return archive_access_select (z, ArchiveFormatLZX, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatLZX, dodefault);
if (strcasecmp (ext, L"rar") == 0)
- return archive_access_select (z, ArchiveFormatRAR, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatRAR, dodefault);
}
if (mask & ZFD_UNPACK) {
if (strcasecmp (ext, L"gz") == 0)
}
if (mask & ZFD_ARCHIVE) {
if (header[0] == 'P' && header[1] == 'K')
- return archive_access_select (z, ArchiveFormatZIP, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatZIP, dodefault);
if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
- return archive_access_select (z, ArchiveFormatRAR, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatRAR, dodefault);
if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
- return archive_access_select (z, ArchiveFormatLZX, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatLZX, dodefault);
if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
- return archive_access_select (z, ArchiveFormatLHA, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatLHA, dodefault);
}
if (mask & ZFD_ADF) {
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
- return archive_access_select (z, ArchiveFormatADF, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
+ if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
+ return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
}
if (ext) {
}
if (mask & ZFD_ADF) {
if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
- return archive_access_select (z, ArchiveFormatADF, dodefault);
+ return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
}
}
return z;
return l;
l2 = NULL;
while (cnt-- > 0) {
- l = zuncompress (l, 0, mask);
+ l = zuncompress (NULL, l, 0, mask);
if (!l)
break;
zfile_fseek (l, 0, SEEK_SET);
l->name = name ? my_strdup (name) : L"";
if (size) {
l->data = xcalloc (size, 1);
+ if (!l->data) {
+ xfree (l);
+ return NULL;
+ }
l->size = size;
} else {
l->data = xcalloc (1, 1);
return NULL;
}
-static struct zvolume *zfile_fopen_archive_ext (struct zfile *zf)
+static struct zvolume *zfile_fopen_archive_ext (struct znode *parent, struct zfile *zf)
{
struct zvolume *zv = NULL;
TCHAR *name = zfile_getname (zf);
if (strcasecmp (ext, L"rar") == 0)
zv = archive_directory_rar (zf);
if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
- zv = archive_directory_adf (zf);
+ zv = archive_directory_adf (parent, zf);
if (strcasecmp (ext, L"hdf") == 0) {
if (!memcmp (header, "RDSK", 4))
zv = archive_directory_rdb (zf);
else
- zv = archive_directory_adf (zf);
+ zv = archive_directory_adf (parent, zf);
}
}
return zv;
}
-struct zvolume *zfile_fopen_archive_data (struct zfile *zf)
+static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct zfile *zf)
{
struct zvolume *zv = NULL;
uae_u8 header[7];
if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
zv = archive_directory_lha (zf);
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
- zv = archive_directory_adf (zf);
+ zv = archive_directory_adf (parent, zf);
if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
zv = archive_directory_rdb (zf);
return zv;
zndir->vfile = zn;
zndir->vchild = zvnew;
zvnew->parent = zv;
+ zndir->offset = zn->offset;
+ zndir->offset2 = zn->offset2;
}
}
zf = zfile_open_archive (path, 0);
if (!zf)
goto end;
- zvnew = zfile_fopen_archive_ext (zf);
+ zvnew = zfile_fopen_archive_ext (zv->parentz, zf);
if (!zvnew) {
struct zfile *zf2 = zf;
- zf = zuncompress (zf2, 0, 1);
+ zf = zuncompress (&zv->root, zf2, 0, ZFD_ALL);
if (zf != zf2)
zvnew = archive_directory_plain (zf);
}
if (!zf)
return NULL;
zf->zfdmask = ZFD_ALL;
- zv = zfile_fopen_archive_ext (zf);
+ zv = zfile_fopen_archive_ext (NULL, zf);
if (!zv)
- zv = zfile_fopen_archive_data (zf);
+ zv = zfile_fopen_archive_data (NULL, zf);
#if 0
if (!zv) {
struct zfile *zf2 = zuncompress (zf, 0, 0);
return t;
}
-static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
+static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsigned int id)
{
struct zvolume *zv = NULL;
zv = archive_directory_plain (zf);
break;
case ArchiveFormatADF:
- zv = archive_directory_adf (zf);
+ zv = archive_directory_adf (parent, zf);
break;
case ArchiveFormatRDB:
zv = archive_directory_rdb (zf);
return zf;
}
-struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dodefault)
+struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault)
{
struct zvolume *zv;
struct znode *zn;
struct zfile *z = NULL;
int we_have_file;
- zv = getzvolume (zf, id);
+ zv = getzvolume (parent, zf, id);
if (!zv)
return zf;
we_have_file = 0;
}
}
zipcnt++;
- zn = zn->sibling;
+ zn = zn->next;
}
#ifndef _CONSOLE
if (first && tmphist[0])
struct zvolume *zv;
struct znode *zn;
- zv = getzvolume (zf, id);
+ zv = getzvolume (NULL, zf, id);
if (!zv)
return;
zn = &zv->root;
}
}
}
- zn = zn->sibling;
+ zn = zn->next;
}
zfile_fclose_archive (zv);
}
xfree (data);
}
zf = zfile_dup (z);
- zf2 = zuncompress (zf, 0, 1);
+ zf2 = zuncompress (NULL, zf, 0, ZFD_ALL);
if (zf2 != zf) {
zf = zf2;
zai.name = zfile_getfilename (zf);
if (zn->offset) {
struct zfile *zf;
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
- zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask);
+ zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF);
zfile_fread (z->data, zn->size, 1, zf);
zfile_fclose (zf);
} else {
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
- zfile_fseek (zn->volume->archive, 0, SEEK_SET);
- zfile_fread (z->data, zn->size, 1, zn->volume->archive);
+ if (z) {
+ zfile_fseek (zn->volume->archive, 0, SEEK_SET);
+ zfile_fread (z->data, zn->size, 1, zn->volume->archive);
+ }
}
return z;
}
uae_u32 dostype;
};
+
+static int dos_checksum (uae_u8 *p, int blocksize)
+{
+ uae_u32 cs = 0;
+ int i;
+ for (i = 0; i < blocksize; i += 4)
+ cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
+ return cs;
+}
+static int sfs_checksum (uae_u8 *p, int blocksize, int sfs2)
+{
+ uae_u32 cs = sfs2 ? 2 : 1;
+ int i;
+ for (i = 0; i < blocksize; i += 4)
+ cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
+ return cs;
+}
+
static TCHAR *getBSTR (uae_u8 *bstr)
{
int n = *bstr++;
buf[i] = 0;
return au (buf);
}
+
static uae_u32 gl (struct adfhandle *adf, int off)
{
uae_u8 *p = adf->block + off;
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
}
+static uae_u32 glx (uae_u8 *p)
+{
+ return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+}
+static uae_u32 gwx (uae_u8 *p)
+{
+ return (p[0] << 8) | (p[1] << 0);
+}
static const int secs_per_day = 24 * 60 * 60;
static const int diff = (8 * 365 + 2) * (24 * 60 * 60);
+static const int diff2 = (-8 * 365 - 2) * (24 * 60 * 60);
static time_t put_time (long days, long mins, long ticks)
{
time_t t;
struct zvolume *zv = zn->volume;
struct adfhandle *adf = zv->handle;
TCHAR name2[MAX_DPATH];
+ int bs = adf->blocksize;
- for (i = 6; i < 78; i++) {
+ for (i = 0; i < bs / 4 - 56; i++) {
int block;
if (!adf_read_block (adf, root))
return;
- block = gl (adf, i * 4);
- while (block > 0 && block < adf->size / 512) {
+ block = gl (adf, (i + 6) * 4);
+ while (block > 0 && block < adf->size / bs) {
struct zarchive_info zai;
TCHAR *fname;
uae_u32 size, secondary;
break;
if (gl (adf, 1 * 4) != block)
break;
- secondary = gl (adf, 512 - 1 * 4);
+ secondary = gl (adf, bs - 1 * 4);
if (secondary != -3 && secondary != 2)
break;
memset (&zai, 0, sizeof zai);
- fname = getBSTR (adf->block + 512 - 20 * 4);
- size = gl (adf, 512 - 47 * 4);
+ fname = getBSTR (adf->block + bs - 20 * 4);
+ size = gl (adf, bs - 47 * 4);
name2[0] = 0;
if (name[0]) {
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
_tcscat (name2, fname);
zai.name = name2;
zai.size = size;
- zai.flags = gl (adf, 512 - 48);
- zai.t = put_time (gl (adf, 512 - 23 * 4),
- gl (adf, 512 - 22 * 4),
- gl (adf, 512 - 21 * 4));
+ zai.flags = gl (adf, bs - 48 * 4);
+ zai.t = put_time (gl (adf, bs - 23 * 4), gl (adf, bs - 22 * 4),gl (adf, bs - 21 * 4));
if (secondary == -3) {
struct znode *znnew = zvolume_addfile_abs (zv, &zai);
znnew->offset = block;
return;
}
xfree (fname);
- block = gl (adf, 512 - 4 * 4);
+ block = gl (adf, bs - 4 * 4);
}
}
}
-struct zvolume *archive_directory_adf (struct zfile *z)
+static void recursesfs (struct znode *zn, int root, TCHAR *name, int sfs2)
+{
+ struct zvolume *zv = zn->volume;
+ struct adfhandle *adf = zv->handle;
+ TCHAR name2[MAX_DPATH];
+ int bs = adf->blocksize;
+ int block;
+ uae_u8 *p, *s;
+ struct zarchive_info zai;
+
+ block = root;
+ while (block) {
+ if (!adf_read_block (adf, block))
+ return;
+ p = adf->block + 12 + 3 * 4;
+ while (glx (p + 4) && p < adf->block + adf->blocksize - 27) {
+ TCHAR *fname;
+ int i;
+ int align;
+
+ memset (&zai, 0, sizeof zai);
+ zai.flags = glx (p + 8) ^ 0x0f;
+ s = p + (sfs2 ? 27 : 25);
+ fname = au (s);
+ i = 0;
+ while (*s) {
+ s++;
+ i++;
+ }
+ s++;
+ i++;
+ if (*s)
+ zai.comment = au (s);
+ while (*s) {
+ s++;
+ i++;
+ }
+ s++;
+ i++;
+ i += sfs2 ? 27 : 25;
+ align = i & 1;
+
+ name2[0] = 0;
+ if (name[0]) {
+ TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+ _tcscpy (name2, name);
+ _tcscat (name2, sep);
+ }
+ _tcscat (name2, fname);
+ zai.name = name2;
+ if (sfs2)
+ zai.t = glx (p + 22) - diff2;
+ else
+ zai.t = glx (p + 20) - diff;
+ if (p[sfs2 ? 26 : 24] & 0x80) { // dir
+ struct znode *znnew = zvolume_adddir_abs (zv, &zai);
+ int newblock = glx (p + 16);
+ if (newblock) {
+ znnew->offset = block;
+ recursesfs (znnew, newblock, name2, sfs2);
+ }
+ if (!adf_read_block (adf, block))
+ return;
+ } else {
+ struct znode *znnew;
+ if (sfs2) {
+ uae_u64 b1 = p[16];
+ uae_u64 b2 = p[17];
+ zai.size = (b1 << 40) | (b2 << 32) | glx (p + 18) ;
+ } else {
+ zai.size = glx (p + 16);
+ }
+ znnew = zvolume_addfile_abs (zv, &zai);
+ znnew->offset = block;
+ znnew->offset2 = p - adf->block;
+ }
+ xfree (zai.comment);
+ xfree (fname);
+ p += i + align;
+ }
+ block = gl (adf, 12 + 4);
+ }
+
+}
+
+struct zvolume *archive_directory_adf (struct znode *parent, struct zfile *z)
{
struct zvolume *zv;
struct adfhandle *adf;
- TCHAR *volname;
+ TCHAR *volname = NULL;
TCHAR name[MAX_DPATH];
+ int gotroot = 0;
adf = xcalloc (sizeof (struct adfhandle), 1);
zfile_fseek (z, 0, SEEK_END);
zfile_fseek (z, 0, SEEK_SET);
adf->blocksize = 512;
+ if (parent && parent->offset2) {
+ if (parent->offset2 == 1024 || parent->offset2 == 2048 || parent->offset2 == 4096 || parent->offset2 == 8192 ||
+ parent->offset2 == 16384 || parent->offset2 == 32768 || parent->offset2 == 65536) {
+ adf->blocksize = parent->offset2;
+ gotroot = 1;
+ }
+ }
+
adf->highblock = adf->size / adf->blocksize;
adf->z = z;
- if (!adf_read_block (adf, 0)) {
- xfree (adf);
- return NULL;
- }
+ if (!adf_read_block (adf, 0))
+ goto fail;
adf->dostype = gl (adf, 0);
- adf->rootblock = ((adf->size / 512) - 1 + 2) / 2;
- for (;;) {
- if (!adf_read_block (adf, adf->rootblock)) {
- xfree (adf);
- return NULL;
+ if ((adf->dostype & 0xffffff00) == 'DOS\0') {
+ int bs = adf->blocksize;
+ int res;
+
+ adf->rootblock = ((adf->size / bs) - 1 + 2) / 2;
+ if (!gotroot) {
+ for (res = 2; res >= 1; res--) {
+ for (bs = 512; bs < 65536; bs <<= 1) {
+ adf->blocksize = bs;
+ adf->rootblock = ((adf->size / bs) - 1 + res) / 2;
+ if (!adf_read_block (adf, adf->rootblock))
+ continue;
+ if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+ continue;
+ if (dos_checksum (adf->block, bs) != 0)
+ continue;
+ gotroot = 1;
+ break;
+ }
+ if (gotroot)
+ break;
+ }
}
- if (gl (adf, 0) != 2 || gl (adf, 512 - 1 * 4) != 1) {
+ if (!gotroot) {
+ bs = adf->blocksize = 512;
if (adf->size < 2000000 && adf->rootblock != 880) {
- adf->rootblock = 880;
- continue;
+ adf->rootblock = 880;
+ if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+ goto fail;
+ if (dos_checksum (adf->block, bs) != 0)
+ goto fail;
+ goto fail;
}
- xfree (adf);
- return NULL;
}
- break;
- }
- volname = getBSTR (adf->block + 512 - 20 * 4);
+ if (!adf_read_block (adf, adf->rootblock))
+ goto fail;
+ if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+ goto fail;
+ if (dos_checksum (adf->block, adf->blocksize) != 0)
+ goto fail;
+ adf->blocksize = bs;
+ adf->highblock = adf->size / adf->blocksize;
+ volname = getBSTR (adf->block + adf->blocksize - 20 * 4);
+ zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
+ zv->method = ArchiveFormatADF;
+ zv->handle = adf;
+
+ name[0] = 0;
+ recurseadf (&zv->root, adf->rootblock, name);
+
+ } else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
+
+ uae_u16 version, sfs2;
+
+ for (;;) {
+ for (;;) {
+ version = gl (adf, 12) >> 16;
+ sfs2 = version > 3;
+ if (version > 4)
+ break;
+ adf->rootblock = gl (adf, 104);
+ if (!adf_read_block (adf, adf->rootblock))
+ break;
+ if (gl (adf, 0) != 'OBJC')
+ break;
+ if (sfs_checksum (adf->block, adf->blocksize, sfs2))
+ break;
+ adf->rootblock = gl (adf, 40);
+ if (!adf_read_block (adf, adf->rootblock))
+ break;
+ if (gl (adf, 0) != 'OBJC')
+ break;
+ if (sfs_checksum (adf->block, adf->blocksize, sfs2))
+ break;
+ gotroot = 1;
+ break;
+ }
+ if (gotroot)
+ break;
+ adf->blocksize <<= 1;
+ if (adf->blocksize == 65536)
+ break;
+ }
+ if (!gotroot)
+ goto fail;
+
+ zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
+ zv->method = ArchiveFormatADF;
+ zv->handle = adf;
+
+ name[0] = 0;
+ recursesfs (&zv->root, adf->rootblock, name, version > 3);
+
+ } else {
+ goto fail;
+ }
- zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
- zv->method = ArchiveFormatADF;
- zv->handle = adf;
- name[0] = 0;
- recurseadf (&zv->root, adf->rootblock, name);
+ xfree (volname);
return zv;
+fail:
+ xfree (adf);
+ return NULL;
}
+struct sfsblock
+{
+ int block;
+ int length;
+};
+
+static int sfsfindblock (struct adfhandle *adf, int btree, int theblock, struct sfsblock **sfsb, int *sfsblockcnt, int *sfsmaxblockcnt, int sfs2)
+{
+ int nodecount, isleaf, nodesize;
+ int i;
+ uae_u8 *p;
+
+ if (!btree)
+ return 0;
+ if (!adf_read_block (adf, btree))
+ return 0;
+ if (memcmp (adf->block, "BNDC", 4))
+ return 0;
+ nodecount = gwx (adf->block + 12);
+ isleaf = adf->block[14];
+ nodesize = adf->block[15];
+ p = adf->block + 16;
+ for (i = 0; i < nodecount; i++) {
+ if (isleaf) {
+ uae_u32 key = glx (p);
+ uae_u32 next = glx (p + 4);
+ uae_u32 prev = glx (p + 8);
+ uae_u32 blocks;
+ if (sfs2)
+ blocks = glx (p + 12);
+ else
+ blocks = gwx (p + 12);
+ if (key == theblock) {
+ struct sfsblock *sb;
+ if (*sfsblockcnt >= *sfsmaxblockcnt) {
+ *sfsmaxblockcnt += 100;
+ *sfsb = realloc (*sfsb, (*sfsmaxblockcnt) * sizeof (struct sfsblock));
+ }
+ sb = *sfsb + (*sfsblockcnt);
+ sb->block = key;
+ sb->length = blocks;
+ (*sfsblockcnt)++;
+ return next;
+ }
+ } else {
+ uae_u32 key = glx (p);
+ uae_u32 data = glx (p + 4);
+ int newblock = sfsfindblock (adf, data, theblock, sfsb, sfsblockcnt, sfsmaxblockcnt, sfs2);
+ if (newblock)
+ return newblock;
+ if (!adf_read_block (adf, btree))
+ return 0;
+ if (memcmp (adf->block, "BNDC", 4))
+ return 0;
+ }
+ p += nodesize;
+ }
+ return 0;
+}
+
+
struct zfile *archive_access_adf (struct znode *zn)
{
- struct zfile *z;
- int block, root, ffs;
+ struct zfile *z = NULL;
+ int root, ffs;
struct adfhandle *adf = zn->volume->handle;
- int size;
+ int size, bs;
int i;
uae_u8 *dst;
size = zn->size;
+ bs = adf->blocksize;
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, size);
if (!z)
return NULL;
- ffs = adf->dostype & 1;
- root = zn->offset;
- dst = z->data;
- for (;;) {
- adf_read_block (adf, root);
- for (i = 128 - 51; i >= 6; i--) {
- int bsize = ffs ? 512 : 488;
- block = gl (adf, i * 4);
- if (size < bsize)
+
+ if ((adf->dostype & 0xffffff00) == 'DOS\0') {
+
+ ffs = adf->dostype & 1;
+ root = zn->offset;
+ dst = z->data;
+ for (;;) {
+ adf_read_block (adf, root);
+ for (i = bs / 4 - 51; i >= 6; i--) {
+ int bsize = ffs ? bs : bs - 24;
+ int block = gl (adf, i * 4);
+ if (size < bsize)
+ bsize = size;
+ if (ffs)
+ zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
+ else
+ zfile_fseek (adf->z, block * adf->blocksize + 24, SEEK_SET);
+ zfile_fread (dst, bsize, 1, adf->z);
+ size -= bsize;
+ dst += bsize;
+ if (size <= 0)
+ break;
+ }
+ if (size <= 0)
+ break;
+ root = gl (adf, bs - 2 * 4);
+ }
+ } else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
+
+ struct sfsblock *sfsblocks;
+ int sfsblockcnt, sfsmaxblockcnt, i;
+ int bsize;
+ int block = zn->offset;
+ int dblock;
+ int btree, version, sfs2;
+ uae_u8 *p;
+
+ if (!adf_read_block (adf, 0))
+ goto end;
+ btree = glx (adf->block + 108);
+ version = gwx (adf->block + 12);
+ sfs2 = version > 3;
+
+ if (!adf_read_block (adf, block))
+ goto end;
+ p = adf->block + zn->offset2;
+ dblock = glx (p + 12);
+
+ sfsblockcnt = 0;
+ sfsmaxblockcnt = 0;
+ sfsblocks = NULL;
+ if (size > 0) {
+ int nextblock = dblock;
+ while (nextblock) {
+ nextblock = sfsfindblock (adf, btree, nextblock, &sfsblocks, &sfsblockcnt, &sfsmaxblockcnt, sfs2);
+ }
+ }
+
+ bsize = 0;
+ for (i = 0; i < sfsblockcnt; i++)
+ bsize += sfsblocks[i].length * adf->blocksize;
+ if (bsize < size)
+ write_log (L"SFS extracting error, %s size mismatch %d<%d\n", z->name, bsize, size);
+
+ dst = z->data;
+ block = zn->offset;
+ for (i = 0; i < sfsblockcnt; i++) {
+ block = sfsblocks[i].block;
+ bsize = sfsblocks[i].length * adf->blocksize;
+ zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
+ if (bsize > size)
bsize = size;
- if (ffs)
- zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
- else
- zfile_fseek (adf->z, block * adf->blocksize + (512 - 488), SEEK_SET);
zfile_fread (dst, bsize, 1, adf->z);
- size -= bsize;
dst += bsize;
- if (size <= 0)
- break;
+ size -= bsize;
}
- if (size <= 0)
- break;
- root = gl (adf, 512 - 2 * 4);
+
+ xfree (sfsblocks);
}
return z;
+end:
+ zfile_fclose (z);
+ return NULL;
}
static void archive_close_adf (void *v)
struct znode *zn;
struct zarchive_info zai;
TCHAR tmp[MAX_DPATH];
- int surf, spt, lowcyl, highcyl, reserved;
+ int surf, spt, spb, lowcyl, highcyl, reserved;
int size, block, blocksize, rootblock;
uae_u8 *p;
- TCHAR comment[81], *com;
+ TCHAR comment[81], *dos;
if (partnum == 0)
partblock = rl (buf + 28);
p = buf + 128 - 16;
surf = rl (p + 28);
+ spb = rl (p + 32);
spt = rl (p + 36);
reserved = rl (p + 40);
lowcyl = rl (p + 52);
highcyl = rl (p + 56);
- blocksize = rl (p + 20) * 4;
+ blocksize = rl (p + 20) * 4 * spb;
block = lowcyl * surf * spt;
size = (highcyl - lowcyl + 1) * surf * spt;
size *= blocksize;
- rootblock = ((size / blocksize) - 1 + 2) / 2;
+ dos = tochar (buf + 192, 4);
+
+ if (!memcmp (dos, L"DOS", 3))
+ rootblock = ((size / blocksize) - 1 + 2) / 2;
+ else
+ rootblock = 0;
devname = getBSTR (buf + 36);
_stprintf (tmp, L"%s.hdf", devname);
memset (&zai, 0, sizeof zai);
- com = tochar (buf + 192, 4);
_stprintf (comment, L"FS=%s LO=%d HI=%d HEADS=%d SPT=%d RES=%d BLOCK=%d ROOT=%d",
- com, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock);
+ dos, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock);
zai.comment = comment;
- xfree (com);
+ xfree (dos);
zai.name = tmp;
zai.size = size;
zai.flags = -1;
zn = zvolume_addfile_abs (zv, &zai);
zn->offset = partblock;
+ zn->offset2 = blocksize; // örp?
}
zv->method = ArchiveFormatRDB;