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);
}
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);
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;
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)
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;
}
{
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;
+++ /dev/null
-/* 7zAlloc.h */
-
-#ifndef __7Z_ALLOC_H
-#define __7Z_ALLOC_H
-
-#include <stddef.h>
-
-typedef struct _ISzAlloc
-{
- void *(*Alloc)(size_t size);
- void (*Free)(void *address); /* address can be 0 */
-} ISzAlloc;
-
-void *SzAlloc(size_t size);
-void SzFree(void *address);
-
-void *SzAllocTemp(size_t size);
-void SzFreeTemp(void *address);
-
-#endif
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 7zBuffer.h */
-
-#ifndef __7Z_BUFFER_H
-#define __7Z_BUFFER_H
-
-#include <stddef.h>
-#include "7zTypes.h"
-
-typedef struct _CSzByteBuffer
-{
- size_t Capacity;
- Byte *Items;
-}CSzByteBuffer;
-
-void SzByteBufferInit(CSzByteBuffer *buffer);
-int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
-void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
-
-#endif
-/* 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++)
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;
}
-/* 7zCrc.h */
+/* 7zCrc.h -- CRC32 calculation
+2008-03-13
+Igor Pavlov
+Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
#include <stddef.h>
-#include "7zTypes.h"
+#include "Types.h"
-extern UInt32 g_CrcTable[256];
-void InitCrcTable();
+extern UInt32 g_CrcTable[];
-void CrcInit(UInt32 *crc);
-UInt32 CrcGetDigest(UInt32 *crc);
-void CrcUpdateByte(UInt32 *crc, Byte v);
-void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
-void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
-void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
-void CrcUpdate(UInt32 *crc, const void *data, size_t size);
+void MY_FAST_CALL CrcGenerateTable(void);
-UInt32 CrcCalculateDigest(const void *data, size_t size);
-int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
#endif
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 7zIn.c */
-
-#include "7zIn.h"
-#include "7zCrc.h"
-#include "7zDecode.h"
-
-#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
-
-void SzArDbExInit(CArchiveDatabaseEx *db)
-{
- SzArchiveDatabaseInit(&db->Database);
- db->FolderStartPackStreamIndex = 0;
- db->PackStreamStartPositions = 0;
- db->FolderStartFileIndex = 0;
- db->FileIndexToFolderIndexMap = 0;
-}
-
-void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
-{
- freeFunc(db->FolderStartPackStreamIndex);
- freeFunc(db->PackStreamStartPositions);
- freeFunc(db->FolderStartFileIndex);
- freeFunc(db->FileIndexToFolderIndexMap);
- SzArchiveDatabaseFree(&db->Database, freeFunc);
- SzArDbExInit(db);
-}
-
-/*
-CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
-{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
-}
-
-CFileSize GetFilePackSize(int fileIndex) const
-{
- int folderIndex = FileIndexToFolderIndexMap[fileIndex];
- if (folderIndex >= 0)
- {
- const CFolder &folderInfo = Folders[folderIndex];
- if (FolderStartFileIndex[folderIndex] == fileIndex)
- return GetFolderFullPackSize(folderIndex);
- }
- return 0;
-}
-*/
-
-#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
- if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
-
-SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
-{
- UInt32 startPos = 0;
- CFileSize startPosSize = 0;
- UInt32 i;
- UInt32 folderIndex = 0;
- UInt32 indexInFolder = 0;
- MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
- for(i = 0; i < db->Database.NumFolders; i++)
- {
- db->FolderStartPackStreamIndex[i] = startPos;
- startPos += db->Database.Folders[i].NumPackStreams;
- }
-
- MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
-
- for(i = 0; i < db->Database.NumPackStreams; i++)
- {
- db->PackStreamStartPositions[i] = startPosSize;
- startPosSize += db->Database.PackSizes[i];
- }
-
- MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
- MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
-
- for (i = 0; i < db->Database.NumFiles; i++)
- {
- CFileItem *file = db->Database.Files + i;
- int emptyStream = !file->HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
- continue;
- }
- if (indexInFolder == 0)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: Loop for skipping empty folders
- */
- while(1)
- {
- if (folderIndex >= db->Database.NumFolders)
- return SZE_ARCHIVE_ERROR;
- db->FolderStartFileIndex[folderIndex] = i;
- if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
- break;
- folderIndex++;
- }
- }
- db->FileIndexToFolderIndexMap[i] = folderIndex;
- if (emptyStream)
- continue;
- indexInFolder++;
- if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
- {
- folderIndex++;
- indexInFolder = 0;
- }
- }
- return SZ_OK;
-}
-
-
-CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
-{
- return db->ArchiveInfo.DataStartPosition +
- db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
-}
-
-CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
-{
- UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
- CFolder *folder = db->Database.Folders + folderIndex;
- CFileSize size = 0;
- UInt32 i;
- for (i = 0; i < folder->NumPackStreams; i++)
- size += db->Database.PackSizes[packStreamIndex + i];
- return size;
-}
-
-
-/*
-SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
- CObjectVector<CFileItem> &files, UInt64 type)
-{
- CBoolVector boolVector;
- RINOK(ReadBoolVector2(files.Size(), boolVector))
-
- CStreamSwitch streamSwitch;
- RINOK(streamSwitch.Set(this, &dataVector));
-
- for(int i = 0; i < files.Size(); i++)
- {
- CFileItem &file = files[i];
- CArchiveFileTime fileTime;
- bool defined = boolVector[i];
- if (defined)
- {
- UInt32 low, high;
- RINOK(SzReadUInt32(low));
- RINOK(SzReadUInt32(high));
- fileTime.dwLowDateTime = low;
- fileTime.dwHighDateTime = high;
- }
- switch(type)
- {
- case k7zIdCreationTime:
- file.IsCreationTimeDefined = defined;
- if (defined)
- file.CreationTime = fileTime;
- break;
- case k7zIdLastWriteTime:
- file.IsLastWriteTimeDefined = defined;
- if (defined)
- file.LastWriteTime = fileTime;
- break;
- case k7zIdLastAccessTime:
- file.IsLastAccessTimeDefined = defined;
- if (defined)
- file.LastAccessTime = fileTime;
- break;
- }
- }
- return SZ_OK;
-}
-*/
-
-SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
-{
- #ifdef _LZMA_IN_CB
- while (size > 0)
- {
- Byte *inBuffer;
- size_t processedSize;
- RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
- if (processedSize == 0 || processedSize > size)
- return SZE_FAIL;
- size -= processedSize;
- do
- {
- *data++ = *inBuffer++;
- }
- while (--processedSize != 0);
- }
- #else
- size_t processedSize;
- RINOK(inStream->Read(inStream, data, size, &processedSize));
- if (processedSize != size)
- return SZE_FAIL;
- #endif
- return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
-{
- return SafeReadDirect(inStream, data, 1);
-}
-
-SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt32)b << (8 * i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt32)b << (8 * i));
- }
- return SZ_OK;
-}
-
-int TestSignatureCandidate(Byte *testBytes)
-{
- size_t i;
- for (i = 0; i < k7zSignatureSize; i++)
- if (testBytes[i] != k7zSignature[i])
- return 0;
- return 1;
-}
-
-typedef struct _CSzState
-{
- Byte *Data;
- size_t Size;
-}CSzData;
-
-SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
-{
- if (sd->Size == 0)
- return SZE_ARCHIVE_ERROR;
- sd->Size--;
- *b = *sd->Data++;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
-{
- size_t i;
- for (i = 0; i < size; i++)
- {
- RINOK(SzReadByte(sd, data + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt32)(b) << (8 * i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
-{
- Byte firstByte;
- Byte mask = 0x80;
- int i;
- RINOK(SzReadByte(sd, &firstByte));
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- if ((firstByte & mask) == 0)
- {
- UInt64 highPart = firstByte & (mask - 1);
- *value += (highPart << (8 * i));
- return SZ_OK;
- }
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt64)b << (8 * i));
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- *value = (CFileSize)value64;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- if (value64 >= 0x80000000)
- return SZE_NOTIMPL;
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
- return SZE_NOTIMPL;
- *value = (UInt32)value64;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
-{
- return SzReadNumber(sd, value);
-}
-
-SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
-{
- if (size > sd->Size)
- return SZE_ARCHIVE_ERROR;
- sd->Size -= (size_t)size;
- sd->Data += (size_t)size;
- return SZ_OK;
-}
-
-SZ_RESULT SzSkeepData(CSzData *sd)
-{
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- return SzSkeepDataSize(sd, size);
-}
-
-SZ_RESULT SzReadArchiveProperties(CSzData *sd)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- SzSkeepData(sd);
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == attribute)
- return SZ_OK;
- if (type == k7zIdEnd)
- return SZE_ARCHIVE_ERROR;
- RINOK(SzSkeepData(sd));
- }
-}
-
-SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
- Byte b = 0;
- Byte mask = 0;
- size_t i;
- MY_ALLOC(Byte, *v, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- {
- if (mask == 0)
- {
- RINOK(SzReadByte(sd, &b));
- mask = 0x80;
- }
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
- Byte allAreDefined;
- size_t i;
- RINOK(SzReadByte(sd, &allAreDefined));
- if (allAreDefined == 0)
- return SzReadBoolVector(sd, numItems, v, allocFunc);
- MY_ALLOC(Byte, *v, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- (*v)[i] = 1;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadHashDigests(
- CSzData *sd,
- size_t numItems,
- Byte **digestsDefined,
- UInt32 **digests,
- void * (*allocFunc)(size_t size))
-{
- size_t i;
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
- MY_ALLOC(UInt32, *digests, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- if ((*digestsDefined)[i])
- {
- RINOK(SzReadUInt32(sd, (*digests) + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadPackInfo(
- CSzData *sd,
- CFileSize *dataOffset,
- UInt32 *numPackStreams,
- CFileSize **packSizes,
- Byte **packCRCsDefined,
- UInt32 **packCRCs,
- void * (*allocFunc)(size_t size))
-{
- UInt32 i;
- RINOK(SzReadSize(sd, dataOffset));
- RINOK(SzReadNumber32(sd, numPackStreams));
-
- RINOK(SzWaitAttribute(sd, k7zIdSize));
-
- MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
-
- for(i = 0; i < *numPackStreams; i++)
- {
- RINOK(SzReadSize(sd, (*packSizes) + i));
- }
-
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- if (type == k7zIdCRC)
- {
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
- if (*packCRCsDefined == 0)
- {
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
- for(i = 0; i < *numPackStreams; i++)
- {
- (*packCRCsDefined)[i] = 0;
- (*packCRCs)[i] = 0;
- }
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadSwitch(CSzData *sd)
-{
- Byte external;
- RINOK(SzReadByte(sd, &external));
- return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
-}
-
-SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
-{
- UInt32 numCoders;
- UInt32 numBindPairs;
- UInt32 numPackedStreams;
- UInt32 i;
- UInt32 numInStreams = 0;
- UInt32 numOutStreams = 0;
- RINOK(SzReadNumber32(sd, &numCoders));
- folder->NumCoders = numCoders;
-
- MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
-
- for (i = 0; i < numCoders; i++)
- SzCoderInfoInit(folder->Coders + i);
-
- for (i = 0; i < numCoders; i++)
- {
- Byte mainByte;
- CCoderInfo *coder = folder->Coders + i;
- {
- RINOK(SzReadByte(sd, &mainByte));
- coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
- RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
- if ((mainByte & 0x10) != 0)
- {
- RINOK(SzReadNumber32(sd, &coder->NumInStreams));
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
- }
- else
- {
- coder->NumInStreams = 1;
- coder->NumOutStreams = 1;
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
- return SZE_OUTOFMEMORY;
- RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
- }
- }
- while ((mainByte & 0x80) != 0)
- {
- RINOK(SzReadByte(sd, &mainByte));
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
- if ((mainByte & 0x10) != 0)
- {
- UInt32 n;
- RINOK(SzReadNumber32(sd, &n));
- RINOK(SzReadNumber32(sd, &n));
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- RINOK(SzSkeepDataSize(sd, propertiesSize));
- }
- }
- numInStreams += (UInt32)coder->NumInStreams;
- numOutStreams += (UInt32)coder->NumOutStreams;
- }
-
- numBindPairs = numOutStreams - 1;
- folder->NumBindPairs = numBindPairs;
-
-
- MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
-
- for (i = 0; i < numBindPairs; i++)
- {
- CBindPair *bindPair = folder->BindPairs + i;;
- RINOK(SzReadNumber32(sd, &bindPair->InIndex));
- RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
- }
-
- numPackedStreams = numInStreams - (UInt32)numBindPairs;
-
- folder->NumPackStreams = numPackedStreams;
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
-
- if (numPackedStreams == 1)
- {
- UInt32 j;
- UInt32 pi = 0;
- for (j = 0; j < numInStreams; j++)
- if (SzFolderFindBindPairForInStream(folder, j) < 0)
- {
- folder->PackStreams[pi++] = j;
- break;
- }
- }
- else
- for(i = 0; i < numPackedStreams; i++)
- {
- RINOK(SzReadNumber32(sd, folder->PackStreams + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadUnPackInfo(
- CSzData *sd,
- UInt32 *numFolders,
- CFolder **folders, /* for allocFunc */
- void * (*allocFunc)(size_t size),
- ISzAlloc *allocTemp)
-{
- UInt32 i;
- RINOK(SzWaitAttribute(sd, k7zIdFolder));
- RINOK(SzReadNumber32(sd, numFolders));
- {
- RINOK(SzReadSwitch(sd));
-
- MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
-
- for(i = 0; i < *numFolders; i++)
- SzFolderInit((*folders) + i);
-
- for(i = 0; i < *numFolders; i++)
- {
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
- }
- }
-
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
-
- for(i = 0; i < *numFolders; i++)
- {
- UInt32 j;
- CFolder *folder = (*folders) + i;
- UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
-
- MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
-
- for(j = 0; j < numOutStreams; j++)
- {
- RINOK(SzReadSize(sd, folder->UnPackSizes + j));
- }
- }
-
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type == k7zIdCRC)
- {
- SZ_RESULT res;
- Byte *crcsDefined = 0;
- UInt32 *crcs = 0;
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
- if (res == SZ_OK)
- {
- for(i = 0; i < *numFolders; i++)
- {
- CFolder *folder = (*folders) + i;
- folder->UnPackCRCDefined = crcsDefined[i];
- folder->UnPackCRC = crcs[i];
- }
- }
- allocTemp->Free(crcs);
- allocTemp->Free(crcsDefined);
- RINOK(res);
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
-}
-
-SZ_RESULT SzReadSubStreamsInfo(
- CSzData *sd,
- UInt32 numFolders,
- CFolder *folders,
- UInt32 *numUnPackStreams,
- CFileSize **unPackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
- UInt64 type = 0;
- UInt32 i;
- UInt32 si = 0;
- UInt32 numDigests = 0;
-
- for(i = 0; i < numFolders; i++)
- folders[i].NumUnPackStreams = 1;
- *numUnPackStreams = numFolders;
-
- while(1)
- {
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdNumUnPackStream)
- {
- *numUnPackStreams = 0;
- for(i = 0; i < numFolders; i++)
- {
- UInt32 numStreams;
- RINOK(SzReadNumber32(sd, &numStreams));
- folders[i].NumUnPackStreams = numStreams;
- *numUnPackStreams += numStreams;
- }
- continue;
- }
- if (type == k7zIdCRC || type == k7zIdSize)
- break;
- if (type == k7zIdEnd)
- break;
- RINOK(SzSkeepData(sd));
- }
-
- if (*numUnPackStreams == 0)
- {
- *unPackSizes = 0;
- *digestsDefined = 0;
- *digests = 0;
- }
- else
- {
- *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
- RINOM(*unPackSizes);
- *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
- RINOM(*digestsDefined);
- *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
- RINOM(*digests);
- }
-
- for(i = 0; i < numFolders; i++)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: we check that folder is empty
- */
- CFileSize sum = 0;
- UInt32 j;
- UInt32 numSubstreams = folders[i].NumUnPackStreams;
- if (numSubstreams == 0)
- continue;
- if (type == k7zIdSize)
- for (j = 1; j < numSubstreams; j++)
- {
- CFileSize size;
- RINOK(SzReadSize(sd, &size));
- (*unPackSizes)[si++] = size;
- sum += size;
- }
- (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
- }
- if (type == k7zIdSize)
- {
- RINOK(SzReadID(sd, &type));
- }
-
- for(i = 0; i < *numUnPackStreams; i++)
- {
- (*digestsDefined)[i] = 0;
- (*digests)[i] = 0;
- }
-
-
- for(i = 0; i < numFolders; i++)
- {
- UInt32 numSubstreams = folders[i].NumUnPackStreams;
- if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
- numDigests += numSubstreams;
- }
-
-
- si = 0;
- while(1)
- {
- if (type == k7zIdCRC)
- {
- int digestIndex = 0;
- Byte *digestsDefined2 = 0;
- UInt32 *digests2 = 0;
- SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
- if (res == SZ_OK)
- {
- for (i = 0; i < numFolders; i++)
- {
- CFolder *folder = folders + i;
- UInt32 numSubstreams = folder->NumUnPackStreams;
- if (numSubstreams == 1 && folder->UnPackCRCDefined)
- {
- (*digestsDefined)[si] = 1;
- (*digests)[si] = folder->UnPackCRC;
- si++;
- }
- else
- {
- UInt32 j;
- for (j = 0; j < numSubstreams; j++, digestIndex++)
- {
- (*digestsDefined)[si] = digestsDefined2[digestIndex];
- (*digests)[si] = digests2[digestIndex];
- si++;
- }
- }
- }
- }
- allocTemp->Free(digestsDefined2);
- allocTemp->Free(digests2);
- RINOK(res);
- }
- else if (type == k7zIdEnd)
- return SZ_OK;
- else
- {
- RINOK(SzSkeepData(sd));
- }
- RINOK(SzReadID(sd, &type));
- }
-}
-
-
-SZ_RESULT SzReadStreamsInfo(
- CSzData *sd,
- CFileSize *dataOffset,
- CArchiveDatabase *db,
- UInt32 *numUnPackStreams,
- CFileSize **unPackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- void * (*allocFunc)(size_t size),
- ISzAlloc *allocTemp)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if ((UInt64)(int)type != type)
- return SZE_FAIL;
- switch((int)type)
- {
- case k7zIdEnd:
- return SZ_OK;
- case k7zIdPackInfo:
- {
- RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
- &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
- break;
- }
- case k7zIdUnPackInfo:
- {
- RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
- break;
- }
- case k7zIdSubStreamsInfo:
- {
- RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
- numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
- break;
- }
- default:
- return SZE_FAIL;
- }
- }
-}
-
-Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
- void * (*allocFunc)(size_t size))
-{
- UInt32 i;
- for(i = 0; i < numFiles; i++)
- {
- UInt32 len = 0;
- UInt32 pos = 0;
- CFileItem *file = files + i;
- while(pos + 2 <= sd->Size)
- {
- int numAdds;
- UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
- pos += 2;
- len++;
- if (value == 0)
- break;
- if (value < 0x80)
- continue;
- if (value >= 0xD800 && value < 0xE000)
- {
- UInt32 c2;
- if (value >= 0xDC00)
- return SZE_ARCHIVE_ERROR;
- if (pos + 2 > sd->Size)
- return SZE_ARCHIVE_ERROR;
- c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
- pos += 2;
- if (c2 < 0xDC00 || c2 >= 0xE000)
- return SZE_ARCHIVE_ERROR;
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
- }
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- len += numAdds;
- }
-
- MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
-
- len = 0;
- while(2 <= sd->Size)
- {
- int numAdds;
- UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
- SzSkeepDataSize(sd, 2);
- if (value < 0x80)
- {
- file->Name[len++] = (char)value;
- if (value == 0)
- break;
- continue;
- }
- if (value >= 0xD800 && value < 0xE000)
- {
- UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
- SzSkeepDataSize(sd, 2);
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
- }
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- do
- {
- numAdds--;
- file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- }
- while(numAdds > 0);
-
- len += numAdds;
- }
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadHeader2(
- CSzData *sd,
- CArchiveDatabaseEx *db, /* allocMain */
- CFileSize **unPackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- Byte **emptyStreamVector, /* allocTemp */
- Byte **emptyFileVector, /* allocTemp */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 type;
- UInt32 numUnPackStreams = 0;
- UInt32 numFiles = 0;
- CFileItem *files = 0;
- UInt32 numEmptyStreams = 0;
- UInt32 i;
-
- RINOK(SzReadID(sd, &type));
-
- if (type == k7zIdArchiveProperties)
- {
- RINOK(SzReadArchiveProperties(sd));
- RINOK(SzReadID(sd, &type));
- }
-
-
- if (type == k7zIdMainStreamsInfo)
- {
- RINOK(SzReadStreamsInfo(sd,
- &db->ArchiveInfo.DataStartPosition,
- &db->Database,
- &numUnPackStreams,
- unPackSizes,
- digestsDefined,
- digests, allocMain->Alloc, allocTemp));
- db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
- RINOK(SzReadID(sd, &type));
- }
-
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type != k7zIdFilesInfo)
- return SZE_ARCHIVE_ERROR;
-
- RINOK(SzReadNumber32(sd, &numFiles));
- db->Database.NumFiles = numFiles;
-
- MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
-
- db->Database.Files = files;
- for(i = 0; i < numFiles; i++)
- SzFileInit(files + i);
-
- while(1)
- {
- UInt64 type;
- UInt64 size;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- RINOK(SzReadNumber(sd, &size));
-
- if ((UInt64)(int)type != type)
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- else
- switch((int)type)
- {
- case k7zIdName:
- {
- RINOK(SzReadSwitch(sd));
- RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
- break;
- }
- case k7zIdEmptyStream:
- {
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
- numEmptyStreams = 0;
- for (i = 0; i < numFiles; i++)
- if ((*emptyStreamVector)[i])
- numEmptyStreams++;
- break;
- }
- case k7zIdEmptyFile:
- {
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
- break;
- }
- default:
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- }
- }
-
- {
- UInt32 emptyFileIndex = 0;
- UInt32 sizeIndex = 0;
- for(i = 0; i < numFiles; i++)
- {
- CFileItem *file = files + i;
- file->IsAnti = 0;
- if (*emptyStreamVector == 0)
- file->HasStream = 1;
- else
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
- if(file->HasStream)
- {
- file->IsDirectory = 0;
- file->Size = (*unPackSizes)[sizeIndex];
- file->FileCRC = (*digests)[sizeIndex];
- file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
- sizeIndex++;
- }
- else
- {
- if (*emptyFileVector == 0)
- file->IsDirectory = 1;
- else
- file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
- emptyFileIndex++;
- file->Size = 0;
- file->IsFileCRCDefined = 0;
- }
- }
- }
- return SzArDbExFill(db, allocMain->Alloc);
-}
-
-SZ_RESULT SzReadHeader(
- CSzData *sd,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- CFileSize *unPackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- Byte *emptyStreamVector = 0;
- Byte *emptyFileVector = 0;
- SZ_RESULT res = SzReadHeader2(sd, db,
- &unPackSizes, &digestsDefined, &digests,
- &emptyStreamVector, &emptyFileVector,
- allocMain, allocTemp);
- allocTemp->Free(unPackSizes);
- allocTemp->Free(digestsDefined);
- allocTemp->Free(digests);
- allocTemp->Free(emptyStreamVector);
- allocTemp->Free(emptyFileVector);
- return res;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams2(
- ISzInStream *inStream,
- CSzData *sd,
- CSzByteBuffer *outBuffer,
- CFileSize baseOffset,
- CArchiveDatabase *db,
- CFileSize **unPackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- #ifndef _LZMA_IN_CB
- Byte **inBuffer,
- #endif
- ISzAlloc *allocTemp)
-{
-
- UInt32 numUnPackStreams = 0;
- CFileSize dataStartPos;
- CFolder *folder;
- #ifndef _LZMA_IN_CB
- CFileSize packSize = 0;
- UInt32 i = 0;
- #endif
- CFileSize unPackSize;
- size_t outRealSize;
- SZ_RESULT res;
-
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
- &numUnPackStreams, unPackSizes, digestsDefined, digests,
- allocTemp->Alloc, allocTemp));
-
- dataStartPos += baseOffset;
- if (db->NumFolders != 1)
- return SZE_ARCHIVE_ERROR;
-
- folder = db->Folders;
- unPackSize = SzFolderGetUnPackSize(folder);
-
- RINOK(inStream->Seek(inStream, dataStartPos));
-
- #ifndef _LZMA_IN_CB
- for (i = 0; i < db->NumPackStreams; i++)
- packSize += db->PackSizes[i];
-
- MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
-
- RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
- #endif
-
- if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
- return SZE_OUTOFMEMORY;
-
- res = SzDecode(db->PackSizes, folder,
- #ifdef _LZMA_IN_CB
- inStream,
- #else
- *inBuffer,
- #endif
- outBuffer->Items, (size_t)unPackSize,
- &outRealSize, allocTemp);
- RINOK(res)
- if (outRealSize != (UInt32)unPackSize)
- return SZE_FAIL;
- if (folder->UnPackCRCDefined)
- if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize))
- return SZE_FAIL;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams(
- ISzInStream *inStream,
- CSzData *sd,
- CSzByteBuffer *outBuffer,
- CFileSize baseOffset,
- ISzAlloc *allocTemp)
-{
- CArchiveDatabase db;
- CFileSize *unPackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- #ifndef _LZMA_IN_CB
- Byte *inBuffer = 0;
- #endif
- SZ_RESULT res;
- SzArchiveDatabaseInit(&db);
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
- &db, &unPackSizes, &digestsDefined, &digests,
- #ifndef _LZMA_IN_CB
- &inBuffer,
- #endif
- allocTemp);
- SzArchiveDatabaseFree(&db, allocTemp->Free);
- allocTemp->Free(unPackSizes);
- allocTemp->Free(digestsDefined);
- allocTemp->Free(digests);
- #ifndef _LZMA_IN_CB
- allocTemp->Free(inBuffer);
- #endif
- return res;
-}
-
-SZ_RESULT SzArchiveOpen2(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- Byte signature[k7zSignatureSize];
- Byte version;
- UInt32 crcFromArchive;
- UInt64 nextHeaderOffset;
- UInt64 nextHeaderSize;
- UInt32 nextHeaderCRC;
- UInt32 crc;
- CFileSize pos = 0;
- CSzByteBuffer buffer;
- CSzData sd;
- SZ_RESULT res;
-
- RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
-
- if (!TestSignatureCandidate(signature))
- return SZE_ARCHIVE_ERROR;
-
- /*
- db.Clear();
- db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
- */
- RINOK(SafeReadDirectByte(inStream, &version));
- if (version != k7zMajorVersion)
- return SZE_ARCHIVE_ERROR;
- RINOK(SafeReadDirectByte(inStream, &version));
-
- RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive));
-
- CrcInit(&crc);
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset));
- CrcUpdateUInt64(&crc, nextHeaderOffset);
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize));
- CrcUpdateUInt64(&crc, nextHeaderSize);
- RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC));
- CrcUpdateUInt32(&crc, nextHeaderCRC);
-
- pos = k7zStartHeaderSize;
- db->ArchiveInfo.StartPositionAfterHeader = pos;
-
- if (CrcGetDigest(&crc) != crcFromArchive)
- return SZE_ARCHIVE_ERROR;
-
- if (nextHeaderSize == 0)
- return SZ_OK;
-
- RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
-
- if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
- return SZE_OUTOFMEMORY;
-
- res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
- if (res == SZ_OK)
- {
- if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
- {
- while (1)
- {
- UInt64 type;
- sd.Data = buffer.Items;
- sd.Size = buffer.Capacity;
- res = SzReadID(&sd, &type);
- if (res != SZ_OK)
- break;
- if (type == k7zIdHeader)
- {
- res = SzReadHeader(&sd, db, allocMain, allocTemp);
- break;
- }
- if (type != k7zIdEncodedHeader)
- {
- res = SZE_ARCHIVE_ERROR;
- break;
- }
- {
- CSzByteBuffer outBuffer;
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
- db->ArchiveInfo.StartPositionAfterHeader,
- allocTemp);
- if (res != SZ_OK)
- {
- SzByteBufferFree(&outBuffer, allocTemp->Free);
- break;
- }
- SzByteBufferFree(&buffer, allocTemp->Free);
- buffer.Items = outBuffer.Items;
- buffer.Capacity = outBuffer.Capacity;
- }
- }
- }
- }
- SzByteBufferFree(&buffer, allocTemp->Free);
- return res;
-}
-
-SZ_RESULT SzArchiveOpen(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
- if (res != SZ_OK)
- SzArDbExFree(db, allocMain->Free);
- return res;
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/*
-7zMain.c
-Test application for 7z Decoder
-LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "7zCrc.h"
-#include "7zIn.h"
-#include "7zExtract.h"
-
-typedef struct _CFileInStream
-{
- ISzInStream InStream;
- FILE *File;
-} CFileInStream;
-
-#ifdef _LZMA_IN_CB
-
-#define kBufferSize (1 << 12)
-Byte g_Buffer[kBufferSize];
-
-SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
-{
- CFileInStream *s = (CFileInStream *)object;
- size_t processedSizeLoc;
- if (maxRequiredSize > kBufferSize)
- maxRequiredSize = kBufferSize;
- processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
- *buffer = g_Buffer;
- if (processedSize != 0)
- *processedSize = processedSizeLoc;
- return SZ_OK;
-}
-
-#else
-
-SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
-{
- CFileInStream *s = (CFileInStream *)object;
- size_t processedSizeLoc = fread(buffer, 1, size, s->File);
- if (processedSize != 0)
- *processedSize = processedSizeLoc;
- return SZ_OK;
-}
-
-#endif
-
-SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
-{
- CFileInStream *s = (CFileInStream *)object;
- int res = fseek(s->File, (long)pos, SEEK_SET);
- if (res == 0)
- return SZ_OK;
- return SZE_FAIL;
-}
-
-void PrintError(char *sz)
-{
- printf("\nERROR: %s\n", sz);
-}
-
-int main(int numargs, char *args[])
-{
- CFileInStream archiveStream;
- CArchiveDatabaseEx db;
- SZ_RESULT res;
- ISzAlloc allocImp;
- ISzAlloc allocTempImp;
-
- printf("\n7z ANSI-C Decoder 4.43 Copyright (c) 1999-2006 Igor Pavlov 2006-06-04\n");
- if (numargs == 1)
- {
- printf(
- "\nUsage: 7zDec <command> <archive_name>\n\n"
- "<Commands>\n"
- " e: Extract files from archive\n"
- " l: List contents of archive\n"
- " t: Test integrity of archive\n");
- return 0;
- }
- if (numargs < 3)
- {
- PrintError("incorrect command");
- return 1;
- }
-
- archiveStream.File = fopen(args[2], "rb");
- if (archiveStream.File == 0)
- {
- PrintError("can not open input file");
- return 1;
- }
-
- archiveStream.InStream.Read = SzFileReadImp;
- archiveStream.InStream.Seek = SzFileSeekImp;
-
- allocImp.Alloc = SzAlloc;
- allocImp.Free = SzFree;
-
- allocTempImp.Alloc = SzAllocTemp;
- allocTempImp.Free = SzFreeTemp;
-
- InitCrcTable();
- SzArDbExInit(&db);
- res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
- if (res == SZ_OK)
- {
- char *command = args[1];
- int listCommand = 0;
- int testCommand = 0;
- int extractCommand = 0;
- if (strcmp(command, "l") == 0)
- listCommand = 1;
- if (strcmp(command, "t") == 0)
- testCommand = 1;
- else if (strcmp(command, "e") == 0)
- extractCommand = 1;
-
- if (listCommand)
- {
- UInt32 i;
- for (i = 0; i < db.Database.NumFiles; i++)
- {
- CFileItem *f = db.Database.Files + i;
- printf("%10d %s\n", (int)f->Size, f->Name);
- }
- }
- else if (testCommand || extractCommand)
- {
- UInt32 i;
-
- /*
- if you need cache, use these 3 variables.
- if you use external function, you can make these variable as static.
- */
- UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
- Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
- size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
-
- printf("\n");
- for (i = 0; i < db.Database.NumFiles; i++)
- {
- size_t offset;
- size_t outSizeProcessed;
- CFileItem *f = db.Database.Files + i;
- if (f->IsDirectory)
- printf("Directory ");
- else
- printf(testCommand ?
- "Testing ":
- "Extracting");
- printf(" %s", f->Name);
- if (f->IsDirectory)
- {
- printf("\n");
- continue;
- }
- res = SzExtract(&archiveStream.InStream, &db, i,
- &blockIndex, &outBuffer, &outBufferSize,
- &offset, &outSizeProcessed,
- &allocImp, &allocTempImp);
- if (res != SZ_OK)
- break;
- if (!testCommand)
- {
- FILE *outputHandle;
- UInt32 processedSize;
- char *fileName = f->Name;
- size_t nameLen = strlen(f->Name);
- for (; nameLen > 0; nameLen--)
- if (f->Name[nameLen - 1] == '/')
- {
- fileName = f->Name + nameLen;
- break;
- }
-
- outputHandle = fopen(fileName, "wb+");
- if (outputHandle == 0)
- {
- PrintError("can not open output file");
- res = SZE_FAIL;
- break;
- }
- processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
- if (processedSize != outSizeProcessed)
- {
- PrintError("can not write output file");
- res = SZE_FAIL;
- break;
- }
- if (fclose(outputHandle))
- {
- PrintError("can not close output file");
- res = SZE_FAIL;
- break;
- }
- }
- printf("\n");
- }
- allocImp.Free(outBuffer);
- }
- else
- {
- PrintError("incorrect command");
- res = SZE_FAIL;
- }
- }
- SzArDbExFree(&db, allocImp.Free);
-
- fclose(archiveStream.File);
- if (res == SZ_OK)
- {
- printf("\nEverything is Ok\n");
- return 0;
- }
- if (res == SZE_OUTOFMEMORY)
- PrintError("can not allocate memory");
- else
- printf("\nERROR #%d\n", res);
- return 1;
-}
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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
--- /dev/null
+/* 7zStream.c -- 7z Stream functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "Types.h"
+
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(stream->Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+{
+ return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+{
+ size_t processed = 1;
+ RINOK(stream->Read(stream, buf, &processed));
+ return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
+}
+
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+{
+ Int64 t = offset;
+ return stream->Seek(stream, &t, SZ_SEEK_SET);
+}
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+{
+ void *lookBuf;
+ if (*size == 0)
+ return SZ_OK;
+ RINOK(stream->Look(stream, &lookBuf, size));
+ memcpy(buf, lookBuf, *size);
+ return stream->Skip(stream, *size);
+}
+
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(stream->Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+{
+ return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size > 0)
+ {
+ p->pos = 0;
+ size2 = LookToRead_BUF_SIZE;
+ res = p->realStream->Read(p->realStream, p->buf, &size2);
+ p->size = size2;
+ }
+ if (size2 < *size)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size > 0)
+ {
+ p->pos = 0;
+ if (*size > LookToRead_BUF_SIZE)
+ *size = LookToRead_BUF_SIZE;
+ res = p->realStream->Read(p->realStream, p->buf, size);
+ size2 = p->size = *size;
+ }
+ if (size2 < *size)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead_Skip(void *pp, size_t offset)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ p->pos += offset;
+ return SZ_OK;
+}
+
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t rem = p->size - p->pos;
+ if (rem == 0)
+ return p->realStream->Read(p->realStream, buf, size);
+ if (rem > *size)
+ rem = *size;
+ memcpy(buf, p->buf + p->pos, rem);
+ p->pos += rem;
+ *size = rem;
+ return SZ_OK;
+}
+
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ p->pos = p->size = 0;
+ return p->realStream->Seek(p->realStream, pos, origin);
+}
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+{
+ p->s.Look = lookahead ?
+ LookToRead_Look_Lookahead :
+ LookToRead_Look_Exact;
+ p->s.Skip = LookToRead_Skip;
+ p->s.Read = LookToRead_Read;
+ p->s.Seek = LookToRead_Seek;
+}
+
+void LookToRead_Init(CLookToRead *p)
+{
+ p->pos = p->size = 0;
+}
+
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+{
+ CSecToLook *p = (CSecToLook *)pp;
+ return LookInStream_LookRead(p->realStream, buf, size);
+}
+
+void SecToLook_CreateVTable(CSecToLook *p)
+{
+ p->s.Read = SecToLook_Read;
+}
+
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+{
+ CSecToRead *p = (CSecToRead *)pp;
+ return p->realStream->Read(p->realStream, buf, size);
+}
+
+void SecToRead_CreateVTable(CSecToRead *p)
+{
+ p->s.Read = SecToRead_Read;
+}
+++ /dev/null
-/* 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
--- /dev/null
+#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
-/* 7zAlloc.c */
+/* 7zAlloc.c -- Allocation functions
+2008-10-04 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include "7zAlloc.h"
#ifdef _WIN32
#include <windows.h>
#endif
+
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
+
#endif
-void *SzAlloc(size_t size)
+void *SzAlloc(void *p, size_t size)
{
+ p = p;
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
return malloc(size);
}
-void SzFree(void *address)
+void SzFree(void *p, void *address)
{
+ p = p;
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
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
return malloc(size);
}
-void SzFreeTemp(void *address)
+void SzFreeTemp(void *p, void *address)
{
+ p = p;
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
--- /dev/null
+/* 7zAlloc.h -- Allocation functions
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+void *SzAlloc(void *p, size_t size);
+void SzFree(void *p, void *address);
+
+void *SzAllocTemp(void *p, size_t size);
+void SzFreeTemp(void *p, void *address);
+
+#endif
--- /dev/null
+/* 7zDecode.c -- Decoding from 7z folder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "../../Bcj2.h"
+#include "../../Bra.h"
+#include "../../LzmaDec.h"
+#include "7zDecode.h"
+
+#define k_Copy 0
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+{
+ CLzmaDec state;
+ SRes res = SZ_OK;
+
+ LzmaDec_Construct(&state);
+ RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
+ state.dic = outBuffer;
+ state.dicBufSize = outSize;
+ LzmaDec_Init(&state);
+
+ for (;;)
+ {
+ Byte *inBuf = NULL;
+ size_t lookahead = (1 << 18);
+ if (lookahead > inSize)
+ lookahead = (size_t)inSize;
+ res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
+ if (res != SZ_OK)
+ break;
+
+ {
+ SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
+ ELzmaStatus status;
+ res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
+ lookahead -= inProcessed;
+ inSize -= inProcessed;
+ if (res != SZ_OK)
+ break;
+ if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
+ {
+ if (state.dicBufSize != outSize || lookahead != 0 ||
+ (status != LZMA_STATUS_FINISHED_WITH_MARK &&
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+ res = SZ_ERROR_DATA;
+ break;
+ }
+ res = inStream->Skip((void *)inStream, inProcessed);
+ if (res != SZ_OK)
+ break;
+ }
+ }
+
+ LzmaDec_FreeProbs(&state, allocMain);
+ return res;
+}
+
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
+{
+ while (inSize > 0)
+ {
+ void *inBuf;
+ size_t curSize = (1 << 18);
+ if (curSize > inSize)
+ curSize = (size_t)inSize;
+ RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
+ if (curSize == 0)
+ return SZ_ERROR_INPUT_EOF;
+ memcpy(outBuffer, inBuf, curSize);
+ outBuffer += curSize;
+ inSize -= curSize;
+ RINOK(inStream->Skip((void *)inStream, curSize));
+ }
+ return SZ_OK;
+}
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
+
+SRes CheckSupportedFolder(const CSzFolder *f)
+{
+ if (f->NumCoders < 1 || f->NumCoders > 4)
+ return SZ_ERROR_UNSUPPORTED;
+ if (IS_UNSUPPORTED_CODER(f->Coders[0]))
+ return SZ_ERROR_UNSUPPORTED;
+ if (f->NumCoders == 1)
+ {
+ if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+ return SZ_ERROR_UNSUPPORTED;
+ return SZ_OK;
+ }
+ if (f->NumCoders == 2)
+ {
+ if (IS_NO_BCJ(f->Coders[1]) ||
+ f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
+ f->NumBindPairs != 1 ||
+ f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
+ return SZ_ERROR_UNSUPPORTED;
+ return SZ_OK;
+ }
+ if (f->NumCoders == 4)
+ {
+ if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
+ IS_UNSUPPORTED_CODER(f->Coders[2]) ||
+ IS_NO_BCJ2(f->Coders[3]))
+ return SZ_ERROR_UNSUPPORTED;
+ if (f->NumPackStreams != 4 ||
+ f->PackStreams[0] != 2 ||
+ f->PackStreams[1] != 6 ||
+ f->PackStreams[2] != 1 ||
+ f->PackStreams[3] != 0 ||
+ f->NumBindPairs != 3 ||
+ f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
+ f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
+ f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+ return SZ_ERROR_UNSUPPORTED;
+ return SZ_OK;
+ }
+ return SZ_ERROR_UNSUPPORTED;
+}
+
+UInt64 GetSum(const UInt64 *values, UInt32 index)
+{
+ UInt64 sum = 0;
+ UInt32 i;
+ for (i = 0; i < index; i++)
+ sum += values[i];
+ return sum;
+}
+
+SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
+ ILookInStream *inStream, UInt64 startPos,
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
+ Byte *tempBuf[])
+{
+ UInt32 ci;
+ SizeT tempSizes[3] = { 0, 0, 0};
+ SizeT tempSize3 = 0;
+ Byte *tempBuf3 = 0;
+
+ RINOK(CheckSupportedFolder(folder));
+
+ for (ci = 0; ci < folder->NumCoders; ci++)
+ {
+ CSzCoderInfo *coder = &folder->Coders[ci];
+
+ if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
+ {
+ UInt32 si = 0;
+ UInt64 offset;
+ UInt64 inSize;
+ Byte *outBufCur = outBuffer;
+ SizeT outSizeCur = outSize;
+ if (folder->NumCoders == 4)
+ {
+ UInt32 indices[] = { 3, 2, 0 };
+ UInt64 unpackSize = folder->UnpackSizes[ci];
+ si = indices[ci];
+ if (ci < 2)
+ {
+ Byte *temp;
+ outSizeCur = (SizeT)unpackSize;
+ if (outSizeCur != unpackSize)
+ return SZ_ERROR_MEM;
+ temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
+ if (temp == 0 && outSizeCur != 0)
+ return SZ_ERROR_MEM;
+ outBufCur = tempBuf[1 - ci] = temp;
+ tempSizes[1 - ci] = outSizeCur;
+ }
+ else if (ci == 2)
+ {
+ if (unpackSize > outSize) /* check it */
+ return SZ_ERROR_PARAM;
+ tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
+ tempSize3 = outSizeCur = (SizeT)unpackSize;
+ }
+ else
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ offset = GetSum(packSizes, si);
+ inSize = packSizes[si];
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+
+ if (coder->MethodID == k_Copy)
+ {
+ if (inSize != outSizeCur) /* check it */
+ return SZ_ERROR_DATA;
+ RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
+ }
+ else
+ {
+ RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+ }
+ }
+ else if (coder->MethodID == k_BCJ)
+ {
+ UInt32 state;
+ if (ci != 1)
+ return SZ_ERROR_UNSUPPORTED;
+ x86_Convert_Init(state);
+ x86_Convert(outBuffer, outSize, 0, &state, 0);
+ }
+ else if (coder->MethodID == k_BCJ2)
+ {
+ UInt64 offset = GetSum(packSizes, 1);
+ UInt64 s3Size = packSizes[1];
+ SRes res;
+ if (ci != 3)
+ return SZ_ERROR_UNSUPPORTED;
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+ tempSizes[2] = (SizeT)s3Size;
+ if (tempSizes[2] != s3Size)
+ return SZ_ERROR_MEM;
+ tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
+ if (tempBuf[2] == 0 && tempSizes[2] != 0)
+ return SZ_ERROR_MEM;
+ res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
+ RINOK(res)
+
+ res = Bcj2_Decode(
+ tempBuf3, tempSize3,
+ tempBuf[0], tempSizes[0],
+ tempBuf[1], tempSizes[1],
+ tempBuf[2], tempSizes[2],
+ outBuffer, outSize);
+ RINOK(res)
+ }
+ else
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ return SZ_OK;
+}
+
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
+ ILookInStream *inStream, UInt64 startPos,
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+ Byte *tempBuf[3] = { 0, 0, 0};
+ int i;
+ SRes res = SzDecode2(packSizes, folder, inStream, startPos,
+ outBuffer, (SizeT)outSize, allocMain, tempBuf);
+ for (i = 0; i < 3; i++)
+ IAlloc_Free(allocMain, tempBuf[i]);
+ return res;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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;
+}
-/* 7zExtract.h */
+/* 7zExtract.h -- Extracting from 7z archive
+2008-11-23 : Igor Pavlov : Public domain */
#ifndef __7Z_EXTRACT_H
#define __7Z_EXTRACT_H
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
-
+
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
-
+
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
-SZ_RESULT SzExtract(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
+SRes SzAr_Extract(
+ const CSzArEx *db,
+ ILookInStream *inStream,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
-/* 7zHeader.c */
+/* 7zHeader.c -- 7z Headers
+2008-10-04 : Igor Pavlov : Public domain */
#include "7zHeader.h"
-/* 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];
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
--- /dev/null
+/* 7zIn.c -- 7z Input functions
+2008-12-31 : Igor Pavlov : Public domain */
+
+#include "../../7zCrc.h"
+#include "../../CpuArch.h"
+
+#include "7zDecode.h"
+#include "7zIn.h"
+
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
+
+#define NUM_FOLDER_CODERS_MAX 32
+#define NUM_CODER_STREAMS_MAX 32
+
+void SzArEx_Init(CSzArEx *p)
+{
+ SzAr_Init(&p->db);
+ p->FolderStartPackStreamIndex = 0;
+ p->PackStreamStartPositions = 0;
+ p->FolderStartFileIndex = 0;
+ p->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
+ IAlloc_Free(alloc, p->PackStreamStartPositions);
+ IAlloc_Free(alloc, p->FolderStartFileIndex);
+ IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
+ SzAr_Free(&p->db, alloc);
+ SzArEx_Init(p);
+}
+
+/*
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+UInt64 GetFilePackSize(int fileIndex) const
+{
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ const CSzFolder &folderInfo = Folders[folderIndex];
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
+
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
+{
+ UInt32 startPos = 0;
+ UInt64 startPosSize = 0;
+ UInt32 i;
+ UInt32 folderIndex = 0;
+ UInt32 indexInFolder = 0;
+ MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
+ for (i = 0; i < p->db.NumFolders; i++)
+ {
+ p->FolderStartPackStreamIndex[i] = startPos;
+ startPos += p->db.Folders[i].NumPackStreams;
+ }
+
+ MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
+
+ for (i = 0; i < p->db.NumPackStreams; i++)
+ {
+ p->PackStreamStartPositions[i] = startPosSize;
+ startPosSize += p->db.PackSizes[i];
+ }
+
+ MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
+ MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
+
+ for (i = 0; i < p->db.NumFiles; i++)
+ {
+ CSzFileItem *file = p->db.Files + i;
+ int emptyStream = !file->HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: Loop for skipping empty folders
+ */
+ for (;;)
+ {
+ if (folderIndex >= p->db.NumFolders)
+ return SZ_ERROR_ARCHIVE;
+ p->FolderStartFileIndex[folderIndex] = i;
+ if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ p->FileIndexToFolderIndexMap[i] = folderIndex;
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
+{
+ return p->dataPos +
+ p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
+{
+ UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
+ CSzFolder *folder = p->db.Folders + folderIndex;
+ UInt64 size = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumPackStreams; i++)
+ {
+ UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
+ if (t < size) /* check it */
+ return SZ_ERROR_FAIL;
+ size = t;
+ }
+ *resSize = size;
+ return SZ_OK;
+}
+
+
+/*
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
+ CObjectVector<CSzFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for (int i = 0; i < files.Size(); i++)
+ {
+ CSzFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(SzReadUInt32(low));
+ RINOK(SzReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
+ case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
+ case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
+ }
+ }
+ return SZ_OK;
+}
+*/
+
+static int TestSignatureCandidate(Byte *testBytes)
+{
+ size_t i;
+ for (i = 0; i < k7zSignatureSize; i++)
+ if (testBytes[i] != k7zSignature[i])
+ return 0;
+ return 1;
+}
+
+typedef struct _CSzState
+{
+ Byte *Data;
+ size_t Size;
+}CSzData;
+
+static SRes SzReadByte(CSzData *sd, Byte *b)
+{
+ if (sd->Size == 0)
+ return SZ_ERROR_ARCHIVE;
+ sd->Size--;
+ *b = *sd->Data++;
+ return SZ_OK;
+}
+
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ {
+ RINOK(SzReadByte(sd, data + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt32)(b) << (8 * i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)
+{
+ Byte firstByte;
+ Byte mask = 0x80;
+ int i;
+ RINOK(SzReadByte(sd, &firstByte));
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ *value += (highPart << (8 * i));
+ return SZ_OK;
+ }
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt64)b << (8 * i));
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ if (value64 >= 0x80000000)
+ return SZ_ERROR_UNSUPPORTED;
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+ return SZ_ERROR_UNSUPPORTED;
+ *value = (UInt32)value64;
+ return SZ_OK;
+}
+
+static SRes SzReadID(CSzData *sd, UInt64 *value)
+{
+ return SzReadNumber(sd, value);
+}
+
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+ if (size > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ sd->Size -= (size_t)size;
+ sd->Data += (size_t)size;
+ return SZ_OK;
+}
+
+static SRes SzSkeepData(CSzData *sd)
+{
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ return SzSkeepDataSize(sd, size);
+}
+
+static SRes SzReadArchiveProperties(CSzData *sd)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ SzSkeepData(sd);
+ }
+ return SZ_OK;
+}
+
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == attribute)
+ return SZ_OK;
+ if (type == k7zIdEnd)
+ return SZ_ERROR_ARCHIVE;
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+ Byte b = 0;
+ Byte mask = 0;
+ size_t i;
+ MY_ALLOC(Byte, *v, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(SzReadByte(sd, &b));
+ mask = 0x80;
+ }
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+ Byte allAreDefined;
+ size_t i;
+ RINOK(SzReadByte(sd, &allAreDefined));
+ if (allAreDefined == 0)
+ return SzReadBoolVector(sd, numItems, v, alloc);
+ MY_ALLOC(Byte, *v, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ (*v)[i] = 1;
+ return SZ_OK;
+}
+
+static SRes SzReadHashDigests(
+ CSzData *sd,
+ size_t numItems,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *alloc)
+{
+ size_t i;
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
+ MY_ALLOC(UInt32, *digests, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ if ((*digestsDefined)[i])
+ {
+ RINOK(SzReadUInt32(sd, (*digests) + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadPackInfo(
+ CSzData *sd,
+ UInt64 *dataOffset,
+ UInt32 *numPackStreams,
+ UInt64 **packSizes,
+ Byte **packCRCsDefined,
+ UInt32 **packCRCs,
+ ISzAlloc *alloc)
+{
+ UInt32 i;
+ RINOK(SzReadNumber(sd, dataOffset));
+ RINOK(SzReadNumber32(sd, numPackStreams));
+
+ RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+ MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
+
+ for (i = 0; i < *numPackStreams; i++)
+ {
+ RINOK(SzReadNumber(sd, (*packSizes) + i));
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ if (type == k7zIdCRC)
+ {
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+ if (*packCRCsDefined == 0)
+ {
+ MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
+ MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
+ for (i = 0; i < *numPackStreams; i++)
+ {
+ (*packCRCsDefined)[i] = 0;
+ (*packCRCs)[i] = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadSwitch(CSzData *sd)
+{
+ Byte external;
+ RINOK(SzReadByte(sd, &external));
+ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
+}
+
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
+{
+ UInt32 numCoders, numBindPairs, numPackStreams, i;
+ UInt32 numInStreams = 0, numOutStreams = 0;
+
+ RINOK(SzReadNumber32(sd, &numCoders));
+ if (numCoders > NUM_FOLDER_CODERS_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ folder->NumCoders = numCoders;
+
+ MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
+
+ for (i = 0; i < numCoders; i++)
+ SzCoderInfo_Init(folder->Coders + i);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ Byte mainByte;
+ CSzCoderInfo *coder = folder->Coders + i;
+ {
+ unsigned idSize, j;
+ Byte longID[15];
+ RINOK(SzReadByte(sd, &mainByte));
+ idSize = (unsigned)(mainByte & 0xF);
+ RINOK(SzReadBytes(sd, longID, idSize));
+ if (idSize > sizeof(coder->MethodID))
+ return SZ_ERROR_UNSUPPORTED;
+ coder->MethodID = 0;
+ for (j = 0; j < idSize; j++)
+ coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+ if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
+ coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ else
+ {
+ coder->NumInStreams = 1;
+ coder->NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
+ return SZ_ERROR_MEM;
+ RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
+ }
+ }
+ while ((mainByte & 0x80) != 0)
+ {
+ RINOK(SzReadByte(sd, &mainByte));
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 n;
+ RINOK(SzReadNumber32(sd, &n));
+ RINOK(SzReadNumber32(sd, &n));
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ RINOK(SzSkeepDataSize(sd, propertiesSize));
+ }
+ }
+ numInStreams += coder->NumInStreams;
+ numOutStreams += coder->NumOutStreams;
+ }
+
+ if (numOutStreams == 0)
+ return SZ_ERROR_UNSUPPORTED;
+
+ folder->NumBindPairs = numBindPairs = numOutStreams - 1;
+ MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
+
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair *bp = folder->BindPairs + i;
+ RINOK(SzReadNumber32(sd, &bp->InIndex));
+ RINOK(SzReadNumber32(sd, &bp->OutIndex));
+ }
+
+ if (numInStreams < numBindPairs)
+ return SZ_ERROR_UNSUPPORTED;
+
+ folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
+ MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
+
+ if (numPackStreams == 1)
+ {
+ for (i = 0; i < numInStreams ; i++)
+ if (SzFolder_FindBindPairForInStream(folder, i) < 0)
+ break;
+ if (i == numInStreams)
+ return SZ_ERROR_UNSUPPORTED;
+ folder->PackStreams[0] = i;
+ }
+ else
+ for (i = 0; i < numPackStreams; i++)
+ {
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadUnpackInfo(
+ CSzData *sd,
+ UInt32 *numFolders,
+ CSzFolder **folders, /* for alloc */
+ ISzAlloc *alloc,
+ ISzAlloc *allocTemp)
+{
+ UInt32 i;
+ RINOK(SzWaitAttribute(sd, k7zIdFolder));
+ RINOK(SzReadNumber32(sd, numFolders));
+ {
+ RINOK(SzReadSwitch(sd));
+
+ MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
+
+ for (i = 0; i < *numFolders; i++)
+ SzFolder_Init((*folders) + i);
+
+ for (i = 0; i < *numFolders; i++)
+ {
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
+ }
+ }
+
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
+
+ for (i = 0; i < *numFolders; i++)
+ {
+ UInt32 j;
+ CSzFolder *folder = (*folders) + i;
+ UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
+
+ MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
+
+ for (j = 0; j < numOutStreams; j++)
+ {
+ RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
+ }
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ SRes res;
+ Byte *crcsDefined = 0;
+ UInt32 *crcs = 0;
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < *numFolders; i++)
+ {
+ CSzFolder *folder = (*folders) + i;
+ folder->UnpackCRCDefined = crcsDefined[i];
+ folder->UnpackCRC = crcs[i];
+ }
+ }
+ IAlloc_Free(allocTemp, crcs);
+ IAlloc_Free(allocTemp, crcsDefined);
+ RINOK(res);
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+static SRes SzReadSubStreamsInfo(
+ CSzData *sd,
+ UInt32 numFolders,
+ CSzFolder *folders,
+ UInt32 *numUnpackStreams,
+ UInt64 **unpackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type = 0;
+ UInt32 i;
+ UInt32 si = 0;
+ UInt32 numDigests = 0;
+
+ for (i = 0; i < numFolders; i++)
+ folders[i].NumUnpackStreams = 1;
+ *numUnpackStreams = numFolders;
+
+ for (;;)
+ {
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdNumUnpackStream)
+ {
+ *numUnpackStreams = 0;
+ for (i = 0; i < numFolders; i++)
+ {
+ UInt32 numStreams;
+ RINOK(SzReadNumber32(sd, &numStreams));
+ folders[i].NumUnpackStreams = numStreams;
+ *numUnpackStreams += numStreams;
+ }
+ continue;
+ }
+ if (type == k7zIdCRC || type == k7zIdSize)
+ break;
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzSkeepData(sd));
+ }
+
+ if (*numUnpackStreams == 0)
+ {
+ *unpackSizes = 0;
+ *digestsDefined = 0;
+ *digests = 0;
+ }
+ else
+ {
+ *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
+ RINOM(*unpackSizes);
+ *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
+ RINOM(*digestsDefined);
+ *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
+ RINOM(*digests);
+ }
+
+ for (i = 0; i < numFolders; i++)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: we check that folder is empty
+ */
+ UInt64 sum = 0;
+ UInt32 j;
+ UInt32 numSubstreams = folders[i].NumUnpackStreams;
+ if (numSubstreams == 0)
+ continue;
+ if (type == k7zIdSize)
+ for (j = 1; j < numSubstreams; j++)
+ {
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ (*unpackSizes)[si++] = size;
+ sum += size;
+ }
+ (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
+ }
+ if (type == k7zIdSize)
+ {
+ RINOK(SzReadID(sd, &type));
+ }
+
+ for (i = 0; i < *numUnpackStreams; i++)
+ {
+ (*digestsDefined)[i] = 0;
+ (*digests)[i] = 0;
+ }
+
+
+ for (i = 0; i < numFolders; i++)
+ {
+ UInt32 numSubstreams = folders[i].NumUnpackStreams;
+ if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+ numDigests += numSubstreams;
+ }
+
+
+ si = 0;
+ for (;;)
+ {
+ if (type == k7zIdCRC)
+ {
+ int digestIndex = 0;
+ Byte *digestsDefined2 = 0;
+ UInt32 *digests2 = 0;
+ SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < numFolders; i++)
+ {
+ CSzFolder *folder = folders + i;
+ UInt32 numSubstreams = folder->NumUnpackStreams;
+ if (numSubstreams == 1 && folder->UnpackCRCDefined)
+ {
+ (*digestsDefined)[si] = 1;
+ (*digests)[si] = folder->UnpackCRC;
+ si++;
+ }
+ else
+ {
+ UInt32 j;
+ for (j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ (*digestsDefined)[si] = digestsDefined2[digestIndex];
+ (*digests)[si] = digests2[digestIndex];
+ si++;
+ }
+ }
+ }
+ }
+ IAlloc_Free(allocTemp, digestsDefined2);
+ IAlloc_Free(allocTemp, digests2);
+ RINOK(res);
+ }
+ else if (type == k7zIdEnd)
+ return SZ_OK;
+ else
+ {
+ RINOK(SzSkeepData(sd));
+ }
+ RINOK(SzReadID(sd, &type));
+ }
+}
+
+
+static SRes SzReadStreamsInfo(
+ CSzData *sd,
+ UInt64 *dataOffset,
+ CSzAr *p,
+ UInt32 *numUnpackStreams,
+ UInt64 **unpackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ ISzAlloc *alloc,
+ ISzAlloc *allocTemp)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if ((UInt64)(int)type != type)
+ return SZ_ERROR_UNSUPPORTED;
+ switch((int)type)
+ {
+ case k7zIdEnd:
+ return SZ_OK;
+ case k7zIdPackInfo:
+ {
+ RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
+ &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
+ break;
+ }
+ case k7zIdUnpackInfo:
+ {
+ RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
+ break;
+ }
+ case k7zIdSubStreamsInfo:
+ {
+ RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
+ numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
+ break;
+ }
+ default:
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
+{
+ UInt32 i;
+ for (i = 0; i < numFiles; i++)
+ {
+ UInt32 len = 0;
+ UInt32 pos = 0;
+ CSzFileItem *file = files + i;
+ while (pos + 2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ len++;
+ if (value == 0)
+ break;
+ if (value < 0x80)
+ continue;
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2;
+ if (value >= 0xDC00)
+ return SZ_ERROR_ARCHIVE;
+ if (pos + 2 > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return SZ_ERROR_ARCHIVE;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ len += numAdds;
+ }
+
+ MY_ALLOC(char, file->Name, (size_t)len, alloc);
+
+ len = 0;
+ while (2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ if (value < 0x80)
+ {
+ file->Name[len++] = (char)value;
+ if (value == 0)
+ break;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while (numAdds > 0);
+
+ len += numAdds;
+ }
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadHeader2(
+ CSzArEx *p, /* allocMain */
+ CSzData *sd,
+ UInt64 **unpackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ Byte **emptyStreamVector, /* allocTemp */
+ Byte **emptyFileVector, /* allocTemp */
+ Byte **lwtVector, /* allocTemp */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type;
+ UInt32 numUnpackStreams = 0;
+ UInt32 numFiles = 0;
+ CSzFileItem *files = 0;
+ UInt32 numEmptyStreams = 0;
+ UInt32 i;
+
+ RINOK(SzReadID(sd, &type));
+
+ if (type == k7zIdArchiveProperties)
+ {
+ RINOK(SzReadArchiveProperties(sd));
+ RINOK(SzReadID(sd, &type));
+ }
+
+
+ if (type == k7zIdMainStreamsInfo)
+ {
+ RINOK(SzReadStreamsInfo(sd,
+ &p->dataPos,
+ &p->db,
+ &numUnpackStreams,
+ unpackSizes,
+ digestsDefined,
+ digests, allocMain, allocTemp));
+ p->dataPos += p->startPosAfterHeader;
+ RINOK(SzReadID(sd, &type));
+ }
+
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type != k7zIdFilesInfo)
+ return SZ_ERROR_ARCHIVE;
+
+ RINOK(SzReadNumber32(sd, &numFiles));
+ p->db.NumFiles = numFiles;
+
+ MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
+
+ p->db.Files = files;
+ for (i = 0; i < numFiles; i++)
+ SzFile_Init(files + i);
+
+ for (;;)
+ {
+ UInt64 type;
+ UInt64 size;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzReadNumber(sd, &size));
+
+ if ((UInt64)(int)type != type)
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ else
+ switch((int)type)
+ {
+ case k7zIdName:
+ {
+ RINOK(SzReadSwitch(sd));
+ RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
+ break;
+ }
+ case k7zIdEmptyStream:
+ {
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
+ numEmptyStreams = 0;
+ for (i = 0; i < numFiles; i++)
+ if ((*emptyStreamVector)[i])
+ numEmptyStreams++;
+ break;
+ }
+ case k7zIdEmptyFile:
+ {
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
+ break;
+ }
+ case k7zIdMTime:
+ {
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
+ RINOK(SzReadSwitch(sd));
+ for (i = 0; i < numFiles; i++)
+ {
+ CSzFileItem *f = &files[i];
+ Byte defined = (*lwtVector)[i];
+ f->MTimeDefined = defined;
+ f->MTime.Low = f->MTime.High = 0;
+ if (defined)
+ {
+ RINOK(SzReadUInt32(sd, &f->MTime.Low));
+ RINOK(SzReadUInt32(sd, &f->MTime.High));
+ }
+ }
+ break;
+ }
+ default:
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ }
+ }
+
+ {
+ UInt32 emptyFileIndex = 0;
+ UInt32 sizeIndex = 0;
+ for (i = 0; i < numFiles; i++)
+ {
+ CSzFileItem *file = files + i;
+ file->IsAnti = 0;
+ if (*emptyStreamVector == 0)
+ file->HasStream = 1;
+ else
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+ if (file->HasStream)
+ {
+ file->IsDir = 0;
+ file->Size = (*unpackSizes)[sizeIndex];
+ file->FileCRC = (*digests)[sizeIndex];
+ file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ if (*emptyFileVector == 0)
+ file->IsDir = 1;
+ else
+ file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+ emptyFileIndex++;
+ file->Size = 0;
+ file->FileCRCDefined = 0;
+ }
+ }
+ }
+ return SzArEx_Fill(p, allocMain);
+}
+
+static SRes SzReadHeader(
+ CSzArEx *p,
+ CSzData *sd,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 *unpackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ Byte *emptyStreamVector = 0;
+ Byte *emptyFileVector = 0;
+ Byte *lwtVector = 0;
+ SRes res = SzReadHeader2(p, sd,
+ &unpackSizes, &digestsDefined, &digests,
+ &emptyStreamVector, &emptyFileVector, &lwtVector,
+ allocMain, allocTemp);
+ IAlloc_Free(allocTemp, unpackSizes);
+ IAlloc_Free(allocTemp, digestsDefined);
+ IAlloc_Free(allocTemp, digests);
+ IAlloc_Free(allocTemp, emptyStreamVector);
+ IAlloc_Free(allocTemp, emptyFileVector);
+ IAlloc_Free(allocTemp, lwtVector);
+ return res;
+}
+
+static SRes SzReadAndDecodePackedStreams2(
+ ILookInStream *inStream,
+ CSzData *sd,
+ CBuf *outBuffer,
+ UInt64 baseOffset,
+ CSzAr *p,
+ UInt64 **unpackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+
+ UInt32 numUnpackStreams = 0;
+ UInt64 dataStartPos;
+ CSzFolder *folder;
+ UInt64 unpackSize;
+ SRes res;
+
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
+ &numUnpackStreams, unpackSizes, digestsDefined, digests,
+ allocTemp, allocTemp));
+
+ dataStartPos += baseOffset;
+ if (p->NumFolders != 1)
+ return SZ_ERROR_ARCHIVE;
+
+ folder = p->Folders;
+ unpackSize = SzFolder_GetUnpackSize(folder);
+
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos));
+
+ if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
+ return SZ_ERROR_MEM;
+
+ res = SzDecode(p->PackSizes, folder,
+ inStream, dataStartPos,
+ outBuffer->data, (size_t)unpackSize, allocTemp);
+ RINOK(res);
+ if (folder->UnpackCRCDefined)
+ if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
+ return SZ_ERROR_CRC;
+ return SZ_OK;
+}
+
+static SRes SzReadAndDecodePackedStreams(
+ ILookInStream *inStream,
+ CSzData *sd,
+ CBuf *outBuffer,
+ UInt64 baseOffset,
+ ISzAlloc *allocTemp)
+{
+ CSzAr p;
+ UInt64 *unpackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ SRes res;
+ SzAr_Init(&p);
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+ &p, &unpackSizes, &digestsDefined, &digests,
+ allocTemp);
+ SzAr_Free(&p, allocTemp);
+ IAlloc_Free(allocTemp, unpackSizes);
+ IAlloc_Free(allocTemp, digestsDefined);
+ IAlloc_Free(allocTemp, digests);
+ return res;
+}
+
+static SRes SzArEx_Open2(
+ CSzArEx *p,
+ ILookInStream *inStream,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ Byte header[k7zStartHeaderSize];
+ UInt64 nextHeaderOffset, nextHeaderSize;
+ size_t nextHeaderSizeT;
+ UInt32 nextHeaderCRC;
+ CBuf buffer;
+ SRes res;
+
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
+
+ if (!TestSignatureCandidate(header))
+ return SZ_ERROR_NO_ARCHIVE;
+ if (header[6] != k7zMajorVersion)
+ return SZ_ERROR_UNSUPPORTED;
+
+ nextHeaderOffset = GetUi64(header + 12);
+ nextHeaderSize = GetUi64(header + 20);
+ nextHeaderCRC = GetUi32(header + 28);
+
+ p->startPosAfterHeader = k7zStartHeaderSize;
+
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
+ return SZ_ERROR_CRC;
+
+ nextHeaderSizeT = (size_t)nextHeaderSize;
+ if (nextHeaderSizeT != nextHeaderSize)
+ return SZ_ERROR_MEM;
+ if (nextHeaderSizeT == 0)
+ return SZ_OK;
+ if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
+ nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
+ return SZ_ERROR_NO_ARCHIVE;
+
+ {
+ Int64 pos = 0;
+ RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+ if ((UInt64)pos < nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+ return SZ_ERROR_INPUT_EOF;
+ }
+
+ RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
+
+ if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
+ return SZ_ERROR_MEM;
+
+ res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
+ if (res == SZ_OK)
+ {
+ res = SZ_ERROR_ARCHIVE;
+ if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
+ {
+ CSzData sd;
+ UInt64 type;
+ sd.Data = buffer.data;
+ sd.Size = buffer.size;
+ res = SzReadID(&sd, &type);
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdEncodedHeader)
+ {
+ CBuf outBuffer;
+ Buf_Init(&outBuffer);
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
+ if (res != SZ_OK)
+ Buf_Free(&outBuffer, allocTemp);
+ else
+ {
+ Buf_Free(&buffer, allocTemp);
+ buffer.data = outBuffer.data;
+ buffer.size = outBuffer.size;
+ sd.Data = buffer.data;
+ sd.Size = buffer.size;
+ res = SzReadID(&sd, &type);
+ }
+ }
+ }
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdHeader)
+ res = SzReadHeader(p, &sd, allocMain, allocTemp);
+ else
+ res = SZ_ERROR_UNSUPPORTED;
+ }
+ }
+ }
+ Buf_Free(&buffer, allocTemp);
+ return res;
+}
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
+{
+ SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
+ if (res != SZ_OK)
+ SzArEx_Free(p, allocMain);
+ return res;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
--- /dev/null
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include <string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+ { UPDATE_0(p); i = (i + i); A0; } else \
+ { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+ { i = 1; \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+ Result:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Error
+ p->remainLen:
+ < kMatchSpecLenStart : normal remain
+ = kMatchSpecLenStart : finished
+ = kMatchSpecLenStart + 1 : Flush marker
+ = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ CLzmaProb *probs = p->probs;
+
+ unsigned state = p->state;
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+ unsigned lc = p->prop.lc;
+
+ Byte *dic = p->dic;
+ SizeT dicBufSize = p->dicBufSize;
+ SizeT dicPos = p->dicPos;
+
+ UInt32 processedPos = p->processedPos;
+ UInt32 checkDicSize = p->checkDicSize;
+ unsigned len = 0;
+
+ const Byte *buf = p->buf;
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+
+ do
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = processedPos & pbMask;
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ unsigned symbol;
+ UPDATE_0(prob);
+ prob = probs + Literal;
+ if (checkDicSize != 0 || processedPos != 0)
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+ if (state < kNumLitStates)
+ {
+ symbol = 1;
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned offs = 0x100;
+ symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ dic[dicPos++] = (Byte)symbol;
+ processedPos++;
+
+ state = kLiteralNextStates[state];
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+ continue;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRep + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ state += kNumStates;
+ prob = probs + LenCoder;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ if (checkDicSize == 0 && processedPos == 0)
+ return SZ_ERROR_DATA;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ processedPos++;
+ state = state < kNumLitStates ? 9 : 11;
+ continue;
+ }
+ UPDATE_1(prob);
+ }
+ else
+ {
+ UInt32 distance;
+ UPDATE_1(prob);
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit = (1 << kLenNumLowBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit = (1 << kLenNumMidBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit = (1 << kLenNumHighBits);
+ }
+ }
+ TREE_DECODE(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state >= kNumStates)
+ {
+ UInt32 distance;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+ TREE_6_DECODE(prob, distance);
+ if (distance >= kStartPosModelIndex)
+ {
+ unsigned posSlot = (unsigned)distance;
+ int numDirectBits = (int)(((distance >> 1) - 1));
+ distance = (2 | (distance & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ distance <<= numDirectBits;
+ prob = probs + SpecPos + distance - posSlot - 1;
+ {
+ UInt32 mask = 1;
+ unsigned i = 1;
+ do
+ {
+ GET_BIT2(prob + i, i, ; , distance |= mask);
+ mask <<= 1;
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE
+ range >>= 1;
+
+ {
+ UInt32 t;
+ code -= range;
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+ distance = (distance << 1) + (t + 1);
+ code += range & t;
+ }
+ /*
+ distance <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ distance |= 1;
+ }
+ */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ distance <<= kNumAlignBits;
+ {
+ unsigned i = 1;
+ GET_BIT2(prob + i, i, ; , distance |= 1);
+ GET_BIT2(prob + i, i, ; , distance |= 2);
+ GET_BIT2(prob + i, i, ; , distance |= 4);
+ GET_BIT2(prob + i, i, ; , distance |= 8);
+ }
+ if (distance == (UInt32)0xFFFFFFFF)
+ {
+ len += kMatchSpecLenStart;
+ state -= kNumStates;
+ break;
+ }
+ }
+ }
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance + 1;
+ if (checkDicSize == 0)
+ {
+ if (distance >= processedPos)
+ return SZ_ERROR_DATA;
+ }
+ else if (distance >= checkDicSize)
+ return SZ_ERROR_DATA;
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+ /* state = kLiteralNextStates[state]; */
+ }
+
+ len += kMatchMinLen;
+
+ if (limit == dicPos)
+ return SZ_ERROR_DATA;
+ {
+ SizeT rem = limit - dicPos;
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+ processedPos += curLen;
+
+ len -= curLen;
+ if (pos + curLen <= dicBufSize)
+ {
+ Byte *dest = dic + dicPos;
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+ const Byte *lim = dest + curLen;
+ dicPos += curLen;
+ do
+ *(dest) = (Byte)*(dest + src);
+ while (++dest != lim);
+ }
+ else
+ {
+ do
+ {
+ dic[dicPos++] = dic[pos];
+ if (++pos == dicBufSize)
+ pos = 0;
+ }
+ while (--curLen != 0);
+ }
+ }
+ }
+ }
+ while (dicPos < limit && buf < bufLimit);
+ NORMALIZE;
+ p->buf = buf;
+ p->range = range;
+ p->code = code;
+ p->remainLen = len;
+ p->dicPos = dicPos;
+ p->processedPos = processedPos;
+ p->reps[0] = rep0;
+ p->reps[1] = rep1;
+ p->reps[2] = rep2;
+ p->reps[3] = rep3;
+ p->state = state;
+
+ return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+ {
+ Byte *dic = p->dic;
+ SizeT dicPos = p->dicPos;
+ SizeT dicBufSize = p->dicBufSize;
+ unsigned len = p->remainLen;
+ UInt32 rep0 = p->reps[0];
+ if (limit - dicPos < len)
+ len = (unsigned)(limit - dicPos);
+
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+ p->checkDicSize = p->prop.dicSize;
+
+ p->processedPos += len;
+ p->remainLen -= len;
+ while (len-- != 0)
+ {
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ }
+ p->dicPos = dicPos;
+ }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ do
+ {
+ SizeT limit2 = limit;
+ if (p->checkDicSize == 0)
+ {
+ UInt32 rem = p->prop.dicSize - p->processedPos;
+ if (limit - p->dicPos > rem)
+ limit2 = p->dicPos + rem;
+ }
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+ if (p->processedPos >= p->prop.dicSize)
+ p->checkDicSize = p->prop.dicSize;
+ LzmaDec_WriteRem(p, limit);
+ }
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+ if (p->remainLen > kMatchSpecLenStart)
+ {
+ p->remainLen = kMatchSpecLenStart;
+ }
+ return 0;
+}
+
+typedef enum
+{
+ DUMMY_ERROR, /* unexpected end of input stream */
+ DUMMY_LIT,
+ DUMMY_MATCH,
+ DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+ const Byte *bufLimit = buf + inSize;
+ CLzmaProb *probs = p->probs;
+ unsigned state = p->state;
+ ELzmaDummy res;
+
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK
+
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+ prob = probs + Literal;
+ if (p->checkDicSize != 0 || p->processedPos != 0)
+ prob += (LZMA_LIT_SIZE *
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+ if (state < kNumLitStates)
+ {
+ unsigned symbol = 1;
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+ unsigned offs = 0x100;
+ unsigned symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ res = DUMMY_LIT;
+ }
+ else
+ {
+ unsigned len;
+ UPDATE_1_CHECK;
+
+ prob = probs + IsRep + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ state = 0;
+ prob = probs + LenCoder;
+ res = DUMMY_MATCH;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ res = DUMMY_REP;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ NORMALIZE_CHECK;
+ return DUMMY_REP;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ }
+ state = kNumStates;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit = 1 << kLenNumLowBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenChoice2;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit = 1 << kLenNumMidBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit = 1 << kLenNumHighBits;
+ }
+ }
+ TREE_DECODE_CHECK(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ unsigned posSlot;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+ if (posSlot < kEndPosModelIndex)
+ {
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE_CHECK
+ range >>= 1;
+ code -= range & (((code - range) >> 31) - 1);
+ /* if (code >= range) code -= range; */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ unsigned i = 1;
+ do
+ {
+ GET_BIT_CHECK(prob + i, i);
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ }
+ }
+ }
+ NORMALIZE_CHECK;
+ return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+ p->range = 0xFFFFFFFF;
+ p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+ p->needFlush = 1;
+ p->remainLen = 0;
+ p->tempBufSize = 0;
+
+ if (initDic)
+ {
+ p->processedPos = 0;
+ p->checkDicSize = 0;
+ p->needInitState = 1;
+ }
+ if (initState)
+ p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+ p->dicPos = 0;
+ LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+ UInt32 i;
+ CLzmaProb *probs = p->probs;
+ for (i = 0; i < numProbs; i++)
+ probs[i] = kBitModelTotal >> 1;
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+ p->state = 0;
+ p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+ ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT inSize = *srcLen;
+ (*srcLen) = 0;
+ LzmaDec_WriteRem(p, dicLimit);
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+
+ while (p->remainLen != kMatchSpecLenStart)
+ {
+ int checkEndMarkNow;
+
+ if (p->needFlush != 0)
+ {
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+ p->tempBuf[p->tempBufSize++] = *src++;
+ if (p->tempBufSize < RC_INIT_SIZE)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (p->tempBuf[0] != 0)
+ return SZ_ERROR_DATA;
+
+ LzmaDec_InitRc(p, p->tempBuf);
+ p->tempBufSize = 0;
+ }
+
+ checkEndMarkNow = 0;
+ if (p->dicPos >= dicLimit)
+ {
+ if (p->remainLen == 0 && p->code == 0)
+ {
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+ return SZ_OK;
+ }
+ if (finishMode == LZMA_FINISH_ANY)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_OK;
+ }
+ if (p->remainLen != 0)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ checkEndMarkNow = 1;
+ }
+
+ if (p->needInitState)
+ LzmaDec_InitStateReal(p);
+
+ if (p->tempBufSize == 0)
+ {
+ SizeT processed;
+ const Byte *bufLimit;
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ memcpy(p->tempBuf, src, inSize);
+ p->tempBufSize = (unsigned)inSize;
+ (*srcLen) += inSize;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ bufLimit = src;
+ }
+ else
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+ p->buf = src;
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+ return SZ_ERROR_DATA;
+ processed = (SizeT)(p->buf - src);
+ (*srcLen) += processed;
+ src += processed;
+ inSize -= processed;
+ }
+ else
+ {
+ unsigned rem = p->tempBufSize, lookAhead = 0;
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+ p->tempBuf[rem++] = src[lookAhead++];
+ p->tempBufSize = rem;
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ (*srcLen) += lookAhead;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ }
+ p->buf = p->tempBuf;
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+ return SZ_ERROR_DATA;
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+ (*srcLen) += lookAhead;
+ src += lookAhead;
+ inSize -= lookAhead;
+ p->tempBufSize = 0;
+ }
+ }
+ if (p->code == 0)
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT outSize = *destLen;
+ SizeT inSize = *srcLen;
+ *srcLen = *destLen = 0;
+ for (;;)
+ {
+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
+ ELzmaFinishMode curFinishMode;
+ SRes res;
+ if (p->dicPos == p->dicBufSize)
+ p->dicPos = 0;
+ dicPos = p->dicPos;
+ if (outSize > p->dicBufSize - dicPos)
+ {
+ outSizeCur = p->dicBufSize;
+ curFinishMode = LZMA_FINISH_ANY;
+ }
+ else
+ {
+ outSizeCur = dicPos + outSize;
+ curFinishMode = finishMode;
+ }
+
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+ src += inSizeCur;
+ inSize -= inSizeCur;
+ *srcLen += inSizeCur;
+ outSizeCur = p->dicPos - dicPos;
+ memcpy(dest, p->dic + dicPos, outSizeCur);
+ dest += outSizeCur;
+ outSize -= outSizeCur;
+ *destLen += outSizeCur;
+ if (res != 0)
+ return res;
+ if (outSizeCur == 0 || outSize == 0)
+ return SZ_OK;
+ }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->probs);
+ p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->dic);
+ p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+ LzmaDec_FreeProbs(p, alloc);
+ LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+ UInt32 dicSize;
+ Byte d;
+
+ if (size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_UNSUPPORTED;
+ else
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+ if (dicSize < LZMA_DIC_MIN)
+ dicSize = LZMA_DIC_MIN;
+ p->dicSize = dicSize;
+
+ d = data[0];
+ if (d >= (9 * 5 * 5))
+ return SZ_ERROR_UNSUPPORTED;
+
+ p->lc = d % 9;
+ d /= 9;
+ p->pb = d / 5;
+ p->lp = d % 5;
+
+ return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+ if (p->probs == 0 || numProbs != p->numProbs)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+ p->numProbs = numProbs;
+ if (p->probs == 0)
+ return SZ_ERROR_MEM;
+ }
+ return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ SizeT dicBufSize;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ dicBufSize = propNew.dicSize;
+ if (p->dic == 0 || dicBufSize != p->dicBufSize)
+ {
+ LzmaDec_FreeDict(p, alloc);
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+ if (p->dic == 0)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ }
+ p->dicBufSize = dicBufSize;
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc)
+{
+ CLzmaDec p;
+ SRes res;
+ SizeT inSize = *srcLen;
+ SizeT outSize = *destLen;
+ *srcLen = *destLen = 0;
+ if (inSize < RC_INIT_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+
+ LzmaDec_Construct(&p);
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+ if (res != 0)
+ return res;
+ p.dic = dest;
+ p.dicBufSize = outSize;
+
+ LzmaDec_Init(&p);
+
+ *srcLen = inSize;
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ res = SZ_ERROR_INPUT_EOF;
+
+ (*destLen) = p.dicPos;
+ LzmaDec_FreeProbs(&p, alloc);
+ return res;
+}
--- /dev/null
+/* 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
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
-LzmaTypes.h
-
-Types for LZMA Decoder
-
-This file written and distributed to public domain by Igor Pavlov.
-This file is part of LZMA SDK 4.40 (2006-05-01)
-*/
-
-#ifndef __LZMATYPES_H
-#define __LZMATYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef unsigned long UInt32;
-#else
-typedef unsigned int UInt32;
-#endif
-#endif
-
-/* #define _LZMA_SYSTEM_SIZE_T */
-/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
-
-#ifndef _7ZIP_SIZET_DEFINED
-#define _7ZIP_SIZET_DEFINED
-#ifdef _LZMA_SYSTEM_SIZE_T
-#include <stddef.h>
-typedef size_t SizeT;
-#else
-typedef UInt32 SizeT;
-#endif
-#endif
-
-#endif
--- /dev/null
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include <stddef.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct
+{
+ size_t (*Write)(void *p, const void *buf, size_t size);
+ /* Returns: result - the number of actually written bytes.
+ (result < size) means error */
+} ISeqOutStream;
+
+typedef enum
+{
+ SZ_SEEK_SET = 0,
+ SZ_SEEK_CUR = 1,
+ SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct
+{
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct
+{
+ SRes (*Look)(void *p, void **buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) > input(*size)) is not allowed
+ (output(*size) < input(*size)) is allowed */
+ SRes (*Skip)(void *p, size_t offset);
+ /* offset must be <= output(*size) of Look */
+
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct
+{
+ ILookInStream s;
+ ISeekInStream *realStream;
+ size_t pos;
+ size_t size;
+ Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct
+{
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+ /* Returns: result. (result != SZ_OK) means break.
+ Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
#define FTIME
#define NOBSTRING
#define NOINDEX
+#define MKTIME
/* ------------------------------------------------------------------------ */
/* LHa for UNIX Archiver Driver */
NULL
};
-struct zvolume *archive_directory_lha(struct zfile *zf)
+struct zvolume *archive_directory_lha (struct zfile *zf)
{
struct zvolume *zv;
struct zarchive_info zai;
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;
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);
/* 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)
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
{
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];
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);
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
*/
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);
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
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);
{
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);
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);
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);
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);
reset_inputdevice_config (p);
}
- fh = zfile_fopen (filename, L"r");
+ fh = zfile_fopen (filename, L"r", ZFD_NORMAL);
#ifndef SINGLEFILE
if (! fh)
return 0;
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;
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]);
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);
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 ())
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);
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);
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")) {
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;
}
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;
}
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++) {
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);
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')
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;
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;
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);
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);
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);
} 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);
}
} 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;
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;
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;
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;
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;
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;
static void diskfile_readonly (const TCHAR *name, int readonly)
{
- struct stat st;
+ struct _stat64 st;
int mode, oldmode;
if (stat (name, &st))
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)) {
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;
--- /dev/null
+#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
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;
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;
; 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
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
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
setup_exter:
movem.l d0-d1/a0-a1,-(sp)
+ bsr.w residenthack
moveq.l #26,d0
move.l #$10001,d1
jsr AllocMem(a6)
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
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
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
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
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);
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;
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++;
{
int i;
int n = get_byte (addr);
- uae_char buf[256];
+ uae_char buf[257];
addr++;
for (i = 0; i < n; i++, addr++)
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)
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 {
}
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.
}
/* 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);
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)
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 ();
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)
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);
db(0x27); db(0x4c); db(0x01); db(0x9c); db(0x7c); db(0x00); db(0xbc); db(0xad);
db(0x01); db(0x0c); db(0x64); db(0x2c); db(0x2f); db(0x06); db(0x7e); db(0x01);
db(0x4a); db(0x45); db(0x67); db(0x04); db(0x08); db(0xc7); db(0x00); db(0x02);
- db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); db(0x06); db(0xd6);
+ db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); db(0x06); db(0xce);
db(0x26); db(0x5f); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
db(0x67); db(0x08); db(0x48); db(0x46); db(0x52); db(0x46); db(0x48); db(0x46);
db(0x60); db(0xdc); db(0x2c); db(0x1f); db(0x52); db(0x46); db(0x60); db(0xce);
db(0x00); db(0x00); db(0x02); db(0x2c); db(0x4e); db(0xae); db(0xff); db(0x2e);
db(0x2c); db(0x78); db(0x00); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae);
db(0xfe); db(0x62); db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00);
- db(0x0a); db(0xf8); db(0x4e); db(0x90); db(0x72); db(0x03); db(0x74); db(0xf6);
+ db(0x0a); db(0xf0); db(0x4e); db(0x90); db(0x72); db(0x03); db(0x74); db(0xf6);
db(0x20); db(0x7c); db(0x00); db(0x20); db(0x00); db(0x00); db(0x90); db(0x88);
db(0x65); db(0x0a); db(0x67); db(0x08); db(0x78); db(0x00); db(0x22); db(0x44);
- db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0x99);
+ db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0x47);
db(0x43); db(0xfa); db(0x00); db(0x54); db(0x70); db(0x0a); db(0x61); db(0x00);
- db(0x0b); db(0xac); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xc4); db(0x4e); db(0x90);
+ db(0x0b); db(0xa4); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xbc); db(0x4e); db(0x90);
db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7);
db(0x38); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x00);
db(0x28); db(0x01); db(0x26); db(0x09); db(0x24); db(0x48); db(0x43); db(0xfa);
- db(0x15); db(0x93); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x15); db(0x41); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
db(0x4a); db(0x80); db(0x67); db(0x14); db(0x2c); db(0x40); db(0x22); db(0x0a);
db(0xe4); db(0x8b); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x22); db(0x4e);
db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
db(0x4c); db(0xdf); db(0x44); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x78);
db(0x00); db(0x04); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x15); db(0x44);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x14); db(0xf2);
db(0x43); db(0xfa); db(0x00); db(0x16); db(0x70); db(0x0f); db(0x22); db(0x3c);
db(0x00); db(0x00); db(0x1f); db(0x40); db(0x61); db(0x00); db(0xff); db(0xa8);
db(0x60); db(0xdc); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
db(0x00); db(0x00); db(0x00); db(0x00); db(0x72); db(0x02); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x4c); db(0x4e); db(0x90);
- db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x07); db(0x92);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x44); db(0x4e); db(0x90);
+ db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x07); db(0x8a);
db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x20);
- db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x32);
+ db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x2a);
db(0x70); db(0x00); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00);
db(0x00); db(0xa2); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c);
- db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x1c); db(0x70); db(0x02);
+ db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x14); db(0x70); db(0x02);
db(0x4e); db(0x90); db(0x0c); db(0x40); db(0x00); db(0x01); db(0x6d); db(0x00);
db(0x00); db(0x7c); db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92);
db(0x60); db(0xe4); db(0x0c); db(0x40); db(0x00); db(0x02); db(0x6e); db(0x08);
db(0x00); db(0x18); db(0x25); db(0x49); db(0x00); db(0x1a); db(0x20); db(0x69);
db(0x00); db(0x10); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0x92);
db(0x60); db(0x00); db(0xff); db(0x74); db(0x30); db(0x3c); db(0xff); db(0x50);
- db(0x61); db(0x00); db(0x09); db(0x8e); db(0x70); db(0x04); db(0x4e); db(0x90);
+ db(0x61); db(0x00); db(0x09); db(0x86); db(0x70); db(0x04); db(0x4e); db(0x90);
db(0x70); db(0x01); db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x70); db(0x1a); db(0x22); db(0x3c);
- db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x22); db(0x40); db(0x41); db(0xfa); db(0x14); db(0x1c); db(0x23); db(0x48);
- db(0x00); db(0x0a); db(0x41); db(0xfa); db(0xff); db(0x28); db(0x23); db(0x48);
- db(0x00); db(0x0e); db(0x41); db(0xfa); db(0xff); db(0x20); db(0x23); db(0x48);
- db(0x00); db(0x12); db(0x33); db(0x7c); db(0x02); db(0x14); db(0x00); db(0x08);
- db(0x70); db(0x03); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x30); db(0x3a);
- db(0x0a); db(0xdc); db(0x67); db(0x04); db(0x61); db(0x00); db(0x0a); db(0x7a);
- db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14); db(0x65); db(0x04);
- db(0x61); db(0x00); db(0x0f); db(0x5a); db(0x4c); db(0xdf); db(0x03); db(0x03);
+ db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x5a);
+ db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa);
+ db(0x13); db(0xc6); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
+ db(0xff); db(0x24); db(0x23); db(0x48); db(0x00); db(0x0e); db(0x41); db(0xfa);
+ db(0xff); db(0x1c); db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c);
+ db(0x02); db(0x14); db(0x00); db(0x08); db(0x70); db(0x03); db(0x4e); db(0xae);
+ db(0xff); db(0x58); db(0x30); db(0x3a); db(0x0a); db(0xd0); db(0x67); db(0x04);
+ db(0x61); db(0x00); db(0x0a); db(0x6e); db(0x4c); db(0xdf); db(0x03); db(0x03);
db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xf2); db(0x2c); db(0x78);
db(0x00); db(0x04); db(0x24); db(0x48); db(0x26); db(0x49); db(0x20); db(0x3c);
db(0x00); db(0x00); db(0x00); db(0xbe); db(0x22); db(0x3c); db(0x00); db(0x01);
db(0x00); db(0x00); db(0x00); db(0x0e); db(0x52); db(0x40); db(0x0c); db(0x40);
db(0x00); db(0x8c); db(0x66); db(0xf2); db(0x20); db(0x0a); db(0xe4); db(0x88);
db(0x21); db(0x40); db(0x00); db(0x36); db(0x22); db(0x48); db(0x41); db(0xfa);
- db(0x13); db(0xa0); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
+ db(0x13); db(0x56); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
db(0x01); db(0x98); db(0x41); db(0xe8); db(0x00); db(0x12); db(0x4e); db(0xae);
db(0xff); db(0x10); db(0x4c); db(0xdf); db(0x4f); db(0x03); db(0x4e); db(0x75);
db(0x48); db(0xe7); db(0x7f); db(0x7e); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x60); db(0xf4); db(0x48); db(0xe7); db(0x40); db(0xe2); db(0x2c); db(0x78);
db(0x00); db(0x04); db(0x41); db(0xee); db(0x01); db(0x50); db(0x20); db(0x50);
db(0x4a); db(0x90); db(0x67); db(0x1a); db(0x22); db(0x68); db(0x00); db(0x0a);
- db(0x45); db(0xfa); db(0x12); db(0xf2); db(0x10); db(0x19); db(0x12); db(0x1a);
+ db(0x45); db(0xfa); db(0x12); db(0xa8); db(0x10); db(0x19); db(0x12); db(0x1a);
db(0xb0); db(0x01); db(0x66); db(0x06); db(0x4a); db(0x00); db(0x67); db(0x42);
db(0x60); db(0xf2); db(0x20); db(0x50); db(0x60); db(0xe2); db(0x70); db(0x20);
db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
db(0xff); db(0x3a); db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x08);
- db(0x00); db(0x08); db(0x41); db(0xfa); db(0x12); db(0xc8); db(0x25); db(0x48);
- db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x12); db(0x44); db(0x25); db(0x48);
+ db(0x00); db(0x08); db(0x41); db(0xfa); db(0x12); db(0x7e); db(0x25); db(0x48);
+ db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x11); db(0xfa); db(0x25); db(0x48);
db(0x00); db(0x0e); db(0x41); db(0xea); db(0x00); db(0x12); db(0x20); db(0x88);
db(0x58); db(0x90); db(0x21); db(0x48); db(0x00); db(0x08); db(0x41); db(0xee);
db(0x01); db(0x50); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xff); db(0x0a);
db(0x30); db(0x3c); db(0xff); db(0x28); db(0x61); db(0x00); db(0x04); db(0x42);
db(0x22); db(0x48); db(0x20); db(0x5f); db(0x42); db(0xa8); db(0x01); db(0x90);
db(0x42); db(0xa8); db(0x01); db(0x94); db(0x4e); db(0x91); db(0x26); db(0x00);
- db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf9); db(0x6e);
+ db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf9); db(0x76);
db(0x20); db(0x28); db(0x01); db(0x90); db(0x67); db(0x14); db(0x6b); db(0x12);
db(0x2f); db(0x08); db(0x72); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x5f); db(0x21); db(0x40);
db(0x22); db(0x69); db(0x01); db(0x94); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4c); db(0xdf); db(0x03); db(0x01);
db(0x4a); db(0x80); db(0x67); db(0x04); db(0x61); db(0x00); db(0xfa); db(0x7c);
- db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf8); db(0xe8); db(0x30); db(0x3c);
+ db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf8); db(0xf0); db(0x30); db(0x3c);
db(0xff); db(0x18); db(0x61); db(0x00); db(0x03); db(0x9c); db(0x4e); db(0x90);
db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80);
db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x17); db(0x70);
- db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0xb8); db(0x20); db(0x08);
+ db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x30); db(0x20); db(0x08);
db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x70); db(0xff);
db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07); db(0x00); db(0x00);
db(0x67); db(0x3a); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14);
db(0x67); db(0x3a); db(0x20); db(0x52); db(0x24); db(0x40); db(0x22); db(0x4a);
db(0x12); db(0xd8); db(0x66); db(0xfc); db(0x13); db(0x7c); db(0x00); db(0x3a);
db(0xff); db(0xff); db(0x42); db(0x11); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x43); db(0xfa); db(0x0d); db(0xc1); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0d); db(0x77); db(0x70); db(0x00); db(0x4e); db(0xae);
db(0xfd); db(0xd8); db(0x2c); db(0x40); db(0x22); db(0x0a); db(0x4e); db(0xae);
db(0xff); db(0x52); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4a); db(0x20); db(0x02);
db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75);
db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x01); db(0x7e); db(0x06);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0xbc);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0x72);
db(0x70); db(0x24); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
db(0x66); db(0x0e); db(0x08); db(0x87); db(0x00); db(0x02); db(0x43); db(0xfa);
- db(0x0d); db(0xaa); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x0d); db(0x60); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
db(0x28); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x2c);
db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
db(0xff); db(0x3a); db(0x20); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x2c);
db(0xfe); db(0x62); db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75);
db(0x2c); db(0x78); db(0x00); db(0x04); db(0x93); db(0xc9); db(0x4e); db(0xae);
db(0xfe); db(0xda); db(0x20); db(0x40); db(0x4b); db(0xe8); db(0x00); db(0x5c);
- db(0x43); db(0xfa); db(0x0d); db(0x11); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0c); db(0xc7); db(0x70); db(0x00); db(0x4e); db(0xae);
db(0xfd); db(0xd8); db(0x24); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00);
db(0x00); db(0xb9); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7c); db(0x00);
db(0x26); db(0x86); db(0x27); db(0x46); db(0x00); db(0x04); db(0x27); db(0x46);
db(0x00); db(0x08); db(0x27); db(0x4a); db(0x00); db(0xa0); db(0x50); db(0xeb);
db(0x00); db(0x9e); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0c); db(0x08);
+ db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0b); db(0xbe);
db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x84);
- db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0c); db(0x05);
+ db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0b); db(0xbb);
db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x74);
db(0x27); db(0x40); db(0x00); db(0xa8); db(0x7a); db(0x00); db(0x20); db(0x4d);
db(0x4e); db(0xae); db(0xfe); db(0x80); db(0x20); db(0x4d); db(0x4e); db(0xae);
db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e);
db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a);
db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0xf4); db(0x2a); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0x41); db(0xfa); db(0xf3); db(0xa2); db(0x02); db(0x80); db(0x00); db(0x00);
db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x20); db(0x88);
db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x21); db(0x48);
db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
db(0x25); db(0x4b); db(0x00); db(0x36); db(0x22); db(0x4a); db(0x24); db(0x43);
db(0x97); db(0xcb); db(0x24); db(0x09); db(0x4e); db(0xae); db(0xfe); db(0xe6);
db(0x20); db(0x02); db(0x4c); db(0xdf); db(0x4c); db(0x1c); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0x09); db(0x65); db(0x43); db(0xfa); db(0x01); db(0x5c);
+ db(0x41); db(0xfa); db(0x09); db(0x1b); db(0x43); db(0xfa); db(0x01); db(0x5c);
db(0x70); db(0x13); db(0x61); db(0x00); db(0xff); db(0x98); db(0x4e); db(0x75);
db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x33); db(0x7c); db(0x00); db(0x0a);
db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e);
db(0x00); db(0x08); db(0x27); db(0x46); db(0x00); db(0x0c); db(0x70); db(0xff);
db(0x37); db(0x40); db(0x00); db(0x00); db(0x43); db(0xed); db(0x00); db(0x00);
db(0x13); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08); db(0x13); db(0x7c);
- db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x07); db(0xa9);
+ db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x07); db(0x5f);
db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x02); db(0xda);
db(0x23); db(0x48); db(0x00); db(0x12); db(0x23); db(0x4d); db(0x00); db(0x0e);
db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x20); db(0x06);
db(0x00); db(0x1c); db(0x6a); db(0x06); db(0x70); db(0x0a); db(0x27); db(0x40);
db(0x00); db(0x1c); db(0x4a); db(0xab); db(0x00); db(0x14); db(0x66); db(0x16);
db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xe0); db(0x43); db(0xfa);
- db(0x07); db(0xc7); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x07); db(0x7d); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
db(0x27); db(0x40); db(0x00); db(0x14); db(0x67); db(0xd0); db(0x4a); db(0xab);
db(0x00); db(0x18); db(0x66); db(0x18); db(0x4a); db(0xab); db(0x00); db(0x1c);
- db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0xbd); db(0x70); db(0x00);
+ db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0x73); db(0x70); db(0x00);
db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x18);
db(0x67); db(0x00); db(0xff); db(0xb4); db(0x4a); db(0xad); db(0x02); db(0x08);
db(0x66); db(0x38); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xa6);
db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0xac); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x43); db(0xfa); db(0x06); db(0x62); db(0x4e); db(0xae); db(0xfe); db(0xec);
db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0x9a); db(0x70); db(0x00);
+ db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0x50); db(0x70); db(0x00);
db(0x72); db(0x00); db(0x61); db(0x00); db(0xfd); db(0x16); db(0x2b); db(0x40);
db(0x02); db(0x08); db(0x67); db(0x00); db(0x02); db(0x42); db(0x60); db(0x00);
db(0xff); db(0x76); db(0x4a); db(0xad); db(0x02); db(0x0c); db(0x66); db(0x48);
db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x00); db(0xff); db(0x68);
db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0x79); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x43); db(0xfa); db(0x06); db(0x2f); db(0x4e); db(0xae); db(0xfe); db(0xec);
db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa); db(0x06); db(0x65);
+ db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa); db(0x06); db(0x1b);
db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0xfc); db(0xd4);
db(0x2b); db(0x40); db(0x02); db(0x0c); db(0x67); db(0x00); db(0x02); db(0x00);
db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x00); db(0x61); db(0x00);
db(0x33); db(0x7c); db(0x00); db(0x32); db(0x00); db(0x46); db(0x30); db(0x3c);
db(0xff); db(0x38); db(0x72); db(0x02); db(0x61); db(0x00); db(0xf9); db(0xea);
db(0x4e); db(0x90); db(0x41); db(0xf9); db(0x00); db(0xdf); db(0xf0); db(0x00);
- db(0x70); db(0x00); db(0x4e); db(0x75); db(0x41); db(0xfa); db(0x04); db(0x63);
- db(0x43); db(0xfa); db(0x00); db(0x0a); db(0x70); db(0xf6); db(0x61); db(0x00);
- db(0xfa); db(0xac); db(0x4e); db(0x75); db(0x9b); db(0xcd); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88);
- db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0x7a);
- db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08);
+ db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x06);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x00); db(0x88); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00);
+ db(0x00); db(0x40); db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14);
db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0e); db(0x61); db(0x00);
- db(0xf9); db(0x98); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x78); db(0x00);
- db(0x7a); db(0x00); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x4e); db(0xae); db(0xff); db(0x7c);
- db(0x4a); db(0x84); db(0x66); db(0x10); db(0x41); db(0xee); db(0x01); db(0x7a);
- db(0x43); db(0xfa); db(0x04); db(0x61); db(0x4e); db(0xae); db(0xfe); db(0xec);
- db(0x28); db(0x00); db(0x60); db(0x02); db(0x7a); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x76); db(0x4a); db(0x85); db(0x67); db(0xd4); db(0x42); db(0xad);
- db(0x00); db(0x08); db(0x41); db(0xfa); db(0x03); db(0xe5); db(0x43); db(0xfa);
- db(0x01); db(0x10); db(0x70); db(0xf6); db(0x22); db(0x3c); db(0x00); db(0x00);
- db(0x27); db(0x10); db(0x61); db(0x00); db(0xee); db(0x92); db(0x70); db(0x00);
+ db(0xf9); db(0xb0); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x41); db(0xfa);
+ db(0x03); db(0xe7); db(0x43); db(0xfa); db(0x01); db(0x14); db(0x70); db(0xf6);
+ db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10); db(0x61); db(0x00);
+ db(0xee); db(0xe6); db(0x70); db(0x00); db(0x4c); db(0xdf); db(0x60); db(0x00);
db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0a);
- db(0x61); db(0x00); db(0xf9); db(0x3e); db(0x4e); db(0x90); db(0x4e); db(0x75);
+ db(0x61); db(0x00); db(0xf9); db(0x86); db(0x4e); db(0x90); db(0x4e); db(0x75);
db(0x61); db(0xf0); db(0x20); db(0x0d); db(0x67); db(0x1c); db(0x2c); db(0x6d);
db(0x00); db(0x14); db(0x20); db(0x2d); db(0x00); db(0x18); db(0x67); db(0x06);
db(0x22); db(0x40); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4d);
db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88); db(0x4e); db(0xae);
db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
db(0x38); db(0x3e); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x41); db(0xfa);
- db(0x03); db(0x77); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
+ db(0x03); db(0x75); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x28); db(0x00);
db(0x67); db(0x4c); db(0x45); db(0xed); db(0x00); db(0x68); db(0x42); db(0x92);
db(0x34); db(0xaa); db(0x00); db(0x02); db(0x24); db(0x0a); db(0x54); db(0x82);
db(0x76); db(0x20); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
db(0xb6); db(0x80); db(0x66); db(0x12); db(0x4a); db(0x6a); db(0x00); db(0x10);
db(0x66); db(0xc4); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x10);
- db(0x61); db(0x00); db(0xf8); db(0xae); db(0x4e); db(0x90); db(0x22); db(0x04);
+ db(0x61); db(0x00); db(0xf8); db(0xf6); db(0x4e); db(0x90); db(0x22); db(0x04);
db(0x67); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x4c); db(0xdf);
db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x6d); db(0x00); db(0x18);
- db(0x41); db(0xfa); db(0x02); db(0xef); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x41); db(0xfa); db(0x02); db(0xed); db(0x22); db(0x08); db(0x74); db(0xfe);
db(0x4e); db(0xae); db(0xff); db(0xac); db(0x22); db(0x00); db(0x67); db(0x34);
db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
db(0x45); db(0xed); db(0x00); db(0x38); db(0x70); db(0xff); db(0x4e); db(0xae);
db(0xfe); db(0xb6); db(0x15); db(0x40); db(0x00); db(0x14); db(0x41); db(0xfa);
- db(0x02); db(0xdf); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
+ db(0x02); db(0xdd); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
db(0x00); db(0x12); db(0x00); db(0x0c); db(0x25); db(0x6d); db(0x00); db(0x08);
db(0x00); db(0x10); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x22); db(0x0a);
db(0x4e); db(0xae); db(0xfc); db(0x88); db(0x2c); db(0x6d); db(0x00); db(0x14);
db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
db(0x00); db(0x00); db(0x00); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x3c); db(0x4e); db(0x90);
+ db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x84); db(0x4e); db(0x90);
db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xfc); db(0x2a); db(0x40);
db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x93); db(0xc9); db(0x4e); db(0xae);
db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08); db(0x43); db(0xfa);
- db(0x03); db(0x0b); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x2b); db(0x40); db(0x00); db(0x18); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0xfe); db(0xd8); db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x02); db(0x41); db(0x22); db(0x08);
- db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80);
- db(0x67); db(0xea); db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6);
- db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa);
- db(0x02); db(0x2b); db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae);
- db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa2);
- db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d);
- db(0x00); db(0x14); db(0x61); db(0x00); db(0xf7); db(0xe8); db(0x72); db(0x00);
- db(0x32); db(0x3c); db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x2c);
- db(0x28); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x82);
- db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae);
- db(0xfe); db(0xc2); db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c);
- db(0x41); db(0xfa); db(0x02); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae);
- db(0xfe); db(0x44); db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c);
- db(0x00); db(0x14); db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14);
- db(0x64); db(0x0c); db(0x61); db(0x00); db(0xfe); db(0x46); db(0x70); db(0x00);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0x7a);
- db(0x4e); db(0x90); db(0x61); db(0x00); db(0xfe); db(0xd8); db(0x41); db(0xed);
- db(0x00); db(0x1c); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01);
- db(0x29); db(0x40); db(0x00); db(0x24); db(0x39); db(0x7c); db(0x00); db(0x0c);
- db(0x00); db(0x1c); db(0x2b); db(0x4d); db(0x00); db(0x2c); db(0x41); db(0xfa);
- db(0x01); db(0x4a); db(0x2b); db(0x48); db(0x00); db(0x24); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x70); db(0x00); db(0x74); db(0x00);
- db(0x14); db(0x2d); db(0x00); db(0x4c); db(0x05); db(0xc0); db(0x08); db(0xc0);
- db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x05); db(0x00);
- db(0x67); db(0x06); db(0x61); db(0x00); db(0xfe); db(0x22); db(0x60); db(0xe4);
- db(0x20); db(0x2d); db(0x00); db(0x00); db(0x67); db(0x00); db(0x00); db(0x72);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2b); db(0x40);
- db(0x00); db(0x04); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0c);
- db(0x61); db(0x00); db(0xf7); db(0x16); db(0x4e); db(0x90); db(0x4a); db(0xad);
- db(0x00); db(0x04); db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03);
- db(0x00); db(0x1c); db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac);
- db(0x00); db(0x20); db(0x29); db(0x6d); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x29); db(0x6d); db(0x00); db(0x04); db(0x00); db(0x28); db(0x42); db(0xac);
- db(0x00); db(0x2c); db(0x42); db(0xac); db(0x00); db(0x30); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x2b); db(0x6c); db(0x00); db(0x30);
- db(0x00); db(0x10); db(0x39); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x1c);
- db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x20); db(0x2d);
- db(0x00); db(0x00); db(0x42); db(0xad); db(0x00); db(0x00); db(0x22); db(0x2d);
- db(0x00); db(0x04); db(0x67); db(0x00); db(0xff); db(0x78); db(0x22); db(0x41);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x6e);
- db(0x39); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x1c); db(0x41); db(0xed);
- db(0x00); db(0x30); db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04);
- db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x2c);
- db(0x42); db(0xac); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
- db(0x70); db(0x08); db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x0c); db(0xad); db(0x46); db(0x4f);
- db(0x52); db(0x4d); db(0x00); db(0x30); db(0x66); db(0x52); db(0x20); db(0x2d);
- db(0x00); db(0x34); db(0x67); db(0x4c); db(0x6b); db(0x4a); db(0x2b); db(0x6c);
- db(0x00); db(0x30); db(0x00); db(0x10); db(0x50); db(0x80); db(0x24); db(0x00);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
- db(0x67); db(0x36); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x20); db(0xed);
- db(0x00); db(0x30); db(0x20); db(0xed); db(0x00); db(0x34); db(0x29); db(0x48);
- db(0x00); db(0x28); db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40);
- db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00);
- db(0xf6); db(0x40); db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90);
- db(0x22); db(0x4a); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e);
- db(0x4a); db(0xac); db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xde);
- db(0x41); db(0xed); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
- db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x24); db(0x42); db(0xac);
- db(0x00); db(0x20); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x60); db(0xde); db(0x41); db(0xe8); db(0xff); db(0xe4); db(0x20); db(0x29);
- db(0x00); db(0x08); db(0xb0); db(0xa8); db(0x00); db(0x10); db(0x67); db(0x1a);
- db(0x21); db(0x40); db(0x00); db(0x10); db(0x2f); db(0x0e); db(0x2c); db(0x68);
- db(0x00); db(0x14); db(0x22); db(0x68); db(0x00); db(0x08); db(0x70); db(0x00);
- db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc);
- db(0x2c); db(0x5f); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x69); db(0x6e);
- db(0x70); db(0x75); db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69);
- db(0x63); db(0x65); db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72);
- db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00);
- db(0x44); db(0x45); db(0x56); db(0x53); db(0x00); db(0x44); db(0x45); db(0x56);
- db(0x53); db(0x3a); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a);
- db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72);
- db(0x64); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
- db(0x00); db(0x52); db(0x41); db(0x4d); db(0x3a); db(0x00); db(0x63); db(0x6c);
+ db(0x03); db(0x09); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x2b); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xfe); db(0xda);
+ db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a);
+ db(0x41); db(0xfa); db(0x02); db(0x41); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0xea);
+ db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x72); db(0x32);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x02); db(0x2b);
+ db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa4); db(0x22); db(0x00);
+ db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x61); db(0x00); db(0xf8); db(0x32); db(0x72); db(0x00); db(0x32); db(0x3c);
+ db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x76); db(0x28); db(0x40);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x84); db(0x70); db(0x00);
+ db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
+ db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c); db(0x41); db(0xfa);
+ db(0x02); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x44);
+ db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c); db(0x00); db(0x14);
+ db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14); db(0x64); db(0x0c);
+ db(0x61); db(0x00); db(0xfe); db(0x48); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0xc4); db(0x4e); db(0x90);
+ db(0x61); db(0x00); db(0xfe); db(0xda); db(0x41); db(0xed); db(0x00); db(0x1c);
+ db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01); db(0x29); db(0x40);
+ db(0x00); db(0x24); db(0x39); db(0x7c); db(0x00); db(0x0c); db(0x00); db(0x1c);
+ db(0x2b); db(0x4d); db(0x00); db(0x2c); db(0x41); db(0xfa); db(0x01); db(0x4a);
+ db(0x2b); db(0x48); db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x70); db(0x00); db(0x74); db(0x00); db(0x14); db(0x2d);
+ db(0x00); db(0x4c); db(0x05); db(0xc0); db(0x08); db(0xc0); db(0x00); db(0x0d);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x05); db(0x00); db(0x67); db(0x06);
+ db(0x61); db(0x00); db(0xfe); db(0x24); db(0x60); db(0xe4); db(0x20); db(0x2d);
+ db(0x00); db(0x00); db(0x67); db(0x00); db(0x00); db(0x72); db(0x72); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2b); db(0x40); db(0x00); db(0x04);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0c); db(0x61); db(0x00);
+ db(0xf7); db(0x60); db(0x4e); db(0x90); db(0x4a); db(0xad); db(0x00); db(0x04);
+ db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03); db(0x00); db(0x1c);
+ db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x20);
+ db(0x29); db(0x6d); db(0x00); db(0x00); db(0x00); db(0x24); db(0x29); db(0x6d);
+ db(0x00); db(0x04); db(0x00); db(0x28); db(0x42); db(0xac); db(0x00); db(0x2c);
+ db(0x42); db(0xac); db(0x00); db(0x30); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x2b); db(0x6c); db(0x00); db(0x30); db(0x00); db(0x10);
+ db(0x39); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x1c); db(0x22); db(0x4c);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x20); db(0x2d); db(0x00); db(0x00);
+ db(0x42); db(0xad); db(0x00); db(0x00); db(0x22); db(0x2d); db(0x00); db(0x04);
+ db(0x67); db(0x00); db(0xff); db(0x78); db(0x22); db(0x41); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x6e); db(0x39); db(0x7c);
+ db(0x00); db(0x02); db(0x00); db(0x1c); db(0x41); db(0xed); db(0x00); db(0x30);
+ db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x42); db(0x2c);
+ db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x2c); db(0x42); db(0xac);
+ db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x08);
+ db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x0c); db(0xad); db(0x46); db(0x4f); db(0x52); db(0x4d);
+ db(0x00); db(0x30); db(0x66); db(0x52); db(0x20); db(0x2d); db(0x00); db(0x34);
+ db(0x67); db(0x4c); db(0x6b); db(0x4a); db(0x2b); db(0x6c); db(0x00); db(0x30);
+ db(0x00); db(0x10); db(0x50); db(0x80); db(0x24); db(0x00); db(0x72); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x36);
+ db(0x24); db(0x40); db(0x20); db(0x4a); db(0x20); db(0xed); db(0x00); db(0x30);
+ db(0x20); db(0xed); db(0x00); db(0x34); db(0x29); db(0x48); db(0x00); db(0x28);
+ db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40); db(0x00); db(0x24);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00); db(0xf6); db(0x8a);
+ db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90); db(0x22); db(0x4a);
+ db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4a); db(0xac);
+ db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xde); db(0x41); db(0xed);
+ db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01);
+ db(0x29); db(0x40); db(0x00); db(0x24); db(0x42); db(0xac); db(0x00); db(0x20);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x60); db(0xde);
+ db(0x41); db(0xe8); db(0xff); db(0xe4); db(0x20); db(0x29); db(0x00); db(0x08);
+ db(0xb0); db(0xa8); db(0x00); db(0x10); db(0x67); db(0x1a); db(0x21); db(0x40);
+ db(0x00); db(0x10); db(0x2f); db(0x0e); db(0x2c); db(0x68); db(0x00); db(0x14);
+ db(0x22); db(0x68); db(0x00); db(0x08); db(0x70); db(0x00); db(0x08); db(0xc0);
+ db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x2c); db(0x5f);
+ db(0x70); db(0x00); db(0x4e); db(0x75); db(0x69); db(0x6e); db(0x70); db(0x75);
+ db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
+ db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72); db(0x2e); db(0x64);
+ db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x44); db(0x45);
+ db(0x56); db(0x53); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a);
+ db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a); db(0x63); db(0x6c);
db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x2e);
db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x52);
- db(0x41); db(0x4d); db(0x3a); db(0x45); db(0x6e); db(0x76); db(0x2f); db(0x53);
- db(0x79); db(0x73); db(0x2f); db(0x50); db(0x6f); db(0x69); db(0x6e); db(0x74);
- db(0x65); db(0x72); db(0x2e); db(0x70); db(0x72); db(0x65); db(0x66); db(0x73);
- db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x63); db(0x6c); db(0x69);
- db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x20); db(0x73);
- db(0x68); db(0x61); db(0x72); db(0x69); db(0x6e); db(0x67); db(0x00); db(0x55);
- db(0x41); db(0x45); db(0x20); db(0x6d); db(0x6f); db(0x75); db(0x73); db(0x65);
- db(0x20); db(0x64); db(0x72); db(0x69); db(0x76); db(0x65); db(0x72); db(0x00);
- db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x69); db(0x6c); db(0x65);
- db(0x73); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x55);
- db(0x41); db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75);
- db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x65);
- db(0x72); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73);
- db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75);
- db(0x6e); db(0x74); db(0x20); db(0x70); db(0x72); db(0x6f); db(0x63); db(0x65);
- db(0x73); db(0x73); db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e); db(0x6c);
- db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x69);
- db(0x6e); db(0x74); db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f); db(0x6e);
- db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79);
- db(0x00); db(0x67); db(0x72); db(0x61); db(0x70); db(0x68); db(0x69); db(0x63);
- db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
- db(0x79); db(0x00); db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); db(0x73);
- db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72);
- db(0x61); db(0x72); db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65);
- db(0x53); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e); db(0x72);
- db(0x65); db(0x73); db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65); db(0x00);
+ db(0x41); db(0x4d); db(0x3a); db(0x00); db(0x63); db(0x6c); db(0x69); db(0x70);
+ db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x2e); db(0x64); db(0x65);
+ db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x52); db(0x41); db(0x4d);
+ db(0x3a); db(0x45); db(0x6e); db(0x76); db(0x2f); db(0x53); db(0x79); db(0x73);
+ db(0x2f); db(0x50); db(0x6f); db(0x69); db(0x6e); db(0x74); db(0x65); db(0x72);
+ db(0x2e); db(0x70); db(0x72); db(0x65); db(0x66); db(0x73); db(0x00); db(0x55);
+ db(0x41); db(0x45); db(0x20); db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62);
+ db(0x6f); db(0x61); db(0x72); db(0x64); db(0x20); db(0x73); db(0x68); db(0x61);
+ db(0x72); db(0x69); db(0x6e); db(0x67); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x6d); db(0x6f); db(0x75); db(0x73); db(0x65); db(0x20); db(0x64);
+ db(0x72); db(0x69); db(0x76); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x66); db(0x69); db(0x6c); db(0x65); db(0x73); db(0x79);
+ db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f);
+ db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x65); db(0x72); db(0x00);
+ db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x61);
+ db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74);
+ db(0x20); db(0x70); db(0x72); db(0x6f); db(0x63); db(0x65); db(0x73); db(0x73);
+ db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62);
+ db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x69); db(0x6e); db(0x74);
+ db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c);
+ db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x67);
+ db(0x72); db(0x61); db(0x70); db(0x68); db(0x69); db(0x63); db(0x73); db(0x2e);
+ db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00);
+ db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); db(0x73); db(0x69); db(0x6f);
+ db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
+ db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65); db(0x53); db(0x79);
+ db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e); db(0x72); db(0x65); db(0x73);
+ db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65); db(0x00); db(0x00); db(0x00);
db(0x00); db(0x00); db(0x03); db(0xf2);
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);
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);
--- /dev/null
+
+int isamigatrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track);
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*);
struct zfile {
TCHAR *name;
TCHAR *zipname;
+ TCHAR *mode;
FILE *f;
uae_u8 *data;
uae_u64 size;
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;
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
#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);
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);
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 *);
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
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);
#include "autoconf.h"
#include "rp.h"
+extern int bootrom_header, bootrom_items;
+
// 01 = host events
// 02 = joystick
// 04 = cia buttons
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;
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;
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)
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;
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;
return;
if (!tablet_data)
return;
- off = 12 + get_long (rtarea_base + 36);
+ off = getmhoffset ();
p = rtarea + off;
p[MH_CNT]++;
}
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);
if (!uae_boot_rom)
return;
- p = rtarea + 12 + get_long (rtarea_base + 36);
+ p = rtarea + getmhoffset ();
tablet_maxx = maxx;
tablet_maxy = maxy;
uae_u32 off;
mousehack_enable ();
- off = 12 + get_long (rtarea_base + 36);
+ off = getmhoffset ();
p = rtarea + off;
memcpy (tmp, p + MH_ABSX, 4);
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);
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);
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);
#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);
}
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);
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);
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);
_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);
}
}
}
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;
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];
}
--- /dev/null
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "options.h"
+#include "memory.h"
+
+#include "fsdb.h"
+#include "win32.h"
+#include <windows.h>
+
+int my_setcurrentdir (const TCHAR *curdir, TCHAR *oldcur)
+{
+ int ret = 0;
+ if (oldcur)
+ ret = GetCurrentDirectory (MAX_DPATH, oldcur);
+ if (curdir)
+ ret = SetCurrentDirectory (curdir);
+ return ret;
+}
+
+int my_mkdir (const TCHAR *name)
+{
+ return CreateDirectory (name, NULL) == 0 ? -1 : 0;
+}
+
+static int recycle (const TCHAR *name)
+{
+ if (currprefs.win32_norecyclebin) {
+ DWORD dirattr = GetFileAttributes (name);
+ if (dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY))
+ return RemoveDirectory (name) ? 0 : -1;
+ return DeleteFile(name) ? 0 : -1;
+ } else {
+ SHFILEOPSTRUCT fos;
+ /* name must be terminated by \0\0 */
+ TCHAR *p = xcalloc ((_tcslen (name) + 2) * sizeof (TCHAR), 1);
+ int v;
+
+ _tcscpy (p, name);
+ memset (&fos, 0, sizeof (fos));
+ fos.wFunc = FO_DELETE;
+ fos.pFrom = p;
+ fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NORECURSION | FOF_SILENT;
+ v = SHFileOperation (&fos);
+ xfree (p);
+ switch (v)
+ {
+ case 0xb7: //DE_ERROR_MAX
+ case 0x7c: //DE_INVALIDFILES
+ case 0x402: // "unknown error"
+ v = ERROR_FILE_NOT_FOUND;
+ break;
+ case 0x75: //DE_OPCANCELLED:
+ case 0x10000: //ERRORONDEST:
+ case 0x78: //DE_ACCESSDENIEDSRC:
+ case 0x74: //DE_ROOTDIR:
+ v = ERROR_ACCESS_DENIED;
+ break;
+ }
+ SetLastError (v);
+ return v ? -1 : 0;
+ }
+}
+
+int my_rmdir (const TCHAR *name)
+{
+ void *od;
+ int cnt;
+ TCHAR tname[MAX_DPATH];
+
+ /* SHFileOperation() ignores FOF_NORECURSION when deleting directories.. */
+ od = my_opendir (name);
+ if (!od) {
+ SetLastError (ERROR_FILE_NOT_FOUND);
+ return -1;
+ }
+ cnt = 0;
+ while (my_readdir (od, tname)) {
+ if (!_tcscmp (tname, L".") || !_tcscmp (tname, L".."))
+ continue;
+ cnt++;
+ break;
+ }
+ my_closedir (od);
+ if (cnt > 0) {
+ SetLastError (ERROR_CURRENT_DIRECTORY);
+ return -1;
+ }
+
+ return recycle (name);
+}
+
+/* "move to Recycle Bin" (if enabled) -version of DeleteFile() */
+int my_unlink (const TCHAR *name)
+{
+ return recycle (name);
+}
+
+int my_rename (const TCHAR *oldname, const TCHAR *newname)
+{
+ return MoveFile (oldname, newname) == 0 ? -1 : 0;
+}
+
+struct my_opendirs {
+ HANDLE *h;
+ WIN32_FIND_DATA fd;
+ int first;
+};
+
+void *my_opendir (const TCHAR *name)
+{
+ struct my_opendirs *mod;
+ TCHAR tmp[MAX_DPATH];
+
+ _tcscpy (tmp, name);
+ _tcscat (tmp, L"\\*.*");
+ mod = xmalloc (sizeof (struct my_opendirs));
+ if (!mod)
+ return NULL;
+ mod->h = FindFirstFile(tmp, &mod->fd);
+ if (mod->h == INVALID_HANDLE_VALUE) {
+ xfree (mod);
+ return NULL;
+ }
+ mod->first = 1;
+ return mod;
+}
+
+void my_closedir (void *d)
+{
+ struct my_opendirs *mod = d;
+ if (d)
+ FindClose (mod->h);
+ xfree (mod);
+}
+
+int my_readdir (void *d, TCHAR *name)
+{
+ struct my_opendirs *mod = d;
+ if (mod->first) {
+ _tcscpy (name, mod->fd.cFileName);
+ mod->first = 0;
+ return 1;
+ }
+ if (!FindNextFile (mod->h, &mod->fd))
+ return 0;
+ _tcscpy (name, mod->fd.cFileName);
+ return 1;
+}
+
+struct my_opens {
+ HANDLE *h;
+};
+
+void my_close (void *d)
+{
+ struct my_opens *mos = d;
+ CloseHandle (mos->h);
+ xfree (mos);
+}
+
+uae_s64 int my_lseek (void *d, uae_s64 int offset, int whence)
+{
+ struct my_opens *mos = d;
+ LARGE_INTEGER li;
+
+ li.QuadPart = offset;
+ li.LowPart = SetFilePointer (mos->h, li.LowPart, &li.HighPart,
+ whence == SEEK_SET ? FILE_BEGIN : (whence == SEEK_END ? FILE_END : FILE_CURRENT));
+ if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
+ li.QuadPart = -1;
+ return li.QuadPart;
+}
+
+unsigned int my_read (void *d, void *b, unsigned int size)
+{
+ struct my_opens *mos = d;
+ DWORD read = 0;
+ ReadFile (mos->h, b, size, &read, NULL);
+ return read;
+}
+
+unsigned int my_write (void *d, void *b, unsigned int size)
+{
+ struct my_opens *mos = d;
+ DWORD written = 0;
+ WriteFile (mos->h, b, size, &written, NULL);
+ return written;
+}
+
+static DWORD GetFileAttributesSafe(const TCHAR *name)
+{
+ DWORD attr, last;
+
+ last = SetErrorMode (SEM_FAILCRITICALERRORS);
+ attr = GetFileAttributes (name);
+ SetErrorMode (last);
+ return attr;
+}
+
+int my_existsfile (const TCHAR *name)
+{
+ DWORD attr = GetFileAttributesSafe (name);
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return 0;
+ if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
+ return 1;
+ return 0;
+}
+
+int my_existsdir (const TCHAR *name)
+{
+ DWORD attr = GetFileAttributesSafe (name);
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return 0;
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ return 1;
+ return 0;
+}
+
+void *my_open (const TCHAR *name, int flags)
+{
+ struct my_opens *mos;
+ HANDLE h;
+ DWORD DesiredAccess = GENERIC_READ;
+ DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ DWORD CreationDisposition = OPEN_EXISTING;
+ DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+ DWORD attr;
+
+ mos = xmalloc (sizeof (struct my_opens));
+ if (!mos)
+ return NULL;
+ attr = GetFileAttributesSafe (name);
+ if (flags & O_TRUNC)
+ CreationDisposition = CREATE_ALWAYS;
+ else if (flags & O_CREAT)
+ CreationDisposition = OPEN_ALWAYS;
+ if (flags & O_WRONLY)
+ DesiredAccess = GENERIC_WRITE;
+ if (flags & O_RDONLY) {
+ DesiredAccess = GENERIC_READ;
+ CreationDisposition = OPEN_EXISTING;
+ }
+ if (flags & O_RDWR)
+ DesiredAccess = GENERIC_READ | GENERIC_WRITE;
+ if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES &&
+ (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
+ SetFileAttributes (name, FILE_ATTRIBUTE_NORMAL);
+ h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ DWORD err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) {
+ DesiredAccess &= ~GENERIC_WRITE;
+ h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ err = GetLastError();
+ }
+ if (h == INVALID_HANDLE_VALUE) {
+ write_log (L"failed to open '%s' %x %x err=%d\n", name, DesiredAccess, CreationDisposition, err);
+ xfree (mos);
+ mos = NULL;
+ goto err;
+ }
+ }
+ mos->h = h;
+err:
+ //write_log (L"open '%s' = %x\n", name, mos ? mos->h : 0);
+ return mos;
+}
+
+int my_truncate (const TCHAR *name, uae_u64 len)
+{
+ HANDLE hFile;
+ BOOL bResult = FALSE;
+ int result = -1;
+
+ if ((hFile = CreateFile (name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
+ {
+ LARGE_INTEGER li;
+ li.QuadPart = len;
+ li.LowPart = SetFilePointer (hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) {
+ write_log (L"truncate: SetFilePointer() failure for %s to posn %d\n", name, len);
+ } else {
+ if (SetEndOfFile (hFile) == TRUE)
+ result = 0;
+ }
+ CloseHandle (hFile);
+ } else {
+ write_log (L"truncate: CreateFile() failed to open %s\n", name);
+ }
+ return result;
+}
+
+int dos_errno (void)
+{
+ DWORD e = GetLastError ();
+
+ //write_log (L"ec=%d\n", e);
+ switch (e) {
+ case ERROR_NOT_ENOUGH_MEMORY:
+ case ERROR_OUTOFMEMORY:
+ return ERROR_NO_FREE_STORE;
+
+ case ERROR_FILE_EXISTS:
+ case ERROR_ALREADY_EXISTS:
+ return ERROR_OBJECT_EXISTS;
+
+ case ERROR_WRITE_PROTECT:
+ case ERROR_ACCESS_DENIED:
+ return ERROR_WRITE_PROTECTED;
+
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_INVALID_DRIVE:
+ case ERROR_INVALID_NAME:
+ case ERROR_PATH_NOT_FOUND:
+ return ERROR_OBJECT_NOT_AROUND;
+
+ case ERROR_HANDLE_DISK_FULL:
+ case ERROR_DISK_FULL:
+ return ERROR_DISK_IS_FULL;
+
+ case ERROR_SHARING_VIOLATION:
+ case ERROR_BUSY:
+ case ERROR_INVALID_HANDLE:
+ return ERROR_OBJECT_IN_USE;
+
+ case ERROR_CURRENT_DIRECTORY:
+ return ERROR_DIRECTORY_NOT_EMPTY;
+
+ case ERROR_NEGATIVE_SEEK:
+ case ERROR_SEEK_ON_DEVICE:
+ return ERROR_SEEK_ERROR;
+
+ default:
+ {
+ gui_message (L"Unimplemented error %d\nContact author!", e);
+ }
+ return ERROR_NOT_IMPLEMENTED;
+ }
+}
+
+typedef BOOL (CALLBACK* GETVOLUMEPATHNAME)
+ (LPCTSTR lpszFileName, LPTSTR lpszVolumePathName, DWORD cchBufferLength);
+
+int my_getvolumeinfo (const TCHAR *root)
+{
+ DWORD v, err;
+ int ret = 0;
+ GETVOLUMEPATHNAME pGetVolumePathName;
+ TCHAR volume[MAX_DPATH];
+
+ v = GetFileAttributesSafe (root);
+ err = GetLastError ();
+ if (v == INVALID_FILE_ATTRIBUTES)
+ return -1;
+ if (!(v & FILE_ATTRIBUTE_DIRECTORY))
+ return -1;
+/*
+ if (v & FILE_ATTRIBUTE_READONLY)
+ ret |= MYVOLUMEINFO_READONLY;
+*/
+ pGetVolumePathName = (GETVOLUMEPATHNAME)GetProcAddress(
+ GetModuleHandle (L"kernel32.dll"), "GetVolumePathNameW");
+ if (pGetVolumePathName && pGetVolumePathName (root, volume, sizeof (volume))) {
+ TCHAR fsname[MAX_DPATH];
+ DWORD comlen;
+ DWORD flags;
+ if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof (fsname))) {
+ write_log (L"Volume %s FS=%s maxlen=%d flags=%08X\n", volume, fsname, comlen, flags);
+ if (flags & FILE_NAMED_STREAMS)
+ ret |= MYVOLUMEINFO_STREAMS;
+ }
+ }
+ return ret;
+}
+
+FILE *my_opentext (const TCHAR *name)
+{
+ FILE *f;
+ uae_u8 tmp[4];
+ int v;
+
+ f = _tfopen (name, L"rb");
+ if (!f)
+ return NULL;
+ v = fread (tmp, 1, 4, f);
+ fclose (f);
+ if (v == 4) {
+ if (tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf)
+ return _tfopen (name, L"r, ccs=UTF-8");
+ if (tmp[0] == 0xff && tmp[1] == 0xfe)
+ return _tfopen (name, L"r, ccs=UTF-16LE");
+ }
+ return _tfopen (name, L"r");
+}
+
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");
-}
-
-
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);
} 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*));
void *arg = thp->arg;
xfree (f);
+
+#ifndef _CONSOLE
__try {
fp (arg);
+#endif
+#ifndef _CONSOLE
} __except (WIN32_ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
}
+#endif
return 0;
}
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="uaeunp"
+ ProjectGUID="{6181E50C-5F32-42DC-BEF6-827AA8A5429D}"
+ RootNamespace="uaeunp"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="d:\amiga"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include,..\..,..\,..\resources,..\osdep,..\sounddep,..\..\prowizard\include,..\tun"
+ PreprocessorDefinitions="WINVER=0x0500,_DEBUG,WIN32_IE=0x0700;WIN32;CINTERFACE;COBJMACROS;_CRT_SECURE_NO_WARNINGS;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="zlibstat.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="d:\amiga"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\..\include,..\..,..\,..\resources,..\osdep,..\sounddep,..\..\prowizard\include,..\tun"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;,WIN32_IE=0x0700;WIN32;CINTERFACE;COBJMACROS;_CRT_SECURE_NO_WARNINGS;"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="zlibstat.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\diskutil.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\fdi2raw.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\missing.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\uaeunp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\zfile.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\zfile_archive.c"
+ >
+ </File>
+ <Filter
+ Name="decompressors"
+ >
+ <Filter
+ Name="dms"
+ >
+ <File
+ RelativePath="..\..\archivers\dms\crc_csum.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\getbits.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\maketbl.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\pfile.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\tables.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_deep.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_heavy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_init.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_medium.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_quick.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\dms\u_rle.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="7z"
+ >
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zAlloc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\7zBuf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\7zCrc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zDecode.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zExtract.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zHeader.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zIn.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zItem.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\7zStream.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Bcj2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Bra.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Bra86.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\LzmaDec.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="lha"
+ >
+ <File
+ RelativePath="..\..\archivers\lha\crcio.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\dhuf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\header.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\huf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\larc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\lhamaketbl.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\lharc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\shuf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\slide.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\uae_lha.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\lha\util.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="zip"
+ >
+ <File
+ RelativePath="..\..\archivers\zip\unzip.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="lzx"
+ >
+ <File
+ RelativePath="..\..\archivers\lzx\unlzx.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="xfd"
+ >
+ </Filter>
+ <Filter
+ Name="wrp"
+ >
+ <File
+ RelativePath="..\..\archivers\wrp\warp.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="win32"
+ >
+ <File
+ RelativePath="..\caps\caps_win32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fsdb_mywin32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\posixemu.c"
+ >
+ </File>
+ <File
+ RelativePath="..\uaeunp_win32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\unicode.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+#include <stdio.h>
+#include <tchar.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "win32.h"
+
+static void LLError(const TCHAR *s)
+{
+ DWORD err = GetLastError ();
+
+ if (err == ERROR_MOD_NOT_FOUND || err == ERROR_DLL_NOT_FOUND)
+ return;
+ write_log (L"%s failed to open %d\n", s, err);
+}
+
+void notify_user (int n)
+{
+}
+
+HMODULE WIN32_LoadLibrary (const TCHAR *name)
+{
+ HMODULE m = NULL;
+ TCHAR *newname;
+ DWORD err = -1;
+#ifdef CPU_64_BIT
+ TCHAR *p;
+#endif
+ int round;
+
+ newname = xmalloc ((_tcslen (name) + 1 + 10) * sizeof (TCHAR));
+ if (!newname)
+ return NULL;
+ for (round = 0; round < 4; round++) {
+ TCHAR *s;
+ _tcscpy (newname, name);
+#ifdef CPU_64_BIT
+ switch(round)
+ {
+ case 0:
+ p = strstr (newname,"32");
+ if (p) {
+ p[0] = '6';
+ p[1] = '4';
+ }
+ break;
+ case 1:
+ p = strchr (newname,'.');
+ _tcscpy(p,"_64");
+ _tcscat(p, strchr (name,'.'));
+ break;
+ case 2:
+ p = strchr (newname,'.');
+ _tcscpy (p,"64");
+ _tcscat (p, strchr (name,'.'));
+ break;
+ }
+#endif
+ s = xmalloc ((_tcslen (start_path_exe) + _tcslen (WIN32_PLUGINDIR) + _tcslen (newname) + 1) * sizeof (TCHAR));
+ if (s) {
+ _stprintf (s, L"%s%s%s", start_path_exe, WIN32_PLUGINDIR, newname);
+ m = LoadLibrary (s);
+ if (m)
+ goto end;
+ _stprintf (s, L"%s%s", start_path_exe, newname);
+ m = LoadLibrary (s);
+ if (m)
+ goto end;
+ _stprintf (s, L"%s%s%s", start_path_exe, WIN32_PLUGINDIR, newname);
+ LLError(s);
+ xfree (s);
+ }
+ m = LoadLibrary (newname);
+ if (m)
+ goto end;
+ LLError (newname);
+#ifndef CPU_64_BIT
+ break;
+#endif
+ }
+end:
+ xfree (newname);
+ return m;
+}
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 ());
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)) {
}
}
+#define MAX_ARGUMENTS 128
+
static int parseargs (const TCHAR *arg, const TCHAR *np, const TCHAR *np2)
{
if (!_tcscmp (arg, L"-convert") && np && np2) {
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;
p++;
if (*p == 0)
break;
- if (cnt >= 32)
+ if (cnt >= MAX_ARGUMENTS)
break;
s = p;
}
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);
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)
#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""
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;
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);
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);
#include "crc32.h"
#include "rp.h"
#include "statusline.h"
+#include "zarchive.h"
#define ARCHIVE_STRING L"*.zip;*.7z;*.rar;*.lha;*.lzh;*.lzx"
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);
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) {
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");
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;
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) {
i++;
}
SendDlgItemMessage (hDlg, v, CB_SETCURSEL, pri, 0);
+
+
}
extern TCHAR *get_aspi_path(int);
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;
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");
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");
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;
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;
cnt = DragQueryFile (hd, 0xffffffff, NULL, 0);
if (!cnt)
return 0;
- drv = 0;
+ drv = harddrive = 0;
drvdrag = 0;
if (currentpage < 0) {
GetClientRect (hMainWnd, &r2);
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++) {
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;
} 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) {
RelativePath="..\dxwrap.c"
>
</File>
+ <File
+ RelativePath="..\fsdb_mywin32.c"
+ >
+ </File>
<File
RelativePath="..\fsdb_win32.c"
>
RelativePath="..\..\disk.c"
>
</File>
+ <File
+ RelativePath="..\..\diskutil.c"
+ >
+ </File>
<File
RelativePath="..\..\drawing.c"
>
Name="7z"
>
<File
- RelativePath="..\..\archivers\7z\7zAlloc.c"
+ RelativePath="..\..\archivers\7z\Archive\7z\7zAlloc.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zBuffer.c"
+ RelativePath="..\..\archivers\7z\7zBuf.c"
>
</File>
<File
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zDecode.c"
+ RelativePath="..\..\archivers\7z\Archive\7z\7zDecode.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zExtract.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\archivers\7z\Archive\7z\7zHeader.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zExtract.c"
+ RelativePath="..\..\archivers\7z\Archive\7z\7zIn.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zHeader.c"
+ RelativePath="..\..\archivers\7z\Archive\7z\7zItem.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zIn.c"
+ RelativePath="..\..\archivers\7z\7zStream.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zItem.c"
+ RelativePath="..\..\archivers\7z\Bcj2.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zMain.c"
+ RelativePath="..\..\archivers\7z\Bra.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\7zMethodID.c"
+ RelativePath="..\..\archivers\7z\Bra86.c"
>
</File>
<File
- RelativePath="..\..\archivers\7z\LzmaDecode.c"
+ RelativePath="..\..\archivers\7z\LzmaDec.c"
>
</File>
</Filter>
+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)
}
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')
}
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')
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);
}
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) {
--- /dev/null
+#include <stdio.h>
+#include <tchar.h>
+
+#include <windows.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "options.h"
+#include "zfile.h"
+#include "fsdb.h"
+#include "zarchive.h"
+
+TCHAR start_path_exe[MAX_DPATH];
+TCHAR start_path_data[MAX_DPATH];
+TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+
+struct uae_prefs currprefs;
+static int debug = 0;
+
+#define WRITE_LOG_BUF_SIZE 4096
+void write_log (const TCHAR *format, ...)
+{
+ int count;
+ TCHAR buffer[WRITE_LOG_BUF_SIZE];
+ va_list parms;
+ va_start (parms, format);
+ if (debug) {
+ count = _vsntprintf (buffer, WRITE_LOG_BUF_SIZE - 1, format, parms);
+ _tprintf (buffer);
+ }
+ va_end (parms);
+}
+
+void gui_message (const TCHAR *format, ...)
+{
+}
+
+int uaerand (void)
+{
+ return rand ();
+}
+
+static int pattern_match (const TCHAR *str, const TCHAR *pattern)
+{
+ enum State {
+ Exact, // exact match
+ Any, // ?
+ AnyRepeat // *
+ };
+
+ const TCHAR *s = str;
+ const TCHAR *p = pattern;
+ const TCHAR *q = 0;
+ int state = 0;
+
+ int match = TRUE;
+ while (match && *p) {
+ if (*p == '*') {
+ state = AnyRepeat;
+ q = p+1;
+ } else if (*p == '?') state = Any;
+ else state = Exact;
+
+ if (*s == 0) break;
+
+ switch (state) {
+ case Exact:
+ match = *s == *p;
+ s++;
+ p++;
+ break;
+
+ case Any:
+ match = TRUE;
+ s++;
+ p++;
+ break;
+
+ case AnyRepeat:
+ match = TRUE;
+ s++;
+
+ if (*s == *q){
+ // make a recursive call so we don't match on just a single character
+ if (pattern_match(s,q) == TRUE) {
+ p++;
+ }
+ }
+ break;
+ }
+ }
+
+ if (state == AnyRepeat) return (*s == *q);
+ else if (state == Any) return (*s == *p);
+ else return match && (*s == *p);
+}
+
+
+
+
+static void geterror (void)
+{
+ TCHAR *err = zfile_geterror();
+ if (!err)
+ return;
+ _tprintf (L"%s\n", err);
+}
+
+static const TCHAR *prots = L"HSPARWED";
+
+struct arcdir {
+ TCHAR *name;
+ int isdir;
+ uae_u32 flags;
+ uae_u64 size;
+ TCHAR *comment;
+ uae_u32 crc32;
+ __time64_t dt;
+ int parent, nextlevel;
+};
+
+static struct arcdir **filelist;
+
+static void dolist (struct arcdir **filelist, struct arcdir *adp, int entries, int parent, int level)
+{
+ int ii, i;
+
+ for (ii = 0; ii < 2; ii++) {
+ for (i = 0; i < entries; i++) {
+ struct arcdir *ad = filelist[i];
+ int j;
+ TCHAR protflags[9];
+ TCHAR dates[32];
+ int flags;
+ struct tm *dt;
+
+ if (ad->parent != parent)
+ continue;
+
+ if ((ii == 0 && ad->isdir) || (ii == 1 && !ad->isdir)) {
+
+ flags = ad->flags;
+
+ if (flags >= 0) {
+ for (j = 0; j < 8; j++) {
+ protflags[j] = '-';
+ if (flags & (1 << (7 - j)))
+ protflags[j] = prots[j];
+ }
+ protflags[j] = 0;
+ } else {
+ _tcscpy (protflags, L"--------");
+ }
+
+ if (ad->dt > 0) {
+ dt = _gmtime64 (&ad->dt);
+ _tcsftime (dates, sizeof (dates) / sizeof (TCHAR), L"%Y/%m/%d %H:%M:%S", dt);
+ } else {
+ _tcscpy (dates, L"-------------------");
+ }
+
+ for (j = 0; j < level; j++)
+ _tprintf (L" ");
+ if (ad->isdir > 0)
+ _tprintf (L" [DIR] %s %s %s\n", protflags, dates, ad->name);
+ else if (ad->isdir < 0)
+ _tprintf (L" [VDIR] %s %s %s\n", protflags, dates, ad->name);
+ else
+ _tprintf (L"%10I64d %s %s %08X %s\n", ad->size, protflags, dates, ad->crc32, ad->name);
+ if (ad->comment)
+ _tprintf (L" \"%s\"\n", ad->comment);
+ if (ad->nextlevel >= 0) {
+ level++;
+ dolist (filelist, adp, entries, ad - adp, level);
+ level--;
+ }
+
+ }
+ }
+ }
+}
+
+static int parentid = -1, subdirid;
+static int maxentries = 10000, entries;
+
+static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
+{
+ struct zvolume *zv;
+ void *h;
+ int i;
+ TCHAR p[MAX_DPATH];
+ TCHAR fn[MAX_DPATH];
+ struct arcdir *ad;
+
+ zv = zfile_fopen_archive_root (src);
+ if (zv == NULL) {
+ geterror();
+ _tprintf (L"Couldn't open archive '%s'\n", src);
+ return 0;
+ }
+ h = zfile_opendir_archive (src);
+ if (!h) {
+ _tcscpy (p, src);
+ _tcscat (p, L".DIR");
+ h = zfile_opendir_archive (src);
+ if (!h) {
+ geterror();
+ _tprintf (L"Couldn't open directory '%s'\n", src);
+ return 0;
+ }
+ }
+
+ while (zfile_readdir_archive (h, fn)) {
+ struct _stat64 st;
+ int isdir;
+ uae_u32 flags;
+ TCHAR *comment;
+ struct zfile *zf;
+ uae_u32 crc32 = 0;
+ int nextdir = -1;
+
+ _tcscpy (p, src);
+ _tcscat (p, sep);
+ _tcscat (p, fn);
+ if (!zfile_stat_archive (p, &st)) {
+ st.st_size = -1;
+ st.st_mtime = 0;
+ }
+ isdir = 0;
+ flags = 0;
+ comment = 0;
+ zfile_fill_file_attrs_archive (p, &isdir, &flags, &comment);
+ flags ^= 15;
+ if (!isdir) {
+ zf = zfile_open_archive (p, 0);
+ if (zf) {
+ crc32 = zfile_crc32 (zf);
+ }
+ }
+
+ ad = &adp[entries++];
+ ad->isdir = isdir;
+ ad->comment = comment;
+ ad->flags = flags;
+ ad->name = my_strdup (fn);
+ ad->size = st.st_size;
+ ad->dt = st.st_mtime;
+ ad->parent = parentid;
+ ad->crc32 = crc32;
+
+ if (isdir && all) {
+ int oldparent = parentid;
+ parentid = ad - adp;
+ nextdir = parentid + 1;
+ unlist2 (adp, p, all);
+ parentid = oldparent;
+ }
+
+ ad->nextlevel = nextdir;
+
+ if (entries >= maxentries)
+ break;
+ }
+ if (parentid >= 0)
+ return 1;
+
+ filelist = xmalloc (entries * sizeof (struct arcdir*));
+ for (i = 0; i < entries; i++) {
+ filelist[i] = &adp[i];
+ }
+
+ // bubblesort is the winner!
+ for (i = 0; i < entries; i++) {
+ int j;
+ for (j = i + 1; j < entries; j++) {
+ int diff = _tcsicmp (filelist[i]->name, filelist[j]->name);
+ if (diff > 0) {
+ struct arcdir *tmp;
+ tmp = filelist[i];
+ filelist[i] = filelist[j];
+ filelist[j] = tmp;
+ }
+ }
+ }
+
+ dolist (filelist, adp, entries, -1, 0);
+ zfile_closedir_archive (h);
+ return 1;
+}
+
+static int unlist (const TCHAR *src, int all)
+{
+ struct arcdir *adp;
+ adp = xcalloc (sizeof (struct arcdir), maxentries);
+ unlist2 (adp, src, all);
+ return 1;
+}
+
+static void setdate (const TCHAR *src, __time64_t tm)
+{
+ struct utimbuf ut;
+ if (tm) {
+ ut.actime = ut.modtime = tm;
+ utime (src, &ut);
+ }
+}
+
+static int found;
+
+static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, int out, int all, int level)
+{
+ void *h;
+ struct zvolume *zv;
+ int ret;
+ uae_u8 *b;
+ int size;
+ TCHAR fn[MAX_DPATH];
+
+ ret = 0;
+ zv = zfile_fopen_archive_root (src);
+ if (zv == NULL) {
+ geterror();
+ _tprintf (L"Couldn't open archive '%s'\n", src);
+ return 0;
+ }
+ h = zfile_opendir_archive (src);
+ if (!h) {
+ geterror();
+ _tprintf (L"Couldn't open directory '%s'\n", src);
+ return 0;
+ }
+ while (zfile_readdir_archive (h, fn)) {
+ if (all || !_tcsicmp (filename, fn)) {
+ TCHAR tmp[MAX_DPATH];
+ struct zfile *s, *d;
+ struct _stat64 st;
+
+ found = 1;
+ _tcscpy (tmp, src);
+ _tcscat (tmp, sep);
+ _tcscat (tmp, fn);
+ if (!zfile_stat_archive (tmp, &st)) {
+ _tprintf (L"Couldn't stat '%s'\n", tmp);
+ continue;
+ }
+ if (dst == NULL || all)
+ dst = fn;
+ if (st.st_mode) {
+ if (all > 0)
+ continue;
+ if (all < 0) {
+ TCHAR oldcur[MAX_DPATH];
+ my_mkdir (fn);
+ my_setcurrentdir (fn, oldcur);
+ unpack (tmp, fn, dst, out, all, 1);
+ my_setcurrentdir (oldcur, NULL);
+ setdate (dst, st.st_mtime);
+ continue;
+ }
+ _tprintf (L"Directory extraction not yet supported\n");
+ return 0;
+ }
+
+ s = zfile_open_archive (tmp, 0);
+ if (!s) {
+ geterror();
+ _tprintf (L"Couldn't open '%s' for reading\n", src);
+ continue;
+ }
+ zfile_fseek (s, 0, SEEK_END);
+ size = zfile_ftell (s);
+ zfile_fseek (s, 0, SEEK_SET);
+ b = xcalloc (size, 1);
+ if (b) {
+ if (zfile_fread (b, size, 1, s) == 1) {
+ if (out) {
+ _tprintf (L"\n");
+ fwrite (b, size, 1, stdout);
+ } else {
+ d = zfile_fopen (dst, L"wb", 0);
+ if (d) {
+ if (zfile_fwrite (b, size, 1, d) == 1) {
+ ret = 1;
+ _tprintf (L"%s extracted, %d bytes\n", dst, size);
+ }
+ zfile_fclose (d);
+ setdate (dst, st.st_mtime);
+ }
+ }
+ }
+ xfree (b);
+ }
+ zfile_fclose (s);
+ if (!all)
+ break;
+ }
+ }
+ if (!found && !level) {
+ _tprintf (L"'%s' not found\n", fn);
+ }
+ return ret;
+}
+
+static int unpack2 (const TCHAR *src, const TCHAR *match, int level)
+{
+ void *h;
+ struct zvolume *zv;
+ int ret;
+ uae_u8 *b;
+ int size;
+ TCHAR fn[MAX_DPATH];
+
+ ret = 0;
+ zv = zfile_fopen_archive_root (src);
+ if (zv == NULL) {
+ geterror();
+ _tprintf (L"Couldn't open archive '%s'\n", src);
+ return 0;
+ }
+ h = zfile_opendir_archive (src);
+ if (!h) {
+ geterror();
+ _tprintf (L"Couldn't open directory '%s'\n", src);
+ return 0;
+ }
+ while (zfile_readdir_archive (h, fn)) {
+ TCHAR tmp[MAX_DPATH];
+ TCHAR *dst;
+ struct zfile *s, *d;
+ int isdir, flags;
+
+ _tcscpy (tmp, src);
+ _tcscat (tmp, sep);
+ _tcscat (tmp, fn);
+ zfile_fill_file_attrs_archive (tmp, &isdir, &flags, NULL);
+ if (isdir) {
+ TCHAR *p = _tcsstr (fn, L".DIR");
+ if (isdir == ZNODE_VDIR && p && _tcslen (p) == 4) {
+ p[0] = 0;
+ if (pattern_match (fn, match))
+ continue;
+ p[0] = '.';
+ }
+ unpack2 (tmp, match, 1);
+ continue;
+ }
+
+ if (pattern_match (fn, match)) {
+ struct _stat64 st;
+
+ if (!zfile_stat_archive (tmp, &st)) {
+ st.st_mtime = -1;
+ }
+ found = 1;
+ dst = fn;
+ s = zfile_open_archive (tmp, 0);
+ if (!s) {
+ geterror();
+ _tprintf (L"Couldn't open '%s' for reading\n", src);
+ continue;
+ }
+ zfile_fseek (s, 0, SEEK_END);
+ size = zfile_ftell (s);
+ zfile_fseek (s, 0, SEEK_SET);
+ b = xcalloc (size, 1);
+ if (b) {
+ if (zfile_fread (b, size, 1, s) == 1) {
+ d = zfile_fopen (dst, L"wb", 0);
+ if (d) {
+ if (zfile_fwrite (b, size, 1, d) == 1) {
+ ret = 1;
+ _tprintf (L"%s extracted, %d bytes\n", dst, size);
+ }
+ zfile_fclose (d);
+ setdate (dst, st.st_mtime);
+ }
+ }
+ xfree (b);
+ }
+ zfile_fclose (s);
+ }
+ }
+ if (!found && !level) {
+ _tprintf (L"'%s' not matched\n", match);
+ }
+ return ret;
+}
+
+static int scanpath (TCHAR *src, TCHAR *outpath)
+{
+ struct zvolume *zv;
+ void *h;
+ TCHAR fn[MAX_DPATH];
+
+ zv = zfile_fopen_archive_root (src);
+ if (zv == NULL) {
+ geterror();
+ _tprintf (L"Couldn't open archive '%s'\n", src);
+ return 0;
+ }
+ h = zfile_opendir_archive (src);
+ if (!h) {
+ geterror();
+ _tprintf (L"Couldn't open directory '%s'\n", src);
+ return 0;
+ }
+ while (zfile_readdir_archive (h, fn)) {
+ TCHAR tmp[MAX_DPATH];
+ int isdir, flags;
+ _tcscpy (tmp, src);
+ _tcscat (tmp, sep);
+ _tcscat (tmp, fn);
+ zfile_fill_file_attrs_archive (tmp, &isdir, &flags, NULL);
+ if (isdir == ZNODE_VDIR) {
+ _tcscpy (outpath, tmp);
+ scanpath (tmp, outpath);
+ break;
+ }
+ }
+ return 1;
+}
+
+int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
+{
+ int ok = 0, i;
+ int list = 0, xtract = 0, extract = 0;
+ int out = 0, all = 0;
+ TCHAR path[MAX_DPATH], tmppath[MAX_DPATH];
+ int used[32] = { 0 };
+ TCHAR *parm2 = NULL;
+ TCHAR *parm3 = NULL;
+ TCHAR *match = NULL;
+
+ for (i = 0; i < argc && i < 32; i++) {
+ if (!_tcsicmp (argv[i], L"o")) {
+ out = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"-o")) {
+ out = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"l")) {
+ list = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"-l")) {
+ list = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"x")) {
+ xtract = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"-x")) {
+ xtract = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"e")) {
+ extract = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"-e")) {
+ extract = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"*")) {
+ all = 1;
+ used[i] = 1;
+ }
+ if (!_tcsicmp (argv[i], L"**")) {
+ all = -1;
+ used[i] = 1;
+ }
+ if (!used[i] && (_tcschr (argv[i], '*') || _tcschr (argv[i], '?'))) {
+ extract = 1;
+ match = argv[i];
+ used[i] = 1;
+ }
+ }
+ for (i = 1; i < argc && i < 32; i++) {
+ if (!used[i]) {
+ GetFullPathName (argv[i], MAX_DPATH, path, NULL);
+ used[i] = 1;
+ break;
+ }
+ }
+ for (i = 1; i < argc && i < 32; i++) {
+ if (!used[i]) {
+ parm2 = argv[i];
+ used[i] = 1;
+ break;
+ }
+ }
+ for (i = 1; i < argc && i < 32; i++) {
+ if (!used[i]) {
+ parm3 = argv[i];
+ used[i] = 1;
+ break;
+ }
+ }
+
+// _tcscpy (tmppath, path);
+// scanpath (tmppath, path);
+
+ if (match) {
+ unpack2 (path, match, 0);
+ ok = 1;
+ } else if (!parm2 && all > 0) {
+ unpack2 (path, L"*", 0);
+ ok = 1;
+ } else if (extract && parm2) {
+ unpack2 (path, parm2, 0);
+ ok = 1;
+ } else if (argc == 2 || (argc > 2 && list)) {
+ unlist (path, all);
+ ok = 1;
+ } else if (((xtract && parm2) || all || (argc >= 3 && parm2)) && !out) {
+ unpack (path, parm2, parm3, 0, all, 0);
+ ok = 1;
+ } else if (parm2 && (argc >= 4 && out)) {
+ unpack (path, parm2, parm3, 1, all, 0);
+ ok = 1;
+ }
+ if (!ok) {
+ _tprintf (L"UAE unpacker uaeunp 0.4c by Toni Wilen (c)2009\n");
+ _tprintf (L"\n");
+ _tprintf (L"List: \"uaeunp (-l) <path>\"\n");
+ _tprintf (L"List all recursively: \"uaeunp -l <path> **\"\n");
+ _tprintf (L"Extract to file: \"uaeunp (-x) <path> <filename> [<dst name>]\"\n");
+ _tprintf (L"Extract all (single directory): \"uaeunp (-x) <path> *\"\n");
+ _tprintf (L"Extract all (recursively): \"uaeunp (-x) <path> **\"\n");
+ _tprintf (L"Extract all (recursively, current dir): \"uaeunp -e <path> <match string>\"\n");
+ _tprintf (L"Output to console: \"uaeunp (-x) -o <path> <filename>\"\n");
+ _tprintf (L"\n");
+ _tprintf (L"Supported disk image formats:\n");
+ _tprintf (L" ADF and HDF (OFS/FFS), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+ _tprintf (L"Supported archive formats:\n");
+ _tprintf (L" 7ZIP, LHA, LZX, RAR (unrar.dll), ZIP, ArchiveAccess.DLL\n");
+ _tprintf (L"Miscellaneous formats:\n");
+ _tprintf (L" RDB partition table, GZIP\n");
+
+
+ }
+ return 0;
+}
#define ZLIB_WINAPI
#define RECURSIVE_ARCHIVES 1
+//#define ZFILE_DEBUG
#include "sysconfig.h"
#include "sysdeps.h"
#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"
}
xfree (f->name);
xfree (f->data);
+ xfree (f->mode);
xfree (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];
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;
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];
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;
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;
}
{
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;
}
-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)
{
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;
}
_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);
}
#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;
return NULL;
l = zfile_create ();
l->name = my_strdup (name);
+ l->mode = my_strdup (mode);
f = _tfopen (name, mode);
if (!f) {
zfile_fclose (l);
return l;
}
-
static struct zfile *openzip (const TCHAR *pname)
{
int i, j;
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;
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;
#else
static void manglefilename(TCHAR *out, const TCHAR *in)
{
- _tcscpy(out, in);
+ _tcscpy (out, in);
}
#endif
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);
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);
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)
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 ();
l->data = xcalloc (1, 1);
l->size = 0;
}
+ if (prev) {
+ l->zfdmask = prev->zfdmask;
+ }
return l;
}
{
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);
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;
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;
}
}
-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;
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);
}
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)
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;
}
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)
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;
}
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)
{
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;
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;
}
}
return NULL;
}
-
static void addvolumesize (struct zvolume *zv, uae_s64 size)
{
unsigned int blocks = (size + 511) / 512;
{
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;
}
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);
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
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;
}
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)
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;
}
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;
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)
_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;
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;
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
static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
{
- struct zvolume *zv;
+ struct zvolume *zv = NULL;
switch (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:
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;
}
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;
}
_tcscpy (tmphist, zn->fullname);
} else {
_tcscpy (tmphist, zn->fullname);
+#ifndef _CONSOLE
DISK_history_add (tmphist, -1);
+#endif
tmphist[0] = 0;
}
select = 0;
}
}
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);
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);
}
}
}
- zn = zn->next;
+ zn = zn->sibling;
}
zfile_fclose_archive (zv);
}
static void archive_close_zip (void *handle)
{
- unzClose(handle);
+ unzClose (handle);
}
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;
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;
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++) {
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);
}
/* 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;
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;
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;
}
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;
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);
return 1;
}
-static int canrar(void)
+static int canrar (void)
{
static int israr;
static void archive_close_rar (struct RARContext *rc)
{
- xfree(rc);
+ xfree (rc);
}
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;
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;
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);
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);
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) {
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;
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)
}
#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);
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;
+ }
+}