PageRenderTime 67ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/zfile.cpp

https://github.com/tonioni/WinUAE
C++ | 3521 lines | 3246 code | 238 blank | 37 comment | 1148 complexity | 4642264c93cd508c0e0245cc6d738082 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * UAE - The Un*x Amiga Emulator
  3. *
  4. * routines to handle compressed file automatically
  5. *
  6. * (c) 1996 Samuel Devulder, Tim Gunn
  7. * 2002-2007 Toni Wilen
  8. */
  9. #define RECURSIVE_ARCHIVES 1
  10. //#define ZFILE_DEBUG
  11. #include "sysconfig.h"
  12. #include "sysdeps.h"
  13. #include "options.h"
  14. #include "zfile.h"
  15. #include "disk.h"
  16. #include "gui.h"
  17. #include "crc32.h"
  18. #include "fsdb.h"
  19. #include "fsusage.h"
  20. #include "zarchive.h"
  21. #include "diskutil.h"
  22. #include "fdi2raw.h"
  23. #include "uae/io.h"
  24. #include "archivers/zip/unzip.h"
  25. #include "archivers/dms/pfile.h"
  26. #include "archivers/wrp/warp.h"
  27. static struct zfile *zlist = 0;
  28. const TCHAR *uae_archive_extensions[] = { _T("zip"), _T("rar"), _T("7z"), _T("lha"), _T("lzh"), _T("lzx"), _T("tar"), NULL };
  29. #define MAX_CACHE_ENTRIES 10
  30. struct zdisktrack
  31. {
  32. void *data;
  33. int len;
  34. };
  35. struct zdiskimage
  36. {
  37. int tracks;
  38. struct zdisktrack zdisktracks[2 * 84];
  39. };
  40. struct zcache
  41. {
  42. TCHAR *name;
  43. struct zdiskimage *zd;
  44. void *data;
  45. int size;
  46. struct zcache *next;
  47. time_t tm;
  48. };
  49. static struct zcache *zcachedata;
  50. static struct zcache *cache_get (const TCHAR *name)
  51. {
  52. struct zcache *zc = zcachedata;
  53. while (zc) {
  54. if (!_tcscmp (name, zc->name)) {
  55. zc->tm = time (NULL);
  56. return zc;
  57. }
  58. zc = zc->next;
  59. }
  60. return NULL;
  61. }
  62. static void zcache_flush (void)
  63. {
  64. }
  65. static void zcache_free_data (struct zcache *zc)
  66. {
  67. int i;
  68. if (zc->zd) {
  69. for (i = 0; i < zc->zd->tracks; i++) {
  70. xfree (zc->zd->zdisktracks[i].data);
  71. }
  72. xfree (zc->zd);
  73. }
  74. xfree (zc->data);
  75. xfree (zc->name);
  76. }
  77. static void zcache_free (struct zcache *zc)
  78. {
  79. struct zcache *pl = NULL;
  80. struct zcache *l = zcachedata;
  81. struct zcache *nxt;
  82. while (l != zc) {
  83. if (l == 0)
  84. return;
  85. pl = l;
  86. l = l->next;
  87. }
  88. if (l)
  89. nxt = l->next;
  90. zcache_free_data (zc);
  91. if (l == 0)
  92. return;
  93. if(!pl)
  94. zcachedata = nxt;
  95. else
  96. pl->next = nxt;
  97. }
  98. static void zcache_close (void)
  99. {
  100. struct zcache *zc = zcachedata;
  101. while (zc) {
  102. struct zcache *n = zc->next;
  103. zcache_free_data (zc);
  104. xfree (n);
  105. zc = n;
  106. }
  107. }
  108. static void zcache_check (void)
  109. {
  110. int cnt = 0;
  111. struct zcache *zc = zcachedata, *last = NULL;
  112. while (zc) {
  113. last = zc;
  114. zc = zc->next;
  115. cnt++;
  116. }
  117. write_log (_T("CACHE: %d\n"), cnt);
  118. if (cnt >= MAX_CACHE_ENTRIES && last)
  119. zcache_free (last);
  120. }
  121. static struct zcache *zcache_put (const TCHAR *name, struct zdiskimage *data)
  122. {
  123. struct zcache *zc;
  124. zcache_check ();
  125. zc = xcalloc (struct zcache, 1);
  126. zc->next = zcachedata;
  127. zcachedata = zc;
  128. zc->zd = data;
  129. zc->name = my_strdup (name);
  130. zc->tm = time (NULL);
  131. return zc;
  132. }
  133. static void checkarchiveparent (struct zfile *z)
  134. {
  135. // unpack completely if opened in PEEK mode
  136. if (z->archiveparent)
  137. archive_unpackzfile (z);
  138. }
  139. static struct zfile *zfile_create (struct zfile *prev, const TCHAR *originalname)
  140. {
  141. struct zfile *z;
  142. z = xmalloc (struct zfile, 1);
  143. if (!z)
  144. return 0;
  145. memset (z, 0, sizeof *z);
  146. z->next = zlist;
  147. zlist = z;
  148. z->opencnt = 1;
  149. if (prev && prev->originalname)
  150. z->originalname = my_strdup(prev->originalname);
  151. else if (originalname)
  152. z->originalname = my_strdup(originalname);
  153. if (prev) {
  154. z->zfdmask = prev->zfdmask;
  155. }
  156. return z;
  157. }
  158. static void zfile_free (struct zfile *f)
  159. {
  160. if (f->f)
  161. fclose (f->f);
  162. if (f->deleteafterclose) {
  163. _wunlink (f->name);
  164. write_log (_T("deleted temporary file '%s'\n"), f->name);
  165. }
  166. xfree (f->name);
  167. xfree (f->originalname);
  168. xfree (f->data);
  169. xfree (f->mode);
  170. xfree (f->userdata);
  171. xfree (f);
  172. }
  173. void zfile_exit (void)
  174. {
  175. struct zfile *l;
  176. while ((l = zlist)) {
  177. zlist = l->next;
  178. zfile_free (l);
  179. }
  180. }
  181. void zfile_fclose (struct zfile *f)
  182. {
  183. //write_log (_T("%p\n"), f);
  184. if (!f)
  185. return;
  186. if (f->opencnt < 0) {
  187. write_log (_T("zfile: tried to free already closed filehandle!\n"));
  188. return;
  189. }
  190. f->opencnt--;
  191. if (f->opencnt > 0)
  192. return;
  193. f->opencnt = -100;
  194. if (f->parent) {
  195. f->parent->opencnt--;
  196. if (f->parent->opencnt <= 0)
  197. zfile_fclose (f->parent);
  198. }
  199. if (f->archiveparent) {
  200. zfile_fclose (f->archiveparent);
  201. f->archiveparent = NULL;
  202. }
  203. struct zfile *pl = NULL;
  204. struct zfile *nxt;
  205. struct zfile *l = zlist;
  206. while (l != f) {
  207. if (l == 0) {
  208. write_log (_T("zfile: tried to free already freed or nonexisting filehandle!\n"));
  209. return;
  210. }
  211. pl = l;
  212. l = l->next;
  213. }
  214. if (l)
  215. nxt = l->next;
  216. zfile_free (f);
  217. if (l == 0)
  218. return;
  219. if(!pl)
  220. zlist = nxt;
  221. else
  222. pl->next = nxt;
  223. }
  224. static void removeext (TCHAR *s, const TCHAR *ext)
  225. {
  226. if (_tcslen (s) < _tcslen (ext))
  227. return;
  228. if (_tcsicmp (s + _tcslen (s) - _tcslen (ext), ext) == 0)
  229. s[_tcslen (s) - _tcslen (ext)] = 0;
  230. }
  231. static bool checkwrite (struct zfile *zf, int *retcode)
  232. {
  233. if (zfile_needwrite (zf)) {
  234. if (retcode)
  235. *retcode = -1;
  236. return true;
  237. }
  238. return false;
  239. }
  240. static uae_u8 exeheader[]={ 0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00 };
  241. static const TCHAR *diskimages[] = { _T("adf"), _T("adz"), _T("ipf"), _T("scp"), _T("fdi"), _T("dms"), _T("wrp"), _T("dsq"), _T("pkd"), _T("ima"), 0 };
  242. int zfile_gettype (struct zfile *z)
  243. {
  244. uae_u8 buf[8];
  245. TCHAR *ext;
  246. if (!z || !z->name)
  247. return ZFILE_UNKNOWN;
  248. ext = _tcsrchr (z->name, '.');
  249. if (ext != NULL) {
  250. int i;
  251. ext++;
  252. for (i = 0; diskimages[i]; i++) {
  253. if (strcasecmp (ext, diskimages[i]) == 0)
  254. return ZFILE_DISKIMAGE;
  255. }
  256. if (strcasecmp (ext, _T("roz")) == 0)
  257. return ZFILE_ROM;
  258. if (strcasecmp (ext, _T("uss")) == 0)
  259. return ZFILE_STATEFILE;
  260. if (strcasecmp (ext, _T("rom")) == 0)
  261. return ZFILE_ROM;
  262. if (strcasecmp (ext, _T("bin")) == 0)
  263. return ZFILE_ROM;
  264. if (strcasecmp (ext, _T("key")) == 0)
  265. return ZFILE_KEY;
  266. if (strcasecmp (ext, _T("nvr")) == 0)
  267. return ZFILE_NVR;
  268. if (strcasecmp (ext, _T("uae")) == 0)
  269. return ZFILE_CONFIGURATION;
  270. if (strcasecmp(ext, _T("cue")) == 0 || strcasecmp(ext, _T("iso")) == 0 || strcasecmp(ext, _T("ccd")) == 0 ||
  271. strcasecmp(ext, _T("mds")) == 0 || strcasecmp(ext, _T("chd")) == 0 || strcasecmp(ext, _T("nrg")) == 0)
  272. return ZFILE_CDIMAGE;
  273. }
  274. memset (buf, 0, sizeof (buf));
  275. zfile_fread (buf, 8, 1, z);
  276. zfile_fseek (z, -8, SEEK_CUR);
  277. if (!memcmp (buf, exeheader, sizeof (buf)))
  278. return ZFILE_DISKIMAGE;
  279. if (!memcmp (buf, "CAPS", 4))
  280. return ZFILE_DISKIMAGE;
  281. if (!memcmp (buf, "SCP", 3))
  282. return ZFILE_DISKIMAGE;
  283. if (!memcmp (buf, "UAE--ADF", 8))
  284. return ZFILE_DISKIMAGE;
  285. if (!memcmp (buf, "UAE-1ADF", 8))
  286. return ZFILE_DISKIMAGE;
  287. if (!memcmp (buf, "Formatte", 8))
  288. return ZFILE_DISKIMAGE;
  289. if (!memcmp (buf, "RDSK", 4))
  290. return ZFILE_HDFRDB;
  291. if (!memcmp (buf, "DOS", 3)) {
  292. if (z->size < 4 * 1024 * 1024)
  293. return ZFILE_DISKIMAGE;
  294. else
  295. return ZFILE_HDF;
  296. }
  297. if (ext != NULL) {
  298. if (strcasecmp (ext, _T("hdf")) == 0)
  299. return ZFILE_HDF;
  300. if (strcasecmp (ext, _T("hdz")) == 0)
  301. return ZFILE_HDF;
  302. if (strcasecmp (ext, _T("vhd")) == 0)
  303. return ZFILE_HDF;
  304. }
  305. return ZFILE_UNKNOWN;
  306. }
  307. #define VHD_DYNAMIC 3
  308. #define VHD_FIXED 2
  309. STATIC_INLINE uae_u32 gl (uae_u8 *p)
  310. {
  311. return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
  312. }
  313. static uae_u32 vhd_checksum (uae_u8 *p, int offset)
  314. {
  315. int i;
  316. uae_u32 sum;
  317. sum = 0;
  318. for (i = 0; i < 512; i++) {
  319. if (offset >= 0 && i >= offset && i < offset + 4)
  320. continue;
  321. sum += p[i];
  322. }
  323. return ~sum;
  324. }
  325. struct zfile_vhd
  326. {
  327. int vhd_type;
  328. uae_u64 virtsize;
  329. uae_u32 vhd_bamoffset;
  330. uae_u32 vhd_blocksize;
  331. uae_u8 *vhd_header, *vhd_sectormap;
  332. uae_u64 vhd_footerblock;
  333. uae_u32 vhd_bamsize;
  334. uae_u64 vhd_sectormapblock;
  335. uae_u32 vhd_bitmapsize;
  336. };
  337. static uae_u64 vhd_fread2 (struct zfile *zf, void *dataptrv, uae_u64 offset, uae_u64 len)
  338. {
  339. uae_u32 bamoffset;
  340. uae_u32 sectoroffset;
  341. uae_u64 read;
  342. struct zfile *zp = zf->parent;
  343. struct zfile_vhd *zvhd = (struct zfile_vhd*)zf->userdata;
  344. uae_u8 *dataptr = (uae_u8*)dataptrv;
  345. //write_log (_T("%08x %08x\n"), (uae_u32)offset, (uae_u32)len);
  346. read = 0;
  347. if (offset & 511)
  348. return read;
  349. if (len & 511)
  350. return read;
  351. while (len > 0) {
  352. bamoffset = (offset / zvhd->vhd_blocksize) * 4 + zvhd->vhd_bamoffset;
  353. sectoroffset = gl (zvhd->vhd_header + bamoffset);
  354. if (sectoroffset == 0xffffffff) {
  355. memset (dataptr, 0, 512);
  356. read += 512;
  357. } else {
  358. int bitmapoffsetbits;
  359. int bitmapoffsetbytes;
  360. int sectormapblock;
  361. bitmapoffsetbits = (offset / 512) % (zvhd->vhd_blocksize / 512);
  362. bitmapoffsetbytes = bitmapoffsetbits / 8;
  363. sectormapblock = sectoroffset * 512 + (bitmapoffsetbytes & ~511);
  364. if (zvhd->vhd_sectormapblock != sectormapblock) {
  365. // read sector bitmap
  366. //write_log (_T("BM %08x\n"), sectormapblock);
  367. zfile_fseek (zp, sectormapblock, SEEK_SET);
  368. if (zfile_fread (zvhd->vhd_sectormap, 1, 512, zp) != 512)
  369. return read;
  370. zvhd->vhd_sectormapblock = sectormapblock;
  371. }
  372. // block allocated in bitmap?
  373. if (zvhd->vhd_sectormap[bitmapoffsetbytes & 511] & (1 << (7 - (bitmapoffsetbits & 7)))) {
  374. // read data block
  375. int block = sectoroffset * 512 + zvhd->vhd_bitmapsize + bitmapoffsetbits * 512;
  376. //write_log (_T("DB %08x\n"), block);
  377. zfile_fseek (zp, block, SEEK_SET);
  378. if (zfile_fread (dataptr, 1, 512, zp) != 512)
  379. return read;
  380. } else {
  381. memset (dataptr, 0, 512);
  382. }
  383. read += 512;
  384. }
  385. len -= 512;
  386. dataptr += 512;
  387. offset += 512;
  388. }
  389. return read;
  390. }
  391. static uae_s64 vhd_fread (void *data, uae_u64 l1, uae_u64 l2, struct zfile *zf)
  392. {
  393. uae_u64 size = l1 * l2;
  394. uae_u64 out = 0;
  395. int len = 0;
  396. if (!l1 || !l2)
  397. return 0;
  398. if ((zf->seek & 511) || (size & 511)) {
  399. uae_u8 tmp[512];
  400. if (zf->seek & 511) {
  401. int s;
  402. s = 512 - (zf->seek & 511);
  403. vhd_fread2 (zf, tmp, zf->seek & ~511, 512);
  404. memcpy ((uae_u8*)data + len, tmp + 512 - s, s);
  405. len += s;
  406. out += s;
  407. zf->seek += s;
  408. }
  409. while (size > 0) {
  410. int s = size > 512 ? 512 : size;
  411. vhd_fread2 (zf, tmp, zf->seek, 512);
  412. memcpy ((uae_u8*)data + len, tmp, s);
  413. zf->seek += s;
  414. size -= s;
  415. out += s;
  416. }
  417. } else {
  418. out = vhd_fread2 (zf, data, zf->seek, size);
  419. zf->seek += out;
  420. out /= l1;
  421. }
  422. return out;
  423. }
  424. static struct zfile *vhd (struct zfile *z)
  425. {
  426. uae_u8 tmp[512], tmp2[512];
  427. uae_u32 v;
  428. struct zfile_vhd *zvhd;
  429. uae_u64 fsize;
  430. zvhd = xcalloc (struct zfile_vhd, 1);
  431. zfile_fseek (z, 0, SEEK_END);
  432. fsize = zfile_ftell (z);
  433. zfile_fseek (z, 0, SEEK_SET);
  434. if (zfile_fread (tmp, 1, 512, z) != 512)
  435. goto nonvhd;
  436. v = gl (tmp + 8); // features
  437. if ((v & 3) != 2)
  438. goto nonvhd;
  439. v = gl (tmp + 8 + 4); // version
  440. if ((v >> 16) != 1)
  441. goto nonvhd;
  442. zvhd->vhd_type = gl (tmp + 8 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 8 + 4);
  443. if (zvhd->vhd_type != VHD_FIXED && zvhd->vhd_type != VHD_DYNAMIC)
  444. goto nonvhd;
  445. v = gl (tmp + 8 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 4);
  446. if (v == 0)
  447. goto nonvhd;
  448. if (vhd_checksum (tmp, 8 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 4) != v)
  449. goto nonvhd;
  450. zfile_fseek (z, fsize - sizeof tmp2, SEEK_SET);
  451. if (zfile_fread (tmp2, 1, 512, z) != 512)
  452. goto end;
  453. if (memcmp (tmp, tmp2, sizeof tmp))
  454. goto nonvhd;
  455. zvhd->vhd_footerblock = fsize - 512;
  456. zvhd->virtsize = (uae_u64)(gl (tmp + 8 + 4 + 4 + 8 + 4 + 4 +4 + 4 + 8)) << 32;
  457. zvhd->virtsize |= gl (tmp + 8 + 4 + 4 + 8 + 4 + 4 +4 + 4 + 8 + 4);
  458. if (zvhd->vhd_type == VHD_DYNAMIC) {
  459. uae_u32 size;
  460. zvhd->vhd_bamoffset = gl (tmp + 8 + 4 + 4 + 4);
  461. if (zvhd->vhd_bamoffset == 0 || zvhd->vhd_bamoffset >= fsize)
  462. goto end;
  463. zfile_fseek (z, zvhd->vhd_bamoffset, SEEK_SET);
  464. if (zfile_fread (tmp, 1, 512, z) != 512)
  465. goto end;
  466. v = gl (tmp + 8 + 8 + 8 + 4 + 4 + 4);
  467. if (vhd_checksum (tmp, 8 + 8 + 8 + 4 + 4 + 4) != v)
  468. goto end;
  469. v = gl (tmp + 8 + 8 + 8);
  470. if ((v >> 16) != 1)
  471. goto end;
  472. zvhd->vhd_blocksize = gl (tmp + 8 + 8 + 8 + 4 + 4);
  473. zvhd->vhd_bamoffset = gl (tmp + 8 + 8 + 4);
  474. zvhd->vhd_bamsize = (((zvhd->virtsize + zvhd->vhd_blocksize - 1) / zvhd->vhd_blocksize) * 4 + 511) & ~511;
  475. size = zvhd->vhd_bamoffset + zvhd->vhd_bamsize;
  476. zvhd->vhd_header = xmalloc (uae_u8, size);
  477. zfile_fseek (z, 0, SEEK_SET);
  478. if (zfile_fread (zvhd->vhd_header, 1, size, z) != size)
  479. goto end;
  480. zvhd->vhd_sectormap = xmalloc (uae_u8, 512);
  481. zvhd->vhd_sectormapblock = -1;
  482. zvhd->vhd_bitmapsize = ((zvhd->vhd_blocksize / (8 * 512)) + 511) & ~511;
  483. }
  484. z = zfile_fopen_parent (z, NULL, 0, zvhd->virtsize);
  485. z->useparent = 0;
  486. z->dataseek = 1;
  487. z->userdata = zvhd;
  488. z->zfileread = vhd_fread;
  489. write_log (_T("%s is VHD %s image, virtual size=%lldK\n"),
  490. zfile_getname (z),
  491. zvhd->vhd_type == 2 ? _T("fixed") : _T("dynamic"),
  492. zvhd->virtsize / 1024);
  493. return z;
  494. nonvhd:
  495. end:
  496. return z;
  497. }
  498. static struct zfile *zfile_gunzip (struct zfile *z, int *retcode)
  499. {
  500. uae_u8 header[2 + 1 + 1 + 4 + 1 + 1];
  501. z_stream zs;
  502. int i, size, ret, first;
  503. uae_u8 flags;
  504. uae_s64 offset;
  505. TCHAR name[MAX_DPATH];
  506. uae_u8 buffer[8192];
  507. struct zfile *z2;
  508. uae_u8 b;
  509. if (checkwrite (z, retcode))
  510. return NULL;
  511. _tcscpy (name, z->name);
  512. memset (&zs, 0, sizeof (zs));
  513. memset (header, 0, sizeof (header));
  514. zfile_fread (header, sizeof (header), 1, z);
  515. flags = header[3];
  516. if (header[0] != 0x1f && header[1] != 0x8b)
  517. return NULL;
  518. if (flags & 2) /* multipart not supported */
  519. return NULL;
  520. if (flags & 32) /* encryption not supported */
  521. return NULL;
  522. if (flags & 4) { /* skip extra field */
  523. zfile_fread (&b, 1, 1, z);
  524. size = b;
  525. zfile_fread (&b, 1, 1, z);
  526. size |= b << 8;
  527. zfile_fseek (z, size + 2, SEEK_CUR);
  528. }
  529. if (flags & 8) { /* get original file name */
  530. uae_char aname[MAX_DPATH];
  531. i = 0;
  532. do {
  533. zfile_fread (aname + i, 1, 1, z);
  534. } while (i < MAX_DPATH - 1 && aname[i++]);
  535. aname[i] = 0;
  536. au_copy (name, MAX_DPATH, aname);
  537. }
  538. if (flags & 16) { /* skip comment */
  539. i = 0;
  540. do {
  541. b = 0;
  542. zfile_fread (&b, 1, 1, z);
  543. } while (b);
  544. }
  545. removeext (name, _T(".gz"));
  546. offset = zfile_ftell (z);
  547. zfile_fseek (z, -4, SEEK_END);
  548. zfile_fread (&b, 1, 1, z);
  549. size = b;
  550. zfile_fread (&b, 1, 1, z);
  551. size |= b << 8;
  552. zfile_fread (&b, 1, 1, z);
  553. size |= b << 16;
  554. zfile_fread (&b, 1, 1, z);
  555. size |= b << 24;
  556. if (size < 8 || size > 256 * 1024 * 1024) /* safety check */
  557. return NULL;
  558. zfile_fseek (z, offset, SEEK_SET);
  559. z2 = zfile_fopen_empty (z, name, size);
  560. if (!z2)
  561. return NULL;
  562. zs.next_out = z2->data;
  563. zs.avail_out = size;
  564. first = 1;
  565. ret = Z_STREAM_ERROR;
  566. do {
  567. zs.next_in = buffer;
  568. zs.avail_in = zfile_fread (buffer, 1, sizeof (buffer), z);
  569. if (first) {
  570. if (inflateInit2_ (&zs, -MAX_WBITS, ZLIB_VERSION, sizeof (z_stream)) != Z_OK)
  571. break;
  572. first = 0;
  573. }
  574. ret = inflate (&zs, 0);
  575. } while (ret == Z_OK);
  576. inflateEnd (&zs);
  577. if (ret != Z_STREAM_END || first != 0) {
  578. zfile_fclose (z2);
  579. return NULL;
  580. }
  581. zfile_fclose (z);
  582. return z2;
  583. }
  584. struct zfile *zfile_gunzip (struct zfile *z)
  585. {
  586. return zfile_gunzip (z, NULL);
  587. }
  588. static void truncate880k (struct zfile *z)
  589. {
  590. int i;
  591. uae_u8 *b;
  592. if (z == NULL || z->data == NULL)
  593. return;
  594. if (z->size < 880 * 512 * 2) {
  595. int size = 880 * 512 * 2 - z->size;
  596. b = xcalloc (uae_u8, size);
  597. zfile_fwrite (b, size, 1, z);
  598. xfree (b);
  599. return;
  600. }
  601. for (i = 880 * 512 * 2; i < z->size; i++) {
  602. if (z->data[i])
  603. return;
  604. }
  605. z->size = 880 * 512 * 2;
  606. }
  607. static struct zfile *extadf (struct zfile *z, int index, int *retcode)
  608. {
  609. int i, r;
  610. struct zfile *zo;
  611. uae_u16 *mfm;
  612. uae_u16 *amigamfmbuffer;
  613. uae_u8 writebuffer_ok[32], *outbuf;
  614. int tracks, len, offs, pos;
  615. uae_u8 buffer[2 + 2 + 4 + 4];
  616. int outsize;
  617. TCHAR newname[MAX_DPATH];
  618. TCHAR *ext;
  619. int cantrunc = 0;
  620. int done = 0;
  621. if (index > 1)
  622. return NULL;
  623. mfm = xcalloc (uae_u16, 32000 / 2);
  624. amigamfmbuffer = xcalloc (uae_u16, 32000 / 2);
  625. outbuf = xcalloc (uae_u8, 16384);
  626. zfile_fread (buffer, 1, 8, z);
  627. zfile_fread (buffer, 1, 4, z);
  628. tracks = buffer[2] * 256 + buffer[3];
  629. offs = 8 + 2 + 2 + tracks * (2 + 2 + 4 + 4);
  630. _tcscpy (newname, zfile_getname (z));
  631. ext = _tcsrchr (newname, '.');
  632. if (ext) {
  633. _tcscpy (newname + _tcslen (newname) - _tcslen (ext), _T(".std.adf"));
  634. } else {
  635. _tcscat (newname, _T(".std.adf"));
  636. }
  637. if (index > 0)
  638. _tcscpy (newname + _tcslen (newname) - 4, _T(".ima"));
  639. zo = zfile_fopen_empty (z, newname, 0);
  640. if (!zo)
  641. goto end;
  642. if (retcode)
  643. *retcode = 1;
  644. pos = 12;
  645. outsize = 0;
  646. for (i = 0; i < tracks; i++) {
  647. int type, bitlen;
  648. zfile_fseek (z, pos, SEEK_SET);
  649. zfile_fread (buffer, 2 + 2 + 4 + 4, 1, z);
  650. pos = zfile_ftell (z);
  651. type = buffer[2] * 256 + buffer[3];
  652. len = buffer[5] * 65536 + buffer[6] * 256 + buffer[7];
  653. bitlen = buffer[9] * 65536 + buffer[10] * 256 + buffer[11];
  654. zfile_fseek (z, offs, SEEK_SET);
  655. if (type == 1) {
  656. zfile_fread (mfm, len, 1, z);
  657. memset (writebuffer_ok, 0, sizeof writebuffer_ok);
  658. memset (outbuf, 0, 16384);
  659. if (index == 0) {
  660. r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
  661. if (r < 0 && i == 0) {
  662. zfile_seterror (_T("'%s' is not AmigaDOS formatted"), zo->name);
  663. goto end;
  664. }
  665. if (i == 0)
  666. done = 1;
  667. } else {
  668. r = ispctrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
  669. if (r < 0 && i == 0) {
  670. zfile_seterror (_T("'%s' is not PC formatted"), zo->name);
  671. goto end;
  672. }
  673. if (i == 0)
  674. done = 1;
  675. }
  676. } else {
  677. outsize = 512 * 11;
  678. if (bitlen / 8 > 18000)
  679. outsize *= 2;
  680. zfile_fread (outbuf, outsize, 1, z);
  681. cantrunc = 1;
  682. if (index == 0)
  683. done = 1;
  684. }
  685. zfile_fwrite (outbuf, outsize, 1, zo);
  686. offs += len;
  687. }
  688. if (done == 0)
  689. goto end;
  690. zfile_fclose (z);
  691. xfree (mfm);
  692. xfree (amigamfmbuffer);
  693. if (cantrunc)
  694. truncate880k (zo);
  695. return zo;
  696. end:
  697. zfile_fclose (zo);
  698. xfree (mfm);
  699. xfree (amigamfmbuffer);
  700. return NULL;
  701. }
  702. #include "fdi2raw.h"
  703. static struct zfile *fdi (struct zfile *z, int index, int *retcode)
  704. {
  705. int i, j, r;
  706. struct zfile *zo;
  707. TCHAR *orgname = zfile_getname (z);
  708. TCHAR *ext = _tcsrchr (orgname, '.');
  709. TCHAR newname[MAX_DPATH];
  710. uae_u16 *amigamfmbuffer;
  711. uae_u8 writebuffer_ok[32], *outbuf;
  712. int tracks, len, outsize;
  713. FDI *fdi;
  714. int startpos = 0;
  715. uae_u8 tmp[12];
  716. struct zcache *zc;
  717. if (checkwrite (z, retcode))
  718. return NULL;
  719. if (index > 2)
  720. return NULL;
  721. zc = cache_get (z->name);
  722. if (!zc) {
  723. uae_u16 *mfm;
  724. struct zdiskimage *zd;
  725. fdi = fdi2raw_header (z);
  726. if (!fdi)
  727. return NULL;
  728. mfm = xcalloc (uae_u16, 32000 / 2);
  729. zd = xcalloc (struct zdiskimage, 1);
  730. tracks = fdi2raw_get_last_track (fdi);
  731. zd->tracks = tracks;
  732. for (i = 0; i < tracks; i++) {
  733. uae_u8 *buf, *p;
  734. fdi2raw_loadtrack (fdi, mfm, NULL, i, &len, NULL, NULL, 1);
  735. len /= 8;
  736. buf = p = xmalloc (uae_u8, len);
  737. for (j = 0; j < len / 2; j++) {
  738. uae_u16 v = mfm[j];
  739. *p++ = v >> 8;
  740. *p++ = v;
  741. }
  742. zd->zdisktracks[i].data = buf;
  743. zd->zdisktracks[i].len = len;
  744. }
  745. fdi2raw_header_free (fdi);
  746. zc = zcache_put (z->name, zd);
  747. }
  748. amigamfmbuffer = xcalloc (uae_u16, 32000 / 2);
  749. outbuf = xcalloc (uae_u8, 16384);
  750. tracks = zc->zd->tracks;
  751. if (ext) {
  752. _tcscpy (newname, orgname);
  753. _tcscpy (newname + _tcslen (newname) - _tcslen (ext), _T(".adf"));
  754. } else {
  755. _tcscat (newname, _T(".adf"));
  756. }
  757. if (index == 1)
  758. _tcscpy (newname + _tcslen (newname) - 4, _T(".ima"));
  759. if (index == 2)
  760. _tcscpy (newname + _tcslen (newname) - 4, _T(".ext.adf"));
  761. zo = zfile_fopen_empty (z, newname, 0);
  762. if (!zo)
  763. goto end;
  764. if (retcode)
  765. *retcode = 1;
  766. if (index > 1) {
  767. zfile_fwrite ("UAE-1ADF", 8, 1, zo);
  768. tmp[0] = 0; tmp[1] = 0; /* flags (reserved) */
  769. tmp[2] = 0; tmp[3] = tracks; /* number of tracks */
  770. zfile_fwrite (tmp, 4, 1, zo);
  771. memset (tmp, 0, sizeof tmp);
  772. tmp[2] = 0; tmp[3] = 1; /* track type */
  773. startpos = zfile_ftell (zo);
  774. for (i = 0; i < tracks; i++)
  775. zfile_fwrite (tmp, sizeof tmp, 1, zo);
  776. }
  777. outsize = 0;
  778. for (i = 0; i < tracks; i++) {
  779. uae_u8 *p = (uae_u8*)zc->zd->zdisktracks[i].data;
  780. len = zc->zd->zdisktracks[i].len;
  781. memset (writebuffer_ok, 0, sizeof writebuffer_ok);
  782. memset (outbuf, 0, 16384);
  783. if (index == 0) {
  784. r = isamigatrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
  785. if (r < 0 && i == 0) {
  786. zfile_seterror (_T("'%s' is not AmigaDOS formatted"), orgname);
  787. goto end;
  788. }
  789. zfile_fwrite (outbuf, outsize, 1, zo);
  790. } else if (index == 1) {
  791. r = ispctrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
  792. if (r < 0 && i == 0) {
  793. zfile_seterror (_T("'%s' is not PC formatted"), orgname);
  794. goto end;
  795. }
  796. zfile_fwrite (outbuf, outsize, 1, zo);
  797. } else {
  798. int pos = zfile_ftell (zo);
  799. int maxlen = len > 12798 ? len : 12798;
  800. int lenb = len * 8;
  801. if (maxlen & 1)
  802. maxlen++;
  803. zfile_fseek (zo, startpos + i * 12 + 4, SEEK_SET);
  804. tmp[4] = 0; tmp[5] = 0; tmp[6] = maxlen >> 8; tmp[7] = maxlen;
  805. tmp[8] = lenb >> 24; tmp[9] = lenb >> 16; tmp[10] = lenb >> 8; tmp[11] = lenb;
  806. zfile_fwrite (tmp + 4, 2, 4, zo);
  807. zfile_fseek (zo, pos, SEEK_SET);
  808. zfile_fwrite (p, 1, len, zo);
  809. if (maxlen > len)
  810. zfile_fwrite (outbuf, 1, maxlen - len, zo);
  811. }
  812. }
  813. zfile_fclose (z);
  814. xfree (amigamfmbuffer);
  815. xfree (outbuf);
  816. if (index == 0)
  817. truncate880k (zo);
  818. return zo;
  819. end:
  820. zfile_fclose (zo);
  821. xfree (amigamfmbuffer);
  822. xfree (outbuf);
  823. return NULL;
  824. }
  825. #ifdef CAPS
  826. #include "caps/caps_win32.h"
  827. static struct zfile *ipf (struct zfile *z, int index, int *retcode)
  828. {
  829. int i, j, r;
  830. struct zfile *zo;
  831. TCHAR *orgname = zfile_getname (z);
  832. TCHAR *ext = _tcsrchr (orgname, '.');
  833. TCHAR newname[MAX_DPATH];
  834. uae_u16 *amigamfmbuffer;
  835. uae_u8 writebuffer_ok[32];
  836. int tracks, len;
  837. int outsize;
  838. int startpos = 0;
  839. uae_u8 *outbuf;
  840. uae_u8 tmp[12];
  841. struct zcache *zc;
  842. if (checkwrite (z, retcode))
  843. return NULL;
  844. if (index > 2)
  845. return NULL;
  846. zc = cache_get (z->name);
  847. if (!zc) {
  848. uae_u16 *mfm;
  849. struct zdiskimage *zd;
  850. if (!caps_loadimage (z, 0, &tracks))
  851. return NULL;
  852. mfm = xcalloc (uae_u16, 32000 / 2);
  853. zd = xcalloc (struct zdiskimage, 1);
  854. zd->tracks = tracks;
  855. for (i = 0; i < tracks; i++) {
  856. uae_u8 *buf, *p;
  857. int mrev, gapo;
  858. caps_loadtrack (mfm, NULL, 0, i, &len, &mrev, &gapo, NULL, true);
  859. //write_log (_T("%d: %d %d %d\n"), i, mrev, gapo, len);
  860. len /= 8;
  861. buf = p = xmalloc (uae_u8, len);
  862. for (j = 0; j < len / 2; j++) {
  863. uae_u16 v = mfm[j];
  864. *p++ = v >> 8;
  865. *p++ = v;
  866. }
  867. zd->zdisktracks[i].data = buf;
  868. zd->zdisktracks[i].len = len;
  869. }
  870. caps_unloadimage (0);
  871. zc = zcache_put (z->name, zd);
  872. }
  873. outbuf = xcalloc (uae_u8, 16384);
  874. amigamfmbuffer = xcalloc (uae_u16, 32000 / 2);
  875. if (ext) {
  876. _tcscpy (newname, orgname);
  877. _tcscpy (newname + _tcslen (newname) - _tcslen (ext), _T(".adf"));
  878. } else {
  879. _tcscat (newname, _T(".adf"));
  880. }
  881. if (index == 1)
  882. _tcscpy (newname + _tcslen (newname) - 4, _T(".ima"));
  883. if (index == 2)
  884. _tcscpy (newname + _tcslen (newname) - 4, _T(".ext.adf"));
  885. zo = zfile_fopen_empty (z, newname, 0);
  886. if (!zo)
  887. goto end;
  888. if (retcode)
  889. *retcode = 1;
  890. tracks = zc->zd->tracks;
  891. if (index > 1) {
  892. zfile_fwrite ("UAE-1ADF", 8, 1, zo);
  893. tmp[0] = 0; tmp[1] = 0; /* flags (reserved) */
  894. tmp[2] = 0; tmp[3] = tracks; /* number of tracks */
  895. zfile_fwrite (tmp, 4, 1, zo);
  896. memset (tmp, 0, sizeof tmp);
  897. tmp[2] = 0; tmp[3] = 1; /* track type */
  898. startpos = zfile_ftell (zo);
  899. for (i = 0; i < tracks; i++)
  900. zfile_fwrite (tmp, sizeof tmp, 1, zo);
  901. }
  902. outsize = 0;
  903. for (i = 0; i < tracks; i++) {
  904. uae_u8 *p = (uae_u8*)zc->zd->zdisktracks[i].data;
  905. len = zc->zd->zdisktracks[i].len;
  906. memset (writebuffer_ok, 0, sizeof writebuffer_ok);
  907. memset (outbuf, 0, 16384);
  908. if (index == 0) {
  909. r = isamigatrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
  910. if (r < 0 && i == 0) {
  911. zfile_seterror (_T("'%s' is not AmigaDOS formatted"), orgname);
  912. goto end;
  913. }
  914. zfile_fwrite (outbuf, 1, outsize, zo);
  915. } else if (index == 1) {
  916. r = ispctrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
  917. if (r < 0 && i == 0) {
  918. zfile_seterror (_T("'%s' is not PC formatted"), orgname);
  919. goto end;
  920. }
  921. zfile_fwrite (outbuf, outsize, 1, zo);
  922. } else {
  923. int pos = zfile_ftell (zo);
  924. int maxlen = len > 12798 ? len : 12798;
  925. int lenb = len * 8;
  926. if (maxlen & 1)
  927. maxlen++;
  928. zfile_fseek (zo, startpos + i * 12 + 4, SEEK_SET);
  929. tmp[4] = 0; tmp[5] = 0; tmp[6] = maxlen >> 8; tmp[7] = maxlen;
  930. tmp[8] = lenb >> 24; tmp[9] = lenb >> 16; tmp[10] = lenb >> 8; tmp[11] = lenb;
  931. zfile_fwrite (tmp + 4, 2, 4, zo);
  932. zfile_fseek (zo, pos, SEEK_SET);
  933. zfile_fwrite (p, 1, len, zo);
  934. if (maxlen > len)
  935. zfile_fwrite (outbuf, 1, maxlen - len, zo);
  936. }
  937. }
  938. zfile_fclose (z);
  939. xfree (amigamfmbuffer);
  940. xfree (outbuf);
  941. if (index == 0)
  942. truncate880k (zo);
  943. return zo;
  944. end:
  945. zfile_fclose (zo);
  946. xfree (amigamfmbuffer);
  947. xfree (outbuf);
  948. return NULL;
  949. }
  950. #endif
  951. #ifdef A_LZX
  952. static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
  953. {
  954. struct zfile *zi = NULL;
  955. struct zvolume *zv = NULL;
  956. if (checkwrite (z, retcode))
  957. return NULL;
  958. if (lzx) {
  959. zv = archive_directory_lzx (z);
  960. if (zv) {
  961. if (zv->root.child)
  962. zi = archive_access_lzx (zv->root.child);
  963. }
  964. } else {
  965. zi = z;
  966. }
  967. if (zi) {
  968. uae_u8 *buf = zfile_getdata (zi, 0, -1, NULL);
  969. if (!memcmp (buf, "PKD\x13", 4) || !memcmp (buf, "PKD\x11", 4)) {
  970. TCHAR *fn;
  971. int sectors = buf[18];
  972. int reserved = buf[15];
  973. int blocks = (buf[6] << 8) | buf[7];
  974. int blocksize = (buf[10] << 8) | buf[11];
  975. struct zfile *zo;
  976. int size = blocks * blocksize;
  977. int off;
  978. int i;
  979. uae_u8 *bitmap = NULL;
  980. uae_u8 *nullsector;
  981. nullsector = xcalloc (uae_u8, blocksize);
  982. sectors /= 2;
  983. if (buf[3] == 0x13) {
  984. off = 52;
  985. if (buf[off - 1] == 1) {
  986. bitmap = &buf[off];
  987. off += (blocks + 7) / 8;
  988. } else if (buf[off - 1] > 1) {
  989. write_log (_T("unknown DSQ extra header type %d\n"), buf[off - 1]);
  990. }
  991. } else {
  992. off = 32;
  993. }
  994. // some Amiga disk images are smaller than full adf for some reason
  995. if (sectors == 11 && size < 1760 * 512)
  996. size = 1760 * 512;
  997. if (zfile_getfilename (zi) && _tcslen (zfile_getfilename (zi))) {
  998. fn = xmalloc (TCHAR, (_tcslen (zfile_getfilename (zi)) + 5));
  999. _tcscpy (fn, zfile_getfilename (zi));
  1000. _tcscat (fn, _T(".adf"));
  1001. } else {
  1002. fn = my_strdup (_T("dsq.adf"));
  1003. }
  1004. zo = zfile_fopen_empty (z, fn, size);
  1005. xfree (fn);
  1006. int seccnt = 0;
  1007. for (i = 0; i < blocks; i++) {
  1008. int bmoff = i - 2;
  1009. int boff = -1;
  1010. uae_u32 mask = 0;
  1011. if (bitmap) {
  1012. boff = (bmoff / 32) * 4;
  1013. mask = (bitmap[boff] << 24) | (bitmap[boff + 1] << 16) | (bitmap[boff + 2] << 8) | (bitmap[boff + 3]);
  1014. }
  1015. if (bmoff >= 0 && boff >= 0 && (mask & (1 << (bmoff & 31)))) {
  1016. zfile_fwrite (nullsector, blocksize, 1, zo);
  1017. } else {
  1018. zfile_fwrite (buf + off, blocksize, 1, zo);
  1019. off += blocksize;
  1020. seccnt++;
  1021. }
  1022. if ((i % sectors) == sectors - 1) {
  1023. off += seccnt * 16;
  1024. seccnt = 0;
  1025. }
  1026. }
  1027. zfile_fclose_archive (zv);
  1028. zfile_fclose (z);
  1029. xfree (buf);
  1030. xfree (nullsector);
  1031. return zo;
  1032. }
  1033. xfree (buf);
  1034. }
  1035. if (lzx)
  1036. zfile_fclose (zi);
  1037. return z;
  1038. }
  1039. #endif
  1040. #ifdef A_WRP
  1041. static struct zfile *wrp (struct zfile *z, int *retcode)
  1042. {
  1043. if (zfile_needwrite (z)) {
  1044. if (retcode)
  1045. *retcode = -1;
  1046. return NULL;
  1047. }
  1048. return unwarp (z);
  1049. }
  1050. #endif
  1051. #ifdef A_7Z
  1052. #include "7z/Xz.h"
  1053. #include "7z/Lzmadec.h"
  1054. #include "7z/7zCrc.h"
  1055. static void *SzAlloc (void *p, size_t size)
  1056. {
  1057. return xmalloc (uae_u8, size);
  1058. }
  1059. static void SzFree(void *p, void *address)
  1060. {
  1061. xfree (address);
  1062. }
  1063. #define XZ_OUT_SIZE 10000
  1064. #define XZ_IN_SIZE 10000
  1065. static struct zfile *xz (struct zfile *z, int *retcode)
  1066. {
  1067. static bool iscrc;
  1068. ISzAlloc allocImp;
  1069. CXzUnpacker cx;
  1070. ECoderStatus status;
  1071. struct zfile *zo = NULL;
  1072. uae_u8 out[XZ_OUT_SIZE], in[XZ_IN_SIZE];
  1073. if (checkwrite (z, retcode))
  1074. return NULL;
  1075. memset (&cx, 0, sizeof cx);
  1076. allocImp.Alloc = SzAlloc;
  1077. allocImp.Free = SzFree;
  1078. if (!iscrc)
  1079. CrcGenerateTable ();
  1080. iscrc = true;
  1081. // if (XzUnpacker_Create (&cx, &allocImp) != SZ_OK)
  1082. // return NULL;
  1083. XzUnpacker_Construct (&cx, &allocImp);
  1084. int outwritten = 0;
  1085. int towrite = 0;
  1086. bool first = true;
  1087. for (;;) {
  1088. int read = zfile_fread (in, 1, XZ_IN_SIZE, z);
  1089. if (first) {
  1090. if (!(in[0] == 0xfd && in[1] == 0x37 && in[2] == 0x7a && in[3] == 0x58 && in[4] == 0x5a && in[5] == 0))
  1091. break;
  1092. }
  1093. first = false;
  1094. if (read == 0)
  1095. break;
  1096. if (read < 0) {
  1097. zfile_fclose (zo);
  1098. zo = NULL;
  1099. break;
  1100. }
  1101. if (!zo)
  1102. zo = zfile_fopen_empty (z, z->name);
  1103. if (!zo)
  1104. break;
  1105. uae_u8 *inp = in;
  1106. for (;;) {
  1107. SizeT srclen = read;
  1108. SizeT outlen = XZ_OUT_SIZE;
  1109. if (XzUnpacker_Code (&cx, out, &outlen, inp, &srclen, LZMA_FINISH_ANY, &status) != SZ_OK) {
  1110. zfile_fclose (zo);
  1111. zo = NULL;
  1112. break;
  1113. }
  1114. if (status != CODER_STATUS_NEEDS_MORE_INPUT && status != CODER_STATUS_NOT_FINISHED) {
  1115. zfile_fclose (zo);
  1116. zo = NULL;
  1117. break;
  1118. }
  1119. zfile_fwrite (out, outlen, 1, zo);
  1120. if (status == CODER_STATUS_FINISHED_WITH_MARK)
  1121. break;
  1122. if (srclen == read)
  1123. break;
  1124. inp += srclen;
  1125. read -= srclen;
  1126. }
  1127. }
  1128. XzUnpacker_Free (&cx);
  1129. return zo;
  1130. }
  1131. #endif
  1132. #ifdef A_DMS
  1133. static struct zfile *dms (struct zfile *z, int index, int *retcode)
  1134. {
  1135. int ret;
  1136. struct zfile *zo;
  1137. TCHAR *orgname = zfile_getname (z);
  1138. TCHAR *ext = _tcsrchr (orgname, '.');
  1139. TCHAR newname[MAX_DPATH];
  1140. static int recursive;
  1141. int i;
  1142. struct zfile *zextra[DMS_EXTRA_SIZE] = { 0 };
  1143. if (checkwrite (z, retcode))
  1144. return NULL;
  1145. if (recursive)
  1146. return NULL;
  1147. if (ext) {
  1148. _tcscpy (newname, orgname);
  1149. _tcscpy (newname + _tcslen (newname) - _tcslen (ext), _T(".adf"));
  1150. } else {
  1151. _tcscat (newname, _T(".adf"));
  1152. }
  1153. zo = zfile_fopen_empty (z, newname, 1760 * 512);
  1154. if (!zo)
  1155. return NULL;
  1156. ret = DMS_Process_File (z, zo, CMD_UNPACK, OPT_VERBOSE, 0, 0, 0, zextra);
  1157. if (ret == NO_PROBLEM || ret == DMS_FILE_END) {
  1158. int off = zfile_ftell (zo);
  1159. if (off >= 1760 * 512 / 3 && off <= 1760 * 512 * 3 / 4) { // possible split dms?
  1160. if (_tcslen (orgname) > 5) {
  1161. TCHAR *s = orgname + _tcslen (orgname) - 5;
  1162. if (!_tcsicmp (s, _T("a.dms"))) {
  1163. TCHAR *fn2 = my_strdup (orgname);
  1164. struct zfile *z2;
  1165. fn2[_tcslen (fn2) - 5]++;
  1166. recursive++;
  1167. z2 = zfile_fopen (fn2, _T("rb"), z->zfdmask);
  1168. recursive--;
  1169. if (z2) {
  1170. ret = DMS_Process_File (z2, zo, CMD_UNPACK, OPT_VERBOSE, 0, 0, 1, NULL);
  1171. zfile_fclose (z2);
  1172. }
  1173. xfree (fn2);
  1174. }
  1175. }
  1176. }
  1177. zfile_fseek (zo, 0, SEEK_SET);
  1178. if (index > 0) {
  1179. zfile_fclose (zo);
  1180. zo = NULL;
  1181. for (i = 0; i < DMS_EXTRA_SIZE && zextra[i]; i++);
  1182. if (index > i)
  1183. goto end;
  1184. zo = zextra[index - 1];
  1185. zextra[index - 1] = NULL;
  1186. }
  1187. if (retcode)
  1188. *retcode = 1;
  1189. zfile_fclose (z);
  1190. z = NULL;
  1191. } else {
  1192. zfile_fclose (zo);
  1193. zo = NULL;
  1194. }
  1195. end:
  1196. for (i = 0; i < DMS_EXTRA_SIZE; i++)
  1197. zfile_fclose (zextra[i]);
  1198. return zo;
  1199. }
  1200. #endif
  1201. const TCHAR *uae_ignoreextensions[] =
  1202. { _T(".gif"), _T(".jpg"), _T(".png"), _T(".xml"), _T(".pdf"), _T(".txt"), 0 };
  1203. const TCHAR *uae_diskimageextensions[] =
  1204. { _T(".adf"), _T(".adz"), _T(".ipf"), _T(".scp"), _T(".fdi"), _T(".exe"), _T(".dms"), _T(".wrp"), _T(".dsq"), 0 };
  1205. int zfile_is_ignore_ext (const TCHAR *name)
  1206. {
  1207. int i;
  1208. const TCHAR *ext;
  1209. ext = _tcsrchr (name, '.');
  1210. if (!ext)
  1211. return 0;
  1212. for (i = 0; uae_ignoreextensions[i]; i++) {
  1213. if (!strcasecmp (uae_ignoreextensions[i], ext))
  1214. return 1;
  1215. }
  1216. return 0;
  1217. }
  1218. int zfile_is_diskimage (const TCHAR *name)
  1219. {
  1220. int i;
  1221. const TCHAR *ext = _tcsrchr (name, '.');
  1222. if (!ext)
  1223. return 0;
  1224. i = 0;
  1225. while (uae_diskimageextensions[i]) {
  1226. if (!strcasecmp (ext, uae_diskimageextensions[i]))
  1227. return HISTORY_FLOPPY;
  1228. i++;
  1229. }
  1230. if (!_tcsicmp (ext, _T(".cue")))
  1231. return HISTORY_CD;
  1232. return -1;
  1233. }
  1234. static const TCHAR *archive_extensions[] = {
  1235. _T("7z"), _T("rar"), _T("zip"), _T("lha"), _T("lzh"), _T("lzx"),
  1236. _T("adf"), _T("adz"), _T("dsq"), _T("dms"), _T("ipf"), _T("fdi"), _T("wrp"), _T("ima"),
  1237. _T("hdf"), _T("tar"),
  1238. NULL
  1239. };
  1240. static const TCHAR *plugins_7z[] = { _T("7z"), _T("rar"), _T("zip"), _T("lha"), _T("lzh"), _T("lzx"), _T("adf"), _T("dsq"), _T("hdf"), _T("tar"), NULL };
  1241. #if defined(ARCHIVEACCESS)
  1242. static const uae_char *plugins_7z_x[] = { "7z", "Rar!", "MK", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  1243. #endif
  1244. static const int plugins_7z_t[] = {
  1245. ArchiveFormat7Zip, ArchiveFormatRAR, ArchiveFormatZIP, ArchiveFormatLHA, ArchiveFormatLHA, ArchiveFormatLZX,
  1246. ArchiveFormatADF, ArchiveFormatADF, ArchiveFormatADF, ArchiveFormatTAR
  1247. };
  1248. static const int plugins_7z_m[] = {
  1249. ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE,
  1250. ZFD_ADF, ZFD_ADF, ZFD_ADF, ZFD_ARCHIVE
  1251. };
  1252. static int iszip (struct zfile *z, int mask)
  1253. {
  1254. TCHAR *name = z->name;
  1255. TCHAR *ext = _tcsrchr (name, '.');
  1256. uae_u8 header[32];
  1257. if (!ext)
  1258. return 0;
  1259. memset (header, 0, sizeof (header));
  1260. zfile_fseek (z, 0, SEEK_SET);
  1261. zfile_fread (header, sizeof (header), 1, z);
  1262. zfile_fseek (z, 0, SEEK_SET);
  1263. if (mask & ZFD_ARCHIVE) {
  1264. if (!strcasecmp (ext, _T(".zip")) || !strcasecmp (ext, _T(".rp9"))) {
  1265. if (header[0] == 'P' && header[1] == 'K')
  1266. return ArchiveFormatZIP;
  1267. return 0;
  1268. }
  1269. }
  1270. if (mask & ZFD_ARCHIVE) {
  1271. if (!strcasecmp (ext, _T(".7z"))) {
  1272. if (header[0] == '7' && header[1] == 'z')
  1273. return ArchiveFormat7Zip;
  1274. return 0;
  1275. }
  1276. if (!strcasecmp (ext, _T(".rar"))) {
  1277. if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
  1278. return ArchiveFormatRAR;
  1279. return 0;
  1280. }
  1281. if (!strcasecmp (ext, _T(".lha")) || !strcasecmp (ext, _T(".lzh"))) {
  1282. if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
  1283. return ArchiveFormatLHA;
  1284. return 0;
  1285. }
  1286. if (!strcasecmp (ext, _T(".lzx"))) {
  1287. if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
  1288. return ArchiveFormatLZX;
  1289. return 0;
  1290. }
  1291. }
  1292. if (mask & ZFD_ADF) {
  1293. if (!strcasecmp (ext, _T(".adf"))) {
  1294. if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
  1295. return ArchiveFormatADF;
  1296. if (isfat (header))
  1297. return ArchiveFormatFAT;
  1298. return 0;
  1299. }
  1300. if (!strcasecmp (ext, _T(".ima"))) {
  1301. if (isfat (header))
  1302. return ArchiveFormatFAT;
  1303. }
  1304. }
  1305. if (mask & ZFD_HD) {
  1306. if (!strcasecmp (ext, _T(".hdf"))) {
  1307. if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
  1308. return ArchiveFormatADF;
  1309. if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
  1310. return ArchiveFormatADF;
  1311. if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
  1312. return ArchiveFormatRDB;
  1313. if (isfat (header))
  1314. return ArchiveFormatFAT;
  1315. return 0;
  1316. }
  1317. }
  1318. #if defined(ARCHIVEACCESS)
  1319. for (int i = 0; plugins_7z_x[i]; i++) {
  1320. if ((plugins_7z_m[i] & mask) && plugins_7z_x[i] && !strcasecmp (ext + 1, plugins_7z[i]) &&
  1321. !memcmp (header, plugins_7z_x[i], strlen (plugins_7z_x[i])))
  1322. return plugins_7z_t[i];
  1323. }
  1324. #endif
  1325. return 0;
  1326. }
  1327. int iszip (struct zfile *z)
  1328. {
  1329. return iszip (z, ZFD_NORMAL);
  1330. }
  1331. struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask, int *retcode, int index)
  1332. {
  1333. TCHAR *name = z->name;
  1334. TCHAR *ext = NULL;
  1335. uae_u8 header[32];
  1336. if (retcode)
  1337. *retcode = 0;
  1338. if (!mask)
  1339. return NULL;
  1340. if (name) {
  1341. ext = _tcsrchr (name, '.');
  1342. if (ext)
  1343. ext++;
  1344. }
  1345. if (ext != NULL) {
  1346. if (mask & ZFD_ARCHIVE) {
  1347. if (strcasecmp (ext, _T("7z")) == 0)
  1348. return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault, retcode, index);
  1349. if (strcasecmp (ext, _T("zip")) == 0)
  1350. return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
  1351. if (strcasecmp (ext, _T("lha")) == 0 || strcasecmp (ext, _T("lzh")) == 0)
  1352. return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
  1353. if (strcasecmp (ext, _T("lzx")) == 0)
  1354. return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
  1355. if (strcasecmp (ext, _T("rar")) == 0)
  1356. return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
  1357. if (strcasecmp (ext, _T("tar")) == 0)
  1358. return archive_access_select (parent, z, ArchiveFormatTAR, dodefault, retcode, index);
  1359. }
  1360. if (mask & ZFD_UNPACK) {
  1361. if (index == 0) {
  1362. if (strcasecmp (ext, _T("gz")) == 0)
  1363. return zfile_gunzip (z, retcode);
  1364. if (strcasecmp (ext, _T("adz")) == 0)
  1365. return zfile_gunzip (z, retcode);
  1366. if (strcasecmp (ext, _T("roz")) == 0)
  1367. return zfile_gunzip (z, retcode);
  1368. if (strcasecmp (ext, _T("hdz")) == 0)
  1369. return zfile_gunzip (z, retcode);
  1370. #ifdef A_WRP
  1371. if (strcasecmp (ext, _T("wrp")) == 0)
  1372. return wrp (z, retcode);
  1373. #endif
  1374. #ifdef A_7Z
  1375. if (strcasecmp (ext, _T("xz")) == 0)
  1376. return xz (z, retcode);
  1377. #endif
  1378. }
  1379. #ifdef A_DMS
  1380. if (strcasecmp (ext, _T("dms")) == 0)
  1381. return dms (z, index, retcode);
  1382. #endif
  1383. }
  1384. if (mask & ZFD_RAWDISK) {
  1385. #ifdef CAPS
  1386. if (strcasecmp (ext, _T("ipf")) == 0)
  1387. return ipf (z, index, retcode);
  1388. #endif
  1389. if (strcasecmp (ext, _T("fdi")) == 0)
  1390. return fdi (z, index, retcode);
  1391. if (mask & (ZFD_RAWDISK_PC | ZFD_RAWDISK_AMIGA))
  1392. return NULL;
  1393. }
  1394. #if defined(ARCHIVEACCESS)
  1395. if (index == 0) {
  1396. for (int i = 0; plugins_7z_x[i]; i++) {
  1397. if ((plugins_7z_t[i] & mask) && strcasecmp (ext, plugins_7z[i]) == 0)
  1398. return archive_access_arcacc_select (z, plugins_7z_t[i], retcode);
  1399. }
  1400. }
  1401. #endif
  1402. }
  1403. memset (header, 0, sizeof (header));
  1404. zfile_fseek (z, 0, SEEK_SET);
  1405. zfile_fread (header, sizeof (header), 1, z);
  1406. zfile_fseek (z, 0, SEEK_SET);
  1407. if (!memcmp (header, "conectix", 8)) {
  1408. if (index > 0)
  1409. return NULL;
  1410. return vhd (z);
  1411. }
  1412. if (mask & ZFD_UNPACK) {
  1413. if (index == 0) {
  1414. if (header[0] == 0x1f && header[1] == 0x8b)
  1415. return zfile_gunzip (z, retcode);
  1416. #ifdef A_LZX
  1417. if (header[0] == 'P' && header[1] == 'K' && header[2] == 'D')
  1418. return dsq (z, 0, retcode);
  1419. #endif
  1420. #ifdef A_7Z
  1421. if (header[0] == 0xfd && header[1] == 0x37 && header[2] == 0x7a && header[3] == 0x58 && header[4] == 0x5a && header[5] == 0)
  1422. return xz (z, retcode);
  1423. #endif
  1424. }
  1425. #ifdef A_DMS
  1426. if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
  1427. return dms (z, index, retcode);
  1428. #endif
  1429. }
  1430. if (mask & ZFD_RAWDISK) {
  1431. #ifdef CAPS
  1432. if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S')
  1433. return ipf (z, index, retcode);
  1434. #endif
  1435. if (!memcmp (header, "Formatte", 8))
  1436. return fdi (z, index, retcode);
  1437. if (!memcmp (header, "UAE-1ADF", 8))
  1438. return extadf (z, index, retcode);
  1439. }
  1440. if (index > 0)
  1441. return NULL;
  1442. if (mask & ZFD_ARCHIVE) {
  1443. if (header[0] == 'P' && header[1] == 'K')
  1444. return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
  1445. if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
  1446. return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
  1447. if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
  1448. return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
  1449. if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
  1450. return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
  1451. }
  1452. if (mask & ZFD_ADF) {
  1453. if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
  1454. return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
  1455. if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
  1456. return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
  1457. if (isfat (header))
  1458. return archive_access_select (parent, z, ArchiveFormatFAT, dodefault, retcode, index);
  1459. }
  1460. if (ext) {
  1461. if (mask & ZFD_UNPACK) {
  1462. #ifdef A_LZX
  1463. if (strcasecmp (ext, _T("dsq")) == 0)
  1464. return dsq (z, 1, retcode);
  1465. #endif
  1466. }
  1467. if (mask & ZFD_ADF) {
  1468. if (strcasecmp (ext, _T("adf")) == 0 && !memcmp (header, "DOS", 3))
  1469. return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
  1470. }
  1471. }
  1472. return NULL;
  1473. }
  1474. #ifdef SINGLEFILE
  1475. extern uae_u8 singlefile_data[];
  1476. static struct zfile *zfile_opensinglefile(struct zfile *l)
  1477. {
  1478. uae_u8 *p = singlefile_data;
  1479. int size, offset;
  1480. TCHAR tmp[256], *s;
  1481. _tcscpy (tmp, l->name);
  1482. s = tmp + _tcslen (tmp) - 1;
  1483. while (*s != 0 && *s != '/' && *s != '\\')
  1484. s--;
  1485. if (s > tmp)
  1486. s++;
  1487. write_log (_T("loading from singlefile: '%s'\n"), tmp);
  1488. while (*p++);
  1489. offset = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|(p[3] << 0);
  1490. p += 4;
  1491. for (;;) {
  1492. size = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|(p[3] << 0);
  1493. if (!size)
  1494. break;
  1495. if (!strcmpi (tmp, p + 4)) {
  1496. l->data = singlefile_data + offset;
  1497. l->size = size;
  1498. write_log (_T("found, size %d\n"), size);
  1499. return l;
  1500. }
  1501. offset += size;
  1502. p += 4;
  1503. p += _tcslen (p) + 1;
  1504. }
  1505. write_log (_T("not found\n"));
  1506. return 0;
  1507. }
  1508. #endif
  1509. static struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
  1510. {
  1511. struct zfile *l;
  1512. FILE *f;
  1513. if(*name == '\0')
  1514. return NULL;
  1515. l = zfile_create (NULL, name);
  1516. l->name = my_strdup (name);
  1517. l->mode = my_strdup (mode);
  1518. f = uae_tfopen (name, mode);
  1519. if (!f) {
  1520. zfile_fclose (l);
  1521. return 0;
  1522. }
  1523. l->f = f;
  1524. return l;
  1525. }
  1526. static struct zfile *openzip (const TCHAR *pname)
  1527. {
  1528. int i, j;
  1529. TCHAR v;
  1530. TCHAR name[MAX_DPATH];
  1531. TCHAR zippath[MAX_DPATH];
  1532. zippath[0] = 0;
  1533. _tcscpy (name, pname);
  1534. i = _tcslen (name) - 2;
  1535. while (i > 0) {
  1536. if ((name[i] == '/' || name[i] == '\\') && i > 4) {
  1537. v = name[i];
  1538. name[i] = 0;
  1539. for (j = 0; plugins_7z[j]; j++) {
  1540. int len = _tcslen (plugins_7z[j]);
  1541. if (name[i - len - 1] == '.' && !strcasecmp (name + i - len, plugins_7z[j])) {
  1542. struct zfile *f = zfile_fopen_nozip (name, _T("rb"));
  1543. if (f) {
  1544. f->zipname = my_strdup (name + i + 1);
  1545. return f;
  1546. }
  1547. break;
  1548. }
  1549. }
  1550. name[i] = v;
  1551. }
  1552. i--;
  1553. }
  1554. return 0;
  1555. }
  1556. static bool writeneeded (const TCHAR *mode)
  1557. {
  1558. return _tcschr (mode, 'w') || _tcschr (mode, 'a') || _tcschr (mode, '+') || _tcschr (mode, 't');
  1559. }
  1560. bool zfile_needwrite (struct zfile *zf)
  1561. {
  1562. if (!zf->mode)
  1563. return false;
  1564. return writeneeded (zf->mode);
  1565. }
  1566. static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int mask)
  1567. {
  1568. struct zfile *l;
  1569. FILE *f;
  1570. if(*name == '\0')
  1571. return NULL;
  1572. #ifdef SINGLEFILE
  1573. if (zfile_opensinglefile (l))
  1574. return l;
  1575. #endif
  1576. l = openzip (name);
  1577. if (l) {
  1578. if (writeneeded (mode)) {
  1579. zfile_fclose (l);
  1580. return 0;
  1581. }
  1582. l->zfdmask = mask;
  1583. } else {
  1584. struct mystat st;
  1585. l = zfile_create (NULL, name);
  1586. l->mode = my_strdup (mode);
  1587. l->name = my_strdup (name);
  1588. l->zfdmask = mask;
  1589. if (!_tcsicmp (mode, _T("r"))) {
  1590. f = my_opentext (l->name);
  1591. l->textmode = 1;
  1592. } else {
  1593. f = uae_tfopen (l->name, mode);
  1594. }
  1595. if (!f) {
  1596. zfile_fclose (l);
  1597. return 0;
  1598. }
  1599. if (my_stat (l->name, &st))
  1600. l->size = st.size;
  1601. l->f = f;
  1602. }
  1603. return l;
  1604. }
  1605. static void manglefilename(const TCHAR *in, TCHAR *out, int outsize)
  1606. {
  1607. if (!target_expand_environment(in, out, outsize))
  1608. _tcscpy(out, in);
  1609. for (int i = 0; i < _tcslen(out); i++) {
  1610. // remove \\ or // in the middle of path
  1611. if ((out[i] == '/' || out[i] == '\\') && (out[i + 1] == '/' || out[i + 1] == '\\') && i > 0) {
  1612. memmove(out + i, out + i + 1, (_tcslen(out + i) + 1) * sizeof(TCHAR));
  1613. i--;
  1614. continue;
  1615. }
  1616. }
  1617. }
  1618. int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
  1619. {
  1620. struct zfile *l;
  1621. int ztype;
  1622. TCHAR path[MAX_DPATH];
  1623. manglefilename (name, path, sizeof path / sizeof(TCHAR));
  1624. l = zfile_fopen_2 (path, _T("rb"), ZFD_NORMAL);
  1625. if (!l)
  1626. return 0;
  1627. ztype = iszip (l);
  1628. if (ztype == 0)
  1629. zc (l, user);
  1630. else
  1631. archive_access_scan (l, zc, user, ztype);
  1632. zfile_fclose (l);
  1633. return 1;
  1634. }
  1635. /*
  1636. * fopen() for a compressed file
  1637. */
  1638. static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int mask, int index)
  1639. {
  1640. int cnt = 10;
  1641. struct zfile *l, *l2;
  1642. TCHAR path[MAX_DPATH];
  1643. if (_tcslen (name) == 0)
  1644. return NULL;
  1645. manglefilename(name, path, sizeof(path) / sizeof TCHAR);
  1646. l = zfile_fopen_2 (path, mode, mask);
  1647. if (!l)
  1648. return 0;
  1649. l2 = NULL;
  1650. while (cnt-- > 0) {
  1651. int rc;
  1652. zfile_fseek (l, 0, SEEK_SET);
  1653. l2 = zuncompress (NULL, l, 0, mask, &rc, index);
  1654. if (!l2) {
  1655. if (rc < 0) {
  1656. zfile_fclose (l);
  1657. return NULL;
  1658. }
  1659. zfile_fseek (l, 0, SEEK_SET);
  1660. break;
  1661. } else {
  1662. if (l2->parent == l)
  1663. l->opencnt--;
  1664. }
  1665. l = l2;
  1666. }
  1667. return l;
  1668. }
  1669. #ifdef _WIN32
  1670. static int isinternetfile (const TCHAR *name)
  1671. {
  1672. if (!_tcsnicmp (name, _T("http://"), 7) || !_tcsnicmp (name, _T("https://"), 8))
  1673. return 1;
  1674. if (!_tcsnicmp (name, _T("ftp://"), 6))
  1675. return -1;
  1676. return 0;
  1677. }
  1678. #include <wininet.h>
  1679. #include "win32.h"
  1680. #define INETBUFFERLEN 1000000
  1681. static struct zfile *zfile_fopen_internet (const TCHAR *name, const TCHAR *mode, int mask)
  1682. {
  1683. static HINTERNET hi;
  1684. HINTERNET i = NULL;
  1685. TCHAR tmp[MAX_DPATH];
  1686. DWORD ierr = 0;
  1687. DWORD outbuf = sizeof tmp / sizeof (TCHAR);
  1688. uae_u8 *data = 0;
  1689. int bufferlen = INETBUFFERLEN;
  1690. int datalen;
  1691. DWORD didread;
  1692. struct zfile *zf = NULL;
  1693. if (_tcschr (mode, 'w') || _tcschr (mode, 'a'))
  1694. return NULL;
  1695. tmp[0] = 0;
  1696. if (!hi) {
  1697. hi = InternetOpen (WINUAEAPPNAME, INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, NULL, NULL, 0);
  1698. if (hi == NULL) {
  1699. write_log (_T("InternetOpen() failed, %d\n"), GetLastError ());
  1700. return NULL;
  1701. }
  1702. }
  1703. i = InternetOpenUrl (hi, name, NULL, 0, INTERNET_FLAG_NO_COOKIES, 0);
  1704. if (i == NULL) {
  1705. DWORD err = GetLastError ();
  1706. if (err == ERROR_INTERNET_EXTENDED_ERROR)
  1707. InternetGetLastResponseInfo (&ierr, tmp, &outbuf);
  1708. write_log (_T("InternetOpenUrl(%s) failed %d (%d,%s)\n"), name, err, ierr, tmp);
  1709. goto end;
  1710. }
  1711. if (isinternetfile (name) > 0) {
  1712. DWORD statuscode;
  1713. DWORD hindex = 0;
  1714. DWORD size = sizeof statuscode;
  1715. if (!HttpQueryInfo (i, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &statuscode, &size, &hindex)) {
  1716. DWORD err = GetLastError ();
  1717. write_log (_T("HttpQueryInfo(%s) failed %d\n"), name, err);
  1718. goto end;
  1719. }
  1720. if (statuscode != 200) {
  1721. write_log (_T("HttpQueryInfo(%s)=%d\n"), name, statuscode);
  1722. goto end;
  1723. }
  1724. }
  1725. if (mask & ZFD_CHECKONLY) {
  1726. zf = zfile_create (NULL, name);
  1727. goto end;
  1728. }
  1729. datalen = 0;
  1730. data = xmalloc (uae_u8, bufferlen);
  1731. for (;;) {
  1732. if (!InternetReadFile (i, data + datalen, INETBUFFERLEN, &didread)) {
  1733. DWORD err = GetLastError ();
  1734. if (err == ERROR_INTERNET_EXTENDED_ERROR)
  1735. InternetGetLastResponseInfo (&ierr, tmp, &outbuf);
  1736. write_log (_T("InternetReadFile(%s) failed %d (%d,%s)\n"), name, err, ierr, tmp);
  1737. break;
  1738. }
  1739. if (didread == 0)
  1740. break;
  1741. datalen += didread;
  1742. if (datalen > bufferlen - INETBUFFERLEN) {
  1743. bufferlen += INETBUFFERLEN;
  1744. data = xrealloc (uae_u8, data, bufferlen);
  1745. if (!data) {
  1746. datalen = 0;
  1747. break;
  1748. }
  1749. }
  1750. }
  1751. if (datalen > 0) {
  1752. zf = zfile_create (NULL, name);
  1753. if (zf) {
  1754. zf->size = datalen;
  1755. zf->data = data;
  1756. data = NULL;
  1757. }
  1758. }
  1759. end:
  1760. if (i)
  1761. InternetCloseHandle (i);
  1762. free (data);
  1763. return zf;
  1764. }
  1765. #endif
  1766. static struct zfile *zfile_fopenx2 (const TCHAR *name, const TCHAR *mode, int mask, int index)
  1767. {
  1768. struct zfile *f;
  1769. TCHAR tmp[MAX_DPATH];
  1770. #ifdef _WIN32
  1771. if (isinternetfile (name))
  1772. return zfile_fopen_internet (name, mode, mask);
  1773. #endif
  1774. f = zfile_fopen_x (name, mode, mask, index);
  1775. if (f)
  1776. return f;
  1777. if (_tcslen (name) <= 2)
  1778. return NULL;
  1779. if (name[1] != ':') {
  1780. _tcscpy (tmp, start_path_data);
  1781. _tcscat (tmp, name);
  1782. f = zfile_fopen_x (tmp, mode, mask, index);
  1783. if (f)
  1784. return f;
  1785. }
  1786. #if 0
  1787. name += 2;
  1788. if (name[0] == '/' || name[0] == '\\')
  1789. name++;
  1790. for (;;) {
  1791. _tcscpy (tmp, start_path_data);
  1792. _tcscpy (tmp, name);
  1793. f = zfile_fopen_x (tmp, mode, mask);
  1794. if (f)
  1795. return f;
  1796. while (name[0]) {
  1797. name++;
  1798. if (name[-1] == '/' || name[-1] == '\\')
  1799. break;
  1800. }
  1801. if (name[0] == 0)
  1802. break;
  1803. }
  1804. #endif
  1805. return NULL;
  1806. }
  1807. static struct zfile *zfile_fopenx (const TCHAR *name, const TCHAR *mode, int mask, int index)
  1808. {
  1809. struct zfile *zf;
  1810. //write_log (_T("zfile_fopen('%s','%s',%08x,%d)\n"), name, mode, mask, index);
  1811. zf = zfile_fopenx2 (name, mode, mask, index);
  1812. //write_log (_T("=%p\n"), zf);
  1813. return zf;
  1814. }
  1815. struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
  1816. {
  1817. return zfile_fopenx (name, mode, mask, 0);
  1818. }
  1819. struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode)
  1820. {
  1821. return zfile_fopenx (name, mode, 0, 0);
  1822. }
  1823. struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask, int index)
  1824. {
  1825. return zfile_fopenx (name, mode, mask, index);
  1826. }
  1827. struct zfile *zfile_dup (struct zfile *zf)
  1828. {
  1829. struct zfile *nzf;
  1830. if (!zf)
  1831. return NULL;
  1832. if (zf->archiveparent)
  1833. checkarchiveparent (zf);
  1834. if (zf->userdata)
  1835. return NULL;
  1836. if (!zf->data && zf->dataseek) {
  1837. nzf = zfile_create (zf, NULL);
  1838. } else if (zf->data) {
  1839. nzf = zfile_create (zf, NULL);
  1840. nzf->data = xmalloc (uae_u8, zf->size);
  1841. if (!nzf->data) {
  1842. write_log(_T("Out of memory: %s\n"), zfile_getname(zf));
  1843. return NULL;
  1844. }
  1845. memcpy (nzf->data, zf->data, zf->size);
  1846. nzf->size = zf->size;
  1847. nzf->datasize = zf->datasize;
  1848. } else if (zf->useparent) {
  1849. nzf = zfile_fopen_parent(zf, zf->name, 0, zf->size);
  1850. return nzf;
  1851. } else {
  1852. if (zf->zipname) {
  1853. nzf = openzip (zf->name);
  1854. if (nzf)
  1855. return nzf;
  1856. }
  1857. if (!zf->name || !zf->mode)
  1858. return NULL;
  1859. FILE *ff = uae_tfopen (zf->name, zf->mode);
  1860. if (!ff)
  1861. return NULL;
  1862. nzf = zfile_create (zf, NULL);
  1863. nzf->f = ff;
  1864. }
  1865. zfile_fseek (nzf, zf->seek, SEEK_SET);
  1866. if (zf->name)
  1867. nzf->name = my_strdup (zf->name);
  1868. if (nzf->zipname)
  1869. nzf->zipname = my_strdup (zf->zipname);
  1870. nzf->zfdmask = zf->zfdmask;
  1871. nzf->mode = my_strdup (zf->mode);
  1872. nzf->size = zf->size;
  1873. return nzf;
  1874. }
  1875. int zfile_exists (const TCHAR *name)
  1876. {
  1877. struct zfile *z;
  1878. if (my_existsfile (name))
  1879. return 1;
  1880. z = zfile_fopen (name, _T("rb"), ZFD_NORMAL | ZFD_CHECKONLY);
  1881. if (!z)
  1882. return 0;
  1883. zfile_fclose (z);
  1884. return 1;
  1885. }
  1886. int zfile_iscompressed (struct zfile *z)
  1887. {
  1888. return z->data ? 1 : 0;
  1889. }
  1890. struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 size)
  1891. {
  1892. struct zfile *l;
  1893. l = zfile_create (prev, NULL);
  1894. l->name = my_strdup (name ? name : _T(""));
  1895. if (size) {
  1896. l->data = xcalloc (uae_u8, size);
  1897. if (!l->data) {
  1898. xfree (l);
  1899. return NULL;
  1900. }
  1901. l->size = size;
  1902. l->datasize = size;
  1903. l->allocsize = size;
  1904. } else {
  1905. l->data = xcalloc (uae_u8, 1000);
  1906. l->size = 0;
  1907. l->allocsize = 1000;
  1908. }
  1909. return l;
  1910. }
  1911. struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name)
  1912. {
  1913. return zfile_fopen_empty (prev, name, 0);
  1914. }
  1915. struct zfile *zfile_fopen_parent (struct zfile *z, const TCHAR *name, uae

Large files files are truncated, but you can click here to view the full file