From: Toni Wilen Date: Fri, 10 Apr 2009 11:01:29 +0000 (+0300) Subject: imported winuaesrc1600b23.zip X-Git-Tag: 2100~87 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=04400fb392767b680a0e5c4d62c77b76541a7a7a;p=francis%2Fwinuae.git imported winuaesrc1600b23.zip --- diff --git a/filesys.asm b/filesys.asm index 50c614ba..0081a0c3 100644 --- a/filesys.asm +++ b/filesys.asm @@ -86,6 +86,7 @@ residenthack subq.l #4,d2 bne.s .cp1 + jsr -$0078(a6) move.l a6,a1 move.w #-$48,a0 ;InitCode move.l a2,d0 @@ -94,6 +95,7 @@ residenthack 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 @@ -101,14 +103,18 @@ residenthack 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: @@ -2031,18 +2037,6 @@ CLIP_POINTER_NOTIFY = (CLIP_BUF+CLIP_BUF_SIZE) 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 diff --git a/filesys_bootrom.c b/filesys_bootrom.c index 00fd32dc..5c5e475e 100644 --- a/filesys_bootrom.c +++ b/filesys_bootrom.c @@ -1,22 +1,24 @@ 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); @@ -90,7 +92,7 @@ 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); @@ -280,7 +282,7 @@ 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); @@ -393,7 +395,7 @@ 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); diff --git a/hardfile.c b/hardfile.c index b980c7b1..bbf4d945 100644 --- a/hardfile.c +++ b/hardfile.c @@ -179,7 +179,7 @@ void getchshd (struct hardfiledata *hfd, int *pcyl, int *phead, int *psectorsper *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; @@ -188,7 +188,7 @@ static void pl(uae_u8 *p, int off, uae_u32 v) p[3] = v >> 0; } -static void rdb_crc(uae_u8 *p) +static void rdb_crc (uae_u8 *p) { uae_u32 sum; int i, blocksize; @@ -552,7 +552,6 @@ end: return ret; } - static uae_u64 vhd_read (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len) { uae_u32 bamoffset; diff --git a/include/zarchive.h b/include/zarchive.h index a9fe26a1..b7c2f224 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -100,12 +100,12 @@ extern struct zvolume *archive_directory_lzx (struct zfile *in_file); 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); diff --git a/include/zfile.h b/include/zfile.h index 7fbe378f..8c630222 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -42,7 +42,7 @@ extern struct zfile *zfile_gunzip (struct zfile *z); 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); diff --git a/od-win32/dinput.c b/od-win32/dinput.c index 67f5bbd1..5bb24c9e 100644 --- a/od-win32/dinput.c +++ b/od-win32/dinput.c @@ -1117,12 +1117,14 @@ void handle_rawinput (LPARAM lParam) 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; @@ -1993,6 +1995,82 @@ void release_keys (void) } } + +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; @@ -2015,7 +2093,7 @@ static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num) } } } else if (hr == DIERR_INPUTLOST) { - acquire (lpdi, L"keyboard"); + acquire_kb (num, 0); IDirectInputDevice8_Poll (lpdi); return 0; } @@ -2023,7 +2101,6 @@ static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num) return 1; } - static void read_kb (void) { DIDEVICEOBJECTDATA didod[DI_KBBUFFER]; @@ -2041,6 +2118,11 @@ static void read_kb (void) 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; @@ -2071,15 +2153,15 @@ static void read_kb (void) } } } 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); @@ -2138,81 +2220,6 @@ void wait_keyrelease (void) 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; diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index b2762e62..47bea70f 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -756,7 +756,7 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri 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; @@ -854,6 +854,7 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR } _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)) { @@ -861,8 +862,8 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR 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)) { @@ -878,22 +879,30 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR 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); diff --git a/od-win32/win32.h b/od-win32/win32.h index a370e05d..92b75f3f 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #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"" diff --git a/od-win32/win32_scale2x.c b/od-win32/win32_scale2x.c index 4987b796..78de8ff2 100644 --- a/od-win32/win32_scale2x.c +++ b/od-win32/win32_scale2x.c @@ -491,6 +491,8 @@ void S2X_render (void) } 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; diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 3dae2f73..299ab1b1 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,12 @@ +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 diff --git a/uaeunp.c b/uaeunp.c index 32b64be0..5b3efd8c 100644 --- a/uaeunp.c +++ b/uaeunp.c @@ -15,7 +15,7 @@ TCHAR start_path_data[MAX_DPATH]; 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, ...) @@ -395,6 +395,7 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in break; } } + geterror (); if (!found && !level) { _tprintf (L"'%s' not found\n", fn); } @@ -480,6 +481,7 @@ static int unpack2 (const TCHAR *src, const TCHAR *match, int level) zfile_fclose (s); } } + geterror (); if (!found && !level) { _tprintf (L"'%s' not matched\n", match); } @@ -623,7 +625,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) 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) \"\n"); _tprintf (L"List all recursively: \"uaeunp -l **\"\n"); @@ -634,7 +636,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) _tprintf (L"Output to console: \"uaeunp (-x) -o \"\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"); @@ -644,3 +646,19 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) } 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 diff --git a/zfile.c b/zfile.c index 608ab211..23bbb8e3 100644 --- a/zfile.c +++ b/zfile.c @@ -594,6 +594,8 @@ int iszip (struct zfile *z) 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; @@ -609,7 +611,7 @@ int iszip (struct zfile *z) 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; @@ -627,15 +629,15 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask) 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) @@ -690,17 +692,19 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask) } 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) { @@ -710,7 +714,7 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask) } 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; @@ -902,7 +906,7 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask) 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); @@ -975,6 +979,10 @@ struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 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); @@ -1462,7 +1470,7 @@ static struct zvolume *get_zvolume (const TCHAR *path) 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); @@ -1491,19 +1499,19 @@ static struct zvolume *zfile_fopen_archive_ext (struct zfile *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]; @@ -1520,7 +1528,7 @@ struct zvolume *zfile_fopen_archive_data (struct zfile *zf) 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; @@ -1550,6 +1558,8 @@ static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn) zndir->vfile = zn; zndir->vchild = zvnew; zvnew->parent = zv; + zndir->offset = zn->offset; + zndir->offset2 = zn->offset2; } } @@ -1589,10 +1599,10 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR 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); } @@ -1763,9 +1773,9 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename) 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); diff --git a/zfile_archive.c b/zfile_archive.c index d17dd102..7671c5af 100644 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -44,7 +44,7 @@ static time_t fromdostime (uae_u32 dd) 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; @@ -69,7 +69,7 @@ static struct zvolume *getzvolume (struct zfile *zf, unsigned int id) 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); @@ -114,7 +114,7 @@ struct zfile *archive_getzfile (struct znode *zn, unsigned int id) 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; @@ -123,7 +123,7 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode 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; @@ -176,7 +176,7 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode } } zipcnt++; - zn = zn->sibling; + zn = zn->next; } #ifndef _CONSOLE if (first && tmphist[0]) @@ -203,7 +203,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig struct zvolume *zv; struct znode *zn; - zv = getzvolume (zf, id); + zv = getzvolume (NULL, zf, id); if (!zv) return; zn = &zv->root; @@ -222,7 +222,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig } } } - zn = zn->sibling; + zn = zn->next; } zfile_fclose_archive (zv); } @@ -886,7 +886,7 @@ struct zvolume *archive_directory_plain (struct zfile *z) 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); @@ -908,13 +908,15 @@ struct zfile *archive_access_plain (struct znode *zn) 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; } @@ -929,6 +931,24 @@ struct adfhandle { 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++; @@ -940,14 +960,24 @@ static TCHAR *getBSTR (uae_u8 *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; @@ -985,13 +1015,14 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name) 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; @@ -1002,12 +1033,12 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name) 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 }; @@ -1017,10 +1048,8 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name) _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; @@ -1032,17 +1061,103 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name) 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); @@ -1050,81 +1165,285 @@ struct zvolume *archive_directory_adf (struct zfile *z) 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) @@ -1175,10 +1494,10 @@ struct zvolume *archive_directory_rdb (struct zfile *z) 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); @@ -1194,31 +1513,37 @@ struct zvolume *archive_directory_rdb (struct zfile *z) 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;