From adc44cc27a268f45c342c942471b0be3481715ea Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 8 Apr 2009 16:11:39 +0300 Subject: [PATCH] imported winuaesrc1600b22.zip --- akiko.c | 6 +- amax.c | 2 +- arcadia.c | 10 +- archivers/7z/7zAlloc.h | 20 - archivers/7z/7zBuf.c | 36 + archivers/7z/7zBuf.h | 31 + archivers/7z/7zBuffer.c | 29 - archivers/7z/7zBuffer.h | 19 - archivers/7z/7zCrc.c | 63 +- archivers/7z/7zCrc.h | 26 +- archivers/7z/7zDecode.c | 151 --- archivers/7z/7zDecode.h | 21 - archivers/7z/7zExtract.c | 116 -- archivers/7z/7zIn.c | 1281 --------------------- archivers/7z/7zIn.h | 55 - archivers/7z/7zItem.c | 133 --- archivers/7z/7zItem.h | 90 -- archivers/7z/7zMain.c | 225 ---- archivers/7z/7zMethodID.c | 14 - archivers/7z/7zMethodID.h | 18 - archivers/7z/7zStream.c | 169 +++ archivers/7z/7zTypes.h | 67 -- archivers/7z/7zVersion.h | 7 + archivers/7z/{ => Archive/7z}/7zAlloc.c | 17 +- archivers/7z/Archive/7z/7zAlloc.h | 15 + archivers/7z/Archive/7z/7zDecode.c | 254 ++++ archivers/7z/Archive/7z/7zDecode.h | 13 + archivers/7z/Archive/7z/7zExtract.c | 93 ++ archivers/7z/{ => Archive/7z}/7zExtract.h | 13 +- archivers/7z/{ => Archive/7z}/7zHeader.c | 3 +- archivers/7z/{ => Archive/7z}/7zHeader.h | 42 +- archivers/7z/Archive/7z/7zIn.c | 1204 +++++++++++++++++++ archivers/7z/Archive/7z/7zIn.h | 41 + archivers/7z/Archive/7z/7zItem.c | 127 ++ archivers/7z/Archive/7z/7zItem.h | 84 ++ archivers/7z/Bcj2.c | 132 +++ archivers/7z/Bcj2.h | 30 + archivers/7z/Bra.c | 133 +++ archivers/7z/Bra.h | 60 + archivers/7z/Bra86.c | 85 ++ archivers/7z/CpuArch.h | 69 ++ archivers/7z/LzmaDec.c | 1007 ++++++++++++++++ archivers/7z/LzmaDec.h | 223 ++++ archivers/7z/LzmaDecode.c | 584 ---------- archivers/7z/LzmaDecode.h | 113 -- archivers/7z/LzmaTypes.h | 45 - archivers/7z/Types.h | 208 ++++ archivers/lha/lha.h | 1 + archivers/lha/uae_lha.c | 18 +- archivers/lzx/unlzx.c | 4 +- archivers/wrp/warp.c | 4 +- audio.c | 2 +- autoconf.c | 6 + catweasel.c | 2 +- cdtv.c | 14 +- cfgfile.c | 8 +- cia.c | 8 +- debug.c | 18 +- disk.c | 160 ++- diskutil.c | 132 +++ driveclick.c | 4 +- fdi2raw.c | 2 + filesys.asm | 157 +-- filesys.c | 49 +- filesys_bootrom.c | 370 +++--- hardfile.c | 2 +- include/autoconf.h | 1 + include/diskutil.h | 2 + include/fsdb.h | 1 + include/zarchive.h | 22 +- include/zfile.h | 36 +- inputdevice.c | 34 +- memory.c | 22 +- od-win32/caps/caps_win32.c | 5 +- od-win32/fsdb_mywin32.c | 398 +++++++ od-win32/fsdb_win32.c | 380 ------ od-win32/hardfile_win32.c | 2 +- od-win32/parser.c | 2 +- od-win32/posixemu.c | 5 + od-win32/uaeunp/uaeunp.vcproj | 430 +++++++ od-win32/uaeunp_win32.c | 85 ++ od-win32/win32.c | 16 +- od-win32/win32.h | 4 +- od-win32/win32gfx.c | 7 +- od-win32/win32gfx.h | 1 + od-win32/win32gui.c | 59 +- od-win32/winuae_msvc/winuae_msvc.vcproj | 36 +- od-win32/winuaechangelog.txt | 23 + od-win32/writelog.c | 8 +- savestate.c | 4 +- uaeunp.c | 646 +++++++++++ zfile.c | 938 ++++++++++++--- zfile_archive.c | 599 ++++++++-- 93 files changed, 7742 insertions(+), 4169 deletions(-) delete mode 100644 archivers/7z/7zAlloc.h create mode 100644 archivers/7z/7zBuf.c create mode 100644 archivers/7z/7zBuf.h delete mode 100644 archivers/7z/7zBuffer.c delete mode 100644 archivers/7z/7zBuffer.h delete mode 100644 archivers/7z/7zDecode.c delete mode 100644 archivers/7z/7zDecode.h delete mode 100644 archivers/7z/7zExtract.c delete mode 100644 archivers/7z/7zIn.c delete mode 100644 archivers/7z/7zIn.h delete mode 100644 archivers/7z/7zItem.c delete mode 100644 archivers/7z/7zItem.h delete mode 100644 archivers/7z/7zMain.c delete mode 100644 archivers/7z/7zMethodID.c delete mode 100644 archivers/7z/7zMethodID.h create mode 100644 archivers/7z/7zStream.c delete mode 100644 archivers/7z/7zTypes.h create mode 100644 archivers/7z/7zVersion.h rename archivers/7z/{ => Archive/7z}/7zAlloc.c (80%) create mode 100644 archivers/7z/Archive/7z/7zAlloc.h create mode 100644 archivers/7z/Archive/7z/7zDecode.c create mode 100644 archivers/7z/Archive/7z/7zDecode.h create mode 100644 archivers/7z/Archive/7z/7zExtract.c rename archivers/7z/{ => Archive/7z}/7zExtract.h (87%) rename archivers/7z/{ => Archive/7z}/7zHeader.c (57%) rename archivers/7z/{ => Archive/7z}/7zHeader.h (65%) create mode 100644 archivers/7z/Archive/7z/7zIn.c create mode 100644 archivers/7z/Archive/7z/7zIn.h create mode 100644 archivers/7z/Archive/7z/7zItem.c create mode 100644 archivers/7z/Archive/7z/7zItem.h create mode 100644 archivers/7z/Bcj2.c create mode 100644 archivers/7z/Bcj2.h create mode 100644 archivers/7z/Bra.c create mode 100644 archivers/7z/Bra.h create mode 100644 archivers/7z/Bra86.c create mode 100644 archivers/7z/CpuArch.h create mode 100644 archivers/7z/LzmaDec.c create mode 100644 archivers/7z/LzmaDec.h delete mode 100644 archivers/7z/LzmaDecode.c delete mode 100644 archivers/7z/LzmaDecode.h delete mode 100644 archivers/7z/LzmaTypes.h create mode 100644 archivers/7z/Types.h create mode 100644 diskutil.c create mode 100644 include/diskutil.h create mode 100644 od-win32/fsdb_mywin32.c create mode 100644 od-win32/uaeunp/uaeunp.vcproj create mode 100644 od-win32/uaeunp_win32.c create mode 100644 uaeunp.c diff --git a/akiko.c b/akiko.c index 135e6133..02a8067b 100644 --- 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 a60e54ab..ce483b9a 100644 --- 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; diff --git a/arcadia.c b/arcadia.c index c359e8ab..801427e9 100644 --- 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 index 4ca4170c..00000000 --- a/archivers/7z/7zAlloc.h +++ /dev/null @@ -1,20 +0,0 @@ -/* 7zAlloc.h */ - -#ifndef __7Z_ALLOC_H -#define __7Z_ALLOC_H - -#include - -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 index 00000000..14e7f4e2 --- /dev/null +++ b/archivers/7z/7zBuf.c @@ -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 index 00000000..c5bd7187 --- /dev/null +++ b/archivers/7z/7zBuf.h @@ -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 index 3c4b71e8..00000000 --- a/archivers/7z/7zBuffer.c +++ /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 index 1aab7fad..00000000 --- a/archivers/7z/7zBuffer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* 7zBuffer.h */ - -#ifndef __7Z_BUFFER_H -#define __7Z_BUFFER_H - -#include -#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 diff --git a/archivers/7z/7zCrc.c b/archivers/7z/7zCrc.c index 72da5302..71962b2c 100644 --- a/archivers/7z/7zCrc.c +++ b/archivers/7z/7zCrc.c @@ -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; } diff --git a/archivers/7z/7zCrc.h b/archivers/7z/7zCrc.h index 0795bad0..00dc29ce 100644 --- a/archivers/7z/7zCrc.h +++ b/archivers/7z/7zCrc.h @@ -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 -#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 index 186c9573..00000000 --- a/archivers/7z/7zDecode.c +++ /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 index b6252883..00000000 --- a/archivers/7z/7zDecode.h +++ /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 index fda5074a..00000000 --- a/archivers/7z/7zExtract.c +++ /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 index ba0ab39b..00000000 --- a/archivers/7z/7zIn.c +++ /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 &dataVector, - CObjectVector &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 index f874225a..00000000 --- a/archivers/7z/7zIn.h +++ /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 index 26ea00f6..00000000 --- a/archivers/7z/7zItem.c +++ /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 index 4d848b0c..00000000 --- a/archivers/7z/7zItem.h +++ /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 index 263bc2c3..00000000 --- a/archivers/7z/7zMain.c +++ /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 -#include -#include - -#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 \n\n" - "\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 index 5047359f..00000000 --- a/archivers/7z/7zMethodID.c +++ /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 index 1ee50b76..00000000 --- a/archivers/7z/7zMethodID.h +++ /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 index 00000000..86232aa3 --- /dev/null +++ b/archivers/7z/7zStream.c @@ -0,0 +1,169 @@ +/* 7zStream.c -- 7z Stream functions +2008-11-23 : Igor Pavlov : Public domain */ + +#include + +#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 index 4de13cae..00000000 --- a/archivers/7z/7zTypes.h +++ /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 index 00000000..b7eb2355 --- /dev/null +++ b/archivers/7z/7zVersion.h @@ -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 diff --git a/archivers/7z/7zAlloc.c b/archivers/7z/Archive/7z/7zAlloc.c similarity index 80% rename from archivers/7z/7zAlloc.c rename to archivers/7z/Archive/7z/7zAlloc.c index 21bb30c7..4bfaf42a 100644 --- a/archivers/7z/7zAlloc.c +++ b/archivers/7z/Archive/7z/7zAlloc.c @@ -1,4 +1,5 @@ -/* 7zAlloc.c */ +/* 7zAlloc.c -- Allocation functions +2008-10-04 : Igor Pavlov : Public domain */ #include #include "7zAlloc.h" @@ -11,13 +12,16 @@ #ifdef _WIN32 #include #endif + #include 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 index 00000000..e752ef18 --- /dev/null +++ b/archivers/7z/Archive/7z/7zAlloc.h @@ -0,0 +1,15 @@ +/* 7zAlloc.h -- Allocation functions +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include + +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 index 00000000..02526f0e --- /dev/null +++ b/archivers/7z/Archive/7z/7zDecode.c @@ -0,0 +1,254 @@ +/* 7zDecode.c -- Decoding from 7z folder +2008-11-23 : Igor Pavlov : Public domain */ + +#include + +#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 index 00000000..e19fe387 --- /dev/null +++ b/archivers/7z/Archive/7z/7zDecode.h @@ -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 index 00000000..ff79802b --- /dev/null +++ b/archivers/7z/Archive/7z/7zExtract.c @@ -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; +} diff --git a/archivers/7z/7zExtract.h b/archivers/7z/Archive/7z/7zExtract.h similarity index 87% rename from archivers/7z/7zExtract.h rename to archivers/7z/Archive/7z/7zExtract.h index 5c97b8ef..5f78415f 100644 --- a/archivers/7z/7zExtract.h +++ b/archivers/7z/Archive/7z/7zExtract.h @@ -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 @@ -18,16 +19,16 @@ *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) */ diff --git a/archivers/7z/7zHeader.c b/archivers/7z/Archive/7z/7zHeader.c similarity index 57% rename from archivers/7z/7zHeader.c rename to archivers/7z/Archive/7z/7zHeader.c index 3be4bc27..e48faa48 100644 --- a/archivers/7z/7zHeader.c +++ b/archivers/7z/Archive/7z/7zHeader.c @@ -1,4 +1,5 @@ -/* 7zHeader.c */ +/* 7zHeader.c -- 7z Headers +2008-10-04 : Igor Pavlov : Public domain */ #include "7zHeader.h" diff --git a/archivers/7z/7zHeader.h b/archivers/7z/Archive/7z/7zHeader.h similarity index 65% rename from archivers/7z/7zHeader.h rename to archivers/7z/Archive/7z/7zHeader.h index f98c3511..9941b6f7 100644 --- a/archivers/7z/7zHeader.h +++ b/archivers/7z/Archive/7z/7zHeader.h @@ -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 index 00000000..f6143f83 --- /dev/null +++ b/archivers/7z/Archive/7z/7zIn.c @@ -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 &dataVector, + CObjectVector &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 index 00000000..c8430a7b --- /dev/null +++ b/archivers/7z/Archive/7z/7zIn.h @@ -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 index 00000000..db44571e --- /dev/null +++ b/archivers/7z/Archive/7z/7zItem.c @@ -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 index 00000000..9f1366cd --- /dev/null +++ b/archivers/7z/Archive/7z/7zItem.h @@ -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 index 00000000..20199ce5 --- /dev/null +++ b/archivers/7z/Bcj2.c @@ -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 index 00000000..32d450b3 --- /dev/null +++ b/archivers/7z/Bcj2.h @@ -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 index 00000000..5e546959 --- /dev/null +++ b/archivers/7z/Bra.c @@ -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 index 00000000..45e231e8 --- /dev/null +++ b/archivers/7z/Bra.h @@ -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 index 00000000..1ee0e709 --- /dev/null +++ b/archivers/7z/Bra86.c @@ -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 index 00000000..7384b0c3 --- /dev/null +++ b/archivers/7z/CpuArch.h @@ -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 index 00000000..d87eb191 --- /dev/null +++ b/archivers/7z/LzmaDec.c @@ -0,0 +1,1007 @@ +/* LzmaDec.c -- LZMA Decoder +2008-11-06 : Igor Pavlov : Public domain */ + +#include "LzmaDec.h" + +#include + +#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 index 00000000..98cdbe94 --- /dev/null +++ b/archivers/7z/LzmaDec.h @@ -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 index 486eff54..00000000 --- a/archivers/7z/LzmaDecode.c +++ /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 index bd75525a..00000000 --- a/archivers/7z/LzmaDecode.h +++ /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 index 0072d99b..00000000 --- a/archivers/7z/LzmaTypes.h +++ /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 -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 index 00000000..1af5cfc4 --- /dev/null +++ b/archivers/7z/Types.h @@ -0,0 +1,208 @@ +/* Types.h -- Basic types +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#include + +#ifdef _WIN32 +#include +#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 diff --git a/archivers/lha/lha.h b/archivers/lha/lha.h index baab0fd6..9415584a 100644 --- a/archivers/lha/lha.h +++ b/archivers/lha/lha.h @@ -7,6 +7,7 @@ #define FTIME #define NOBSTRING #define NOINDEX +#define MKTIME /* ------------------------------------------------------------------------ */ /* LHa for UNIX Archiver Driver */ diff --git a/archivers/lha/uae_lha.c b/archivers/lha/uae_lha.c index 32997337..7547269f 100644 --- a/archivers/lha/uae_lha.c +++ b/archivers/lha/uae_lha.c @@ -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); diff --git a/archivers/lzx/unlzx.c b/archivers/lzx/unlzx.c index a4e6086d..79530180 100644 --- a/archivers/lzx/unlzx.c +++ b/archivers/lzx/unlzx.c @@ -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 { diff --git a/archivers/wrp/warp.c b/archivers/wrp/warp.c index 4408a335..a1477ba9 100644 --- a/archivers/wrp/warp.c +++ b/archivers/wrp/warp.c @@ -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 9309066c..d43bd5b3 100644 --- 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); diff --git a/autoconf.c b/autoconf.c index 7abd6ecd..37578f88 100644 --- a/autoconf.c +++ b/autoconf.c @@ -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 */ diff --git a/catweasel.c b/catweasel.c index 7778bd6b..1e45a465 100644 --- a/catweasel.c +++ b/catweasel.c @@ -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 b0bc1940..159897da 100644 --- 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); diff --git a/cfgfile.c b/cfgfile.c index 3f47b05a..9c2ea492 100644 --- 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 206f5a76..b7891b0f 100644 --- 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 df3a550b..662414fe 100644 --- 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 e7e4457e..e976b9ee 100644 --- 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 index 00000000..be0b238b --- /dev/null +++ b/diskutil.c @@ -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 diff --git a/driveclick.c b/driveclick.c index aa022ae2..7f8f9abc 100644 --- a/driveclick.c +++ b/driveclick.c @@ -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; diff --git a/fdi2raw.c b/fdi2raw.c index 5579fd56..247c3ef2 100644 --- 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; diff --git a/filesys.asm b/filesys.asm index b5193137..50c614ba 100644 --- a/filesys.asm +++ b/filesys.asm @@ -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 diff --git a/filesys.c b/filesys.c index d61c1ad7..99ef96f4 100644 --- a/filesys.c +++ b/filesys.c @@ -63,6 +63,12 @@ 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) diff --git a/filesys_bootrom.c b/filesys_bootrom.c index 08a8026c..00fd32dc 100644 --- a/filesys_bootrom.c +++ b/filesys_bootrom.c @@ -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); @@ -25,34 +43,34 @@ 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); @@ -70,18 +88,17 @@ 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); @@ -90,7 +107,7 @@ 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); @@ -127,13 +144,13 @@ 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); @@ -242,7 +259,7 @@ 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); @@ -259,11 +276,11 @@ 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); @@ -285,16 +302,16 @@ 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); @@ -307,16 +324,16 @@ 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); @@ -376,7 +393,7 @@ db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a); db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75); - db(0x41); db(0xfa); db(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); @@ -415,7 +432,7 @@ 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); @@ -470,7 +487,7 @@ 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); @@ -478,25 +495,25 @@ 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); @@ -572,34 +589,25 @@ 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); @@ -610,131 +618,131 @@ 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); diff --git a/hardfile.c b/hardfile.c index 774edc10..b980c7b1 100644 --- a/hardfile.c +++ b/hardfile.c @@ -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); diff --git a/include/autoconf.h b/include/autoconf.h index ffc80432..f979f7be 100644 --- a/include/autoconf.h +++ b/include/autoconf.h @@ -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 index 00000000..48daf0e5 --- /dev/null +++ b/include/diskutil.h @@ -0,0 +1,2 @@ + +int isamigatrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track); diff --git a/include/fsdb.h b/include/fsdb.h index 91dcd6cc..f81994be 100644 --- a/include/fsdb.h +++ b/include/fsdb.h @@ -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*); diff --git a/include/zarchive.h b/include/zarchive.h index 25c8a143..a9fe26a1 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -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); diff --git a/include/zfile.h b/include/zfile.h index 32351922..7fbe378f 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -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); diff --git a/inputdevice.c b/inputdevice.c index b1db645e..c3ef0077 100644 --- a/inputdevice.c +++ b/inputdevice.c @@ -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); diff --git a/memory.c b/memory.c index 88e4702d..3c0d3c3e 100644 --- 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); } } } diff --git a/od-win32/caps/caps_win32.c b/od-win32/caps/caps_win32.c index 5df11c63..aa34fa4b 100644 --- a/od-win32/caps/caps_win32.c +++ b/od-win32/caps/caps_win32.c @@ -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 index 00000000..88fa816a --- /dev/null +++ b/od-win32/fsdb_mywin32.c @@ -0,0 +1,398 @@ +#include "sysconfig.h" +#include "sysdeps.h" +#include "options.h" +#include "memory.h" + +#include "fsdb.h" +#include "win32.h" +#include + +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"); +} + diff --git a/od-win32/fsdb_win32.c b/od-win32/fsdb_win32.c index 38045c3a..9299e10c 100644 --- a/od-win32/fsdb_win32.c +++ b/od-win32/fsdb_win32.c @@ -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"); -} - - diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index 25736f75..b2762e62 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -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); diff --git a/od-win32/parser.c b/od-win32/parser.c index 17598af9..4548c1e3 100644 --- a/od-win32/parser.c +++ b/od-win32/parser.c @@ -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*)); diff --git a/od-win32/posixemu.c b/od-win32/posixemu.c index 459f162a..ba9e8dea 100644 --- a/od-win32/posixemu.c +++ b/od-win32/posixemu.c @@ -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 index 00000000..e2f2f075 --- /dev/null +++ b/od-win32/uaeunp/uaeunp.vcproj @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/od-win32/uaeunp_win32.c b/od-win32/uaeunp_win32.c new file mode 100644 index 00000000..1ac23c8a --- /dev/null +++ b/od-win32/uaeunp_win32.c @@ -0,0 +1,85 @@ +#include +#include + +#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; +} diff --git a/od-win32/win32.c b/od-win32/win32.c index 738fb7b2..42263aae 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -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) diff --git a/od-win32/win32.h b/od-win32/win32.h index bb62f585..a370e05d 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -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"" diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 27012272..77edfefd 100644 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -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); diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index ec56b4a1..dadd01ac 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -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); diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 8ce1b410..13abf0f5 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -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) { diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 14b36741..0756fcc4 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -1309,6 +1309,10 @@ RelativePath="..\dxwrap.c" > + + @@ -1711,6 +1715,10 @@ RelativePath="..\..\disk.c" > + + @@ -2396,11 +2404,11 @@ Name="7z" > + + + + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 4c19028f..3dae2f73 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -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) diff --git a/od-win32/writelog.c b/od-win32/writelog.c index 260aa7ae..26f03fe5 100644 --- a/od-win32/writelog.c +++ b/od-win32/writelog.c @@ -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') diff --git a/savestate.c b/savestate.c index a2bf51bc..3cfe5f69 100644 --- a/savestate.c +++ b/savestate.c @@ -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 index 00000000..32b64be0 --- /dev/null +++ b/uaeunp.c @@ -0,0 +1,646 @@ +#include +#include + +#include + +#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) \"\n"); + _tprintf (L"List all recursively: \"uaeunp -l **\"\n"); + _tprintf (L"Extract to file: \"uaeunp (-x) []\"\n"); + _tprintf (L"Extract all (single directory): \"uaeunp (-x) *\"\n"); + _tprintf (L"Extract all (recursively): \"uaeunp (-x) **\"\n"); + _tprintf (L"Extract all (recursively, current dir): \"uaeunp -e \"\n"); + _tprintf (L"Output to console: \"uaeunp (-x) -o \"\n"); + _tprintf (L"\n"); + _tprintf (L"Supported disk image formats:\n"); + _tprintf (L" ADF and HDF (OFS/FFS), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n"); + _tprintf (L"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 5f9101f3..608ab211 100644 --- 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 diff --git a/zfile_archive.c b/zfile_archive.c index 2db23540..d17dd102 100644 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -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; + } +} -- 2.47.3