]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1600b22.zip
authorToni Wilen <twilen@winuae.net>
Wed, 8 Apr 2009 13:11:39 +0000 (16:11 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:45:47 +0000 (21:45 +0200)
93 files changed:
akiko.c
amax.c
arcadia.c
archivers/7z/7zAlloc.h [deleted file]
archivers/7z/7zBuf.c [new file with mode: 0644]
archivers/7z/7zBuf.h [new file with mode: 0644]
archivers/7z/7zBuffer.c [deleted file]
archivers/7z/7zBuffer.h [deleted file]
archivers/7z/7zCrc.c
archivers/7z/7zCrc.h
archivers/7z/7zDecode.c [deleted file]
archivers/7z/7zDecode.h [deleted file]
archivers/7z/7zExtract.c [deleted file]
archivers/7z/7zIn.c [deleted file]
archivers/7z/7zIn.h [deleted file]
archivers/7z/7zItem.c [deleted file]
archivers/7z/7zItem.h [deleted file]
archivers/7z/7zMain.c [deleted file]
archivers/7z/7zMethodID.c [deleted file]
archivers/7z/7zMethodID.h [deleted file]
archivers/7z/7zStream.c [new file with mode: 0644]
archivers/7z/7zTypes.h [deleted file]
archivers/7z/7zVersion.h [new file with mode: 0644]
archivers/7z/Archive/7z/7zAlloc.c [moved from archivers/7z/7zAlloc.c with 80% similarity]
archivers/7z/Archive/7z/7zAlloc.h [new file with mode: 0644]
archivers/7z/Archive/7z/7zDecode.c [new file with mode: 0644]
archivers/7z/Archive/7z/7zDecode.h [new file with mode: 0644]
archivers/7z/Archive/7z/7zExtract.c [new file with mode: 0644]
archivers/7z/Archive/7z/7zExtract.h [moved from archivers/7z/7zExtract.h with 87% similarity]
archivers/7z/Archive/7z/7zHeader.c [moved from archivers/7z/7zHeader.c with 57% similarity]
archivers/7z/Archive/7z/7zHeader.h [moved from archivers/7z/7zHeader.h with 65% similarity]
archivers/7z/Archive/7z/7zIn.c [new file with mode: 0644]
archivers/7z/Archive/7z/7zIn.h [new file with mode: 0644]
archivers/7z/Archive/7z/7zItem.c [new file with mode: 0644]
archivers/7z/Archive/7z/7zItem.h [new file with mode: 0644]
archivers/7z/Bcj2.c [new file with mode: 0644]
archivers/7z/Bcj2.h [new file with mode: 0644]
archivers/7z/Bra.c [new file with mode: 0644]
archivers/7z/Bra.h [new file with mode: 0644]
archivers/7z/Bra86.c [new file with mode: 0644]
archivers/7z/CpuArch.h [new file with mode: 0644]
archivers/7z/LzmaDec.c [new file with mode: 0644]
archivers/7z/LzmaDec.h [new file with mode: 0644]
archivers/7z/LzmaDecode.c [deleted file]
archivers/7z/LzmaDecode.h [deleted file]
archivers/7z/LzmaTypes.h [deleted file]
archivers/7z/Types.h [new file with mode: 0644]
archivers/lha/lha.h
archivers/lha/uae_lha.c
archivers/lzx/unlzx.c
archivers/wrp/warp.c
audio.c
autoconf.c
catweasel.c
cdtv.c
cfgfile.c
cia.c
debug.c
disk.c
diskutil.c [new file with mode: 0644]
driveclick.c
fdi2raw.c
filesys.asm
filesys.c
filesys_bootrom.c
hardfile.c
include/autoconf.h
include/diskutil.h [new file with mode: 0644]
include/fsdb.h
include/zarchive.h
include/zfile.h
inputdevice.c
memory.c
od-win32/caps/caps_win32.c
od-win32/fsdb_mywin32.c [new file with mode: 0644]
od-win32/fsdb_win32.c
od-win32/hardfile_win32.c
od-win32/parser.c
od-win32/posixemu.c
od-win32/uaeunp/uaeunp.vcproj [new file with mode: 0644]
od-win32/uaeunp_win32.c [new file with mode: 0644]
od-win32/win32.c
od-win32/win32.h
od-win32/win32gfx.c
od-win32/win32gfx.h
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
od-win32/writelog.c
savestate.c
uaeunp.c [new file with mode: 0644]
zfile.c
zfile_archive.c

diff --git a/akiko.c b/akiko.c
index 135e61336e94269893406338c9580ababf117742..02a8067b4dc7279d546d334f195d8716d68725a5 100644 (file)
--- a/akiko.c
+++ b/akiko.c
@@ -82,9 +82,9 @@ static void nvram_write (int offset, int len)
 
     if (!currprefs.cs_cd32nvram)
        return;
-    f = zfile_fopen (currprefs.flashfile, L"rb+");
+    f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f) {
-       f = zfile_fopen (currprefs.flashfile, L"wb");
+       f = zfile_fopen (currprefs.flashfile, L"wb", 0);
        if (!f) return;
        zfile_fwrite (cd32_nvram, NVRAM_SIZE, 1, f);
     }
@@ -99,7 +99,7 @@ static void nvram_read (void)
 
     if (!currprefs.cs_cd32nvram)
        return;
-    f = zfile_fopen (currprefs.flashfile, L"rb");
+    f = zfile_fopen (currprefs.flashfile, L"rb", ZFD_NORMAL);
     memset (cd32_nvram, 0, NVRAM_SIZE);
     if (!f) return;
     zfile_fread (cd32_nvram, NVRAM_SIZE, 1, f);
diff --git a/amax.c b/amax.c
index a60e54ab93e02ead57890aa2ab783f048b9babbd..ce483b9a4c7a4d2ac686dbab73da5686e7953a98 100644 (file)
--- a/amax.c
+++ b/amax.c
@@ -139,7 +139,7 @@ void amax_init (void)
     if (!currprefs.amaxromfile[0])
        return;
     amax_reset ();
-    z = zfile_fopen (currprefs.amaxromfile, L"rb");
+    z = zfile_fopen (currprefs.amaxromfile, L"rb", ZFD_NORMAL);
     if (!z) {
        write_log (L"AMAX: failed to load rom '%s'\n", currprefs.amaxromfile);
        return;
index c359e8ab46d7b554087c35597280edf164015f40..801427e907e313e0cfb54d1881e84c3a1d82f5ef 100644 (file)
--- a/arcadia.c
+++ b/arcadia.c
@@ -95,14 +95,14 @@ static int load_rom8 (TCHAR *xpath, uae_u8 *mem,    int extra)
 
     memset (tmp, 0, 131072);
     _stprintf (path, L"%s%s%s", xpath, extra == 3 ? L"-hi" : (extra == 2 ? L"hi" : L"h"), bin);
-    zf = zfile_fopen (path, L"rb");
+    zf = zfile_fopen (path, L"rb", ZFD_NORMAL);
     if (!zf)
        goto end;
     if (zfile_fread (tmp, 65536, 1, zf) == 0)
        goto end;
     zfile_fclose (zf);
     _stprintf (path, L"%s%s%s", xpath, extra == 3 ? L"-lo" : (extra == 2 ? L"lo" : L"l"), bin);
-    zf = zfile_fopen (path, L"rb");
+    zf = zfile_fopen (path, L"rb", ZFD_NORMAL);
     if (!zf)
        goto end;
     if (zfile_fread (tmp + 65536, 65536, 1, zf) == 0)
@@ -362,9 +362,9 @@ int is_arcadia_rom (const TCHAR *path)
 
 static void nvram_write (void)
 {
-    struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+");
+    struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f) {
-       f = zfile_fopen (currprefs.flashfile, L"wb");
+       f = zfile_fopen (currprefs.flashfile, L"wb", 0);
        if (!f)
            return;
     }
@@ -376,7 +376,7 @@ static void nvram_read (void)
 {
     struct zfile *f;
 
-    f = zfile_fopen (currprefs.flashfile, L"rb");
+    f = zfile_fopen (currprefs.flashfile, L"rb", ZFD_NORMAL);
     memset (arbmemory + nvram_offset, 0, NVRAM_SIZE);
     if (!f)
        return;
diff --git a/archivers/7z/7zAlloc.h b/archivers/7z/7zAlloc.h
deleted file mode 100644 (file)
index 4ca4170..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 7zAlloc.h */
-
-#ifndef __7Z_ALLOC_H
-#define __7Z_ALLOC_H
-
-#include <stddef.h>
-
-typedef struct _ISzAlloc
-{
-  void *(*Alloc)(size_t size);
-  void (*Free)(void *address); /* address can be 0 */
-} ISzAlloc;
-
-void *SzAlloc(size_t size);
-void SzFree(void *address);
-
-void *SzAllocTemp(size_t size);
-void SzFreeTemp(void *address);
-
-#endif
diff --git a/archivers/7z/7zBuf.c b/archivers/7z/7zBuf.c
new file mode 100644 (file)
index 0000000..14e7f4e
--- /dev/null
@@ -0,0 +1,36 @@
+/* 7zBuf.c -- Byte Buffer
+2008-03-28
+Igor Pavlov
+Public domain */
+
+#include "7zBuf.h"
+
+void Buf_Init(CBuf *p)
+{
+  p->data = 0;
+  p->size = 0;
+}
+
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
+{
+  p->size = 0;
+  if (size == 0)
+  {
+    p->data = 0;
+    return 1;
+  }
+  p->data = (Byte *)alloc->Alloc(alloc, size);
+  if (p->data != 0)
+  {
+    p->size = size;
+    return 1;
+  }
+  return 0;
+}
+
+void Buf_Free(CBuf *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->data);
+  p->data = 0;
+  p->size = 0;
+}
diff --git a/archivers/7z/7zBuf.h b/archivers/7z/7zBuf.h
new file mode 100644 (file)
index 0000000..c5bd718
--- /dev/null
@@ -0,0 +1,31 @@
+/* 7zBuf.h -- Byte Buffer
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_BUF_H
+#define __7Z_BUF_H
+
+#include "Types.h"
+
+typedef struct
+{
+  Byte *data;
+  size_t size;
+} CBuf;
+
+void Buf_Init(CBuf *p);
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
+void Buf_Free(CBuf *p, ISzAlloc *alloc);
+
+typedef struct
+{
+  Byte *data;
+  size_t size;
+  size_t pos;
+} CDynBuf;
+
+void DynBuf_Construct(CDynBuf *p);
+void DynBuf_SeekToBeg(CDynBuf *p);
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
+
+#endif
diff --git a/archivers/7z/7zBuffer.c b/archivers/7z/7zBuffer.c
deleted file mode 100644 (file)
index 3c4b71e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 7zBuffer.c */
-
-#include "7zBuffer.h"
-#include "7zAlloc.h"
-
-void SzByteBufferInit(CSzByteBuffer *buffer)
-{
-  buffer->Capacity = 0;
-  buffer->Items = 0;
-}
-
-int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
-{
-  buffer->Capacity = newCapacity;
-  if (newCapacity == 0)
-  {
-    buffer->Items = 0;
-    return 1;
-  }
-  buffer->Items = (Byte *)allocFunc(newCapacity);
-  return (buffer->Items != 0);
-}
-
-void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
-{
-  freeFunc(buffer->Items);
-  buffer->Items = 0;
-  buffer->Capacity = 0;
-}
diff --git a/archivers/7z/7zBuffer.h b/archivers/7z/7zBuffer.h
deleted file mode 100644 (file)
index 1aab7fa..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 7zBuffer.h */
-
-#ifndef __7Z_BUFFER_H
-#define __7Z_BUFFER_H
-
-#include <stddef.h>
-#include "7zTypes.h"
-
-typedef struct _CSzByteBuffer
-{
-       size_t Capacity;
-  Byte *Items;
-}CSzByteBuffer;
-
-void SzByteBufferInit(CSzByteBuffer *buffer);
-int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
-void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
-
-#endif
index 72da5302547840104a0c8b9544355b6f13682804..71962b2c28d04562e78c7ee6eec0cf2909b54cd0 100644 (file)
@@ -1,12 +1,14 @@
-/* 7zCrc.c */
+/* 7zCrc.c -- CRC32 calculation
+2008-08-05
+Igor Pavlov
+Public domain */
 
 #include "7zCrc.h"
 
 #define kCrcPoly 0xEDB88320
-
 UInt32 g_CrcTable[256];
 
-void InitCrcTable()
+void MY_FAST_CALL CrcGenerateTable(void)
 {
   UInt32 i;
   for (i = 0; i < 256; i++)
@@ -14,63 +16,20 @@ void InitCrcTable()
     UInt32 r = i;
     int j;
     for (j = 0; j < 8; j++)
-      if (r & 1)
-       r = (r >> 1) ^ kCrcPoly;
-      else
-       r >>= 1;
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
     g_CrcTable[i] = r;
   }
 }
 
-void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
-UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
-
-void CrcUpdateByte(UInt32 *crc, Byte b)
-{
-  *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
-}
-
-void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
 {
-  CrcUpdateByte(crc, (Byte)v);
-  CrcUpdateByte(crc, (Byte)(v >> 8));
-}
-
-void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
-{
-  int i;
-  for (i = 0; i < 4; i++)
-    CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
-}
-
-void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
-{
-  int i;
-  for (i = 0; i < 8; i++)
-  {
-    CrcUpdateByte(crc, (Byte)(v));
-    v >>= 8;
-  }
-}
-
-void CrcUpdate(UInt32 *crc, const void *data, size_t size)
-{
-  UInt32 v = *crc;
   const Byte *p = (const Byte *)data;
   for (; size > 0 ; size--, p++)
-    v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
-  *crc = v;
-}
-
-UInt32 CrcCalculateDigest(const void *data, size_t size)
-{
-  UInt32 crc;
-  CrcInit(&crc);
-  CrcUpdate(&crc, data, size);
-  return CrcGetDigest(&crc);
+    v = CRC_UPDATE_BYTE(v, *p);
+  return v;
 }
 
-int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
 {
-  return (CrcCalculateDigest(data, size) == digest);
+  return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
 }
index 0795bad034e58b411d399b01d10840821e9bf082..00dc29cee3c678ae27fe5ce38c10977697583b13 100644 (file)
@@ -1,24 +1,24 @@
-/* 7zCrc.h */
+/* 7zCrc.h -- CRC32 calculation
+2008-03-13
+Igor Pavlov
+Public domain */
 
 #ifndef __7Z_CRC_H
 #define __7Z_CRC_H
 
 #include <stddef.h>
 
-#include "7zTypes.h"
+#include "Types.h"
 
-extern UInt32 g_CrcTable[256];
-void InitCrcTable();
+extern UInt32 g_CrcTable[];
 
-void CrcInit(UInt32 *crc);
-UInt32 CrcGetDigest(UInt32 *crc);
-void CrcUpdateByte(UInt32 *crc, Byte v);
-void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
-void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
-void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
-void CrcUpdate(UInt32 *crc, const void *data, size_t size);
+void MY_FAST_CALL CrcGenerateTable(void);
 
-UInt32 CrcCalculateDigest(const void *data, size_t size);
-int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
 
 #endif
diff --git a/archivers/7z/7zDecode.c b/archivers/7z/7zDecode.c
deleted file mode 100644 (file)
index 186c957..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 7zDecode.c */
-
-#include "7zDecode.h"
-#define _SZ_ONE_DIRECTORY
-#ifdef _SZ_ONE_DIRECTORY
-#include "LzmaDecode.h"
-#else
-#include "../../Compress/LZMA_C/LzmaDecode.h"
-#endif
-
-CMethodID k_Copy = { { 0x0 }, 1 };
-CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
-
-#ifdef _LZMA_IN_CB
-
-typedef struct _CLzmaInCallbackImp
-{
-  ILzmaInCallback InCallback;
-  ISzInStream *InStream;
-  size_t Size;
-} CLzmaInCallbackImp;
-
-int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
-{
-  CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
-  size_t processedSize;
-  SZ_RESULT res;
-  *size = 0;
-  res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
-  *size = (SizeT)processedSize;
-  if (processedSize > cb->Size)
-    return (int)SZE_FAIL;
-  cb->Size -= processedSize;
-  if (res == SZ_OK)
-    return 0;
-  return (int)res;
-}
-
-#endif
-
-SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
-    #ifdef _LZMA_IN_CB
-    ISzInStream *inStream,
-    #else
-    const Byte *inBuffer,
-    #endif
-    Byte *outBuffer, size_t outSize,
-    size_t *outSizeProcessed, ISzAlloc *allocMain)
-{
-  UInt32 si;
-  size_t inSize = 0;
-  CCoderInfo *coder;
-  if (folder->NumPackStreams != 1)
-    return SZE_NOTIMPL;
-  if (folder->NumCoders != 1)
-    return SZE_NOTIMPL;
-  coder = folder->Coders;
-  *outSizeProcessed = 0;
-
-  for (si = 0; si < folder->NumPackStreams; si++)
-    inSize += (size_t)packSizes[si];
-
-  if (AreMethodsEqual(&coder->MethodID, &k_Copy))
-  {
-    size_t i;
-    if (inSize != outSize)
-      return SZE_DATA_ERROR;
-    #ifdef _LZMA_IN_CB
-    for (i = 0; i < inSize;)
-    {
-      size_t j;
-      Byte *inBuffer;
-      size_t bufferSize;
-      RINOK(inStream->Read((void *)inStream,  (void **)&inBuffer, inSize - i, &bufferSize));
-      if (bufferSize == 0)
-       return SZE_DATA_ERROR;
-      if (bufferSize > inSize - i)
-       return SZE_FAIL;
-      *outSizeProcessed += bufferSize;
-      for (j = 0; j < bufferSize && i < inSize; j++, i++)
-       outBuffer[i] = inBuffer[j];
-    }
-    #else
-    for (i = 0; i < inSize; i++)
-      outBuffer[i] = inBuffer[i];
-    *outSizeProcessed = inSize;
-    #endif
-    return SZ_OK;
-  }
-
-  if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
-  {
-    #ifdef _LZMA_IN_CB
-    CLzmaInCallbackImp lzmaCallback;
-    #else
-    SizeT inProcessed;
-    #endif
-
-    CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
-    int result;
-    SizeT outSizeProcessedLoc;
-
-    #ifdef _LZMA_IN_CB
-    lzmaCallback.Size = inSize;
-    lzmaCallback.InStream = inStream;
-    lzmaCallback.InCallback.Read = LzmaReadImp;
-    #endif
-
-    if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
-       coder->Properties.Capacity) != LZMA_RESULT_OK)
-      return SZE_FAIL;
-
-    state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
-    if (state.Probs == 0)
-      return SZE_OUTOFMEMORY;
-
-    #ifdef _LZMA_OUT_READ
-    if (state.Properties.DictionarySize == 0)
-      state.Dictionary = 0;
-    else
-    {
-      state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
-      if (state.Dictionary == 0)
-      {
-       allocMain->Free(state.Probs);
-       return SZE_OUTOFMEMORY;
-      }
-    }
-    LzmaDecoderInit(&state);
-    #endif
-
-    result = LzmaDecode(&state,
-       #ifdef _LZMA_IN_CB
-       &lzmaCallback.InCallback,
-       #else
-       inBuffer, (SizeT)inSize, &inProcessed,
-       #endif
-       outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
-    *outSizeProcessed = (size_t)outSizeProcessedLoc;
-    allocMain->Free(state.Probs);
-    #ifdef _LZMA_OUT_READ
-    allocMain->Free(state.Dictionary);
-    #endif
-    if (result == LZMA_RESULT_DATA_ERROR)
-      return SZE_DATA_ERROR;
-    if (result != LZMA_RESULT_OK)
-      return SZE_FAIL;
-    return SZ_OK;
-  }
-  return SZE_NOTIMPL;
-}
diff --git a/archivers/7z/7zDecode.h b/archivers/7z/7zDecode.h
deleted file mode 100644 (file)
index b625288..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* 7zDecode.h */
-
-#ifndef __7Z_DECODE_H
-#define __7Z_DECODE_H
-
-#include "7zItem.h"
-#include "7zAlloc.h"
-#ifdef _LZMA_IN_CB
-#include "7zIn.h"
-#endif
-
-SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
-    #ifdef _LZMA_IN_CB
-    ISzInStream *stream,
-    #else
-    const Byte *inBuffer,
-    #endif
-    Byte *outBuffer, size_t outSize,
-    size_t *outSizeProcessed, ISzAlloc *allocMain);
-
-#endif
diff --git a/archivers/7z/7zExtract.c b/archivers/7z/7zExtract.c
deleted file mode 100644 (file)
index fda5074..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* 7zExtract.c */
-
-#include "7zExtract.h"
-#include "7zDecode.h"
-#include "7zCrc.h"
-
-SZ_RESULT SzExtract(
-    ISzInStream *inStream,
-    CArchiveDatabaseEx *db,
-    UInt32 fileIndex,
-    UInt32 *blockIndex,
-    Byte **outBuffer,
-    size_t *outBufferSize,
-    size_t *offset,
-    size_t *outSizeProcessed,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
-{
-  UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
-  SZ_RESULT res = SZ_OK;
-  *offset = 0;
-  *outSizeProcessed = 0;
-  if (folderIndex == (UInt32)-1)
-  {
-    allocMain->Free(*outBuffer);
-    *blockIndex = folderIndex;
-    *outBuffer = 0;
-    *outBufferSize = 0;
-    return SZ_OK;
-  }
-
-  if (*outBuffer == 0 || *blockIndex != folderIndex)
-  {
-    CFolder *folder = db->Database.Folders + folderIndex;
-    CFileSize unPackSize = SzFolderGetUnPackSize(folder);
-    #ifndef _LZMA_IN_CB
-    CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
-    Byte *inBuffer = 0;
-    size_t processedSize;
-    #endif
-    *blockIndex = folderIndex;
-    allocMain->Free(*outBuffer);
-    *outBuffer = 0;
-
-    RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
-
-    #ifndef _LZMA_IN_CB
-    if (packSize != 0)
-    {
-      inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
-      if (inBuffer == 0)
-       return SZE_OUTOFMEMORY;
-    }
-    res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
-    if (res == SZ_OK && processedSize != (size_t)packSize)
-      res = SZE_FAIL;
-    #endif
-    if (res == SZ_OK)
-    {
-      *outBufferSize = (size_t)unPackSize;
-      if (unPackSize != 0)
-      {
-       *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
-       if (*outBuffer == 0)
-         res = SZE_OUTOFMEMORY;
-      }
-      if (res == SZ_OK)
-      {
-       size_t outRealSize;
-       res = SzDecode(db->Database.PackSizes +
-         db->FolderStartPackStreamIndex[folderIndex], folder,
-         #ifdef _LZMA_IN_CB
-         inStream,
-         #else
-         inBuffer,
-         #endif
-         *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
-       if (res == SZ_OK)
-       {
-         if (outRealSize == (size_t)unPackSize)
-         {
-           if (folder->UnPackCRCDefined)
-           {
-             if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
-               res = SZE_FAIL;
-           }
-         }
-         else
-           res = SZE_FAIL;
-       }
-      }
-    }
-    #ifndef _LZMA_IN_CB
-    allocTemp->Free(inBuffer);
-    #endif
-  }
-  if (res == SZ_OK)
-  {
-    UInt32 i;
-    CFileItem *fileItem = db->Database.Files + fileIndex;
-    *offset = 0;
-    for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
-      *offset += (UInt32)db->Database.Files[i].Size;
-    *outSizeProcessed = (size_t)fileItem->Size;
-    if (*offset + *outSizeProcessed > *outBufferSize)
-      return SZE_FAIL;
-    {
-      if (fileItem->IsFileCRCDefined)
-      {
-       if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
-         res = SZE_FAIL;
-      }
-    }
-  }
-  return res;
-}
diff --git a/archivers/7z/7zIn.c b/archivers/7z/7zIn.c
deleted file mode 100644 (file)
index ba0ab39..0000000
+++ /dev/null
@@ -1,1281 +0,0 @@
-/* 7zIn.c */
-
-#include "7zIn.h"
-#include "7zCrc.h"
-#include "7zDecode.h"
-
-#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
-
-void SzArDbExInit(CArchiveDatabaseEx *db)
-{
-  SzArchiveDatabaseInit(&db->Database);
-  db->FolderStartPackStreamIndex = 0;
-  db->PackStreamStartPositions = 0;
-  db->FolderStartFileIndex = 0;
-  db->FileIndexToFolderIndexMap = 0;
-}
-
-void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
-{
-  freeFunc(db->FolderStartPackStreamIndex);
-  freeFunc(db->PackStreamStartPositions);
-  freeFunc(db->FolderStartFileIndex);
-  freeFunc(db->FileIndexToFolderIndexMap);
-  SzArchiveDatabaseFree(&db->Database, freeFunc);
-  SzArDbExInit(db);
-}
-
-/*
-CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
-{
-  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
-}
-
-CFileSize GetFilePackSize(int fileIndex) const
-{
-  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
-  if (folderIndex >= 0)
-  {
-    const CFolder &folderInfo = Folders[folderIndex];
-    if (FolderStartFileIndex[folderIndex] == fileIndex)
-    return GetFolderFullPackSize(folderIndex);
-  }
-  return 0;
-}
-*/
-
-#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
-  if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
-
-SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
-{
-  UInt32 startPos = 0;
-  CFileSize startPosSize = 0;
-  UInt32 i;
-  UInt32 folderIndex = 0;
-  UInt32 indexInFolder = 0;
-  MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
-  for(i = 0; i < db->Database.NumFolders; i++)
-  {
-    db->FolderStartPackStreamIndex[i] = startPos;
-    startPos += db->Database.Folders[i].NumPackStreams;
-  }
-
-  MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
-
-  for(i = 0; i < db->Database.NumPackStreams; i++)
-  {
-    db->PackStreamStartPositions[i] = startPosSize;
-    startPosSize += db->Database.PackSizes[i];
-  }
-
-  MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
-  MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
-
-  for (i = 0; i < db->Database.NumFiles; i++)
-  {
-    CFileItem *file = db->Database.Files + i;
-    int emptyStream = !file->HasStream;
-    if (emptyStream && indexInFolder == 0)
-    {
-      db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
-      continue;
-    }
-    if (indexInFolder == 0)
-    {
-      /*
-      v3.13 incorrectly worked with empty folders
-      v4.07: Loop for skipping empty folders
-      */
-      while(1)
-      {
-       if (folderIndex >= db->Database.NumFolders)
-         return SZE_ARCHIVE_ERROR;
-       db->FolderStartFileIndex[folderIndex] = i;
-       if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
-         break;
-       folderIndex++;
-      }
-    }
-    db->FileIndexToFolderIndexMap[i] = folderIndex;
-    if (emptyStream)
-      continue;
-    indexInFolder++;
-    if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
-    {
-      folderIndex++;
-      indexInFolder = 0;
-    }
-  }
-  return SZ_OK;
-}
-
-
-CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
-{
-  return db->ArchiveInfo.DataStartPosition +
-    db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
-}
-
-CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
-{
-  UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
-  CFolder *folder = db->Database.Folders + folderIndex;
-  CFileSize size = 0;
-  UInt32 i;
-  for (i = 0; i < folder->NumPackStreams; i++)
-    size += db->Database.PackSizes[packStreamIndex + i];
-  return size;
-}
-
-
-/*
-SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
-    CObjectVector<CFileItem> &files, UInt64 type)
-{
-  CBoolVector boolVector;
-  RINOK(ReadBoolVector2(files.Size(), boolVector))
-
-  CStreamSwitch streamSwitch;
-  RINOK(streamSwitch.Set(this, &dataVector));
-
-  for(int i = 0; i < files.Size(); i++)
-  {
-    CFileItem &file = files[i];
-    CArchiveFileTime fileTime;
-    bool defined = boolVector[i];
-    if (defined)
-    {
-      UInt32 low, high;
-      RINOK(SzReadUInt32(low));
-      RINOK(SzReadUInt32(high));
-      fileTime.dwLowDateTime = low;
-      fileTime.dwHighDateTime = high;
-    }
-    switch(type)
-    {
-      case k7zIdCreationTime:
-       file.IsCreationTimeDefined = defined;
-       if (defined)
-         file.CreationTime = fileTime;
-       break;
-      case k7zIdLastWriteTime:
-       file.IsLastWriteTimeDefined = defined;
-       if (defined)
-         file.LastWriteTime = fileTime;
-       break;
-      case k7zIdLastAccessTime:
-       file.IsLastAccessTimeDefined = defined;
-       if (defined)
-         file.LastAccessTime = fileTime;
-       break;
-    }
-  }
-  return SZ_OK;
-}
-*/
-
-SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
-{
-  #ifdef _LZMA_IN_CB
-  while (size > 0)
-  {
-    Byte *inBuffer;
-    size_t processedSize;
-    RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
-    if (processedSize == 0 || processedSize > size)
-      return SZE_FAIL;
-    size -= processedSize;
-    do
-    {
-      *data++ = *inBuffer++;
-    }
-    while (--processedSize != 0);
-  }
-  #else
-  size_t processedSize;
-  RINOK(inStream->Read(inStream, data, size, &processedSize));
-  if (processedSize != size)
-    return SZE_FAIL;
-  #endif
-  return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
-{
-  return SafeReadDirect(inStream, data, 1);
-}
-
-SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value)
-{
-  int i;
-  *value = 0;
-  for (i = 0; i < 4; i++)
-  {
-    Byte b;
-    RINOK(SafeReadDirectByte(inStream, &b));
-    *value |= ((UInt32)b << (8 * i));
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
-{
-  int i;
-  *value = 0;
-  for (i = 0; i < 8; i++)
-  {
-    Byte b;
-    RINOK(SafeReadDirectByte(inStream, &b));
-    *value |= ((UInt32)b << (8 * i));
-  }
-  return SZ_OK;
-}
-
-int TestSignatureCandidate(Byte *testBytes)
-{
-  size_t i;
-  for (i = 0; i < k7zSignatureSize; i++)
-    if (testBytes[i] != k7zSignature[i])
-      return 0;
-  return 1;
-}
-
-typedef struct _CSzState
-{
-  Byte *Data;
-  size_t Size;
-}CSzData;
-
-SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
-{
-  if (sd->Size == 0)
-    return SZE_ARCHIVE_ERROR;
-  sd->Size--;
-  *b = *sd->Data++;
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
-{
-  size_t i;
-  for (i = 0; i < size; i++)
-  {
-    RINOK(SzReadByte(sd, data + i));
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
-{
-  int i;
-  *value = 0;
-  for (i = 0; i < 4; i++)
-  {
-    Byte b;
-    RINOK(SzReadByte(sd, &b));
-    *value |= ((UInt32)(b) << (8 * i));
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
-{
-  Byte firstByte;
-  Byte mask = 0x80;
-  int i;
-  RINOK(SzReadByte(sd, &firstByte));
-  *value = 0;
-  for (i = 0; i < 8; i++)
-  {
-    Byte b;
-    if ((firstByte & mask) == 0)
-    {
-      UInt64 highPart = firstByte & (mask - 1);
-      *value += (highPart << (8 * i));
-      return SZ_OK;
-    }
-    RINOK(SzReadByte(sd, &b));
-    *value |= ((UInt64)b << (8 * i));
-    mask >>= 1;
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
-{
-  UInt64 value64;
-  RINOK(SzReadNumber(sd, &value64));
-  *value = (CFileSize)value64;
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
-{
-  UInt64 value64;
-  RINOK(SzReadNumber(sd, &value64));
-  if (value64 >= 0x80000000)
-    return SZE_NOTIMPL;
-  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
-    return SZE_NOTIMPL;
-  *value = (UInt32)value64;
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
-{
-  return SzReadNumber(sd, value);
-}
-
-SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
-{
-  if (size > sd->Size)
-    return SZE_ARCHIVE_ERROR;
-  sd->Size -= (size_t)size;
-  sd->Data += (size_t)size;
-  return SZ_OK;
-}
-
-SZ_RESULT SzSkeepData(CSzData *sd)
-{
-  UInt64 size;
-  RINOK(SzReadNumber(sd, &size));
-  return SzSkeepDataSize(sd, size);
-}
-
-SZ_RESULT SzReadArchiveProperties(CSzData *sd)
-{
-  while(1)
-  {
-    UInt64 type;
-    RINOK(SzReadID(sd, &type));
-    if (type == k7zIdEnd)
-      break;
-    SzSkeepData(sd);
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
-{
-  while(1)
-  {
-    UInt64 type;
-    RINOK(SzReadID(sd, &type));
-    if (type == attribute)
-      return SZ_OK;
-    if (type == k7zIdEnd)
-      return SZE_ARCHIVE_ERROR;
-    RINOK(SzSkeepData(sd));
-  }
-}
-
-SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
-  Byte b = 0;
-  Byte mask = 0;
-  size_t i;
-  MY_ALLOC(Byte, *v, numItems, allocFunc);
-  for(i = 0; i < numItems; i++)
-  {
-    if (mask == 0)
-    {
-      RINOK(SzReadByte(sd, &b));
-      mask = 0x80;
-    }
-    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
-    mask >>= 1;
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
-  Byte allAreDefined;
-  size_t i;
-  RINOK(SzReadByte(sd, &allAreDefined));
-  if (allAreDefined == 0)
-    return SzReadBoolVector(sd, numItems, v, allocFunc);
-  MY_ALLOC(Byte, *v, numItems, allocFunc);
-  for(i = 0; i < numItems; i++)
-    (*v)[i] = 1;
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadHashDigests(
-    CSzData *sd,
-    size_t numItems,
-    Byte **digestsDefined,
-    UInt32 **digests,
-    void * (*allocFunc)(size_t size))
-{
-  size_t i;
-  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
-  MY_ALLOC(UInt32, *digests, numItems, allocFunc);
-  for(i = 0; i < numItems; i++)
-    if ((*digestsDefined)[i])
-    {
-      RINOK(SzReadUInt32(sd, (*digests) + i));
-    }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadPackInfo(
-    CSzData *sd,
-    CFileSize *dataOffset,
-    UInt32 *numPackStreams,
-    CFileSize **packSizes,
-    Byte **packCRCsDefined,
-    UInt32 **packCRCs,
-    void * (*allocFunc)(size_t size))
-{
-  UInt32 i;
-  RINOK(SzReadSize(sd, dataOffset));
-  RINOK(SzReadNumber32(sd, numPackStreams));
-
-  RINOK(SzWaitAttribute(sd, k7zIdSize));
-
-  MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
-
-  for(i = 0; i < *numPackStreams; i++)
-  {
-    RINOK(SzReadSize(sd, (*packSizes) + i));
-  }
-
-  while(1)
-  {
-    UInt64 type;
-    RINOK(SzReadID(sd, &type));
-    if (type == k7zIdEnd)
-      break;
-    if (type == k7zIdCRC)
-    {
-      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
-      continue;
-    }
-    RINOK(SzSkeepData(sd));
-  }
-  if (*packCRCsDefined == 0)
-  {
-    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
-    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
-    for(i = 0; i < *numPackStreams; i++)
-    {
-      (*packCRCsDefined)[i] = 0;
-      (*packCRCs)[i] = 0;
-    }
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadSwitch(CSzData *sd)
-{
-  Byte external;
-  RINOK(SzReadByte(sd, &external));
-  return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
-}
-
-SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
-{
-  UInt32 numCoders;
-  UInt32 numBindPairs;
-  UInt32 numPackedStreams;
-  UInt32 i;
-  UInt32 numInStreams = 0;
-  UInt32 numOutStreams = 0;
-  RINOK(SzReadNumber32(sd, &numCoders));
-  folder->NumCoders = numCoders;
-
-  MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
-
-  for (i = 0; i < numCoders; i++)
-    SzCoderInfoInit(folder->Coders + i);
-
-  for (i = 0; i < numCoders; i++)
-  {
-    Byte mainByte;
-    CCoderInfo *coder = folder->Coders + i;
-    {
-      RINOK(SzReadByte(sd, &mainByte));
-      coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
-      RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
-      if ((mainByte & 0x10) != 0)
-      {
-       RINOK(SzReadNumber32(sd, &coder->NumInStreams));
-       RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
-      }
-      else
-      {
-       coder->NumInStreams = 1;
-       coder->NumOutStreams = 1;
-      }
-      if ((mainByte & 0x20) != 0)
-      {
-       UInt64 propertiesSize = 0;
-       RINOK(SzReadNumber(sd, &propertiesSize));
-       if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
-         return SZE_OUTOFMEMORY;
-       RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
-      }
-    }
-    while ((mainByte & 0x80) != 0)
-    {
-      RINOK(SzReadByte(sd, &mainByte));
-      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
-      if ((mainByte & 0x10) != 0)
-      {
-       UInt32 n;
-       RINOK(SzReadNumber32(sd, &n));
-       RINOK(SzReadNumber32(sd, &n));
-      }
-      if ((mainByte & 0x20) != 0)
-      {
-       UInt64 propertiesSize = 0;
-       RINOK(SzReadNumber(sd, &propertiesSize));
-       RINOK(SzSkeepDataSize(sd, propertiesSize));
-      }
-    }
-    numInStreams += (UInt32)coder->NumInStreams;
-    numOutStreams += (UInt32)coder->NumOutStreams;
-  }
-
-  numBindPairs = numOutStreams - 1;
-  folder->NumBindPairs = numBindPairs;
-
-
-  MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
-
-  for (i = 0; i < numBindPairs; i++)
-  {
-    CBindPair *bindPair = folder->BindPairs + i;;
-    RINOK(SzReadNumber32(sd, &bindPair->InIndex));
-    RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
-  }
-
-  numPackedStreams = numInStreams - (UInt32)numBindPairs;
-
-  folder->NumPackStreams = numPackedStreams;
-  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
-
-  if (numPackedStreams == 1)
-  {
-    UInt32 j;
-    UInt32 pi = 0;
-    for (j = 0; j < numInStreams; j++)
-      if (SzFolderFindBindPairForInStream(folder, j) < 0)
-      {
-       folder->PackStreams[pi++] = j;
-       break;
-      }
-  }
-  else
-    for(i = 0; i < numPackedStreams; i++)
-    {
-      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
-    }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadUnPackInfo(
-    CSzData *sd,
-    UInt32 *numFolders,
-    CFolder **folders,  /* for allocFunc */
-    void * (*allocFunc)(size_t size),
-    ISzAlloc *allocTemp)
-{
-  UInt32 i;
-  RINOK(SzWaitAttribute(sd, k7zIdFolder));
-  RINOK(SzReadNumber32(sd, numFolders));
-  {
-    RINOK(SzReadSwitch(sd));
-
-    MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
-
-    for(i = 0; i < *numFolders; i++)
-      SzFolderInit((*folders) + i);
-
-    for(i = 0; i < *numFolders; i++)
-    {
-      RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
-    }
-  }
-
-  RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
-
-  for(i = 0; i < *numFolders; i++)
-  {
-    UInt32 j;
-    CFolder *folder = (*folders) + i;
-    UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
-
-    MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
-
-    for(j = 0; j < numOutStreams; j++)
-    {
-      RINOK(SzReadSize(sd, folder->UnPackSizes + j));
-    }
-  }
-
-  while(1)
-  {
-    UInt64 type;
-    RINOK(SzReadID(sd, &type));
-    if (type == k7zIdEnd)
-      return SZ_OK;
-    if (type == k7zIdCRC)
-    {
-      SZ_RESULT res;
-      Byte *crcsDefined = 0;
-      UInt32 *crcs = 0;
-      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
-      if (res == SZ_OK)
-      {
-       for(i = 0; i < *numFolders; i++)
-       {
-         CFolder *folder = (*folders) + i;
-         folder->UnPackCRCDefined = crcsDefined[i];
-         folder->UnPackCRC = crcs[i];
-       }
-      }
-      allocTemp->Free(crcs);
-      allocTemp->Free(crcsDefined);
-      RINOK(res);
-      continue;
-    }
-    RINOK(SzSkeepData(sd));
-  }
-}
-
-SZ_RESULT SzReadSubStreamsInfo(
-    CSzData *sd,
-    UInt32 numFolders,
-    CFolder *folders,
-    UInt32 *numUnPackStreams,
-    CFileSize **unPackSizes,
-    Byte **digestsDefined,
-    UInt32 **digests,
-    ISzAlloc *allocTemp)
-{
-  UInt64 type = 0;
-  UInt32 i;
-  UInt32 si = 0;
-  UInt32 numDigests = 0;
-
-  for(i = 0; i < numFolders; i++)
-    folders[i].NumUnPackStreams = 1;
-  *numUnPackStreams = numFolders;
-
-  while(1)
-  {
-    RINOK(SzReadID(sd, &type));
-    if (type == k7zIdNumUnPackStream)
-    {
-      *numUnPackStreams = 0;
-      for(i = 0; i < numFolders; i++)
-      {
-       UInt32 numStreams;
-       RINOK(SzReadNumber32(sd, &numStreams));
-       folders[i].NumUnPackStreams = numStreams;
-       *numUnPackStreams += numStreams;
-      }
-      continue;
-    }
-    if (type == k7zIdCRC || type == k7zIdSize)
-      break;
-    if (type == k7zIdEnd)
-      break;
-    RINOK(SzSkeepData(sd));
-  }
-
-  if (*numUnPackStreams == 0)
-  {
-    *unPackSizes = 0;
-    *digestsDefined = 0;
-    *digests = 0;
-  }
-  else
-  {
-    *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
-    RINOM(*unPackSizes);
-    *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
-    RINOM(*digestsDefined);
-    *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
-    RINOM(*digests);
-  }
-
-  for(i = 0; i < numFolders; i++)
-  {
-    /*
-    v3.13 incorrectly worked with empty folders
-    v4.07: we check that folder is empty
-    */
-    CFileSize sum = 0;
-    UInt32 j;
-    UInt32 numSubstreams = folders[i].NumUnPackStreams;
-    if (numSubstreams == 0)
-      continue;
-    if (type == k7zIdSize)
-    for (j = 1; j < numSubstreams; j++)
-    {
-      CFileSize size;
-      RINOK(SzReadSize(sd, &size));
-      (*unPackSizes)[si++] = size;
-      sum += size;
-    }
-    (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
-  }
-  if (type == k7zIdSize)
-  {
-    RINOK(SzReadID(sd, &type));
-  }
-
-  for(i = 0; i < *numUnPackStreams; i++)
-  {
-    (*digestsDefined)[i] = 0;
-    (*digests)[i] = 0;
-  }
-
-
-  for(i = 0; i < numFolders; i++)
-  {
-    UInt32 numSubstreams = folders[i].NumUnPackStreams;
-    if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
-      numDigests += numSubstreams;
-  }
-
-
-  si = 0;
-  while(1)
-  {
-    if (type == k7zIdCRC)
-    {
-      int digestIndex = 0;
-      Byte *digestsDefined2 = 0;
-      UInt32 *digests2 = 0;
-      SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
-      if (res == SZ_OK)
-      {
-       for (i = 0; i < numFolders; i++)
-       {
-         CFolder *folder = folders + i;
-         UInt32 numSubstreams = folder->NumUnPackStreams;
-         if (numSubstreams == 1 && folder->UnPackCRCDefined)
-         {
-           (*digestsDefined)[si] = 1;
-           (*digests)[si] = folder->UnPackCRC;
-           si++;
-         }
-         else
-         {
-           UInt32 j;
-           for (j = 0; j < numSubstreams; j++, digestIndex++)
-           {
-             (*digestsDefined)[si] = digestsDefined2[digestIndex];
-             (*digests)[si] = digests2[digestIndex];
-             si++;
-           }
-         }
-       }
-      }
-      allocTemp->Free(digestsDefined2);
-      allocTemp->Free(digests2);
-      RINOK(res);
-    }
-    else if (type == k7zIdEnd)
-      return SZ_OK;
-    else
-    {
-      RINOK(SzSkeepData(sd));
-    }
-    RINOK(SzReadID(sd, &type));
-  }
-}
-
-
-SZ_RESULT SzReadStreamsInfo(
-    CSzData *sd,
-    CFileSize *dataOffset,
-    CArchiveDatabase *db,
-    UInt32 *numUnPackStreams,
-    CFileSize **unPackSizes, /* allocTemp */
-    Byte **digestsDefined,   /* allocTemp */
-    UInt32 **digests,        /* allocTemp */
-    void * (*allocFunc)(size_t size),
-    ISzAlloc *allocTemp)
-{
-  while(1)
-  {
-    UInt64 type;
-    RINOK(SzReadID(sd, &type));
-    if ((UInt64)(int)type != type)
-      return SZE_FAIL;
-    switch((int)type)
-    {
-      case k7zIdEnd:
-       return SZ_OK;
-      case k7zIdPackInfo:
-      {
-       RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
-           &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
-       break;
-      }
-      case k7zIdUnPackInfo:
-      {
-       RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
-       break;
-      }
-      case k7zIdSubStreamsInfo:
-      {
-       RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
-           numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
-       break;
-      }
-      default:
-       return SZE_FAIL;
-    }
-  }
-}
-
-Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
-    void * (*allocFunc)(size_t size))
-{
-  UInt32 i;
-  for(i = 0; i < numFiles; i++)
-  {
-    UInt32 len = 0;
-    UInt32 pos = 0;
-    CFileItem *file = files + i;
-    while(pos + 2 <= sd->Size)
-    {
-      int numAdds;
-      UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
-      pos += 2;
-      len++;
-      if (value == 0)
-       break;
-      if (value < 0x80)
-       continue;
-      if (value >= 0xD800 && value < 0xE000)
-      {
-       UInt32 c2;
-       if (value >= 0xDC00)
-         return SZE_ARCHIVE_ERROR;
-       if (pos + 2 > sd->Size)
-         return SZE_ARCHIVE_ERROR;
-       c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
-       pos += 2;
-       if (c2 < 0xDC00 || c2 >= 0xE000)
-         return SZE_ARCHIVE_ERROR;
-       value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
-      }
-      for (numAdds = 1; numAdds < 5; numAdds++)
-       if (value < (((UInt32)1) << (numAdds * 5 + 6)))
-         break;
-      len += numAdds;
-    }
-
-    MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
-
-    len = 0;
-    while(2 <= sd->Size)
-    {
-      int numAdds;
-      UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
-      SzSkeepDataSize(sd, 2);
-      if (value < 0x80)
-      {
-       file->Name[len++] = (char)value;
-       if (value == 0)
-         break;
-       continue;
-      }
-      if (value >= 0xD800 && value < 0xE000)
-      {
-       UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
-       SzSkeepDataSize(sd, 2);
-       value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
-      }
-      for (numAdds = 1; numAdds < 5; numAdds++)
-       if (value < (((UInt32)1) << (numAdds * 5 + 6)))
-         break;
-      file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
-      do
-      {
-       numAdds--;
-       file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
-      }
-      while(numAdds > 0);
-
-      len += numAdds;
-    }
-  }
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadHeader2(
-    CSzData *sd,
-    CArchiveDatabaseEx *db,   /* allocMain */
-    CFileSize **unPackSizes,  /* allocTemp */
-    Byte **digestsDefined,    /* allocTemp */
-    UInt32 **digests,         /* allocTemp */
-    Byte **emptyStreamVector, /* allocTemp */
-    Byte **emptyFileVector,   /* allocTemp */
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
-{
-  UInt64 type;
-  UInt32 numUnPackStreams = 0;
-  UInt32 numFiles = 0;
-  CFileItem *files = 0;
-  UInt32 numEmptyStreams = 0;
-  UInt32 i;
-
-  RINOK(SzReadID(sd, &type));
-
-  if (type == k7zIdArchiveProperties)
-  {
-    RINOK(SzReadArchiveProperties(sd));
-    RINOK(SzReadID(sd, &type));
-  }
-
-
-  if (type == k7zIdMainStreamsInfo)
-  {
-    RINOK(SzReadStreamsInfo(sd,
-       &db->ArchiveInfo.DataStartPosition,
-       &db->Database,
-       &numUnPackStreams,
-       unPackSizes,
-       digestsDefined,
-       digests, allocMain->Alloc, allocTemp));
-    db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
-    RINOK(SzReadID(sd, &type));
-  }
-
-  if (type == k7zIdEnd)
-    return SZ_OK;
-  if (type != k7zIdFilesInfo)
-    return SZE_ARCHIVE_ERROR;
-
-  RINOK(SzReadNumber32(sd, &numFiles));
-  db->Database.NumFiles = numFiles;
-
-  MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
-
-  db->Database.Files = files;
-  for(i = 0; i < numFiles; i++)
-    SzFileInit(files + i);
-
-  while(1)
-  {
-    UInt64 type;
-    UInt64 size;
-    RINOK(SzReadID(sd, &type));
-    if (type == k7zIdEnd)
-      break;
-    RINOK(SzReadNumber(sd, &size));
-
-    if ((UInt64)(int)type != type)
-    {
-      RINOK(SzSkeepDataSize(sd, size));
-    }
-    else
-    switch((int)type)
-    {
-      case k7zIdName:
-      {
-       RINOK(SzReadSwitch(sd));
-       RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
-       break;
-      }
-      case k7zIdEmptyStream:
-      {
-       RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
-       numEmptyStreams = 0;
-       for (i = 0; i < numFiles; i++)
-         if ((*emptyStreamVector)[i])
-           numEmptyStreams++;
-       break;
-      }
-      case k7zIdEmptyFile:
-      {
-       RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
-       break;
-      }
-      default:
-      {
-       RINOK(SzSkeepDataSize(sd, size));
-      }
-    }
-  }
-
-  {
-    UInt32 emptyFileIndex = 0;
-    UInt32 sizeIndex = 0;
-    for(i = 0; i < numFiles; i++)
-    {
-      CFileItem *file = files + i;
-      file->IsAnti = 0;
-      if (*emptyStreamVector == 0)
-       file->HasStream = 1;
-      else
-       file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
-      if(file->HasStream)
-      {
-       file->IsDirectory = 0;
-       file->Size = (*unPackSizes)[sizeIndex];
-       file->FileCRC = (*digests)[sizeIndex];
-       file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
-       sizeIndex++;
-      }
-      else
-      {
-       if (*emptyFileVector == 0)
-         file->IsDirectory = 1;
-       else
-         file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
-       emptyFileIndex++;
-       file->Size = 0;
-       file->IsFileCRCDefined = 0;
-      }
-    }
-  }
-  return SzArDbExFill(db, allocMain->Alloc);
-}
-
-SZ_RESULT SzReadHeader(
-    CSzData *sd,
-    CArchiveDatabaseEx *db,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
-{
-  CFileSize *unPackSizes = 0;
-  Byte *digestsDefined = 0;
-  UInt32 *digests = 0;
-  Byte *emptyStreamVector = 0;
-  Byte *emptyFileVector = 0;
-  SZ_RESULT res = SzReadHeader2(sd, db,
-      &unPackSizes, &digestsDefined, &digests,
-      &emptyStreamVector, &emptyFileVector,
-      allocMain, allocTemp);
-  allocTemp->Free(unPackSizes);
-  allocTemp->Free(digestsDefined);
-  allocTemp->Free(digests);
-  allocTemp->Free(emptyStreamVector);
-  allocTemp->Free(emptyFileVector);
-  return res;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams2(
-    ISzInStream *inStream,
-    CSzData *sd,
-    CSzByteBuffer *outBuffer,
-    CFileSize baseOffset,
-    CArchiveDatabase *db,
-    CFileSize **unPackSizes,
-    Byte **digestsDefined,
-    UInt32 **digests,
-    #ifndef _LZMA_IN_CB
-    Byte **inBuffer,
-    #endif
-    ISzAlloc *allocTemp)
-{
-
-  UInt32 numUnPackStreams = 0;
-  CFileSize dataStartPos;
-  CFolder *folder;
-  #ifndef _LZMA_IN_CB
-  CFileSize packSize = 0;
-  UInt32 i = 0;
-  #endif
-  CFileSize unPackSize;
-  size_t outRealSize;
-  SZ_RESULT res;
-
-  RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
-      &numUnPackStreams,  unPackSizes, digestsDefined, digests,
-      allocTemp->Alloc, allocTemp));
-
-  dataStartPos += baseOffset;
-  if (db->NumFolders != 1)
-    return SZE_ARCHIVE_ERROR;
-
-  folder = db->Folders;
-  unPackSize = SzFolderGetUnPackSize(folder);
-
-  RINOK(inStream->Seek(inStream, dataStartPos));
-
-  #ifndef _LZMA_IN_CB
-  for (i = 0; i < db->NumPackStreams; i++)
-    packSize += db->PackSizes[i];
-
-  MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
-
-  RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
-  #endif
-
-  if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
-    return SZE_OUTOFMEMORY;
-
-  res = SzDecode(db->PackSizes, folder,
-         #ifdef _LZMA_IN_CB
-         inStream,
-         #else
-         *inBuffer,
-         #endif
-         outBuffer->Items, (size_t)unPackSize,
-         &outRealSize, allocTemp);
-  RINOK(res)
-  if (outRealSize != (UInt32)unPackSize)
-    return SZE_FAIL;
-  if (folder->UnPackCRCDefined)
-    if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize))
-      return SZE_FAIL;
-  return SZ_OK;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams(
-    ISzInStream *inStream,
-    CSzData *sd,
-    CSzByteBuffer *outBuffer,
-    CFileSize baseOffset,
-    ISzAlloc *allocTemp)
-{
-  CArchiveDatabase db;
-  CFileSize *unPackSizes = 0;
-  Byte *digestsDefined = 0;
-  UInt32 *digests = 0;
-  #ifndef _LZMA_IN_CB
-  Byte *inBuffer = 0;
-  #endif
-  SZ_RESULT res;
-  SzArchiveDatabaseInit(&db);
-  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
-    &db, &unPackSizes, &digestsDefined, &digests,
-    #ifndef _LZMA_IN_CB
-    &inBuffer,
-    #endif
-    allocTemp);
-  SzArchiveDatabaseFree(&db, allocTemp->Free);
-  allocTemp->Free(unPackSizes);
-  allocTemp->Free(digestsDefined);
-  allocTemp->Free(digests);
-  #ifndef _LZMA_IN_CB
-  allocTemp->Free(inBuffer);
-  #endif
-  return res;
-}
-
-SZ_RESULT SzArchiveOpen2(
-    ISzInStream *inStream,
-    CArchiveDatabaseEx *db,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
-{
-  Byte signature[k7zSignatureSize];
-  Byte version;
-  UInt32 crcFromArchive;
-  UInt64 nextHeaderOffset;
-  UInt64 nextHeaderSize;
-  UInt32 nextHeaderCRC;
-  UInt32 crc;
-  CFileSize pos = 0;
-  CSzByteBuffer buffer;
-  CSzData sd;
-  SZ_RESULT res;
-
-  RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
-
-  if (!TestSignatureCandidate(signature))
-    return SZE_ARCHIVE_ERROR;
-
-  /*
-  db.Clear();
-  db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
-  */
-  RINOK(SafeReadDirectByte(inStream, &version));
-  if (version != k7zMajorVersion)
-    return SZE_ARCHIVE_ERROR;
-  RINOK(SafeReadDirectByte(inStream, &version));
-
-  RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive));
-
-  CrcInit(&crc);
-  RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset));
-  CrcUpdateUInt64(&crc, nextHeaderOffset);
-  RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize));
-  CrcUpdateUInt64(&crc, nextHeaderSize);
-  RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC));
-  CrcUpdateUInt32(&crc, nextHeaderCRC);
-
-  pos = k7zStartHeaderSize;
-  db->ArchiveInfo.StartPositionAfterHeader = pos;
-
-  if (CrcGetDigest(&crc) != crcFromArchive)
-    return SZE_ARCHIVE_ERROR;
-
-  if (nextHeaderSize == 0)
-    return SZ_OK;
-
-  RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
-
-  if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
-    return SZE_OUTOFMEMORY;
-
-  res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
-  if (res == SZ_OK)
-  {
-    if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
-    {
-      while (1)
-      {
-       UInt64 type;
-       sd.Data = buffer.Items;
-       sd.Size = buffer.Capacity;
-       res = SzReadID(&sd, &type);
-       if (res != SZ_OK)
-         break;
-       if (type == k7zIdHeader)
-       {
-         res = SzReadHeader(&sd, db, allocMain, allocTemp);
-         break;
-       }
-       if (type != k7zIdEncodedHeader)
-       {
-         res = SZE_ARCHIVE_ERROR;
-         break;
-       }
-       {
-         CSzByteBuffer outBuffer;
-         res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
-             db->ArchiveInfo.StartPositionAfterHeader,
-             allocTemp);
-         if (res != SZ_OK)
-         {
-           SzByteBufferFree(&outBuffer, allocTemp->Free);
-           break;
-         }
-         SzByteBufferFree(&buffer, allocTemp->Free);
-         buffer.Items = outBuffer.Items;
-         buffer.Capacity = outBuffer.Capacity;
-       }
-      }
-    }
-  }
-  SzByteBufferFree(&buffer, allocTemp->Free);
-  return res;
-}
-
-SZ_RESULT SzArchiveOpen(
-    ISzInStream *inStream,
-    CArchiveDatabaseEx *db,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
-{
-  SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
-  if (res != SZ_OK)
-    SzArDbExFree(db, allocMain->Free);
-  return res;
-}
diff --git a/archivers/7z/7zIn.h b/archivers/7z/7zIn.h
deleted file mode 100644 (file)
index f874225..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 7zIn.h */
-
-#ifndef __7Z_IN_H
-#define __7Z_IN_H
-
-#include "7zHeader.h"
-#include "7zItem.h"
-#include "7zAlloc.h"
-
-typedef struct _CInArchiveInfo
-{
-  CFileSize StartPositionAfterHeader;
-  CFileSize DataStartPosition;
-}CInArchiveInfo;
-
-typedef struct _CArchiveDatabaseEx
-{
-  CArchiveDatabase Database;
-  CInArchiveInfo ArchiveInfo;
-  UInt32 *FolderStartPackStreamIndex;
-  CFileSize *PackStreamStartPositions;
-  UInt32 *FolderStartFileIndex;
-  UInt32 *FileIndexToFolderIndexMap;
-}CArchiveDatabaseEx;
-
-void SzArDbExInit(CArchiveDatabaseEx *db);
-void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
-CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
-CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
-
-typedef struct _ISzInStream
-{
-  #ifdef _LZMA_IN_CB
-  SZ_RESULT (*Read)(
-      void *object,           /* pointer to ISzInStream itself */
-      void **buffer,          /* out: pointer to buffer with data */
-      size_t maxRequiredSize, /* max required size to read */
-      size_t *processedSize); /* real processed size.
-                                processedSize can be less than maxRequiredSize.
-                                If processedSize == 0, then there are no more
-                                bytes in stream. */
-  #else
-  SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
-  #endif
-  SZ_RESULT (*Seek)(void *object, CFileSize pos);
-} ISzInStream;
-
-
-int SzArchiveOpen(
-    ISzInStream *inStream,
-    CArchiveDatabaseEx *db,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp);
-
-#endif
diff --git a/archivers/7z/7zItem.c b/archivers/7z/7zItem.c
deleted file mode 100644 (file)
index 26ea00f..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* 7zItem.c */
-
-#include "7zItem.h"
-#include "7zAlloc.h"
-
-void SzCoderInfoInit(CCoderInfo *coder)
-{
-  SzByteBufferInit(&coder->Properties);
-}
-
-void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
-{
-  SzByteBufferFree(&coder->Properties, freeFunc);
-  SzCoderInfoInit(coder);
-}
-
-void SzFolderInit(CFolder *folder)
-{
-  folder->NumCoders = 0;
-  folder->Coders = 0;
-  folder->NumBindPairs = 0;
-  folder->BindPairs = 0;
-  folder->NumPackStreams = 0;
-  folder->PackStreams = 0;
-  folder->UnPackSizes = 0;
-  folder->UnPackCRCDefined = 0;
-  folder->UnPackCRC = 0;
-  folder->NumUnPackStreams = 0;
-}
-
-void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
-{
-  UInt32 i;
-  for (i = 0; i < folder->NumCoders; i++)
-    SzCoderInfoFree(&folder->Coders[i], freeFunc);
-  freeFunc(folder->Coders);
-  freeFunc(folder->BindPairs);
-  freeFunc(folder->PackStreams);
-  freeFunc(folder->UnPackSizes);
-  SzFolderInit(folder);
-}
-
-UInt32 SzFolderGetNumOutStreams(CFolder *folder)
-{
-  UInt32 result = 0;
-  UInt32 i;
-  for (i = 0; i < folder->NumCoders; i++)
-    result += folder->Coders[i].NumOutStreams;
-  return result;
-}
-
-int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
-{
-  UInt32 i;
-  for(i = 0; i < folder->NumBindPairs; i++)
-    if (folder->BindPairs[i].InIndex == inStreamIndex)
-      return i;
-  return -1;
-}
-
-
-int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
-{
-  UInt32 i;
-  for(i = 0; i < folder->NumBindPairs; i++)
-    if (folder->BindPairs[i].OutIndex == outStreamIndex)
-      return i;
-  return -1;
-}
-
-CFileSize SzFolderGetUnPackSize(CFolder *folder)
-{
-  int i = (int)SzFolderGetNumOutStreams(folder);
-  if (i == 0)
-    return 0;
-  for (i--; i >= 0; i--)
-    if (SzFolderFindBindPairForOutStream(folder, i) < 0)
-      return folder->UnPackSizes[i];
-  /* throw 1; */
-  return 0;
-}
-
-/*
-int FindPackStreamArrayIndex(int inStreamIndex) const
-{
-  for(int i = 0; i < PackStreams.Size(); i++)
-  if (PackStreams[i] == inStreamIndex)
-    return i;
-  return -1;
-}
-*/
-
-void SzFileInit(CFileItem *fileItem)
-{
-  fileItem->IsFileCRCDefined = 0;
-  fileItem->HasStream = 1;
-  fileItem->IsDirectory = 0;
-  fileItem->IsAnti = 0;
-  fileItem->Name = 0;
-}
-
-void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
-{
-  freeFunc(fileItem->Name);
-  SzFileInit(fileItem);
-}
-
-void SzArchiveDatabaseInit(CArchiveDatabase *db)
-{
-  db->NumPackStreams = 0;
-  db->PackSizes = 0;
-  db->PackCRCsDefined = 0;
-  db->PackCRCs = 0;
-  db->NumFolders = 0;
-  db->Folders = 0;
-  db->NumFiles = 0;
-  db->Files = 0;
-}
-
-void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
-{
-  UInt32 i;
-  for (i = 0; i < db->NumFolders; i++)
-    SzFolderFree(&db->Folders[i], freeFunc);
-  for (i = 0; i < db->NumFiles; i++)
-    SzFileFree(&db->Files[i], freeFunc);
-  freeFunc(db->PackSizes);
-  freeFunc(db->PackCRCsDefined);
-  freeFunc(db->PackCRCs);
-  freeFunc(db->Folders);
-  freeFunc(db->Files);
-  SzArchiveDatabaseInit(db);
-}
diff --git a/archivers/7z/7zItem.h b/archivers/7z/7zItem.h
deleted file mode 100644 (file)
index 4d848b0..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* 7zItem.h */
-
-#ifndef __7Z_ITEM_H
-#define __7Z_ITEM_H
-
-#include "7zMethodID.h"
-#include "7zHeader.h"
-#include "7zBuffer.h"
-
-typedef struct _CCoderInfo
-{
-  UInt32 NumInStreams;
-  UInt32 NumOutStreams;
-  CMethodID MethodID;
-  CSzByteBuffer Properties;
-}CCoderInfo;
-
-void SzCoderInfoInit(CCoderInfo *coder);
-void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
-
-typedef struct _CBindPair
-{
-  UInt32 InIndex;
-  UInt32 OutIndex;
-}CBindPair;
-
-typedef struct _CFolder
-{
-  UInt32 NumCoders;
-  CCoderInfo *Coders;
-  UInt32 NumBindPairs;
-  CBindPair *BindPairs;
-  UInt32 NumPackStreams;
-  UInt32 *PackStreams;
-  CFileSize *UnPackSizes;
-  int UnPackCRCDefined;
-  UInt32 UnPackCRC;
-
-  UInt32 NumUnPackStreams;
-}CFolder;
-
-void SzFolderInit(CFolder *folder);
-CFileSize SzFolderGetUnPackSize(CFolder *folder);
-int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
-UInt32 SzFolderGetNumOutStreams(CFolder *folder);
-CFileSize SzFolderGetUnPackSize(CFolder *folder);
-
-/* #define CArchiveFileTime UInt64 */
-
-typedef struct _CFileItem
-{
-  /*
-  CArchiveFileTime LastWriteTime;
-  CFileSize StartPos;
-  UInt32 Attributes;
-  */
-  CFileSize Size;
-  UInt32 FileCRC;
-  char *Name;
-
-  Byte IsFileCRCDefined;
-  Byte HasStream;
-  Byte IsDirectory;
-  Byte IsAnti;
-  /*
-  int AreAttributesDefined;
-  int IsLastWriteTimeDefined;
-  int IsStartPosDefined;
-  */
-}CFileItem;
-
-void SzFileInit(CFileItem *fileItem);
-
-typedef struct _CArchiveDatabase
-{
-  UInt32 NumPackStreams;
-  CFileSize *PackSizes;
-  Byte *PackCRCsDefined;
-  UInt32 *PackCRCs;
-  UInt32 NumFolders;
-  CFolder *Folders;
-  UInt32 NumFiles;
-  CFileItem *Files;
-}CArchiveDatabase;
-
-void SzArchiveDatabaseInit(CArchiveDatabase *db);
-void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
-
-
-#endif
diff --git a/archivers/7z/7zMain.c b/archivers/7z/7zMain.c
deleted file mode 100644 (file)
index 263bc2c..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-7zMain.c
-Test application for 7z Decoder
-LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "7zCrc.h"
-#include "7zIn.h"
-#include "7zExtract.h"
-
-typedef struct _CFileInStream
-{
-  ISzInStream InStream;
-  FILE *File;
-} CFileInStream;
-
-#ifdef _LZMA_IN_CB
-
-#define kBufferSize (1 << 12)
-Byte g_Buffer[kBufferSize];
-
-SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
-{
-  CFileInStream *s = (CFileInStream *)object;
-  size_t processedSizeLoc;
-  if (maxRequiredSize > kBufferSize)
-    maxRequiredSize = kBufferSize;
-  processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
-  *buffer = g_Buffer;
-  if (processedSize != 0)
-    *processedSize = processedSizeLoc;
-  return SZ_OK;
-}
-
-#else
-
-SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
-{
-  CFileInStream *s = (CFileInStream *)object;
-  size_t processedSizeLoc = fread(buffer, 1, size, s->File);
-  if (processedSize != 0)
-    *processedSize = processedSizeLoc;
-  return SZ_OK;
-}
-
-#endif
-
-SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
-{
-  CFileInStream *s = (CFileInStream *)object;
-  int res = fseek(s->File, (long)pos, SEEK_SET);
-  if (res == 0)
-    return SZ_OK;
-  return SZE_FAIL;
-}
-
-void PrintError(char *sz)
-{
-  printf("\nERROR: %s\n", sz);
-}
-
-int main(int numargs, char *args[])
-{
-  CFileInStream archiveStream;
-  CArchiveDatabaseEx db;
-  SZ_RESULT res;
-  ISzAlloc allocImp;
-  ISzAlloc allocTempImp;
-
-  printf("\n7z ANSI-C Decoder 4.43  Copyright (c) 1999-2006 Igor Pavlov  2006-06-04\n");
-  if (numargs == 1)
-  {
-    printf(
-      "\nUsage: 7zDec <command> <archive_name>\n\n"
-      "<Commands>\n"
-      "  e: Extract files from archive\n"
-      "  l: List contents of archive\n"
-      "  t: Test integrity of archive\n");
-    return 0;
-  }
-  if (numargs < 3)
-  {
-    PrintError("incorrect command");
-    return 1;
-  }
-
-  archiveStream.File = fopen(args[2], "rb");
-  if (archiveStream.File == 0)
-  {
-    PrintError("can not open input file");
-    return 1;
-  }
-
-  archiveStream.InStream.Read = SzFileReadImp;
-  archiveStream.InStream.Seek = SzFileSeekImp;
-
-  allocImp.Alloc = SzAlloc;
-  allocImp.Free = SzFree;
-
-  allocTempImp.Alloc = SzAllocTemp;
-  allocTempImp.Free = SzFreeTemp;
-
-  InitCrcTable();
-  SzArDbExInit(&db);
-  res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
-  if (res == SZ_OK)
-  {
-    char *command = args[1];
-    int listCommand = 0;
-    int testCommand = 0;
-    int extractCommand = 0;
-    if (strcmp(command, "l") == 0)
-      listCommand = 1;
-    if (strcmp(command, "t") == 0)
-      testCommand = 1;
-    else if (strcmp(command, "e") == 0)
-      extractCommand = 1;
-
-    if (listCommand)
-    {
-      UInt32 i;
-      for (i = 0; i < db.Database.NumFiles; i++)
-      {
-       CFileItem *f = db.Database.Files + i;
-       printf("%10d  %s\n", (int)f->Size, f->Name);
-      }
-    }
-    else if (testCommand || extractCommand)
-    {
-      UInt32 i;
-
-      /*
-      if you need cache, use these 3 variables.
-      if you use external function, you can make these variable as static.
-      */
-      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
-      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
-      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
-
-      printf("\n");
-      for (i = 0; i < db.Database.NumFiles; i++)
-      {
-       size_t offset;
-       size_t outSizeProcessed;
-       CFileItem *f = db.Database.Files + i;
-       if (f->IsDirectory)
-         printf("Directory ");
-       else
-         printf(testCommand ?
-           "Testing   ":
-           "Extracting");
-       printf(" %s", f->Name);
-       if (f->IsDirectory)
-       {
-         printf("\n");
-         continue;
-       }
-       res = SzExtract(&archiveStream.InStream, &db, i,
-           &blockIndex, &outBuffer, &outBufferSize,
-           &offset, &outSizeProcessed,
-           &allocImp, &allocTempImp);
-       if (res != SZ_OK)
-         break;
-       if (!testCommand)
-       {
-         FILE *outputHandle;
-         UInt32 processedSize;
-         char *fileName = f->Name;
-         size_t nameLen = strlen(f->Name);
-         for (; nameLen > 0; nameLen--)
-           if (f->Name[nameLen - 1] == '/')
-           {
-             fileName = f->Name + nameLen;
-             break;
-           }
-
-         outputHandle = fopen(fileName, "wb+");
-         if (outputHandle == 0)
-         {
-           PrintError("can not open output file");
-           res = SZE_FAIL;
-           break;
-         }
-         processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
-         if (processedSize != outSizeProcessed)
-         {
-           PrintError("can not write output file");
-           res = SZE_FAIL;
-           break;
-         }
-         if (fclose(outputHandle))
-         {
-           PrintError("can not close output file");
-           res = SZE_FAIL;
-           break;
-         }
-       }
-       printf("\n");
-      }
-      allocImp.Free(outBuffer);
-    }
-    else
-    {
-      PrintError("incorrect command");
-      res = SZE_FAIL;
-    }
-  }
-  SzArDbExFree(&db, allocImp.Free);
-
-  fclose(archiveStream.File);
-  if (res == SZ_OK)
-  {
-    printf("\nEverything is Ok\n");
-    return 0;
-  }
-  if (res == SZE_OUTOFMEMORY)
-    PrintError("can not allocate memory");
-  else
-    printf("\nERROR #%d\n", res);
-  return 1;
-}
diff --git a/archivers/7z/7zMethodID.c b/archivers/7z/7zMethodID.c
deleted file mode 100644 (file)
index 5047359..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* 7zMethodID.c */
-
-#include "7zMethodID.h"
-
-int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
-{
-  int i;
-  if (a1->IDSize != a2->IDSize)
-    return 0;
-  for (i = 0; i < a1->IDSize; i++)
-    if (a1->ID[i] != a2->ID[i])
-      return 0;
-  return 1;
-}
diff --git a/archivers/7z/7zMethodID.h b/archivers/7z/7zMethodID.h
deleted file mode 100644 (file)
index 1ee50b7..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 7zMethodID.h */
-
-#ifndef __7Z_METHOD_ID_H
-#define __7Z_METHOD_ID_H
-
-#include "7zTypes.h"
-
-#define kMethodIDSize 15
-
-typedef struct _CMethodID
-{
-  Byte ID[kMethodIDSize];
-  Byte IDSize;
-} CMethodID;
-
-int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
-
-#endif
diff --git a/archivers/7z/7zStream.c b/archivers/7z/7zStream.c
new file mode 100644 (file)
index 0000000..86232aa
--- /dev/null
@@ -0,0 +1,169 @@
+/* 7zStream.c -- 7z Stream functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "Types.h"
+
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+{
+  while (size != 0)
+  {
+    size_t processed = size;
+    RINOK(stream->Read(stream, buf, &processed));
+    if (processed == 0)
+      return errorType;
+    buf = (void *)((Byte *)buf + processed);
+    size -= processed;
+  }
+  return SZ_OK;
+}
+
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+{
+  return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+{
+  size_t processed = 1;
+  RINOK(stream->Read(stream, buf, &processed));
+  return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
+}
+
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+{
+  Int64 t = offset;
+  return stream->Seek(stream, &t, SZ_SEEK_SET);
+}
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+{
+  void *lookBuf;
+  if (*size == 0)
+    return SZ_OK;
+  RINOK(stream->Look(stream, &lookBuf, size));
+  memcpy(buf, lookBuf, *size);
+  return stream->Skip(stream, *size);
+}
+
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+{
+  while (size != 0)
+  {
+    size_t processed = size;
+    RINOK(stream->Read(stream, buf, &processed));
+    if (processed == 0)
+      return errorType;
+    buf = (void *)((Byte *)buf + processed);
+    size -= processed;
+  }
+  return SZ_OK;
+}
+
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+{
+  return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
+{
+  SRes res = SZ_OK;
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t size2 = p->size - p->pos;
+  if (size2 == 0 && *size > 0)
+  {
+    p->pos = 0;
+    size2 = LookToRead_BUF_SIZE;
+    res = p->realStream->Read(p->realStream, p->buf, &size2);
+    p->size = size2;
+  }
+  if (size2 < *size)
+    *size = size2;
+  *buf = p->buf + p->pos;
+  return res;
+}
+
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
+{
+  SRes res = SZ_OK;
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t size2 = p->size - p->pos;
+  if (size2 == 0 && *size > 0)
+  {
+    p->pos = 0;
+    if (*size > LookToRead_BUF_SIZE)
+      *size = LookToRead_BUF_SIZE;
+    res = p->realStream->Read(p->realStream, p->buf, size);
+    size2 = p->size = *size;
+  }
+  if (size2 < *size)
+    *size = size2;
+  *buf = p->buf + p->pos;
+  return res;
+}
+
+static SRes LookToRead_Skip(void *pp, size_t offset)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  p->pos += offset;
+  return SZ_OK;
+}
+
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t rem = p->size - p->pos;
+  if (rem == 0)
+    return p->realStream->Read(p->realStream, buf, size);
+  if (rem > *size)
+    rem = *size;
+  memcpy(buf, p->buf + p->pos, rem);
+  p->pos += rem;
+  *size = rem;
+  return SZ_OK;
+}
+
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  p->pos = p->size = 0;
+  return p->realStream->Seek(p->realStream, pos, origin);
+}
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+{
+  p->s.Look = lookahead ?
+      LookToRead_Look_Lookahead :
+      LookToRead_Look_Exact;
+  p->s.Skip = LookToRead_Skip;
+  p->s.Read = LookToRead_Read;
+  p->s.Seek = LookToRead_Seek;
+}
+
+void LookToRead_Init(CLookToRead *p)
+{
+  p->pos = p->size = 0;
+}
+
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+{
+  CSecToLook *p = (CSecToLook *)pp;
+  return LookInStream_LookRead(p->realStream, buf, size);
+}
+
+void SecToLook_CreateVTable(CSecToLook *p)
+{
+  p->s.Read = SecToLook_Read;
+}
+
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+{
+  CSecToRead *p = (CSecToRead *)pp;
+  return p->realStream->Read(p->realStream, buf, size);
+}
+
+void SecToRead_CreateVTable(CSecToRead *p)
+{
+  p->s.Read = SecToRead_Read;
+}
diff --git a/archivers/7z/7zTypes.h b/archivers/7z/7zTypes.h
deleted file mode 100644 (file)
index 4de13ca..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 7zTypes.h */
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef unsigned long UInt32;
-#else
-typedef unsigned int UInt32;
-#endif
-#endif
-
-/* #define _SZ_NO_INT_64 */
-/* define it your compiler doesn't support long long int */
-
-#ifndef _7ZIP_UINT64_DEFINED
-#define _7ZIP_UINT64_DEFINED
-#ifdef _SZ_NO_INT_64
-typedef unsigned long UInt64;
-#else
-#ifdef _MSC_VER
-typedef unsigned __int64 UInt64;
-#else
-typedef unsigned long long int UInt64;
-#endif
-#endif
-#endif
-
-
-/* #define _SZ_FILE_SIZE_64 */
-/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
-
-#ifndef CFileSize
-#ifdef _SZ_FILE_SIZE_64
-typedef UInt64 CFileSize;
-#else
-typedef UInt32 CFileSize;
-#endif
-#endif
-
-#define SZ_RESULT int
-
-#define SZ_OK (0)
-#define SZE_DATA_ERROR (1)
-#define SZE_OUTOFMEMORY (2)
-#define SZE_CRC_ERROR (3)
-
-#define SZE_NOTIMPL (4)
-#define SZE_FAIL (5)
-
-#define SZE_ARCHIVE_ERROR (6)
-
-#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
-
-#endif
diff --git a/archivers/7z/7zVersion.h b/archivers/7z/7zVersion.h
new file mode 100644 (file)
index 0000000..b7eb235
--- /dev/null
@@ -0,0 +1,7 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 65
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.65"
+#define MY_DATE "2009-02-03"
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
similarity index 80%
rename from archivers/7z/7zAlloc.c
rename to archivers/7z/Archive/7z/7zAlloc.c
index 21bb30c7c2349f09b592ea80e67a55251167e8bc..4bfaf42a8461049935dc8eb6cb17c7e766a68b74 100644 (file)
@@ -1,4 +1,5 @@
-/* 7zAlloc.c */
+/* 7zAlloc.c -- Allocation functions
+2008-10-04 : Igor Pavlov : Public domain */
 
 #include <stdlib.h>
 #include "7zAlloc.h"
 #ifdef _WIN32
 #include <windows.h>
 #endif
+
 #include <stdio.h>
 int g_allocCount = 0;
 int g_allocCountTemp = 0;
+
 #endif
 
-void *SzAlloc(size_t size)
+void *SzAlloc(void *p, size_t size)
 {
+  p = p;
   if (size == 0)
     return 0;
   #ifdef _SZ_ALLOC_DEBUG
@@ -27,8 +31,9 @@ void *SzAlloc(size_t size)
   return malloc(size);
 }
 
-void SzFree(void *address)
+void SzFree(void *p, void *address)
 {
+  p = p;
   #ifdef _SZ_ALLOC_DEBUG
   if (address != 0)
   {
@@ -39,8 +44,9 @@ void SzFree(void *address)
   free(address);
 }
 
-void *SzAllocTemp(size_t size)
+void *SzAllocTemp(void *p, size_t size)
 {
+  p = p;
   if (size == 0)
     return 0;
   #ifdef _SZ_ALLOC_DEBUG
@@ -53,8 +59,9 @@ void *SzAllocTemp(size_t size)
   return malloc(size);
 }
 
-void SzFreeTemp(void *address)
+void SzFreeTemp(void *p, void *address)
 {
+  p = p;
   #ifdef _SZ_ALLOC_DEBUG
   if (address != 0)
   {
diff --git a/archivers/7z/Archive/7z/7zAlloc.h b/archivers/7z/Archive/7z/7zAlloc.h
new file mode 100644 (file)
index 0000000..e752ef1
--- /dev/null
@@ -0,0 +1,15 @@
+/* 7zAlloc.h -- Allocation functions
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+void *SzAlloc(void *p, size_t size);
+void SzFree(void *p, void *address);
+
+void *SzAllocTemp(void *p, size_t size);
+void SzFreeTemp(void *p, void *address);
+
+#endif
diff --git a/archivers/7z/Archive/7z/7zDecode.c b/archivers/7z/Archive/7z/7zDecode.c
new file mode 100644 (file)
index 0000000..02526f0
--- /dev/null
@@ -0,0 +1,254 @@
+/* 7zDecode.c -- Decoding from 7z folder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "../../Bcj2.h"
+#include "../../Bra.h"
+#include "../../LzmaDec.h"
+#include "7zDecode.h"
+
+#define k_Copy 0
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+{
+  CLzmaDec state;
+  SRes res = SZ_OK;
+
+  LzmaDec_Construct(&state);
+  RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
+  state.dic = outBuffer;
+  state.dicBufSize = outSize;
+  LzmaDec_Init(&state);
+
+  for (;;)
+  {
+    Byte *inBuf = NULL;
+    size_t lookahead = (1 << 18);
+    if (lookahead > inSize)
+      lookahead = (size_t)inSize;
+    res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
+    if (res != SZ_OK)
+      break;
+
+    {
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
+      ELzmaStatus status;
+      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
+      lookahead -= inProcessed;
+      inSize -= inProcessed;
+      if (res != SZ_OK)
+        break;
+      if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
+      {
+        if (state.dicBufSize != outSize || lookahead != 0 ||
+            (status != LZMA_STATUS_FINISHED_WITH_MARK &&
+             status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+          res = SZ_ERROR_DATA;
+        break;
+      }
+      res = inStream->Skip((void *)inStream, inProcessed);
+      if (res != SZ_OK)
+        break;
+    }
+  }
+
+  LzmaDec_FreeProbs(&state, allocMain);
+  return res;
+}
+
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
+{
+  while (inSize > 0)
+  {
+    void *inBuf;
+    size_t curSize = (1 << 18);
+    if (curSize > inSize)
+      curSize = (size_t)inSize;
+    RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
+    if (curSize == 0)
+      return SZ_ERROR_INPUT_EOF;
+    memcpy(outBuffer, inBuf, curSize);
+    outBuffer += curSize;
+    inSize -= curSize;
+    RINOK(inStream->Skip((void *)inStream, curSize));
+  }
+  return SZ_OK;
+}
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
+
+SRes CheckSupportedFolder(const CSzFolder *f)
+{
+  if (f->NumCoders < 1 || f->NumCoders > 4)
+    return SZ_ERROR_UNSUPPORTED;
+  if (IS_UNSUPPORTED_CODER(f->Coders[0]))
+    return SZ_ERROR_UNSUPPORTED;
+  if (f->NumCoders == 1)
+  {
+    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  if (f->NumCoders == 2)
+  {
+    if (IS_NO_BCJ(f->Coders[1]) ||
+        f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
+        f->NumBindPairs != 1 ||
+        f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  if (f->NumCoders == 4)
+  {
+    if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
+        IS_UNSUPPORTED_CODER(f->Coders[2]) ||
+        IS_NO_BCJ2(f->Coders[3]))
+      return SZ_ERROR_UNSUPPORTED;
+    if (f->NumPackStreams != 4 ||
+        f->PackStreams[0] != 2 ||
+        f->PackStreams[1] != 6 ||
+        f->PackStreams[2] != 1 ||
+        f->PackStreams[3] != 0 ||
+        f->NumBindPairs != 3 ||
+        f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
+        f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
+        f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  return SZ_ERROR_UNSUPPORTED;
+}
+
+UInt64 GetSum(const UInt64 *values, UInt32 index)
+{
+  UInt64 sum = 0;
+  UInt32 i;
+  for (i = 0; i < index; i++)
+    sum += values[i];
+  return sum;
+}
+
+SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
+    ILookInStream *inStream, UInt64 startPos,
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
+    Byte *tempBuf[])
+{
+  UInt32 ci;
+  SizeT tempSizes[3] = { 0, 0, 0};
+  SizeT tempSize3 = 0;
+  Byte *tempBuf3 = 0;
+
+  RINOK(CheckSupportedFolder(folder));
+
+  for (ci = 0; ci < folder->NumCoders; ci++)
+  {
+    CSzCoderInfo *coder = &folder->Coders[ci];
+
+    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
+    {
+      UInt32 si = 0;
+      UInt64 offset;
+      UInt64 inSize;
+      Byte *outBufCur = outBuffer;
+      SizeT outSizeCur = outSize;
+      if (folder->NumCoders == 4)
+      {
+        UInt32 indices[] = { 3, 2, 0 };
+        UInt64 unpackSize = folder->UnpackSizes[ci];
+        si = indices[ci];
+        if (ci < 2)
+        {
+          Byte *temp;
+          outSizeCur = (SizeT)unpackSize;
+          if (outSizeCur != unpackSize)
+            return SZ_ERROR_MEM;
+          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
+          if (temp == 0 && outSizeCur != 0)
+            return SZ_ERROR_MEM;
+          outBufCur = tempBuf[1 - ci] = temp;
+          tempSizes[1 - ci] = outSizeCur;
+        }
+        else if (ci == 2)
+        {
+          if (unpackSize > outSize) /* check it */
+            return SZ_ERROR_PARAM;
+          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
+          tempSize3 = outSizeCur = (SizeT)unpackSize;
+        }
+        else
+          return SZ_ERROR_UNSUPPORTED;
+      }
+      offset = GetSum(packSizes, si);
+      inSize = packSizes[si];
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+
+      if (coder->MethodID == k_Copy)
+      {
+        if (inSize != outSizeCur) /* check it */
+          return SZ_ERROR_DATA;
+        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
+      }
+      else
+      {
+        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+      }
+    }
+    else if (coder->MethodID == k_BCJ)
+    {
+      UInt32 state;
+      if (ci != 1)
+        return SZ_ERROR_UNSUPPORTED;
+      x86_Convert_Init(state);
+      x86_Convert(outBuffer, outSize, 0, &state, 0);
+    }
+    else if (coder->MethodID == k_BCJ2)
+    {
+      UInt64 offset = GetSum(packSizes, 1);
+      UInt64 s3Size = packSizes[1];
+      SRes res;
+      if (ci != 3)
+        return SZ_ERROR_UNSUPPORTED;
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+      tempSizes[2] = (SizeT)s3Size;
+      if (tempSizes[2] != s3Size)
+        return SZ_ERROR_MEM;
+      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
+      if (tempBuf[2] == 0 && tempSizes[2] != 0)
+        return SZ_ERROR_MEM;
+      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
+      RINOK(res)
+
+      res = Bcj2_Decode(
+          tempBuf3, tempSize3,
+          tempBuf[0], tempSizes[0],
+          tempBuf[1], tempSizes[1],
+          tempBuf[2], tempSizes[2],
+          outBuffer, outSize);
+      RINOK(res)
+    }
+    else
+      return SZ_ERROR_UNSUPPORTED;
+  }
+  return SZ_OK;
+}
+
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
+    ILookInStream *inStream, UInt64 startPos,
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+  Byte *tempBuf[3] = { 0, 0, 0};
+  int i;
+  SRes res = SzDecode2(packSizes, folder, inStream, startPos,
+      outBuffer, (SizeT)outSize, allocMain, tempBuf);
+  for (i = 0; i < 3; i++)
+    IAlloc_Free(allocMain, tempBuf[i]);
+  return res;
+}
diff --git a/archivers/7z/Archive/7z/7zDecode.h b/archivers/7z/Archive/7z/7zDecode.h
new file mode 100644 (file)
index 0000000..e19fe38
--- /dev/null
@@ -0,0 +1,13 @@
+/* 7zDecode.h -- Decoding from 7z folder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "7zItem.h"
+
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
+    ILookInStream *stream, UInt64 startPos,
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+
+#endif
diff --git a/archivers/7z/Archive/7z/7zExtract.c b/archivers/7z/Archive/7z/7zExtract.c
new file mode 100644 (file)
index 0000000..ff79802
--- /dev/null
@@ -0,0 +1,93 @@
+/* 7zExtract.c -- Extracting from 7z archive
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include "../../7zCrc.h"
+#include "7zDecode.h"
+#include "7zExtract.h"
+
+SRes SzAr_Extract(
+    const CSzArEx *p,
+    ILookInStream *inStream,
+    UInt32 fileIndex,
+    UInt32 *blockIndex,
+    Byte **outBuffer,
+    size_t *outBufferSize,
+    size_t *offset,
+    size_t *outSizeProcessed,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
+  SRes res = SZ_OK;
+  *offset = 0;
+  *outSizeProcessed = 0;
+  if (folderIndex == (UInt32)-1)
+  {
+    IAlloc_Free(allocMain, *outBuffer);
+    *blockIndex = folderIndex;
+    *outBuffer = 0;
+    *outBufferSize = 0;
+    return SZ_OK;
+  }
+
+  if (*outBuffer == 0 || *blockIndex != folderIndex)
+  {
+    CSzFolder *folder = p->db.Folders + folderIndex;
+    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
+    size_t unpackSize = (size_t)unpackSizeSpec;
+    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
+
+    if (unpackSize != unpackSizeSpec)
+      return SZ_ERROR_MEM;
+    *blockIndex = folderIndex;
+    IAlloc_Free(allocMain, *outBuffer);
+    *outBuffer = 0;
+    
+    RINOK(LookInStream_SeekTo(inStream, startOffset));
+    
+    if (res == SZ_OK)
+    {
+      *outBufferSize = unpackSize;
+      if (unpackSize != 0)
+      {
+        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+        if (*outBuffer == 0)
+          res = SZ_ERROR_MEM;
+      }
+      if (res == SZ_OK)
+      {
+        res = SzDecode(p->db.PackSizes +
+          p->FolderStartPackStreamIndex[folderIndex], folder,
+          inStream, startOffset,
+          *outBuffer, unpackSize, allocTemp);
+        if (res == SZ_OK)
+        {
+          if (folder->UnpackCRCDefined)
+          {
+            if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
+              res = SZ_ERROR_CRC;
+          }
+        }
+      }
+    }
+  }
+  if (res == SZ_OK)
+  {
+    UInt32 i;
+    CSzFileItem *fileItem = p->db.Files + fileIndex;
+    *offset = 0;
+    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+      *offset += (UInt32)p->db.Files[i].Size;
+    *outSizeProcessed = (size_t)fileItem->Size;
+    if (*offset + *outSizeProcessed > *outBufferSize)
+      return SZ_ERROR_FAIL;
+    {
+      if (fileItem->FileCRCDefined)
+      {
+        if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
+          res = SZ_ERROR_CRC;
+      }
+    }
+  }
+  return res;
+}
similarity index 87%
rename from archivers/7z/7zExtract.h
rename to archivers/7z/Archive/7z/7zExtract.h
index 5c97b8ef25134f7dc2e3d51d0eea7cdbd2f03b73..5f78415f1b6ca52951a0215a9c05b4df36950b04 100644 (file)
@@ -1,4 +1,5 @@
-/* 7zExtract.h */
+/* 7zExtract.h -- Extracting from 7z archive
+2008-11-23 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_EXTRACT_H
 #define __7Z_EXTRACT_H
       *outBufferSize
     You can consider "*outBuffer" as cache of solid block. If your archive is solid,
     it will increase decompression speed.
-
+  
     If you use external function, you can declare these 3 cache variables
     (blockIndex, outBuffer, outBufferSize) as static in that external function.
-
+    
     Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
 */
 
-SZ_RESULT SzExtract(
-    ISzInStream *inStream,
-    CArchiveDatabaseEx *db,
+SRes SzAr_Extract(
+    const CSzArEx *db,
+    ILookInStream *inStream,
     UInt32 fileIndex,         /* index of file */
     UInt32 *blockIndex,       /* index of solid block */
     Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */
similarity index 57%
rename from archivers/7z/7zHeader.c
rename to archivers/7z/Archive/7z/7zHeader.c
index 3be4bc27eaac5bf6ef2f28cd96f39137336a3415..e48faa48543c9d11226498420a6259cb9d291d99 100644 (file)
@@ -1,4 +1,5 @@
-/*  7zHeader.c */
+/*  7zHeader.c -- 7z Headers
+2008-10-04 : Igor Pavlov : Public domain */
 
 #include "7zHeader.h"
 
similarity index 65%
rename from archivers/7z/7zHeader.h
rename to archivers/7z/Archive/7z/7zHeader.h
index f98c3511a58839e03bd550f780f2d8dc658efe02..9941b6f7f86d23766db80d6a582bf7e02686b640 100644 (file)
@@ -1,9 +1,10 @@
-/* 7zHeader.h */
+/* 7zHeader.h -- 7z Headers
+2008-10-04 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_HEADER_H
 #define __7Z_HEADER_H
 
-#include "7zTypes.h"
+#include "../../Types.h"
 
 #define k7zSignatureSize 6
 extern Byte k7zSignature[k7zSignatureSize];
@@ -15,41 +16,42 @@ extern Byte k7zSignature[k7zSignatureSize];
 enum EIdEnum
 {
   k7zIdEnd,
-
+    
   k7zIdHeader,
-
+    
   k7zIdArchiveProperties,
-
+    
   k7zIdAdditionalStreamsInfo,
   k7zIdMainStreamsInfo,
   k7zIdFilesInfo,
-
+  
   k7zIdPackInfo,
-  k7zIdUnPackInfo,
+  k7zIdUnpackInfo,
   k7zIdSubStreamsInfo,
-
+  
   k7zIdSize,
   k7zIdCRC,
-
+  
   k7zIdFolder,
-
-  k7zIdCodersUnPackSize,
-  k7zIdNumUnPackStream,
-
+  
+  k7zIdCodersUnpackSize,
+  k7zIdNumUnpackStream,
+  
   k7zIdEmptyStream,
   k7zIdEmptyFile,
   k7zIdAnti,
-
+  
   k7zIdName,
-  k7zIdCreationTime,
-  k7zIdLastAccessTime,
-  k7zIdLastWriteTime,
+  k7zIdCTime,
+  k7zIdATime,
+  k7zIdMTime,
   k7zIdWinAttributes,
   k7zIdComment,
-
+  
   k7zIdEncodedHeader,
-
-  k7zIdStartPos
+  
+  k7zIdStartPos,
+  k7zIdDummy
 };
 
 #endif
diff --git a/archivers/7z/Archive/7z/7zIn.c b/archivers/7z/Archive/7z/7zIn.c
new file mode 100644 (file)
index 0000000..f6143f8
--- /dev/null
@@ -0,0 +1,1204 @@
+/* 7zIn.c -- 7z Input functions
+2008-12-31 : Igor Pavlov : Public domain */
+
+#include "../../7zCrc.h"
+#include "../../CpuArch.h"
+
+#include "7zDecode.h"
+#include "7zIn.h"
+
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
+
+#define NUM_FOLDER_CODERS_MAX 32
+#define NUM_CODER_STREAMS_MAX 32
+
+void SzArEx_Init(CSzArEx *p)
+{
+  SzAr_Init(&p->db);
+  p->FolderStartPackStreamIndex = 0;
+  p->PackStreamStartPositions = 0;
+  p->FolderStartFileIndex = 0;
+  p->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+{
+  IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
+  IAlloc_Free(alloc, p->PackStreamStartPositions);
+  IAlloc_Free(alloc, p->FolderStartFileIndex);
+  IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
+  SzAr_Free(&p->db, alloc);
+  SzArEx_Init(p);
+}
+
+/*
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+UInt64 GetFilePackSize(int fileIndex) const
+{
+  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+  if (folderIndex >= 0)
+  {
+    const CSzFolder &folderInfo = Folders[folderIndex];
+    if (FolderStartFileIndex[folderIndex] == fileIndex)
+    return GetFolderFullPackSize(folderIndex);
+  }
+  return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
+  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
+
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
+{
+  UInt32 startPos = 0;
+  UInt64 startPosSize = 0;
+  UInt32 i;
+  UInt32 folderIndex = 0;
+  UInt32 indexInFolder = 0;
+  MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
+  for (i = 0; i < p->db.NumFolders; i++)
+  {
+    p->FolderStartPackStreamIndex[i] = startPos;
+    startPos += p->db.Folders[i].NumPackStreams;
+  }
+
+  MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
+
+  for (i = 0; i < p->db.NumPackStreams; i++)
+  {
+    p->PackStreamStartPositions[i] = startPosSize;
+    startPosSize += p->db.PackSizes[i];
+  }
+
+  MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
+  MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
+
+  for (i = 0; i < p->db.NumFiles; i++)
+  {
+    CSzFileItem *file = p->db.Files + i;
+    int emptyStream = !file->HasStream;
+    if (emptyStream && indexInFolder == 0)
+    {
+      p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+      continue;
+    }
+    if (indexInFolder == 0)
+    {
+      /*
+      v3.13 incorrectly worked with empty folders
+      v4.07: Loop for skipping empty folders
+      */
+      for (;;)
+      {
+        if (folderIndex >= p->db.NumFolders)
+          return SZ_ERROR_ARCHIVE;
+        p->FolderStartFileIndex[folderIndex] = i;
+        if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
+          break;
+        folderIndex++;
+      }
+    }
+    p->FileIndexToFolderIndexMap[i] = folderIndex;
+    if (emptyStream)
+      continue;
+    indexInFolder++;
+    if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
+    {
+      folderIndex++;
+      indexInFolder = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
+{
+  return p->dataPos +
+    p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
+{
+  UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
+  CSzFolder *folder = p->db.Folders + folderIndex;
+  UInt64 size = 0;
+  UInt32 i;
+  for (i = 0; i < folder->NumPackStreams; i++)
+  {
+    UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
+    if (t < size) /* check it */
+      return SZ_ERROR_FAIL;
+    size = t;
+  }
+  *resSize = size;
+  return SZ_OK;
+}
+
+
+/*
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
+    CObjectVector<CSzFileItem> &files, UInt64 type)
+{
+  CBoolVector boolVector;
+  RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+  CStreamSwitch streamSwitch;
+  RINOK(streamSwitch.Set(this, &dataVector));
+
+  for (int i = 0; i < files.Size(); i++)
+  {
+    CSzFileItem &file = files[i];
+    CArchiveFileTime fileTime;
+    bool defined = boolVector[i];
+    if (defined)
+    {
+      UInt32 low, high;
+      RINOK(SzReadUInt32(low));
+      RINOK(SzReadUInt32(high));
+      fileTime.dwLowDateTime = low;
+      fileTime.dwHighDateTime = high;
+    }
+    switch(type)
+    {
+      case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
+      case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
+      case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
+    }
+  }
+  return SZ_OK;
+}
+*/
+
+static int TestSignatureCandidate(Byte *testBytes)
+{
+  size_t i;
+  for (i = 0; i < k7zSignatureSize; i++)
+    if (testBytes[i] != k7zSignature[i])
+      return 0;
+  return 1;
+}
+
+typedef struct _CSzState
+{
+  Byte *Data;
+  size_t Size;
+}CSzData;
+
+static SRes SzReadByte(CSzData *sd, Byte *b)
+{
+  if (sd->Size == 0)
+    return SZ_ERROR_ARCHIVE;
+  sd->Size--;
+  *b = *sd->Data++;
+  return SZ_OK;
+}
+
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+  size_t i;
+  for (i = 0; i < size; i++)
+  {
+    RINOK(SzReadByte(sd, data + i));
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+  int i;
+  *value = 0;
+  for (i = 0; i < 4; i++)
+  {
+    Byte b;
+    RINOK(SzReadByte(sd, &b));
+    *value |= ((UInt32)(b) << (8 * i));
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)
+{
+  Byte firstByte;
+  Byte mask = 0x80;
+  int i;
+  RINOK(SzReadByte(sd, &firstByte));
+  *value = 0;
+  for (i = 0; i < 8; i++)
+  {
+    Byte b;
+    if ((firstByte & mask) == 0)
+    {
+      UInt64 highPart = firstByte & (mask - 1);
+      *value += (highPart << (8 * i));
+      return SZ_OK;
+    }
+    RINOK(SzReadByte(sd, &b));
+    *value |= ((UInt64)b << (8 * i));
+    mask >>= 1;
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+  UInt64 value64;
+  RINOK(SzReadNumber(sd, &value64));
+  if (value64 >= 0x80000000)
+    return SZ_ERROR_UNSUPPORTED;
+  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+    return SZ_ERROR_UNSUPPORTED;
+  *value = (UInt32)value64;
+  return SZ_OK;
+}
+
+static SRes SzReadID(CSzData *sd, UInt64 *value)
+{
+  return SzReadNumber(sd, value);
+}
+
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+  if (size > sd->Size)
+    return SZ_ERROR_ARCHIVE;
+  sd->Size -= (size_t)size;
+  sd->Data += (size_t)size;
+  return SZ_OK;
+}
+
+static SRes SzSkeepData(CSzData *sd)
+{
+  UInt64 size;
+  RINOK(SzReadNumber(sd, &size));
+  return SzSkeepDataSize(sd, size);
+}
+
+static SRes SzReadArchiveProperties(CSzData *sd)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    SzSkeepData(sd);
+  }
+  return SZ_OK;
+}
+
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == attribute)
+      return SZ_OK;
+    if (type == k7zIdEnd)
+      return SZ_ERROR_ARCHIVE;
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+  Byte b = 0;
+  Byte mask = 0;
+  size_t i;
+  MY_ALLOC(Byte, *v, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+  {
+    if (mask == 0)
+    {
+      RINOK(SzReadByte(sd, &b));
+      mask = 0x80;
+    }
+    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+    mask >>= 1;
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+  Byte allAreDefined;
+  size_t i;
+  RINOK(SzReadByte(sd, &allAreDefined));
+  if (allAreDefined == 0)
+    return SzReadBoolVector(sd, numItems, v, alloc);
+  MY_ALLOC(Byte, *v, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+    (*v)[i] = 1;
+  return SZ_OK;
+}
+
+static SRes SzReadHashDigests(
+    CSzData *sd,
+    size_t numItems,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *alloc)
+{
+  size_t i;
+  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
+  MY_ALLOC(UInt32, *digests, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+    if ((*digestsDefined)[i])
+    {
+      RINOK(SzReadUInt32(sd, (*digests) + i));
+    }
+  return SZ_OK;
+}
+
+static SRes SzReadPackInfo(
+    CSzData *sd,
+    UInt64 *dataOffset,
+    UInt32 *numPackStreams,
+    UInt64 **packSizes,
+    Byte **packCRCsDefined,
+    UInt32 **packCRCs,
+    ISzAlloc *alloc)
+{
+  UInt32 i;
+  RINOK(SzReadNumber(sd, dataOffset));
+  RINOK(SzReadNumber32(sd, numPackStreams));
+
+  RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+  MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
+
+  for (i = 0; i < *numPackStreams; i++)
+  {
+    RINOK(SzReadNumber(sd, (*packSizes) + i));
+  }
+
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    if (type == k7zIdCRC)
+    {
+      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+  if (*packCRCsDefined == 0)
+  {
+    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
+    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
+    for (i = 0; i < *numPackStreams; i++)
+    {
+      (*packCRCsDefined)[i] = 0;
+      (*packCRCs)[i] = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadSwitch(CSzData *sd)
+{
+  Byte external;
+  RINOK(SzReadByte(sd, &external));
+  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
+}
+
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
+{
+  UInt32 numCoders, numBindPairs, numPackStreams, i;
+  UInt32 numInStreams = 0, numOutStreams = 0;
+  
+  RINOK(SzReadNumber32(sd, &numCoders));
+  if (numCoders > NUM_FOLDER_CODERS_MAX)
+    return SZ_ERROR_UNSUPPORTED;
+  folder->NumCoders = numCoders;
+  
+  MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
+
+  for (i = 0; i < numCoders; i++)
+    SzCoderInfo_Init(folder->Coders + i);
+
+  for (i = 0; i < numCoders; i++)
+  {
+    Byte mainByte;
+    CSzCoderInfo *coder = folder->Coders + i;
+    {
+      unsigned idSize, j;
+      Byte longID[15];
+      RINOK(SzReadByte(sd, &mainByte));
+      idSize = (unsigned)(mainByte & 0xF);
+      RINOK(SzReadBytes(sd, longID, idSize));
+      if (idSize > sizeof(coder->MethodID))
+        return SZ_ERROR_UNSUPPORTED;
+      coder->MethodID = 0;
+      for (j = 0; j < idSize; j++)
+        coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+
+      if ((mainByte & 0x10) != 0)
+      {
+        RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+        if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
+            coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
+          return SZ_ERROR_UNSUPPORTED;
+      }
+      else
+      {
+        coder->NumInStreams = 1;
+        coder->NumOutStreams = 1;
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        UInt64 propertiesSize = 0;
+        RINOK(SzReadNumber(sd, &propertiesSize));
+        if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
+          return SZ_ERROR_MEM;
+        RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
+      }
+    }
+    while ((mainByte & 0x80) != 0)
+    {
+      RINOK(SzReadByte(sd, &mainByte));
+      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+      if ((mainByte & 0x10) != 0)
+      {
+        UInt32 n;
+        RINOK(SzReadNumber32(sd, &n));
+        RINOK(SzReadNumber32(sd, &n));
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        UInt64 propertiesSize = 0;
+        RINOK(SzReadNumber(sd, &propertiesSize));
+        RINOK(SzSkeepDataSize(sd, propertiesSize));
+      }
+    }
+    numInStreams += coder->NumInStreams;
+    numOutStreams += coder->NumOutStreams;
+  }
+
+  if (numOutStreams == 0)
+    return SZ_ERROR_UNSUPPORTED;
+
+  folder->NumBindPairs = numBindPairs = numOutStreams - 1;
+  MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
+
+  for (i = 0; i < numBindPairs; i++)
+  {
+    CBindPair *bp = folder->BindPairs + i;
+    RINOK(SzReadNumber32(sd, &bp->InIndex));
+    RINOK(SzReadNumber32(sd, &bp->OutIndex));
+  }
+
+  if (numInStreams < numBindPairs)
+    return SZ_ERROR_UNSUPPORTED;
+
+  folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
+  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
+
+  if (numPackStreams == 1)
+  {
+    for (i = 0; i < numInStreams ; i++)
+      if (SzFolder_FindBindPairForInStream(folder, i) < 0)
+        break;
+    if (i == numInStreams)
+      return SZ_ERROR_UNSUPPORTED;
+    folder->PackStreams[0] = i;
+  }
+  else
+    for (i = 0; i < numPackStreams; i++)
+    {
+      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+    }
+  return SZ_OK;
+}
+
+static SRes SzReadUnpackInfo(
+    CSzData *sd,
+    UInt32 *numFolders,
+    CSzFolder **folders,  /* for alloc */
+    ISzAlloc *alloc,
+    ISzAlloc *allocTemp)
+{
+  UInt32 i;
+  RINOK(SzWaitAttribute(sd, k7zIdFolder));
+  RINOK(SzReadNumber32(sd, numFolders));
+  {
+    RINOK(SzReadSwitch(sd));
+
+    MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
+
+    for (i = 0; i < *numFolders; i++)
+      SzFolder_Init((*folders) + i);
+
+    for (i = 0; i < *numFolders; i++)
+    {
+      RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
+    }
+  }
+
+  RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
+
+  for (i = 0; i < *numFolders; i++)
+  {
+    UInt32 j;
+    CSzFolder *folder = (*folders) + i;
+    UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
+
+    MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
+
+    for (j = 0; j < numOutStreams; j++)
+    {
+      RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
+    }
+  }
+
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      return SZ_OK;
+    if (type == k7zIdCRC)
+    {
+      SRes res;
+      Byte *crcsDefined = 0;
+      UInt32 *crcs = 0;
+      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
+      if (res == SZ_OK)
+      {
+        for (i = 0; i < *numFolders; i++)
+        {
+          CSzFolder *folder = (*folders) + i;
+          folder->UnpackCRCDefined = crcsDefined[i];
+          folder->UnpackCRC = crcs[i];
+        }
+      }
+      IAlloc_Free(allocTemp, crcs);
+      IAlloc_Free(allocTemp, crcsDefined);
+      RINOK(res);
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+static SRes SzReadSubStreamsInfo(
+    CSzData *sd,
+    UInt32 numFolders,
+    CSzFolder *folders,
+    UInt32 *numUnpackStreams,
+    UInt64 **unpackSizes,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *allocTemp)
+{
+  UInt64 type = 0;
+  UInt32 i;
+  UInt32 si = 0;
+  UInt32 numDigests = 0;
+
+  for (i = 0; i < numFolders; i++)
+    folders[i].NumUnpackStreams = 1;
+  *numUnpackStreams = numFolders;
+
+  for (;;)
+  {
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdNumUnpackStream)
+    {
+      *numUnpackStreams = 0;
+      for (i = 0; i < numFolders; i++)
+      {
+        UInt32 numStreams;
+        RINOK(SzReadNumber32(sd, &numStreams));
+        folders[i].NumUnpackStreams = numStreams;
+        *numUnpackStreams += numStreams;
+      }
+      continue;
+    }
+    if (type == k7zIdCRC || type == k7zIdSize)
+      break;
+    if (type == k7zIdEnd)
+      break;
+    RINOK(SzSkeepData(sd));
+  }
+
+  if (*numUnpackStreams == 0)
+  {
+    *unpackSizes = 0;
+    *digestsDefined = 0;
+    *digests = 0;
+  }
+  else
+  {
+    *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
+    RINOM(*unpackSizes);
+    *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
+    RINOM(*digestsDefined);
+    *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
+    RINOM(*digests);
+  }
+
+  for (i = 0; i < numFolders; i++)
+  {
+    /*
+    v3.13 incorrectly worked with empty folders
+    v4.07: we check that folder is empty
+    */
+    UInt64 sum = 0;
+    UInt32 j;
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
+    if (numSubstreams == 0)
+      continue;
+    if (type == k7zIdSize)
+    for (j = 1; j < numSubstreams; j++)
+    {
+      UInt64 size;
+      RINOK(SzReadNumber(sd, &size));
+      (*unpackSizes)[si++] = size;
+      sum += size;
+    }
+    (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
+  }
+  if (type == k7zIdSize)
+  {
+    RINOK(SzReadID(sd, &type));
+  }
+
+  for (i = 0; i < *numUnpackStreams; i++)
+  {
+    (*digestsDefined)[i] = 0;
+    (*digests)[i] = 0;
+  }
+
+
+  for (i = 0; i < numFolders; i++)
+  {
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
+    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+      numDigests += numSubstreams;
+  }
+
+  si = 0;
+  for (;;)
+  {
+    if (type == k7zIdCRC)
+    {
+      int digestIndex = 0;
+      Byte *digestsDefined2 = 0;
+      UInt32 *digests2 = 0;
+      SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
+      if (res == SZ_OK)
+      {
+        for (i = 0; i < numFolders; i++)
+        {
+          CSzFolder *folder = folders + i;
+          UInt32 numSubstreams = folder->NumUnpackStreams;
+          if (numSubstreams == 1 && folder->UnpackCRCDefined)
+          {
+            (*digestsDefined)[si] = 1;
+            (*digests)[si] = folder->UnpackCRC;
+            si++;
+          }
+          else
+          {
+            UInt32 j;
+            for (j = 0; j < numSubstreams; j++, digestIndex++)
+            {
+              (*digestsDefined)[si] = digestsDefined2[digestIndex];
+              (*digests)[si] = digests2[digestIndex];
+              si++;
+            }
+          }
+        }
+      }
+      IAlloc_Free(allocTemp, digestsDefined2);
+      IAlloc_Free(allocTemp, digests2);
+      RINOK(res);
+    }
+    else if (type == k7zIdEnd)
+      return SZ_OK;
+    else
+    {
+      RINOK(SzSkeepData(sd));
+    }
+    RINOK(SzReadID(sd, &type));
+  }
+}
+
+
+static SRes SzReadStreamsInfo(
+    CSzData *sd,
+    UInt64 *dataOffset,
+    CSzAr *p,
+    UInt32 *numUnpackStreams,
+    UInt64 **unpackSizes, /* allocTemp */
+    Byte **digestsDefined,   /* allocTemp */
+    UInt32 **digests,        /* allocTemp */
+    ISzAlloc *alloc,
+    ISzAlloc *allocTemp)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if ((UInt64)(int)type != type)
+      return SZ_ERROR_UNSUPPORTED;
+    switch((int)type)
+    {
+      case k7zIdEnd:
+        return SZ_OK;
+      case k7zIdPackInfo:
+      {
+        RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
+            &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
+        break;
+      }
+      case k7zIdUnpackInfo:
+      {
+        RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
+        break;
+      }
+      case k7zIdSubStreamsInfo:
+      {
+        RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
+            numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
+        break;
+      }
+      default:
+        return SZ_ERROR_UNSUPPORTED;
+    }
+  }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
+{
+  UInt32 i;
+  for (i = 0; i < numFiles; i++)
+  {
+    UInt32 len = 0;
+    UInt32 pos = 0;
+    CSzFileItem *file = files + i;
+    while (pos + 2 <= sd->Size)
+    {
+      int numAdds;
+      UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+      pos += 2;
+      len++;
+      if (value == 0)
+        break;
+      if (value < 0x80)
+        continue;
+      if (value >= 0xD800 && value < 0xE000)
+      {
+        UInt32 c2;
+        if (value >= 0xDC00)
+          return SZ_ERROR_ARCHIVE;
+        if (pos + 2 > sd->Size)
+          return SZ_ERROR_ARCHIVE;
+        c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+        pos += 2;
+        if (c2 < 0xDC00 || c2 >= 0xE000)
+          return SZ_ERROR_ARCHIVE;
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+      }
+      for (numAdds = 1; numAdds < 5; numAdds++)
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+          break;
+      len += numAdds;
+    }
+
+    MY_ALLOC(char, file->Name, (size_t)len, alloc);
+
+    len = 0;
+    while (2 <= sd->Size)
+    {
+      int numAdds;
+      UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+      SzSkeepDataSize(sd, 2);
+      if (value < 0x80)
+      {
+        file->Name[len++] = (char)value;
+        if (value == 0)
+          break;
+        continue;
+      }
+      if (value >= 0xD800 && value < 0xE000)
+      {
+        UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+        SzSkeepDataSize(sd, 2);
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+      }
+      for (numAdds = 1; numAdds < 5; numAdds++)
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+          break;
+      file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+      do
+      {
+        numAdds--;
+        file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+      }
+      while (numAdds > 0);
+
+      len += numAdds;
+    }
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadHeader2(
+    CSzArEx *p,   /* allocMain */
+    CSzData *sd,
+    UInt64 **unpackSizes,  /* allocTemp */
+    Byte **digestsDefined,    /* allocTemp */
+    UInt32 **digests,         /* allocTemp */
+    Byte **emptyStreamVector, /* allocTemp */
+    Byte **emptyFileVector,   /* allocTemp */
+    Byte **lwtVector,         /* allocTemp */
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt64 type;
+  UInt32 numUnpackStreams = 0;
+  UInt32 numFiles = 0;
+  CSzFileItem *files = 0;
+  UInt32 numEmptyStreams = 0;
+  UInt32 i;
+
+  RINOK(SzReadID(sd, &type));
+
+  if (type == k7zIdArchiveProperties)
+  {
+    RINOK(SzReadArchiveProperties(sd));
+    RINOK(SzReadID(sd, &type));
+  }
+  if (type == k7zIdMainStreamsInfo)
+  {
+    RINOK(SzReadStreamsInfo(sd,
+        &p->dataPos,
+        &p->db,
+        &numUnpackStreams,
+        unpackSizes,
+        digestsDefined,
+        digests, allocMain, allocTemp));
+    p->dataPos += p->startPosAfterHeader;
+    RINOK(SzReadID(sd, &type));
+  }
+
+  if (type == k7zIdEnd)
+    return SZ_OK;
+  if (type != k7zIdFilesInfo)
+    return SZ_ERROR_ARCHIVE;
+  
+  RINOK(SzReadNumber32(sd, &numFiles));
+  p->db.NumFiles = numFiles;
+
+  MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
+
+  p->db.Files = files;
+  for (i = 0; i < numFiles; i++)
+    SzFile_Init(files + i);
+
+  for (;;)
+  {
+    UInt64 type;
+    UInt64 size;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    RINOK(SzReadNumber(sd, &size));
+
+    if ((UInt64)(int)type != type)
+    {
+      RINOK(SzSkeepDataSize(sd, size));
+    }
+    else
+    switch((int)type)
+    {
+      case k7zIdName:
+      {
+        RINOK(SzReadSwitch(sd));
+        RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
+        break;
+      }
+      case k7zIdEmptyStream:
+      {
+        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
+        numEmptyStreams = 0;
+        for (i = 0; i < numFiles; i++)
+          if ((*emptyStreamVector)[i])
+            numEmptyStreams++;
+        break;
+      }
+      case k7zIdEmptyFile:
+      {
+        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
+        break;
+      }
+      case k7zIdMTime:
+      {
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
+        RINOK(SzReadSwitch(sd));
+        for (i = 0; i < numFiles; i++)
+        {
+          CSzFileItem *f = &files[i];
+          Byte defined = (*lwtVector)[i];
+          f->MTimeDefined = defined;
+          f->MTime.Low = f->MTime.High = 0;
+          if (defined)
+          {
+            RINOK(SzReadUInt32(sd, &f->MTime.Low));
+            RINOK(SzReadUInt32(sd, &f->MTime.High));
+          }
+        }
+        break;
+      }
+      default:
+      {
+        RINOK(SzSkeepDataSize(sd, size));
+      }
+    }
+  }
+
+  {
+    UInt32 emptyFileIndex = 0;
+    UInt32 sizeIndex = 0;
+    for (i = 0; i < numFiles; i++)
+    {
+      CSzFileItem *file = files + i;
+      file->IsAnti = 0;
+      if (*emptyStreamVector == 0)
+        file->HasStream = 1;
+      else
+        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+      if (file->HasStream)
+      {
+        file->IsDir = 0;
+        file->Size = (*unpackSizes)[sizeIndex];
+        file->FileCRC = (*digests)[sizeIndex];
+        file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+        sizeIndex++;
+      }
+      else
+      {
+        if (*emptyFileVector == 0)
+          file->IsDir = 1;
+        else
+          file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+        emptyFileIndex++;
+        file->Size = 0;
+        file->FileCRCDefined = 0;
+      }
+    }
+  }
+  return SzArEx_Fill(p, allocMain);
+}
+
+static SRes SzReadHeader(
+    CSzArEx *p,
+    CSzData *sd,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt64 *unpackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  Byte *emptyStreamVector = 0;
+  Byte *emptyFileVector = 0;
+  Byte *lwtVector = 0;
+  SRes res = SzReadHeader2(p, sd,
+      &unpackSizes, &digestsDefined, &digests,
+      &emptyStreamVector, &emptyFileVector, &lwtVector,
+      allocMain, allocTemp);
+  IAlloc_Free(allocTemp, unpackSizes);
+  IAlloc_Free(allocTemp, digestsDefined);
+  IAlloc_Free(allocTemp, digests);
+  IAlloc_Free(allocTemp, emptyStreamVector);
+  IAlloc_Free(allocTemp, emptyFileVector);
+  IAlloc_Free(allocTemp, lwtVector);
+  return res;
+}
+
+static SRes SzReadAndDecodePackedStreams2(
+    ILookInStream *inStream,
+    CSzData *sd,
+    CBuf *outBuffer,
+    UInt64 baseOffset,
+    CSzAr *p,
+    UInt64 **unpackSizes,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *allocTemp)
+{
+
+  UInt32 numUnpackStreams = 0;
+  UInt64 dataStartPos;
+  CSzFolder *folder;
+  UInt64 unpackSize;
+  SRes res;
+
+  RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
+      &numUnpackStreams,  unpackSizes, digestsDefined, digests,
+      allocTemp, allocTemp));
+  
+  dataStartPos += baseOffset;
+  if (p->NumFolders != 1)
+    return SZ_ERROR_ARCHIVE;
+
+  folder = p->Folders;
+  unpackSize = SzFolder_GetUnpackSize(folder);
+  
+  RINOK(LookInStream_SeekTo(inStream, dataStartPos));
+
+  if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
+    return SZ_ERROR_MEM;
+  
+  res = SzDecode(p->PackSizes, folder,
+          inStream, dataStartPos,
+          outBuffer->data, (size_t)unpackSize, allocTemp);
+  RINOK(res);
+  if (folder->UnpackCRCDefined)
+    if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
+      return SZ_ERROR_CRC;
+  return SZ_OK;
+}
+
+static SRes SzReadAndDecodePackedStreams(
+    ILookInStream *inStream,
+    CSzData *sd,
+    CBuf *outBuffer,
+    UInt64 baseOffset,
+    ISzAlloc *allocTemp)
+{
+  CSzAr p;
+  UInt64 *unpackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  SRes res;
+  SzAr_Init(&p);
+  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+    &p, &unpackSizes, &digestsDefined, &digests,
+    allocTemp);
+  SzAr_Free(&p, allocTemp);
+  IAlloc_Free(allocTemp, unpackSizes);
+  IAlloc_Free(allocTemp, digestsDefined);
+  IAlloc_Free(allocTemp, digests);
+  return res;
+}
+
+static SRes SzArEx_Open2(
+    CSzArEx *p,
+    ILookInStream *inStream,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  Byte header[k7zStartHeaderSize];
+  UInt64 nextHeaderOffset, nextHeaderSize;
+  size_t nextHeaderSizeT;
+  UInt32 nextHeaderCRC;
+  CBuf buffer;
+  SRes res;
+
+  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
+
+  if (!TestSignatureCandidate(header))
+    return SZ_ERROR_NO_ARCHIVE;
+  if (header[6] != k7zMajorVersion)
+    return SZ_ERROR_UNSUPPORTED;
+
+  nextHeaderOffset = GetUi64(header + 12);
+  nextHeaderSize = GetUi64(header + 20);
+  nextHeaderCRC = GetUi32(header + 28);
+
+  p->startPosAfterHeader = k7zStartHeaderSize;
+  
+  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
+    return SZ_ERROR_CRC;
+
+  nextHeaderSizeT = (size_t)nextHeaderSize;
+  if (nextHeaderSizeT != nextHeaderSize)
+    return SZ_ERROR_MEM;
+  if (nextHeaderSizeT == 0)
+    return SZ_OK;
+  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
+      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
+    return SZ_ERROR_NO_ARCHIVE;
+
+  {
+    Int64 pos = 0;
+    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+    if ((UInt64)pos < nextHeaderOffset ||
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+      return SZ_ERROR_INPUT_EOF;
+  }
+
+  RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
+
+  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
+    return SZ_ERROR_MEM;
+
+  res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
+  if (res == SZ_OK)
+  {
+    res = SZ_ERROR_ARCHIVE;
+    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
+    {
+      CSzData sd;
+      UInt64 type;
+      sd.Data = buffer.data;
+      sd.Size = buffer.size;
+      res = SzReadID(&sd, &type);
+      if (res == SZ_OK)
+      {
+        if (type == k7zIdEncodedHeader)
+        {
+          CBuf outBuffer;
+          Buf_Init(&outBuffer);
+          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
+          if (res != SZ_OK)
+            Buf_Free(&outBuffer, allocTemp);
+          else
+          {
+            Buf_Free(&buffer, allocTemp);
+            buffer.data = outBuffer.data;
+            buffer.size = outBuffer.size;
+            sd.Data = buffer.data;
+            sd.Size = buffer.size;
+            res = SzReadID(&sd, &type);
+          }
+        }
+      }
+      if (res == SZ_OK)
+      {
+        if (type == k7zIdHeader)
+          res = SzReadHeader(p, &sd, allocMain, allocTemp);
+        else
+          res = SZ_ERROR_UNSUPPORTED;
+      }
+    }
+  }
+  Buf_Free(&buffer, allocTemp);
+  return res;
+}
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
+{
+  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
+  if (res != SZ_OK)
+    SzArEx_Free(p, allocMain);
+  return res;
+}
diff --git a/archivers/7z/Archive/7z/7zIn.h b/archivers/7z/Archive/7z/7zIn.h
new file mode 100644 (file)
index 0000000..c8430a7
--- /dev/null
@@ -0,0 +1,41 @@
+/* 7zIn.h -- 7z Input functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+
+typedef struct
+{
+  CSzAr db;
+  
+  UInt64 startPosAfterHeader;
+  UInt64 dataPos;
+
+  UInt32 *FolderStartPackStreamIndex;
+  UInt64 *PackStreamStartPositions;
+  UInt32 *FolderStartFileIndex;
+  UInt32 *FileIndexToFolderIndexMap;
+} CSzArEx;
+
+void SzArEx_Init(CSzArEx *p);
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
+
+/*
+Errors:
+SZ_ERROR_NO_ARCHIVE
+SZ_ERROR_ARCHIVE
+SZ_ERROR_UNSUPPORTED
+SZ_ERROR_MEM
+SZ_ERROR_CRC
+SZ_ERROR_INPUT_EOF
+SZ_ERROR_FAIL
+*/
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
+#endif
diff --git a/archivers/7z/Archive/7z/7zItem.c b/archivers/7z/Archive/7z/7zItem.c
new file mode 100644 (file)
index 0000000..db44571
--- /dev/null
@@ -0,0 +1,127 @@
+/* 7zItem.c -- 7z Items
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "7zItem.h"
+
+void SzCoderInfo_Init(CSzCoderInfo *p)
+{
+  Buf_Init(&p->Props);
+}
+
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
+{
+  Buf_Free(&p->Props, alloc);
+  SzCoderInfo_Init(p);
+}
+
+void SzFolder_Init(CSzFolder *p)
+{
+  p->Coders = 0;
+  p->BindPairs = 0;
+  p->PackStreams = 0;
+  p->UnpackSizes = 0;
+  p->NumCoders = 0;
+  p->NumBindPairs = 0;
+  p->NumPackStreams = 0;
+  p->UnpackCRCDefined = 0;
+  p->UnpackCRC = 0;
+  p->NumUnpackStreams = 0;
+}
+
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
+{
+  UInt32 i;
+  if (p->Coders)
+    for (i = 0; i < p->NumCoders; i++)
+      SzCoderInfo_Free(&p->Coders[i], alloc);
+  IAlloc_Free(alloc, p->Coders);
+  IAlloc_Free(alloc, p->BindPairs);
+  IAlloc_Free(alloc, p->PackStreams);
+  IAlloc_Free(alloc, p->UnpackSizes);
+  SzFolder_Init(p);
+}
+
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
+{
+  UInt32 result = 0;
+  UInt32 i;
+  for (i = 0; i < p->NumCoders; i++)
+    result += p->Coders[i].NumOutStreams;
+  return result;
+}
+
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
+{
+  UInt32 i;
+  for (i = 0; i < p->NumBindPairs; i++)
+    if (p->BindPairs[i].InIndex == inStreamIndex)
+      return i;
+  return -1;
+}
+
+
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
+{
+  UInt32 i;
+  for (i = 0; i < p->NumBindPairs; i++)
+    if (p->BindPairs[i].OutIndex == outStreamIndex)
+      return i;
+  return -1;
+}
+
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
+{
+  int i = (int)SzFolder_GetNumOutStreams(p);
+  if (i == 0)
+    return 0;
+  for (i--; i >= 0; i--)
+    if (SzFolder_FindBindPairForOutStream(p, i) < 0)
+      return p->UnpackSizes[i];
+  /* throw 1; */
+  return 0;
+}
+
+void SzFile_Init(CSzFileItem *p)
+{
+  p->HasStream = 1;
+  p->IsDir = 0;
+  p->IsAnti = 0;
+  p->FileCRCDefined = 0;
+  p->MTimeDefined = 0;
+  p->Name = 0;
+}
+
+static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
+{
+  IAlloc_Free(alloc, p->Name);
+  SzFile_Init(p);
+}
+
+void SzAr_Init(CSzAr *p)
+{
+  p->PackSizes = 0;
+  p->PackCRCsDefined = 0;
+  p->PackCRCs = 0;
+  p->Folders = 0;
+  p->Files = 0;
+  p->NumPackStreams = 0;
+  p->NumFolders = 0;
+  p->NumFiles = 0;
+}
+
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+{
+  UInt32 i;
+  if (p->Folders)
+    for (i = 0; i < p->NumFolders; i++)
+      SzFolder_Free(&p->Folders[i], alloc);
+  if (p->Files)
+    for (i = 0; i < p->NumFiles; i++)
+      SzFile_Free(&p->Files[i], alloc);
+  IAlloc_Free(alloc, p->PackSizes);
+  IAlloc_Free(alloc, p->PackCRCsDefined);
+  IAlloc_Free(alloc, p->PackCRCs);
+  IAlloc_Free(alloc, p->Folders);
+  IAlloc_Free(alloc, p->Files);
+  SzAr_Init(p);
+}
diff --git a/archivers/7z/Archive/7z/7zItem.h b/archivers/7z/Archive/7z/7zItem.h
new file mode 100644 (file)
index 0000000..9f1366c
--- /dev/null
@@ -0,0 +1,84 @@
+/* 7zItem.h -- 7z Items
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../7zBuf.h"
+
+typedef struct
+{
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+  UInt64 MethodID;
+  CBuf Props;
+} CSzCoderInfo;
+
+void SzCoderInfo_Init(CSzCoderInfo *p);
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
+
+typedef struct
+{
+  UInt32 InIndex;
+  UInt32 OutIndex;
+} CBindPair;
+
+typedef struct
+{
+  CSzCoderInfo *Coders;
+  CBindPair *BindPairs;
+  UInt32 *PackStreams;
+  UInt64 *UnpackSizes;
+  UInt32 NumCoders;
+  UInt32 NumBindPairs;
+  UInt32 NumPackStreams;
+  int UnpackCRCDefined;
+  UInt32 UnpackCRC;
+
+  UInt32 NumUnpackStreams;
+} CSzFolder;
+
+void SzFolder_Init(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+
+typedef struct
+{
+  UInt32 Low;
+  UInt32 High;
+} CNtfsFileTime;
+
+typedef struct
+{
+  CNtfsFileTime MTime;
+  UInt64 Size;
+  char *Name;
+  UInt32 FileCRC;
+
+  Byte HasStream;
+  Byte IsDir;
+  Byte IsAnti;
+  Byte FileCRCDefined;
+  Byte MTimeDefined;
+} CSzFileItem;
+
+void SzFile_Init(CSzFileItem *p);
+
+typedef struct
+{
+  UInt64 *PackSizes;
+  Byte *PackCRCsDefined;
+  UInt32 *PackCRCs;
+  CSzFolder *Folders;
+  CSzFileItem *Files;
+  UInt32 NumPackStreams;
+  UInt32 NumFolders;
+  UInt32 NumFiles;
+} CSzAr;
+
+void SzAr_Init(CSzAr *p);
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
+
+#endif
diff --git a/archivers/7z/Bcj2.c b/archivers/7z/Bcj2.c
new file mode 100644 (file)
index 0000000..20199ce
--- /dev/null
@@ -0,0 +1,132 @@
+/* Bcj2.c -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bcj2.h"
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*buffer++)
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
+  { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
+
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
+
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
+
+int Bcj2_Decode(
+    const Byte *buf0, SizeT size0,
+    const Byte *buf1, SizeT size1,
+    const Byte *buf2, SizeT size2,
+    const Byte *buf3, SizeT size3,
+    Byte *outBuf, SizeT outSize)
+{
+  CProb p[256 + 2];
+  SizeT inPos = 0, outPos = 0;
+
+  const Byte *buffer, *bufferLim;
+  UInt32 range, code;
+  Byte prevByte = 0;
+
+  unsigned int i;
+  for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
+    p[i] = kBitModelTotal >> 1;
+
+  buffer = buf3;
+  bufferLim = buffer + size3;
+  RC_INIT2
+
+  if (outSize == 0)
+    return SZ_OK;
+
+  for (;;)
+  {
+    Byte b;
+    CProb *prob;
+    UInt32 bound;
+    UInt32 ttt;
+
+    SizeT limit = size0 - inPos;
+    if (outSize - outPos < limit)
+      limit = outSize - outPos;
+    while (limit != 0)
+    {
+      Byte b = buf0[inPos];
+      outBuf[outPos++] = b;
+      if (IsJ(prevByte, b))
+        break;
+      inPos++;
+      prevByte = b;
+      limit--;
+    }
+
+    if (limit == 0 || outPos == outSize)
+      break;
+
+    b = buf0[inPos++];
+
+    if (b == 0xE8)
+      prob = p + prevByte;
+    else if (b == 0xE9)
+      prob = p + 256;
+    else
+      prob = p + 257;
+
+    IF_BIT_0(prob)
+    {
+      UPDATE_0(prob)
+      prevByte = b;
+    }
+    else
+    {
+      UInt32 dest;
+      const Byte *v;
+      UPDATE_1(prob)
+      if (b == 0xE8)
+      {
+        v = buf1;
+        if (size1 < 4)
+          return SZ_ERROR_DATA;
+        buf1 += 4;
+        size1 -= 4;
+      }
+      else
+      {
+        v = buf2;
+        if (size2 < 4)
+          return SZ_ERROR_DATA;
+        buf2 += 4;
+        size2 -= 4;
+      }
+      dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
+          ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
+      outBuf[outPos++] = (Byte)dest;
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = (Byte)(dest >> 8);
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = (Byte)(dest >> 16);
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+    }
+  }
+  return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
+}
diff --git a/archivers/7z/Bcj2.h b/archivers/7z/Bcj2.h
new file mode 100644 (file)
index 0000000..32d450b
--- /dev/null
@@ -0,0 +1,30 @@
+/* Bcj2.h -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BCJ2_H
+#define __BCJ2_H
+
+#include "Types.h"
+
+/*
+Conditions:
+  outSize <= FullOutputSize,
+  where FullOutputSize is full size of output stream of x86_2 filter.
+
+If buf0 overlaps outBuf, there are two required conditions:
+  1) (buf0 >= outBuf)
+  2) (buf0 + size0 >= outBuf + FullOutputSize).
+
+Returns:
+  SZ_OK
+  SZ_ERROR_DATA - Data error
+*/
+
+int Bcj2_Decode(
+    const Byte *buf0, SizeT size0,
+    const Byte *buf1, SizeT size1,
+    const Byte *buf2, SizeT size2,
+    const Byte *buf3, SizeT size3,
+    Byte *outBuf, SizeT outSize);
+
+#endif
diff --git a/archivers/7z/Bra.c b/archivers/7z/Bra.c
new file mode 100644 (file)
index 0000000..5e54695
--- /dev/null
@@ -0,0 +1,133 @@
+/* Bra.c -- Converters for RISC code
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  ip += 8;
+  for (i = 0; i <= size; i += 4)
+  {
+    if (data[i + 3] == 0xEB)
+    {
+      UInt32 dest;
+      UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
+      src <<= 2;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      dest >>= 2;
+      data[i + 2] = (Byte)(dest >> 16);
+      data[i + 1] = (Byte)(dest >> 8);
+      data[i + 0] = (Byte)dest;
+    }
+  }
+  return i;
+}
+
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  ip += 4;
+  for (i = 0; i <= size; i += 2)
+  {
+    if ((data[i + 1] & 0xF8) == 0xF0 &&
+        (data[i + 3] & 0xF8) == 0xF8)
+    {
+      UInt32 dest;
+      UInt32 src =
+        (((UInt32)data[i + 1] & 0x7) << 19) |
+        ((UInt32)data[i + 0] << 11) |
+        (((UInt32)data[i + 3] & 0x7) << 8) |
+        (data[i + 2]);
+      
+      src <<= 1;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      dest >>= 1;
+      
+      data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
+      data[i + 0] = (Byte)(dest >> 11);
+      data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
+      data[i + 2] = (Byte)dest;
+      i += 2;
+    }
+  }
+  return i;
+}
+
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  for (i = 0; i <= size; i += 4)
+  {
+    if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
+    {
+      UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
+        ((UInt32)data[i + 1] << 16) |
+        ((UInt32)data[i + 2] << 8) |
+        ((UInt32)data[i + 3] & (~3));
+      
+      UInt32 dest;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));
+      data[i + 1] = (Byte)(dest >> 16);
+      data[i + 2] = (Byte)(dest >> 8);
+      data[i + 3] &= 0x3;
+      data[i + 3] |= dest;
+    }
+  }
+  return i;
+}
+
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  UInt32 i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  for (i = 0; i <= size; i += 4)
+  {
+    if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
+        data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
+    {
+      UInt32 src =
+        ((UInt32)data[i + 0] << 24) |
+        ((UInt32)data[i + 1] << 16) |
+        ((UInt32)data[i + 2] << 8) |
+        ((UInt32)data[i + 3]);
+      UInt32 dest;
+      
+      src <<= 2;
+      if (encoding)
+        dest = ip + i + src;
+      else
+        dest = src - (ip + i);
+      dest >>= 2;
+      
+      dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
+
+      data[i + 0] = (Byte)(dest >> 24);
+      data[i + 1] = (Byte)(dest >> 16);
+      data[i + 2] = (Byte)(dest >> 8);
+      data[i + 3] = (Byte)dest;
+    }
+  }
+  return i;
+}
diff --git a/archivers/7z/Bra.h b/archivers/7z/Bra.h
new file mode 100644 (file)
index 0000000..45e231e
--- /dev/null
@@ -0,0 +1,60 @@
+/* Bra.h -- Branch converters for executables
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "Types.h"
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+  
+  In:
+    data     - data buffer
+    size     - size of data
+    ip       - current virtual Instruction Pinter (IP) value
+    state    - state variable for x86 converter
+    encoding - 0 (for decoding), 1 (for encoding)
+  
+  Out:
+    state    - state variable for x86 converter
+
+  Returns:
+    The number of processed bytes. If you call these functions with multiple calls,
+    you must start next call with first byte after block of processed bytes.
+  
+  Type   Endian  Alignment  LookAhead
+  
+  x86    little      1          4
+  ARMT   little      2          2
+  ARM    little      4          0
+  PPC     big        4          0
+  SPARC   big        4          0
+  IA64   little     16          0
+
+  size must be >= Alignment + LookAhead, if it's not last block.
+  If (size < Alignment + LookAhead), converter returns 0.
+
+  Example:
+
+    UInt32 ip = 0;
+    for ()
+    {
+      ; size must be >= Alignment + LookAhead, if it's not last block
+      SizeT processed = Convert(data, size, ip, 1);
+      data += processed;
+      size -= processed;
+      ip += processed;
+    }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+#endif
diff --git a/archivers/7z/Bra86.c b/archivers/7z/Bra86.c
new file mode 100644 (file)
index 0000000..1ee0e70
--- /dev/null
@@ -0,0 +1,85 @@
+/* Bra86.c -- Converter for x86 code (BCJ)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+  SizeT bufferPos = 0, prevPosT;
+  UInt32 prevMask = *state & 0x7;
+  if (size < 5)
+    return 0;
+  ip += 5;
+  prevPosT = (SizeT)0 - 1;
+
+  for (;;)
+  {
+    Byte *p = data + bufferPos;
+    Byte *limit = data + size - 4;
+    for (; p < limit; p++)
+      if ((*p & 0xFE) == 0xE8)
+        break;
+    bufferPos = (SizeT)(p - data);
+    if (p >= limit)
+      break;
+    prevPosT = bufferPos - prevPosT;
+    if (prevPosT > 3)
+      prevMask = 0;
+    else
+    {
+      prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+      if (prevMask != 0)
+      {
+        Byte b = p[4 - kMaskToBitNumber[prevMask]];
+        if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+        {
+          prevPosT = bufferPos;
+          prevMask = ((prevMask << 1) & 0x7) | 1;
+          bufferPos++;
+          continue;
+        }
+      }
+    }
+    prevPosT = bufferPos;
+
+    if (Test86MSByte(p[4]))
+    {
+      UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+      UInt32 dest;
+      for (;;)
+      {
+        Byte b;
+        int index;
+        if (encoding)
+          dest = (ip + (UInt32)bufferPos) + src;
+        else
+          dest = src - (ip + (UInt32)bufferPos);
+        if (prevMask == 0)
+          break;
+        index = kMaskToBitNumber[prevMask] * 8;
+        b = (Byte)(dest >> (24 - index));
+        if (!Test86MSByte(b))
+          break;
+        src = dest ^ ((1 << (32 - index)) - 1);
+      }
+      p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+      p[3] = (Byte)(dest >> 16);
+      p[2] = (Byte)(dest >> 8);
+      p[1] = (Byte)dest;
+      bufferPos += 5;
+    }
+    else
+    {
+      prevMask = ((prevMask << 1) & 0x7) | 1;
+      bufferPos++;
+    }
+  }
+  prevPosT = bufferPos - prevPosT;
+  *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+  return bufferPos;
+}
diff --git a/archivers/7z/CpuArch.h b/archivers/7z/CpuArch.h
new file mode 100644 (file)
index 0000000..7384b0c
--- /dev/null
@@ -0,0 +1,69 @@
+/* CpuArch.h
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __CPUARCH_H
+#define __CPUARCH_H
+
+/*
+LITTLE_ENDIAN_UNALIGN means:
+  1) CPU is LITTLE_ENDIAN
+  2) it's allowed to make unaligned memory accesses
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
+about these properties of platform.
+*/
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef LITTLE_ENDIAN_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(p))
+#define GetUi32(p) (*(const UInt32 *)(p))
+#define GetUi64(p) (*(const UInt64 *)(p))
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);
+
+#else
+
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
+
+#define GetUi32(p) ( \
+             ((const Byte *)(p))[0]        | \
+    ((UInt32)((const Byte *)(p))[1] <<  8) | \
+    ((UInt32)((const Byte *)(p))[2] << 16) | \
+    ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi32(p, d) { UInt32 _x_ = (d); \
+    ((Byte *)(p))[0] = (Byte)_x_; \
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
+    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
+    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
+
+#endif
+
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
+
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#else
+
+#define GetBe32(p) ( \
+    ((UInt32)((const Byte *)(p))[0] << 24) | \
+    ((UInt32)((const Byte *)(p))[1] << 16) | \
+    ((UInt32)((const Byte *)(p))[2] <<  8) | \
+             ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#endif
+
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
+
+#endif
diff --git a/archivers/7z/LzmaDec.c b/archivers/7z/LzmaDec.c
new file mode 100644 (file)
index 0000000..d87eb19
--- /dev/null
@@ -0,0 +1,1007 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include <string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+  { UPDATE_0(p); i = (i + i); A0; } else \
+  { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+  { i = 1; \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
+  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+  Result:
+    SZ_OK - OK
+    SZ_ERROR_DATA - Error
+  p->remainLen:
+    < kMatchSpecLenStart : normal remain
+    = kMatchSpecLenStart : finished
+    = kMatchSpecLenStart + 1 : Flush marker
+    = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  CLzmaProb *probs = p->probs;
+
+  unsigned state = p->state;
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+  unsigned lc = p->prop.lc;
+
+  Byte *dic = p->dic;
+  SizeT dicBufSize = p->dicBufSize;
+  SizeT dicPos = p->dicPos;
+  
+  UInt32 processedPos = p->processedPos;
+  UInt32 checkDicSize = p->checkDicSize;
+  unsigned len = 0;
+
+  const Byte *buf = p->buf;
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+
+  do
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = processedPos & pbMask;
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0(prob)
+    {
+      unsigned symbol;
+      UPDATE_0(prob);
+      prob = probs + Literal;
+      if (checkDicSize != 0 || processedPos != 0)
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+      if (state < kNumLitStates)
+      {
+        symbol = 1;
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned offs = 0x100;
+        symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      dic[dicPos++] = (Byte)symbol;
+      processedPos++;
+
+      state = kLiteralNextStates[state];
+      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+      continue;
+    }
+    else
+    {
+      UPDATE_1(prob);
+      prob = probs + IsRep + state;
+      IF_BIT_0(prob)
+      {
+        UPDATE_0(prob);
+        state += kNumStates;
+        prob = probs + LenCoder;
+      }
+      else
+      {
+        UPDATE_1(prob);
+        if (checkDicSize == 0 && processedPos == 0)
+          return SZ_ERROR_DATA;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0(prob)
+        {
+          UPDATE_0(prob);
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dicPos++;
+            processedPos++;
+            state = state < kNumLitStates ? 9 : 11;
+            continue;
+          }
+          UPDATE_1(prob);
+        }
+        else
+        {
+          UInt32 distance;
+          UPDATE_1(prob);
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            distance = rep1;
+          }
+          else
+          {
+            UPDATE_1(prob);
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0(prob)
+            {
+              UPDATE_0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UPDATE_1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = (1 << kLenNumLowBits);
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = (1 << kLenNumMidBits);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = (1 << kLenNumHighBits);
+          }
+        }
+        TREE_DECODE(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state >= kNumStates)
+      {
+        UInt32 distance;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+        TREE_6_DECODE(prob, distance);
+        if (distance >= kStartPosModelIndex)
+        {
+          unsigned posSlot = (unsigned)distance;
+          int numDirectBits = (int)(((distance >> 1) - 1));
+          distance = (2 | (distance & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            distance <<= numDirectBits;
+            prob = probs + SpecPos + distance - posSlot - 1;
+            {
+              UInt32 mask = 1;
+              unsigned i = 1;
+              do
+              {
+                GET_BIT2(prob + i, i, ; , distance |= mask);
+                mask <<= 1;
+              }
+              while (--numDirectBits != 0);
+            }
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE
+              range >>= 1;
+              
+              {
+                UInt32 t;
+                code -= range;
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+                distance = (distance << 1) + (t + 1);
+                code += range & t;
+              }
+              /*
+              distance <<= 1;
+              if (code >= range)
+              {
+                code -= range;
+                distance |= 1;
+              }
+              */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            distance <<= kNumAlignBits;
+            {
+              unsigned i = 1;
+              GET_BIT2(prob + i, i, ; , distance |= 1);
+              GET_BIT2(prob + i, i, ; , distance |= 2);
+              GET_BIT2(prob + i, i, ; , distance |= 4);
+              GET_BIT2(prob + i, i, ; , distance |= 8);
+            }
+            if (distance == (UInt32)0xFFFFFFFF)
+            {
+              len += kMatchSpecLenStart;
+              state -= kNumStates;
+              break;
+            }
+          }
+        }
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        rep0 = distance + 1;
+        if (checkDicSize == 0)
+        {
+          if (distance >= processedPos)
+            return SZ_ERROR_DATA;
+        }
+        else if (distance >= checkDicSize)
+          return SZ_ERROR_DATA;
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+        /* state = kLiteralNextStates[state]; */
+      }
+
+      len += kMatchMinLen;
+
+      if (limit == dicPos)
+        return SZ_ERROR_DATA;
+      {
+        SizeT rem = limit - dicPos;
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+        processedPos += curLen;
+
+        len -= curLen;
+        if (pos + curLen <= dicBufSize)
+        {
+          Byte *dest = dic + dicPos;
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+          const Byte *lim = dest + curLen;
+          dicPos += curLen;
+          do
+            *(dest) = (Byte)*(dest + src);
+          while (++dest != lim);
+        }
+        else
+        {
+          do
+          {
+            dic[dicPos++] = dic[pos];
+            if (++pos == dicBufSize)
+              pos = 0;
+          }
+          while (--curLen != 0);
+        }
+      }
+    }
+  }
+  while (dicPos < limit && buf < bufLimit);
+  NORMALIZE;
+  p->buf = buf;
+  p->range = range;
+  p->code = code;
+  p->remainLen = len;
+  p->dicPos = dicPos;
+  p->processedPos = processedPos;
+  p->reps[0] = rep0;
+  p->reps[1] = rep1;
+  p->reps[2] = rep2;
+  p->reps[3] = rep3;
+  p->state = state;
+
+  return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+  {
+    Byte *dic = p->dic;
+    SizeT dicPos = p->dicPos;
+    SizeT dicBufSize = p->dicBufSize;
+    unsigned len = p->remainLen;
+    UInt32 rep0 = p->reps[0];
+    if (limit - dicPos < len)
+      len = (unsigned)(limit - dicPos);
+
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+      p->checkDicSize = p->prop.dicSize;
+
+    p->processedPos += len;
+    p->remainLen -= len;
+    while (len-- != 0)
+    {
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dicPos++;
+    }
+    p->dicPos = dicPos;
+  }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  do
+  {
+    SizeT limit2 = limit;
+    if (p->checkDicSize == 0)
+    {
+      UInt32 rem = p->prop.dicSize - p->processedPos;
+      if (limit - p->dicPos > rem)
+        limit2 = p->dicPos + rem;
+    }
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+    if (p->processedPos >= p->prop.dicSize)
+      p->checkDicSize = p->prop.dicSize;
+    LzmaDec_WriteRem(p, limit);
+  }
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+  if (p->remainLen > kMatchSpecLenStart)
+  {
+    p->remainLen = kMatchSpecLenStart;
+  }
+  return 0;
+}
+
+typedef enum
+{
+  DUMMY_ERROR, /* unexpected end of input stream */
+  DUMMY_LIT,
+  DUMMY_MATCH,
+  DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+  const Byte *bufLimit = buf + inSize;
+  CLzmaProb *probs = p->probs;
+  unsigned state = p->state;
+  ELzmaDummy res;
+
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0_CHECK(prob)
+    {
+      UPDATE_0_CHECK
+
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+      prob = probs + Literal;
+      if (p->checkDicSize != 0 || p->processedPos != 0)
+        prob += (LZMA_LIT_SIZE *
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+      if (state < kNumLitStates)
+      {
+        unsigned symbol = 1;
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+        unsigned offs = 0x100;
+        unsigned symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      res = DUMMY_LIT;
+    }
+    else
+    {
+      unsigned len;
+      UPDATE_1_CHECK;
+
+      prob = probs + IsRep + state;
+      IF_BIT_0_CHECK(prob)
+      {
+        UPDATE_0_CHECK;
+        state = 0;
+        prob = probs + LenCoder;
+        res = DUMMY_MATCH;
+      }
+      else
+      {
+        UPDATE_1_CHECK;
+        res = DUMMY_REP;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0_CHECK(prob)
+        {
+          UPDATE_0_CHECK;
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+            NORMALIZE_CHECK;
+            return DUMMY_REP;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+          }
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0_CHECK(prob)
+            {
+              UPDATE_0_CHECK;
+            }
+            else
+            {
+              UPDATE_1_CHECK;
+            }
+          }
+        }
+        state = kNumStates;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0_CHECK(probLen)
+        {
+          UPDATE_0_CHECK;
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = 1 << kLenNumLowBits;
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          probLen = prob + LenChoice2;
+          IF_BIT_0_CHECK(probLen)
+          {
+            UPDATE_0_CHECK;
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = 1 << kLenNumMidBits;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = 1 << kLenNumHighBits;
+          }
+        }
+        TREE_DECODE_CHECK(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        unsigned posSlot;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+            kNumPosSlotBits);
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+          if (posSlot < kEndPosModelIndex)
+          {
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE_CHECK
+              range >>= 1;
+              code -= range & (((code - range) >> 31) - 1);
+              /* if (code >= range) code -= range; */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            unsigned i = 1;
+            do
+            {
+              GET_BIT_CHECK(prob + i, i);
+            }
+            while (--numDirectBits != 0);
+          }
+        }
+      }
+    }
+  }
+  NORMALIZE_CHECK;
+  return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+  p->range = 0xFFFFFFFF;
+  p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+  p->needFlush = 1;
+  p->remainLen = 0;
+  p->tempBufSize = 0;
+
+  if (initDic)
+  {
+    p->processedPos = 0;
+    p->checkDicSize = 0;
+    p->needInitState = 1;
+  }
+  if (initState)
+    p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+  p->dicPos = 0;
+  LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+  UInt32 i;
+  CLzmaProb *probs = p->probs;
+  for (i = 0; i < numProbs; i++)
+    probs[i] = kBitModelTotal >> 1;
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+  p->state = 0;
+  p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+    ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT inSize = *srcLen;
+  (*srcLen) = 0;
+  LzmaDec_WriteRem(p, dicLimit);
+  
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+
+  while (p->remainLen != kMatchSpecLenStart)
+  {
+      int checkEndMarkNow;
+
+      if (p->needFlush != 0)
+      {
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+          p->tempBuf[p->tempBufSize++] = *src++;
+        if (p->tempBufSize < RC_INIT_SIZE)
+        {
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+          return SZ_OK;
+        }
+        if (p->tempBuf[0] != 0)
+          return SZ_ERROR_DATA;
+
+        LzmaDec_InitRc(p, p->tempBuf);
+        p->tempBufSize = 0;
+      }
+
+      checkEndMarkNow = 0;
+      if (p->dicPos >= dicLimit)
+      {
+        if (p->remainLen == 0 && p->code == 0)
+        {
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+          return SZ_OK;
+        }
+        if (finishMode == LZMA_FINISH_ANY)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_OK;
+        }
+        if (p->remainLen != 0)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_ERROR_DATA;
+        }
+        checkEndMarkNow = 1;
+      }
+
+      if (p->needInitState)
+        LzmaDec_InitStateReal(p);
+  
+      if (p->tempBufSize == 0)
+      {
+        SizeT processed;
+        const Byte *bufLimit;
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            memcpy(p->tempBuf, src, inSize);
+            p->tempBufSize = (unsigned)inSize;
+            (*srcLen) += inSize;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+          bufLimit = src;
+        }
+        else
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+        p->buf = src;
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+          return SZ_ERROR_DATA;
+        processed = (SizeT)(p->buf - src);
+        (*srcLen) += processed;
+        src += processed;
+        inSize -= processed;
+      }
+      else
+      {
+        unsigned rem = p->tempBufSize, lookAhead = 0;
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+          p->tempBuf[rem++] = src[lookAhead++];
+        p->tempBufSize = rem;
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            (*srcLen) += lookAhead;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+        }
+        p->buf = p->tempBuf;
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+          return SZ_ERROR_DATA;
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+        (*srcLen) += lookAhead;
+        src += lookAhead;
+        inSize -= lookAhead;
+        p->tempBufSize = 0;
+      }
+  }
+  if (p->code == 0)
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT outSize = *destLen;
+  SizeT inSize = *srcLen;
+  *srcLen = *destLen = 0;
+  for (;;)
+  {
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
+    ELzmaFinishMode curFinishMode;
+    SRes res;
+    if (p->dicPos == p->dicBufSize)
+      p->dicPos = 0;
+    dicPos = p->dicPos;
+    if (outSize > p->dicBufSize - dicPos)
+    {
+      outSizeCur = p->dicBufSize;
+      curFinishMode = LZMA_FINISH_ANY;
+    }
+    else
+    {
+      outSizeCur = dicPos + outSize;
+      curFinishMode = finishMode;
+    }
+
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+    src += inSizeCur;
+    inSize -= inSizeCur;
+    *srcLen += inSizeCur;
+    outSizeCur = p->dicPos - dicPos;
+    memcpy(dest, p->dic + dicPos, outSizeCur);
+    dest += outSizeCur;
+    outSize -= outSizeCur;
+    *destLen += outSizeCur;
+    if (res != 0)
+      return res;
+    if (outSizeCur == 0 || outSize == 0)
+      return SZ_OK;
+  }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->probs);
+  p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->dic);
+  p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+  LzmaDec_FreeProbs(p, alloc);
+  LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+  UInt32 dicSize;
+  Byte d;
+  
+  if (size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_UNSUPPORTED;
+  else
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+  if (dicSize < LZMA_DIC_MIN)
+    dicSize = LZMA_DIC_MIN;
+  p->dicSize = dicSize;
+
+  d = data[0];
+  if (d >= (9 * 5 * 5))
+    return SZ_ERROR_UNSUPPORTED;
+
+  p->lc = d % 9;
+  d /= 9;
+  p->pb = d / 5;
+  p->lp = d % 5;
+
+  return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+  if (p->probs == 0 || numProbs != p->numProbs)
+  {
+    LzmaDec_FreeProbs(p, alloc);
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->numProbs = numProbs;
+    if (p->probs == 0)
+      return SZ_ERROR_MEM;
+  }
+  return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  SizeT dicBufSize;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  dicBufSize = propNew.dicSize;
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+  {
+    LzmaDec_FreeDict(p, alloc);
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    if (p->dic == 0)
+    {
+      LzmaDec_FreeProbs(p, alloc);
+      return SZ_ERROR_MEM;
+    }
+  }
+  p->dicBufSize = dicBufSize;
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc)
+{
+  CLzmaDec p;
+  SRes res;
+  SizeT inSize = *srcLen;
+  SizeT outSize = *destLen;
+  *srcLen = *destLen = 0;
+  if (inSize < RC_INIT_SIZE)
+    return SZ_ERROR_INPUT_EOF;
+
+  LzmaDec_Construct(&p);
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+  if (res != 0)
+    return res;
+  p.dic = dest;
+  p.dicBufSize = outSize;
+
+  LzmaDec_Init(&p);
+  
+  *srcLen = inSize;
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+    res = SZ_ERROR_INPUT_EOF;
+
+  (*destLen) = p.dicPos;
+  LzmaDec_FreeProbs(&p, alloc);
+  return res;
+}
diff --git a/archivers/7z/LzmaDec.h b/archivers/7z/LzmaDec.h
new file mode 100644 (file)
index 0000000..98cdbe9
--- /dev/null
@@ -0,0 +1,223 @@
+/* LzmaDec.h -- LZMA Decoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+   but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+  unsigned lc, lp, pb;
+  UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+  SZ_OK
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+  CLzmaProps prop;
+  CLzmaProb *probs;
+  Byte *dic;
+  const Byte *buf;
+  UInt32 range, code;
+  SizeT dicPos;
+  SizeT dicBufSize;
+  UInt32 processedPos;
+  UInt32 checkDicSize;
+  unsigned state;
+  UInt32 reps[4];
+  unsigned remainLen;
+  int needFlush;
+  int needInitState;
+  UInt32 numProbs;
+  unsigned tempBufSize;
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+  LZMA_FINISH_ANY,   /* finish at any point */
+  LZMA_FINISH_END    /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+   You must use LZMA_FINISH_END, when you know that current output buffer
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+   and output value of destLen will be less than output buffer size limit.
+   You can check status result also.
+
+   You can use multiple checks to test data integrity after full decompression:
+     1) Check Result and "status" variable.
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+        You must use correct finish mode in that case. */
+
+typedef enum
+{
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+     1) Dictionary Interface
+     2) Buffer Interface
+     3) One Call Interface
+   You can select any of these interfaces, but don't mix functions from different
+   groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+     1) LzmaDec_Allocate / LzmaDec_Free
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+   You can use variant 2, if you set dictionary buffer manually.
+   For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+  SZ_OK
+  SZ_ERROR_MEM         - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+   
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+   dictionary to some other external buffer.
+   You must work with CLzmaDec variables directly in this interface.
+
+   STEPS:
+     LzmaDec_Constr()
+     LzmaDec_Allocate()
+     for (each new stream)
+     {
+       LzmaDec_Init()
+       while (it needs more decompression)
+       {
+         LzmaDec_DecodeToDic()
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
+       }
+     }
+     LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+   
+   The decoding to internal dictionary buffer (CLzmaDec::dic).
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (dicLimit).
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
+  LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_NEEDS_MORE_INPUT
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+   to work with CLzmaDec variables manually.
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+  SZ_ERROR_MEM  - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc);
+
+#endif
diff --git a/archivers/7z/LzmaDecode.c b/archivers/7z/LzmaDecode.c
deleted file mode 100644 (file)
index 486eff5..0000000
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
-  LzmaDecode.c
-  LZMA Decoder (optimized for Speed version)
-
-  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
-  http://www.7-zip.org/
-
-  LZMA SDK is licensed under two licenses:
-  1) GNU Lesser General Public License (GNU LGPL)
-  2) Common Public License (CPL)
-  It means that you can select one of these two licenses and
-  follow rules of that license.
-
-  SPECIAL EXCEPTION:
-  Igor Pavlov, as the author of this Code, expressly permits you to
-  statically or dynamically link your Code (or bind by name) to the
-  interfaces of this file without subjecting your linked Code to the
-  terms of the CPL or GNU LGPL. Any modifications or additions
-  to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#include "LzmaDecode.h"
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_READ_BYTE (*Buffer++)
-
-#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
-  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
-
-#ifdef _LZMA_IN_CB
-
-#define RC_TEST { if (Buffer == BufferLim) \
-  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
-  BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
-
-#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
-
-#else
-
-#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
-
-#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
-
-#endif
-
-#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
-
-#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
-#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
-#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
-
-#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
-  { UpdateBit0(p); mi <<= 1; A0; } else \
-  { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
-
-#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
-
-#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
-  { int i = numLevels; res = 1; \
-  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
-  res -= (1 << numLevels); }
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
-{
-  unsigned char prop0;
-  if (size < LZMA_PROPERTIES_SIZE)
-    return LZMA_RESULT_DATA_ERROR;
-  prop0 = propsData[0];
-  if (prop0 >= (9 * 5 * 5))
-    return LZMA_RESULT_DATA_ERROR;
-  {
-    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
-    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
-    propsRes->lc = prop0;
-    /*
-    unsigned char remainder = (unsigned char)(prop0 / 9);
-    propsRes->lc = prop0 % 9;
-    propsRes->pb = remainder / 5;
-    propsRes->lp = remainder % 5;
-    */
-  }
-
-  #ifdef _LZMA_OUT_READ
-  {
-    int i;
-    propsRes->DictionarySize = 0;
-    for (i = 0; i < 4; i++)
-      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
-    if (propsRes->DictionarySize == 0)
-      propsRes->DictionarySize = 1;
-  }
-  #endif
-  return LZMA_RESULT_OK;
-}
-
-#define kLzmaStreamWasFinishedId (-1)
-
-int LzmaDecode(CLzmaDecoderState *vs,
-    #ifdef _LZMA_IN_CB
-    ILzmaInCallback *InCallback,
-    #else
-    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
-    #endif
-    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
-{
-  CProb *p = vs->Probs;
-  SizeT nowPos = 0;
-  Byte previousByte = 0;
-  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
-  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
-  int lc = vs->Properties.lc;
-
-  #ifdef _LZMA_OUT_READ
-
-  UInt32 Range = vs->Range;
-  UInt32 Code = vs->Code;
-  #ifdef _LZMA_IN_CB
-  const Byte *Buffer = vs->Buffer;
-  const Byte *BufferLim = vs->BufferLim;
-  #else
-  const Byte *Buffer = inStream;
-  const Byte *BufferLim = inStream + inSize;
-  #endif
-  int state = vs->State;
-  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
-  int len = vs->RemainLen;
-  UInt32 globalPos = vs->GlobalPos;
-  UInt32 distanceLimit = vs->DistanceLimit;
-
-  Byte *dictionary = vs->Dictionary;
-  UInt32 dictionarySize = vs->Properties.DictionarySize;
-  UInt32 dictionaryPos = vs->DictionaryPos;
-
-  Byte tempDictionary[4];
-
-  #ifndef _LZMA_IN_CB
-  *inSizeProcessed = 0;
-  #endif
-  *outSizeProcessed = 0;
-  if (len == kLzmaStreamWasFinishedId)
-    return LZMA_RESULT_OK;
-
-  if (dictionarySize == 0)
-  {
-    dictionary = tempDictionary;
-    dictionarySize = 1;
-    tempDictionary[0] = vs->TempDictionary[0];
-  }
-
-  if (len == kLzmaNeedInitId)
-  {
-    {
-      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
-      UInt32 i;
-      for (i = 0; i < numProbs; i++)
-       p[i] = kBitModelTotal >> 1;
-      rep0 = rep1 = rep2 = rep3 = 1;
-      state = 0;
-      globalPos = 0;
-      distanceLimit = 0;
-      dictionaryPos = 0;
-      dictionary[dictionarySize - 1] = 0;
-      #ifdef _LZMA_IN_CB
-      RC_INIT;
-      #else
-      RC_INIT(inStream, inSize);
-      #endif
-    }
-    len = 0;
-  }
-  while(len != 0 && nowPos < outSize)
-  {
-    UInt32 pos = dictionaryPos - rep0;
-    if (pos >= dictionarySize)
-      pos += dictionarySize;
-    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
-    if (++dictionaryPos == dictionarySize)
-      dictionaryPos = 0;
-    len--;
-  }
-  if (dictionaryPos == 0)
-    previousByte = dictionary[dictionarySize - 1];
-  else
-    previousByte = dictionary[dictionaryPos - 1];
-
-  #else /* if !_LZMA_OUT_READ */
-
-  int state = 0;
-  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
-  int len = 0;
-  const Byte *Buffer;
-  const Byte *BufferLim;
-  UInt32 Range;
-  UInt32 Code;
-
-  #ifndef _LZMA_IN_CB
-  *inSizeProcessed = 0;
-  #endif
-  *outSizeProcessed = 0;
-
-  {
-    UInt32 i;
-    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
-    for (i = 0; i < numProbs; i++)
-      p[i] = kBitModelTotal >> 1;
-  }
-
-  #ifdef _LZMA_IN_CB
-  RC_INIT;
-  #else
-  RC_INIT(inStream, inSize);
-  #endif
-
-  #endif /* _LZMA_OUT_READ */
-
-  while(nowPos < outSize)
-  {
-    CProb *prob;
-    UInt32 bound;
-    int posState = (int)(
-       (nowPos
-       #ifdef _LZMA_OUT_READ
-       + globalPos
-       #endif
-       )
-       & posStateMask);
-
-    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
-    IfBit0(prob)
-    {
-      int symbol = 1;
-      UpdateBit0(prob)
-      prob = p + Literal + (LZMA_LIT_SIZE *
-       (((
-       (nowPos
-       #ifdef _LZMA_OUT_READ
-       + globalPos
-       #endif
-       )
-       & literalPosMask) << lc) + (previousByte >> (8 - lc))));
-
-      if (state >= kNumLitStates)
-      {
-       int matchByte;
-       #ifdef _LZMA_OUT_READ
-       UInt32 pos = dictionaryPos - rep0;
-       if (pos >= dictionarySize)
-         pos += dictionarySize;
-       matchByte = dictionary[pos];
-       #else
-       matchByte = outStream[nowPos - rep0];
-       #endif
-       do
-       {
-         int bit;
-         CProb *probLit;
-         matchByte <<= 1;
-         bit = (matchByte & 0x100);
-         probLit = prob + 0x100 + bit + symbol;
-         RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
-       }
-       while (symbol < 0x100);
-      }
-      while (symbol < 0x100)
-      {
-       CProb *probLit = prob + symbol;
-       RC_GET_BIT(probLit, symbol)
-      }
-      previousByte = (Byte)symbol;
-
-      outStream[nowPos++] = previousByte;
-      #ifdef _LZMA_OUT_READ
-      if (distanceLimit < dictionarySize)
-       distanceLimit++;
-
-      dictionary[dictionaryPos] = previousByte;
-      if (++dictionaryPos == dictionarySize)
-       dictionaryPos = 0;
-      #endif
-      if (state < 4) state = 0;
-      else if (state < 10) state -= 3;
-      else state -= 6;
-    }
-    else
-    {
-      UpdateBit1(prob);
-      prob = p + IsRep + state;
-      IfBit0(prob)
-      {
-       UpdateBit0(prob);
-       rep3 = rep2;
-       rep2 = rep1;
-       rep1 = rep0;
-       state = state < kNumLitStates ? 0 : 3;
-       prob = p + LenCoder;
-      }
-      else
-      {
-       UpdateBit1(prob);
-       prob = p + IsRepG0 + state;
-       IfBit0(prob)
-       {
-         UpdateBit0(prob);
-         prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
-         IfBit0(prob)
-         {
-           #ifdef _LZMA_OUT_READ
-           UInt32 pos;
-           #endif
-           UpdateBit0(prob);
-
-           #ifdef _LZMA_OUT_READ
-           if (distanceLimit == 0)
-           #else
-           if (nowPos == 0)
-           #endif
-             return LZMA_RESULT_DATA_ERROR;
-
-           state = state < kNumLitStates ? 9 : 11;
-           #ifdef _LZMA_OUT_READ
-           pos = dictionaryPos - rep0;
-           if (pos >= dictionarySize)
-             pos += dictionarySize;
-           previousByte = dictionary[pos];
-           dictionary[dictionaryPos] = previousByte;
-           if (++dictionaryPos == dictionarySize)
-             dictionaryPos = 0;
-           #else
-           previousByte = outStream[nowPos - rep0];
-           #endif
-           outStream[nowPos++] = previousByte;
-           #ifdef _LZMA_OUT_READ
-           if (distanceLimit < dictionarySize)
-             distanceLimit++;
-           #endif
-
-           continue;
-         }
-         else
-         {
-           UpdateBit1(prob);
-         }
-       }
-       else
-       {
-         UInt32 distance;
-         UpdateBit1(prob);
-         prob = p + IsRepG1 + state;
-         IfBit0(prob)
-         {
-           UpdateBit0(prob);
-           distance = rep1;
-         }
-         else
-         {
-           UpdateBit1(prob);
-           prob = p + IsRepG2 + state;
-           IfBit0(prob)
-           {
-             UpdateBit0(prob);
-             distance = rep2;
-           }
-           else
-           {
-             UpdateBit1(prob);
-             distance = rep3;
-             rep3 = rep2;
-           }
-           rep2 = rep1;
-         }
-         rep1 = rep0;
-         rep0 = distance;
-       }
-       state = state < kNumLitStates ? 8 : 11;
-       prob = p + RepLenCoder;
-      }
-      {
-       int numBits, offset;
-       CProb *probLen = prob + LenChoice;
-       IfBit0(probLen)
-       {
-         UpdateBit0(probLen);
-         probLen = prob + LenLow + (posState << kLenNumLowBits);
-         offset = 0;
-         numBits = kLenNumLowBits;
-       }
-       else
-       {
-         UpdateBit1(probLen);
-         probLen = prob + LenChoice2;
-         IfBit0(probLen)
-         {
-           UpdateBit0(probLen);
-           probLen = prob + LenMid + (posState << kLenNumMidBits);
-           offset = kLenNumLowSymbols;
-           numBits = kLenNumMidBits;
-         }
-         else
-         {
-           UpdateBit1(probLen);
-           probLen = prob + LenHigh;
-           offset = kLenNumLowSymbols + kLenNumMidSymbols;
-           numBits = kLenNumHighBits;
-         }
-       }
-       RangeDecoderBitTreeDecode(probLen, numBits, len);
-       len += offset;
-      }
-
-      if (state < 4)
-      {
-       int posSlot;
-       state += kNumLitStates;
-       prob = p + PosSlot +
-           ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-           kNumPosSlotBits);
-       RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
-       if (posSlot >= kStartPosModelIndex)
-       {
-         int numDirectBits = ((posSlot >> 1) - 1);
-         rep0 = (2 | ((UInt32)posSlot & 1));
-         if (posSlot < kEndPosModelIndex)
-         {
-           rep0 <<= numDirectBits;
-           prob = p + SpecPos + rep0 - posSlot - 1;
-         }
-         else
-         {
-           numDirectBits -= kNumAlignBits;
-           do
-           {
-             RC_NORMALIZE
-             Range >>= 1;
-             rep0 <<= 1;
-             if (Code >= Range)
-             {
-               Code -= Range;
-               rep0 |= 1;
-             }
-           }
-           while (--numDirectBits != 0);
-           prob = p + Align;
-           rep0 <<= kNumAlignBits;
-           numDirectBits = kNumAlignBits;
-         }
-         {
-           int i = 1;
-           int mi = 1;
-           do
-           {
-             CProb *prob3 = prob + mi;
-             RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
-             i <<= 1;
-           }
-           while(--numDirectBits != 0);
-         }
-       }
-       else
-         rep0 = posSlot;
-       if (++rep0 == (UInt32)(0))
-       {
-         /* it's for stream version */
-         len = kLzmaStreamWasFinishedId;
-         break;
-       }
-      }
-
-      len += kMatchMinLen;
-      #ifdef _LZMA_OUT_READ
-      if (rep0 > distanceLimit)
-      #else
-      if (rep0 > nowPos)
-      #endif
-       return LZMA_RESULT_DATA_ERROR;
-
-      #ifdef _LZMA_OUT_READ
-      if (dictionarySize - distanceLimit > (UInt32)len)
-       distanceLimit += len;
-      else
-       distanceLimit = dictionarySize;
-      #endif
-
-      do
-      {
-       #ifdef _LZMA_OUT_READ
-       UInt32 pos = dictionaryPos - rep0;
-       if (pos >= dictionarySize)
-         pos += dictionarySize;
-       previousByte = dictionary[pos];
-       dictionary[dictionaryPos] = previousByte;
-       if (++dictionaryPos == dictionarySize)
-         dictionaryPos = 0;
-       #else
-       previousByte = outStream[nowPos - rep0];
-       #endif
-       len--;
-       outStream[nowPos++] = previousByte;
-      }
-      while(len != 0 && nowPos < outSize);
-    }
-  }
-  RC_NORMALIZE;
-
-  #ifdef _LZMA_OUT_READ
-  vs->Range = Range;
-  vs->Code = Code;
-  vs->DictionaryPos = dictionaryPos;
-  vs->GlobalPos = globalPos + (UInt32)nowPos;
-  vs->DistanceLimit = distanceLimit;
-  vs->Reps[0] = rep0;
-  vs->Reps[1] = rep1;
-  vs->Reps[2] = rep2;
-  vs->Reps[3] = rep3;
-  vs->State = state;
-  vs->RemainLen = len;
-  vs->TempDictionary[0] = tempDictionary[0];
-  #endif
-
-  #ifdef _LZMA_IN_CB
-  vs->Buffer = Buffer;
-  vs->BufferLim = BufferLim;
-  #else
-  *inSizeProcessed = (SizeT)(Buffer - inStream);
-  #endif
-  *outSizeProcessed = nowPos;
-  return LZMA_RESULT_OK;
-}
diff --git a/archivers/7z/LzmaDecode.h b/archivers/7z/LzmaDecode.h
deleted file mode 100644 (file)
index bd75525..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-  LzmaDecode.h
-  LZMA Decoder interface
-
-  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
-  http://www.7-zip.org/
-
-  LZMA SDK is licensed under two licenses:
-  1) GNU Lesser General Public License (GNU LGPL)
-  2) Common Public License (CPL)
-  It means that you can select one of these two licenses and
-  follow rules of that license.
-
-  SPECIAL EXCEPTION:
-  Igor Pavlov, as the author of this code, expressly permits you to
-  statically or dynamically link your code (or bind by name) to the
-  interfaces of this file without subjecting your linked code to the
-  terms of the CPL or GNU LGPL. Any modifications or additions
-  to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#ifndef __LZMADECODE_H
-#define __LZMADECODE_H
-
-#include "LzmaTypes.h"
-
-/* #define _LZMA_IN_CB */
-/* Use callback for input data */
-
-/* #define _LZMA_OUT_READ */
-/* Use read function for output data */
-
-/* #define _LZMA_PROB32 */
-/* It can increase speed on some 32-bit CPUs,
-   but memory usage will be doubled in that case */
-
-/* #define _LZMA_LOC_OPT */
-/* Enable local speed optimizations inside code */
-
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
-#define CProb UInt16
-#endif
-
-#define LZMA_RESULT_OK 0
-#define LZMA_RESULT_DATA_ERROR 1
-
-#ifdef _LZMA_IN_CB
-typedef struct _ILzmaInCallback
-{
-  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
-} ILzmaInCallback;
-#endif
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LZMA_PROPERTIES_SIZE 5
-
-typedef struct _CLzmaProperties
-{
-  int lc;
-  int lp;
-  int pb;
-  #ifdef _LZMA_OUT_READ
-  UInt32 DictionarySize;
-  #endif
-}CLzmaProperties;
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
-
-#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
-
-#define kLzmaNeedInitId (-2)
-
-typedef struct _CLzmaDecoderState
-{
-  CLzmaProperties Properties;
-  CProb *Probs;
-
-  #ifdef _LZMA_IN_CB
-  const unsigned char *Buffer;
-  const unsigned char *BufferLim;
-  #endif
-
-  #ifdef _LZMA_OUT_READ
-  unsigned char *Dictionary;
-  UInt32 Range;
-  UInt32 Code;
-  UInt32 DictionaryPos;
-  UInt32 GlobalPos;
-  UInt32 DistanceLimit;
-  UInt32 Reps[4];
-  int State;
-  int RemainLen;
-  unsigned char TempDictionary[4];
-  #endif
-} CLzmaDecoderState;
-
-#ifdef _LZMA_OUT_READ
-#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
-#endif
-
-int LzmaDecode(CLzmaDecoderState *vs,
-    #ifdef _LZMA_IN_CB
-    ILzmaInCallback *inCallback,
-    #else
-    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
-    #endif
-    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
-
-#endif
diff --git a/archivers/7z/LzmaTypes.h b/archivers/7z/LzmaTypes.h
deleted file mode 100644 (file)
index 0072d99..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-LzmaTypes.h
-
-Types for LZMA Decoder
-
-This file written and distributed to public domain by Igor Pavlov.
-This file is part of LZMA SDK 4.40 (2006-05-01)
-*/
-
-#ifndef __LZMATYPES_H
-#define __LZMATYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef unsigned long UInt32;
-#else
-typedef unsigned int UInt32;
-#endif
-#endif
-
-/* #define _LZMA_SYSTEM_SIZE_T */
-/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
-
-#ifndef _7ZIP_SIZET_DEFINED
-#define _7ZIP_SIZET_DEFINED
-#ifdef _LZMA_SYSTEM_SIZE_T
-#include <stddef.h>
-typedef size_t SizeT;
-#else
-typedef UInt32 SizeT;
-#endif
-#endif
-
-#endif
diff --git a/archivers/7z/Types.h b/archivers/7z/Types.h
new file mode 100644 (file)
index 0000000..1af5cfc
--- /dev/null
@@ -0,0 +1,208 @@
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include <stddef.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+   NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct
+{
+  size_t (*Write)(void *p, const void *buf, size_t size);
+    /* Returns: result - the number of actually written bytes.
+       (result < size) means error */
+} ISeqOutStream;
+
+typedef enum
+{
+  SZ_SEEK_SET = 0,
+  SZ_SEEK_CUR = 1,
+  SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct
+{
+  SRes (*Look)(void *p, void **buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) > input(*size)) is not allowed
+       (output(*size) < input(*size)) is allowed */
+  SRes (*Skip)(void *p, size_t offset);
+    /* offset must be <= output(*size) of Look */
+
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* reads directly (without buffer). It's same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct
+{
+  ILookInStream s;
+  ISeekInStream *realStream;
+  size_t pos;
+  size_t size;
+  Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct
+{
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+    /* Returns: result. (result != SZ_OK) means break.
+       Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+  void *(*Alloc)(void *p, size_t size);
+  void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
index baab0fd6a3b2097b3dd1be1c9690b9645428c340..9415584a63d3c3abf418c66c2153b9ea5572ee51 100644 (file)
@@ -7,6 +7,7 @@
 #define FTIME
 #define NOBSTRING
 #define NOINDEX
+#define MKTIME
 
 /* ------------------------------------------------------------------------ */
 /* LHa for UNIX    Archiver Driver                                                                                     */
index 3299733734b2089215b7f871714072021540db21..7547269f9c0cc75ebff0c7ada600dd35d418299c 100644 (file)
@@ -19,7 +19,7 @@ static char *methods[] =
        NULL
 };
 
-struct zvolume *archive_directory_lha(struct zfile *zf)
+struct zvolume *archive_directory_lha (struct zfile *zf)
 {
     struct zvolume *zv;
     struct zarchive_info zai;
@@ -27,16 +27,16 @@ struct zvolume *archive_directory_lha(struct zfile *zf)
     int i;
 
     _tzset();
-    zv = zvolume_alloc(zf, ArchiveFormatLHA, NULL);
+    zv = zvolume_alloc (zf, ArchiveFormatLHA, NULL, NULL);
     while (get_header(zf, &hdr)) {
        struct znode *zn;
        int method;
 
        for (i = 0; methods[i]; i++) {
-           if (!strcmp(methods[i], hdr.method))
+           if (!strcmp (methods[i], hdr.method))
                method = i;
        }
-       memset(&zai, 0, sizeof zai);
+       memset (&zai, 0, sizeof zai);
        zai.name = au (hdr.name);
        zai.size = hdr.original_size;
        zai.flags = hdr.attribute;
@@ -44,25 +44,25 @@ struct zvolume *archive_directory_lha(struct zfile *zf)
        if (hdr.name[strlen(hdr.name) + 1] != 0)
            zai.comment = au (&hdr.name[strlen(hdr.name) + 1]);
        if (method == LZHDIRS_METHOD_NUM) {
-           zvolume_adddir_abs(zv, &zai);
+           zvolume_adddir_abs (zv, &zai);
        } else {
-           zn = zvolume_addfile_abs(zv, &zai);
+           zn = zvolume_addfile_abs (zv, &zai);
            zn->offset = zfile_ftell(zf);
            zn->packedsize = hdr.packed_size;
            zn->method = method;
        }
        xfree (zai.name);
        xfree (zai.comment);
-       zfile_fseek(zf, hdr.packed_size, SEEK_CUR);
+       zfile_fseek (zf, hdr.packed_size, SEEK_CUR);
 
     }
     return zv;
 }
 
-struct zfile *archive_access_lha(struct znode *zn)
+struct zfile *archive_access_lha (struct znode *zn)
 {
     struct zfile *zf = zn->volume->archive;
-    struct zfile *out = zfile_fopen_empty (zn->name, zn->size);
+    struct zfile *out = zfile_fopen_empty (zf, zn->name, zn->size);
     struct interfacing lhinterface;
 
     zfile_fseek(zf, zn->offset, SEEK_SET);
index a4e6086d6cc7c0694e64e908404bdb4de315452f..79530180ec134394c590e43d584498aa8bd77dff 100644 (file)
@@ -675,7 +675,7 @@ struct zfile *archive_access_lzx (struct znode *zn)
     /* pre-cache all files we just decompressed */
     for (;;) {
        if (znfirst->size && !znfirst->f) {
-           dstf = zfile_fopen_empty (znfirst->name, znfirst->size);
+           dstf = zfile_fopen_empty (zf, znfirst->name, znfirst->size);
            zfile_fwrite(dbuf + znfirst->offset2, znfirst->size, 1, dstf);
            znfirst->f = dstf;
            if (znfirst == zn)
@@ -716,7 +716,7 @@ struct zvolume *archive_directory_lzx (struct zfile *in_file)
      return 0;
  if (memcmp(archive_header, "LZX", 3))
      return 0;
- zv = zvolume_alloc(in_file, ArchiveFormatLZX, NULL);
+ zv = zvolume_alloc (in_file, ArchiveFormatLZX, NULL, NULL);
 
  do
  {
index 4408a335a2f2116799736669367e860512b86387..a1477ba9b34f35a7377653bfacab92e1afada4ba 100644 (file)
@@ -403,8 +403,8 @@ struct zfile *unwarp(struct zfile *zf)
        if (!iswrp (buf))
            break;
        if (!nf) {
-           nf = zfile_fopen_empty (L"zipped.wrp", 1760 * 512);
-           tmpf = zfile_fopen_empty (L"tmp", outsize2);
+           nf = zfile_fopen_empty (zf, L"zipped.wrp", 1760 * 512);
+           tmpf = zfile_fopen_empty (zf, L"tmp", outsize2);
        }
        track = (buf[10] << 8) | buf[11];
         algo = buf[19];
diff --git a/audio.c b/audio.c
index 9309066c50e6f1f8b18b8d1d9fb525a6c53df4de..d43bd5b343ef1a14206d1a1e906c644077a5d565 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -192,7 +192,7 @@ void audio_sampleripper (int mode)
            namesplit (name);
            _tcscpy (extension, L"wav");
            _stprintf (filename, L"%s%s%s%03.3d.%s", path, name, underline, cnt, extension);
-           wavfile = zfile_fopen (filename, L"wb");
+           wavfile = zfile_fopen (filename, L"wb", 0);
            if (wavfile) {
                int freq = rs->per > 0 ? (currprefs.ntscmode ? 3579545 : 3546895 / rs->per) : 8000;
                write_wavheader (wavfile, 0, 0);
index 7abd6ecd972b3a3c6cd93f8755413e7ad9f9d244..37578f886e1e3f66cab8dcb0192106c5d5c34efc 100644 (file)
@@ -137,6 +137,12 @@ void dl (uae_u32 data)
     rtarea[rt_addr++] = data;
 }
 
+uae_u8 dbg (uaecptr addr)
+{
+    addr -= rtarea_base;
+    return rtarea[addr];
+}
+
 /* store strings starting at the end of the rt area and working
  * backward.  store pointer at current address
  */
index 7778bd6ba87ba7b07e83fea1061aff1d32c35e02..1e45a465361ec0d328768255582c6f951000d1cb 100644 (file)
@@ -366,7 +366,7 @@ static int catweasel4_configure (void)
        write_log (L"CW: FPGA failed to reset!\n");
        return 0;
     }
-    f = zfile_fopen(L"core.cw4", L"rb");
+    f = zfile_fopen(L"core.cw4", L"rb", ZFD_NORMAL);
     if (!f) {
        f = zfile_fopen_data (L"core.cw4.gz", core_len, core);
        f = zfile_gunzip (f);
diff --git a/cdtv.c b/cdtv.c
index b0bc194040e59f7e90a2cb5685757cfd630aed8a..159897da7132bb7658e4547ba9723e2f80f70fcb 100644 (file)
--- a/cdtv.c
+++ b/cdtv.c
@@ -589,7 +589,7 @@ static uae_u8 *read_raw (int sector, int size)
     if (track != trackcnt) {
        _stprintf (fname, L"track%d.bin", trackcnt);
        zfile_fclose (f);
-       f = zfile_fopen (fname, L"rb");
+       f = zfile_fopen (fname, L"rb", ZFD_NORMAL);
        if (!f)
            write_log (L"failed to open '%s'\n", fname);
        else
@@ -1409,7 +1409,7 @@ void cdtv_loadcardmem(uae_u8 *p, int size)
     struct zfile *f;
 
     memset (p, 0, size);
-    f = zfile_fopen (currprefs.flashfile, L"rb");
+    f = zfile_fopen (currprefs.flashfile, L"rb", ZFD_NORMAL);
     if (!f)
        return;
     zfile_fseek (f, CDTV_NVRAM_SIZE, SEEK_SET);
@@ -1421,7 +1421,7 @@ void cdtv_savecardmem(uae_u8 *p, int size)
 {
     struct zfile *f;
 
-    f = zfile_fopen (currprefs.flashfile, L"rb+");
+    f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f)
        return;
     zfile_fseek (f, CDTV_NVRAM_SIZE, SEEK_SET);
@@ -1435,9 +1435,9 @@ static void cdtv_battram_reset (void)
     int v;
 
     memset (cdtv_battram, 0, CDTV_NVRAM_SIZE);
-    f = zfile_fopen (currprefs.flashfile, L"rb+");
+    f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f) {
-       f = zfile_fopen (currprefs.flashfile, L"wb");
+       f = zfile_fopen (currprefs.flashfile, L"wb", 0);
        if (f) {
            zfile_fwrite (cdtv_battram, CDTV_NVRAM_SIZE, 1, f);
            zfile_fclose (f);
@@ -1460,7 +1460,7 @@ void cdtv_battram_write (int addr, int v)
     if (cdtv_battram[offset] == v)
        return;
     cdtv_battram[offset] = v;
-    f = zfile_fopen (currprefs.flashfile, L"rb+");
+    f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f)
        return;
     zfile_fseek (f, offset, SEEK_SET);
@@ -1524,7 +1524,7 @@ static void romhack (void)
     rl = getromlistbyids(roms);
     if (rl) {
        write_log (L"A590/A2091 BOOT ROM '%s' %d.%d\n", rl->path, rl->rd->ver, rl->rd->rev);
-       z = zfile_fopen(rl->path, "rb");
+       z = zfile_fopen(rl->path, "rb", ZFD_NORMAL);
        if (z) {
            rom_size = 16384;
            rom = (uae_u8*)xmalloc (rom_size);
index 3f47b05a092a0b14f9bf4a8d51267bbd5311a905..9c2ea492191c9b557df31fe2e04ea0a7848fd0f0 100644 (file)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -2087,7 +2087,7 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, int real,
        reset_inputdevice_config (p);
     }
 
-    fh = zfile_fopen (filename, L"r");
+    fh = zfile_fopen (filename, L"r", ZFD_NORMAL);
 #ifndef        SINGLEFILE
     if (! fh)
        return 0;
@@ -2190,7 +2190,7 @@ int cfgfile_save (struct uae_prefs *p, const TCHAR *filename, int type)
     struct zfile *fh;
 
     cfgfile_backup (filename);
-    fh = zfile_fopen (filename, unicode_config ? L"w, ccs=UTF-8" : L"w");
+    fh = zfile_fopen (filename, unicode_config ? L"w, ccs=UTF-8" : L"w", ZFD_NORMAL);
     if (! fh)
        return 0;
 
@@ -2841,7 +2841,7 @@ uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, u
     if (argv <= 1 && index == 0xffffffff) {
        zfile_fclose (configstore);
        xfree (configsearch);
-       configstore = zfile_fopen_empty (L"configstore", 50000);
+       configstore = zfile_fopen_empty (NULL, L"configstore", 50000);
        configsearch = NULL;
        if (argv > 0 && _tcslen (argc[0]) > 0)
            configsearch = my_strdup (argc[0]);
@@ -3281,7 +3281,7 @@ void default_prefs (struct uae_prefs *p, int type)
 
     zfile_fclose (default_file);
     default_file = NULL;
-    f = zfile_fopen_empty (L"configstore", 100000);
+    f = zfile_fopen_empty (NULL, L"configstore", 100000);
     if (f) {
        uaeconfig++;
        cfgfile_save_options (f, p, 0);
diff --git a/cia.c b/cia.c
index 206f5a76152d3bf11a12aedc89c36dc03b2bca04..b7891b0fc96e117921609315d065a907e6874d64 100644 (file)
--- a/cia.c
+++ b/cia.c
@@ -1003,7 +1003,7 @@ static void WriteCIAB (uae_u16 addr,uae_u8 val)
        if (notinrom ())
            write_log (L"BFD100 W %02X %s\n", val, debuginfo(0));
 #endif
-       ciabprb = val; DISK_select(val); break;
+       ciabprb = val; DISK_select (val); break;
     case 2:
 #ifdef DONGLE_DEBUG
        if (notinrom ())
@@ -1403,9 +1403,9 @@ static uae_u8 rtc_memory[RF5C01A_RAM_SIZE], rtc_alarm[RF5C01A_RAM_SIZE];
 
 static void write_battclock (void)
 {
-    struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+");
+    struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
     if (!f) {
-        f = zfile_fopen (currprefs.flashfile, L"wb");
+        f = zfile_fopen (currprefs.flashfile, L"wb", 0);
         if (f) {
            zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
            zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
@@ -1438,7 +1438,7 @@ void rtc_hardreset (void)
        memset (rtc_alarm, 0, RF5C01A_RAM_SIZE);
 #if 0
        struct zfile *f;
-       f = zfile_fopen (currprefs.flashfile, "rb");
+       f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
        if (f) {
            zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
            zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
diff --git a/debug.c b/debug.c
index df3a550be53eb7a429b72e44dc4b935b272b9706..662414fe04312e1e3b1e3f4f2680d063d0434057 100644 (file)
--- a/debug.c
+++ b/debug.c
@@ -188,14 +188,14 @@ static int readregx (TCHAR **c, uae_u32 *valp)
     addr = 0;
     i = 0;
     while (p[i]) {
-       tmp[i] = _totupper(p[i]);
-       if (i >= sizeof (tmp) - 1)
+       tmp[i] = _totupper (p[i]);
+       if (i >= sizeof (tmp) / sizeof (TCHAR) - 1)
            break;
        i++;
     }
     tmp[i] = 0;
     if (_totupper (tmp[0]) == 'R') {
-       memmove (tmp, tmp + 1, sizeof (tmp) - 1);
+       memmove (tmp, tmp + 1, sizeof (tmp) - sizeof (TCHAR));
        extra = 1;
     }
     if (!_tcscmp (tmp, L"USP")) {
@@ -554,7 +554,7 @@ uaecptr dumpmem2 (uaecptr addr, TCHAR *out, int osize)
     if (nonsafe == cols) {
        addrbank *ab = &get_mem_bank (addr);
        if (ab->name)
-           memcpy (out + 9 + 4 + 1, ab->name, _tcslen (ab->name));
+           memcpy (out + (9 + 4 + 1) * sizeof (TCHAR), ab->name, _tcslen (ab->name) * sizeof (TCHAR));
     }
     return addr;
 }
@@ -863,7 +863,7 @@ static int totaltrainers;
 static void clearcheater(void)
 {
     if (!trainerdata)
-       trainerdata = (struct trainerstruct*)xmalloc(MAX_CHEAT_VIEW * sizeof (struct trainerstruct));
+       trainerdata =  xmalloc(MAX_CHEAT_VIEW * sizeof (struct trainerstruct));
     memset(trainerdata, 0, sizeof (struct trainerstruct) * MAX_CHEAT_VIEW);
     totaltrainers = 0;
 }
@@ -1304,7 +1304,7 @@ static void smc_detect_init (TCHAR **c)
     if (currprefs.z3fastmem_size)
        smc_size = currprefs.z3fastmem_start + currprefs.z3fastmem_size;
     smc_size += 4;
-    smc_table = (struct smc_item*)xmalloc (smc_size * sizeof (struct smc_item));
+    smc_table = xmalloc (smc_size * sizeof (struct smc_item));
     if (!smc_table)
        return;
     for (i = 0; i < smc_size; i++) {
@@ -1749,7 +1749,7 @@ static void memwatch_dump (int num)
     TCHAR *buf;
     int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
 
-    buf = malloc (50 * multiplier);
+    buf = malloc (50 * multiplier * sizeof (TCHAR));
     if (!buf)
        return;
     memwatch_dump2 (buf, 50 * multiplier, num);
@@ -2521,7 +2521,7 @@ static void disk_debug (TCHAR **inptr)
     disk_debug_mode = 0;
     disk_debug_track = -1;
     ignore_ws (inptr);
-    if (!next_string (inptr, parm, sizeof (parm), 1))
+    if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
        goto end;
     for (i = 0; i < _tcslen(parm); i++) {
        if (parm[i] == 'R')
@@ -2584,7 +2584,7 @@ static void m68k_modify (TCHAR **inptr)
     TCHAR c1, c2;
     int i;
 
-    if (!next_string (inptr, parm, sizeof (parm), 1))
+    if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
        return;
     c1 = _totupper (parm[0]);
     c2 = 99;
diff --git a/disk.c b/disk.c
index e7e4457ea50e70c4e7ad3117ba5908f0d0888e8d..e976b9ee08f67abe5a26c2d3cfaec52b8fe6abc9 100644 (file)
--- a/disk.c
+++ b/disk.c
@@ -107,7 +107,7 @@ static uae_u16 word, dsksync;
 static int disk_hpos;
 static int disk_jitter;
 
-typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS } image_tracktype;
+typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS, TRACK_DISKSPARE } image_tracktype;
 typedef struct {
     uae_u16 len;
     uae_u32 offs;
@@ -453,7 +453,7 @@ static int createimagefromexe (struct zfile *src, struct zfile *dst)
     bitmap[1] = 1;
 
     dblock1 = createdirheaderblock (sector2, 880, dirname1, bitmap);
-    ss = zfile_fopen_empty (fname1b, strlen (fname1));
+    ss = zfile_fopen_empty (src, fname1b, strlen (fname1));
     zfile_fwrite (fname1, strlen(fname1), 1, ss);
     fblock1 = createfileheaderblock (dst, sector1,  dblock1, fname2, ss, bitmap);
     zfile_fclose (ss);
@@ -656,14 +656,14 @@ struct zfile *DISK_validate_filename (const TCHAR *fname, int leave_open, int *w
     if (crc32)
        *crc32 = 0;
     if (leave_open) {
-       struct zfile *f = zfile_fopen (fname, L"r+b");
+       struct zfile *f = zfile_fopen (fname, L"r+b", ZFD_NORMAL);
        if (f) {
            if (wrprot)
                *wrprot = 0;
        } else {
            if (wrprot)
                *wrprot = 1;
-           f = zfile_fopen (fname, L"rb");
+           f = zfile_fopen (fname, L"rb", ZFD_NORMAL);
        }
        if (f && crc32)
            *crc32 = zfile_crc32 (f);
@@ -673,7 +673,7 @@ struct zfile *DISK_validate_filename (const TCHAR *fname, int leave_open, int *w
            if (wrprot)
                *wrprot = 0;
            if (crc32) {
-               struct zfile *f = zfile_fopen (fname, L"rb");
+               struct zfile *f = zfile_fopen (fname, L"rb", ZFD_NORMAL);
                if (f)
                    *crc32 = zfile_crc32 (f);
                zfile_fclose (f);
@@ -969,7 +969,7 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
 
     } else if (memcmp (exeheader, buffer, sizeof (exeheader)) == 0) {
        int i;
-       struct zfile *z = zfile_fopen_empty (L"", 512 * 1760);
+       struct zfile *z = zfile_fopen_empty (NULL, L"", 512 * 1760);
        createimagefromexe (drv->diskfile, z);
        drv->filetype = ADF_NORMAL;
        zfile_fclose (drv->diskfile);
@@ -1017,21 +1017,49 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
        }
 
     } else {
-       int i;
+       int i, ds;
+
+       ds = 0;
        drv->filetype = ADF_NORMAL;
 
-       /* High-density disk? */
-       if (size >= 160 * 22 * 512) {
-           drv->num_tracks = size / (512 * (drv->num_secs = 22));
-           drv->ddhd = 2;
-       } else
+       /* High-density or diskspare disk? */
+       drv->num_tracks = 0;
+       if (size > 160 * 11 * 512) { // larger than standard adf?
+           for (i = 80; i <= 83; i++) {
+               if (size == i * 22 * 512 * 2) { // HD
+                   drv->ddhd = 2;
+                   drv->num_tracks = size / (512 * (drv->num_secs = 22));
+                   break;
+               }
+               if (size == i * 11 * 512 * 2) { // >80 cyl DD
+                   drv->num_tracks = size / (512 * (drv->num_secs = 11));
+                   break;
+               }
+               if (size == i * 12 * 512 * 2) { // ds 12 sectors
+                   drv->num_tracks = size / (512 * (drv->num_secs = 12));
+                   ds = 1;
+                   break;
+               }
+               if (size == i * 24 * 512 * 2) { // ds 24 sectors
+                   drv->num_tracks = size / (512 * (drv->num_secs = 24));
+                   drv->ddhd = 2;
+                   ds = 1;
+                   break;
+               }
+           }
+           if (drv->num_tracks == 0) {
+               drv->num_tracks = size / (512 * (drv->num_secs = 22));
+               drv->ddhd = 2;
+           }
+       } else {
            drv->num_tracks = size / (512 * (drv->num_secs = 11));
+       }
 
-       if (drv->num_tracks > MAX_TRACKS)
+       if (!ds && drv->num_tracks > MAX_TRACKS)
            write_log (L"Your diskfile is too big, %d bytes!\n", size);
        for (i = 0; i < drv->num_tracks; i++) {
            tid = &drv->trackdata[i];
-           tid->type = TRACK_AMIGADOS;
+           tid->type = ds ? TRACK_DISKSPARE : TRACK_AMIGADOS;
            tid->len = 512 * drv->num_secs;
            tid->bitlen = 0;
            tid->offs = i * 512 * drv->num_secs;
@@ -1408,6 +1436,93 @@ static void decode_amigados (drive *drv)
        write_log (L"amigados read track %d\n", tr);
 }
 
+/*
+ * diskspare format
+ *
+ * 0 <4489> <4489> 0 track sector crchi, crclo, data[512] (520 bytes per sector)
+ *
+ * 0xAAAA 0x4489 0x4489 0x2AAA oddhi, oddlo, evenhi, evenlo, ...
+ *
+ * NOTE: data is MFM encoded using same method as ADOS header, not like ADOS data!
+ *
+ */
+
+static void decode_diskspare (drive *drv)
+{
+    int tr = drv->cyl * 2 + side;
+    int sec;
+    int dstmfmoffset = 0;
+    int size = 512 + 8;
+    uae_u16 *dstmfmbuf = drv->bigmfmbuf;
+    int len = drv->num_secs * size + FLOPPY_GAP_LEN;
+
+    trackid *ti = drv->trackdata + tr;
+    memset (dstmfmbuf, 0xaa, len * 2);
+    dstmfmoffset += FLOPPY_GAP_LEN;
+    drv->skipoffset = (FLOPPY_GAP_LEN * 8) / 3 * 2;
+    drv->tracklen = len * 2 * 8;
+
+    for (sec = 0; sec < drv->num_secs; sec++) {
+       uae_u8 secbuf[512 + 8];
+       uae_u16 mfmbuf[512 + 8];
+       int i;
+       uae_u32 deven, dodd;
+       uae_u16 chk;
+
+       secbuf[0] = tr;
+       secbuf[1] = sec;
+       secbuf[2] = 0;
+       secbuf[3] = 0;
+
+       read_floppy_data (drv->diskfile, ti, sec * 512, &secbuf[4], 512);
+
+       mfmbuf[0] = 0xaaaa;
+       mfmbuf[1] = 0x4489;
+       mfmbuf[2] = 0x4489;
+       mfmbuf[3] = 0x2aaa;
+
+       for (i = 0; i < 512; i += 4) {
+           deven = ((secbuf[i + 4] << 24) | (secbuf[i + 5] << 16)
+                        | (secbuf[i + 6] << 8) | (secbuf[i + 7]));
+           dodd = deven >> 1;
+           deven &= 0x55555555;
+           dodd &= 0x55555555;
+           mfmbuf[i + 8 + 0] = dodd >> 16;
+           mfmbuf[i + 8 + 1] = dodd;
+           mfmbuf[i + 8 + 2] = deven >> 16;
+           mfmbuf[i + 8 + 3] = deven;
+       }
+       mfmcode (mfmbuf + 8, 512);
+
+       i = 8;
+       chk = mfmbuf[i++] & 0x7fff;
+       while (i < 512 + 8)
+           chk ^= mfmbuf[i++];
+       secbuf[2] = chk >> 8;
+       secbuf[3] = chk;
+
+       deven = ((secbuf[0] << 24) | (secbuf[1] << 16)
+                    | (secbuf[2] << 8) | (secbuf[3]));
+       dodd = deven >> 1;
+       deven &= 0x55555555;
+       dodd &= 0x55555555;
+
+       mfmbuf[4] = dodd >> 16;
+       mfmbuf[5] = dodd;
+       mfmbuf[6] = deven >> 16;
+       mfmbuf[7] = deven;
+       mfmcode (mfmbuf + 4, 4);
+
+       for (i = 0; i < 512 + 8; i++) {
+           dstmfmbuf[dstmfmoffset % len] = mfmbuf[i];
+           dstmfmoffset++;
+       }
+     }
+
+    if (disk_debug_logging > 0)
+       write_log (L"diskspare read track %d\n", tr);
+}
+
 static void drive_fill_bigbuf (drive * drv, int force)
 {
     int tr = drv->cyl * 2 + side;
@@ -1470,11 +1585,14 @@ static void drive_fill_bigbuf (drive * drv, int force)
 
        decode_pcdos (drv);
 
-
     } else if (ti->type == TRACK_AMIGADOS) {
 
        decode_amigados (drv);
 
+    } else if (ti->type == TRACK_DISKSPARE) {
+
+       decode_diskspare (drv);
+
     } else {
        int i;
        int base_offset = ti->type == TRACK_RAW ? 0 : 1;
@@ -1574,7 +1692,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
 
        trackoffs = (id & 0xff00) >> 8;
        if (trackoffs + 1 > drvsec) {
-           write_log (L"Disk decode: weird sector number %d\n", trackoffs);
+           write_log (L"Disk decode: weird sector number %d (%04x)\n", trackoffs, id);
            if (filetype == ADF_EXT2)
                return 2;
            continue;
@@ -1640,7 +1758,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
     return 0;
 }
 
-static uae_u8 mfmdecode(uae_u16 **mfmp, int shift)
+static uae_u8 mfmdecode (uae_u16 **mfmp, int shift)
 {
     uae_u16 mfm = getmfmword (*mfmp, shift);
     uae_u8 out = 0;
@@ -1890,7 +2008,7 @@ void disk_creatediskfile (TCHAR *name, int type, drive_type adftype, TCHAR *disk
        tracks /= 2;
     }
 
-    f = zfile_fopen (name, L"wb");
+    f = zfile_fopen (name, L"wb", 0);
     chunk = xmalloc (32768);
     if (f && chunk) {
        int cylsize = sectors * 2 * 512;
@@ -1958,7 +2076,7 @@ int disk_getwriteprotect (const TCHAR *name)
 
 static void diskfile_readonly (const TCHAR *name, int readonly)
 {
-    struct stat st;
+    struct _stat64 st;
     int mode, oldmode;
 
     if (stat (name, &st))
@@ -2812,7 +2930,7 @@ void DISK_update (int tohpos)
     for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
        drive *drv = &floppy[dr];
 
-       if (drv->motoroff)
+       if (drv->motoroff || !drv->tracklen || !drv->trackspeed)
            continue;
        drv->floppybitcounter += cycles;
        if (selected & (1 << dr)) {
@@ -2828,7 +2946,7 @@ void DISK_update (int tohpos)
     didread = 0;
     for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
        drive *drv = &floppy[dr];
-       if (drv->motoroff)
+       if (drv->motoroff || !drv->trackspeed)
            continue;
        if (selected & (1 << dr))
            continue;
diff --git a/diskutil.c b/diskutil.c
new file mode 100644 (file)
index 0000000..be0b238
--- /dev/null
@@ -0,0 +1,132 @@
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#define MFMMASK 0x55555555
+static uae_u32 getmfmlong (uae_u16 * mbuf)
+{
+       return (uae_u32)(((*mbuf << 16) | *(mbuf + 1)) & MFMMASK);
+}
+
+#define FLOPPY_WRITE_LEN 6250
+
+static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track)
+{
+       int i;
+       uae_u32 odd, even, chksum, id, dlong;
+       uae_u8 *secdata;
+       uae_u8 secbuf[544];
+
+       mend -= (4 + 16 + 8 + 512);
+       for (;;) {
+               int trackoffs;
+
+       /* all sectors complete? */
+               for (i = 0; i < 11; i++) {
+                       if (!writebuffer_ok[i])
+                               break;
+               }
+               if (i == 11)
+                       return 0;
+
+               do {
+                       while (*mbuf++ != 0x4489) {
+                               if (mbuf >= mend) {
+                                       write_log (L"* track %d, unexpected end of data\n", track);
+                                       return 1;
+                               }
+                       }
+               } while (*mbuf++ != 0x4489);
+
+               odd = getmfmlong (mbuf);
+               even = getmfmlong (mbuf + 2);
+               mbuf += 4;
+               id = (odd << 1) | even;
+
+               trackoffs = (id & 0xff00) >> 8;
+               if (trackoffs > 10) {
+                       write_log (L"* track %d, corrupt sector number %d\n", track, trackoffs);
+                       goto next;
+               }
+               /* this sector is already ok? */
+               if (writebuffer_ok[trackoffs])
+                       goto next;
+
+               chksum = odd ^ even;
+               for (i = 0; i < 4; i++) {
+                       odd = getmfmlong (mbuf);
+                       even = getmfmlong (mbuf + 8);
+                       mbuf += 2;
+
+                       dlong = (odd << 1) | even;
+                       if (dlong) {
+                               write_log (L"* track %d, sector %d header crc error\n", track, trackoffs);
+                               goto next;
+                       }
+                       chksum ^= odd ^ even;
+               } /* could check here if the label is nonstandard */
+               mbuf += 8;
+               odd = getmfmlong (mbuf);
+               even = getmfmlong (mbuf + 2);
+               mbuf += 4;
+               if (((odd << 1) | even) != chksum || ((id & 0x00ff0000) >> 16) != (uae_u32)track) return 3;
+               odd = getmfmlong (mbuf);
+               even = getmfmlong (mbuf + 2);
+               mbuf += 4;
+               chksum = (odd << 1) | even;
+               secdata = secbuf + 32;
+               for (i = 0; i < 128; i++) {
+                       odd = getmfmlong (mbuf);
+                       even = getmfmlong (mbuf + 256);
+                       mbuf += 2;
+                       dlong = (odd << 1) | even;
+                       *secdata++ = (uae_u8)(dlong >> 24);
+                       *secdata++ = (uae_u8)(dlong >> 16);
+                       *secdata++ = (uae_u8)(dlong >> 8);
+                       *secdata++ = (uae_u8)dlong;
+                       chksum ^= odd ^ even;
+               }
+               mbuf += 256;
+               if (chksum) {
+                       write_log (L"* track %d, sector %d data crc error\n", track, trackoffs);
+                       goto next;
+               }
+               memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512);
+               writebuffer_ok[trackoffs] = 0xff;
+               continue;
+next:
+               mbuf += 8;
+       }
+}
+
+/* search and align to 0x4489 WORDSYNC markers */
+int isamigatrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track)
+{
+       uae_u16 *dst = amigamfmbuffer;
+       int shift, syncshift, sync;
+       uae_u32 l;
+       uae_u16 w;
+
+       len *= 8;
+       sync = syncshift = shift = 0;
+       while (len--) {
+               l = (mfmdata[0] << 16) | (mfmdata[1] << 8) | (mfmdata[2] << 0);
+               w = (uae_u16)(l >> (8 - shift));
+               if (w == 0x4489) {
+                       sync = 1;
+                       syncshift = 0;
+               }
+               if (sync) {
+                       if (syncshift == 0) *dst++ = w;
+                       syncshift++;
+                       if (syncshift == 16) syncshift = 0;
+               }
+               shift++;
+               if (shift == 8) {
+                       mfmdata++;
+                       shift = 0;
+               }
+       }
+       if (sync)
+               return drive_write_adf_amigados (amigamfmbuffer, dst, writebuffer, writebuffer_ok, track);
+       return -1;
+}
\ No newline at end of file
index aa022ae2c2a14f63f817ce144fc124fa642d08bf..7f8f9abc338f24bd29ea9c0c2e2be4acebd8356d 100644 (file)
@@ -66,11 +66,11 @@ static int loadsample (TCHAR *path, struct drvsample *ds)
     int size;
     TCHAR name[MAX_DPATH];
 
-    f = zfile_fopen (path, L"rb");
+    f = zfile_fopen (path, L"rb", ZFD_NORMAL);
     if (!f) {
        _tcscpy (name, path);
        _tcscat (name, L".wav");
-       f = zfile_fopen (name, L"rb");
+       f = zfile_fopen (name, L"rb", ZFD_NORMAL);
        if (!f) {
            write_log (L"driveclick: can't open '%s' (or '%s')\n", path, name);
            return 0;
index 5579fd56419b5193d21ba7a8fb3304f1dd6bbe73..247c3ef296fa7b91734fff6d986ccdf01f08002c 100644 (file)
--- a/fdi2raw.c
+++ b/fdi2raw.c
@@ -1796,6 +1796,8 @@ static void fdi2_celltiming (FDI *fdi, unsigned long totalavg, int bitoffset, ua
        double avg_bit_len;
        int i;
 
+       if (out == NULL)
+           return;
        avg_bit_len = (double)totalavg / (double)bitoffset;
        pt2 = fdi->track_dst_buffer_timing;
        pt = out;
index b519313766bf5354f4c06517307ec336bcc00391..50c614ba87de38bbb800b4567e73af100450498d 100644 (file)
@@ -16,7 +16,7 @@
 ; 2007.06.15 uninitialized variable in memory type selection fixed (stupid me) (TW)
 ; 2007.08.09 started implementing removable drive support (TW)
 ; 2007.09.01 ACTION_EXAMINE_ALL (TW)
-; 2007.09.05 fully filesystem device mounting on the fly (TW)
+; 2007.09.05 full filesystem device mounting on the fly (TW)
 ; 2008.01.09 ACTION_EXAMINE_ALL does not anymore return eac_Entries = 0 with continue (fixes some broken programs)
 ; 2008.12.11 mousehack -> tablet driver
 ; 2008.12.25 mousehack cursor sync
@@ -46,14 +46,16 @@ NRF_MAGIC = $80000000
 our_seglist:
        dc.l 0                                                                  ; 8 /* NextSeg */
 start:
-       bra.w filesys_mainloop  ;12
-       dc.l make_dev-start                     ;16
-       dc.l filesys_init-start ;20
-       dc.l exter_server-start ;24
-       dc.l bootcode-start                     ;28
-       dc.l setup_exter-start  ;32
-       dc.l mh_e-start                                 ;36
-                                                                                                       ;40
+       dc.l 9                                                                  ;0 12
+       bra.w filesys_mainloop  ;1 16
+       dc.l make_dev-start                     ;2 20
+       dc.l filesys_init-start ;3 24
+       dc.l exter_server-start ;4 28
+       dc.l bootcode-start                     ;5 32
+       dc.l setup_exter-start  ;6 36
+       dc.l mh_e-start                                 ;7 40
+       dc.l clipboard_init-start ;8 44
+       ;48
 
 bootcode:
        lea.l doslibname(pc),a1
@@ -64,6 +66,62 @@ bootcode:
        jsr (a0)
        rts
 
+residenthack
+       movem.l d0-d2/a0-a2/a6,-(sp)
+       move.l 4.w,a6
+       cmp.w #37,20(a6)
+       bcs.s .rsh
+       moveq #residentcodeend-residentcodestart,d0
+       move.l d0,d2
+       move.l #65536+1,d1
+       jsr AllocMem(a6)
+       tst.l d0
+       beq.s .rsh
+       move.l d0,a2
+
+       move.l a2,a0
+       lea residentcodestart(pc),a1
+.cp1
+       move.l (a1)+,(a0)+
+       subq.l #4,d2
+       bne.s .cp1
+
+       move.l a6,a1
+       move.w #-$48,a0 ;InitCode
+       move.l a2,d0
+       jsr -$01a4(a6) ;SetFunction
+       move.l d0,residentcodejump2-residentcodestart+2(a2)
+       lea myafterdos(pc),a0
+       move.l a0,residentcodejump1-residentcodestart+2(a2)
+       jsr -$27C(a6) ;CacheClearU
+.rsh
+       movem.l (sp)+,d0-d2/a0-a2/a6
+       rts
+       
+myafterdos
+       move.l (sp),a0
+       move.l 2(a0),a0
+       movem.l d0-d7/a1-a6,-(sp)
+       move.l a6,a1
+       move.l a0,d0
+       move.w #-$48,a0 ;InitResident
+       jsr -$01a4(a6) ;SetFunction
+       bsr.w clipboard_init
+       movem.l (sp)+,d0-d7/a1-a6
+       rts
+
+       cnop 0,4
+residentcodestart:
+       btst #2,d0 ;RTF_AFTERDOS?
+       beq.s resjump
+residentcodejump1
+       jsr $f00000
+resjump
+residentcodejump2
+       jmp $f00000
+       cnop 0,4
+residentcodeend:
+
 filesys_init:
        movem.l d0-d7/a0-a6,-(sp)
        move.l 4.w,a6
@@ -307,6 +365,7 @@ exter_server_exit:
 
 setup_exter:
        movem.l d0-d1/a0-a1,-(sp)
+       bsr.w residenthack
        moveq.l #26,d0
        move.l #$10001,d1
        jsr AllocMem(a6)
@@ -324,10 +383,6 @@ setup_exter:
        beq.s .nomh
        bsr.w mousehack_init
 .nomh
-       cmp.w #36,20(a6)
-       bcs.s .noclip
-       bsr.w clipboard_init
-.noclip
        movem.l (sp)+,d0-d1/a0-a1
        rts
 
@@ -1976,86 +2031,44 @@ CLIP_POINTER_NOTIFY = (CLIP_BUF+CLIP_BUF_SIZE)
 CLIP_POINTER_PREFS = (CLIP_POINTER_NOTIFY+48)
 CLIP_END = (CLIP_POINTER_PREFS+32)
 
-clipboard_init:
-       lea clname(pc),a0
-       lea clipboard_task(pc),a1
-       moveq #-10,d0
-       bsr createtask
-       rts
+;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_task:
-       sub.l a5,a5
+clipboard_init:
+       movem.l a5/a6,-(sp)
        move.l 4.w,a6
-
        move.l #CLIP_END,d0
        move.l #$10001,d1
        jsr AllocMem(a6)
        tst.l d0
        beq.w clipdie
        move.l d0,a5
-
        move.l a6,CLIP_EXEC(a5)
 
-       sub.l a1,a1
-       jsr -294(a6) ; FindTask
-       move.l d0,CLIP_TASK(a5)
-
        move.w #$FF38,d0
        moveq #14,d1
        bsr.w getrtbase
        move.l a5,d0
        jsr (a0)
 
-       moveq #0,d4
-       moveq #0,d5
-
-       ;move.l d0,$100.w
-
-.wait
-       moveq #0,d0
-       bset #13,d0
-       jsr -$013e(a6) ;Wait
-
-       jsr -$0084(a6) ;Forbid
-
-       tst.l d4
-       bne.s .wait2
-       lea 378(a6),a0 ;LibList
-       lea doslibname(pc),a1
-       jsr -$114(a6) ;FindName
-       move.l d0,d4
-       bra.s .wait3
-.wait2
-
-       moveq #1,d5
-;      exg d4,a6
-;      moveq #(1<<0)+(1<<4),d1 ;LDF_READ | LDF_ASSIGNS
-;      jsr -$28E(a6) ;LockDosList
-;      move.l d0,d1
-;      lea devsn_name(pc),a0
-;      move.l a0,d2
-;      moveq #(1<<4),d3 ;LDF_ASSIGNS
-;      jsr -$2AC(a6) ;FindDosEntry
-;      move.l d0,d5
-;      moveq #(1<<0)+(1<<4),d1 ;LDF_READ | LDF_ASSIGNS
-;      jsr -$294(a6) ;UnLockDosList
-;      exg d4,a6
-
-.wait3
-       jsr -$008a(a6) ;Permit
-       tst.l d5
-       beq.s .wait
-
-       clr.l CLIP_TASK(a5)
        ; we need to be a process, LoadLibrary() needs to call dos
        lea clname(pc),a0
        lea clipboard_proc(pc),a1
        moveq #-10,d0
        move.l #10000,d1
        bsr.w createproc
-       
-       ; task has done its job, process continues..
+
        moveq #0,d0
+       movem.l (sp)+,a5/a6
        rts
 
 clipkill
@@ -2176,14 +2189,12 @@ clipboard_proc:
        moveq #0,d0
        jsr -$0228(a6) ; OpenLibrary
        move.l d0,CLIP_DOS(a5)
-       tst.l d0
        beq.w clipdie
        move.l d0,a6
 
 .devsloop
        moveq #50,d1
        jsr -$00c6(a6) ;Delay
-       ;move.l d0,$104.w
        lea devs_name(pc),a0
        move.l a0,d1
        moveq #-2,d2
@@ -2388,7 +2399,7 @@ devs_name: dc.b 'DEVS:',0
 clip_name: dc.b 'DEVS:clipboard.device',0
 ram_name: dc.b 'RAM:',0
 clip_dev: dc.b 'clipboard.device',0
- ;argghh but StartNofity()ing non-existing ENV: causes "Insert disk ENV: in any drive" dialog..
+ ;argghh but StartNotify()ing non-existing ENV: causes "Insert disk ENV: in any drive" dialog..
 pointer_prefs: dc.b 'RAM:Env/Sys/Pointer.prefs',0
 clname: dc.b 'UAE clipboard sharing',0
 mhname: dc.b 'UAE mouse driver',0
index d61c1ad70c29c070682eb6d9b0590bb91bc60ff5..99ef96f4d0b42d7af80e490bd57d7aef5e0dfea4 100644 (file)
--- a/filesys.c
+++ b/filesys.c
 
 static uae_sem_t test_sem;
 
+int bootrom_header, bootrom_items;
+static uae_u32 dlg (uae_u32 a)
+{
+    return (dbg (a + 0) << 24) | (dbg (a + 1) << 16) | (dbg (a + 2) << 8) | (dbg (a + 3) << 0);
+}
+
 static char *ua_fs (const TCHAR *src)
 {
     return uacp (src, currprefs.win32_fscodepage);
@@ -366,9 +372,9 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, const
 static int set_filesys_volume (const TCHAR *rootdir, int *flags, int *readonly, int *emptydrive, struct zvolume **zvp)
 {
     *emptydrive = 0;
-    if (my_existsfile(rootdir)) {
+    if (my_existsfile (rootdir)) {
        struct zvolume *zv;
-       zv = zfile_fopen_archive(rootdir);
+       zv = zfile_fopen_archive (rootdir);
        if (!zv) {
            write_log (L"'%s' is not a supported archive file\n", rootdir);
            return -1;
@@ -872,8 +878,8 @@ static TCHAR *char1 (uaecptr addr)
 
 static TCHAR *bstr1 (uaecptr addr)
 {
-    static TCHAR bufx[256];
-    static uae_char buf[256];
+    static TCHAR bufx[257];
+    static uae_char buf[257];
     int i;
     int n = get_byte (addr);
     addr++;
@@ -888,7 +894,7 @@ static TCHAR *bstr (Unit *unit, uaecptr addr)
 {
     int i;
     int n = get_byte (addr);
-    uae_char buf[256];
+    uae_char buf[257];
 
     addr++;
     for (i = 0; i < n; i++, addr++)
@@ -951,7 +957,7 @@ static void *fs_open (Unit *unit, const TCHAR *name, int flags)
     else
        return my_open (name, flags);
 }
-static void fs_close(Unit *unit, void *fd)
+static void fs_close (Unit *unit, void *fd)
 {
     int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
     if (isarch)
@@ -1659,7 +1665,9 @@ static int fill_file_attrs (Unit *u, a_inode *base, a_inode *c)
        TCHAR *comment;
        zfile_fill_file_attrs_archive (c->nname, &isdir, &flags, &comment);
        c->dir = isdir;
-       c->amigaos_mode = flags;
+       c->amigaos_mode = 0;
+       if (flags >= 0)
+           c->amigaos_mode = flags;
        c->comment = comment;
        return 1;
     } else {
@@ -5070,7 +5078,6 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context)
     }
     resaddr += 0x1A;
     tmp = resaddr;
-
     /* The good thing about this function is that it always gets called
      * when we boot. So we could put all sorts of stuff that wants to be done
      * here.
@@ -5109,9 +5116,9 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context)
     }
     /* call setup_exter */
     put_word (resaddr +  0, 0x2079);
-    put_long (resaddr +  2, rtarea_base + 28 + 4); /* move.l RTAREA_BASE+32,a0 */
+    put_long (resaddr +  2, rtarea_base + bootrom_header + 4 + 5 * 4); /* move.l RTAREA_BASE+setup_exter,a0 */
     put_word (resaddr +  6, 0xd1fc);
-    put_long (resaddr +  8, rtarea_base + 8 + 4); /* add.l #RTAREA_BASE+12,a0 */
+    put_long (resaddr +  8, rtarea_base + bootrom_header); /* add.l #RTAREA_BASE+bootrom_header,a0 */
     put_word (resaddr + 12, 0x4e90); /* jsr (a0) */
     put_word (resaddr + 14, 0x7001); /* moveq.l #1,d0 */
     put_word (resaddr + 16, RTS);
@@ -5573,7 +5580,7 @@ static int dofakefilesys (UnitInfo *uip, uaecptr parmpacket)
        return -1;
     }
     write_log (L"RDB: fakefilesys, trying to load '%s', dostype 0x%08X\n", tmp, dostype);
-    zf = zfile_fopen (tmp, L"rb");
+    zf = zfile_fopen (tmp, L"rb", ZFD_NORMAL);
     if (!zf) {
        write_log (L"RDB: filesys not found\n");
        if ((dostype & 0xffffff00) == 0x444f5300)
@@ -5712,8 +5719,8 @@ void filesys_install (void)
 
     fsdevname = ds (L"uae.device"); /* does not really exist */
 
-    ROM_filesys_diagentry = here();
-    calltrap (deftrap2(filesys_diagentry, 0, L"filesys_diagentry"));
+    ROM_filesys_diagentry = here ();
+    calltrap (deftrap2 (filesys_diagentry, 0, L"filesys_diagentry"));
     dw(0x4ED0); /* JMP (a0) - jump to code that inits Residents */
 
     loop = here ();
@@ -5760,16 +5767,20 @@ void filesys_install (void)
 
 void filesys_install_code (void)
 {
-    uae_u32 a;
-    align(4);
+    uae_u32 a, b;
 
+    bootrom_header = 3 * 4;
+    align(4);
     a = here ();
-    /* The last offset comes from the code itself, look for it near the top. */
-    EXPANSION_bootcode = a + 40 - 4;
-    filesys_initcode = a + 40 - 4 + 20;
-
     #include "filesys_bootrom.c"
+
+    bootrom_items = dlg (a + 8);
+    /* The last offset comes from the code itself, look for it near the top. */
+    EXPANSION_bootcode = a + bootrom_header + bootrom_items * 4 - 4;
+    b = a + bootrom_header + 3 * 4 - 4;
+    filesys_initcode = a + dlg (b) + bootrom_header - 4;
 }
+
 #include "od-win32/win32_filesys.c"
 
 static uae_u8 *restore_filesys_hardfile (UnitInfo *ui, uae_u8 *src)
index 08a8026c52aac3f4bacd2246c8c744189e56f46c..00fd32dc94b6fef32373a69cd8b5aa422313b4e8 100644 (file)
@@ -1,15 +1,33 @@
  db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x60); db(0x00); db(0x09); db(0x8e); db(0x00); db(0x00); db(0x07); db(0x6c);
- db(0x00); db(0x00); db(0x00); db(0x30); db(0x00); db(0x00); db(0x01); db(0x8c);
- db(0x00); db(0x00); db(0x00); db(0x1c); db(0x00); db(0x00); db(0x02); db(0x48);
- db(0x00); db(0x00); db(0x0d); db(0x5c); db(0x43); db(0xfa); db(0x16); db(0x95);
+ 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(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(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(0x4e); db(0x75); db(0x20); db(0x57); db(0x20); db(0x68); db(0x00); db(0x02);
+ db(0x48); db(0xe7); db(0xff); db(0x7e); db(0x22); db(0x4e); db(0x20); db(0x08);
+ db(0x30); db(0x7c); db(0xff); db(0xb8); db(0x4e); db(0xae); db(0xfe); db(0x5c);
+ db(0x61); db(0x00); db(0x11); db(0xd2); db(0x4c); db(0xdf); db(0x7e); db(0xff);
+ db(0x4e); db(0x75); db(0x00); db(0x00); db(0x08); db(0x00); db(0x00); db(0x02);
+ db(0x67); db(0x06); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0x00); db(0x00);
+ db(0x4e); db(0xf9); db(0x00); db(0xf0); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x30); db(0x3c); db(0xff); db(0xfc); db(0x61); db(0x00); db(0x0b); db(0x8a);
- db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x16); db(0x9e); db(0x70); db(0x24);
+ db(0x30); db(0x3c); db(0xff); db(0xfc); db(0x61); db(0x00); db(0x0b); db(0x82);
+ db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x16); db(0x4c); db(0x70); db(0x24);
  db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
- db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x16); db(0x8e); db(0x70); db(0x00);
+ db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x16); db(0x3c); db(0x70); db(0x00);
  db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
  db(0x4a); db(0xad); db(0x01); db(0x0c); db(0x67); db(0x5a); db(0x20); db(0x3c);
  db(0x00); db(0x00); db(0x02); db(0x2c); db(0x22); db(0x3c); db(0x00); db(0x01);
@@ -17,7 +35,7 @@
  db(0x27); db(0x4c); db(0x01); db(0x9c); db(0x7c); db(0x00); db(0xbc); db(0xad);
  db(0x01); db(0x0c); db(0x64); db(0x2c); db(0x2f); db(0x06); db(0x7e); db(0x01);
  db(0x4a); db(0x45); db(0x67); db(0x04); db(0x08); db(0xc7); db(0x00); db(0x02);
- db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); db(0x06); db(0xd6);
+ db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); db(0x06); db(0xce);
  db(0x26); db(0x5f); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
  db(0x67); db(0x08); db(0x48); db(0x46); db(0x52); db(0x46); db(0x48); db(0x46);
  db(0x60); db(0xdc); db(0x2c); db(0x1f); db(0x52); db(0x46); db(0x60); db(0xce);
  db(0x00); db(0x00); db(0x02); db(0x2c); db(0x4e); db(0xae); db(0xff); db(0x2e);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae);
  db(0xfe); db(0x62); db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00);
- db(0x0a); db(0xf8); db(0x4e); db(0x90); db(0x72); db(0x03); db(0x74); db(0xf6);
+ db(0x0a); db(0xf0); db(0x4e); db(0x90); db(0x72); db(0x03); db(0x74); db(0xf6);
  db(0x20); db(0x7c); db(0x00); db(0x20); db(0x00); db(0x00); db(0x90); db(0x88);
  db(0x65); db(0x0a); db(0x67); db(0x08); db(0x78); db(0x00); db(0x22); db(0x44);
- db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0x99);
+ db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0x47);
  db(0x43); db(0xfa); db(0x00); db(0x54); db(0x70); db(0x0a); db(0x61); db(0x00);
- db(0x0b); db(0xac); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xc4); db(0x4e); db(0x90);
+ db(0x0b); db(0xa4); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xbc); db(0x4e); db(0x90);
  db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7);
  db(0x38); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x00);
  db(0x28); db(0x01); db(0x26); db(0x09); db(0x24); db(0x48); db(0x43); db(0xfa);
- db(0x15); db(0x93); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x15); db(0x41); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
  db(0x4a); db(0x80); db(0x67); db(0x14); db(0x2c); db(0x40); db(0x22); db(0x0a);
  db(0xe4); db(0x8b); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x22); db(0x4e);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
  db(0x4c); db(0xdf); db(0x44); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x15); db(0x44);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x14); db(0xf2);
  db(0x43); db(0xfa); db(0x00); db(0x16); db(0x70); db(0x0f); db(0x22); db(0x3c);
  db(0x00); db(0x00); db(0x1f); db(0x40); db(0x61); db(0x00); db(0xff); db(0xa8);
  db(0x60); db(0xdc); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x72); db(0x02); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x4c); db(0x4e); db(0x90);
- db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x07); db(0x92);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x44); db(0x4e); db(0x90);
+ db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x07); db(0x8a);
  db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x20);
- db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x32);
+ db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x2a);
  db(0x70); db(0x00); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00);
  db(0x00); db(0xa2); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c);
- db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x1c); db(0x70); db(0x02);
+ db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x14); db(0x70); db(0x02);
  db(0x4e); db(0x90); db(0x0c); db(0x40); db(0x00); db(0x01); db(0x6d); db(0x00);
  db(0x00); db(0x7c); db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92);
  db(0x60); db(0xe4); db(0x0c); db(0x40); db(0x00); db(0x02); db(0x6e); db(0x08);
  db(0x00); db(0x18); db(0x25); db(0x49); db(0x00); db(0x1a); db(0x20); db(0x69);
  db(0x00); db(0x10); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0x92);
  db(0x60); db(0x00); db(0xff); db(0x74); db(0x30); db(0x3c); db(0xff); db(0x50);
- db(0x61); db(0x00); db(0x09); db(0x8e); db(0x70); db(0x04); db(0x4e); db(0x90);
+ 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(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(0x14); db(0x1c); db(0x23); db(0x48);
- db(0x00); db(0x0a); db(0x41); db(0xfa); db(0xff); db(0x28); db(0x23); db(0x48);
- db(0x00); db(0x0e); db(0x41); db(0xfa); db(0xff); db(0x20); db(0x23); db(0x48);
- db(0x00); db(0x12); db(0x33); db(0x7c); db(0x02); db(0x14); db(0x00); db(0x08);
- db(0x70); db(0x03); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x30); db(0x3a);
- db(0x0a); db(0xdc); db(0x67); db(0x04); db(0x61); db(0x00); db(0x0a); db(0x7a);
- db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14); db(0x65); db(0x04);
- db(0x61); db(0x00); db(0x0f); db(0x5a); db(0x4c); db(0xdf); db(0x03); db(0x03);
+ db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x5a);
+ db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa);
+ db(0x13); db(0xc6); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
+ db(0xff); db(0x24); db(0x23); db(0x48); db(0x00); db(0x0e); db(0x41); db(0xfa);
+ db(0xff); db(0x1c); db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c);
+ db(0x02); db(0x14); db(0x00); db(0x08); db(0x70); db(0x03); db(0x4e); db(0xae);
+ db(0xff); db(0x58); db(0x30); db(0x3a); db(0x0a); db(0xd0); db(0x67); db(0x04);
+ db(0x61); db(0x00); db(0x0a); db(0x6e); db(0x4c); db(0xdf); db(0x03); db(0x03);
  db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xf2); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x24); db(0x48); db(0x26); db(0x49); db(0x20); db(0x3c);
  db(0x00); db(0x00); db(0x00); db(0xbe); db(0x22); db(0x3c); db(0x00); db(0x01);
  db(0x00); db(0x00); db(0x00); db(0x0e); db(0x52); db(0x40); db(0x0c); db(0x40);
  db(0x00); db(0x8c); db(0x66); db(0xf2); db(0x20); db(0x0a); db(0xe4); db(0x88);
  db(0x21); db(0x40); db(0x00); db(0x36); db(0x22); db(0x48); db(0x41); db(0xfa);
- db(0x13); db(0xa0); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
+ db(0x13); db(0x56); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
  db(0x01); db(0x98); db(0x41); db(0xe8); db(0x00); db(0x12); db(0x4e); db(0xae);
  db(0xff); db(0x10); db(0x4c); db(0xdf); db(0x4f); db(0x03); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0x7f); db(0x7e); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x60); db(0xf4); db(0x48); db(0xe7); db(0x40); db(0xe2); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x41); db(0xee); db(0x01); db(0x50); db(0x20); db(0x50);
  db(0x4a); db(0x90); db(0x67); db(0x1a); db(0x22); db(0x68); db(0x00); db(0x0a);
- db(0x45); db(0xfa); db(0x12); db(0xf2); db(0x10); db(0x19); db(0x12); db(0x1a);
+ db(0x45); db(0xfa); db(0x12); db(0xa8); db(0x10); db(0x19); db(0x12); db(0x1a);
  db(0xb0); db(0x01); db(0x66); db(0x06); db(0x4a); db(0x00); db(0x67); db(0x42);
  db(0x60); db(0xf2); db(0x20); db(0x50); db(0x60); db(0xe2); db(0x70); db(0x20);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
  db(0xff); db(0x3a); db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x08);
- db(0x00); db(0x08); db(0x41); db(0xfa); db(0x12); db(0xc8); db(0x25); db(0x48);
- db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x12); db(0x44); db(0x25); db(0x48);
+ db(0x00); db(0x08); db(0x41); db(0xfa); db(0x12); db(0x7e); db(0x25); db(0x48);
+ db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x11); db(0xfa); db(0x25); db(0x48);
  db(0x00); db(0x0e); db(0x41); db(0xea); db(0x00); db(0x12); db(0x20); db(0x88);
  db(0x58); db(0x90); db(0x21); db(0x48); db(0x00); db(0x08); db(0x41); db(0xee);
  db(0x01); db(0x50); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xff); db(0x0a);
  db(0x30); db(0x3c); db(0xff); db(0x28); db(0x61); db(0x00); db(0x04); db(0x42);
  db(0x22); db(0x48); db(0x20); db(0x5f); db(0x42); db(0xa8); db(0x01); db(0x90);
  db(0x42); db(0xa8); db(0x01); db(0x94); db(0x4e); db(0x91); db(0x26); db(0x00);
- db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf9); db(0x6e);
+ db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf9); db(0x76);
  db(0x20); db(0x28); db(0x01); db(0x90); db(0x67); db(0x14); db(0x6b); db(0x12);
  db(0x2f); db(0x08); db(0x72); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x5f); db(0x21); db(0x40);
  db(0x22); db(0x69); db(0x01); db(0x94); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4c); db(0xdf); db(0x03); db(0x01);
  db(0x4a); db(0x80); db(0x67); db(0x04); db(0x61); db(0x00); db(0xfa); db(0x7c);
- db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf8); db(0xe8); db(0x30); db(0x3c);
+ db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf8); db(0xf0); db(0x30); db(0x3c);
  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(0xb8); db(0x20); db(0x08);
+ db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x30); db(0x20); db(0x08);
  db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x70); db(0xff);
  db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07); db(0x00); db(0x00);
  db(0x67); db(0x3a); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14);
  db(0x67); db(0x3a); db(0x20); db(0x52); db(0x24); db(0x40); db(0x22); db(0x4a);
  db(0x12); db(0xd8); db(0x66); db(0xfc); db(0x13); db(0x7c); db(0x00); db(0x3a);
  db(0xff); db(0xff); db(0x42); db(0x11); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x43); db(0xfa); db(0x0d); db(0xc1); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0d); db(0x77); db(0x70); db(0x00); db(0x4e); db(0xae);
  db(0xfd); db(0xd8); db(0x2c); db(0x40); db(0x22); db(0x0a); db(0x4e); db(0xae);
  db(0xff); db(0x52); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4a); db(0x20); db(0x02);
  db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x01); db(0x7e); db(0x06);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0xbc);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0x72);
  db(0x70); db(0x24); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
  db(0x66); db(0x0e); db(0x08); db(0x87); db(0x00); db(0x02); db(0x43); db(0xfa);
- db(0x0d); db(0xaa); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x0d); db(0x60); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
  db(0x28); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x2c);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
  db(0xff); db(0x3a); db(0x20); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x2c);
  db(0xfe); db(0x62); db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x93); db(0xc9); db(0x4e); db(0xae);
  db(0xfe); db(0xda); db(0x20); db(0x40); db(0x4b); db(0xe8); db(0x00); db(0x5c);
- db(0x43); db(0xfa); db(0x0d); db(0x11); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0c); db(0xc7); db(0x70); db(0x00); db(0x4e); db(0xae);
  db(0xfd); db(0xd8); db(0x24); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00);
  db(0x00); db(0xb9); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7c); db(0x00);
  db(0x26); db(0x86); db(0x27); db(0x46); db(0x00); db(0x04); db(0x27); db(0x46);
  db(0x00); db(0x08); db(0x27); db(0x4a); db(0x00); db(0xa0); db(0x50); db(0xeb);
  db(0x00); db(0x9e); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0c); db(0x08);
+ db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0b); db(0xbe);
  db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x84);
- db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0c); db(0x05);
+ db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0b); db(0xbb);
  db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x74);
  db(0x27); db(0x40); db(0x00); db(0xa8); db(0x7a); db(0x00); db(0x20); db(0x4d);
  db(0x4e); db(0xae); db(0xfe); db(0x80); db(0x20); db(0x4d); db(0x4e); db(0xae);
  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(0xf4); db(0x2a); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0x41); db(0xfa); db(0xf3); db(0xa2); 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);
  db(0x25); db(0x4b); db(0x00); db(0x36); db(0x22); db(0x4a); db(0x24); db(0x43);
  db(0x97); db(0xcb); db(0x24); db(0x09); db(0x4e); db(0xae); db(0xfe); db(0xe6);
  db(0x20); db(0x02); db(0x4c); db(0xdf); db(0x4c); db(0x1c); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0x09); db(0x65); db(0x43); db(0xfa); db(0x01); db(0x5c);
+ db(0x41); db(0xfa); db(0x09); db(0x1b); db(0x43); db(0xfa); db(0x01); db(0x5c);
  db(0x70); db(0x13); db(0x61); db(0x00); db(0xff); db(0x98); db(0x4e); db(0x75);
  db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x33); db(0x7c); db(0x00); db(0x0a);
  db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e);
  db(0x00); db(0x08); db(0x27); db(0x46); db(0x00); db(0x0c); db(0x70); db(0xff);
  db(0x37); db(0x40); db(0x00); db(0x00); db(0x43); db(0xed); db(0x00); db(0x00);
  db(0x13); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08); db(0x13); db(0x7c);
- db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x07); db(0xa9);
+ db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x07); db(0x5f);
  db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x02); db(0xda);
  db(0x23); db(0x48); db(0x00); db(0x12); db(0x23); db(0x4d); db(0x00); db(0x0e);
  db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x20); db(0x06);
  db(0x00); db(0x1c); db(0x6a); db(0x06); db(0x70); db(0x0a); db(0x27); db(0x40);
  db(0x00); db(0x1c); db(0x4a); db(0xab); db(0x00); db(0x14); db(0x66); db(0x16);
  db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xe0); db(0x43); db(0xfa);
- db(0x07); db(0xc7); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x07); db(0x7d); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
  db(0x27); db(0x40); db(0x00); db(0x14); db(0x67); db(0xd0); db(0x4a); db(0xab);
  db(0x00); db(0x18); db(0x66); db(0x18); db(0x4a); db(0xab); db(0x00); db(0x1c);
- db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0xbd); db(0x70); db(0x00);
+ db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0x73); db(0x70); db(0x00);
  db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x18);
  db(0x67); db(0x00); db(0xff); db(0xb4); db(0x4a); db(0xad); db(0x02); db(0x08);
  db(0x66); db(0x38); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xa6);
  db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0xac); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x43); db(0xfa); db(0x06); db(0x62); db(0x4e); db(0xae); db(0xfe); db(0xec);
  db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0x9a); db(0x70); db(0x00);
+ db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0x50); db(0x70); db(0x00);
  db(0x72); db(0x00); db(0x61); db(0x00); db(0xfd); db(0x16); db(0x2b); db(0x40);
  db(0x02); db(0x08); db(0x67); db(0x00); db(0x02); db(0x42); db(0x60); db(0x00);
  db(0xff); db(0x76); db(0x4a); db(0xad); db(0x02); db(0x0c); db(0x66); db(0x48);
  db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x00); db(0xff); db(0x68);
  db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0x79); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x43); db(0xfa); db(0x06); db(0x2f); db(0x4e); db(0xae); db(0xfe); db(0xec);
  db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa); db(0x06); db(0x65);
+ db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa); db(0x06); db(0x1b);
  db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0xfc); db(0xd4);
  db(0x2b); db(0x40); db(0x02); db(0x0c); db(0x67); db(0x00); db(0x02); db(0x00);
  db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x00); db(0x61); db(0x00);
  db(0x33); db(0x7c); db(0x00); db(0x32); db(0x00); db(0x46); db(0x30); db(0x3c);
  db(0xff); db(0x38); db(0x72); db(0x02); db(0x61); db(0x00); db(0xf9); db(0xea);
  db(0x4e); db(0x90); db(0x41); db(0xf9); db(0x00); db(0xdf); db(0xf0); db(0x00);
- db(0x70); db(0x00); db(0x4e); db(0x75); db(0x41); db(0xfa); db(0x04); db(0x63);
- db(0x43); db(0xfa); db(0x00); db(0x0a); db(0x70); db(0xf6); db(0x61); db(0x00);
- db(0xfa); db(0xac); db(0x4e); db(0x75); db(0x9b); db(0xcd); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88);
- 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(0x00); db(0x00); db(0x7a);
- db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08);
+ db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x06);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x00); db(0x88); 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(0x00);
+ db(0x00); db(0x40); db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14);
  db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0e); db(0x61); db(0x00);
- db(0xf9); db(0x98); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x78); db(0x00);
- db(0x7a); db(0x00); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x4e); db(0xae); db(0xff); db(0x7c);
- db(0x4a); db(0x84); db(0x66); db(0x10); db(0x41); db(0xee); db(0x01); db(0x7a);
- db(0x43); db(0xfa); db(0x04); db(0x61); db(0x4e); db(0xae); db(0xfe); db(0xec);
- db(0x28); db(0x00); db(0x60); db(0x02); db(0x7a); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x76); db(0x4a); db(0x85); db(0x67); db(0xd4); db(0x42); db(0xad);
- db(0x00); db(0x08); db(0x41); db(0xfa); db(0x03); db(0xe5); db(0x43); db(0xfa);
- db(0x01); db(0x10); db(0x70); db(0xf6); db(0x22); db(0x3c); db(0x00); db(0x00);
- db(0x27); db(0x10); db(0x61); db(0x00); db(0xee); db(0x92); db(0x70); db(0x00);
+ db(0xf9); db(0xb0); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x41); db(0xfa);
+ db(0x03); db(0xe7); db(0x43); db(0xfa); db(0x01); db(0x14); db(0x70); db(0xf6);
+ db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10); db(0x61); db(0x00);
+ db(0xee); db(0xe6); db(0x70); db(0x00); db(0x4c); db(0xdf); db(0x60); db(0x00);
  db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0a);
- db(0x61); db(0x00); db(0xf9); db(0x3e); db(0x4e); db(0x90); db(0x4e); db(0x75);
+ db(0x61); db(0x00); db(0xf9); db(0x86); db(0x4e); db(0x90); db(0x4e); db(0x75);
  db(0x61); db(0xf0); db(0x20); db(0x0d); db(0x67); db(0x1c); db(0x2c); db(0x6d);
  db(0x00); db(0x14); db(0x20); db(0x2d); db(0x00); db(0x18); db(0x67); db(0x06);
  db(0x22); db(0x40); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4d);
  db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88); db(0x4e); db(0xae);
  db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
  db(0x38); db(0x3e); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x41); db(0xfa);
- db(0x03); db(0x77); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
+ db(0x03); db(0x75); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
  db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x28); db(0x00);
  db(0x67); db(0x4c); db(0x45); db(0xed); db(0x00); db(0x68); db(0x42); db(0x92);
  db(0x34); db(0xaa); db(0x00); db(0x02); db(0x24); db(0x0a); db(0x54); db(0x82);
  db(0x76); db(0x20); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
  db(0xb6); db(0x80); db(0x66); db(0x12); db(0x4a); db(0x6a); db(0x00); db(0x10);
  db(0x66); db(0xc4); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x10);
- db(0x61); db(0x00); db(0xf8); db(0xae); db(0x4e); db(0x90); db(0x22); db(0x04);
+ db(0x61); db(0x00); db(0xf8); db(0xf6); db(0x4e); db(0x90); db(0x22); db(0x04);
  db(0x67); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x4c); db(0xdf);
  db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x6d); db(0x00); db(0x18);
- db(0x41); db(0xfa); db(0x02); db(0xef); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x41); db(0xfa); db(0x02); db(0xed); db(0x22); db(0x08); db(0x74); db(0xfe);
  db(0x4e); db(0xae); db(0xff); db(0xac); db(0x22); db(0x00); db(0x67); db(0x34);
  db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
  db(0x45); db(0xed); db(0x00); db(0x38); db(0x70); db(0xff); db(0x4e); db(0xae);
  db(0xfe); db(0xb6); db(0x15); db(0x40); db(0x00); db(0x14); db(0x41); db(0xfa);
- db(0x02); db(0xdf); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
+ db(0x02); db(0xdd); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
  db(0x00); db(0x12); db(0x00); db(0x0c); db(0x25); db(0x6d); db(0x00); db(0x08);
  db(0x00); db(0x10); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x22); db(0x0a);
  db(0x4e); db(0xae); db(0xfc); db(0x88); db(0x2c); db(0x6d); db(0x00); db(0x14);
  db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x3c); db(0x4e); db(0x90);
+ db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x84); db(0x4e); db(0x90);
  db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xfc); db(0x2a); db(0x40);
  db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x93); db(0xc9); db(0x4e); db(0xae);
  db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08); db(0x43); db(0xfa);
- db(0x03); db(0x0b); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x2b); db(0x40); db(0x00); db(0x18); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0xfe); db(0xd8); db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x02); db(0x41); db(0x22); db(0x08);
- db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80);
- db(0x67); db(0xea); db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6);
- db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa);
- db(0x02); db(0x2b); db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae);
- db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa2);
- db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d);
- db(0x00); db(0x14); db(0x61); db(0x00); db(0xf7); db(0xe8); db(0x72); db(0x00);
- db(0x32); db(0x3c); db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x2c);
- db(0x28); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x82);
- db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae);
- db(0xfe); db(0xc2); db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c);
- db(0x41); db(0xfa); db(0x02); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae);
- db(0xfe); db(0x44); db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c);
- db(0x00); db(0x14); db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14);
- db(0x64); db(0x0c); db(0x61); db(0x00); db(0xfe); db(0x46); db(0x70); db(0x00);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0x7a);
- db(0x4e); db(0x90); db(0x61); db(0x00); db(0xfe); db(0xd8); db(0x41); db(0xed);
- db(0x00); db(0x1c); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01);
- db(0x29); db(0x40); db(0x00); db(0x24); db(0x39); db(0x7c); db(0x00); db(0x0c);
- db(0x00); db(0x1c); db(0x2b); db(0x4d); db(0x00); db(0x2c); db(0x41); db(0xfa);
- db(0x01); db(0x4a); db(0x2b); db(0x48); db(0x00); db(0x24); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x70); db(0x00); db(0x74); db(0x00);
- db(0x14); db(0x2d); db(0x00); db(0x4c); db(0x05); db(0xc0); db(0x08); db(0xc0);
- db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x05); db(0x00);
- db(0x67); db(0x06); db(0x61); db(0x00); db(0xfe); db(0x22); db(0x60); db(0xe4);
- db(0x20); db(0x2d); db(0x00); db(0x00); db(0x67); db(0x00); db(0x00); db(0x72);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2b); db(0x40);
- db(0x00); db(0x04); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0c);
- db(0x61); db(0x00); db(0xf7); db(0x16); db(0x4e); db(0x90); db(0x4a); db(0xad);
- db(0x00); db(0x04); db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03);
- db(0x00); db(0x1c); db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac);
- db(0x00); db(0x20); db(0x29); db(0x6d); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x29); db(0x6d); db(0x00); db(0x04); db(0x00); db(0x28); db(0x42); db(0xac);
- db(0x00); db(0x2c); db(0x42); db(0xac); db(0x00); db(0x30); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x2b); db(0x6c); db(0x00); db(0x30);
- db(0x00); db(0x10); db(0x39); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x1c);
- db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x20); db(0x2d);
- db(0x00); db(0x00); db(0x42); db(0xad); db(0x00); db(0x00); db(0x22); db(0x2d);
- db(0x00); db(0x04); db(0x67); db(0x00); db(0xff); db(0x78); db(0x22); db(0x41);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x6e);
- db(0x39); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x1c); db(0x41); db(0xed);
- db(0x00); db(0x30); db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04);
- db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x2c);
- db(0x42); db(0xac); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
- db(0x70); db(0x08); db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x0c); db(0xad); db(0x46); db(0x4f);
- db(0x52); db(0x4d); db(0x00); db(0x30); db(0x66); db(0x52); db(0x20); db(0x2d);
- db(0x00); db(0x34); db(0x67); db(0x4c); db(0x6b); db(0x4a); db(0x2b); db(0x6c);
- db(0x00); db(0x30); db(0x00); db(0x10); db(0x50); db(0x80); db(0x24); db(0x00);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
- db(0x67); db(0x36); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x20); db(0xed);
- db(0x00); db(0x30); db(0x20); db(0xed); db(0x00); db(0x34); db(0x29); db(0x48);
- db(0x00); db(0x28); db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40);
- db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00);
- db(0xf6); db(0x40); db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90);
- db(0x22); db(0x4a); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e);
- db(0x4a); db(0xac); db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xde);
- db(0x41); db(0xed); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
- db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x24); db(0x42); db(0xac);
- db(0x00); db(0x20); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x60); db(0xde); db(0x41); db(0xe8); db(0xff); db(0xe4); db(0x20); db(0x29);
- db(0x00); db(0x08); db(0xb0); db(0xa8); db(0x00); db(0x10); db(0x67); db(0x1a);
- db(0x21); db(0x40); db(0x00); db(0x10); db(0x2f); db(0x0e); db(0x2c); db(0x68);
- db(0x00); db(0x14); db(0x22); db(0x68); db(0x00); db(0x08); db(0x70); db(0x00);
- db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc);
- db(0x2c); db(0x5f); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x69); db(0x6e);
- db(0x70); db(0x75); db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69);
- db(0x63); db(0x65); db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72);
- db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00);
- db(0x44); db(0x45); db(0x56); db(0x53); db(0x00); db(0x44); db(0x45); db(0x56);
- db(0x53); db(0x3a); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a);
- db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72);
- db(0x64); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
- db(0x00); db(0x52); db(0x41); db(0x4d); db(0x3a); db(0x00); db(0x63); db(0x6c);
+ db(0x03); db(0x09); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x2b); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xfe); db(0xda);
+ db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a);
+ db(0x41); db(0xfa); db(0x02); db(0x41); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0xea);
+ db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x72); db(0x32);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x02); db(0x2b);
+ db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa4); db(0x22); db(0x00);
+ db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x61); db(0x00); db(0xf8); db(0x32); db(0x72); db(0x00); db(0x32); db(0x3c);
+ db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x76); db(0x28); db(0x40);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x84); db(0x70); db(0x00);
+ db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
+ db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c); db(0x41); db(0xfa);
+ db(0x02); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x44);
+ db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c); db(0x00); db(0x14);
+ db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14); db(0x64); db(0x0c);
+ db(0x61); db(0x00); db(0xfe); db(0x48); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0xc4); db(0x4e); db(0x90);
+ db(0x61); db(0x00); db(0xfe); db(0xda); db(0x41); db(0xed); db(0x00); db(0x1c);
+ db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01); db(0x29); db(0x40);
+ db(0x00); db(0x24); db(0x39); db(0x7c); db(0x00); db(0x0c); db(0x00); db(0x1c);
+ db(0x2b); db(0x4d); db(0x00); db(0x2c); db(0x41); db(0xfa); db(0x01); db(0x4a);
+ db(0x2b); db(0x48); db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x70); db(0x00); db(0x74); db(0x00); db(0x14); db(0x2d);
+ db(0x00); db(0x4c); db(0x05); db(0xc0); db(0x08); db(0xc0); db(0x00); db(0x0d);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x05); db(0x00); db(0x67); db(0x06);
+ db(0x61); db(0x00); db(0xfe); db(0x24); db(0x60); db(0xe4); db(0x20); db(0x2d);
+ db(0x00); db(0x00); db(0x67); db(0x00); db(0x00); db(0x72); db(0x72); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2b); db(0x40); db(0x00); db(0x04);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0c); db(0x61); db(0x00);
+ db(0xf7); db(0x60); db(0x4e); db(0x90); db(0x4a); db(0xad); db(0x00); db(0x04);
+ db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03); db(0x00); db(0x1c);
+ db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x20);
+ db(0x29); db(0x6d); db(0x00); db(0x00); db(0x00); db(0x24); db(0x29); db(0x6d);
+ db(0x00); db(0x04); db(0x00); db(0x28); db(0x42); db(0xac); db(0x00); db(0x2c);
+ db(0x42); db(0xac); db(0x00); db(0x30); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x2b); db(0x6c); db(0x00); db(0x30); db(0x00); db(0x10);
+ db(0x39); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x1c); db(0x22); db(0x4c);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x20); db(0x2d); db(0x00); db(0x00);
+ db(0x42); db(0xad); db(0x00); db(0x00); db(0x22); db(0x2d); db(0x00); db(0x04);
+ db(0x67); db(0x00); db(0xff); db(0x78); db(0x22); db(0x41); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x6e); db(0x39); db(0x7c);
+ db(0x00); db(0x02); db(0x00); db(0x1c); db(0x41); db(0xed); db(0x00); db(0x30);
+ db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x42); db(0x2c);
+ db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x2c); db(0x42); db(0xac);
+ db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x08);
+ db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x0c); db(0xad); db(0x46); db(0x4f); db(0x52); db(0x4d);
+ db(0x00); db(0x30); db(0x66); db(0x52); db(0x20); db(0x2d); db(0x00); db(0x34);
+ db(0x67); db(0x4c); db(0x6b); db(0x4a); db(0x2b); db(0x6c); db(0x00); db(0x30);
+ db(0x00); db(0x10); db(0x50); db(0x80); db(0x24); db(0x00); db(0x72); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x36);
+ db(0x24); db(0x40); db(0x20); db(0x4a); db(0x20); db(0xed); db(0x00); db(0x30);
+ db(0x20); db(0xed); db(0x00); db(0x34); db(0x29); db(0x48); db(0x00); db(0x28);
+ db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40); db(0x00); db(0x24);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00); db(0xf6); db(0x8a);
+ db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90); db(0x22); db(0x4a);
+ db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4a); db(0xac);
+ db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xde); db(0x41); db(0xed);
+ db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01);
+ db(0x29); db(0x40); db(0x00); db(0x24); db(0x42); db(0xac); db(0x00); db(0x20);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x60); db(0xde);
+ db(0x41); db(0xe8); db(0xff); db(0xe4); db(0x20); db(0x29); db(0x00); db(0x08);
+ db(0xb0); db(0xa8); db(0x00); db(0x10); db(0x67); db(0x1a); db(0x21); db(0x40);
+ db(0x00); db(0x10); db(0x2f); db(0x0e); db(0x2c); db(0x68); db(0x00); db(0x14);
+ db(0x22); db(0x68); db(0x00); db(0x08); db(0x70); db(0x00); db(0x08); db(0xc0);
+ db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x2c); db(0x5f);
+ db(0x70); db(0x00); db(0x4e); db(0x75); db(0x69); db(0x6e); db(0x70); db(0x75);
+ db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
+ db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72); db(0x2e); db(0x64);
+ db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x44); db(0x45);
+ db(0x56); db(0x53); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a);
+ db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a); db(0x63); db(0x6c);
  db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x2e);
  db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x52);
- db(0x41); db(0x4d); db(0x3a); db(0x45); db(0x6e); db(0x76); db(0x2f); db(0x53);
- db(0x79); db(0x73); db(0x2f); db(0x50); db(0x6f); db(0x69); db(0x6e); db(0x74);
- db(0x65); db(0x72); db(0x2e); db(0x70); db(0x72); db(0x65); db(0x66); db(0x73);
- db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x63); db(0x6c); db(0x69);
- db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x20); db(0x73);
- db(0x68); db(0x61); db(0x72); db(0x69); db(0x6e); db(0x67); db(0x00); db(0x55);
- db(0x41); db(0x45); db(0x20); db(0x6d); db(0x6f); db(0x75); db(0x73); db(0x65);
- db(0x20); db(0x64); db(0x72); db(0x69); db(0x76); db(0x65); db(0x72); db(0x00);
- db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x69); db(0x6c); db(0x65);
- db(0x73); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x55);
- db(0x41); db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75);
- db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x65);
- db(0x72); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73);
- db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75);
- db(0x6e); db(0x74); db(0x20); db(0x70); db(0x72); db(0x6f); db(0x63); db(0x65);
- db(0x73); db(0x73); db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e); db(0x6c);
- db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x69);
- db(0x6e); db(0x74); db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f); db(0x6e);
- db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79);
- db(0x00); db(0x67); db(0x72); db(0x61); db(0x70); db(0x68); db(0x69); db(0x63);
- db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
- db(0x79); db(0x00); db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); db(0x73);
- db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72);
- db(0x61); db(0x72); db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65);
- db(0x53); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e); db(0x72);
- db(0x65); db(0x73); db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65); db(0x00);
+ db(0x41); db(0x4d); db(0x3a); db(0x00); db(0x63); db(0x6c); db(0x69); db(0x70);
+ db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x2e); db(0x64); db(0x65);
+ db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x52); db(0x41); db(0x4d);
+ db(0x3a); db(0x45); db(0x6e); db(0x76); db(0x2f); db(0x53); db(0x79); db(0x73);
+ db(0x2f); db(0x50); db(0x6f); db(0x69); db(0x6e); db(0x74); db(0x65); db(0x72);
+ db(0x2e); db(0x70); db(0x72); db(0x65); db(0x66); db(0x73); db(0x00); db(0x55);
+ db(0x41); db(0x45); db(0x20); db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62);
+ db(0x6f); db(0x61); db(0x72); db(0x64); db(0x20); db(0x73); db(0x68); db(0x61);
+ db(0x72); db(0x69); db(0x6e); db(0x67); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x6d); db(0x6f); db(0x75); db(0x73); db(0x65); db(0x20); db(0x64);
+ db(0x72); db(0x69); db(0x76); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x66); db(0x69); db(0x6c); db(0x65); db(0x73); db(0x79);
+ db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f);
+ db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x65); db(0x72); db(0x00);
+ db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x61);
+ db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74);
+ db(0x20); db(0x70); db(0x72); db(0x6f); db(0x63); db(0x65); db(0x73); db(0x73);
+ db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62);
+ db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x69); db(0x6e); db(0x74);
+ db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c);
+ db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x67);
+ db(0x72); db(0x61); db(0x70); db(0x68); db(0x69); db(0x63); db(0x73); db(0x2e);
+ db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00);
+ db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); db(0x73); db(0x69); db(0x6f);
+ db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
+ db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65); db(0x53); db(0x79);
+ db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e); db(0x72); db(0x65); db(0x73);
+ db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x00); db(0x03); db(0xf2);
 
index 774edc109a2487803aae9d60041e4fb49d0ea206..b980c7b161a1e2a38690399f196a947a62c9be41 100644 (file)
@@ -453,7 +453,7 @@ int vhd_create (const TCHAR *name, uae_u64 size)
     batsize &= ~511;
     ret = 0;
     b = NULL;
-    zf = zfile_fopen (name, L"wb");
+    zf = zfile_fopen (name, L"wb", 0);
     if (!zf)
        goto end;
     b = xcalloc (512 + 1024 + batsize + 512, 1);
index ffc8043212c50f9fd20d65186542755d4d63c97b..f979f7be0dc7fa62d39c21285655db5581360f91 100644 (file)
@@ -15,6 +15,7 @@ extern void dw (uae_u16);
 extern void dl (uae_u32);
 extern uae_u32 ds_ansi (const uae_char*);
 extern uae_u32 ds (const TCHAR*);
+extern uae_u8 dbg (uaecptr);
 extern void calltrap (uae_u32);
 extern void org (uae_u32);
 extern uae_u32 here (void);
diff --git a/include/diskutil.h b/include/diskutil.h
new file mode 100644 (file)
index 0000000..48daf0e
--- /dev/null
@@ -0,0 +1,2 @@
+
+int isamigatrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track);
index 91dcd6cc79996d0ec6398459f9bb1db4274d34b6..f81994be3c7c2b91d10dd05b8690ffc694721f63 100644 (file)
@@ -131,6 +131,7 @@ extern int my_rmdir (const TCHAR*);
 extern int my_mkdir (const TCHAR*);
 extern int my_unlink (const TCHAR*);
 extern int my_rename (const TCHAR*, const TCHAR*);
+extern int my_setcurrentdir (const TCHAR *curdir, TCHAR *oldcur);
 
 extern void *my_open (const TCHAR*, int);
 extern void my_close (void*);
index 25c8a143d2a3f8c886769db40782c52e41bcdec7..a9fe26a18bc7441b1672098f52ac0435d6f9fc38 100644 (file)
@@ -2,6 +2,7 @@
 struct zfile {
     TCHAR *name;
     TCHAR *zipname;
+    TCHAR *mode;
     FILE *f;
     uae_u8 *data;
     uae_u64 size;
@@ -9,10 +10,14 @@ struct zfile {
     int deleteafterclose;
     int textmode;
     struct zfile *next;
+    int zfdmask;
 };
 
+#define ZNODE_FILE 0
+#define ZNODE_DIR 1
+#define ZNODE_VDIR -1
 struct znode {
-    int isfile;
+    int type;
     struct znode *sibling;
     struct znode *child;
     struct zvolume *vchild;
@@ -42,12 +47,15 @@ struct zvolume
     struct znode root;
     struct zvolume *next;
     struct znode *last;
+    struct znode *parentz;
     struct zvolume *parent;
     uae_u64 size;
     unsigned int blocks;
     unsigned int id;
     uae_u64 archivesize;
     unsigned int method;
+    TCHAR *volumename;
+    int zfdmask;
 };
 
 struct zarchive_info
@@ -66,17 +74,19 @@ struct zarchive_info
 #define ArchiveFormatLZX 'lzx '
 #define ArchiveFormatPLAIN '----'
 #define ArchiveFormatAA 'aa  ' // method only
+#define ArchiveFormatADF 'DOS '
+#define ArchiveFormatRDB 'RDSK'
 
 extern int zfile_is_ignore_ext(const TCHAR *name);
 
-extern struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle);
-extern struct zvolume *zvolume_alloc_empty(const TCHAR *name);
+extern struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle, const TCHAR*);
+extern struct zvolume *zvolume_alloc_empty(struct zvolume *zv, const TCHAR *name);
 
 extern struct znode *zvolume_addfile_abs(struct zvolume *zv, struct zarchive_info*);
 extern struct znode *zvolume_adddir_abs(struct zvolume *zv, struct zarchive_info *zai);
 extern struct znode *znode_adddir(struct znode *parent, const TCHAR *name, struct zarchive_info*);
 
-extern struct zvolume *archive_directory_plain(struct zfile *zf);
+extern struct zvolume *archive_directory_plain (struct zfile *zf);
 extern struct zfile *archive_access_plain (struct znode *zn);
 extern struct zvolume *archive_directory_lha(struct zfile *zf);
 extern struct zfile *archive_access_lha (struct znode *zn);
@@ -90,6 +100,10 @@ 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 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_arcacc_select (struct zfile *zf, unsigned int id);
index 32351922dd6a6bea3b044598e783db04c3cf2583..7fbe378f057d25df3b0e995bc76ea537ebdce23b 100644 (file)
@@ -11,9 +11,8 @@ struct zvolume;
 
 typedef int (*zfile_callback)(struct zfile*, void*);
 
-extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *);
-extern struct zfile *zfile_fopen_nozip (const TCHAR *, const TCHAR *);
-extern struct zfile *zfile_fopen_empty (const TCHAR *name, uae_u64 size);
+extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask);
+extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name, uae_u64 size);
 extern struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data);
 extern int zfile_exists (const TCHAR *name);
 extern void zfile_fclose (struct zfile *);
@@ -36,12 +35,25 @@ extern int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int src
 extern int zfile_gettype (struct zfile *z);
 extern int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user);
 extern TCHAR *zfile_getname (struct zfile *f);
+extern TCHAR *zfile_getfilename (struct zfile *f);
 extern uae_u32 zfile_crc32 (struct zfile *f);
 extern struct zfile *zfile_dup (struct zfile *f);
 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 void zfile_seterror (const TCHAR *format, ...);
+extern TCHAR *zfile_geterror (void);
+
+#define ZFD_NONE 0
+#define ZFD_ARCHIVE 1 //zip/lha..
+#define ZFD_ADF 2 //adf as a filesystem
+#define ZFD_HD 4 //rdb/hdf
+#define ZFD_UNPACK 8 //gzip,dms
+#define ZFD_RAWDISK 16  //fdi->adf,ipf->adf etc..
+#define ZFD_NORMAL (ZFD_ARCHIVE|ZFD_UNPACK)
+#define ZFD_ALL -1
 
 #define ZFILE_UNKNOWN 0
 #define ZFILE_CONFIGURATION 1
@@ -57,14 +69,16 @@ extern const TCHAR *uae_archive_extensions[];
 extern const TCHAR *uae_ignoreextensions[];
 extern const TCHAR *uae_diskimageextensions[];
 
-extern struct zvolume *zfile_fopen_archive(const TCHAR *filename);
-extern void zfile_fclose_archive(struct zvolume *zv);
-extern int zfile_fs_usage_archive(const TCHAR *path, const TCHAR *disk, struct fs_usage *fsp);
-extern int zfile_stat_archive(const TCHAR *path, struct _stat64 *statbuf);
-extern void *zfile_opendir_archive(const TCHAR *path);
-extern void zfile_closedir_archive(void*);
-extern int zfile_readdir_archive(void*, TCHAR*);
-extern zfile_fill_file_attrs_archive(const TCHAR *path, int *isdir, int *flags, TCHAR **comment);
+extern struct zvolume *zfile_fopen_archive (const TCHAR *filename);
+extern struct zvolume *zfile_fopen_archive_root (const TCHAR *filename);
+extern void zfile_fclose_archive (struct zvolume *zv);
+extern int zfile_fs_usage_archive (const TCHAR *path, const TCHAR *disk, struct fs_usage *fsp);
+extern int zfile_stat_archive (const TCHAR *path, struct _stat64 *statbuf);
+extern void *zfile_opendir_archive (const TCHAR *path);
+extern void zfile_closedir_archive (void*);
+extern int zfile_readdir_archive (void*, TCHAR*);
+extern void zfile_resetdir_archive (void*);
+extern zfile_fill_file_attrs_archive (const TCHAR *path, int *isdir, int *flags, TCHAR **comment);
 extern uae_s64 zfile_lseek_archive (void *d, uae_s64 offset, int whence);
 extern unsigned int zfile_read_archive (void *d, void *b, unsigned int size);
 extern void zfile_close_archive (void *d);
index b1db645e5e20de55dabd232ad86e37ab617f0705..c3ef007760eca5e41ff3762fe740807d11849eac 100644 (file)
@@ -47,6 +47,8 @@
 #include "autoconf.h"
 #include "rp.h"
 
+extern int bootrom_header, bootrom_items;
+
 // 01 = host events
 // 02 = joystick
 // 04 = cia buttons
@@ -143,7 +145,7 @@ int inprec_open (TCHAR *fname, int record)
     int i;
 
     inprec_close();
-    inprec_zf = zfile_fopen (fname, record > 0 ? L"wb" : L"rb");
+    inprec_zf = zfile_fopen (fname, record > 0 ? L"wb" : L"rb", ZFD_NORMAL);
     if (inprec_zf == NULL)
        return 0;
     inprec_size = 10000;
@@ -959,6 +961,13 @@ int inputdevice_is_tablet (void)
     return v ? 1 : 0;
 }
 
+static int getmhoffset (void)
+{
+    if (!uae_boot_rom)
+       return 0;
+    return get_long (rtarea_base + bootrom_header + 7 * 4) + bootrom_header;
+}
+
 static void mousehack_reset (void)
 {
     int off;
@@ -969,10 +978,9 @@ static void mousehack_reset (void)
     mousehack_alive_cnt = 0;
     vp_xoffset = vp_yoffset = 0;
     tablet_data = 0;
-    if (!uae_boot_rom)
-       return;
-    off = 12 + get_long (rtarea_base + 36);
-    rtarea[off + MH_E] = 0;
+    off = getmhoffset ();
+    if (off)
+       rtarea[off + MH_E] = 0;
 }
 
 static void mousehack_enable (void)
@@ -981,7 +989,7 @@ static void mousehack_enable (void)
 
     if (!uae_boot_rom || currprefs.input_tablet == TABLET_OFF)
        return;
-    off = 12 + get_long (rtarea_base + 36);
+    off = getmhoffset ();
     if (rtarea[off + MH_E])
        return;
     mode = 0x80;
@@ -1002,9 +1010,9 @@ void input_mousehack_mouseoffset (uaecptr pointerprefs)
 void input_mousehack_status (int mode, uaecptr diminfo, uaecptr dispinfo, uaecptr vp, uae_u32 moffset)
 {
     if (mode == 0) {
-       uae_u8 v = rtarea[12 + get_long (rtarea_base + 36)];
+       uae_u8 v = rtarea[getmhoffset ()];
        v |= 0x40;
-       rtarea[12 + get_long (rtarea_base + 36)] = v;
+       rtarea[getmhoffset ()] = v;
        write_log (L"Tablet driver running (%02x)\n", v);
     } else if (mode == 1) {
         int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
@@ -1051,7 +1059,7 @@ void inputdevice_tablet_strobe (void)
        return;
     if (!tablet_data)
        return;
-    off = 12 + get_long (rtarea_base + 36);
+    off = getmhoffset ();
     p = rtarea + off;
     p[MH_CNT]++;
 }
@@ -1066,7 +1074,7 @@ void inputdevice_tablet (int x, int y, int z, int pressure, uae_u32 buttonbits,
     if (inputdevice_is_tablet () <= 0)
        return;
     //write_log (L"%d %d %d %d %08X %d %d %d %d\n", x, y, z, pressure, buttonbits, inproximity, ax, ay, az);
-    off = 12 + get_long (rtarea_base + 36);
+    off = getmhoffset ();
     p = rtarea + off;
 
     memcpy (tmp, p + MH_START, MH_END - MH_START); 
@@ -1156,7 +1164,7 @@ void inputdevice_tablet_info (int maxx, int maxy, int maxz, int maxax, int maxay
 
     if (!uae_boot_rom)
        return;
-    p = rtarea + 12 + get_long (rtarea_base + 36);
+    p = rtarea + getmhoffset ();
 
     tablet_maxx = maxx;
     tablet_maxy = maxy;
@@ -1190,7 +1198,7 @@ static void inputdevice_mh_abs (int x, int y)
     uae_u32 off;
 
     mousehack_enable ();
-    off = 12 + get_long (rtarea_base + 36);
+    off = getmhoffset ();
     p = rtarea + off;
 
     memcpy (tmp, p + MH_ABSX, 4);
@@ -1220,7 +1228,7 @@ static void inputdevice_mh_abs_v36 (int x, int y)
     int fdy, fdx, fmx, fmy;
 
     mousehack_enable ();
-    off = 12 + get_long (rtarea_base + 36);
+    off = getmhoffset ();
     p = rtarea + off;
 
     memcpy (tmp, p + MH_START, MH_END - MH_START); 
index 88e4702d224f2fadababf56b17ccbfc5c33e16df..3c0d3c3e2ef872a2e4f1211ec0cc8f367c591303 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -613,7 +613,7 @@ static void addkeyfile (const TCHAR *path)
     int keysize;
     uae_u8 *keybuf;
 
-    f = zfile_fopen (path, L"rb");
+    f = zfile_fopen (path, L"rb", ZFD_NORMAL);
     if (!f)
        return;
     zfile_fseek (f, 0, SEEK_END);
@@ -2412,7 +2412,7 @@ static int read_rom_file (uae_u8 *buf, struct romdata *rd)
 
     if (!rl || _tcslen (rl->path) == 0)
        return 0;
-    zf = zfile_fopen (rl->path, L"rb");
+    zf = zfile_fopen (rl->path, L"rb", ZFD_NORMAL);
     if (!zf)
        return 0;
     addkeydir (rl->path);
@@ -2466,7 +2466,7 @@ static void mergecd32 (uae_u8 *dst, uae_u8 *src, int size)
 #if 0
     {
        struct zfile *f;
-       f = zfile_fopen ("c:\\d\\1.rom","wb");
+       f = zfile_fopen ("c:\\d\\1.rom","wb", ZFD_NORMAL);
        zfile_fwrite (dst, 1, size, f);
        zfile_fclose(f);
     }
@@ -2575,7 +2575,7 @@ struct zfile *read_rom (struct romdata **prd)
                    ok = 1;
            }
            if (ok) {
-               struct zfile *zf = zfile_fopen_empty (name, size);
+               struct zfile *zf = zfile_fopen_empty (NULL, name, size);
                if (zf) {
                    zfile_fwrite (buf, size, 1, zf);
                    zfile_fseek (zf, 0, SEEK_SET);
@@ -2604,7 +2604,7 @@ struct zfile *read_rom_name (const TCHAR *filename)
                return f;
        }
     }
-    f = zfile_fopen (filename, L"rb");
+    f = zfile_fopen (filename, L"rb", ZFD_NORMAL);
     if (f) {
        uae_u8 tmp[11];
        zfile_fread (tmp, sizeof tmp, 1, f);
@@ -2618,7 +2618,7 @@ struct zfile *read_rom_name (const TCHAR *filename)
            zfile_fseek (f, sizeof tmp, SEEK_SET);
            buf = xmalloc (size);
            zfile_fread (buf, size, 1, f);
-           df = zfile_fopen_empty (L"tmp.rom", size);
+           df = zfile_fopen_empty (f, L"tmp.rom", size);
            decode_cloanto_rom_do (buf, size, size);
            zfile_fwrite (buf, size, 1, df);
            zfile_fclose (f);
@@ -2875,19 +2875,19 @@ static int load_kickstart (void)
     _tcscpy (tmprom, currprefs.romfile);
     if (f == NULL) {
        _stprintf (tmprom2, L"%s%s", start_path_data, currprefs.romfile);
-       f = zfile_fopen (tmprom2, L"rb");
+       f = zfile_fopen (tmprom2, L"rb", ZFD_NORMAL);
        if (f == NULL) {
            _stprintf (currprefs.romfile, L"%sroms/kick.rom", start_path_data);
-           f = zfile_fopen (currprefs.romfile, L"rb");
+           f = zfile_fopen (currprefs.romfile, L"rb", ZFD_NORMAL);
            if (f == NULL) {
                _stprintf (currprefs.romfile, L"%skick.rom", start_path_data);
-               f = zfile_fopen (currprefs.romfile, L"rb");
+               f = zfile_fopen (currprefs.romfile, L"rb", ZFD_NORMAL);
                if (f == NULL) {
                    _stprintf (currprefs.romfile, L"%s../shared/rom/kick.rom", start_path_data);
-                   f = zfile_fopen (currprefs.romfile, L"rb");
+                   f = zfile_fopen (currprefs.romfile, L"rb", ZFD_NORMAL);
                    if (f == NULL) {
                        _stprintf (currprefs.romfile, L"%s../System/rom/kick.rom", start_path_data);
-                       f = zfile_fopen (currprefs.romfile, L"rb");
+                       f = zfile_fopen (currprefs.romfile, L"rb", ZFD_NORMAL);
                    }
                }
            }
index 5df11c63075ede758acf743847c0c22a0d955066..aa34fa4b3e13bf8188be8fda15538fc0f471cc6e 100644 (file)
@@ -182,7 +182,8 @@ int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, i
     struct CapsTrackInfoT1 ci;
 
     ci.type = LIB_TYPE;
-    *tracktiming = 0;
+    if (tracktiming)
+       *tracktiming = 0;
     pCAPSLockTrack ((PCAPSTRACKINFO)&ci, caps_cont[drv], track / 2, track & 1, caps_flags);
     mfm = mfmbuf;
     *multirev = (ci.type & CTIT_FLAG_FLAKEY) ? 1 : 0;
@@ -201,7 +202,7 @@ int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, i
        fclose (f);
     }
 #endif
-    if (ci.timelen > 0) {
+    if (ci.timelen > 0 && tracktiming) {
        for (i = 0; i < ci.timelen; i++)
            tracktiming[i] = (uae_u16)ci.timebuf[i];
     }
diff --git a/od-win32/fsdb_mywin32.c b/od-win32/fsdb_mywin32.c
new file mode 100644 (file)
index 0000000..88fa816
--- /dev/null
@@ -0,0 +1,398 @@
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "options.h"
+#include "memory.h"
+
+#include "fsdb.h"
+#include "win32.h"
+#include <windows.h>
+
+int my_setcurrentdir (const TCHAR *curdir, TCHAR *oldcur)
+{
+    int ret = 0;
+    if (oldcur)
+       ret = GetCurrentDirectory (MAX_DPATH, oldcur);
+    if (curdir)
+       ret = SetCurrentDirectory (curdir);
+    return ret;
+}
+
+int my_mkdir (const TCHAR *name)
+{
+    return CreateDirectory (name, NULL) == 0 ? -1 : 0;
+}
+
+static int recycle (const TCHAR *name)
+{
+    if (currprefs.win32_norecyclebin) {
+       DWORD dirattr = GetFileAttributes (name);
+       if (dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY))
+           return RemoveDirectory (name) ? 0 : -1;
+       return DeleteFile(name) ? 0 : -1;
+    } else {
+       SHFILEOPSTRUCT fos;
+       /* name must be terminated by \0\0 */
+       TCHAR *p = xcalloc ((_tcslen (name) + 2) * sizeof (TCHAR), 1);
+       int v;
+
+       _tcscpy (p, name);
+       memset (&fos, 0, sizeof (fos));
+       fos.wFunc = FO_DELETE;
+       fos.pFrom = p;
+       fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NORECURSION | FOF_SILENT;
+       v = SHFileOperation (&fos);
+       xfree (p);
+       switch (v)
+       {
+           case 0xb7: //DE_ERROR_MAX
+           case 0x7c: //DE_INVALIDFILES
+           case 0x402: // "unknown error"
+           v = ERROR_FILE_NOT_FOUND;
+           break;
+           case 0x75: //DE_OPCANCELLED:
+           case 0x10000: //ERRORONDEST:
+           case 0x78: //DE_ACCESSDENIEDSRC:
+           case 0x74: //DE_ROOTDIR:
+           v = ERROR_ACCESS_DENIED;
+           break;
+       }
+       SetLastError (v);
+       return v ? -1 : 0;
+    }
+}
+
+int my_rmdir (const TCHAR *name)
+{
+    void *od;
+    int cnt;
+    TCHAR tname[MAX_DPATH];
+
+    /* SHFileOperation() ignores FOF_NORECURSION when deleting directories.. */
+    od = my_opendir (name);
+    if (!od) {
+       SetLastError (ERROR_FILE_NOT_FOUND);
+       return -1;
+    }
+    cnt = 0;
+    while (my_readdir (od, tname)) {
+       if (!_tcscmp (tname, L".") || !_tcscmp (tname, L".."))
+           continue;
+       cnt++;
+       break;
+    }
+    my_closedir (od);
+    if (cnt > 0) {
+       SetLastError (ERROR_CURRENT_DIRECTORY);
+       return -1;
+    }
+
+    return recycle (name);
+}
+
+/* "move to Recycle Bin" (if enabled) -version of DeleteFile() */
+int my_unlink (const TCHAR *name)
+{
+    return recycle (name);
+}
+
+int my_rename (const TCHAR *oldname, const TCHAR *newname)
+{
+    return MoveFile (oldname, newname) == 0 ? -1 : 0;
+}
+
+struct my_opendirs {
+    HANDLE *h;
+    WIN32_FIND_DATA fd;
+    int first;
+};
+
+void *my_opendir (const TCHAR *name)
+{
+    struct my_opendirs *mod;
+    TCHAR tmp[MAX_DPATH];
+
+    _tcscpy (tmp, name);
+    _tcscat (tmp, L"\\*.*");
+    mod = xmalloc (sizeof (struct my_opendirs));
+    if (!mod)
+       return NULL;
+    mod->h = FindFirstFile(tmp, &mod->fd);
+    if (mod->h == INVALID_HANDLE_VALUE) {
+       xfree (mod);
+       return NULL;
+    }
+    mod->first = 1;
+    return mod;
+}
+
+void my_closedir (void *d)
+{
+    struct my_opendirs *mod = d;
+    if (d)
+       FindClose (mod->h);
+    xfree (mod);
+}
+
+int my_readdir (void *d, TCHAR *name)
+{
+    struct my_opendirs *mod = d;
+    if (mod->first) {
+       _tcscpy (name, mod->fd.cFileName);
+       mod->first = 0;
+       return 1;
+    }
+    if (!FindNextFile (mod->h, &mod->fd))
+       return 0;
+    _tcscpy (name, mod->fd.cFileName);
+    return 1;
+}
+
+struct my_opens {
+    HANDLE *h;
+};
+
+void my_close (void *d)
+{
+    struct my_opens *mos = d;
+    CloseHandle (mos->h);
+    xfree (mos);
+}
+
+uae_s64 int my_lseek (void *d, uae_s64 int offset, int whence)
+{
+    struct my_opens *mos = d;
+    LARGE_INTEGER li;
+
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer (mos->h, li.LowPart, &li.HighPart,
+       whence == SEEK_SET ? FILE_BEGIN : (whence == SEEK_END ? FILE_END : FILE_CURRENT));
+    if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
+       li.QuadPart = -1;
+    return li.QuadPart;
+}
+
+unsigned int my_read (void *d, void *b, unsigned int size)
+{
+    struct my_opens *mos = d;
+    DWORD read = 0;
+    ReadFile (mos->h, b, size, &read, NULL);
+    return read;
+}
+
+unsigned int my_write (void *d, void *b, unsigned int size)
+{
+    struct my_opens *mos = d;
+    DWORD written = 0;
+    WriteFile (mos->h, b, size, &written, NULL);
+    return written;
+}
+
+static DWORD GetFileAttributesSafe(const TCHAR *name)
+{
+    DWORD attr, last;
+
+    last = SetErrorMode (SEM_FAILCRITICALERRORS);
+    attr = GetFileAttributes (name);
+    SetErrorMode (last);
+    return attr;
+}
+
+int my_existsfile (const TCHAR *name)
+{
+    DWORD attr = GetFileAttributesSafe (name);
+    if (attr == INVALID_FILE_ATTRIBUTES)
+       return 0;
+    if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
+       return 1;
+    return 0;
+}
+
+int my_existsdir (const TCHAR *name)
+{
+    DWORD attr = GetFileAttributesSafe (name);
+    if (attr == INVALID_FILE_ATTRIBUTES)
+       return 0;
+    if (attr & FILE_ATTRIBUTE_DIRECTORY)
+       return 1;
+    return 0;
+}
+
+void *my_open (const TCHAR *name, int flags)
+{
+    struct my_opens *mos;
+    HANDLE h;
+    DWORD DesiredAccess = GENERIC_READ;
+    DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+    DWORD CreationDisposition = OPEN_EXISTING;
+    DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+    DWORD attr;
+
+    mos = xmalloc (sizeof (struct my_opens));
+    if (!mos)
+       return NULL;
+    attr = GetFileAttributesSafe (name);
+    if (flags & O_TRUNC)
+       CreationDisposition = CREATE_ALWAYS;
+    else if (flags & O_CREAT)
+       CreationDisposition = OPEN_ALWAYS;
+    if (flags & O_WRONLY)
+       DesiredAccess = GENERIC_WRITE;
+    if (flags & O_RDONLY) {
+       DesiredAccess = GENERIC_READ;
+       CreationDisposition = OPEN_EXISTING;
+    }
+    if (flags & O_RDWR)
+       DesiredAccess = GENERIC_READ | GENERIC_WRITE;
+    if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES &&
+       (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
+       SetFileAttributes (name, FILE_ATTRIBUTE_NORMAL);
+    h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
+    if (h == INVALID_HANDLE_VALUE) {
+       DWORD err = GetLastError();
+       if (err == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) {
+           DesiredAccess &= ~GENERIC_WRITE;
+           h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
+           if (h == INVALID_HANDLE_VALUE)
+               err = GetLastError();
+       }
+       if (h == INVALID_HANDLE_VALUE) {
+           write_log (L"failed to open '%s' %x %x err=%d\n", name, DesiredAccess, CreationDisposition, err);
+           xfree (mos);
+           mos = NULL;
+           goto err;
+       }
+    }
+    mos->h = h;
+err:
+    //write_log (L"open '%s' = %x\n", name, mos ? mos->h : 0);
+    return mos;
+}
+
+int my_truncate (const TCHAR *name, uae_u64 len)
+{
+    HANDLE hFile;
+    BOOL bResult = FALSE;
+    int result = -1;
+
+    if ((hFile = CreateFile (name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
+    {
+       LARGE_INTEGER li;
+       li.QuadPart = len;
+       li.LowPart = SetFilePointer (hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+       if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) {
+           write_log (L"truncate: SetFilePointer() failure for %s to posn %d\n", name, len);
+       } else {
+           if (SetEndOfFile (hFile) == TRUE)
+               result = 0;
+       }
+       CloseHandle (hFile);
+    } else {
+       write_log (L"truncate: CreateFile() failed to open %s\n", name);
+    }
+    return result;
+}
+
+int dos_errno (void)
+{
+    DWORD e = GetLastError ();
+
+    //write_log (L"ec=%d\n", e);
+    switch (e) {
+     case ERROR_NOT_ENOUGH_MEMORY:
+     case ERROR_OUTOFMEMORY:
+       return ERROR_NO_FREE_STORE;
+
+     case ERROR_FILE_EXISTS:
+     case ERROR_ALREADY_EXISTS:
+       return ERROR_OBJECT_EXISTS;
+
+     case ERROR_WRITE_PROTECT:
+     case ERROR_ACCESS_DENIED:
+       return ERROR_WRITE_PROTECTED;
+
+     case ERROR_FILE_NOT_FOUND:
+     case ERROR_INVALID_DRIVE:
+     case ERROR_INVALID_NAME:
+     case ERROR_PATH_NOT_FOUND:
+       return ERROR_OBJECT_NOT_AROUND;
+
+     case ERROR_HANDLE_DISK_FULL:
+     case ERROR_DISK_FULL:
+       return ERROR_DISK_IS_FULL;
+
+     case ERROR_SHARING_VIOLATION:
+     case ERROR_BUSY:
+     case ERROR_INVALID_HANDLE:
+       return ERROR_OBJECT_IN_USE;
+
+     case ERROR_CURRENT_DIRECTORY:
+       return ERROR_DIRECTORY_NOT_EMPTY;
+
+     case ERROR_NEGATIVE_SEEK:
+     case ERROR_SEEK_ON_DEVICE:
+       return ERROR_SEEK_ERROR;
+
+     default:
+       {
+           gui_message (L"Unimplemented error %d\nContact author!", e);
+       }
+       return ERROR_NOT_IMPLEMENTED;
+    }
+}
+
+typedef BOOL (CALLBACK* GETVOLUMEPATHNAME)
+  (LPCTSTR lpszFileName, LPTSTR lpszVolumePathName, DWORD cchBufferLength);
+
+int my_getvolumeinfo (const TCHAR *root)
+{
+    DWORD v, err;
+    int ret = 0;
+    GETVOLUMEPATHNAME pGetVolumePathName;
+    TCHAR volume[MAX_DPATH];
+
+    v = GetFileAttributesSafe (root);
+    err = GetLastError ();
+    if (v == INVALID_FILE_ATTRIBUTES)
+       return -1;
+    if (!(v & FILE_ATTRIBUTE_DIRECTORY))
+       return -1;
+/*
+    if (v & FILE_ATTRIBUTE_READONLY)
+       ret |= MYVOLUMEINFO_READONLY;
+*/
+    pGetVolumePathName = (GETVOLUMEPATHNAME)GetProcAddress(
+       GetModuleHandle (L"kernel32.dll"), "GetVolumePathNameW");
+    if (pGetVolumePathName && pGetVolumePathName (root, volume, sizeof (volume))) {
+       TCHAR fsname[MAX_DPATH];
+       DWORD comlen;
+       DWORD flags;
+       if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof (fsname))) {
+           write_log (L"Volume %s FS=%s maxlen=%d flags=%08X\n", volume, fsname, comlen, flags);
+           if (flags & FILE_NAMED_STREAMS)
+               ret |= MYVOLUMEINFO_STREAMS;
+       }
+    }
+    return ret;
+}
+
+FILE *my_opentext (const TCHAR *name)
+{
+    FILE *f;
+    uae_u8 tmp[4];
+    int v;
+
+    f = _tfopen (name, L"rb");
+    if (!f)
+       return NULL;
+    v = fread (tmp, 1, 4, f);
+    fclose (f);
+    if (v == 4) {
+       if (tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf)
+           return _tfopen (name, L"r, ccs=UTF-8");
+       if (tmp[0] == 0xff && tmp[1] == 0xfe)
+           return _tfopen (name, L"r, ccs=UTF-16LE");
+    }
+    return _tfopen (name, L"r");
+}
+
index 38045c3af3a00d6d9b951c95a89b6601494ca5c0..9299e10c7299859d867a8134c69a7d3f7bbb45d7 100644 (file)
@@ -569,383 +569,3 @@ int custom_fsdb_used_as_nname (a_inode *base, const TCHAR *nname)
     return 0;
 }
 
-int my_mkdir (const TCHAR *name)
-{
-    return CreateDirectory (name, NULL) == 0 ? -1 : 0;
-}
-
-static int recycle (const TCHAR *name)
-{
-    if (currprefs.win32_norecyclebin) {
-       DWORD dirattr = GetFileAttributes (name);
-       if (dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY))
-           return RemoveDirectory (name) ? 0 : -1;
-       return DeleteFile(name) ? 0 : -1;
-    } else {
-       SHFILEOPSTRUCT fos;
-       /* name must be terminated by \0\0 */
-       TCHAR *p = xcalloc ((_tcslen (name) + 2) * sizeof (TCHAR), 1);
-       int v;
-
-       _tcscpy (p, name);
-       memset (&fos, 0, sizeof (fos));
-       fos.wFunc = FO_DELETE;
-       fos.pFrom = p;
-       fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NORECURSION | FOF_SILENT;
-       v = SHFileOperation (&fos);
-       xfree (p);
-       switch (v)
-       {
-           case 0xb7: //DE_ERROR_MAX
-           case 0x7c: //DE_INVALIDFILES
-           case 0x402: // "unknown error"
-           v = ERROR_FILE_NOT_FOUND;
-           break;
-           case 0x75: //DE_OPCANCELLED:
-           case 0x10000: //ERRORONDEST:
-           case 0x78: //DE_ACCESSDENIEDSRC:
-           case 0x74: //DE_ROOTDIR:
-           v = ERROR_ACCESS_DENIED;
-           break;
-       }
-       SetLastError (v);
-       return v ? -1 : 0;
-    }
-}
-
-int my_rmdir (const TCHAR *name)
-{
-    void *od;
-    int cnt;
-    TCHAR tname[MAX_DPATH];
-
-    /* SHFileOperation() ignores FOF_NORECURSION when deleting directories.. */
-    od = my_opendir (name);
-    if (!od) {
-       SetLastError (ERROR_FILE_NOT_FOUND);
-       return -1;
-    }
-    cnt = 0;
-    while (my_readdir (od, tname)) {
-       if (!_tcscmp (tname, L".") || !_tcscmp (tname, L".."))
-           continue;
-       cnt++;
-       break;
-    }
-    my_closedir (od);
-    if (cnt > 0) {
-       SetLastError (ERROR_CURRENT_DIRECTORY);
-       return -1;
-    }
-
-    return recycle (name);
-}
-
-/* "move to Recycle Bin" (if enabled) -version of DeleteFile() */
-int my_unlink (const TCHAR *name)
-{
-    return recycle (name);
-}
-
-int my_rename (const TCHAR *oldname, const TCHAR *newname)
-{
-    return MoveFile (oldname, newname) == 0 ? -1 : 0;
-}
-
-struct my_opendirs {
-    HANDLE *h;
-    WIN32_FIND_DATA fd;
-    int first;
-};
-
-void *my_opendir (const TCHAR *name)
-{
-    struct my_opendirs *mod;
-    TCHAR tmp[MAX_DPATH];
-
-    _tcscpy (tmp, name);
-    _tcscat (tmp, L"\\*.*");
-    mod = xmalloc (sizeof (struct my_opendirs));
-    if (!mod)
-       return NULL;
-    mod->h = FindFirstFile(tmp, &mod->fd);
-    if (mod->h == INVALID_HANDLE_VALUE) {
-       xfree (mod);
-       return NULL;
-    }
-    mod->first = 1;
-    return mod;
-}
-
-void my_closedir (void *d)
-{
-    struct my_opendirs *mod = d;
-    if (d)
-       FindClose (mod->h);
-    xfree (mod);
-}
-
-int my_readdir (void *d, TCHAR *name)
-{
-    struct my_opendirs *mod = d;
-    if (mod->first) {
-       _tcscpy (name, mod->fd.cFileName);
-       mod->first = 0;
-       return 1;
-    }
-    if (!FindNextFile (mod->h, &mod->fd))
-       return 0;
-    _tcscpy (name, mod->fd.cFileName);
-    return 1;
-}
-
-struct my_opens {
-    HANDLE *h;
-};
-
-void my_close (void *d)
-{
-    struct my_opens *mos = d;
-    CloseHandle (mos->h);
-    xfree (mos);
-}
-
-uae_s64 int my_lseek (void *d, uae_s64 int offset, int whence)
-{
-    struct my_opens *mos = d;
-    LARGE_INTEGER li;
-
-    li.QuadPart = offset;
-    li.LowPart = SetFilePointer (mos->h, li.LowPart, &li.HighPart,
-       whence == SEEK_SET ? FILE_BEGIN : (whence == SEEK_END ? FILE_END : FILE_CURRENT));
-    if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
-       li.QuadPart = -1;
-    return li.QuadPart;
-}
-
-unsigned int my_read (void *d, void *b, unsigned int size)
-{
-    struct my_opens *mos = d;
-    DWORD read = 0;
-    ReadFile (mos->h, b, size, &read, NULL);
-    return read;
-}
-
-unsigned int my_write (void *d, void *b, unsigned int size)
-{
-    struct my_opens *mos = d;
-    DWORD written = 0;
-    WriteFile (mos->h, b, size, &written, NULL);
-    return written;
-}
-
-static DWORD GetFileAttributesSafe(const TCHAR *name)
-{
-    DWORD attr, last;
-
-    last = SetErrorMode (SEM_FAILCRITICALERRORS);
-    attr = GetFileAttributes (name);
-    SetErrorMode (last);
-    return attr;
-}
-
-int my_existsfile (const TCHAR *name)
-{
-    DWORD attr = GetFileAttributesSafe (name);
-    if (attr == INVALID_FILE_ATTRIBUTES)
-       return 0;
-    if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
-       return 1;
-    return 0;
-}
-
-int my_existsdir (const TCHAR *name)
-{
-    DWORD attr = GetFileAttributesSafe (name);
-    if (attr == INVALID_FILE_ATTRIBUTES)
-       return 0;
-    if (attr & FILE_ATTRIBUTE_DIRECTORY)
-       return 1;
-    return 0;
-}
-
-void *my_open (const TCHAR *name, int flags)
-{
-    struct my_opens *mos;
-    HANDLE h;
-    DWORD DesiredAccess = GENERIC_READ;
-    DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-    DWORD CreationDisposition = OPEN_EXISTING;
-    DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
-    DWORD attr;
-
-    mos = xmalloc (sizeof (struct my_opens));
-    if (!mos)
-       return NULL;
-    attr = GetFileAttributesSafe (name);
-    if (flags & O_TRUNC)
-       CreationDisposition = CREATE_ALWAYS;
-    else if (flags & O_CREAT)
-       CreationDisposition = OPEN_ALWAYS;
-    if (flags & O_WRONLY)
-       DesiredAccess = GENERIC_WRITE;
-    if (flags & O_RDONLY) {
-       DesiredAccess = GENERIC_READ;
-       CreationDisposition = OPEN_EXISTING;
-    }
-    if (flags & O_RDWR)
-       DesiredAccess = GENERIC_READ | GENERIC_WRITE;
-    if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES &&
-       (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
-       SetFileAttributes (name, FILE_ATTRIBUTE_NORMAL);
-    h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
-    if (h == INVALID_HANDLE_VALUE) {
-       DWORD err = GetLastError();
-       if (err == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) {
-           DesiredAccess &= ~GENERIC_WRITE;
-           h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
-           if (h == INVALID_HANDLE_VALUE)
-               err = GetLastError();
-       }
-       if (h == INVALID_HANDLE_VALUE) {
-           write_log (L"failed to open '%s' %x %x err=%d\n", name, DesiredAccess, CreationDisposition, err);
-           xfree (mos);
-           mos = NULL;
-           goto err;
-       }
-    }
-    mos->h = h;
-err:
-    //write_log (L"open '%s' = %x\n", name, mos ? mos->h : 0);
-    return mos;
-}
-
-int my_truncate (const TCHAR *name, uae_u64 len)
-{
-    HANDLE hFile;
-    BOOL bResult = FALSE;
-    int result = -1;
-
-    if ((hFile = CreateFile (name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
-    {
-       LARGE_INTEGER li;
-       li.QuadPart = len;
-       li.LowPart = SetFilePointer (hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
-       if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) {
-           write_log (L"truncate: SetFilePointer() failure for %s to posn %d\n", name, len);
-       } else {
-           if (SetEndOfFile (hFile) == TRUE)
-               result = 0;
-       }
-       CloseHandle (hFile);
-    } else {
-       write_log (L"truncate: CreateFile() failed to open %s\n", name);
-    }
-    return result;
-}
-
-int dos_errno (void)
-{
-    DWORD e = GetLastError ();
-
-    //write_log (L"ec=%d\n", e);
-    switch (e) {
-     case ERROR_NOT_ENOUGH_MEMORY:
-     case ERROR_OUTOFMEMORY:
-       return ERROR_NO_FREE_STORE;
-
-     case ERROR_FILE_EXISTS:
-     case ERROR_ALREADY_EXISTS:
-       return ERROR_OBJECT_EXISTS;
-
-     case ERROR_WRITE_PROTECT:
-     case ERROR_ACCESS_DENIED:
-       return ERROR_WRITE_PROTECTED;
-
-     case ERROR_FILE_NOT_FOUND:
-     case ERROR_INVALID_DRIVE:
-     case ERROR_INVALID_NAME:
-     case ERROR_PATH_NOT_FOUND:
-       return ERROR_OBJECT_NOT_AROUND;
-
-     case ERROR_HANDLE_DISK_FULL:
-     case ERROR_DISK_FULL:
-       return ERROR_DISK_IS_FULL;
-
-     case ERROR_SHARING_VIOLATION:
-     case ERROR_BUSY:
-     case ERROR_INVALID_HANDLE:
-       return ERROR_OBJECT_IN_USE;
-
-     case ERROR_CURRENT_DIRECTORY:
-       return ERROR_DIRECTORY_NOT_EMPTY;
-
-     case ERROR_NEGATIVE_SEEK:
-     case ERROR_SEEK_ON_DEVICE:
-       return ERROR_SEEK_ERROR;
-
-     default:
-       {
-           gui_message (L"Unimplemented error %d\nContact author!", e);
-       }
-       return ERROR_NOT_IMPLEMENTED;
-    }
-}
-
-typedef BOOL (CALLBACK* GETVOLUMEPATHNAME)
-  (LPCTSTR lpszFileName, LPTSTR lpszVolumePathName, DWORD cchBufferLength);
-
-int my_getvolumeinfo (const TCHAR *root)
-{
-    DWORD v, err;
-    int ret = 0;
-    GETVOLUMEPATHNAME pGetVolumePathName;
-    TCHAR volume[MAX_DPATH];
-
-    v = GetFileAttributesSafe (root);
-    err = GetLastError ();
-    if (v == INVALID_FILE_ATTRIBUTES)
-       return -1;
-    if (!(v & FILE_ATTRIBUTE_DIRECTORY))
-       return -1;
-/*
-    if (v & FILE_ATTRIBUTE_READONLY)
-       ret |= MYVOLUMEINFO_READONLY;
-*/
-    pGetVolumePathName = (GETVOLUMEPATHNAME)GetProcAddress(
-       GetModuleHandle (L"kernel32.dll"), "GetVolumePathNameW");
-    if (pGetVolumePathName && pGetVolumePathName (root, volume, sizeof (volume))) {
-       TCHAR fsname[MAX_DPATH];
-       DWORD comlen;
-       DWORD flags;
-       if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof (fsname))) {
-           write_log (L"Volume %s FS=%s maxlen=%d flags=%08X\n", volume, fsname, comlen, flags);
-           if (flags & FILE_NAMED_STREAMS)
-               ret |= MYVOLUMEINFO_STREAMS;
-       }
-    }
-    return ret;
-}
-
-FILE *my_opentext (const TCHAR *name)
-{
-    FILE *f;
-    uae_u8 tmp[4];
-    int v;
-
-    f = _tfopen (name, L"rb");
-    if (!f)
-       return NULL;
-    v = fread (tmp, 1, 4, f);
-    fclose (f);
-    if (v == 4) {
-       if (tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf)
-           return _tfopen (name, L"r, ccs=UTF-8");
-       if (tmp[0] == 0xff && tmp[1] == 0xfe)
-           return _tfopen (name, L"r, ccs=UTF-16LE");
-    }
-    return _tfopen (name, L"r");
-}
-
-
index 25736f75a0ea61e5c4a42386273b08ee66175a64..b2762e62e809670420a7b71ed3dea280ef32c58d 100644 (file)
@@ -276,7 +276,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
            if (hfd->physsize < 64 * 1024 * 1024 && zmode) {
                write_log (L"HDF '%s' re-opened in zfile-mode\n", name);
                CloseHandle (h);
-               hfd->handle = h = zfile_fopen(name, hfd->readonly ? L"rb" : L"r+b");
+               hfd->handle = h = zfile_fopen(name, hfd->readonly ? L"rb" : L"r+b", ZFD_NORMAL);
                if (!h)
                    goto end;
                zfile_fseek (h, 0, SEEK_END);
index 17598af9e9e8aa91b5a67346573a8d5d5ce93175..4548c1e3ea10717efa1a2ff6c83dc45871e8e16e 100644 (file)
@@ -290,7 +290,7 @@ static void DoSomeWeirdPrintingStuff (uae_char val)
        } else if (!psmode && !stricmp (prev, "%!PS")) {
 
            if (postscript_print_debugging)
-               prtdump = zfile_fopen (L"psdump.dat", L"wb");
+               prtdump = zfile_fopen (L"psdump.dat", L"wb", 0);
 
            psmode = 1;
            psbuffer = malloc (sizeof (uae_u8*));
index 459f162a688b582c2b3a9bb49bb99efe9e34015b..ba9e8dea1385eee05cf672f9726533a1d68c75a5 100644 (file)
@@ -248,10 +248,15 @@ static unsigned __stdcall thread_init (void *f)
     void *arg = thp->arg;
 
     xfree (f);
+
+#ifndef _CONSOLE
     __try {
        fp (arg);
+#endif
+#ifndef _CONSOLE
     } __except (WIN32_ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
     }
+#endif
     return 0;
 }
 
diff --git a/od-win32/uaeunp/uaeunp.vcproj b/od-win32/uaeunp/uaeunp.vcproj
new file mode 100644 (file)
index 0000000..e2f2f07
--- /dev/null
@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9,00"
+       Name="uaeunp"
+       ProjectGUID="{6181E50C-5F32-42DC-BEF6-827AA8A5429D}"
+       RootNamespace="uaeunp"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="d:\amiga"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\include,..\..,..\,..\resources,..\osdep,..\sounddep,..\..\prowizard\include,..\tun"
+                               PreprocessorDefinitions="WINVER=0x0500,_DEBUG,WIN32_IE=0x0700;WIN32;CINTERFACE;COBJMACROS;_CRT_SECURE_NO_WARNINGS;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="zlibstat.lib"
+                               LinkIncremental="2"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="d:\amiga"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               AdditionalIncludeDirectories="..\..\include,..\..,..\,..\resources,..\osdep,..\sounddep,..\..\prowizard\include,..\tun"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;,WIN32_IE=0x0700;WIN32;CINTERFACE;COBJMACROS;_CRT_SECURE_NO_WARNINGS;"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                               CompileAs="1"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="zlibstat.lib"
+                               LinkIncremental="1"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\..\crc32.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\diskutil.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\fdi2raw.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\missing.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\uaeunp.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\zfile.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\zfile_archive.c"
+                               >
+                       </File>
+                       <Filter
+                               Name="decompressors"
+                               >
+                               <Filter
+                                       Name="dms"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\dms\crc_csum.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\getbits.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\maketbl.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\pfile.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\tables.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_deep.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_heavy.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_init.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_medium.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_quick.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\dms\u_rle.c"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="7z"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zAlloc.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\7zBuf.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\7zCrc.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zDecode.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zExtract.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zHeader.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zIn.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Archive\7z\7zItem.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\7zStream.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Bcj2.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Bra.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\Bra86.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\7z\LzmaDec.c"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="lha"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\lha\crcio.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\dhuf.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\header.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\huf.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\larc.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\lhamaketbl.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\lharc.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\shuf.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\slide.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\uae_lha.c"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\archivers\lha\util.c"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="zip"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\zip\unzip.c"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="lzx"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\lzx\unlzx.c"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="xfd"
+                                       >
+                               </Filter>
+                               <Filter
+                                       Name="wrp"
+                                       >
+                                       <File
+                                               RelativePath="..\..\archivers\wrp\warp.c"
+                                               >
+                                       </File>
+                               </Filter>
+                       </Filter>
+                       <Filter
+                               Name="win32"
+                               >
+                               <File
+                                       RelativePath="..\caps\caps_win32.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\fsdb_mywin32.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\posixemu.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\uaeunp_win32.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\unicode.c"
+                                       >
+                               </File>
+                       </Filter>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/od-win32/uaeunp_win32.c b/od-win32/uaeunp_win32.c
new file mode 100644 (file)
index 0000000..1ac23c8
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <tchar.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "win32.h"
+
+static void LLError(const TCHAR *s)
+{
+    DWORD err = GetLastError ();
+
+    if (err == ERROR_MOD_NOT_FOUND || err == ERROR_DLL_NOT_FOUND)
+       return;
+    write_log (L"%s failed to open %d\n", s, err);
+}
+
+void notify_user (int n)
+{
+}
+
+HMODULE WIN32_LoadLibrary (const TCHAR *name)
+{
+    HMODULE m = NULL;
+    TCHAR *newname;
+    DWORD err = -1;
+#ifdef CPU_64_BIT
+    TCHAR *p;
+#endif
+    int round;
+
+    newname = xmalloc ((_tcslen (name) + 1 + 10) * sizeof (TCHAR));
+    if (!newname)
+       return NULL;
+    for (round = 0; round < 4; round++) {
+       TCHAR *s;
+       _tcscpy (newname, name);
+#ifdef CPU_64_BIT
+       switch(round)
+       {
+           case 0:
+           p = strstr (newname,"32");
+           if (p) {
+               p[0] = '6';
+               p[1] = '4';
+           }
+           break;
+           case 1:
+           p = strchr (newname,'.');
+           _tcscpy(p,"_64");
+           _tcscat(p, strchr (name,'.'));
+           break;
+           case 2:
+           p = strchr (newname,'.');
+           _tcscpy (p,"64");
+           _tcscat (p, strchr (name,'.'));
+           break;
+       }
+#endif
+       s = xmalloc ((_tcslen (start_path_exe) + _tcslen (WIN32_PLUGINDIR) + _tcslen (newname) + 1) * sizeof (TCHAR));
+       if (s) {
+           _stprintf (s, L"%s%s%s", start_path_exe, WIN32_PLUGINDIR, newname);
+           m = LoadLibrary (s);
+           if (m)
+               goto end;
+           _stprintf (s, L"%s%s", start_path_exe, newname);
+           m = LoadLibrary (s);
+           if (m)
+               goto end;
+           _stprintf (s, L"%s%s%s", start_path_exe, WIN32_PLUGINDIR, newname);
+           LLError(s);
+           xfree (s);
+       }
+       m = LoadLibrary (newname);
+       if (m)
+           goto end;
+       LLError (newname);
+#ifndef CPU_64_BIT
+       break;
+#endif
+    }
+end:
+    xfree (newname);
+    return m;
+}
index 738fb7b26c80fd504aaabdc5457498420eadc321..42263aaefa3219e6226590bab6307905c705283d 100644 (file)
@@ -483,6 +483,10 @@ static int avioutput_video = 0;
 void setpriority (struct threadpriorities *pri)
 {
     int err;
+    DWORD opri = GetPriorityClass (GetCurrentProcess ());
+
+    if (opri != IDLE_PRIORITY_CLASS && opri != NORMAL_PRIORITY_CLASS && opri != BELOW_NORMAL_PRIORITY_CLASS && opri != ABOVE_NORMAL_PRIORITY_CLASS)
+       return;
     err = SetPriorityClass (GetCurrentProcess (), pri->classvalue);
     if (!err)
        write_log (L"priority set failed, %08X\n", GetLastError ());
@@ -1026,7 +1030,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
 
        if (lParam == SHCNE_MEDIAINSERTED || lParam == SHCNE_MEDIAREMOVED) {
            SHNOTIFYSTRUCT *shns = (SHNOTIFYSTRUCT*)wParam;
-           if(SHGetPathFromIDList((struct _ITEMIDLIST *)(shns->dwItem1), path)) {
+           if (SHGetPathFromIDList ((struct _ITEMIDLIST *)(shns->dwItem1), path)) {
                int inserted = lParam == SHCNE_MEDIAINSERTED ? 1 : 0;
                write_log (L"Shell Notification %d '%s'\n", inserted, path);
                if (!win32_hardfile_media_change (path, inserted)) {    
@@ -3394,6 +3398,8 @@ static void makeverstr (TCHAR *s)
     }
 }
 
+#define MAX_ARGUMENTS 128
+
 static int parseargs (const TCHAR *arg, const TCHAR *np, const TCHAR *np2)
 {
     if (!_tcscmp (arg, L"-convert") && np && np2) {
@@ -3586,7 +3592,7 @@ static TCHAR **parseargstring (TCHAR *s)
 
     if (_tcslen (s) == 0)
        return NULL;
-    args = xcalloc (sizeof (TCHAR*), 32 + 1);
+    args = xcalloc (sizeof (TCHAR*), MAX_ARGUMENTS + 1);
     cnt = 0;
     for (;;) {
        TCHAR *p = s;
@@ -3612,7 +3618,7 @@ static TCHAR **parseargstring (TCHAR *s)
            p++;
        if (*p == 0)
            break;
-       if (cnt >= 32)
+       if (cnt >= MAX_ARGUMENTS)
            break;
        s = p;
     }
@@ -3665,7 +3671,7 @@ static int process_arg (TCHAR *cmdline, TCHAR **xargv, TCHAR ***xargv3)
        ok = 0;
        if (f[0] != '-' && f[0] != '/') {
            int type = -1;
-           struct zfile *z = zfile_fopen (f, L"rb");
+           struct zfile *z = zfile_fopen (f, L"rb", ZFD_NORMAL);
            if (z) {
                type = zfile_gettype (z);
                zfile_fclose (z);
@@ -3770,7 +3776,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
     hMutex = CreateMutex (NULL, FALSE, L"WinUAE Instantiated"); // To tell the installer we're running
 
 
-    argv = xcalloc (sizeof (TCHAR*), 32);
+    argv = xcalloc (sizeof (TCHAR*), MAX_ARGUMENTS);
     argv3 = NULL;
     argc = process_arg (lpCmdLine, argv, &argv3);
     if (doquit)
index bb62f58540891f08544654cf64083161002acea2..a370e05de10216744011d0d7bc1bd2a03ea9f672 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"21"
-#define WINUAEDATE MAKEBD(2009, 3, 31)
+#define WINUAEBETA L"22"
+#define WINUAEDATE MAKEBD(2009, 4, 8)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 270122726adf5a29fc0d67489f067bfe5c8b2efc..77edfefdf4e4db4a75e031aa5c6fbbb57b2c7a4a 100644 (file)
@@ -99,6 +99,7 @@ static struct winuae_currentmode currentmodestruct;
 static int screen_is_initialized;
 int display_change_requested, normal_display_change_starting;
 int window_led_drives, window_led_drives_end;
+int window_led_hd, window_led_hd_end;
 extern int console_logging;
 int window_extra_width, window_extra_height;
 
@@ -1790,14 +1791,16 @@ static void createstatuswindow (void)
        lpParts[2] = lpParts[1] + idle_width;
        lpParts[3] = lpParts[2] + fps_width;
        lpParts[4] = lpParts[3] + power_width;
-       lpParts[5] = lpParts[4] + cd_width;
-       lpParts[6] = lpParts[5] + hd_width;
+       lpParts[5] = lpParts[4] + hd_width;
+       lpParts[6] = lpParts[5] + cd_width;
        lpParts[7] = lpParts[6] + drive_width;
        lpParts[8] = lpParts[7] + drive_width;
        lpParts[9] = lpParts[8] + drive_width;
        lpParts[10] = lpParts[9] + drive_width;
        window_led_drives = lpParts[6];
        window_led_drives_end = lpParts[10];
+       window_led_hd = lpParts[4];
+       window_led_hd_end = lpParts[5];
 
        /* Create the parts */
        SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM)num_parts, (LPARAM)lpParts);
index ec56b4a173565b8d693b39b4e8756b6e80716d83..dadd01acbddb6a0004fb6309031ddd95afdd773c 100644 (file)
@@ -28,6 +28,7 @@ extern HWND hStatusWnd;
 extern uae_u32 default_freq;
 extern int normal_display_change_starting;
 extern int window_led_drives, window_led_drives_end;
+extern int window_led_hd, window_led_hd_end;
 
 extern HDC gethdc (void);
 extern void releasehdc (HDC hdc);
index 8ce1b410bce26147c217b04edda9c126759d013f..13abf0f555b6ac0714e16c3c2f1868335a08422f 100644 (file)
@@ -83,6 +83,7 @@
 #include "crc32.h"
 #include "rp.h"
 #include "statusline.h"
+#include "zarchive.h"
 
 #define ARCHIVE_STRING L"*.zip;*.7z;*.rar;*.lha;*.lzh;*.lzx"
 
@@ -939,7 +940,7 @@ static struct romdata *scan_single_rom (TCHAR *path)
     rd = getromdatabypath (path);
     if (rd && rd->crc32 == 0xffffffff)
        return rd;
-    z = zfile_fopen (path, L"rb");
+    z = zfile_fopen (path, L"rb", ZFD_NORMAL);
     if (!z)
        return 0;
     return scan_single_rom_2 (z);
@@ -5634,9 +5635,10 @@ static void values_to_memorydlg (HWND hDlg)
     SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_SETCURSEL,
        (workprefs.win32_rtgscaleaspectratio == 0) ? 0 :
        (workprefs.win32_rtgscaleaspectratio == 4 * 256 + 3) ? 2 :
-       (workprefs.win32_rtgscaleaspectratio == 15 * 256 + 9) ? 3 :
-       (workprefs.win32_rtgscaleaspectratio == 16 * 256 + 9) ? 4 :
-       (workprefs.win32_rtgscaleaspectratio == 16 * 256 + 10) ? 5 : 1, 0);
+       (workprefs.win32_rtgscaleaspectratio == 5 * 256 + 4) ? 3 :
+       (workprefs.win32_rtgscaleaspectratio == 15 * 256 + 9) ? 4 :
+       (workprefs.win32_rtgscaleaspectratio == 16 * 256 + 9) ? 5 :
+       (workprefs.win32_rtgscaleaspectratio == 16 * 256 + 10) ? 6 : 1, 0);
 
     mem_size = 0;
     switch (workprefs.mbresmem_low_size) {
@@ -5752,6 +5754,7 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
            WIN32GUI_LoadUIString (IDS_AUTOMATIC, tmp, sizeof tmp / sizeof (TCHAR));
            SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)tmp);
            SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)L"4:3");
+           SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)L"5:4");
            SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)L"15:9");
            SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)L"16:9");
            SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)L"16:10");
@@ -5822,10 +5825,12 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                        if (v == 2)
                            workprefs.win32_rtgscaleaspectratio = 4 * 256 + 3;
                        if (v == 3)
-                           workprefs.win32_rtgscaleaspectratio = 15 * 256 + 9;
+                           workprefs.win32_rtgscaleaspectratio = 5 * 256 + 4;
                        if (v == 4)
-                           workprefs.win32_rtgscaleaspectratio = 16 * 256 + 9;
+                           workprefs.win32_rtgscaleaspectratio = 15 * 256 + 9;
                        if (v == 5)
+                           workprefs.win32_rtgscaleaspectratio = 16 * 256 + 9;
+                       if (v == 6)
                            workprefs.win32_rtgscaleaspectratio = 16 * 256 + 10;
                    }
                    break;
@@ -6193,6 +6198,9 @@ static void misc_getpri (HWND hDlg, int v, int *n)
 static void misc_addpri (HWND hDlg, int v, int pri)
 {
     int i;
+    
+    DWORD opri = GetPriorityClass (GetCurrentProcess ());
+    ew (hDlg, v, !(opri != IDLE_PRIORITY_CLASS && opri != NORMAL_PRIORITY_CLASS && opri != BELOW_NORMAL_PRIORITY_CLASS && opri != ABOVE_NORMAL_PRIORITY_CLASS));
     SendDlgItemMessage (hDlg, v, CB_RESETCONTENT, 0, 0L);
     i = 0;
     while (priorities[i].name) {
@@ -6200,6 +6208,8 @@ static void misc_addpri (HWND hDlg, int v, int pri)
        i++;
     }
     SendDlgItemMessage (hDlg, v, CB_SETCURSEL, pri, 0);
+
+
 }
 
 extern TCHAR *get_aspi_path(int);
@@ -7487,7 +7497,7 @@ static void sethfdostype (HWND hDlg, int idx)
 
 static void hardfile_testrdb (HWND hDlg, struct hfdlg_vals *hdf)
 {
-    void *f = zfile_fopen (hdf->filename, L"rb");
+    void *f = zfile_fopen (hdf->filename, L"rb", ZFD_NORMAL);
     uae_u8 tmp[8] = { 0 };
     if (!f)
        return;
@@ -10184,9 +10194,10 @@ static void values_to_hw3ddlg (HWND hDlg)
     SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_SETCURSEL,
        (workprefs.gfx_filter_aspect == 0) ? 0 :
        (workprefs.gfx_filter_aspect == 4 * 256 + 3) ? 1 :
-       (workprefs.gfx_filter_aspect == 15 * 256 + 9) ? 2 :
-       (workprefs.gfx_filter_aspect == 16 * 256 + 9) ? 3 :
-       (workprefs.gfx_filter_aspect == 16 * 256 + 10) ? 4 : 0, 0);
+       (workprefs.gfx_filter_aspect == 5 * 256 + 4) ? 2 :
+       (workprefs.gfx_filter_aspect == 15 * 256 + 9) ? 3 :
+       (workprefs.gfx_filter_aspect == 16 * 256 + 9) ? 4 :
+       (workprefs.gfx_filter_aspect == 16 * 256 + 10) ? 5 : 0, 0);
 
     SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_RESETCONTENT, 0, 0L);
     SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)L"Disabled");
@@ -10523,6 +10534,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
            WIN32GUI_LoadUIString (IDS_DISABLED, tmp, sizeof tmp / sizeof (TCHAR));
            SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)tmp);
            SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)L"4:3");
+           SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)L"5:4");
            SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)L"15:9");
            SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)L"16:9");
            SendDlgItemMessage (hDlg, IDC_FILTERASPECT, CB_ADDSTRING, 0, (LPARAM)L"16:10");
@@ -10615,10 +10627,12 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                if (v == 1)
                                    v2 = 4 * 256 + 3;
                                if (v == 2)
-                                   v2 = 15 * 256 + 9;
+                                   v2 = 5 * 256 + 4;
                                if (v == 3)
-                                   v2 = 16 * 256 + 9;
+                                   v2 = 15 * 256 + 9;
                                if (v == 4)
+                                   v2 = 16 * 256 + 9;
+                               if (v == 5)
                                    v2 = 16 * 256 + 10;
                            }
                            currprefs.gfx_filter_aspect = workprefs.gfx_filter_aspect = v2;
@@ -11445,7 +11459,7 @@ static int do_filesys_insert (const TCHAR *root)
 
 int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int        currentpage)
 {
-    int cnt, i, drv, drvdrag, firstdrv, list;
+    int cnt, i, drv, harddrive, drvdrag, firstdrv, list;
     TCHAR file[MAX_DPATH];
     int dfxtext[] = { IDC_DF0TEXT, IDC_DF0TEXTQ, IDC_DF1TEXT, IDC_DF1TEXTQ, IDC_DF2TEXT, -1, IDC_DF3TEXT, -1 };
     POINT pt;
@@ -11458,7 +11472,7 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage)
     cnt = DragQueryFile (hd, 0xffffffff, NULL, 0);
     if (!cnt)
        return 0;
-    drv = 0;
+    drv = harddrive = 0;
     drvdrag = 0;
     if (currentpage < 0) {
        GetClientRect (hMainWnd, &r2);
@@ -11471,6 +11485,9 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage)
                if (drv < 0 || drv > 3)
                    drv = 0;
            }
+           if (pt.x >= window_led_hd && pt.x < window_led_hd_end && window_led_hd > 0) {
+               harddrive = 1;
+           }
        }
     } else if (currentpage == FLOPPY_ID || currentpage == QUICKSTART_ID) {
        for (i = 0; i < 4; i++) {
@@ -11490,22 +11507,26 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int       currentpage)
        struct romdata *rd = NULL;
        struct zfile *z;
        int type = -1, zip = 0;
+       int mask;
 
        DragQueryFile (hd, i, file, sizeof (file) / sizeof (TCHAR));
        flags = GetFileAttributes (file);
        if (flags & FILE_ATTRIBUTE_DIRECTORY)
            type = ZFILE_HDF;
+       if (harddrive)
+           mask = ZFD_ALL;
+       else
+           mask = ZFD_NORMAL;
        if (type < 0) {
            if (currentpage < 0) {
-               z = zfile_fopen_nozip (file, L"rb");
+               z = zfile_fopen (file, L"rb", mask);
                if (z) {
-                   if (iszip (z))
-                       zip = 1;
+                   int zip = iszip (z);
                    zfile_fclose (z);
                }
            }
            if (!zip) {
-               z = zfile_fopen (file, L"rb");
+               z = zfile_fopen (file, L"rb", mask);
                if (z) {
                    if (currentpage < 0 && iszip (z)) {
                        zip = 1;
@@ -11616,6 +11637,8 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage)
                } else if (currentpage == HARDDISK_ID) {
                    add_filesys_config (&workprefs, -1, NULL, L"", file, 0,
                        0, 0, 0, 0, 0, NULL, 0, 0);
+                   if (!full_property_sheet)
+                       do_filesys_insert (file);
                } else {
                    rd = scan_arcadia_rom (file, 0);
                    if (rd) {
index 14b3674170e2bcd8af040f009d9c00c1efc7b964..0756fcc4849bad889ca9f57e05d5fbf0844604b6 100644 (file)
                                RelativePath="..\dxwrap.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\fsdb_mywin32.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\fsdb_win32.c"
                                >
                                RelativePath="..\..\disk.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\diskutil.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\drawing.c"
                                >
                                Name="7z"
                                >
                                <File
-                                       RelativePath="..\..\archivers\7z\7zAlloc.c"
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zAlloc.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zBuffer.c"
+                                       RelativePath="..\..\archivers\7z\7zBuf.c"
                                        >
                                </File>
                                <File
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zDecode.c"
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zDecode.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zExtract.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zHeader.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zExtract.c"
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zIn.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zHeader.c"
+                                       RelativePath="..\..\archivers\7z\Archive\7z\7zItem.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zIn.c"
+                                       RelativePath="..\..\archivers\7z\7zStream.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zItem.c"
+                                       RelativePath="..\..\archivers\7z\Bcj2.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zMain.c"
+                                       RelativePath="..\..\archivers\7z\Bra.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\7zMethodID.c"
+                                       RelativePath="..\..\archivers\7z\Bra86.c"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\..\archivers\7z\LzmaDecode.c"
+                                       RelativePath="..\..\archivers\7z\LzmaDec.c"
                                        >
                                </File>
                        </Filter>
index 4c19028feafd0ff41250e0f0f5489cd4d0ac6996..3dae2f73515a291b822d2364a193f9e420f73473 100644 (file)
@@ -1,4 +1,27 @@
 
+Beta 22:
+
+- do not change priority if current priority is HIGH or REALTIME
+- command line parameter parsing crash fixed
+- added 5:4 aspect ratio to rtg and filter settings
+- archiveaccess filename encoding fixed (b15)
+- recursive archive support fixed (b15)
+- added adf, rdb and hdf "archive" support. It is now possible to
+  browse adf/hdf/dms/ipf/fdi/extended adf inside zip/lha/whatever
+  archives when mounted as a harddrive :) (uaeunp.exe feature mainly)
+- clipboard initialization should really be after dos initialization,
+  should fix random "UAE clipboard sharing" crashes when booting
+- debugger crash fixes (b15)
+- lha non-extended file/dir timestamps fixed
+- 7z SDK updated to newer version, timestamps supported
+- diskspare (12/24 sector) disk images supported, also includes "plain"
+  adf files that have exact diskspare format size
+- dragging to windowed mode HD-"led" forces harddrive mount (for
+  example adf is mounted as a harddrive, normally dragging autodetects
+  type and inserts adfs to disk drive)
+- dragging file to harddrive panel also automounts it immediately if
+  emulation is already running
+
 Beta 21:
 
 - registry subsystem wasn't initialized in b20 (broke lots of things)
index 260aa7aeae8fffe1e201ed46ef38c82882a781ff..26f03fe515534672604e2ef856e5fe36335c78e1 100644 (file)
@@ -253,8 +253,8 @@ void write_dlog (const TCHAR *format, ...)
     }
     if (debugfile) {
        if (lfdetected && ts)
-           _ftprintf (debugfile, ts);
-       _ftprintf (debugfile, buffer);
+           _ftprintf (debugfile, L"%s", ts);
+       _ftprintf (debugfile, L"%s", buffer);
     }
     lfdetected = 0;
     if (_tcslen (buffer) > 0 && buffer[_tcslen(buffer) - 1] == '\n')
@@ -300,8 +300,8 @@ void write_log (const TCHAR *format, ...)
     }
     if (debugfile) {
        if (lfdetected && ts)
-           _ftprintf (debugfile, ts);
-       _ftprintf (debugfile, bufp);
+           _ftprintf (debugfile, L"%s", ts);
+       _ftprintf (debugfile, L"%s", bufp);
     }
     lfdetected = 0;
     if (_tcslen (bufp) > 0 && bufp[_tcslen (bufp) - 1] == '\n')
index a2bf51bcd763ee55bd2fda4b81fb2bf1139ef94c..3cfe5f696247f4f9d221af7d0adf945b1f362560 100644 (file)
@@ -405,7 +405,7 @@ void restore_state (const TCHAR *filename)
     int z3num;
 
     chunk = 0;
-    f = zfile_fopen (filename, L"rb");
+    f = zfile_fopen (filename, L"rb", ZFD_NORMAL);
     if (!f)
        goto error;
     zfile_fseek (f, 0, SEEK_END);
@@ -662,7 +662,7 @@ int save_state (const TCHAR *filename, const TCHAR *description)
     }
     savestate_nodialogs = 0;
     custom_prepare_savestate ();
-    f = zfile_fopen (filename, L"w+b");
+    f = zfile_fopen (filename, L"w+b", 0);
     if (!f)
        return 0;
     if (savestate_specialdump) {
diff --git a/uaeunp.c b/uaeunp.c
new file mode 100644 (file)
index 0000000..32b64be
--- /dev/null
+++ b/uaeunp.c
@@ -0,0 +1,646 @@
+#include <stdio.h>
+#include <tchar.h>
+
+#include <windows.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "options.h"
+#include "zfile.h"
+#include "fsdb.h"
+#include "zarchive.h"
+
+TCHAR start_path_exe[MAX_DPATH];
+TCHAR start_path_data[MAX_DPATH];
+TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+
+struct uae_prefs currprefs;
+static int debug = 0;
+
+#define WRITE_LOG_BUF_SIZE 4096
+void write_log (const TCHAR *format, ...)
+{
+    int count;
+    TCHAR buffer[WRITE_LOG_BUF_SIZE];
+    va_list parms;
+    va_start (parms, format);
+    if (debug) {
+       count = _vsntprintf (buffer, WRITE_LOG_BUF_SIZE - 1, format, parms);
+       _tprintf (buffer);
+    }
+    va_end (parms);
+}
+
+void gui_message (const TCHAR *format, ...)
+{
+}
+
+int uaerand (void)
+{
+    return rand ();
+}
+
+static int pattern_match (const TCHAR *str, const TCHAR *pattern)
+{
+    enum State {
+        Exact,        // exact match
+        Any,        // ?
+        AnyRepeat    // *
+    };
+
+    const TCHAR *s = str;
+    const TCHAR *p = pattern;
+    const TCHAR *q = 0;
+    int state = 0;
+
+    int match = TRUE;
+    while (match && *p) {
+        if (*p == '*') {
+            state = AnyRepeat;
+            q = p+1;
+        } else if (*p == '?') state = Any;
+        else state = Exact;
+
+        if (*s == 0) break;
+
+        switch (state) {
+            case Exact:
+                match = *s == *p;
+                s++;
+                p++;
+                break;
+
+            case Any:
+                match = TRUE;
+                s++;
+                p++;
+                break;
+
+            case AnyRepeat:
+                match = TRUE;
+                s++;
+
+               if (*s == *q){
+                   // make a recursive call so we don't match on just a single character
+                   if (pattern_match(s,q) == TRUE) {
+                       p++;
+                   }
+               }
+                break;
+        }
+    }
+
+    if (state == AnyRepeat) return (*s == *q);
+    else if (state == Any) return (*s == *p);
+    else return match && (*s == *p);
+} 
+
+
+
+
+static void geterror (void)
+{
+    TCHAR *err = zfile_geterror();
+    if (!err)
+       return;
+    _tprintf (L"%s\n", err);
+}
+
+static const TCHAR *prots = L"HSPARWED";
+
+struct arcdir {
+    TCHAR *name;
+    int isdir;
+    uae_u32 flags;
+    uae_u64 size;
+    TCHAR *comment;
+    uae_u32 crc32;
+    __time64_t dt;
+    int parent, nextlevel;
+};
+
+static struct arcdir **filelist;
+
+static void dolist (struct arcdir **filelist, struct arcdir *adp, int entries, int parent, int level)
+{
+    int ii, i;
+
+    for (ii = 0; ii < 2; ii++) {
+       for (i = 0; i < entries; i++) {
+           struct arcdir *ad = filelist[i];
+           int j;
+           TCHAR protflags[9];
+           TCHAR dates[32];
+           int flags;
+           struct tm *dt;
+
+           if (ad->parent != parent)
+               continue;
+
+           if ((ii == 0 && ad->isdir) || (ii == 1 && !ad->isdir)) {
+
+               flags = ad->flags;
+
+               if (flags >= 0) {
+                   for (j = 0; j < 8; j++) {
+                       protflags[j] = '-';
+                       if (flags & (1 << (7 - j)))
+                           protflags[j] = prots[j];
+                   }
+                   protflags[j] = 0;
+               } else {
+                   _tcscpy (protflags, L"--------");
+               }
+
+               if (ad->dt > 0) {
+                   dt = _gmtime64 (&ad->dt);
+                   _tcsftime (dates, sizeof (dates) / sizeof (TCHAR), L"%Y/%m/%d %H:%M:%S", dt);
+               } else {
+                   _tcscpy (dates, L"-------------------");
+               }
+
+               for (j = 0; j < level; j++)
+                   _tprintf (L" ");
+               if (ad->isdir > 0)
+                   _tprintf (L"     [DIR] %s %s          %s\n", protflags, dates, ad->name);
+               else if (ad->isdir < 0)
+                   _tprintf (L"    [VDIR] %s %s          %s\n", protflags, dates, ad->name);
+               else
+                   _tprintf (L"%10I64d %s %s %08X %s\n", ad->size, protflags, dates, ad->crc32, ad->name);
+               if (ad->comment)
+                   _tprintf (L" \"%s\"\n", ad->comment);
+               if (ad->nextlevel >= 0) {
+                   level++;
+                   dolist (filelist, adp, entries, ad - adp, level);
+                   level--;
+               }
+
+           }
+       }
+    }
+}
+
+static int parentid = -1, subdirid;
+static int maxentries = 10000, entries;
+
+static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
+{
+    struct zvolume *zv;
+    void *h;
+    int i;
+    TCHAR p[MAX_DPATH];
+    TCHAR fn[MAX_DPATH];
+    struct arcdir *ad;
+   
+    zv = zfile_fopen_archive_root (src);
+    if (zv == NULL) {
+       geterror();
+       _tprintf (L"Couldn't open archive '%s'\n", src);
+       return 0;
+    }
+    h = zfile_opendir_archive (src);
+    if (!h) {
+       _tcscpy (p, src);
+       _tcscat (p, L".DIR");
+       h = zfile_opendir_archive (src);
+       if (!h) {
+           geterror();
+           _tprintf (L"Couldn't open directory '%s'\n", src);
+           return 0;
+       }
+    }
+
+    while (zfile_readdir_archive (h, fn)) {
+        struct _stat64 st; 
+        int isdir;
+       uae_u32 flags;
+        TCHAR *comment;
+       struct zfile *zf;
+       uae_u32 crc32 = 0;
+       int nextdir = -1;
+
+        _tcscpy (p, src);
+        _tcscat (p, sep);
+        _tcscat (p, fn);
+       if (!zfile_stat_archive (p, &st)) {
+           st.st_size = -1;
+           st.st_mtime = 0;
+       }
+       isdir = 0;
+       flags = 0;
+       comment = 0;
+       zfile_fill_file_attrs_archive (p, &isdir, &flags, &comment);
+       flags ^= 15;
+       if (!isdir) {
+           zf = zfile_open_archive (p, 0);
+           if (zf) {
+               crc32 = zfile_crc32 (zf);
+           }
+       }
+
+        ad = &adp[entries++];
+       ad->isdir = isdir;
+       ad->comment = comment;
+       ad->flags = flags;
+       ad->name = my_strdup (fn);
+       ad->size = st.st_size;
+       ad->dt = st.st_mtime;
+       ad->parent = parentid;
+       ad->crc32 = crc32;
+
+       if (isdir && all) {
+           int oldparent = parentid;
+           parentid = ad - adp;
+           nextdir = parentid + 1;
+           unlist2 (adp, p, all);
+           parentid = oldparent;
+       }
+
+       ad->nextlevel = nextdir;
+
+       if (entries >= maxentries)
+           break;
+    }
+    if (parentid >= 0)
+       return 1;
+
+    filelist = xmalloc (entries * sizeof (struct arcdir*));
+    for (i = 0; i < entries; i++) {
+       filelist[i] = &adp[i];
+    }
+
+    // bubblesort is the winner!
+    for (i = 0; i < entries; i++) {
+       int j;
+       for (j = i + 1; j < entries; j++) {
+           int diff = _tcsicmp (filelist[i]->name, filelist[j]->name);
+           if (diff > 0) {
+               struct arcdir *tmp;
+               tmp = filelist[i];
+               filelist[i] = filelist[j];
+               filelist[j] = tmp;
+           }
+       }
+    }
+
+    dolist (filelist, adp, entries, -1, 0);
+    zfile_closedir_archive (h);
+    return 1;
+}
+
+static int unlist (const TCHAR *src, int all)
+{
+    struct arcdir *adp;
+    adp = xcalloc (sizeof (struct arcdir), maxentries);
+    unlist2 (adp, src, all);
+    return 1;
+}
+
+static void setdate (const TCHAR *src, __time64_t tm)
+{
+    struct utimbuf ut;
+    if (tm) {
+       ut.actime = ut.modtime = tm;
+       utime (src, &ut);
+    }
+}
+
+static int found;
+
+static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, int out, int all, int level)
+{
+    void *h;
+    struct zvolume *zv;
+    int ret;
+    uae_u8 *b;
+    int size;
+    TCHAR fn[MAX_DPATH];
+
+    ret = 0;
+    zv = zfile_fopen_archive_root (src);
+    if (zv == NULL) {
+       geterror();
+       _tprintf (L"Couldn't open archive '%s'\n", src);
+       return 0;
+    }
+    h = zfile_opendir_archive (src);
+    if (!h) {
+       geterror();
+       _tprintf (L"Couldn't open directory '%s'\n", src);
+       return 0;
+    }
+    while (zfile_readdir_archive (h, fn)) {
+       if (all || !_tcsicmp (filename, fn)) {
+           TCHAR tmp[MAX_DPATH];
+           struct zfile *s, *d;
+           struct _stat64 st;
+
+           found = 1;
+           _tcscpy (tmp, src);
+           _tcscat (tmp, sep);
+           _tcscat (tmp, fn);
+           if (!zfile_stat_archive (tmp, &st)) {
+               _tprintf (L"Couldn't stat '%s'\n", tmp);
+               continue;
+           }
+           if (dst == NULL || all)
+               dst = fn;
+           if (st.st_mode) {
+               if (all > 0)
+                   continue;
+               if (all < 0) {
+                   TCHAR oldcur[MAX_DPATH];
+                   my_mkdir (fn);
+                   my_setcurrentdir (fn, oldcur);
+                   unpack (tmp, fn, dst, out, all, 1);
+                   my_setcurrentdir (oldcur, NULL);
+                   setdate (dst, st.st_mtime);
+                   continue;
+               }
+               _tprintf (L"Directory extraction not yet supported\n");
+               return 0;
+           }
+
+           s = zfile_open_archive (tmp, 0);
+           if (!s) {
+               geterror();
+               _tprintf (L"Couldn't open '%s' for reading\n", src);
+               continue;
+           }
+           zfile_fseek (s, 0, SEEK_END);
+           size = zfile_ftell (s);
+           zfile_fseek (s, 0, SEEK_SET);
+           b = xcalloc (size, 1);
+           if (b) {
+               if (zfile_fread (b, size, 1, s) == 1) {
+                   if (out) {
+                       _tprintf (L"\n");
+                       fwrite (b, size, 1, stdout);
+                   } else {
+                       d = zfile_fopen (dst, L"wb", 0);
+                       if (d) {
+                           if (zfile_fwrite (b, size, 1, d) == 1) {
+                               ret = 1;
+                               _tprintf (L"%s extracted, %d bytes\n", dst, size);
+                           }
+                           zfile_fclose (d);
+                           setdate (dst, st.st_mtime);
+                       }
+                   }
+               }
+               xfree (b);
+           }
+           zfile_fclose (s);
+           if (!all)
+               break;
+       }
+    }
+    if (!found && !level) {
+       _tprintf (L"'%s' not found\n", fn);
+    }
+    return ret;
+}
+
+static int unpack2 (const TCHAR *src, const TCHAR *match, int level)
+{
+    void *h;
+    struct zvolume *zv;
+    int ret;
+    uae_u8 *b;
+    int size;
+    TCHAR fn[MAX_DPATH];
+
+    ret = 0;
+    zv = zfile_fopen_archive_root (src);
+    if (zv == NULL) {
+       geterror();
+       _tprintf (L"Couldn't open archive '%s'\n", src);
+       return 0;
+    }
+    h = zfile_opendir_archive (src);
+    if (!h) {
+       geterror();
+       _tprintf (L"Couldn't open directory '%s'\n", src);
+       return 0;
+    }
+    while (zfile_readdir_archive (h, fn)) {
+        TCHAR tmp[MAX_DPATH];
+        TCHAR *dst;
+       struct zfile *s, *d;
+       int isdir, flags;
+
+       _tcscpy (tmp, src);
+       _tcscat (tmp, sep);
+       _tcscat (tmp, fn);
+       zfile_fill_file_attrs_archive (tmp, &isdir, &flags, NULL);
+       if (isdir) {
+           TCHAR *p = _tcsstr (fn, L".DIR");
+           if (isdir == ZNODE_VDIR && p && _tcslen (p) == 4) {
+               p[0] = 0;
+               if (pattern_match (fn, match))
+                   continue;
+               p[0] = '.';
+           }
+           unpack2 (tmp, match, 1);
+           continue;
+       }
+       
+       if (pattern_match (fn, match)) {
+           struct _stat64 st;
+
+           if (!zfile_stat_archive (tmp, &st)) {
+               st.st_mtime = -1;
+           }
+           found = 1;
+           dst = fn;
+           s = zfile_open_archive (tmp, 0);
+           if (!s) {
+               geterror();
+               _tprintf (L"Couldn't open '%s' for reading\n", src);
+               continue;
+           }
+           zfile_fseek (s, 0, SEEK_END); 
+           size = zfile_ftell (s);
+           zfile_fseek (s, 0, SEEK_SET);
+           b = xcalloc (size, 1);
+           if (b) {
+               if (zfile_fread (b, size, 1, s) == 1) {
+                   d = zfile_fopen (dst, L"wb", 0);
+                   if (d) {
+                       if (zfile_fwrite (b, size, 1, d) == 1) {
+                           ret = 1;
+                           _tprintf (L"%s extracted, %d bytes\n", dst, size);
+                       }
+                       zfile_fclose (d);
+                       setdate (dst, st.st_mtime);
+                   }
+               }
+               xfree (b);
+           }
+           zfile_fclose (s);
+       }
+    }
+    if (!found && !level) {
+       _tprintf (L"'%s' not matched\n", match);
+    }
+    return ret;
+}
+
+static int scanpath (TCHAR *src, TCHAR *outpath)
+{
+    struct zvolume *zv;
+    void *h;
+    TCHAR fn[MAX_DPATH];
+
+    zv = zfile_fopen_archive_root (src);
+    if (zv == NULL) {
+       geterror();
+       _tprintf (L"Couldn't open archive '%s'\n", src);
+       return 0;
+    }
+    h = zfile_opendir_archive (src);
+    if (!h) {
+       geterror();
+       _tprintf (L"Couldn't open directory '%s'\n", src);
+       return 0;
+    }
+    while (zfile_readdir_archive (h, fn)) {
+        TCHAR tmp[MAX_DPATH];
+       int isdir, flags;
+        _tcscpy (tmp, src);
+       _tcscat (tmp, sep);
+       _tcscat (tmp, fn);
+       zfile_fill_file_attrs_archive (tmp, &isdir, &flags, NULL);
+       if (isdir == ZNODE_VDIR) {
+           _tcscpy (outpath, tmp);
+           scanpath (tmp, outpath);
+           break;
+       }
+    }
+    return 1;
+}
+
+int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
+{
+    int ok = 0, i;
+    int list = 0, xtract = 0, extract = 0;
+    int out = 0, all = 0;
+    TCHAR path[MAX_DPATH], tmppath[MAX_DPATH];
+    int used[32] = { 0 };
+    TCHAR *parm2 = NULL;
+    TCHAR *parm3 = NULL;
+    TCHAR *match = NULL;
+    
+    for (i = 0; i < argc && i < 32; i++) {
+       if (!_tcsicmp (argv[i], L"o")) {
+           out = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"-o")) {
+           out = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"l")) {
+           list = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"-l")) {
+           list = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"x")) {
+           xtract = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"-x")) {
+           xtract = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"e")) {
+           extract = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"-e")) {
+           extract = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"*")) {
+           all = 1;
+           used[i] = 1;
+       }
+       if (!_tcsicmp (argv[i], L"**")) {
+           all = -1;
+           used[i] = 1;
+       }
+       if (!used[i] && (_tcschr (argv[i], '*') || _tcschr (argv[i], '?'))) {
+           extract = 1;
+           match = argv[i];
+           used[i] = 1;
+       }
+    }
+    for (i = 1; i < argc && i < 32; i++) {
+       if (!used[i]) {
+           GetFullPathName (argv[i], MAX_DPATH, path, NULL);
+           used[i] = 1;
+           break;
+       }
+    }
+    for (i = 1; i < argc && i < 32; i++) {
+       if (!used[i]) {
+           parm2 = argv[i];
+           used[i] = 1;
+           break;
+       }
+    }
+    for (i = 1; i < argc && i < 32; i++) {
+       if (!used[i]) {
+           parm3 = argv[i];
+           used[i] = 1;
+           break;
+       }
+    }
+
+//    _tcscpy (tmppath, path);
+//    scanpath (tmppath, path);
+
+    if (match) {
+       unpack2 (path, match, 0);
+       ok = 1;
+    } else if (!parm2 && all > 0) {
+       unpack2 (path, L"*", 0);
+       ok = 1;
+    } else if (extract && parm2) {
+       unpack2 (path, parm2, 0);
+       ok = 1;
+    } else if (argc == 2 || (argc > 2 && list)) {
+       unlist (path, all);
+       ok = 1;
+    } else if (((xtract && parm2) || all || (argc >= 3 && parm2)) && !out) {
+       unpack (path, parm2, parm3, 0, all, 0);
+       ok = 1;
+    } else if (parm2 && (argc >= 4 && out)) {
+       unpack (path, parm2, parm3, 1, all, 0);
+       ok = 1;
+    }
+    if (!ok) {
+       _tprintf (L"UAE unpacker uaeunp 0.4c by Toni Wilen (c)2009\n");
+       _tprintf (L"\n");
+       _tprintf (L"List: \"uaeunp (-l) <path>\"\n");
+       _tprintf (L"List all recursively: \"uaeunp -l <path> **\"\n");
+       _tprintf (L"Extract to file: \"uaeunp (-x) <path> <filename> [<dst name>]\"\n");
+       _tprintf (L"Extract all (single directory): \"uaeunp (-x) <path> *\"\n");
+       _tprintf (L"Extract all (recursively): \"uaeunp (-x) <path> **\"\n");
+       _tprintf (L"Extract all (recursively, current dir): \"uaeunp -e <path> <match string>\"\n");
+       _tprintf (L"Output to console: \"uaeunp (-x) -o <path> <filename>\"\n");
+       _tprintf (L"\n");
+       _tprintf (L"Supported disk image formats:\n");
+       _tprintf (L" ADF and HDF (OFS/FFS), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+       _tprintf (L"Supported archive formats:\n");
+       _tprintf (L" 7ZIP, LHA, LZX, RAR (unrar.dll), ZIP, ArchiveAccess.DLL\n");
+       _tprintf (L"Miscellaneous formats:\n");
+       _tprintf (L" RDB partition table, GZIP\n");
+
+
+    }
+    return 0;
+}
diff --git a/zfile.c b/zfile.c
index 5f9101f3a5bd10a2e66474bc8a7ebaf337a2013d..608ab21125cb142318bde5a68117c347ed2d3d53 100644 (file)
--- a/zfile.c
+++ b/zfile.c
@@ -9,6 +9,7 @@
 
 #define ZLIB_WINAPI
 #define RECURSIVE_ARCHIVES 1
+//#define ZFILE_DEBUG
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -21,6 +22,8 @@
 #include "fsdb.h"
 #include "fsusage.h"
 #include "zarchive.h"
+#include "diskutil.h"
+#include "fdi2raw.h"
 
 #include "archivers/zip/unzip.h"
 #include "archivers/dms/pfile.h"
@@ -53,6 +56,7 @@ static void zfile_free (struct zfile *f)
     }
     xfree (f->name);
     xfree (f->data);
+    xfree (f->mode);
     xfree (f);
 }
 
@@ -94,6 +98,7 @@ void zfile_fclose (struct zfile *f)
 
 static uae_u8 exeheader[]={ 0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00 };
 static TCHAR *diskimages[] = { L"adf", L"adz", L"ipf", L"fdi", L"dms", L"wrp", L"dsq", 0 };
+
 int zfile_gettype (struct zfile *z)
 {
     uae_u8 buf[8];
@@ -125,7 +130,7 @@ int zfile_gettype (struct zfile *z)
     memset (buf, 0, sizeof (buf));
     zfile_fread (buf, 8, 1, z);
     zfile_fseek (z, -8, SEEK_CUR);
-    if (!memcmp (buf, exeheader, sizeof(buf)))
+    if (!memcmp (buf, exeheader, sizeof (buf)))
        return ZFILE_DISKIMAGE;
     if (!memcmp (buf, "RDSK", 4))
        return ZFILE_HDFRDB;
@@ -140,8 +145,6 @@ int zfile_gettype (struct zfile *z)
     return ZFILE_UNKNOWN;
 }
 
-static struct zfile *zuncompress (struct zfile *z, int);
-
 struct zfile *zfile_gunzip (struct zfile *z)
 {
     uae_u8 header[2 + 1 + 1 + 4 + 1 + 1];
@@ -199,7 +202,7 @@ struct zfile *zfile_gunzip (struct zfile *z)
     if (size < 8 || size > 64 * 1024 * 1024) /* safety check */
        return z;
     zfile_fseek (z, offset, SEEK_SET);
-    z2 = zfile_fopen_empty (name, size);
+    z2 = zfile_fopen_empty (z, name, size);
     if (!z2)
        return z;
     zs.next_out = z2->data;
@@ -224,41 +227,241 @@ struct zfile *zfile_gunzip (struct zfile *z)
     return z2;
 }
 
-static struct zfile *dsq (struct zfile *z)
+static struct zfile *extadf (struct zfile *z)
 {
+    int i, r;
     struct zfile *zo;
+    uae_u16 *mfm;
+    uae_u16 *amigamfmbuffer;
+    uae_u8 writebuffer_ok[11];
+    int tracks, size, len, offs, pos;
+    uae_u8 buffer[2 + 2 + 4 + 4];
+
+    mfm = xcalloc (32000, 1);
+    amigamfmbuffer = xcalloc (32000, 1);
+
+    zfile_fread (buffer, 1, 8, z);
+    zfile_fread (buffer, 1, 4, z);
+    tracks = buffer[2] * 256 + buffer[3];
+    offs = 8 + 2 + 2 + tracks * (2 + 2 + 4 + 4);
+
+    size = tracks * 512 * 11;
+    zo = zfile_fopen_empty (z, zfile_getname (z), size);
+    if (!zo)
+       goto end;
 
-    zo = zfile_fopen_empty (L"zipped.dsq", 1760 * 512);
-    if (zo) {
-       struct zvolume *zv = archive_directory_lzx (z);
-       if (zv) {
-           if (zv->root.child) {
-               struct zfile *zi = archive_access_lzx (zv->root.child);
-               if (zi && zi->data && zi->size > 1000) {
-                   uae_u8 *buf = zi->data;
-                   if (!memcmp (buf, "PKD\x13", 4) || !memcmp (buf, "PKD\x11", 4)) {
-                       int sectors = buf[18];
-                       int heads = buf[15];
-                       int blocks = (buf[6] << 8) | buf[7];
-                       int blocksize = (buf[10] << 8) | buf[11];
-                       if (blocksize == 512 && blocks == 1760 && sectors == 22 && heads == 2) {
-                           int off = buf[3] == 0x13 ? 52 : 32;
-                           int i;
-                           for (i = 0; i < blocks / (sectors / heads); i++) {
-                               zfile_fwrite (zi->data + off, sectors * blocksize / heads, 1, zo);
-                               off += sectors * (blocksize + 16) / heads;
-                           }
-                           zfile_fclose_archive (zv);
-                           zfile_fclose (z);
-                           return zo;
-                       }
-                   }
-               }
-               zfile_fclose (zi);
+    pos = 12;
+    for (i = 0; i < tracks; i++) {
+       int type, bitlen;
+       
+       zfile_fseek (z, pos, SEEK_SET);
+       zfile_fread (buffer, 2 + 2 + 4 + 4, 1, z);
+       pos = zfile_ftell (z);
+       type = buffer[2] * 256 + buffer[3];
+       len = buffer[5] * 65536 + buffer[6] * 256 + buffer[7];
+       bitlen = buffer[9] * 65536 + buffer[10] * 256 + buffer[11];
+
+       zfile_fseek (z, offs, SEEK_SET);
+       if (type == 1) {
+           zfile_fread (mfm, len, 1, z);
+           memset (writebuffer_ok, 0, sizeof writebuffer_ok);
+           r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
+           if (r < 0 && i == 0) {
+               zfile_seterror (L"'%s' is not AmigaDOS formatted", zo->name);
+               goto end;
            }
+       } else {
+           zfile_fread (zo->data + i * 512 * 11, 11 * 512, 1, z);
+       }
+
+       offs += len;
+
+    }
+    zfile_fclose (z);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return zo;
+end:
+    zfile_fclose (zo);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return z;
+}
+
+
+#include "fdi2raw.h"
+static struct zfile *fdi (struct zfile *z)
+{
+    int i, j, r;
+    struct zfile *zo;
+    TCHAR *orgname = zfile_getname (z);
+    TCHAR *ext = _tcsrchr (orgname, '.');
+    TCHAR newname[MAX_DPATH];
+    uae_u16 *mfm;
+    uae_u16 *amigamfmbuffer;
+    uae_u8 writebuffer_ok[11];
+    int tracks, size, len;
+    FDI *fdi;
+
+    fdi = fdi2raw_header (z);
+    if (!fdi)
+       return z;
+    mfm = xcalloc (32000, 1);
+    amigamfmbuffer = xcalloc (32000, 1);
+    tracks = fdi2raw_get_last_track (fdi);
+    size = tracks * 512 * 11;
+    if (ext) {
+       _tcscpy (newname, orgname);
+       _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
+    } else {
+       _tcscat (newname, L".adf");
+    }
+    zo = zfile_fopen_empty (z, newname, size);
+    if (!zo)
+       goto end;
+    for (i = 0; i < tracks; i++) {
+       uae_u8 *p = (uae_u8*)mfm;
+       fdi2raw_loadtrack (fdi, mfm, NULL, i, &len, NULL, NULL, 1);
+       len /= 8;
+       for (j = 0; j < len / 2; j++) {
+           uae_u16 v = mfm[j];
+           *p++ = v >> 8;
+           *p++ = v;
+       }
+       memset (writebuffer_ok, 0, sizeof writebuffer_ok);
+       r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
+       if (r < 0 && i == 0) {
+           zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
+           goto end;
        }
+    }
+    zfile_fclose (z);
+    fdi2raw_header_free (fdi);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return zo;
+end:
+    if (zo)
        zfile_fclose (zo);
+    fdi2raw_header_free (fdi);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return z;
+}
+
+
+#ifdef CAPS
+#include "caps/caps_win32.h"
+static struct zfile *ipf (struct zfile *z)
+{
+    int i, j, r;
+    struct zfile *zo;
+    TCHAR *orgname = zfile_getname (z);
+    TCHAR *ext = _tcsrchr (orgname, '.');
+    TCHAR newname[MAX_DPATH];
+    uae_u16 *mfm;
+    uae_u16 *amigamfmbuffer;
+    uae_u8 writebuffer_ok[11];
+    int tracks, size, len;
+
+
+    if (!caps_loadimage (z, 0, &tracks))
+       return z;
+    mfm = xcalloc (32000, 1);
+    amigamfmbuffer = xcalloc (32000, 1);
+    size = tracks * 512 * 11;
+    if (ext) {
+       _tcscpy (newname, orgname);
+       _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
+    } else {
+       _tcscat (newname, L".adf");
     }
+    zo = zfile_fopen_empty (z, newname, size);
+    if (!zo)
+       goto end;
+    for (i = 0; i < tracks; i++) {
+       uae_u8 *p = (uae_u8*)mfm;
+       caps_loadrevolution (mfm, 0, i, &len);
+       len /= 8;
+       for (j = 0; j < len / 2; j++) {
+           uae_u16 v = mfm[j];
+           *p++ = v >> 8;
+           *p++ = v;
+       }
+       memset (writebuffer_ok, 0, sizeof writebuffer_ok);
+       r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
+       if (r < 0 && i == 0) {
+           zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
+           goto end;
+       }
+    }
+    caps_unloadimage (0);
+    zfile_fclose (z);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return zo;
+end:
+    if (zo)
+       zfile_fclose (zo);
+    caps_unloadimage (0);
+    xfree (mfm);
+    xfree (amigamfmbuffer);
+    return z;
+}
+#endif
+
+static struct zfile *dsq (struct zfile *z, int lzx)
+{
+    struct zfile *zi = NULL;
+    struct zvolume *zv = NULL;
+
+    if (lzx) {
+       zv = archive_directory_lzx (z);
+       if (zv) {
+           if (zv->root.child)
+               zi = archive_access_lzx (zv->root.child);
+       }
+    } else {
+       zi = z;
+    }
+    if (zi) {
+        uae_u8 *buf = zfile_getdata (zi, 0, -1);
+       if (!memcmp (buf, "PKD\x13", 4) || !memcmp (buf, "PKD\x11", 4)) {
+           TCHAR *fn;
+           int sectors = buf[18];
+           int heads = buf[15];
+           int blocks = (buf[6] << 8) | buf[7];
+           int blocksize = (buf[10] << 8) | buf[11];
+           struct zfile *zo;
+           int size = blocks * blocksize;
+           int off = buf[3] == 0x13 ? 52 : 32;
+           int i;
+
+           if (size < 1760 * 512)
+               size = 1760 * 512;
+
+           if (zfile_getfilename (zi) && _tcslen (zfile_getfilename (zi))) {
+               fn = xmalloc ((_tcslen (zfile_getfilename (zi)) + 5) * sizeof (TCHAR));
+               _tcscpy (fn, zfile_getfilename (zi));
+               _tcscat (fn, L".adf");
+           } else {
+               fn = my_strdup (L"dsq.adf");
+           }
+           zo = zfile_fopen_empty (z, fn, size);
+           xfree (fn);
+           for (i = 0; i < blocks / (sectors / heads); i++) {
+               zfile_fwrite (buf + off, sectors * blocksize / heads, 1, zo);
+               off += sectors * (blocksize + 16) / heads;
+           }
+           zfile_fclose_archive (zv);
+           zfile_fclose (z);
+           xfree (buf);
+           return zo;
+       }
+       xfree (buf);
+    }
+    if (lzx)
+       zfile_fclose (zi);
     return z;
 }
 
@@ -271,13 +474,24 @@ static struct zfile *dms (struct zfile *z)
 {
     int ret;
     struct zfile *zo;
+    TCHAR *orgname = zfile_getname (z);
+    TCHAR *ext = _tcsrchr (orgname, '.');
+    TCHAR newname[MAX_DPATH];
 
-    zo = zfile_fopen_empty (L"undms.adf", 1760 * 512);
+    if (ext) {
+       _tcscpy (newname, orgname);
+       _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
+    } else {
+       _tcscat (newname, L".adf");
+    }
+
+    zo = zfile_fopen_empty (z, newname, 1760 * 512);
     if (!zo)
        return z;
     ret = DMS_Process_File (z, zo, CMD_UNPACK, OPT_VERBOSE, 0, 0);
     if (ret == NO_PROBLEM || ret == DMS_FILE_END) {
        zfile_fclose (z);
+       zfile_fseek (zo, 0, SEEK_SET);
        return zo;
     }
     return z;
@@ -314,9 +528,14 @@ int zfile_isdiskimage (const TCHAR *name)
 }
 
 
-static const TCHAR *plugins_7z[] = { L"7z", L"rar", L"zip", L"lha", L"lzh", L"lzx", NULL };
-static const TCHAR *plugins_7z_x[] = { L"7z", L"Rar!", L"MK", NULL, NULL, NULL, NULL };
-static const int plugins_7z_t[] = { ArchiveFormat7Zip, ArchiveFormatRAR, ArchiveFormatZIP, ArchiveFormatLHA, ArchiveFormatLHA, ArchiveFormatLZX };
+static const TCHAR *plugins_7z[] = { L"7z", L"rar", L"zip", L"lha", L"lzh", L"lzx", L"adf", L"dsq", NULL };
+static const uae_char *plugins_7z_x[] = { "7z", "Rar!", "MK", NULL, NULL, NULL, NULL, NULL, NULL };
+static const int plugins_7z_t[] = {
+    ArchiveFormat7Zip, ArchiveFormatRAR, ArchiveFormatZIP, ArchiveFormatLHA, ArchiveFormatLHA, ArchiveFormatLZX,
+    ArchiveFormatADF, ArchiveFormatADF };
+static const int plugins_7z_m[] = {
+    ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE, ZFD_ARCHIVE,
+    ZFD_ADF, ZFD_ADF };
 
 int iszip (struct zfile *z)
 {
@@ -324,88 +543,175 @@ int iszip (struct zfile *z)
     TCHAR *ext = _tcsrchr (name, '.');
     uae_u8 header[7];
     int i;
+    int mask = z->zfdmask;
 
+    if (!mask)
+       return 0;
     if (!ext)
        return 0;
     memset (header, 0, sizeof (header));
     zfile_fseek (z, 0, SEEK_SET);
     zfile_fread (header, sizeof (header), 1, z);
     zfile_fseek (z, 0, SEEK_SET);
-    if (!strcasecmp (ext, L".zip") && header[0] == 'P' && header[1] == 'K')
-       return ArchiveFormatZIP;
-    if (!strcasecmp (ext, L".7z") && header[0] == '7' && header[1] == 'z')
-       return ArchiveFormat7Zip;
-    if (!strcasecmp (ext, L".rar") && header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
-       return ArchiveFormatRAR;
-    if ((!strcasecmp (ext, L".lha") || !strcasecmp (ext, L".lzh")) && header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
-       return ArchiveFormatLHA;
-    if (!strcasecmp (ext, L".lzx") && header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
-       return ArchiveFormatLZX;
+    
+    if (mask & ZFD_ARCHIVE) {
+       if (!strcasecmp (ext, L".zip")) {
+           if (header[0] == 'P' && header[1] == 'K')
+               return ArchiveFormatZIP;
+           return 0;
+       }
+    }
+    if (mask & ZFD_ARCHIVE) {
+       if (!strcasecmp (ext, L".7z")) {
+           if (header[0] == '7' && header[1] == 'z')
+               return ArchiveFormat7Zip;
+           return 0;
+       }
+       if (!strcasecmp (ext, L".rar")) {
+           if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
+               return ArchiveFormatRAR;
+           return 0;
+       }
+       if (!strcasecmp (ext, L".lha") || !strcasecmp (ext, L".lzh")) {
+           if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
+               return ArchiveFormatLHA;
+           return 0;
+       }
+       if (!strcasecmp (ext, L".lzx")) {
+           if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
+               return ArchiveFormatLZX;
+           return 0;
+       }
+    }
+    if (mask & ZFD_ADF) {
+       if (!strcasecmp (ext, L".adf")) {
+           if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
+               return ArchiveFormatADF;
+           return 0;
+       }
+    }
+    if (mask & ZFD_HD) {
+       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] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
+               return ArchiveFormatRDB;
+           return 0;
+       }
+    }
 #if defined(ARCHIVEACCESS)
     for (i = 0; plugins_7z_x[i]; i++) {
-       if (plugins_7z_x[i] && !strcasecmp (ext + 1, plugins_7z[i]) &&
-           !memcmp (header, plugins_7z_x[i], _tcslen (plugins_7z_x[i])))
+       if ((plugins_7z_m[i] & mask) && plugins_7z_x[i] && !strcasecmp (ext + 1, plugins_7z[i]) &&
+           !memcmp (header, plugins_7z_x[i], strlen (plugins_7z_x[i])))
                return plugins_7z_t[i];
     }
 #endif
     return 0;
 }
 
-static struct zfile *zuncompress (struct zfile *z, int dodefault)
+struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
 {
     TCHAR *name = z->name;
-    TCHAR *ext = _tcsrchr (name, '.');
-    uae_u8 header[7];
+    TCHAR *ext = NULL;
+    uae_u8 header[8];
     int i;
 
+    if (!mask)
+       return z;
+    if (name) {
+       ext = _tcsrchr (name, '.');
+       if (ext)
+           ext++;
+    }
+
     if (ext != NULL) {
-       ext++;
-       if (strcasecmp (ext, L"7z") == 0)
-            return archive_access_select (z, ArchiveFormat7Zip, dodefault);
-       if (strcasecmp (ext, L"zip") == 0)
-            return archive_access_select (z, ArchiveFormatZIP, dodefault);
-       if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
-            return archive_access_select (z, ArchiveFormatLHA, dodefault);
-       if (strcasecmp (ext, L"lzx") == 0)
-            return archive_access_select (z, ArchiveFormatLZX, dodefault);
-       if (strcasecmp (ext, L"rar") == 0)
-            return archive_access_select (z, ArchiveFormatRAR, dodefault);
-       if (strcasecmp (ext, L"gz") == 0)
-            return zfile_gunzip (z);
-       if (strcasecmp (ext, L"adz") == 0)
-            return zfile_gunzip (z);
-       if (strcasecmp (ext, L"roz") == 0)
-            return zfile_gunzip (z);
-       if (strcasecmp (ext, L"hdz") == 0)
-            return zfile_gunzip (z);
-       if (strcasecmp (ext, L"dms") == 0)
-            return dms (z);
-       if (strcasecmp (ext, L"wrp") == 0)
-            return wrp (z);
-       if (strcasecmp (ext, L"dsq") == 0)
-            return dsq (z);
+       if (mask & ZFD_ARCHIVE) {
+           if (strcasecmp (ext, L"7z") == 0)
+                return archive_access_select (z, ArchiveFormat7Zip, dodefault);
+           if (strcasecmp (ext, L"zip") == 0)
+                return archive_access_select (z, ArchiveFormatZIP, dodefault);
+           if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
+                return archive_access_select (z, ArchiveFormatLHA, dodefault);
+           if (strcasecmp (ext, L"lzx") == 0)
+                return archive_access_select (z, ArchiveFormatLZX, dodefault);
+           if (strcasecmp (ext, L"rar") == 0)
+                return archive_access_select (z, ArchiveFormatRAR, dodefault);
+       }
+       if (mask & ZFD_UNPACK) {
+           if (strcasecmp (ext, L"gz") == 0)
+                return zfile_gunzip (z);
+           if (strcasecmp (ext, L"adz") == 0)
+                return zfile_gunzip (z);
+           if (strcasecmp (ext, L"roz") == 0)
+                return zfile_gunzip (z);
+           if (strcasecmp (ext, L"hdz") == 0)
+                return zfile_gunzip (z);
+           if (strcasecmp (ext, L"dms") == 0)
+                return dms (z);
+           if (strcasecmp (ext, L"wrp") == 0)
+                return wrp (z);
+       }
+       if (mask & ZFD_RAWDISK) {
+#ifdef CAPS
+           if (strcasecmp (ext, L"ipf") == 0)
+                return ipf (z);
+#endif
+           if (strcasecmp (ext, L"fdi") == 0)
+                return fdi (z);
+       }
 #if defined(ARCHIVEACCESS)
        for (i = 0; plugins_7z_x[i]; i++) {
-           if (strcasecmp (ext, plugins_7z[i]) == 0)
-               return archive_access_arcacc_select (z, plugins_7z_t[i]);
+           if ((plugins_7z_t[i] & mask) && strcasecmp (ext, plugins_7z[i]) == 0)
+               return archive_access_arcacc_select (z, plugins_7z_t[i]);
        }
 #endif
-       memset (header, 0, sizeof (header));
-       zfile_fseek (z, 0, SEEK_SET);
-       zfile_fread (header, sizeof (header), 1, z);
-       zfile_fseek (z, 0, SEEK_SET);
+    }
+    memset (header, 0, sizeof (header));
+    zfile_fseek (z, 0, SEEK_SET);
+    zfile_fread (header, sizeof (header), 1, z);
+    zfile_fseek (z, 0, SEEK_SET);
+    if (mask & ZFD_UNPACK) {
        if (header[0] == 0x1f && header[1] == 0x8b)
            return zfile_gunzip (z);
-       if (header[0] == 'P' && header[1] == 'K')
-            return archive_access_select (z, ArchiveFormatZIP, dodefault);
-       if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
-            return archive_access_select (z, ArchiveFormatRAR, dodefault);
        if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
            return dms (z);
+       if (header[0] == 'P' && header[1] == 'K' && header[2] == 'D')
+           return dsq (z, 0);
+    }
+    if (mask & ZFD_RAWDISK) {
+#ifdef CAPS
+       if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S')
+            return ipf (z);
+#endif
+       if (!memcmp (header, "Formatte", 8))
+           return fdi (z);
+       if (!memcmp (header, "UAE-1ADF", 8))
+           return extadf (z);
+    }
+    if (mask & ZFD_ARCHIVE) {
+        if (header[0] == 'P' && header[1] == 'K')
+           return archive_access_select (z, ArchiveFormatZIP, dodefault);
+        if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
+           return archive_access_select (z, ArchiveFormatRAR, dodefault);
        if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
-            return archive_access_select (z, ArchiveFormatLZX, dodefault);
+           return archive_access_select (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 (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);
+    }
+
+    if (ext) {
+       if (mask & ZFD_UNPACK) {
+           if (strcasecmp (ext, L"dsq") == 0)
+               return dsq (z, 1);
+       }
+       if (mask & ZFD_ADF) {
+           if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
+               return archive_access_select (z, ArchiveFormatADF, dodefault);
+       }
     }
     return z;
 }
@@ -422,7 +728,8 @@ static struct zfile *zfile_opensinglefile(struct zfile *l)
 
     _tcscpy (tmp, l->name);
     s = tmp + _tcslen (tmp) - 1;
-    while (*s != 0 && *s != '/' && *s != '\\') s--;
+    while (*s != 0 && *s != '/' && *s != '\\')
+       s--;
     if (s > tmp)
        s++;
     write_log (L"loading from singlefile: '%s'\n", tmp);
@@ -448,7 +755,7 @@ static struct zfile *zfile_opensinglefile(struct zfile *l)
 }
 #endif
 
-struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
+static struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
 {
     struct zfile *l;
     FILE *f;
@@ -457,6 +764,7 @@ struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
        return NULL;
     l = zfile_create ();
     l->name = my_strdup (name);
+    l->mode = my_strdup (mode);
     f = _tfopen (name, mode);
     if (!f) {
        zfile_fclose (l);
@@ -466,7 +774,6 @@ struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
     return l;
 }
 
-
 static struct zfile *openzip (const TCHAR *pname)
 {
     int i, j;
@@ -499,7 +806,7 @@ static struct zfile *openzip (const TCHAR *pname)
     return 0;
 }
 
-static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode)
+static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int mask)
 {
     struct zfile *l;
     FILE *f;
@@ -516,9 +823,12 @@ static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode)
            zfile_fclose (l);
            return 0;
        }
+       l->zfdmask = mask;
     } else {
        l = zfile_create ();
+       l->mode = my_strdup (mode);
        l->name = my_strdup (name);
+       l->zfdmask = mask;
        if (!_tcsicmp (mode, L"r")) {
            f = my_opentext (l->name);
            l->textmode = 1;
@@ -551,7 +861,7 @@ static void manglefilename (TCHAR *out, const TCHAR *in)
 #else
 static void manglefilename(TCHAR *out, const TCHAR *in)
 {
-    _tcscpy(out, in);
+    _tcscpy (out, in);
 }
 #endif
 
@@ -562,7 +872,7 @@ int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
     TCHAR path[MAX_DPATH];
 
     manglefilename (path, name);
-    l = zfile_fopen_2 (path, L"rb");
+    l = zfile_fopen_2 (path, L"rb", ZFD_NORMAL);
     if (!l)
        return 0;
     ztype = iszip (l);
@@ -574,22 +884,25 @@ int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
     return 1;
 }
 
+
 /*
  * fopen() for a compressed file
  */
-struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode)
+struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
 {
     int cnt = 10;
     struct zfile *l, *l2;
     TCHAR path[MAX_DPATH];
 
     manglefilename (path, name);
-    l = zfile_fopen_2 (path, mode);
+    l = zfile_fopen_2 (path, mode, mask);
     if (!l)
        return 0;
+    if (_tcschr (mode, 'w') || _tcschr (mode, 'a'))
+       return l;
     l2 = NULL;
     while (cnt-- > 0) {
-       l = zuncompress (l, 0);
+       l = zuncompress (l, 0, mask);
        if (!l)
            break;
        zfile_fseek (l, 0, SEEK_SET);
@@ -603,18 +916,33 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode)
 struct zfile *zfile_dup (struct zfile *zf)
 {
     struct zfile *nzf;
-    if (!zf || !zf->data)
+    if (!zf)
        return NULL;
-    nzf = zfile_create ();
-    nzf->data = xmalloc (zf->size);
-    memcpy (nzf->data, zf->data, zf->size);
-    nzf->size = zf->size;
+    if (zf->data) {
+       nzf = zfile_create ();
+       nzf->data = xmalloc (zf->size);
+       memcpy (nzf->data, zf->data, zf->size);
+       nzf->size = zf->size;
+    } else if (zf->zipname) {
+       nzf = openzip (zf->name);
+       return nzf;
+    } else {
+       nzf = zfile_create ();
+        nzf->f = _tfopen (zf->name, zf->mode);
+    }
+    zfile_fseek (nzf, zf->seek, SEEK_SET);
+    if (zf->name)
+        nzf->name = my_strdup (zf->name);
+    if (nzf->zipname)
+        nzf->zipname = my_strdup (zf->zipname);
+    nzf->zfdmask = zf->zfdmask;
+    nzf->mode = my_strdup (zf->mode);
     return nzf;
 }
 
 int zfile_exists (const TCHAR *name)
 {
-    TCHAR fname[2000];
+    TCHAR fname[MAX_DPATH];
     struct zfile *f;
 
     if (_tcslen (name) == 0)
@@ -640,7 +968,7 @@ int zfile_iscompressed (struct zfile *z)
     return z->data ? 1 : 0;
 }
 
-struct zfile *zfile_fopen_empty (const TCHAR *name, uae_u64 size)
+struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 size)
 {
     struct zfile *l;
     l = zfile_create ();
@@ -652,6 +980,9 @@ struct zfile *zfile_fopen_empty (const TCHAR *name, uae_u64 size)
        l->data = xcalloc (1, 1);
        l->size = 0;
     }
+    if (prev) {
+       l->zfdmask = prev->zfdmask;
+    }
     return l;
 }
 
@@ -836,8 +1167,11 @@ uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len)
 {
     uae_s64 pos;
     uae_u8 *b;
-    if (len < 0)
-       len = z->size;
+    if (len < 0) {
+       zfile_fseek (z, 0, SEEK_END);
+       len = zfile_ftell (z);
+       zfile_fseek (z, 0, SEEK_SET);
+    }
     b = xmalloc (len);
     if (z->data) {
        memcpy (b, z->data + offset, len);
@@ -908,6 +1242,20 @@ TCHAR *zfile_getname (struct zfile *f)
     return f->name;
 }
 
+TCHAR *zfile_getfilename (struct zfile *f)
+{
+    int i;
+    if (f->name == NULL)
+       return NULL;
+    for (i = _tcslen (f->name) - 1; i >= 0; i--) {
+        if (f->name[i] == '\\' || f->name[i] == '/' || f->name[i] == ':') {
+           i++;
+           return &f->name[i];
+       }
+    }
+    return f->name;
+}
+
 uae_u32 zfile_crc32 (struct zfile *f)
 {
     uae_u8 *p;
@@ -935,14 +1283,64 @@ uae_u32 zfile_crc32 (struct zfile *f)
 
 static struct zvolume *zvolume_list;
 
+static void recurparent (TCHAR *newpath, struct znode *zn, int recurse)
+{
+    TCHAR tmp[2] = { FSDB_DIR_SEPARATOR, 0 };
+    if (zn->parent && (&zn->volume->root != zn->parent || zn->volume->parentz == NULL)) {
+       if (&zn->volume->root == zn->parent && zn->volume->parentz == NULL && !_tcscmp (zn->name, zn->parent->name))
+           goto end;
+       recurparent (newpath, zn->parent, recurse);
+    } else {
+       struct zvolume *zv = zn->volume;
+       if (zv->parentz && recurse)
+           recurparent (newpath, zv->parentz, recurse);
+    }
+end:
+    if (newpath[0])
+       _tcscat (newpath, tmp);
+    _tcscat (newpath, zn->name);
+}
+
 static struct znode *znode_alloc (struct znode *parent, const TCHAR *name)
 {
     TCHAR fullpath[MAX_DPATH];
+    TCHAR tmpname[MAX_DPATH];
     struct znode *zn = xcalloc (sizeof (struct znode), 1);
+    struct znode *zn2;
+    TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+
+    _tcscpy (tmpname, name);
+    zn2 = parent->child;
+    while (zn2) {
+       if (!_tcscmp (zn2->name, tmpname)) {
+           TCHAR *ext = _tcsrchr (tmpname, '.');
+           if (ext && ext > tmpname + 2 && ext[-2] == '.') {
+               ext[-1]++;
+           } else if (ext) {
+               memmove (ext + 2, ext, (_tcslen (ext) + 1) * sizeof (TCHAR));
+               ext[0] = '.';
+               ext[1] = '1';
+           } else {
+               int len = _tcslen (tmpname);
+               tmpname[len] = '.';
+               tmpname[len + 1] = '1';
+               tmpname[len + 2] = 0;
+           }
+           zn2 = parent->child;
+           continue;
+       }
+       zn2 = zn2->sibling;
+    }
 
-    _stprintf (fullpath, L"%s%c%s", parent->fullname, FSDB_DIR_SEPARATOR, name);
+    fullpath[0] = 0;
+    recurparent (fullpath, parent, FALSE);
+    _tcscat (fullpath, sep);
+    _tcscat (fullpath, tmpname);
+#ifdef ZFILE_DEBUG
+    write_log (L"znode_alloc vol='%s' parent='%s' name='%s'\n", parent->volume->root.name, parent->name, name);
+#endif
     zn->fullname = my_strdup (fullpath);
-    zn->name = my_strdup (name);
+    zn->name = my_strdup (tmpname);
     zn->volume = parent->volume;
     zn->volume->last->next = zn;
     zn->prev = zn->volume->last;
@@ -995,11 +1393,12 @@ static void zvolume_addtolist (struct zvolume *zv)
     }
 }
 
-static struct zvolume *zvolume_alloc_2 (const TCHAR *name, struct zfile *z, unsigned int id, void *handle)
+static struct zvolume *zvolume_alloc_2 (const TCHAR *name, struct zfile *z, unsigned int id, void *handle, const TCHAR *volname)
 {
     struct zvolume *zv = xcalloc (sizeof (struct zvolume), 1);
     struct znode *root;
     uae_s64 pos;
+    int i;
 
     root = &zv->root;
     zv->last = root;
@@ -1007,9 +1406,28 @@ static struct zvolume *zvolume_alloc_2 (const TCHAR *name, struct zfile *z, unsi
     zv->handle = handle;
     zv->id = id;
     zv->blocks = 4;
+    if (z)
+       zv->zfdmask = z->zfdmask;
     root->volume = zv;
-    root->name = my_strdup (name);
+    root->type = ZNODE_DIR;
+    i = 0;
+    if (name[0] != '/' && name[0] != '\\') {
+       if (_tcschr (name, ':') == 0) {
+           for (i = _tcslen (name) - 1; i > 0; i--) {
+               if (name[i] == FSDB_DIR_SEPARATOR) {
+                   i++;
+                   break;
+               }
+           }
+       }
+    }
+    root->name = my_strdup (name + i);
     root->fullname = my_strdup (name);
+#ifdef ZFILE_DEBUG
+    write_log (L"created zvolume: '%s' (%s)\n", root->name, root->fullname);
+#endif
+    if (volname)
+       zv->volumename = my_strdup (volname);
     if (z) {
        pos = zfile_ftell (z);
        zfile_fseek (z, 0, SEEK_END);
@@ -1018,13 +1436,18 @@ static struct zvolume *zvolume_alloc_2 (const TCHAR *name, struct zfile *z, unsi
     }
     return zv;
 }
-struct zvolume *zvolume_alloc (struct zfile *z, unsigned int id, void *handle)
+struct zvolume *zvolume_alloc (struct zfile *z, unsigned int id, void *handle, const TCHAR *volumename)
 {
-    return zvolume_alloc_2 (zfile_getname (z), z, id, handle);
+    return zvolume_alloc_2 (zfile_getname (z), z, id, handle, volumename);
 }
-struct zvolume *zvolume_alloc_empty (const TCHAR *name)
+struct zvolume *zvolume_alloc_empty (struct zvolume *prev, const TCHAR *name)
 {
-    return zvolume_alloc_2(name, 0, 0, 0);
+    struct zvolume *zv = zvolume_alloc_2(name, 0, 0, 0, NULL);
+    if (!zv)
+       return NULL;
+    if (prev)
+       zv->zfdmask = prev->zfdmask;
+    return zv;
 }
 
 static struct zvolume *get_zvolume (const TCHAR *path)
@@ -1032,7 +1455,7 @@ static struct zvolume *get_zvolume (const TCHAR *path)
     struct zvolume *zv = zvolume_list;
     while (zv) {
        TCHAR *s = zfile_getname (zv->archive);
-       if (_tcslen (path) >= _tcslen(s) && !memcmp (path, s, _tcslen(s)))
+       if (_tcslen (path) >= _tcslen (s) && !memcmp (path, s, _tcslen (s) * sizeof (TCHAR)))
            return zv;
        zv = zv->next;
     }
@@ -1042,8 +1465,19 @@ static struct zvolume *get_zvolume (const TCHAR *path)
 static struct zvolume *zfile_fopen_archive_ext (struct zfile *zf)
 {
     struct zvolume *zv = NULL;
-    TCHAR *ext = _tcsrchr (zfile_getname(zf), '.');
+    TCHAR *name = zfile_getname (zf);
+    TCHAR *ext;
+    uae_u8 header[7];
+
+    if (!name)
+       return NULL;
+
+    memset (header, 0, sizeof (header));
+    zfile_fseek (zf, 0, SEEK_SET);
+    zfile_fread (header, sizeof (header), 1, zf);
+    zfile_fseek (zf, 0, SEEK_SET);
 
+    ext = _tcsrchr (name, '.');
     if (ext != NULL) {
        ext++;
        if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
@@ -1056,6 +1490,14 @@ static struct zvolume *zfile_fopen_archive_ext (struct zfile *zf)
             zv = archive_directory_lzx (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);
+       if (strcasecmp (ext, L"hdf") == 0)  {
+           if (!memcmp (header, "RDSK", 4))
+               zv = archive_directory_rdb (zf);
+           else
+               zv = archive_directory_adf (zf);
+       }
     }
     return zv;
 }
@@ -1077,10 +1519,39 @@ struct zvolume *zfile_fopen_archive_data (struct zfile *zf)
         zv = archive_directory_lzx (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);
+    if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
+        zv = archive_directory_rdb (zf);
     return zv;
 }
 
-static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath);
+static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath, int);
+
+static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn)
+{
+    struct zvolume *zvnew;
+    struct znode *zndir;
+    TCHAR tmp[MAX_DPATH];
+
+    _stprintf (tmp, L"%s.DIR", zn->fullname + _tcslen (zv->root.name) + 1);
+    zndir = get_znode (zv, tmp, TRUE);
+    if (!zndir) {
+       struct zarchive_info zai = { 0 };
+       zvnew = zvolume_alloc_empty (zv, tmp);
+       zvnew->parentz = zn;
+       zai.name = tmp;
+       zai.t = zn->mtime;
+       zai.comment = zv->volumename;
+       if (zn->flags < 0)
+           zai.flags = zn->flags;
+       zndir = zvolume_adddir_abs (zv, &zai);
+       zndir->type = ZNODE_VDIR;
+       zndir->vfile = zn;
+       zndir->vchild = zvnew;
+       zvnew->parent = zv;
+    }
+}
 
 static int zfile_fopen_archive_recurse (struct zvolume *zv)
 {
@@ -1090,54 +1561,41 @@ static int zfile_fopen_archive_recurse (struct zvolume *zv)
     added = 0;
     zn = zv->root.child;
     while (zn) {
+       struct zfile *z;
        TCHAR *ext = _tcsrchr (zn->name, '.');
-       if (ext && !zn->vchild && zn->isfile) {
+       if (ext && !zn->vchild && zn->type == ZNODE_FILE) {
            for (i = 0; plugins_7z[i]; i++) {
                if (!strcasecmp (ext + 1, plugins_7z[i])) {
-                   struct zvolume *zvnew;
-                   struct znode *zndir;
-                   TCHAR tmp[MAX_DPATH];
-
-                   _stprintf (tmp, L"%s.DIR", zn->fullname + _tcslen (zv->root.name) + 1);
-                   zndir = get_znode (zv, tmp);
-                   if (!zndir) {
-                       struct zarchive_info zai = { 0 };
-                       zvnew = zvolume_alloc_empty (tmp);
-                       zai.name = tmp;
-                       zai.t = zn->mtime;
-                       zndir = zvolume_adddir_abs (zv, &zai);
-                       zndir->vfile = zn;
-                       zndir->vchild = zvnew;
-                       zvnew->parent = zv;
-                   }
+                   zfile_fopen_archive_recurse2 (zv, zn);
                }
            }
        }
+       z = archive_getzfile (zn, zv->method);
+       if (z && iszip (z))
+           zfile_fopen_archive_recurse2 (zv, zn);
        zn = zn->next;
     }
     return 0;
 }
 
-static void recursivepath (TCHAR *path, struct zvolume *zv)
-{
-    TCHAR tmp[2] = { FSDB_DIR_SEPARATOR, 0 };
-    if (!zv)
-       return;
-    recursivepath (path, zv->parent);
-    _tcscat (path, zv->root.fullname);
-    _tcscat (path, tmp);
-}
-
 static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR *path)
 {
     struct zfile *zf = NULL;
     struct zvolume *zvnew = NULL;
 
+#ifdef ZFILE_DEBUG
     write_log (L"unpacking '%s'\n", path);
+#endif
     zf = zfile_open_archive (path, 0);
     if (!zf)
        goto end;
     zvnew = zfile_fopen_archive_ext (zf);
+    if (!zvnew) {
+       struct zfile *zf2 = zf;
+       zf = zuncompress (zf2, 0, 1);
+       if (zf != zf2)
+           zvnew = archive_directory_plain (zf);
+    }
     if (!zvnew)
        goto end;
     zvnew->parent = zv->parent;
@@ -1145,57 +1603,55 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
     zfile_fclose_archive (zv);
     return zvnew;
 end:
-    write_log (L"unpack failed\n");
+    write_log (L"unpack '%s' failed\n", path);
     zfile_fclose_archive (zvnew);
     zfile_fclose (zf);
     return NULL;
 }
 
-static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath)
+static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath, int recurse)
 {
     struct znode *zn;
-    int prevlen = 0;
-    TCHAR path[MAX_DPATH];
+    TCHAR path[MAX_DPATH], zpath[MAX_DPATH];
 
     if (!zv)
        return NULL;
     _tcscpy (path, ppath);
     zn = &zv->root;
     while (zn) {
-       if (zn->isfile) {
-           if (!_tcsicmp (zn->fullname, path))
+       zpath[0] = 0;
+       recurparent (zpath, zn, recurse);
+       if (zn->type == ZNODE_FILE) {
+           if (!_tcsicmp (zpath, path))
                return zn;
        } else {
-           int len = _tcslen (zn->fullname);
-           if (_tcslen (path) >= len && (path[len] == 0 || path[len] == FSDB_DIR_SEPARATOR) && !_tcsncmp (zn->fullname, path, len)) {
+           int len = _tcslen (zpath);
+           if (_tcslen (path) >= len && (path[len] == 0 || path[len] == FSDB_DIR_SEPARATOR) && !_tcsnicmp (zpath, path, len)) {
                if (path[len] == 0)
                    return zn;
                if (zn->vchild) {
                    /* jump to separate tree, recursive archives */
                    struct zvolume *zvdeep = zn->vchild;
-                   TCHAR *p = path + prevlen + 1;
                    if (zvdeep->archive == NULL) {
-                       zvdeep = prepare_recursive_volume (zvdeep, zn->fullname);
+                       TCHAR newpath[MAX_DPATH];
+                       newpath[0] = 0;
+                       recurparent (newpath, zn, recurse);
+#ifdef ZFILE_DEBUG
+                       write_log (L"'%s'\n", newpath);
+#endif
+                       zvdeep = prepare_recursive_volume (zvdeep, newpath);
                        if (!zvdeep) {
-                           write_log (L"failed to unpack '%s'\n", zn->fullname);
+                           write_log (L"failed to unpack '%s'\n", newpath);
                            return NULL;
                        }
                        /* replace dummy empty volume with real volume */
                        zn->vchild = zvdeep;
+                       zvdeep->parentz = zn;
                    }
                    zn = zvdeep->root.child;
-                   while (*p && *p != FSDB_DIR_SEPARATOR)
-                       p++;
-                   if (*p == 0)
-                       return NULL;
-                   p++;
-                   _tcscpy (path, zn->volume->root.name);
-                   memmove (path + _tcslen (path) + 1, p, _tcslen (p) + 1);
-                   path[_tcslen(path)] = FSDB_DIR_SEPARATOR;
                } else {
                    zn = zn->child;
                }
-               prevlen = len;
                continue;
            }
        }
@@ -1204,7 +1660,6 @@ static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath)
     return NULL;
 }
 
-
 static void addvolumesize (struct zvolume *zv, uae_s64 size)
 {
     unsigned int blocks = (size + 511) / 512;
@@ -1222,13 +1677,22 @@ struct znode *znode_adddir (struct znode *parent, const TCHAR *name, struct zarc
 {
     struct znode *zn;
     TCHAR path[MAX_DPATH];
+    TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
 
-    _stprintf (path, L"%s%c%s", parent->fullname, FSDB_DIR_SEPARATOR, name);
-    zn = get_znode (parent->volume, path);
+    path[0] = 0;
+    recurparent (path, parent, FALSE);
+    _tcscat (path, sep);
+    _tcscat (path, name);
+    zn = get_znode (parent->volume, path, FALSE);
     if (zn)
        return zn;
     zn = znode_alloc_child (parent, name);
     zn->mtime = zai->t;
+    zn->type = ZNODE_DIR;
+    if (zai->comment)
+       zn->comment = my_strdup (zai->comment);
+    if (zai->flags < 0)
+       zn->flags = zai->flags;
     addvolumesize (parent->volume, 0);
     return zn;
 }
@@ -1280,7 +1744,7 @@ struct znode *zvolume_addfile_abs (struct zvolume *zv, struct zarchive_info *zai
     if (p2) {
        zn = znode_alloc_child (zn2, p2);
        zn->size = zai->size;
-       zn->isfile = 1;
+       zn->type = ZNODE_FILE;
        zn->mtime = zai->t;
        if (zai->comment)
            zn->comment = my_strdup (zai->comment);
@@ -1298,16 +1762,30 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename)
 
     if (!zf)
        return NULL;
+    zf->zfdmask = ZFD_ALL;
     zv = zfile_fopen_archive_ext (zf);
     if (!zv)
        zv = zfile_fopen_archive_data (zf);
-#if RECURSIVE_ARCHIVES
-    if (zv)
-       zfile_fopen_archive_recurse (zv);
+#if 0
+    if (!zv) {
+       struct zfile *zf2 = zuncompress (zf, 0, 0);
+       if (zf2 != zf) {
+           zf = zf2;
+           zv = zfile_fopen_archive_ext (zf);
+           if (!zv)
+               zv = zfile_fopen_archive_data (zf);
+       }
+    }
 #endif
     /* pointless but who cares? */
     if (!zv)
        zv = archive_directory_plain (zf);
+
+#if RECURSIVE_ARCHIVES
+    if (zv)
+       zfile_fopen_archive_recurse (zv);
+#endif
+
     if (zv)
        zvolume_addtolist (zv);
     else
@@ -1315,6 +1793,55 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename)
     return zv;
 }
 
+struct zvolume *zfile_fopen_archive_root (const TCHAR *filename)
+{
+    TCHAR path[MAX_DPATH], *p1, *p2, *lastp;
+    struct zvolume *zv = NULL;
+    //int last = 0;
+    int num, i;
+
+    num = 1;
+    lastp = NULL;
+    for (;;) {
+       _tcscpy (path, filename);
+       p1 = p2 = path;
+       for (i = 0; i < num; i++) {
+           while (*p1 != FSDB_DIR_SEPARATOR && *p1 != 0)
+               p1++;
+           if (*p1 == 0 && p1 == lastp)
+               return NULL;
+           if (i + 1 < num)
+               p1++;
+       }
+       *p1 = 0;
+       lastp = p1;
+       if (my_existsfile (p2))
+           return zfile_fopen_archive (p2);
+       num++;
+    }
+
+#if 0
+    while (!last) {
+       while (*p1 != FSDB_DIR_SEPARATOR && *p1 != 0)
+           p1++;
+       if (*p1 == 0)
+           last = 1;
+       *p1 = 0;
+       if (!zv) {
+           zv = zfile_fopen_archive (p2);
+           if (!zv)
+               return NULL;
+       } else {
+           struct znode *zn = get_znode (zv, p2);
+           if (!zn)
+               return NULL;
+       }
+       p2 = p1 + 1;
+    }
+    return zv;
+#endif
+}
+
 void zfile_fclose_archive (struct zvolume *zv)
 {
     struct znode *zn;
@@ -1352,27 +1879,32 @@ void zfile_fclose_archive (struct zvolume *zv)
 }
 
 struct zdirectory {
+    struct znode *first;
     struct znode *n;
 };
 
 void *zfile_opendir_archive (const TCHAR *path)
 {
     struct zvolume *zv = get_zvolume (path);
-    struct znode *zn = get_znode (zv, path);
-    struct zdirectory *zd = xmalloc (sizeof (struct zdirectory));
+    struct znode *zn = get_znode (zv, path, TRUE);
+    struct zdirectory *zd;
 
     if (!zn || (!zn->child && !zn->vchild))
        return NULL;
+    zd = xmalloc (sizeof (struct zdirectory));
     if (zn->child) {
        zd->n = zn->child;
     } else {
        if (zn->vchild->archive == NULL) {
            struct zvolume *zvnew = prepare_recursive_volume (zn->vchild, path);
-           if (zvnew)
+           if (zvnew) {
                zn->vchild = zvnew;
+               zvnew->parentz = zn;
+           }
        }
        zd->n = zn->vchild->root.next;
     }
+    zd->first = zd->n;
     return zd;
 }
 void zfile_closedir_archive (struct zdirectory *zd)
@@ -1387,20 +1919,28 @@ int zfile_readdir_archive (struct zdirectory *zd, TCHAR *out)
     zd->n = zd->n->sibling;
     return 1;
 }
+void zfile_resetdir_archive (struct zdirectory *zd)
+{
+    zd->n = zd->first;
+}
 
 int zfile_fill_file_attrs_archive (const TCHAR *path, int *isdir, int *flags, TCHAR **comment)
 {
     struct zvolume *zv = get_zvolume (path);
-    struct znode *zn = get_znode (zv, path);
+    struct znode *zn = get_znode (zv, path, TRUE);
 
     *isdir = 0;
     *flags = 0;
-    *comment = 0;
+    if (comment)
+       *comment = 0;
     if (!zn)
        return 0;
-    *isdir = zn->isfile ? 0 : 1;
+    if (zn->type == ZNODE_DIR)
+       *isdir = 1;
+    else if (zn->type == ZNODE_VDIR)
+       *isdir = -1;
     *flags = zn->flags;
-    if (zn->comment)
+    if (zn->comment && comment)
        *comment = my_strdup (zn->comment);
     return 1;
 }
@@ -1419,11 +1959,12 @@ int zfile_fs_usage_archive (const TCHAR *path, const TCHAR *disk, struct fs_usag
 int zfile_stat_archive (const TCHAR *path, struct _stat64 *s)
 {
     struct zvolume *zv = get_zvolume (path);
-    struct znode *zn = get_znode (zv, path);
+    struct znode *zn = get_znode (zv, path, TRUE);
 
+    memset (s, 0, sizeof (struct _stat64));
     if (!zn)
        return 0;
-    s->st_mode = zn->isfile ? 0 : FILEFLAG_DIR;
+    s->st_mode = zn->type == ZNODE_FILE ? 0 : FILEFLAG_DIR;
     s->st_size = zn->size;
     s->st_mtime = zn->mtime;
     return 1;
@@ -1449,7 +1990,7 @@ void zfile_close_archive (void *d)
 void *zfile_open_archive (const TCHAR *path, int flags)
 {
     struct zvolume *zv = get_zvolume (path);
-    struct znode *zn = get_znode (zv, path);
+    struct znode *zn = get_znode (zv, path, TRUE);
     struct zfile *z;
 
     if (!zn)
@@ -1475,16 +2016,18 @@ int zfile_exists_archive (const TCHAR *path, const TCHAR *rel)
 
     _stprintf (tmp, L"%s%c%s", path, FSDB_DIR_SEPARATOR, rel);
     zv = get_zvolume (tmp);
-    zn = get_znode (zv, tmp);
+    zn = get_znode (zv, tmp, TRUE);
     return zn ? 1 : 0;
 }
 
 int zfile_convertimage (const TCHAR *src, const TCHAR *dst)
 {
     struct zfile *s, *d;
+    struct zvolume *zv;
     int ret = 0;
 
-    s = zfile_fopen (src, L"rb");
+    zv = zfile_open_archive (src, 0);
+    s = zfile_fopen (src, L"rb", ZFD_NORMAL);
     if (s) {
        uae_u8 *b;
        int size;
@@ -1494,7 +2037,7 @@ int zfile_convertimage (const TCHAR *src, const TCHAR *dst)
        b = xcalloc (size, 1);
        if (b) {
            if (zfile_fread (b, size, 1, s) == 1) {
-               d = zfile_fopen (dst, L"wb");
+               d = zfile_fopen (dst, L"wb", 0);
                if (d) {
                    if (zfile_fwrite (b, size, 1, d) == 1)
                        ret = 1;
@@ -1506,4 +2049,29 @@ int zfile_convertimage (const TCHAR *src, const TCHAR *dst)
        zfile_fclose (s);
     }
     return ret;
-}
\ No newline at end of file
+}
+
+#ifdef _CONSOLE
+static TCHAR *zerror;
+#define WRITE_LOG_BUF_SIZE 4096
+void zfile_seterror (const TCHAR *format, ...)
+{
+    int count;
+    if (!zerror) {
+       TCHAR buffer[WRITE_LOG_BUF_SIZE];
+       va_list parms;
+       va_start (parms, format);
+        count = _vsntprintf (buffer, WRITE_LOG_BUF_SIZE - 1, format, parms);
+        zerror = my_strdup (buffer);
+       va_end (parms);
+    }
+}
+TCHAR *zfile_geterror (void)
+{
+    return zerror;
+}
+#else
+void zfile_seterror (const TCHAR *format, ...)
+{
+}
+#endif
\ No newline at end of file
index 2db235408cd2ef87a13ed268df6ba3dd7d6c0576..d17dd102ab885ae22833a1af37507b9a22b50e80 100644 (file)
@@ -46,7 +46,7 @@ static time_t fromdostime (uae_u32 dd)
 
 static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
 {
-    struct zvolume *zv;
+    struct zvolume *zv = NULL;
 
     switch (id)
     {
@@ -68,15 +68,22 @@ static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
        case ArchiveFormatPLAIN:
        zv = archive_directory_plain (zf);
        break;
+       case ArchiveFormatADF:
+       zv = archive_directory_adf (zf);
+       break;
+       case ArchiveFormatRDB:
+       zv = archive_directory_rdb (zf);
+       break;
     }
     if (!zv)
        zv = archive_directory_arcacc (zf, id);
     return zv;
 }
 
-struct zfile *archive_getzfile(struct znode *zn, unsigned int id)
+struct zfile *archive_getzfile (struct znode *zn, unsigned int id)
 {
     struct zfile *zf = NULL;
+
     switch (id)
     {
        case ArchiveFormatZIP:
@@ -97,6 +104,12 @@ struct zfile *archive_getzfile(struct znode *zn, unsigned int id)
        case ArchiveFormatPLAIN:
        zf = archive_access_plain (zn);
        break;
+       case ArchiveFormatADF:
+       zf = archive_access_adf (zn);
+       break;
+       case ArchiveFormatRDB:
+       zf = archive_access_rdb (zn);
+       break;
     }
     return zf;
 }
@@ -121,13 +134,15 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode
     while (zn) {
        int isok = 1;
 
-       if (!zn->isfile)
+       if (zn->type != ZNODE_FILE)
            isok = 0;
        if (zfile_is_ignore_ext (zn->fullname))
            isok = 0;
        if (isok) {
            if (tmphist[0]) {
+#ifndef _CONSOLE
                DISK_history_add (tmphist, -1);
+#endif
                tmphist[0] = 0;
                first = 0;
            }
@@ -136,7 +151,9 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode
                    _tcscpy (tmphist, zn->fullname);
            } else {
                _tcscpy (tmphist, zn->fullname);
+#ifndef _CONSOLE
                DISK_history_add (tmphist, -1);
+#endif
                tmphist[0] = 0;
            }
            select = 0;
@@ -159,10 +176,12 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode
            }
        }
        zipcnt++;
-       zn = zn->next;
+       zn = zn->sibling;
     }
+#ifndef _CONSOLE
     if (first && tmphist[0])
        DISK_history_add (zfile_getname(zf), -1);
+#endif
     zfile_fclose_archive (zv);
     if (z) {
        zfile_fclose (zf);
@@ -184,12 +203,12 @@ 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 (zf, id);
     if (!zv)
        return;
     zn = &zv->root;
     while (zn) {
-       if (zn->isfile) {
+       if (zn->type == ZNODE_FILE) {
            struct zfile *zf2 = archive_getzfile (zn, id);
            if (zf2) {
                int ztype = iszip (zf2);
@@ -203,7 +222,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig
                }
            }
        }
-       zn = zn->next;
+       zn = zn->sibling;
     }
     zfile_fclose_archive (zv);
 }
@@ -212,7 +231,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig
 
 static void archive_close_zip (void *handle)
 {
-    unzClose(handle);
+    unzClose (handle);
 }
 
 struct zvolume *archive_directory_zip (struct zfile *z)
@@ -227,7 +246,7 @@ struct zvolume *archive_directory_zip (struct zfile *z)
        return 0;
     if (unzGoToFirstFile (uz) != UNZ_OK)
        return 0;
-    zv = zvolume_alloc (z, ArchiveFormatZIP, uz);
+    zv = zvolume_alloc (z, ArchiveFormatZIP, uz, NULL);
     for (;;) {
        char filename_inzip2[MAX_DPATH];
        TCHAR c;
@@ -245,13 +264,14 @@ struct zvolume *archive_directory_zip (struct zfile *z)
        memset(&zai, 0, sizeof zai);
        zai.name = filename_inzip;
        zai.t = t;
+       zai.flags = -1;
        c = filename_inzip[_tcslen (filename_inzip) - 1];
        if (c != '/' && c != '\\') {
            int err = unzOpenCurrentFile (uz);
            if (err == UNZ_OK) {
                struct znode *zn;
                zai.size = file_info.uncompressed_size;
-               zn = zvolume_addfile_abs(zv, &zai);
+               zn = zvolume_addfile_abs (zv, &zai);
            }
        } else {
            filename_inzip[_tcslen (filename_inzip) - 1] = 0;
@@ -275,7 +295,7 @@ struct zfile *archive_access_zip (struct znode *zn)
     TCHAR tmp[MAX_DPATH];
     char *s;
 
-    _tcscpy (tmp, zn->fullname + _tcslen(zn->volume->root.fullname) + 1);
+    _tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1);
     if (unzGoToFirstFile (uz) != UNZ_OK)
        return 0;
     for (i = 0; tmp[i]; i++) {
@@ -299,7 +319,7 @@ struct zfile *archive_access_zip (struct znode *zn)
     s = NULL;
     if (unzOpenCurrentFile (uz) != UNZ_OK)
        return 0;
-    z = zfile_fopen_empty (zn->fullname, zn->size);
+    z = zfile_fopen_empty (uz, zn->fullname, zn->size);
     if (z) {
        err = unzReadCurrentFile (uz, z->data, zn->size);
     }
@@ -309,38 +329,46 @@ struct zfile *archive_access_zip (struct znode *zn)
 
 /* 7Z */
 
+#include "archivers/7z/Types.h"
 #include "archivers/7z/7zCrc.h"
-#include "archivers/7z/7zIn.h"
-#include "archivers/7z/7zExtract.h"
+#include "archivers/7z/Archive/7z/7zIn.h"
+#include "archivers/7z/Archive/7z/7zExtract.h"
+#include "archivers/7z/Archive/7z/7zAlloc.h"
 
-typedef struct _CFileInStream
+static ISzAlloc allocImp;
+static ISzAlloc allocTempImp;
+
+typedef struct
 {
-  ISzInStream InStream;
+  ISeekInStream s;
   struct zfile *zf;
 } CFileInStream;
 
-static ISzAlloc allocImp;
-static ISzAlloc allocTempImp;
 
-static SZ_RESULT SzFileReadImp (void *object, void *buffer, size_t size, size_t *processedSize)
+
+static SRes SzFileReadImp (void *object, void *buffer, size_t *size)
 {
   CFileInStream *s = (CFileInStream *)object;
-  size_t processedSizeLoc = zfile_fread (buffer, 1, size, s->zf);
-  if (processedSize != 0)
-    *processedSize = processedSizeLoc;
+  *size = zfile_fread (buffer, 1, *size, s->zf);
   return SZ_OK;
 }
 
-static SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+static SRes SzFileSeekImp(void *object, Int64 *pos, ESzSeek origin)
 {
   CFileInStream *s = (CFileInStream *)object;
-  int res = zfile_fseek (s->zf, pos, SEEK_SET);
-  if (res == 0)
-    return SZ_OK;
-  return SZE_FAIL;
+  int org = 0;
+  switch (origin)
+  {
+    case SZ_SEEK_SET: org = SEEK_SET; break;
+    case SZ_SEEK_CUR: org = SEEK_CUR; break;
+    case SZ_SEEK_END: org = SEEK_END; break;
+  }
+  zfile_fseek (s->zf, *pos, org);
+  *pos = zfile_ftell (s->zf);
+  return 0;
 }
 
-static void init_7z(void)
+static void init_7z (void)
 {
     static int initialized;
 
@@ -351,13 +379,15 @@ static void init_7z(void)
     allocImp.Free = SzFree;
     allocTempImp.Alloc = SzAllocTemp;
     allocTempImp.Free = SzFreeTemp;
-    InitCrcTable ();
+    CrcGenerateTable ();
+    _tzset ();
 }
 
 struct SevenZContext
 {
-    CArchiveDatabaseEx db;
+    CSzArEx db;
     CFileInStream archiveStream;
+    CLookToRead lookStream;
     Byte *outBuffer;
     size_t outBufferSize;
     UInt32 blockIndex;
@@ -365,40 +395,59 @@ struct SevenZContext
 
 static void archive_close_7z (struct SevenZContext *ctx)
 {
-    SzArDbExFree (&ctx->db, allocImp.Free);
-    allocImp.Free (ctx->outBuffer);
+    SzArEx_Free (&ctx->db, &allocImp);
+    allocImp.Free (&allocImp, ctx->outBuffer);
     xfree (ctx);
 }
 
+#define EPOCH_DIFF 0x019DB1DED53E8000LL /* 116444736000000000 nsecs */
+#define RATE_DIFF 10000000 /* 100 nsecs */
+
 struct zvolume *archive_directory_7z (struct zfile *z)
 {
-    SZ_RESULT res;
+    SRes res;
     struct zvolume *zv;
     int i;
     struct SevenZContext *ctx;
 
-    init_7z();
+    init_7z ();
     ctx = xcalloc (sizeof (struct SevenZContext), 1);
     ctx->blockIndex = 0xffffffff;
-    ctx->archiveStream.InStream.Read = SzFileReadImp;
-    ctx->archiveStream.InStream.Seek = SzFileSeekImp;
-    SzArDbExInit (&ctx->db);
+    ctx->archiveStream.s.Read = SzFileReadImp;
+    ctx->archiveStream.s.Seek = SzFileSeekImp;
     ctx->archiveStream.zf = z;
-    res = SzArchiveOpen (&ctx->archiveStream.InStream, &ctx->db, &allocImp, &allocTempImp);
+    LookToRead_CreateVTable (&ctx->lookStream, False);
+    ctx->lookStream.realStream = &ctx->archiveStream.s;
+    LookToRead_Init (&ctx->lookStream);
+
+    SzArEx_Init (&ctx->db);
+    res = SzArEx_Open (&ctx->db, &ctx->lookStream.s, &allocImp, &allocTempImp);
     if (res != SZ_OK) {
-       write_log (L"7Z: SzArchiveOpen %s returned %d\n", zfile_getname(z), res);
+       write_log (L"7Z: SzArchiveOpen %s returned %d\n", zfile_getname (z), res);
+       xfree (ctx);
        return NULL;
     }
-    zv = zvolume_alloc (z, ArchiveFormat7Zip, ctx);
-    for (i = 0; i < ctx->db.Database.NumFiles; i++) {
-       CFileItem *f = ctx->db.Database.Files + i;
+    zv = zvolume_alloc (z, ArchiveFormat7Zip, ctx, NULL);
+    for (i = 0; i < ctx->db.db.NumFiles; i++) {
+       CSzFileItem *f = ctx->db.db.Files + i;
        TCHAR *name = au (f->Name);
        struct zarchive_info zai;
 
        memset(&zai, 0, sizeof zai);
        zai.name = name;
+       zai.flags = -1;
        zai.size = f->Size;
-       if (!f->IsDirectory) {
+       zai.t = 0;
+       if (f->MTimeDefined) {
+           uae_u64 t = (((uae_u64)f->MTime.High) << 32) | f->MTime.Low;
+           if (t >= EPOCH_DIFF) {
+               zai.t = (t - EPOCH_DIFF) / RATE_DIFF;
+               zai.t -= _timezone;
+               if (_daylight)
+                   zai.t += 1 * 60 * 60;
+           }
+       }
+       if (!f->IsDir) {
            struct znode *zn = zvolume_addfile_abs (zv, &zai);
            zn->offset = i;
        }
@@ -410,7 +459,7 @@ struct zvolume *archive_directory_7z (struct zfile *z)
 
 struct zfile *archive_access_7z (struct znode *zn)
 {
-    SZ_RESULT res;
+    SRes res;
     struct zvolume *zv = zn->volume;
     struct zfile *z = NULL;
     size_t offset;
@@ -418,12 +467,12 @@ struct zfile *archive_access_7z (struct znode *zn)
     struct SevenZContext *ctx;
 
     ctx = zv->handle;
-    res = SzExtract (&ctx->archiveStream.InStream, &ctx->db, zn->offset,
+    res = SzAr_Extract (&ctx->db, &ctx->lookStream.s, zn->offset,
                    &ctx->blockIndex, &ctx->outBuffer, &ctx->outBufferSize,
                    &offset, &outSizeProcessed,
                    &allocImp, &allocTempImp);
     if (res == SZ_OK) {
-       z = zfile_fopen_empty (zn->fullname, zn->size);
+       z = zfile_fopen_empty (NULL, zn->fullname, zn->size);
        zfile_fwrite (ctx->outBuffer + offset, zn->size, 1, z);
     } else {
        write_log (L"7Z: SzExtract %s returned %d\n", zn->fullname, res);
@@ -461,7 +510,7 @@ static int rar_resetf (struct zfile *z)
     return 1;
 }
 
-static int canrar(void)
+static int canrar (void)
 {
     static int israr;
 
@@ -510,7 +559,7 @@ struct RARContext
 
 static void archive_close_rar (struct RARContext *rc)
 {
-    xfree(rc);
+    xfree (rc);
 }
 
 struct zvolume *archive_directory_rar (struct zfile *z)
@@ -526,7 +575,7 @@ struct zvolume *archive_directory_rar (struct zfile *z)
         /* wtf? stupid unrar.dll only accept filename as an input.. */
        return archive_directory_arcacc (z, ArchiveFormatRAR);
     rc = xcalloc (sizeof (struct RARContext), 1);
-    zv = zvolume_alloc (z, ArchiveFormatRAR, rc);
+    zv = zvolume_alloc (z, ArchiveFormatRAR, rc, NULL);
     fclose (z->f); /* bleh, unrar.dll fails to open the archive if it is already open.. */
     z->f = NULL;
     rc->OpenArchiveData.ArcNameW = z->name;
@@ -546,16 +595,17 @@ struct zvolume *archive_directory_rar (struct zfile *z)
     while (pRARReadHeaderEx (rc->hArcData, &rc->HeaderData) == 0) {
        struct zarchive_info zai;
        struct znode *zn;
-       memset(&zai, 0, sizeof zai);
+       memset (&zai, 0, sizeof zai);
        zai.name = rc->HeaderData.FileNameW;
        zai.size = rc->HeaderData.UnpSize;
+       zai.flags = -1;
        zai.t = fromdostime (rc->HeaderData.FileTime);
        zn = zvolume_addfile_abs (zv, &zai);
        zn->offset = cnt++;
        pRARProcessFile (rc->hArcData, RAR_SKIP, NULL, NULL);
     }
     pRARCloseArchive (rc->hArcData);
-    zftmp = zfile_fopen_empty (z->name, 0);
+    zftmp = zfile_fopen_empty (z, z->name, 0);
     zv->archive = zftmp;
     zv->method = ArchiveFormatRAR;
     return zv;
@@ -582,7 +632,7 @@ struct zfile *archive_access_rar (struct znode *zn)
                goto end;
        }
     }
-    zf = zfile_fopen_empty (zn->fullname, zn->size);
+    zf = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
     rarunpackzf = zf;
     if (pRARProcessFile (rc->hArcData, RAR_TEST, NULL, NULL)) {
        zfile_fclose (zf);
@@ -612,9 +662,9 @@ struct aaFileInArchiveInfo {
        uae_u64 CompressedFileSize;
        uae_u64 UncompressedFileSize;
        uae_u32 attributes;
-       int IsDir, IsEncrypted;
+       int IsDir;
        struct aaFILETIME LastWriteTime;
-       TCHAR path[FileInArchiveInfoStringSize];
+       char path[FileInArchiveInfoStringSize];
 };
 
 typedef HRESULT (__stdcall *aaReadCallback)(int StreamID, uae_u64 offset, uae_u32 count, void* buf, uae_u32 *processedSize);
@@ -715,7 +765,7 @@ struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id)
 
     if (!arcacc_init (z))
        return NULL;
-    zv = zvolume_alloc(z, id, NULL);
+    zv = zvolume_alloc (z, id, NULL, NULL);
     id_r = arcacc_push (z);
     ah = aaOpenArchive (readCallback, id_r, zv->archivesize, id, &status, NULL);
     if (!status) {
@@ -732,11 +782,13 @@ struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id)
            if (fi.IsDir)
                continue;
 
-           name = fi.path;
-           memset(&zai, 0, sizeof zai);
+           name = au (fi.path);
+           memset (&zai, 0, sizeof zai);
            zai.name = name;
+           zai.flags = -1;
            zai.size = (unsigned int)fi.UncompressedFileSize;
-           zn = zvolume_addfile_abs(zv, &zai);
+           zn = zvolume_addfile_abs (zv, &zai);
+           xfree (name);
            zn->offset = f;
            zn->method = id;
 
@@ -770,7 +822,7 @@ struct zfile *archive_access_arcacc (struct znode *zn)
        struct aaFileInArchiveInfo fi;
        memset (&fi, 0, sizeof (fi));
        aaGetFileInfo (ah, zn->offset, &fi);
-       zf = zfile_fopen_empty (zn->fullname, zn->size);
+       zf = zfile_fopen_empty (z, zn->fullname, zn->size);
        id_w = arcacc_push (zf);
        err = aaExtract(ah, zn->offset, id_w, writeCallback, &written);
        if (zf->seek == fi.UncompressedFileSize)
@@ -786,64 +838,41 @@ struct zfile *archive_access_arcacc (struct znode *zn)
 }
 #endif
 
-void archive_access_close (void *handle, unsigned int id)
-{
-    switch (id)
-    {
-       case ArchiveFormatZIP:
-       archive_close_zip(handle);
-       break;
-       case ArchiveFormat7Zip:
-       archive_close_7z(handle);
-       break;
-       case ArchiveFormatRAR:
-       archive_close_rar(handle);
-       break;
-       case ArchiveFormatLHA:
-       break;
-    }
-}
-
 /* plain single file */
 
-static void addfile (struct zvolume *zv, const TCHAR *path, uae_u8 *data, int size)
+static struct znode *addfile (struct zvolume *zv, struct zfile *zf, const TCHAR *path, uae_u8 *data, int size)
 {
     struct zarchive_info zai;
     struct znode *zn;
-    struct zfile *z = zfile_fopen_empty (path, size);
+    struct zfile *z = zfile_fopen_empty (zf, path, size);
 
     zfile_fwrite (data, size, 1, z);
     memset(&zai, 0, sizeof zai);
     zai.name = path;
+    zai.flags = -1;
     zai.size = size;
     zn = zvolume_addfile_abs (zv, &zai);
     if (zn)
        zn->f = z;
     else
        zfile_fclose (z);
+    return zn;
 }
 
 static uae_u8 exeheader[]={0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00};
 struct zvolume *archive_directory_plain (struct zfile *z)
 {
+    struct zfile *zf, *zf2;
     struct zvolume *zv;
     struct znode *zn;
     struct zarchive_info zai;
-    int i;
-    TCHAR *filename;
     uae_u8 id[8];
 
     memset (&zai, 0, sizeof zai);
-    zv = zvolume_alloc (z, ArchiveFormatPLAIN, NULL);
-    for (i = _tcslen (z->name) - 1; i >= 0; i--) {
-       if (z->name[i] == '\\' || z->name[i] == '/' || z->name[i] == ':') {
-           i++;
-           break;
-       }
-    }
-    filename = &z->name[i];
+    zv = zvolume_alloc (z, ArchiveFormatPLAIN, NULL, NULL);
     memset(id, 0, sizeof id);
-    zai.name = filename;
+    zai.name = zfile_getfilename (z);
+    zai.flags = -1;
     zfile_fseek(z, 0, SEEK_END);
     zai.size = zfile_ftell(z);
     zfile_fseek(z, 0, SEEK_SET);
@@ -851,18 +880,398 @@ struct zvolume *archive_directory_plain (struct zfile *z)
     zfile_fseek(z, 0, SEEK_SET);
     zn = zvolume_addfile_abs (zv, &zai);
     if (!memcmp (id, exeheader, sizeof id)) {
-       uae_u8 *data = xmalloc (1 + _tcslen (filename) + 1 + 2);
-       sprintf (data, "\"%s\"\n", filename);
-       addfile (zv, L"s/startup-sequence", data, strlen (data));
+       uae_u8 *data = xmalloc (1 + _tcslen (zai.name) + 1 + 2);
+       sprintf (data, "\"%s\"\n", zai.name);
+       zn = addfile (zv, z, L"s/startup-sequence", data, strlen (data));
        xfree (data);
     }
+    zf = zfile_dup (z);
+    zf2 = zuncompress (zf, 0, 1);
+    if (zf2 != zf) {
+       zf = zf2;
+       zai.name = zfile_getfilename (zf);
+       zai.flags = -1;
+       zfile_fseek(zf, 0, SEEK_END);
+       zai.size = zfile_ftell (zf2);
+       zfile_fseek(zf, 0, SEEK_SET);
+       zn = zvolume_addfile_abs (zv, &zai);
+       if (zn)
+           zn->offset = 1;
+    }
+    zfile_fclose (zf2);
     return zv;
 }
 struct zfile *archive_access_plain (struct znode *zn)
 {
     struct zfile *z;
 
-    z = zfile_fopen_empty (zn->fullname, zn->size);
-    zfile_fread (z->data, zn->size, 1, zn->volume->archive);
+    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);
+       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);
+    }
+    return z;
+}
+
+struct adfhandle {
+    int size;
+    int highblock;
+    int blocksize;
+    int rootblock;
+    struct zfile *z;
+    uae_u8 block[65536];
+    uae_u32 dostype;
+};
+
+static TCHAR *getBSTR (uae_u8 *bstr)
+{
+    int n = *bstr++;
+    uae_char buf[257];
+    int i;
+
+    for (i = 0; i < n; i++)
+       buf[i] = *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 const int secs_per_day = 24 * 60 * 60;
+static const int diff = (8 * 365 + 2) * (24 * 60 * 60);
+static time_t put_time (long days, long mins, long ticks)
+{
+    time_t t;
+
+    if (days < 0)
+       days = 0;
+    if (days > 9900 * 365)
+       days = 9900 * 365; // in future far enough?
+    if (mins < 0 || mins >= 24 * 60)
+       mins = 0;
+    if (ticks < 0 || ticks >= 60 * 50)
+       ticks = 0;
+
+    t = ticks / 50;
+    t += mins * 60;
+    t += ((uae_u64)days) * secs_per_day;
+    t += diff;
+
+    return t;
+}
+
+static int adf_read_block (struct adfhandle *adf, int block)
+{
+    memset (adf->block, 0, adf->blocksize);
+    if (block >= adf->highblock || block < 0)
+       return 0;
+    zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
+    zfile_fread (adf->block, adf->blocksize, 1, adf->z);
+    return 1;
+}
+
+static void recurseadf (struct znode *zn, int root, TCHAR *name)
+{
+    int i;
+    struct zvolume *zv = zn->volume;
+    struct adfhandle *adf = zv->handle;
+    TCHAR name2[MAX_DPATH];
+
+    for (i = 6; i < 78; i++) {
+       int block;
+       if (!adf_read_block (adf, root))
+           return;
+       block = gl (adf, i * 4);
+       while (block > 0 && block < adf->size / 512) {
+           struct zarchive_info zai;
+           TCHAR *fname;
+           uae_u32 size, secondary;
+
+           if (!adf_read_block (adf, block))
+               return;
+           if (gl (adf, 0) != 2)
+               break;
+           if (gl (adf, 1 * 4) != block)
+               break;
+           secondary = gl (adf, 512 - 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);
+           name2[0] = 0;
+           if (name[0]) {
+               TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+               _tcscpy (name2, name);
+               _tcscat (name2, sep);
+           }
+           _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));
+           if (secondary == -3) {
+               struct znode *znnew = zvolume_addfile_abs (zv, &zai);
+               znnew->offset = block;
+           } else {
+               struct znode *znnew = zvolume_adddir_abs (zv, &zai);
+               znnew->offset = block;
+               recurseadf (znnew, block, name2);
+               if (!adf_read_block (adf, block))
+                   return;
+           }
+           xfree (fname);
+           block = gl (adf, 512 - 4 * 4);
+       }
+    }
+}
+
+struct zvolume *archive_directory_adf (struct zfile *z)
+{
+    struct zvolume *zv;
+    struct adfhandle *adf;
+    TCHAR *volname;
+    TCHAR name[MAX_DPATH];
+
+    adf = xcalloc (sizeof (struct adfhandle), 1);
+    zfile_fseek (z, 0, SEEK_END);
+    adf->size = zfile_ftell (z);
+    zfile_fseek (z, 0, SEEK_SET);
+
+    adf->blocksize = 512;
+    adf->highblock = adf->size / adf->blocksize;
+    adf->z = z;
+
+    if (!adf_read_block (adf, 0)) {
+       xfree (adf);
+       return NULL;
+    }
+    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 (gl (adf, 0) != 2 || gl (adf, 512 - 1 * 4) != 1) {
+           if (adf->size < 2000000 && adf->rootblock != 880) {
+               adf->rootblock = 880;
+               continue;
+           }
+           xfree (adf);
+           return NULL;
+       }
+       break;
+    }
+
+    volname = getBSTR (adf->block + 512 - 20 * 4);
+
+    zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
+    zv->method = ArchiveFormatADF;
+    zv->handle = adf;
+
+    name[0] = 0;
+    recurseadf (&zv->root, adf->rootblock, name);
+    return zv;
+}
+
+struct zfile *archive_access_adf (struct znode *zn)
+{
+    struct zfile *z;
+    int block, root, ffs;
+    struct adfhandle *adf = zn->volume->handle;
+    int size;
+    int i;
+    uae_u8 *dst;
+
+    size = zn->size;
+    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)
+               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;
+       }
+       if (size <= 0)
+           break;
+       root = gl (adf, 512 - 2 * 4);
+    }
     return z;
 }
+
+static void archive_close_adf (void *v)
+{
+    struct adfhandle *adf = v;
+    xfree (adf);
+}
+
+static int rl (uae_u8 *p)
+{
+    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
+}
+static TCHAR *tochar (uae_u8 *s, int len)
+{
+    int i, j;
+    uae_char tmp[256];
+    j = 0;
+    for (i = 0; i < len; i++) {
+       uae_char c = *s++;
+       if (c >= 0 && c <= 9) {
+           tmp[j++] = '\\';
+           tmp[j++] = '0' + c;
+       } else if (c < ' ' || c > 'z') {
+           tmp[j++] = '.';
+       } else {
+           tmp[j++] = c;
+       }
+       tmp[j] = 0;
+    }
+    return au (tmp);
+}
+
+struct zvolume *archive_directory_rdb (struct zfile *z)
+{
+    uae_u8 buf[512] = { 0 };
+    int partnum;
+    TCHAR *devname;
+    struct zvolume *zv;
+
+    zv = zvolume_alloc (z, ArchiveFormatRDB, NULL, NULL);
+
+    zfile_fseek (z, 0, SEEK_SET);
+    zfile_fread (buf, 1, 512, z);
+
+    partnum = 0;
+    for (;;) {
+       int partblock;
+       struct znode *zn;
+        struct zarchive_info zai;
+       TCHAR tmp[MAX_DPATH];
+       int surf, spt, lowcyl, highcyl, reserved;
+       int size, block, blocksize, rootblock;
+       uae_u8 *p;
+       TCHAR comment[81], *com;
+
+       if (partnum == 0)
+           partblock = rl (buf + 28);
+       else
+           partblock = rl (buf + 4 * 4);
+       partnum++;
+       if (partblock <= 0)
+           break;
+       zfile_fseek (z, partblock * 512, SEEK_SET);
+       zfile_fread (buf, 1, 512, z);
+       if (memcmp (buf, "PART", 4))
+           break;
+
+       p = buf + 128 - 16;
+       surf = rl (p + 28);
+       spt = rl (p + 36);
+       reserved = rl (p + 40);
+       lowcyl = rl (p + 52);
+       highcyl = rl (p + 56);
+       blocksize = rl (p + 20) * 4;
+       block = lowcyl * surf * spt;
+
+       size = (highcyl - lowcyl + 1) * surf * spt;
+       size *= blocksize;
+
+       rootblock = ((size / blocksize) - 1 + 2) / 2;
+
+       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);
+       zai.comment = comment;
+       xfree (com);
+        zai.name = tmp;
+       zai.size = size;
+       zai.flags = -1;
+       zn = zvolume_addfile_abs (zv, &zai);
+       zn->offset = partblock;
+    }
+
+    zv->method = ArchiveFormatRDB;
+    return zv;
+}
+
+struct zfile *archive_access_rdb (struct znode *zn)
+{
+    struct zfile *z = zn->volume->archive;
+    struct zfile *zf;
+    uae_u8 buf[512] = { 0 };
+    int surf, spb, spt, lowcyl, highcyl;
+    int size, block, blocksize;
+    uae_u8 *p;
+
+    zfile_fseek (z, zn->offset * 512, SEEK_SET);
+    zfile_fread (buf, 1, 512, z);
+    p = buf + 128 - 16;
+    surf = rl (p + 28);
+    spb = rl (p + 32);
+    spt = rl (p + 36);
+    lowcyl = rl (p + 52);
+    highcyl = rl (p + 56);
+    blocksize = rl (p + 20) * 4;
+    block = lowcyl * surf * spt;
+
+    size = (highcyl - lowcyl + 1) * surf * spt;
+    size *= blocksize;
+
+    zf = zfile_fopen_empty (z, zn->fullname, size);
+    zfile_fseek (z, block * blocksize, SEEK_SET);
+    zfile_fread (zf->data, size, 1, z);
+    return zf;
+}
+
+void archive_access_close (void *handle, unsigned int id)
+{
+    switch (id)
+    {
+       case ArchiveFormatZIP:
+       archive_close_zip (handle);
+       break;
+       case ArchiveFormat7Zip:
+       archive_close_7z (handle);
+       break;
+       case ArchiveFormatRAR:
+       archive_close_rar (handle);
+       break;
+       case ArchiveFormatLHA:
+       break;
+       case ArchiveFormatADF:
+       archive_close_adf (handle);
+       break;
+    }
+}