mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-01-07 20:50:20 -05:00
Remove the vendored unrar code
This commit is contained in:
parent
df660f4f9a
commit
d305656bb4
@ -199,16 +199,5 @@
|
||||
"sources": "calibre/devices/mtp/unix/devices.c calibre/devices/mtp/unix/libmtp.c",
|
||||
"headers": "calibre/devices/mtp/unix/devices.h calibre/devices/mtp/unix/upstream/music-players.h calibre/devices/mtp/unix/upstream/device-flags.h",
|
||||
"libraries": "mtp"
|
||||
},
|
||||
{
|
||||
"name": "unrar",
|
||||
"sources": "unrar/rar.cpp unrar/strlist.cpp unrar/strfn.cpp unrar/pathfn.cpp unrar/savepos.cpp unrar/smallfn.cpp unrar/global.cpp unrar/file.cpp unrar/filefn.cpp unrar/filcreat.cpp unrar/archive.cpp unrar/arcread.cpp unrar/unicode.cpp unrar/system.cpp unrar/isnt.cpp unrar/crypt.cpp unrar/crc.cpp unrar/rawread.cpp unrar/encname.cpp unrar/resource.cpp unrar/match.cpp unrar/timefn.cpp unrar/rdwrfn.cpp unrar/consio.cpp unrar/options.cpp unrar/ulinks.cpp unrar/errhnd.cpp unrar/rarvm.cpp unrar/secpassword.cpp unrar/rijndael.cpp unrar/getbits.cpp unrar/sha1.cpp unrar/extinfo.cpp unrar/extract.cpp unrar/volume.cpp unrar/list.cpp unrar/find.cpp unrar/unpack.cpp unrar/cmddata.cpp unrar/filestr.cpp unrar/scantree.cpp calibre/utils/unrar.cpp",
|
||||
"inc_dirs": "unrar",
|
||||
"defines": "SILENT RARDLL UNRAR _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE",
|
||||
"windows_defines": "SILENT RARDLL UNRAR",
|
||||
"haiku_defines": "LITTLE_ENDIAN SILENT RARDLL UNRAR _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _BSD_SOURCE",
|
||||
"haiku_libraries": "bsd",
|
||||
"optimize_level": 2,
|
||||
"windows_libraries": "User32 Advapi32 kernel32 Shell32"
|
||||
}
|
||||
]
|
||||
|
||||
@ -158,7 +158,6 @@ class Plugins(collections.Mapping):
|
||||
'zlib2',
|
||||
'html',
|
||||
'freetype',
|
||||
'unrar',
|
||||
'imageops',
|
||||
'qt_hack',
|
||||
'hunspell',
|
||||
|
||||
@ -57,8 +57,7 @@ class ArchiveExtract(FileTypePlugin):
|
||||
zf = ZipFile(archive, 'r')
|
||||
|
||||
if is_rar:
|
||||
with open(archive, 'rb') as rf:
|
||||
fnames = list(names(rf))
|
||||
fnames = list(names(archive))
|
||||
else:
|
||||
fnames = zf.namelist()
|
||||
|
||||
@ -94,8 +93,7 @@ class ArchiveExtract(FileTypePlugin):
|
||||
of = self.temporary_file('_archive_extract.'+ext)
|
||||
with closing(of):
|
||||
if is_rar:
|
||||
with open(archive, 'rb') as f:
|
||||
data = extract_member(f, match=None, name=fname)[1]
|
||||
data = extract_member(archive, match=None, name=fname)[1]
|
||||
of.write(data)
|
||||
else:
|
||||
of.write(zf.read(fname))
|
||||
@ -162,9 +160,8 @@ def get_comic_metadata(stream, stream_type, series_index='volume'):
|
||||
zf = ZipFile(stream)
|
||||
comment = zf.comment
|
||||
elif stream_type == 'cbr':
|
||||
from calibre.utils.unrar import RARFile
|
||||
f = RARFile(stream, get_comment=True)
|
||||
comment = f.comment
|
||||
from calibre.utils.unrar import comment as get_comment
|
||||
comment = get_comment(stream)
|
||||
|
||||
if comment:
|
||||
import json
|
||||
|
||||
@ -1,553 +0,0 @@
|
||||
/*
|
||||
* unrar.cpp
|
||||
* Copyright (C) 2012 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#define _UNICODE
|
||||
#define UNICODE
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
|
||||
#ifndef RARDLL // Needed for syntastic
|
||||
#define RARDLL
|
||||
#endif
|
||||
|
||||
#include <rar.hpp>
|
||||
#include <dll.hpp>
|
||||
#include <errno.h>
|
||||
#include <new>
|
||||
|
||||
static PyObject *UNRARError = NULL;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static int wcscpy_s(wchar_t *dest, size_t sz, const wchar_t *src) {
|
||||
if (dest == NULL || src == NULL) return EINVAL;
|
||||
if (wcslen(src) >= sz) return ERANGE;
|
||||
wcscpy(dest, src);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define STRFY(x) #x
|
||||
#define STRFY2(x) STRFY(x)
|
||||
#define NOMEM PyErr_SetString(PyExc_MemoryError, "Out of memory at line number: " STRFY2(__LINE__))
|
||||
|
||||
static wchar_t *unicode_to_wchar(PyObject *o) {
|
||||
wchar_t *buf;
|
||||
Py_ssize_t len;
|
||||
if (o == NULL) return NULL;
|
||||
if (!PyUnicode_Check(o)) {PyErr_Format(PyExc_TypeError, "The python object must be a unicode object"); return NULL;}
|
||||
len = PyUnicode_GET_SIZE(o);
|
||||
buf = (wchar_t *)calloc(len+2, sizeof(wchar_t));
|
||||
if (buf == NULL) { NOMEM; return NULL; }
|
||||
len = PyUnicode_AsWideChar((PyUnicodeObject*)o, buf, len);
|
||||
if (len == -1) { free(buf); PyErr_Format(PyExc_TypeError, "Invalid python unicode object."); return NULL; }
|
||||
return buf;
|
||||
}
|
||||
|
||||
static PyObject *wchar_to_unicode(const wchar_t *o) {
|
||||
PyObject *ans;
|
||||
if (o == NULL) return NULL;
|
||||
ans = PyUnicode_FromWideChar(o, wcslen(o));
|
||||
if (ans == NULL) NOMEM;
|
||||
return ans;
|
||||
}
|
||||
|
||||
class PyArchive : public Archive { // {{{
|
||||
public:
|
||||
PyArchive(PyObject *f, wchar_t *name, RAROptions *Cmd) : Archive(Cmd), file(f) {
|
||||
Py_XINCREF(f);
|
||||
wcscpy_s(FileNameW, NM, (wcslen(name) < NM-1) ? name : L"<stream>");
|
||||
if (wcstombs(FileName, FileNameW, NM-1) == (size_t)-1)
|
||||
memcpy(FileName, "<stream>", strlen("<stream>\0"));
|
||||
}
|
||||
|
||||
~PyArchive() { Py_XDECREF(file); }
|
||||
|
||||
virtual bool is_archive() {
|
||||
return IsArchive(false);
|
||||
}
|
||||
|
||||
virtual bool IsOpened() { return true; }
|
||||
|
||||
virtual int DirectRead(void *data, size_t size) {
|
||||
// printf("direct read()\n");
|
||||
char *buf;
|
||||
Py_ssize_t sz = 0;
|
||||
int ret = 0;
|
||||
|
||||
PyObject *res = PyObject_CallMethod(file, (char*)"read", (char*)"(k)", size);
|
||||
if (res == NULL) return -1;
|
||||
|
||||
ret = PyBytes_AsStringAndSize(res, &buf, &sz);
|
||||
if (ret != -1) {
|
||||
memcpy(data, buf, (size_t)sz);
|
||||
ret = (int)sz;
|
||||
}
|
||||
Py_XDECREF(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual int Read(void *data, size_t size) {
|
||||
int ret = DirectRead(data, size);
|
||||
if (ret == -1) {
|
||||
ErrHandler.ReadError(FileName, FileNameW);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual bool RawSeek(int64 offset, int method) {
|
||||
// printf("raw seek(%lld, %d)\n", offset, method);
|
||||
PyObject *res = PyObject_CallMethod(file, (char*)"seek", (char*)"Li", offset, method);
|
||||
if (res == NULL) return false;
|
||||
Py_XDECREF(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Seek(int64 offset, int method) {
|
||||
if (!RawSeek(offset, method))
|
||||
ErrHandler.SeekError(FileName, FileNameW);
|
||||
}
|
||||
|
||||
virtual bool Close() { return true; }
|
||||
|
||||
virtual int64 Tell() {
|
||||
// printf("tell()\n");
|
||||
PyObject *res = PyObject_CallMethod(file, (char*)"tell", NULL);
|
||||
if (res == NULL) {
|
||||
ErrHandler.SeekError(FileName, FileNameW);
|
||||
}
|
||||
Py_ssize_t pos = PyInt_AsSsize_t(res);
|
||||
Py_XDECREF(res);
|
||||
return (int64)pos;
|
||||
}
|
||||
|
||||
virtual byte GetByte() {
|
||||
// printf("get byte()\n");
|
||||
byte b = 0;
|
||||
DirectRead(&b, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
virtual int64 FileLength() {
|
||||
// printf("file length()\n");
|
||||
int64 pos = Tell();
|
||||
Seek(0, SEEK_END);
|
||||
int64 ans = Tell();
|
||||
Seek(pos, SEEK_SET);
|
||||
return ans;
|
||||
}
|
||||
|
||||
virtual bool IsDevice() { return false; }
|
||||
|
||||
private:
|
||||
PyObject *file;
|
||||
}; // }}}
|
||||
|
||||
static
|
||||
PyMethodDef methods[] = {
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
// RARArchive object definition {{{
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
// Type-specific fields go here.
|
||||
PyArchive *archive;
|
||||
PyObject *comment;
|
||||
int header_size;
|
||||
RAROptions Cmd;
|
||||
ComprDataIO DataIO;
|
||||
Unpack *Unp;
|
||||
size_t file_count;
|
||||
|
||||
} RARArchive;
|
||||
|
||||
static void
|
||||
RAR_dealloc(RARArchive* self) {
|
||||
Py_XDECREF(self->comment); self->comment = NULL;
|
||||
|
||||
if (self->Unp != NULL) { delete self->Unp; self->Unp = NULL; }
|
||||
|
||||
if (self->archive != NULL) {
|
||||
self->archive->Close();
|
||||
delete self->archive;
|
||||
self->archive = NULL;
|
||||
}
|
||||
|
||||
self->ob_type->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static const char* unrar_callback_err = NULL;
|
||||
|
||||
static void handle_rar_error(RAR_EXIT errcode) {
|
||||
if (PyErr_Occurred()) return;
|
||||
if (unrar_callback_err != NULL) {
|
||||
PyErr_SetString(UNRARError, unrar_callback_err);
|
||||
unrar_callback_err = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
const char *err = "UNKNOWN";
|
||||
switch (errcode) {
|
||||
case RARX_SUCCESS: err = "RARX_SUCCESS"; break;
|
||||
case RARX_WARNING: err = "RARX_WARNING"; break;
|
||||
case RARX_FATAL: err = "RARX_FATAL"; break;
|
||||
case RARX_CRC: err = "RARX_CRC"; break;
|
||||
case RARX_LOCK: err = "RARX_LOCK"; break;
|
||||
case RARX_WRITE: err = "RARX_WRITE"; break;
|
||||
case RARX_OPEN: err = "RARX_OPEN"; break;
|
||||
case RARX_USERERROR: err = "RARX_USERERROR"; break;
|
||||
case RARX_MEMORY: err = "RARX_MEMORY"; break;
|
||||
case RARX_CREATE: err = "RARX_CREATE"; break;
|
||||
case RARX_NOFILES: err = "RARX_NOFILES"; break;
|
||||
case RARX_USERBREAK: err = "RARX_USERBREAK"; break;
|
||||
}
|
||||
PyErr_Format(UNRARError, "RAR error code: %s", err);
|
||||
}
|
||||
|
||||
static int CALLBACK callback(UINT msg, LPARAM data, LPARAM p1, LPARAM p2) {
|
||||
PyObject *c = (PyObject*)data, *ret;
|
||||
if (msg == UCM_PROCESSDATA) {
|
||||
ret = PyObject_CallMethod(c, (char*)"handle_data", (char*)"(s#)", (char*)p1, (size_t)p2);
|
||||
if (ret == NULL) return -1;
|
||||
Py_DECREF(ret);
|
||||
return 0;
|
||||
} else if (msg == UCM_NEEDPASSWORD || msg == UCM_NEEDPASSWORDW) {
|
||||
unrar_callback_err = "This archive is password protected.";
|
||||
} else if (msg == UCM_CHANGEVOLUME || msg == UCM_CHANGEVOLUMEW) {
|
||||
unrar_callback_err = "This is an unsupported multi-volume RAR archive.";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
RAR_init(RARArchive *self, PyObject *args, PyObject *kwds) {
|
||||
PyObject *file, *name, *get_comment = Py_False, *pycallback;
|
||||
wchar_t *cname;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOO|O", &file, &name, &pycallback, &get_comment)) return -1;
|
||||
if (!PyObject_HasAttrString(file, "read") || !PyObject_HasAttrString(file, "seek") || !PyObject_HasAttrString(file, "tell")) {
|
||||
PyErr_SetString(PyExc_TypeError, "file must be a file like object");
|
||||
return -1;
|
||||
}
|
||||
cname = unicode_to_wchar(name);
|
||||
if (cname == NULL) return -1;
|
||||
|
||||
self->Cmd.Callback = (UNRARCALLBACK)callback;
|
||||
self->Cmd.UserData = (LPARAM)pycallback;
|
||||
|
||||
self->archive = new (std::nothrow) PyArchive(file, cname, &self->Cmd);
|
||||
if (self->archive == NULL) { NOMEM; return -1; }
|
||||
free(cname);
|
||||
|
||||
self->DataIO.UnpArcSize=self->archive->FileLength();
|
||||
self->DataIO.UnpVolume=false;
|
||||
|
||||
self->Unp = new (std::nothrow) Unpack(&self->DataIO);
|
||||
if (self->Unp == NULL) { NOMEM; return -1; }
|
||||
self->file_count = 0;
|
||||
|
||||
try {
|
||||
self->Unp->Init();
|
||||
if (!self->archive->is_archive()) {
|
||||
if (!PyErr_Occurred())
|
||||
PyErr_SetString(UNRARError, "Not a RAR archive");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyObject_IsTrue(get_comment)) {
|
||||
Array<byte> cdata;
|
||||
if (self->archive->GetComment(&cdata, NULL)) {
|
||||
self->comment = PyBytes_FromStringAndSize((const char*)&cdata[0], cdata.Size());
|
||||
if (self->comment == NULL) { NOMEM; return -1; }
|
||||
} else {
|
||||
self->comment = Py_None;
|
||||
Py_INCREF(self->comment);
|
||||
}
|
||||
|
||||
} else {
|
||||
self->comment = Py_None;
|
||||
Py_INCREF(self->comment);
|
||||
}
|
||||
|
||||
} catch (RAR_EXIT errcode) {
|
||||
handle_rar_error(errcode);
|
||||
return -1;
|
||||
} catch (std::bad_alloc) {
|
||||
if (!PyErr_Occurred())
|
||||
NOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Properties {{{
|
||||
|
||||
// RARArchive.friendly_name {{{
|
||||
static PyObject *
|
||||
RAR_comment(RARArchive *self, void *closure) {
|
||||
Py_INCREF(self->comment); return self->comment;
|
||||
} // }}}
|
||||
|
||||
static PyGetSetDef RAR_getsetters[] = {
|
||||
{(char *)"comment",
|
||||
(getter)RAR_comment, NULL,
|
||||
(char *)"The RAR archive comment or None",
|
||||
NULL},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
// }}}
|
||||
|
||||
static PyObject *
|
||||
RAR_current_item(RARArchive *self, PyObject *args) {
|
||||
PyObject *filename = Py_None;
|
||||
try {
|
||||
self->header_size = (int) self->archive->SearchBlock(FILE_HEAD);
|
||||
|
||||
if (self->header_size <= 0) {
|
||||
if (self->archive->Volume && self->archive->GetHeaderType() == ENDARC_HEAD &&
|
||||
self->archive->EndArcHead.Flags & EARC_NEXT_VOLUME) {
|
||||
PyErr_SetString(UNRARError, "This is a multivolume RAR archive. Not supported.");
|
||||
return NULL;
|
||||
}
|
||||
if (self->archive->BrokenFileHeader) {
|
||||
PyErr_SetString(UNRARError, "This archive has a broken file header.");
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (self->archive->NewLhd.Flags & LHD_SPLIT_BEFORE) {
|
||||
PyErr_SetString(UNRARError, "This is a split RAR archive. Not supported.");
|
||||
return NULL;
|
||||
}
|
||||
} catch (RAR_EXIT errcode) {
|
||||
handle_rar_error(errcode);
|
||||
return NULL;
|
||||
} catch (std::bad_alloc) {
|
||||
if (!PyErr_Occurred())
|
||||
NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileHeader fh = self->archive->NewLhd;
|
||||
|
||||
if (*(fh.FileNameW)) {
|
||||
filename = wchar_to_unicode(fh.FileNameW);
|
||||
if (!filename) return NULL;
|
||||
} else {
|
||||
Py_INCREF(filename);
|
||||
}
|
||||
PyObject *tret = PyDict_New();
|
||||
PyObject *temp = NULL;
|
||||
if(!tret) goto error;
|
||||
if (!(temp = Py_BuildValue("s#", fh.FileName, fh.NameSize))) goto error;
|
||||
if (PyDict_SetItemString(tret, "filename", temp) != 0) goto error;
|
||||
Py_DECREF(temp); temp = NULL;
|
||||
#define AVAL(name, code, val) {if (!(temp = Py_BuildValue(code, (val)))) goto error; if (PyDict_SetItemString(tret, name, temp) != 0) goto error; Py_DECREF(temp); temp = NULL;}
|
||||
AVAL("arcname", "s", self->archive->FileName);
|
||||
AVAL("filenamew", "N", filename);
|
||||
AVAL("flags", "H", fh.Flags);
|
||||
AVAL("pack_size", "I", fh.PackSize);
|
||||
AVAL("pack_size_high", "I", fh.HighPackSize);
|
||||
AVAL("unpack_size", "I", fh.UnpSize);
|
||||
AVAL("unpack_size_high", "I", fh.HighUnpSize);
|
||||
AVAL("host_os", "b", fh.HostOS);
|
||||
AVAL("file_crc", "I", fh.FileCRC);
|
||||
AVAL("file_time", "I", fh.FileTime);
|
||||
AVAL("unpack_ver", "b", fh.UnpVer);
|
||||
AVAL("method", "b", fh.Method);
|
||||
AVAL("file_attr", "I", fh.FileAttr);
|
||||
AVAL("is_directory", "O", (self->archive->IsArcDir()) ? Py_True : Py_False);
|
||||
AVAL("is_symlink", "O", (IsLink(fh.FileAttr)) ? Py_True : Py_False);
|
||||
AVAL("is_label", "O", (self->archive->IsArcLabel()) ? Py_True : Py_False);
|
||||
AVAL("has_password", "O", ((fh.Flags & LHD_PASSWORD) != 0) ? Py_True : Py_False);
|
||||
|
||||
return tret;
|
||||
error:
|
||||
Py_XDECREF(tret); Py_XDECREF(temp); Py_XDECREF(filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static File unrar_dummy_output = File();
|
||||
|
||||
static PyObject *
|
||||
RAR_process_item(RARArchive *self, PyObject *args) {
|
||||
PyObject *extract = Py_False;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|O", &extract)) return NULL;
|
||||
self->file_count++;
|
||||
try {
|
||||
if (PyObject_IsTrue(extract)) {
|
||||
if ((self->archive->NewLhd.Flags & LHD_PASSWORD) != 0) {
|
||||
PyErr_SetString(UNRARError, "This file is locked with a password.");
|
||||
return NULL;
|
||||
}
|
||||
if (self->archive->NewLhd.Flags & LHD_SPLIT_AFTER) {
|
||||
PyErr_SetString(UNRARError, "This file is part of a multivolume RAR archive.");
|
||||
return NULL;
|
||||
}
|
||||
self->DataIO.UnpVolume = false;
|
||||
self->DataIO.NextVolumeMissing=false;
|
||||
self->DataIO.CurUnpRead=0;
|
||||
self->DataIO.CurUnpWrite=0;
|
||||
self->DataIO.UnpFileCRC=self->archive->OldFormat ? 0 : 0xffffffff;
|
||||
self->DataIO.PackedCRC=0xffffffff;
|
||||
// self->DataIO.SetEncryption(0, NULL, NULL, false, self->archive->NewLhd.UnpVer>=36);
|
||||
self->DataIO.SetPackedSizeToRead(self->archive->NewLhd.FullPackSize);
|
||||
self->DataIO.SetFiles(self->archive, &unrar_dummy_output);
|
||||
self->DataIO.SetTestMode(false);
|
||||
self->DataIO.SetSkipUnpCRC(false);
|
||||
self->DataIO.SetTestMode(true); // We set this so that the Write method is not called on the output file by UnpWrite()
|
||||
self->Cmd.DllOpMode = RAR_EXTRACT;
|
||||
|
||||
if (IsLink(self->archive->NewLhd.FileAttr)) {
|
||||
char LinkTarget[NM];
|
||||
int datasz = Min(self->archive->NewLhd.PackSize, NM-1);
|
||||
self->DataIO.UnpRead((byte *)LinkTarget, datasz);
|
||||
LinkTarget[datasz]=0;
|
||||
self->DataIO.UnpWrite((byte*)LinkTarget, datasz);
|
||||
self->archive->SeekToNext();
|
||||
} else if (self->archive->IsArcDir() || self->archive->NewLhd.FullUnpSize < 1) {
|
||||
self->archive->SeekToNext();
|
||||
} else {
|
||||
// Implementation from the ExtractCurrentFile() method in the unrar source code
|
||||
if (self->archive->NewLhd.Method == 0x30) {
|
||||
Array<byte> Buffer(0x10000);
|
||||
int64 DestUnpSize = self->archive->NewLhd.FullUnpSize;
|
||||
uint Code = 0;
|
||||
while (true)
|
||||
{
|
||||
Code = self->DataIO.UnpRead(&Buffer[0], Buffer.Size());
|
||||
if (Code==0 || (int)Code==-1) break;
|
||||
Code = (Code < DestUnpSize) ? Code:(uint)DestUnpSize;
|
||||
self->DataIO.UnpWrite(&Buffer[0], Code);
|
||||
if (DestUnpSize >= 0) DestUnpSize -= Code;
|
||||
}
|
||||
} else {
|
||||
self->Unp->SetDestSize(self->archive->NewLhd.FullUnpSize);
|
||||
if (self->archive->NewLhd.UnpVer<=15)
|
||||
self->Unp->DoUnpack(15,self->file_count>1 && self->archive->Solid);
|
||||
else
|
||||
self->Unp->DoUnpack(self->archive->NewLhd.UnpVer,(self->archive->NewLhd.Flags & LHD_SOLID)!=0);
|
||||
}
|
||||
self->archive->SeekToNext();
|
||||
bool ValidCRC = (self->archive->OldFormat && GET_UINT32(self->DataIO.UnpFileCRC)==GET_UINT32(self->archive->NewLhd.FileCRC)) ||
|
||||
(!self->archive->OldFormat && GET_UINT32(self->DataIO.UnpFileCRC)==GET_UINT32(self->archive->NewLhd.FileCRC^0xffffffff));
|
||||
if (!ValidCRC) {
|
||||
PyErr_SetString(UNRARError, "Invalid CRC for item");
|
||||
return NULL;
|
||||
}
|
||||
// Comes from ProcessFile in dll.cpp
|
||||
while(self->archive->IsOpened() && self->archive->ReadHeader() != 0 && self->archive->GetHeaderType() == NEWSUB_HEAD) {
|
||||
// Skip extra file information
|
||||
self->archive->SeekToNext();
|
||||
}
|
||||
self->archive->Seek(self->archive->CurBlockPos, SEEK_SET);
|
||||
}
|
||||
} else {
|
||||
if (self->archive->Volume && self->archive->GetHeaderType() == FILE_HEAD && self->archive->NewLhd.Flags & LHD_SPLIT_AFTER) {
|
||||
PyErr_SetString(UNRARError, "This is a split RAR archive. Not supported.");
|
||||
return NULL;
|
||||
}
|
||||
self->archive->SeekToNext();
|
||||
}
|
||||
} catch(RAR_EXIT errcode) {
|
||||
handle_rar_error(errcode);
|
||||
return NULL;
|
||||
} catch (std::bad_alloc) {
|
||||
if (!PyErr_Occurred())
|
||||
NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef RAR_methods[] = {
|
||||
{"current_item", (PyCFunction)RAR_current_item, METH_VARARGS,
|
||||
"current_item() -> Return the current item in this RAR file."
|
||||
},
|
||||
|
||||
{"process_item", (PyCFunction)RAR_process_item, METH_VARARGS,
|
||||
"process_item(extract=False) -> Process the current item."
|
||||
},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject RARArchiveType = { // {{{
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size*/
|
||||
"unrar.RARArchive", /*tp_name*/
|
||||
sizeof(RARArchive), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)RAR_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash */
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
"RARArchive", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
RAR_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
RAR_getsetters, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)RAR_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
}; // }}}
|
||||
|
||||
// }}} End RARArchive
|
||||
|
||||
|
||||
CALIBRE_MODINIT_FUNC
|
||||
initunrar(void) {
|
||||
PyObject *m;
|
||||
|
||||
RARArchiveType.tp_new = PyType_GenericNew;
|
||||
if (PyType_Ready(&RARArchiveType) < 0)
|
||||
return;
|
||||
|
||||
m = Py_InitModule3(
|
||||
"unrar", methods,
|
||||
"Support for reading RAR archives"
|
||||
);
|
||||
if (m == NULL) return;
|
||||
|
||||
UNRARError = PyErr_NewException((char*)"unrar.UNRARError", NULL, NULL);
|
||||
if (UNRARError == NULL) return;
|
||||
PyModule_AddObject(m, "UNRARError", UNRARError);
|
||||
|
||||
Py_INCREF(&RARArchiveType);
|
||||
PyModule_AddObject(m, "RARArchive", (PyObject *)&RARArchiveType);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,205 +1,95 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, sys, re
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
from io import BytesIO
|
||||
|
||||
from calibre import force_unicode
|
||||
from calibre.constants import filesystem_encoding, isosx
|
||||
from calibre.constants import filesystem_encoding
|
||||
from calibre.ptempfile import PersistentTemporaryFile, TemporaryDirectory
|
||||
|
||||
|
||||
class UNRARError(Exception):
|
||||
pass
|
||||
def as_unicode(x):
|
||||
if isinstance(x, bytes):
|
||||
x = x.decode(filesystem_encoding)
|
||||
return x
|
||||
|
||||
|
||||
class DevNull:
|
||||
|
||||
def write(self, x):
|
||||
pass
|
||||
|
||||
|
||||
class RARStream(object):
|
||||
|
||||
def __init__(self, stream, unrar, get_comment=False):
|
||||
self.stream = stream
|
||||
self.unrar = unrar
|
||||
self._current_cache = None
|
||||
try:
|
||||
self.r = unrar.RARArchive(stream, force_unicode(
|
||||
getattr(stream, 'name', '<stream>'), filesystem_encoding),
|
||||
self, get_comment)
|
||||
except unrar.UNRARError as e:
|
||||
raise UNRARError(type(u'')(e))
|
||||
self.comment = self.r.comment
|
||||
|
||||
def handle_data(self, raw):
|
||||
if self._current_dest is not None:
|
||||
self._current_dest.write(raw)
|
||||
|
||||
def populate_header(self):
|
||||
c = self._current_cache
|
||||
if c['filenamew'] is None:
|
||||
c['filenamew'] = self._decode(c['filename'])
|
||||
c['filename'] = c.pop('filenamew').replace('\\', '/')
|
||||
|
||||
def _decode(self, raw):
|
||||
for enc in ('utf-8', 'utf-16le'):
|
||||
try:
|
||||
return raw.decode(enc)
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
return raw.decode('windows-1252', 'replace')
|
||||
|
||||
@property
|
||||
def current_item(self):
|
||||
if self._current_cache is None:
|
||||
try:
|
||||
self._current_cache = self.r.current_item()
|
||||
except self.unrar.UNRARError as e:
|
||||
raise UNRARError(type(u'')(e))
|
||||
if self._current_cache is None:
|
||||
raise EOFError('End of RAR file')
|
||||
self.populate_header()
|
||||
return self._current_cache
|
||||
|
||||
def process_current_item(self, extract_to=None):
|
||||
self._current_cache = None
|
||||
self._current_dest = extract_to
|
||||
try:
|
||||
ans = self.r.process_item(extract_to is not None)
|
||||
except self.unrar.UNRARError as e:
|
||||
raise UNRARError(type(u'')(e))
|
||||
return ans
|
||||
|
||||
def test(self, print_names=False):
|
||||
null = DevNull()
|
||||
while True:
|
||||
try:
|
||||
h = self.current_item
|
||||
except EOFError:
|
||||
break
|
||||
if print_names:
|
||||
print (h['filename'].encode(sys.stdout.encoding))
|
||||
self.process_current_item(null)
|
||||
|
||||
|
||||
def RARFile(stream, get_comment=False):
|
||||
from calibre.constants import plugins
|
||||
unrar, err = plugins['unrar']
|
||||
if err:
|
||||
raise RuntimeError('Failed to load unrar module with error: %s'
|
||||
%err)
|
||||
return RARStream(stream, unrar, get_comment=get_comment)
|
||||
|
||||
|
||||
class SaveStream(object):
|
||||
class StreamAsPath(object):
|
||||
|
||||
def __init__(self, stream):
|
||||
self.stream = stream
|
||||
|
||||
def __enter__(self):
|
||||
self.stream.seek(0)
|
||||
self.temppath = None
|
||||
if isinstance(self.stream, basestring):
|
||||
return as_unicode(self.stream)
|
||||
name = getattr(self.stream, 'name', None)
|
||||
if name and os.access(name, os.R_OK):
|
||||
return as_unicode(name)
|
||||
pos = self.stream.tell()
|
||||
with PersistentTemporaryFile('for-unar', 'wb') as f:
|
||||
shutil.copyfileobj(self.stream, f)
|
||||
self.stream.seek(pos)
|
||||
self.temppath = f.name
|
||||
return as_unicode(f.name)
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.stream.seek(0)
|
||||
|
||||
|
||||
def safe_path(base, relpath):
|
||||
base = os.path.abspath(base)
|
||||
path = os.path.abspath(os.path.join(base, relpath))
|
||||
if (os.path.normcase(path) == os.path.normcase(base) or not
|
||||
os.path.normcase(path).startswith(os.path.normcase(base))):
|
||||
return None
|
||||
return path
|
||||
|
||||
|
||||
def is_useful(h):
|
||||
return not (h['is_label'] or h['is_symlink'] or h['has_password'] or
|
||||
h['is_directory'])
|
||||
|
||||
|
||||
def stream_extract(stream, location):
|
||||
location = os.path.abspath(location)
|
||||
if not os.path.exists(location):
|
||||
os.makedirs(location)
|
||||
|
||||
with SaveStream(stream):
|
||||
f = RARFile(stream)
|
||||
while True:
|
||||
def __exit__(self, *a):
|
||||
if self.temppath is not None:
|
||||
try:
|
||||
h = f.current_item
|
||||
except EOFError:
|
||||
break
|
||||
if not is_useful(h):
|
||||
f.process_current_item() # Skip these
|
||||
if h['is_directory']:
|
||||
try:
|
||||
os.makedirs(safe_path(location, h['filename']))
|
||||
except:
|
||||
# We ignore create directory errors since we dont
|
||||
# care about missing empty dirs
|
||||
pass
|
||||
else:
|
||||
path = safe_path(location, h['filename'])
|
||||
if path is not None:
|
||||
base, fname = os.path.split(path)
|
||||
if not os.path.exists(base):
|
||||
os.makedirs(base)
|
||||
with open(path, 'wb') as dest:
|
||||
f.process_current_item(dest)
|
||||
os.remove(self.temppath)
|
||||
except EnvironmentError:
|
||||
pass
|
||||
self.temppath = None
|
||||
|
||||
|
||||
def extract(path, location):
|
||||
with open(path, 'rb') as stream:
|
||||
stream_extract(stream, location)
|
||||
def extract(path_or_stream, location):
|
||||
from unrardll import extract
|
||||
with StreamAsPath(path_or_stream) as path:
|
||||
return extract(path, location)
|
||||
|
||||
|
||||
def names(stream):
|
||||
with SaveStream(stream):
|
||||
f = RARFile(stream)
|
||||
while True:
|
||||
try:
|
||||
h = f.current_item
|
||||
except EOFError:
|
||||
break
|
||||
f.process_current_item()
|
||||
if is_useful(h):
|
||||
yield h['filename']
|
||||
def names(path_or_stream):
|
||||
from unrardll import names
|
||||
with StreamAsPath(path_or_stream) as path:
|
||||
for name in names(path, only_useful=True):
|
||||
yield name
|
||||
|
||||
|
||||
def extract_member(stream, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I),
|
||||
name=None):
|
||||
def comment(path_or_stream):
|
||||
from unrardll import comment
|
||||
with StreamAsPath(path_or_stream) as path:
|
||||
return comment(path)
|
||||
|
||||
def is_match(fname):
|
||||
|
||||
def extract_member(
|
||||
path_or_stream, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), name=None):
|
||||
from unrardll import extract_member
|
||||
|
||||
def is_match(header):
|
||||
fname = header['filename']
|
||||
return (name is not None and fname == name) or \
|
||||
(match is not None and match.search(fname) is not None)
|
||||
|
||||
with SaveStream(stream):
|
||||
f = RARFile(stream)
|
||||
while True:
|
||||
try:
|
||||
h = f.current_item
|
||||
except EOFError:
|
||||
break
|
||||
if (not is_useful(h) or not is_match(h['filename'])):
|
||||
f.process_current_item()
|
||||
continue
|
||||
|
||||
et = BytesIO()
|
||||
f.process_current_item(et)
|
||||
return h['filename'], et.getvalue()
|
||||
with StreamAsPath(path_or_stream) as path:
|
||||
name, data = extract_member(path, is_match)
|
||||
if name is not None:
|
||||
return name, data
|
||||
|
||||
|
||||
def extract_first_alphabetically(stream):
|
||||
from calibre.libunzip import sort_key
|
||||
names_ = sorted([x for x in names(stream) if os.path.splitext(x)[1][1:].lower() in
|
||||
{'png', 'jpg', 'jpeg', 'gif', 'webp'}], key=sort_key)
|
||||
names_ = sorted([
|
||||
x for x in names(stream)
|
||||
if os.path.splitext(x)[1][1:].lower() in {
|
||||
'png', 'jpg', 'jpeg', 'gif', 'webp'}],
|
||||
key=sort_key)
|
||||
return extract_member(stream, name=names_[0], match=None)
|
||||
|
||||
|
||||
@ -209,79 +99,57 @@ def extract_cover_image(stream):
|
||||
if name_ok(name):
|
||||
return extract_member(stream, name=name, match=None)
|
||||
|
||||
|
||||
# Test normal RAR file {{{
|
||||
|
||||
|
||||
def test_basic():
|
||||
|
||||
stream = BytesIO(
|
||||
b"Rar!\x1a\x07\x00\xcf\x90s\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x14\xe7z\x00\x80#\x00\x17\x00\x00\x00\r\x00\x00\x00\x03\xc2\xb3\x96o\x00\x00\x00\x00\x1d3\x03\x00\x00\x00\x00\x00CMT\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe6h\x04\x17\xff\xcd\x0f\xffk9b\x11]^\x80\xd3dt \x90+\x00\x14\x00\x00\x00\x08\x00\x00\x00\x03\xf1\x84\x93\\\xb9]yA\x1d3\t\x00\xa4\x81\x00\x001\\sub-one\x00\xc0\x0c\x00\x8f\xec\x89\xfe.JM\x86\x82\x0c_\xfd\xfd\xd7\x11\x1a\xef@\x9eHt \x80'\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x03\x9f\xa8\x17\xf8\xaf]yA\x1d3\x07\x00\xa4\x81\x00\x00one.txt\x00\x08\xbf\x08\xae\xf3\xca\x87\xfeo\xfe\xd2n\x80-Ht \x82:\x00\x18\x00\x00\x00\x10\x00\x00\x00\x03\xa86\x81\xdf\xf9fyA\x1d3\x1a\x00\xa4\x81\x00\x00\xe8\xaf\xb6\xe6\xaf\x94\xe5\xb1\x81.txt\x00\x8bh\xf6\xd4kA\\.\x00txt\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe2l\x91\x189\xff\xdf\xfe\xc2\xd3:g\x9a\x19F=cYt \x928\x00\x11\x00\x00\x00\x08\x00\x00\x00\x03\x7f\xd6\xb6\x7f\xeafyA\x1d3\x16\x00\xa4\x81\x00\x00F\xc3\xbc\xc3\x9fe.txt\x00\x01\x00F\xfc\xdfe\x00.txt\x00\xc0<D\xfe\xc8\xef\xbc\xd1\x04I?\xfd\xff\xdbF)]\xe8\xb9\xe1t \x90/\x00\x13\x00\x00\x00\x08\x00\x00\x00\x03\x1a$\x932\xc2]yA\x1d3\r\x00\xa4\x81\x00\x002\\sub-two.txt\x00\xc0\x10\x00S\xec\xcb\x7f\x8b\xa5(\x0b\x01\xcb\xef\xdf\xf6t\x89\x97z\x0eft \x90)\x00\r\x00\x00\x00\r\x00\x00\x00\x03c\x89K\xd3\xc8fyA\x140\x07\x00\xff\xa1\x00\x00symlink\x00\xc02/sub-two.txt\xeb\x86t\xe0\x90#\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xb9]yA\x140\x01\x00\xedA\x00\x001\x00\xc0\xe0Dt\xe0\x90#\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xc2]yA\x140\x01\x00\xedA\x00\x002\x00\xc0u\xa1t \x80,\x00\r\x00\x00\x00\r\x00\x00\x00\x03T\xea\x04\xca\xe6\x84yA\x140\x0c\x00\xa4\x81\x00\x00uncompresseduncompressed\n\xda\x10t \x900\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x035K.\xa6\x18\x85yA\x1d5\x0e\x00\xa4\x81\x00\x00max-compressed\x00\xc0\x00\x08\xbf\x08\xae\xf2\xcc\x01s\xf8\xff\xec\x96\xe8\xc4={\x00@\x07\x00") # noqa
|
||||
tdata = {u'1': b'',
|
||||
u'1/sub-one': b'sub-one\n',
|
||||
u'2': b'',
|
||||
u'2/sub-two.txt': b'sub-two\n',
|
||||
u'F\xfc\xdfe.txt': b'unicode\n',
|
||||
u'max-compressed': b'max\n',
|
||||
u'one.txt': b'one\n',
|
||||
u'symlink': b'2/sub-two.txt',
|
||||
u'uncompressed': b'uncompressed\n',
|
||||
u'\u8bf6\u6bd4\u5c41.txt': b'chinese unicode\n'}
|
||||
f = RARFile(stream, True)
|
||||
names = set()
|
||||
data = {}
|
||||
if f.comment != b'some comment\n':
|
||||
raise ValueError('Comment not read: %r != %r'%(
|
||||
f.comment, b'some comment\n'))
|
||||
while True:
|
||||
try:
|
||||
h = f.current_item
|
||||
except EOFError:
|
||||
break
|
||||
isdir = h['is_directory']
|
||||
if isdir and h['filename'] not in {'1', '2'}:
|
||||
raise ValueError('Incorrect identification of a directory')
|
||||
if h['is_symlink'] and h['filename'] != 'symlink':
|
||||
raise ValueError('Incorrect identification of a symlink')
|
||||
names.add(h['filename'])
|
||||
et = BytesIO()
|
||||
f.process_current_item(et)
|
||||
data[h['filename']] = et.getvalue()
|
||||
stream = BytesIO( # {{{
|
||||
b"Rar!\x1a\x07\x00\xcf\x90s\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x14\xe7z\x00\x80#\x00\x17\x00\x00\x00\r\x00\x00\x00\x03\xc2\xb3\x96o\x00\x00\x00\x00\x1d3\x03\x00\x00\x00\x00\x00CMT\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe6h\x04\x17\xff\xcd\x0f\xffk9b\x11]^\x80\xd3dt \x90+\x00\x14\x00\x00\x00\x08\x00\x00\x00\x03\xf1\x84\x93\\\xb9]yA\x1d3\t\x00\xa4\x81\x00\x001\\sub-one\x00\xc0\x0c\x00\x8f\xec\x89\xfe.JM\x86\x82\x0c_\xfd\xfd\xd7\x11\x1a\xef@\x9eHt \x80'\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x03\x9f\xa8\x17\xf8\xaf]yA\x1d3\x07\x00\xa4\x81\x00\x00one.txt\x00\x08\xbf\x08\xae\xf3\xca\x87\xfeo\xfe\xd2n\x80-Ht \x82:\x00\x18\x00\x00\x00\x10\x00\x00\x00\x03\xa86\x81\xdf\xf9fyA\x1d3\x1a\x00\xa4\x81\x00\x00\xe8\xaf\xb6\xe6\xaf\x94\xe5\xb1\x81.txt\x00\x8bh\xf6\xd4kA\\.\x00txt\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe2l\x91\x189\xff\xdf\xfe\xc2\xd3:g\x9a\x19F=cYt \x928\x00\x11\x00\x00\x00\x08\x00\x00\x00\x03\x7f\xd6\xb6\x7f\xeafyA\x1d3\x16\x00\xa4\x81\x00\x00F\xc3\xbc\xc3\x9fe.txt\x00\x01\x00F\xfc\xdfe\x00.txt\x00\xc0<D\xfe\xc8\xef\xbc\xd1\x04I?\xfd\xff\xdbF)]\xe8\xb9\xe1t \x90/\x00\x13\x00\x00\x00\x08\x00\x00\x00\x03\x1a$\x932\xc2]yA\x1d3\r\x00\xa4\x81\x00\x002\\sub-two.txt\x00\xc0\x10\x00S\xec\xcb\x7f\x8b\xa5(\x0b\x01\xcb\xef\xdf\xf6t\x89\x97z\x0eft \x90)\x00\r\x00\x00\x00\r\x00\x00\x00\x03c\x89K\xd3\xc8fyA\x140\x07\x00\xff\xa1\x00\x00symlink\x00\xc02/sub-two.txt\xeb\x86t\xe0\x90#\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xb9]yA\x140\x01\x00\xedA\x00\x001\x00\xc0\xe0Dt\xe0\x90#\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xc2]yA\x140\x01\x00\xedA\x00\x002\x00\xc0u\xa1t \x80,\x00\r\x00\x00\x00\r\x00\x00\x00\x03T\xea\x04\xca\xe6\x84yA\x140\x0c\x00\xa4\x81\x00\x00uncompresseduncompressed\n\xda\x10t \x900\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x035K.\xa6\x18\x85yA\x1d5\x0e\x00\xa4\x81\x00\x00max-compressed\x00\xc0\x00\x08\xbf\x08\xae\xf2\xcc\x01s\xf8\xff\xec\x96\xe8\xc4={\x00@\x07\x00") # noqa }}}
|
||||
|
||||
if names != {'1/sub-one', 'one.txt', '2/sub-two.txt',
|
||||
'1', '2', '诶比屁.txt', 'Füße.txt', 'symlink',
|
||||
'uncompressed', 'max-compressed'}:
|
||||
raise ValueError('Name list does not match')
|
||||
if data != tdata:
|
||||
raise ValueError('Some data was not read correctly')
|
||||
tdata = {
|
||||
u'1': b'',
|
||||
u'1/sub-one': b'sub-one\n',
|
||||
u'2': b'',
|
||||
u'2/sub-two.txt': b'sub-two\n',
|
||||
u'F\xfc\xdfe.txt': b'unicode\n',
|
||||
u'max-compressed': b'max\n',
|
||||
u'one.txt': b'one\n',
|
||||
u'symlink': b'2/sub-two.txt',
|
||||
u'uncompressed': b'uncompressed\n',
|
||||
u'\u8bf6\u6bd4\u5c41.txt': b'chinese unicode\n'}
|
||||
|
||||
from calibre.utils.mem import memory
|
||||
import gc
|
||||
del f
|
||||
for i in xrange(3):
|
||||
gc.collect()
|
||||
def do_test(stream):
|
||||
c = comment(stream)
|
||||
if c != b'some comment\n':
|
||||
raise ValueError('Comment not read: %r != %r' % (c, b'some comment\n'))
|
||||
for name in tdata:
|
||||
if name not in '1 2 symlink'.split():
|
||||
d = extract_member(stream, name=name)[1]
|
||||
if d != tdata[name]:
|
||||
raise ValueError(
|
||||
'Failed to extract %s %r != %r' % (name, d, tdata[name]))
|
||||
|
||||
def get_mem_use(num):
|
||||
start = memory()
|
||||
s = SaveStream(stream)
|
||||
for i in xrange(num):
|
||||
with s:
|
||||
f = RARFile(stream)
|
||||
f.test()
|
||||
del f, s
|
||||
for i in xrange(3):
|
||||
gc.collect()
|
||||
return memory() - start
|
||||
(get_mem_use(20))
|
||||
a, b = get_mem_use(10), get_mem_use(110)
|
||||
if not isosx and abs(b - a) > 1:
|
||||
raise ValueError('Leaked %s MB for %d calls'%(b - a, 100))
|
||||
# }}}
|
||||
if set(names(stream)) != {
|
||||
'1/sub-one', 'one.txt', '2/sub-two.txt', '诶比屁.txt', 'Füße.txt',
|
||||
'uncompressed', 'max-compressed'}:
|
||||
raise ValueError('Name list does not match')
|
||||
with TemporaryDirectory('test-unrar') as tdir:
|
||||
extract(stream, tdir)
|
||||
for name in tdata:
|
||||
if name not in '1 2 symlink'.split():
|
||||
with open(os.path.join(tdir, name), 'rb') as s:
|
||||
if s.read() != tdata[name]:
|
||||
raise ValueError('Did not extract %s properly' % name)
|
||||
|
||||
do_test(stream)
|
||||
with PersistentTemporaryFile('test-unrar') as f:
|
||||
shutil.copyfileobj(stream, f)
|
||||
with open(f.name, 'rb') as stream:
|
||||
do_test(stream)
|
||||
os.remove(f.name)
|
||||
|
||||
def test_rar(path):
|
||||
with open(path, 'rb') as stream:
|
||||
f = RARFile(stream)
|
||||
f.test(print_names=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_basic()
|
||||
|
||||
@ -1,623 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="UnRAR"
|
||||
ProjectGUID="{95CC809B-03FC-4EDB-BB20-FD07A698C05F}"
|
||||
RootNamespace="UnRAR"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="build\unrar32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrar32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="UNRAR"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
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="Debug|x64"
|
||||
OutputDirectory="build\unrar64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrar64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="UNRAR"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<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="build\unrar32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrar32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="UNRAR"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
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|x64"
|
||||
OutputDirectory="build\unrar64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrar64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="UNRAR"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<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="archive.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="arcread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="cmddata.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="consio.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crypt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="encname.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="errhnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filcreat.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="file.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filestr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="find.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="getbits.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="global.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="isnt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="list.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="match.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="options.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="pathfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarpch.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarvm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rawread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rdwrfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="recvol.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="resource.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rijndael.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="savepos.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="scantree.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="secpassword.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sha1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="smallfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strlist.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="system.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="timefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ulinks.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unicode.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unpack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="volume.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="rar.hpp"
|
||||
>
|
||||
</File>
|
||||
</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>
|
||||
@ -1,848 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="UnRAR"
|
||||
ProjectGUID="{E815C46C-36C4-499F-BBC2-E772C6B17971}"
|
||||
RootNamespace="UnRAR"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
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="Debug|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<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="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
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|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<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_nocrypt|Win32"
|
||||
OutputDirectory="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT;NOCRYPT"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar_nocrypt.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll_nocrypt.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
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_nocrypt|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT;NOCRYPT"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64_nocrypt.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll_nocrypt.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<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="archive.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="arcread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="cmddata.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="consio.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crypt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dll.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="encname.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="errhnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filcreat.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="file.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filestr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="find.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="getbits.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="global.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="isnt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="list.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="match.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="options.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="pathfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarpch.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarvm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rawread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rdwrfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="recvol.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rijndael.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="savepos.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="scantree.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="secpassword.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sha1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\smallfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strlist.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="system.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="timefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ulinks.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unicode.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unpack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="volume.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="rar.hpp"
|
||||
>
|
||||
</File>
|
||||
</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}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\dll.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@ -1,81 +0,0 @@
|
||||
ACKNOWLEDGMENTS
|
||||
|
||||
* RAR text compression algorithm is based on Dmitry Shkarin PPMII
|
||||
and Dmitry Subbotin carryless rangecoder public domain source code.
|
||||
You may find it in ftp.elf.stuba.sk/pub/pc/pack.
|
||||
|
||||
* RAR encryption includes parts of code from Szymon Stefanek
|
||||
and Brian Gladman AES implementations also as Steve Reid SHA-1 source.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||
All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Source code of this package also as other cryptographic technology
|
||||
and computing project related links are available on Brian Gladman's
|
||||
web site: http://www.gladman.me.uk
|
||||
|
||||
* RAR uses CRC32 function based on Intel Slicing-by-8 algorithm.
|
||||
Original Intel Slicing-by-8 code is available here:
|
||||
|
||||
http://sourceforge.net/projects/slicing-by-8/
|
||||
|
||||
Original Intel Slicing-by-8 code is licensed under BSD License
|
||||
available at http://www.opensource.org/licenses/bsd-license.html
|
||||
|
||||
Copyright (c) 2004-2006 Intel Corporation.
|
||||
All Rights Reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with
|
||||
the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
* Useful hints provided by Alexander Khoroshev and Bulat Ziganshin allowed
|
||||
to significantly improve RAR compression and speed.
|
||||
@ -1,235 +0,0 @@
|
||||
bool IsAnsiComment(const char *Data,int Size);
|
||||
|
||||
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||
{
|
||||
if (!MainComment)
|
||||
return(false);
|
||||
SaveFilePos SavePos(*this);
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
ushort CmtLength;
|
||||
if (OldFormat)
|
||||
{
|
||||
Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
|
||||
CmtLength=GetByte();
|
||||
CmtLength+=(GetByte()<<8);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if ((NewMhd.Flags & MHD_COMMENT)!=0)
|
||||
{
|
||||
// Old style (RAR 2.9) archive comment embedded into the main
|
||||
// archive header.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
|
||||
ReadHeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current (RAR 3.0+) version of archive comment.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
|
||||
return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
|
||||
}
|
||||
#ifndef SFX_MODULE
|
||||
// Old style (RAR 2.9) comment header embedded into the main
|
||||
// archive header.
|
||||
if (CommHead.HeadCRC!=HeaderCRC)
|
||||
{
|
||||
Log(FileName,St(MLogCommHead));
|
||||
Alarm();
|
||||
return(false);
|
||||
}
|
||||
CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
|
||||
#endif
|
||||
}
|
||||
#ifndef SFX_MODULE
|
||||
if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT)!=0 || !OldFormat && CommHead.Method!=0x30)
|
||||
{
|
||||
if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
|
||||
return(false);
|
||||
ComprDataIO DataIO;
|
||||
DataIO.SetTestMode(true);
|
||||
uint UnpCmtLength;
|
||||
if (OldFormat)
|
||||
{
|
||||
#ifdef RAR_NOCRYPT
|
||||
return(false);
|
||||
#else
|
||||
UnpCmtLength=GetByte();
|
||||
UnpCmtLength+=(GetByte()<<8);
|
||||
CmtLength-=2;
|
||||
DataIO.SetCmt13Encryption();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
UnpCmtLength=CommHead.UnpSize;
|
||||
DataIO.SetFiles(this,NULL);
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetPackedSizeToRead(CmtLength);
|
||||
|
||||
Unpack Unpack(&DataIO);
|
||||
Unpack.Init();
|
||||
Unpack.SetDestSize(UnpCmtLength);
|
||||
Unpack.DoUnpack(CommHead.UnpVer,false);
|
||||
|
||||
if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
|
||||
{
|
||||
Log(FileName,St(MLogCommBrk));
|
||||
Alarm();
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte *UnpData;
|
||||
size_t UnpDataSize;
|
||||
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
|
||||
CmtData->Alloc(UnpDataSize);
|
||||
memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CmtData->Alloc(CmtLength);
|
||||
|
||||
Read(&((*CmtData)[0]),CmtLength);
|
||||
if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
|
||||
{
|
||||
Log(FileName,St(MLogCommBrk));
|
||||
Alarm();
|
||||
CmtData->Reset();
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
if (CmtData->Size()>0)
|
||||
{
|
||||
size_t CmtSize=CmtData->Size();
|
||||
char *DataA=(char *)CmtData->Addr();
|
||||
OemToCharBuffA(DataA,DataA,(DWORD)CmtSize);
|
||||
|
||||
if (CmtDataW!=NULL)
|
||||
{
|
||||
CmtDataW->Alloc(CmtSize+1);
|
||||
|
||||
// It can cause reallocation, so we should not use 'DataA' variable
|
||||
// with previosuly saved CmtData->Addr() after Push() call.
|
||||
CmtData->Push(0);
|
||||
|
||||
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||
CmtData->Alloc(CmtSize);
|
||||
CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return(CmtData->Size()>0);
|
||||
}
|
||||
|
||||
|
||||
size_t Archive::ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||
{
|
||||
bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE;
|
||||
if (!ReadSubData(CmtData,NULL))
|
||||
return(0);
|
||||
size_t CmtSize=CmtData->Size();
|
||||
if (Unicode)
|
||||
{
|
||||
CmtSize/=2;
|
||||
Array<wchar> DataW(CmtSize+1);
|
||||
RawToWide(CmtData->Addr(),DataW.Addr(),CmtSize);
|
||||
DataW[CmtSize]=0;
|
||||
size_t DestSize=CmtSize*4;
|
||||
CmtData->Alloc(DestSize+1);
|
||||
WideToChar(DataW.Addr(),(char *)CmtData->Addr(),DestSize);
|
||||
(*CmtData)[DestSize]=0;
|
||||
CmtSize=strlen((char *)CmtData->Addr());
|
||||
CmtData->Alloc(CmtSize);
|
||||
if (CmtDataW!=NULL)
|
||||
{
|
||||
*CmtDataW=DataW;
|
||||
CmtDataW->Alloc(CmtSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (CmtDataW!=NULL)
|
||||
{
|
||||
CmtData->Push(0);
|
||||
CmtDataW->Alloc(CmtSize+1);
|
||||
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||
CmtData->Alloc(CmtSize);
|
||||
CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
|
||||
}
|
||||
return(CmtSize);
|
||||
}
|
||||
|
||||
|
||||
void Archive::ViewComment()
|
||||
{
|
||||
#ifndef GUI
|
||||
if (Cmd->DisableComment)
|
||||
return;
|
||||
Array<byte> CmtBuf;
|
||||
if (GetComment(&CmtBuf,NULL))
|
||||
{
|
||||
size_t CmtSize=CmtBuf.Size();
|
||||
char *ChPtr=(char *)memchr(&CmtBuf[0],0x1A,CmtSize);
|
||||
if (ChPtr!=NULL)
|
||||
CmtSize=ChPtr-(char *)&CmtBuf[0];
|
||||
mprintf("\n");
|
||||
OutComment((char *)&CmtBuf[0],CmtSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Used for archives created by old RAR versions up to and including RAR 2.9.
|
||||
// New RAR versions store file comments in separate headers and such comments
|
||||
// are displayed in ListNewSubHeader function.
|
||||
void Archive::ViewFileComment()
|
||||
{
|
||||
if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat)
|
||||
return;
|
||||
#ifndef GUI
|
||||
mprintf(St(MFileComment));
|
||||
#endif
|
||||
const int MaxSize=0x8000;
|
||||
Array<char> CmtBuf(MaxSize);
|
||||
SaveFilePos SavePos(*this);
|
||||
Seek(CurBlockPos+SIZEOF_NEWLHD+NewLhd.NameSize,SEEK_SET);
|
||||
int64 SaveCurBlockPos=CurBlockPos;
|
||||
int64 SaveNextBlockPos=NextBlockPos;
|
||||
|
||||
size_t Size=ReadHeader();
|
||||
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
|
||||
if (Size<7 || CommHead.HeadType!=COMM_HEAD)
|
||||
return;
|
||||
if (CommHead.HeadCRC!=HeaderCRC)
|
||||
{
|
||||
#ifndef GUI
|
||||
Log(FileName,St(MLogCommHead));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER ||
|
||||
CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize)
|
||||
return;
|
||||
Read(&CmtBuf[0],CommHead.UnpSize);
|
||||
if (CommHead.CommCRC!=((~CRC(0xffffffff,&CmtBuf[0],CommHead.UnpSize)&0xffff)))
|
||||
{
|
||||
Log(FileName,St(MLogBrokFCmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutComment(&CmtBuf[0],CommHead.UnpSize);
|
||||
#ifndef GUI
|
||||
mprintf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,284 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifndef SHELL_EXT
|
||||
#include "arccmt.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
Archive::Archive(RAROptions *InitCmd)
|
||||
{
|
||||
Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
|
||||
OpenShared=Cmd->OpenShared;
|
||||
OldFormat=false;
|
||||
Solid=false;
|
||||
Volume=false;
|
||||
MainComment=false;
|
||||
Locked=false;
|
||||
Signed=false;
|
||||
NotFirstVolume=false;
|
||||
SFXSize=0;
|
||||
LatestTime.Reset();
|
||||
Protected=false;
|
||||
Encrypted=false;
|
||||
FailedHeaderDecryption=false;
|
||||
BrokenFileHeader=false;
|
||||
LastReadBlock=0;
|
||||
|
||||
CurBlockPos=0;
|
||||
NextBlockPos=0;
|
||||
|
||||
RecoveryPos=SIZEOF_MARKHEAD;
|
||||
RecoverySectors=-1;
|
||||
|
||||
memset(&NewMhd,0,sizeof(NewMhd));
|
||||
NewMhd.HeadType=MAIN_HEAD;
|
||||
NewMhd.HeadSize=SIZEOF_NEWMHD;
|
||||
HeaderCRC=0;
|
||||
VolWrite=0;
|
||||
AddingFilesSize=0;
|
||||
AddingHeadersSize=0;
|
||||
#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
|
||||
*HeadersSalt=0;
|
||||
*SubDataSalt=0;
|
||||
#endif
|
||||
*FirstVolumeName=0;
|
||||
*FirstVolumeNameW=0;
|
||||
|
||||
Splitting=false;
|
||||
NewArchive=false;
|
||||
|
||||
SilentOpen=false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef SHELL_EXT
|
||||
void Archive::CheckArc(bool EnableBroken)
|
||||
{
|
||||
if (!IsArchive(EnableBroken))
|
||||
{
|
||||
Log(FileName,St(MBadArc),FileName);
|
||||
ErrHandler.Exit(RARX_FATAL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
void Archive::CheckOpen(const char *Name,const wchar *NameW)
|
||||
{
|
||||
TOpen(Name,NameW);
|
||||
CheckArc(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Archive::WCheckOpen(const char *Name,const wchar *NameW)
|
||||
{
|
||||
if (!WOpen(Name,NameW))
|
||||
return(false);
|
||||
if (!IsArchive(false))
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MNotRAR),FileName);
|
||||
#endif
|
||||
Close();
|
||||
return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
ARCSIGN_TYPE Archive::IsSignature(const byte *D,size_t Size)
|
||||
{
|
||||
ARCSIGN_TYPE Type=ARCSIGN_NONE;
|
||||
if (Size>=1 && D[0]==0x52)
|
||||
#ifndef SFX_MODULE
|
||||
if (Size>=4 && D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
|
||||
Type=ARCSIGN_OLD;
|
||||
else
|
||||
#endif
|
||||
if (Size>=7 && D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07)
|
||||
{
|
||||
// We check for non-zero last signature byte, so we can return
|
||||
// a sensible warning in case we'll want to change the archive
|
||||
// format sometimes in the future.
|
||||
Type=D[6]==0 ? ARCSIGN_CURRENT:ARCSIGN_FUTURE;
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
|
||||
|
||||
bool Archive::IsArchive(bool EnableBroken)
|
||||
{
|
||||
Encrypted=false;
|
||||
#ifndef SFX_MODULE
|
||||
if (IsDevice())
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MInvalidName),FileName);
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
#endif
|
||||
if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
|
||||
return(false);
|
||||
SFXSize=0;
|
||||
|
||||
ARCSIGN_TYPE Type;
|
||||
if ((Type=IsSignature(MarkHead.Mark,sizeof(MarkHead.Mark)))!=ARCSIGN_NONE)
|
||||
{
|
||||
OldFormat=(Type==ARCSIGN_OLD);
|
||||
if (OldFormat)
|
||||
Seek(0,SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<char> Buffer(MAXSFXSIZE);
|
||||
long CurPos=(long)Tell();
|
||||
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
|
||||
for (int I=0;I<ReadSize;I++)
|
||||
if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=ARCSIGN_NONE)
|
||||
{
|
||||
OldFormat=(Type==ARCSIGN_OLD);
|
||||
if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
|
||||
{
|
||||
char *D=&Buffer[28-CurPos];
|
||||
if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
|
||||
continue;
|
||||
}
|
||||
SFXSize=CurPos+I;
|
||||
Seek(SFXSize,SEEK_SET);
|
||||
if (!OldFormat)
|
||||
Read(MarkHead.Mark,SIZEOF_MARKHEAD);
|
||||
break;
|
||||
}
|
||||
if (SFXSize==0)
|
||||
return false;
|
||||
}
|
||||
if (Type==ARCSIGN_FUTURE)
|
||||
{
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
Log(FileName,St(MNewRarFormat));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
ReadHeader();
|
||||
SeekToNext();
|
||||
#ifndef SFX_MODULE
|
||||
if (OldFormat)
|
||||
{
|
||||
NewMhd.Flags=OldMhd.Flags & 0x3f;
|
||||
NewMhd.HeadSize=OldMhd.HeadSize;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (HeaderCRC!=NewMhd.HeadCRC)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MLogMainHead));
|
||||
#endif
|
||||
Alarm();
|
||||
if (!EnableBroken)
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
Volume=(NewMhd.Flags & MHD_VOLUME);
|
||||
Solid=(NewMhd.Flags & MHD_SOLID)!=0;
|
||||
MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
|
||||
Locked=(NewMhd.Flags & MHD_LOCK)!=0;
|
||||
Signed=(NewMhd.PosAV!=0);
|
||||
Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
|
||||
Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
|
||||
|
||||
if (NewMhd.EncryptVer>UNP_VER)
|
||||
{
|
||||
#ifdef RARDLL
|
||||
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
|
||||
#else
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
Log(FileName,St(MUnknownMeth),FileName);
|
||||
Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
|
||||
#endif
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
#ifdef RARDLL
|
||||
// If callback function is not set, we cannot get the password,
|
||||
// so we skip the initial header processing for encrypted header archive.
|
||||
// It leads to skipped archive comment, but the rest of archive data
|
||||
// is processed correctly.
|
||||
if (Cmd->Callback==NULL)
|
||||
SilentOpen=true;
|
||||
#endif
|
||||
|
||||
// If not encrypted, we'll check it below.
|
||||
NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
|
||||
|
||||
if (!SilentOpen || !Encrypted)
|
||||
{
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||
|
||||
NotFirstVolume=false;
|
||||
while (ReadHeader()!=0)
|
||||
{
|
||||
int HeaderType=GetHeaderType();
|
||||
if (HeaderType==NEWSUB_HEAD)
|
||||
{
|
||||
if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
|
||||
MainComment=true;
|
||||
if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
|
||||
Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
|
||||
NotFirstVolume=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
|
||||
Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
|
||||
NotFirstVolume=true;
|
||||
break;
|
||||
}
|
||||
SeekToNext();
|
||||
}
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
}
|
||||
if (!Volume || !NotFirstVolume)
|
||||
{
|
||||
strcpy(FirstVolumeName,FileName);
|
||||
wcscpy(FirstVolumeNameW,FileNameW);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Archive::SeekToNext()
|
||||
{
|
||||
Seek(NextBlockPos,SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int Archive::GetRecoverySize(bool Required)
|
||||
{
|
||||
if (!Protected)
|
||||
return(0);
|
||||
if (RecoverySectors!=-1 || !Required)
|
||||
return(RecoverySectors);
|
||||
SaveFilePos SavePos(*this);
|
||||
Seek(SFXSize,SEEK_SET);
|
||||
SearchSubBlock(SUBHEAD_TYPE_RR);
|
||||
return(RecoverySectors);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
#ifndef _RAR_ARCHIVE_
|
||||
#define _RAR_ARCHIVE_
|
||||
|
||||
class Pack;
|
||||
|
||||
enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4};
|
||||
|
||||
enum ARCSIGN_TYPE {ARCSIGN_NONE,ARCSIGN_OLD,ARCSIGN_CURRENT,ARCSIGN_FUTURE};
|
||||
|
||||
class Archive:public File
|
||||
{
|
||||
private:
|
||||
ARCSIGN_TYPE IsSignature(const byte *D,size_t Size);
|
||||
void UpdateLatestTime(FileHeader *CurBlock);
|
||||
void ConvertNameCase(char *Name);
|
||||
void ConvertNameCase(wchar *Name);
|
||||
void ConvertUnknownHeader();
|
||||
size_t ReadOldHeader();
|
||||
void UnexpEndArcMsg();
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
|
||||
CryptData HeadersCrypt;
|
||||
byte HeadersSalt[SALT_SIZE];
|
||||
#endif
|
||||
#ifndef SHELL_EXT
|
||||
ComprDataIO SubDataIO;
|
||||
byte SubDataSalt[SALT_SIZE];
|
||||
#endif
|
||||
RAROptions *Cmd,DummyCmd;
|
||||
|
||||
MarkHeader MarkHead;
|
||||
OldMainHeader OldMhd;
|
||||
|
||||
int RecoverySectors;
|
||||
int64 RecoveryPos;
|
||||
|
||||
bool FailedHeaderDecryption;
|
||||
|
||||
RarTime LatestTime;
|
||||
int LastReadBlock;
|
||||
int CurHeaderType;
|
||||
|
||||
bool SilentOpen;
|
||||
public:
|
||||
Archive(RAROptions *InitCmd=NULL);
|
||||
bool IsArchive(bool EnableBroken);
|
||||
size_t SearchBlock(int BlockType);
|
||||
size_t SearchSubBlock(const char *Type);
|
||||
int ReadBlock(int BlockType);
|
||||
void WriteBlock(int BlockType,BaseBlock *wb=NULL);
|
||||
int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW);
|
||||
void SetLhdSize();
|
||||
size_t ReadHeader();
|
||||
void CheckArc(bool EnableBroken);
|
||||
void CheckOpen(const char *Name,const wchar *NameW=NULL);
|
||||
bool WCheckOpen(const char *Name,const wchar *NameW=NULL);
|
||||
bool GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||
void ViewComment();
|
||||
void ViewFileComment();
|
||||
void SetLatestTime(RarTime *NewTime);
|
||||
void SeekToNext();
|
||||
bool CheckAccess();
|
||||
bool IsArcDir();
|
||||
bool IsArcLabel();
|
||||
void ConvertAttributes();
|
||||
int GetRecoverySize(bool Required);
|
||||
void VolSubtractHeaderSize(size_t SubSize);
|
||||
void AddSubData(byte *SrcData,size_t DataSize,File *SrcFile,const char *Name,bool AllowSplit);
|
||||
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
|
||||
int GetHeaderType() {return(CurHeaderType);};
|
||||
size_t ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||
void WriteCommentData(byte *Data,size_t DataSize,bool FileComment);
|
||||
RAROptions* GetRAROptions() {return(Cmd);}
|
||||
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
|
||||
|
||||
BaseBlock ShortBlock;
|
||||
MainHeader NewMhd;
|
||||
FileHeader NewLhd;
|
||||
EndArcHeader EndArcHead;
|
||||
SubBlockHeader SubBlockHead;
|
||||
FileHeader SubHead;
|
||||
CommentHeader CommHead;
|
||||
ProtectHeader ProtectHead;
|
||||
AVHeader AVHead;
|
||||
SignHeader SignHead;
|
||||
UnixOwnersHeader UOHead;
|
||||
MacFInfoHeader MACHead;
|
||||
EAHeader EAHead;
|
||||
StreamHeader StreamHead;
|
||||
|
||||
int64 CurBlockPos;
|
||||
int64 NextBlockPos;
|
||||
|
||||
bool OldFormat;
|
||||
bool Solid;
|
||||
bool Volume;
|
||||
bool MainComment;
|
||||
bool Locked;
|
||||
bool Signed;
|
||||
bool NotFirstVolume;
|
||||
bool Protected;
|
||||
bool Encrypted;
|
||||
size_t SFXSize;
|
||||
bool BrokenFileHeader;
|
||||
|
||||
bool Splitting;
|
||||
|
||||
ushort HeaderCRC;
|
||||
|
||||
int64 VolWrite;
|
||||
int64 AddingFilesSize;
|
||||
size_t AddingHeadersSize;
|
||||
|
||||
bool NewArchive;
|
||||
|
||||
char FirstVolumeName[NM];
|
||||
wchar FirstVolumeNameW[NM];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,765 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
size_t Archive::SearchBlock(int BlockType)
|
||||
{
|
||||
size_t Size,Count=0;
|
||||
while ((Size=ReadHeader())!=0 &&
|
||||
(BlockType==ENDARC_HEAD || GetHeaderType()!=ENDARC_HEAD))
|
||||
{
|
||||
if ((++Count & 127)==0)
|
||||
Wait();
|
||||
if (GetHeaderType()==BlockType)
|
||||
return(Size);
|
||||
SeekToNext();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
size_t Archive::SearchSubBlock(const char *Type)
|
||||
{
|
||||
size_t Size;
|
||||
while ((Size=ReadHeader())!=0 && GetHeaderType()!=ENDARC_HEAD)
|
||||
{
|
||||
if (GetHeaderType()==NEWSUB_HEAD && SubHead.CmpName(Type))
|
||||
return(Size);
|
||||
SeekToNext();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void Archive::UnexpEndArcMsg()
|
||||
{
|
||||
int64 ArcSize=FileLength();
|
||||
if (CurBlockPos>ArcSize || NextBlockPos>ArcSize)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MLogUnexpEOF));
|
||||
#endif
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t Archive::ReadHeader()
|
||||
{
|
||||
// Once we failed to decrypt an encrypted block, there is no reason to
|
||||
// attempt to do it further. We'll never be successful and only generate
|
||||
// endless errors.
|
||||
if (FailedHeaderDecryption)
|
||||
return 0;
|
||||
|
||||
CurBlockPos=Tell();
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
if (OldFormat)
|
||||
return(ReadOldHeader());
|
||||
#endif
|
||||
|
||||
RawRead Raw(this);
|
||||
|
||||
bool Decrypt=Encrypted && CurBlockPos>=(int64)SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD;
|
||||
|
||||
if (Decrypt)
|
||||
{
|
||||
#if defined(SHELL_EXT) || defined(RAR_NOCRYPT)
|
||||
return(0);
|
||||
#else
|
||||
if (Read(HeadersSalt,SALT_SIZE)!=SALT_SIZE)
|
||||
{
|
||||
UnexpEndArcMsg();
|
||||
return(0);
|
||||
}
|
||||
if (!Cmd->Password.IsSet())
|
||||
{
|
||||
#ifdef RARDLL
|
||||
if (Cmd->Callback!=NULL)
|
||||
{
|
||||
wchar PasswordW[MAXPASSWORD];
|
||||
*PasswordW=0;
|
||||
if (Cmd->Callback(UCM_NEEDPASSWORDW,Cmd->UserData,(LPARAM)PasswordW,ASIZE(PasswordW))==-1)
|
||||
*PasswordW=0;
|
||||
if (*PasswordW==0)
|
||||
{
|
||||
char PasswordA[MAXPASSWORD];
|
||||
*PasswordA=0;
|
||||
if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1)
|
||||
*PasswordA=0;
|
||||
GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW));
|
||||
cleandata(PasswordA,sizeof(PasswordA));
|
||||
}
|
||||
Cmd->Password.Set(PasswordW);
|
||||
cleandata(PasswordW,sizeof(PasswordW));
|
||||
}
|
||||
if (!Cmd->Password.IsSet())
|
||||
{
|
||||
Close();
|
||||
Cmd->DllError=ERAR_MISSING_PASSWORD;
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
#else
|
||||
if (!GetPassword(PASSWORD_ARCHIVE,FileName,FileNameW,&Cmd->Password))
|
||||
{
|
||||
Close();
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
HeadersCrypt.SetCryptKeys(&Cmd->Password,HeadersSalt,false,false,NewMhd.EncryptVer>=36);
|
||||
Raw.SetCrypt(&HeadersCrypt);
|
||||
#endif
|
||||
}
|
||||
|
||||
Raw.Read(SIZEOF_SHORTBLOCKHEAD);
|
||||
if (Raw.Size()==0)
|
||||
{
|
||||
UnexpEndArcMsg();
|
||||
return(0);
|
||||
}
|
||||
|
||||
Raw.Get(ShortBlock.HeadCRC);
|
||||
byte HeadType;
|
||||
Raw.Get(HeadType);
|
||||
ShortBlock.HeadType=(HEADER_TYPE)HeadType;
|
||||
Raw.Get(ShortBlock.Flags);
|
||||
Raw.Get(ShortBlock.HeadSize);
|
||||
if (ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MLogFileHead),"???");
|
||||
#endif
|
||||
BrokenFileHeader=true;
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (ShortBlock.HeadType==COMM_HEAD)
|
||||
{
|
||||
// Old style (up to RAR 2.9) comment header embedded into main
|
||||
// or file header. We must not read the entire ShortBlock.HeadSize here
|
||||
// to not break the comment processing logic later.
|
||||
Raw.Read(SIZEOF_COMMHEAD-SIZEOF_SHORTBLOCKHEAD);
|
||||
}
|
||||
else
|
||||
if (ShortBlock.HeadType==MAIN_HEAD && (ShortBlock.Flags & MHD_COMMENT)!=0)
|
||||
{
|
||||
// Old style (up to RAR 2.9) main archive comment embedded into
|
||||
// the main archive header found. While we can read the entire
|
||||
// ShortBlock.HeadSize here and remove this part of "if", it would be
|
||||
// waste of memory, because we'll read and process this comment data
|
||||
// in other function anyway and we do not need them here now.
|
||||
Raw.Read(SIZEOF_NEWMHD-SIZEOF_SHORTBLOCKHEAD);
|
||||
}
|
||||
else
|
||||
Raw.Read(ShortBlock.HeadSize-SIZEOF_SHORTBLOCKHEAD);
|
||||
|
||||
NextBlockPos=CurBlockPos+ShortBlock.HeadSize;
|
||||
|
||||
switch(ShortBlock.HeadType)
|
||||
{
|
||||
case MAIN_HEAD:
|
||||
*(BaseBlock *)&NewMhd=ShortBlock;
|
||||
Raw.Get(NewMhd.HighPosAV);
|
||||
Raw.Get(NewMhd.PosAV);
|
||||
if (NewMhd.Flags & MHD_ENCRYPTVER)
|
||||
Raw.Get(NewMhd.EncryptVer);
|
||||
break;
|
||||
case ENDARC_HEAD:
|
||||
*(BaseBlock *)&EndArcHead=ShortBlock;
|
||||
if (EndArcHead.Flags & EARC_DATACRC)
|
||||
Raw.Get(EndArcHead.ArcDataCRC);
|
||||
if (EndArcHead.Flags & EARC_VOLNUMBER)
|
||||
Raw.Get(EndArcHead.VolNumber);
|
||||
break;
|
||||
case FILE_HEAD:
|
||||
case NEWSUB_HEAD:
|
||||
{
|
||||
FileHeader *hd=ShortBlock.HeadType==FILE_HEAD ? &NewLhd:&SubHead;
|
||||
*(BaseBlock *)hd=ShortBlock;
|
||||
Raw.Get(hd->PackSize);
|
||||
Raw.Get(hd->UnpSize);
|
||||
Raw.Get(hd->HostOS);
|
||||
Raw.Get(hd->FileCRC);
|
||||
Raw.Get(hd->FileTime);
|
||||
Raw.Get(hd->UnpVer);
|
||||
Raw.Get(hd->Method);
|
||||
Raw.Get(hd->NameSize);
|
||||
Raw.Get(hd->FileAttr);
|
||||
if (hd->Flags & LHD_LARGE)
|
||||
{
|
||||
Raw.Get(hd->HighPackSize);
|
||||
Raw.Get(hd->HighUnpSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
hd->HighPackSize=hd->HighUnpSize=0;
|
||||
if (hd->UnpSize==0xffffffff)
|
||||
{
|
||||
// UnpSize equal to 0xffffffff without LHD_LARGE flag indicates
|
||||
// that we do not know the unpacked file size and must unpack it
|
||||
// until we find the end of file marker in compressed data.
|
||||
hd->UnpSize=(uint)(INT64NDF);
|
||||
hd->HighUnpSize=(uint)(INT64NDF>>32);
|
||||
}
|
||||
}
|
||||
hd->FullPackSize=INT32TO64(hd->HighPackSize,hd->PackSize);
|
||||
hd->FullUnpSize=INT32TO64(hd->HighUnpSize,hd->UnpSize);
|
||||
|
||||
char FileName[NM*4];
|
||||
size_t NameSize=Min(hd->NameSize,sizeof(FileName)-1);
|
||||
Raw.Get((byte *)FileName,NameSize);
|
||||
FileName[NameSize]=0;
|
||||
|
||||
strncpyz(hd->FileName,FileName,ASIZE(hd->FileName));
|
||||
|
||||
if (hd->HeadType==NEWSUB_HEAD)
|
||||
{
|
||||
// Let's calculate the size of optional data.
|
||||
int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD;
|
||||
if (hd->Flags & LHD_SALT)
|
||||
DataSize-=SALT_SIZE;
|
||||
|
||||
if (DataSize>0)
|
||||
{
|
||||
// Here we read optional additional fields for subheaders.
|
||||
// They are stored after the file name and before salt.
|
||||
hd->SubData.Alloc(DataSize);
|
||||
Raw.Get(&hd->SubData[0],DataSize);
|
||||
if (hd->CmpName(SUBHEAD_TYPE_RR))
|
||||
{
|
||||
byte *D=&hd->SubData[8];
|
||||
RecoverySectors=D[0]+((uint)D[1]<<8)+((uint)D[2]<<16)+((uint)D[3]<<24);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (hd->HeadType==FILE_HEAD)
|
||||
{
|
||||
if (hd->Flags & LHD_UNICODE)
|
||||
{
|
||||
EncodeFileName NameCoder;
|
||||
size_t Length=strlen(FileName);
|
||||
if (Length==hd->NameSize)
|
||||
{
|
||||
UtfToWide(FileName,hd->FileNameW,sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0])-1);
|
||||
WideToChar(hd->FileNameW,hd->FileName,sizeof(hd->FileName)/sizeof(hd->FileName[0])-1);
|
||||
ExtToInt(hd->FileName,hd->FileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Length++;
|
||||
NameCoder.Decode(FileName,(byte *)FileName+Length,
|
||||
hd->NameSize-Length,hd->FileNameW,
|
||||
sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0]));
|
||||
}
|
||||
if (*hd->FileNameW==0)
|
||||
hd->Flags &= ~LHD_UNICODE;
|
||||
}
|
||||
else
|
||||
*hd->FileNameW=0;
|
||||
#ifndef SFX_MODULE
|
||||
ConvertNameCase(hd->FileName);
|
||||
ConvertNameCase(hd->FileNameW);
|
||||
#endif
|
||||
ConvertUnknownHeader();
|
||||
}
|
||||
if (hd->Flags & LHD_SALT)
|
||||
Raw.Get(hd->Salt,SALT_SIZE);
|
||||
hd->mtime.SetDos(hd->FileTime);
|
||||
hd->ctime.Reset();
|
||||
hd->atime.Reset();
|
||||
hd->arctime.Reset();
|
||||
if (hd->Flags & LHD_EXTTIME)
|
||||
{
|
||||
ushort Flags;
|
||||
Raw.Get(Flags);
|
||||
RarTime *tbl[4];
|
||||
tbl[0]=&NewLhd.mtime;
|
||||
tbl[1]=&NewLhd.ctime;
|
||||
tbl[2]=&NewLhd.atime;
|
||||
tbl[3]=&NewLhd.arctime;
|
||||
for (int I=0;I<4;I++)
|
||||
{
|
||||
RarTime *CurTime=tbl[I];
|
||||
uint rmode=Flags>>(3-I)*4;
|
||||
if ((rmode & 8)==0)
|
||||
continue;
|
||||
if (I!=0)
|
||||
{
|
||||
uint DosTime;
|
||||
Raw.Get(DosTime);
|
||||
CurTime->SetDos(DosTime);
|
||||
}
|
||||
RarLocalTime rlt;
|
||||
CurTime->GetLocal(&rlt);
|
||||
if (rmode & 4)
|
||||
rlt.Second++;
|
||||
rlt.Reminder=0;
|
||||
int count=rmode&3;
|
||||
for (int J=0;J<count;J++)
|
||||
{
|
||||
byte CurByte;
|
||||
Raw.Get(CurByte);
|
||||
rlt.Reminder|=(((uint)CurByte)<<((J+3-count)*8));
|
||||
}
|
||||
CurTime->SetLocal(&rlt);
|
||||
}
|
||||
}
|
||||
NextBlockPos+=hd->FullPackSize;
|
||||
bool CRCProcessedOnly=(hd->Flags & LHD_COMMENT)!=0;
|
||||
HeaderCRC=~Raw.GetCRC(CRCProcessedOnly)&0xffff;
|
||||
if (hd->HeadCRC!=HeaderCRC)
|
||||
{
|
||||
if (hd->HeadType==NEWSUB_HEAD && strlen(hd->FileName)<ASIZE(hd->FileName)-5)
|
||||
strcat(hd->FileName,"- ???");
|
||||
BrokenFileHeader=true;
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
|
||||
// If we have a broken encrypted header, we do not need to display
|
||||
// the error message here, because it will be displayed for such
|
||||
// headers later in this function. Also such headers are unlikely
|
||||
// to have anything sensible in file name field, so it is useless
|
||||
// to display the file name.
|
||||
bool EncBroken=Decrypt && ShortBlock.HeadCRC!=(~Raw.GetCRC(false)&0xffff);
|
||||
if (!EncBroken)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(Archive::FileName,St(MLogFileHead),IntNameToExt(hd->FileName));
|
||||
Alarm();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifndef SFX_MODULE
|
||||
case COMM_HEAD:
|
||||
*(BaseBlock *)&CommHead=ShortBlock;
|
||||
Raw.Get(CommHead.UnpSize);
|
||||
Raw.Get(CommHead.UnpVer);
|
||||
Raw.Get(CommHead.Method);
|
||||
Raw.Get(CommHead.CommCRC);
|
||||
break;
|
||||
case SIGN_HEAD:
|
||||
*(BaseBlock *)&SignHead=ShortBlock;
|
||||
Raw.Get(SignHead.CreationTime);
|
||||
Raw.Get(SignHead.ArcNameSize);
|
||||
Raw.Get(SignHead.UserNameSize);
|
||||
break;
|
||||
case AV_HEAD:
|
||||
*(BaseBlock *)&AVHead=ShortBlock;
|
||||
Raw.Get(AVHead.UnpVer);
|
||||
Raw.Get(AVHead.Method);
|
||||
Raw.Get(AVHead.AVVer);
|
||||
Raw.Get(AVHead.AVInfoCRC);
|
||||
break;
|
||||
case PROTECT_HEAD:
|
||||
*(BaseBlock *)&ProtectHead=ShortBlock;
|
||||
Raw.Get(ProtectHead.DataSize);
|
||||
Raw.Get(ProtectHead.Version);
|
||||
Raw.Get(ProtectHead.RecSectors);
|
||||
Raw.Get(ProtectHead.TotalBlocks);
|
||||
Raw.Get(ProtectHead.Mark,8);
|
||||
NextBlockPos+=ProtectHead.DataSize;
|
||||
RecoverySectors=ProtectHead.RecSectors;
|
||||
break;
|
||||
case SUB_HEAD:
|
||||
*(BaseBlock *)&SubBlockHead=ShortBlock;
|
||||
Raw.Get(SubBlockHead.DataSize);
|
||||
NextBlockPos+=SubBlockHead.DataSize;
|
||||
Raw.Get(SubBlockHead.SubType);
|
||||
Raw.Get(SubBlockHead.Level);
|
||||
switch(SubBlockHead.SubType)
|
||||
{
|
||||
case UO_HEAD:
|
||||
*(SubBlockHeader *)&UOHead=SubBlockHead;
|
||||
Raw.Get(UOHead.OwnerNameSize);
|
||||
Raw.Get(UOHead.GroupNameSize);
|
||||
if (UOHead.OwnerNameSize>NM-1)
|
||||
UOHead.OwnerNameSize=NM-1;
|
||||
if (UOHead.GroupNameSize>NM-1)
|
||||
UOHead.GroupNameSize=NM-1;
|
||||
Raw.Get((byte *)UOHead.OwnerName,UOHead.OwnerNameSize);
|
||||
Raw.Get((byte *)UOHead.GroupName,UOHead.GroupNameSize);
|
||||
UOHead.OwnerName[UOHead.OwnerNameSize]=0;
|
||||
UOHead.GroupName[UOHead.GroupNameSize]=0;
|
||||
break;
|
||||
case MAC_HEAD:
|
||||
*(SubBlockHeader *)&MACHead=SubBlockHead;
|
||||
Raw.Get(MACHead.fileType);
|
||||
Raw.Get(MACHead.fileCreator);
|
||||
break;
|
||||
case EA_HEAD:
|
||||
case BEEA_HEAD:
|
||||
case NTACL_HEAD:
|
||||
*(SubBlockHeader *)&EAHead=SubBlockHead;
|
||||
Raw.Get(EAHead.UnpSize);
|
||||
Raw.Get(EAHead.UnpVer);
|
||||
Raw.Get(EAHead.Method);
|
||||
Raw.Get(EAHead.EACRC);
|
||||
break;
|
||||
case STREAM_HEAD:
|
||||
*(SubBlockHeader *)&StreamHead=SubBlockHead;
|
||||
Raw.Get(StreamHead.UnpSize);
|
||||
Raw.Get(StreamHead.UnpVer);
|
||||
Raw.Get(StreamHead.Method);
|
||||
Raw.Get(StreamHead.StreamCRC);
|
||||
Raw.Get(StreamHead.StreamNameSize);
|
||||
if (StreamHead.StreamNameSize>NM-1)
|
||||
StreamHead.StreamNameSize=NM-1;
|
||||
Raw.Get((byte *)StreamHead.StreamName,StreamHead.StreamNameSize);
|
||||
StreamHead.StreamName[StreamHead.StreamNameSize]=0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (ShortBlock.Flags & LONG_BLOCK)
|
||||
{
|
||||
uint DataSize;
|
||||
Raw.Get(DataSize);
|
||||
NextBlockPos+=DataSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
HeaderCRC=~Raw.GetCRC(false)&0xffff;
|
||||
CurHeaderType=ShortBlock.HeadType;
|
||||
if (Decrypt)
|
||||
{
|
||||
NextBlockPos+=Raw.PaddedSize()+SALT_SIZE;
|
||||
|
||||
if (ShortBlock.HeadCRC!=HeaderCRC)
|
||||
{
|
||||
bool Recovered=false;
|
||||
if (ShortBlock.HeadType==ENDARC_HEAD && (EndArcHead.Flags & EARC_REVSPACE)!=0)
|
||||
{
|
||||
// Last 7 bytes of recovered volume can contain zeroes, because
|
||||
// REV files store its own information (volume number, etc.) here.
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 Length=Tell();
|
||||
Seek(Length-7,SEEK_SET);
|
||||
Recovered=true;
|
||||
for (int J=0;J<7;J++)
|
||||
if (GetByte()!=0)
|
||||
Recovered=false;
|
||||
}
|
||||
if (!Recovered)
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(FileName,St(MEncrBadCRC),FileName);
|
||||
#endif
|
||||
// Close();
|
||||
FailedHeaderDecryption=true;
|
||||
BrokenFileHeader=true;
|
||||
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NextBlockPos<=CurBlockPos)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MLogFileHead),"???");
|
||||
#endif
|
||||
BrokenFileHeader=true;
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return(0);
|
||||
}
|
||||
return(Raw.Size());
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
size_t Archive::ReadOldHeader()
|
||||
{
|
||||
RawRead Raw(this);
|
||||
if (CurBlockPos<=(int64)SFXSize)
|
||||
{
|
||||
Raw.Read(SIZEOF_OLDMHD);
|
||||
Raw.Get(OldMhd.Mark,4);
|
||||
Raw.Get(OldMhd.HeadSize);
|
||||
Raw.Get(OldMhd.Flags);
|
||||
NextBlockPos=CurBlockPos+OldMhd.HeadSize;
|
||||
CurHeaderType=MAIN_HEAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldFileHeader OldLhd;
|
||||
Raw.Read(SIZEOF_OLDLHD);
|
||||
NewLhd.HeadType=FILE_HEAD;
|
||||
Raw.Get(NewLhd.PackSize);
|
||||
Raw.Get(NewLhd.UnpSize);
|
||||
Raw.Get(OldLhd.FileCRC);
|
||||
Raw.Get(NewLhd.HeadSize);
|
||||
Raw.Get(NewLhd.FileTime);
|
||||
Raw.Get(OldLhd.FileAttr);
|
||||
Raw.Get(OldLhd.Flags);
|
||||
Raw.Get(OldLhd.UnpVer);
|
||||
Raw.Get(OldLhd.NameSize);
|
||||
Raw.Get(OldLhd.Method);
|
||||
|
||||
NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
|
||||
NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
|
||||
NewLhd.Method=OldLhd.Method+0x30;
|
||||
NewLhd.NameSize=OldLhd.NameSize;
|
||||
NewLhd.FileAttr=OldLhd.FileAttr;
|
||||
NewLhd.FileCRC=OldLhd.FileCRC;
|
||||
NewLhd.FullPackSize=NewLhd.PackSize;
|
||||
NewLhd.FullUnpSize=NewLhd.UnpSize;
|
||||
|
||||
NewLhd.mtime.SetDos(NewLhd.FileTime);
|
||||
NewLhd.ctime.Reset();
|
||||
NewLhd.atime.Reset();
|
||||
NewLhd.arctime.Reset();
|
||||
|
||||
Raw.Read(OldLhd.NameSize);
|
||||
Raw.Get((byte *)NewLhd.FileName,OldLhd.NameSize);
|
||||
NewLhd.FileName[OldLhd.NameSize]=0;
|
||||
ConvertNameCase(NewLhd.FileName);
|
||||
*NewLhd.FileNameW=0;
|
||||
|
||||
if (Raw.Size()!=0)
|
||||
NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize;
|
||||
CurHeaderType=FILE_HEAD;
|
||||
}
|
||||
return(NextBlockPos>CurBlockPos ? Raw.Size():0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Archive::ConvertNameCase(char *Name)
|
||||
{
|
||||
if (Cmd->ConvertNames==NAMES_UPPERCASE)
|
||||
{
|
||||
IntToExt(Name,Name);
|
||||
strupper(Name);
|
||||
ExtToInt(Name,Name);
|
||||
}
|
||||
if (Cmd->ConvertNames==NAMES_LOWERCASE)
|
||||
{
|
||||
IntToExt(Name,Name);
|
||||
strlower(Name);
|
||||
ExtToInt(Name,Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void Archive::ConvertNameCase(wchar *Name)
|
||||
{
|
||||
if (Cmd->ConvertNames==NAMES_UPPERCASE)
|
||||
wcsupper(Name);
|
||||
if (Cmd->ConvertNames==NAMES_LOWERCASE)
|
||||
wcslower(Name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Archive::IsArcDir()
|
||||
{
|
||||
return((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY);
|
||||
}
|
||||
|
||||
|
||||
bool Archive::IsArcLabel()
|
||||
{
|
||||
return(NewLhd.HostOS<=HOST_WIN32 && (NewLhd.FileAttr & 8));
|
||||
}
|
||||
|
||||
|
||||
void Archive::ConvertAttributes()
|
||||
{
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
switch(NewLhd.HostOS)
|
||||
{
|
||||
case HOST_MSDOS:
|
||||
case HOST_OS2:
|
||||
case HOST_WIN32:
|
||||
break;
|
||||
case HOST_UNIX:
|
||||
case HOST_BEOS:
|
||||
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||
NewLhd.FileAttr=0x10;
|
||||
else
|
||||
NewLhd.FileAttr=0x20;
|
||||
break;
|
||||
default:
|
||||
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||
NewLhd.FileAttr=0x10;
|
||||
else
|
||||
NewLhd.FileAttr=0x20;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
// umask defines which permission bits must not be set by default
|
||||
// when creating a file or directory. The typical default value
|
||||
// for the process umask is S_IWGRP | S_IWOTH (octal 022),
|
||||
// resulting in 0644 mode for new files.
|
||||
static mode_t mask = (mode_t) -1;
|
||||
|
||||
if (mask == (mode_t) -1)
|
||||
{
|
||||
// umask call returns the current umask value. Argument (022) is not
|
||||
// really important here.
|
||||
mask = umask(022);
|
||||
|
||||
// Restore the original umask value, which was changed to 022 above.
|
||||
umask(mask);
|
||||
}
|
||||
|
||||
switch(NewLhd.HostOS)
|
||||
{
|
||||
case HOST_MSDOS:
|
||||
case HOST_OS2:
|
||||
case HOST_WIN32:
|
||||
{
|
||||
// Mapping MSDOS, OS/2 and Windows file attributes to Unix.
|
||||
|
||||
if (NewLhd.FileAttr & 0x10) // FILE_ATTRIBUTE_DIRECTORY
|
||||
{
|
||||
// For directories we use 0777 mask.
|
||||
NewLhd.FileAttr=0777 & ~mask;
|
||||
}
|
||||
else
|
||||
if (NewLhd.FileAttr & 1) // FILE_ATTRIBUTE_READONLY
|
||||
{
|
||||
// For read only files we use 0444 mask with 'w' bits turned off.
|
||||
NewLhd.FileAttr=0444 & ~mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// umask does not set +x for regular files, so we use 0666
|
||||
// instead of 0777 as for directories.
|
||||
NewLhd.FileAttr=0666 & ~mask;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HOST_UNIX:
|
||||
case HOST_BEOS:
|
||||
break;
|
||||
default:
|
||||
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||
NewLhd.FileAttr=0x41ff & ~mask;
|
||||
else
|
||||
NewLhd.FileAttr=0x81b6 & ~mask;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Archive::ConvertUnknownHeader()
|
||||
{
|
||||
if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10))
|
||||
NewLhd.Flags|=LHD_DIRECTORY;
|
||||
if (NewLhd.HostOS>=HOST_MAX)
|
||||
{
|
||||
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||
NewLhd.FileAttr=0x10;
|
||||
else
|
||||
NewLhd.FileAttr=0x20;
|
||||
}
|
||||
for (char *s=NewLhd.FileName;*s!=0;s=charnext(s))
|
||||
{
|
||||
if (*s=='/' || *s=='\\')
|
||||
*s=CPATHDIVIDER;
|
||||
#if defined(_APPLE) && !defined(UNICODE_SUPPORTED)
|
||||
if ((byte)*s<32 || (byte)*s>127)
|
||||
*s='_';
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
// ':' in file names is allowed in Unix, but not in Windows.
|
||||
// Even worse, file data will be written to NTFS stream on NTFS,
|
||||
// so automatic name correction on file create error in extraction
|
||||
// routine does not work. In Windows and DOS versions we better
|
||||
// replace ':' now.
|
||||
if (*s==':')
|
||||
*s='_';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for (wchar *s=NewLhd.FileNameW;*s!=0;s++)
|
||||
{
|
||||
if (*s=='/' || *s=='\\')
|
||||
*s=CPATHDIVIDER;
|
||||
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
// ':' in file names is allowed in Unix, but not in Windows.
|
||||
// Even worse, file data will be written to NTFS stream on NTFS,
|
||||
// so automatic name correction on file create error in extraction
|
||||
// routine does not work. In Windows and DOS versions we better
|
||||
// replace ':' now.
|
||||
if (*s==':')
|
||||
*s='_';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef SHELL_EXT
|
||||
bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile)
|
||||
{
|
||||
if (HeaderCRC!=SubHead.HeadCRC)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MSubHeadCorrupt));
|
||||
#endif
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return(false);
|
||||
}
|
||||
if (SubHead.Method<0x30 || SubHead.Method>0x35 || SubHead.UnpVer>/*PACK_VER*/36)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MSubHeadUnknown));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (SubHead.PackSize==0 && (SubHead.Flags & LHD_SPLIT_AFTER)==0)
|
||||
return(true);
|
||||
|
||||
SubDataIO.Init();
|
||||
Unpack Unpack(&SubDataIO);
|
||||
Unpack.Init();
|
||||
|
||||
if (DestFile==NULL)
|
||||
{
|
||||
UnpData->Alloc(SubHead.UnpSize);
|
||||
SubDataIO.SetUnpackToMemory(&(*UnpData)[0],SubHead.UnpSize);
|
||||
}
|
||||
if (SubHead.Flags & LHD_PASSWORD)
|
||||
if (Cmd->Password.IsSet())
|
||||
SubDataIO.SetEncryption(SubHead.UnpVer,&Cmd->Password,
|
||||
(SubHead.Flags & LHD_SALT) ? SubHead.Salt:NULL,false,
|
||||
SubHead.UnpVer>=36);
|
||||
else
|
||||
return(false);
|
||||
SubDataIO.SetPackedSizeToRead(SubHead.PackSize);
|
||||
SubDataIO.EnableShowProgress(false);
|
||||
SubDataIO.SetFiles(this,DestFile);
|
||||
SubDataIO.UnpVolume=(SubHead.Flags & LHD_SPLIT_AFTER)!=0;
|
||||
SubDataIO.SetSubHeader(&SubHead,NULL);
|
||||
Unpack.SetDestSize(SubHead.UnpSize);
|
||||
if (SubHead.Method==0x30)
|
||||
CmdExtract::UnstoreFile(SubDataIO,SubHead.UnpSize);
|
||||
else
|
||||
Unpack.DoUnpack(SubHead.UnpVer,false);
|
||||
|
||||
if (SubHead.FileCRC!=~SubDataIO.UnpFileCRC)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MSubHeadDataCRC),SubHead.FileName);
|
||||
#endif
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
if (UnpData!=NULL)
|
||||
UnpData->Reset();
|
||||
return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
@ -1,131 +0,0 @@
|
||||
#ifndef _RAR_ARRAY_
|
||||
#define _RAR_ARRAY_
|
||||
|
||||
extern ErrorHandler ErrHandler;
|
||||
|
||||
template <class T> class Array
|
||||
{
|
||||
private:
|
||||
T *Buffer;
|
||||
size_t BufSize;
|
||||
size_t AllocSize;
|
||||
public:
|
||||
Array();
|
||||
Array(size_t Size);
|
||||
~Array();
|
||||
inline void CleanData();
|
||||
inline T& operator [](size_t Item);
|
||||
inline size_t Size(); // Returns the size in items, not in bytes.
|
||||
void Add(size_t Items);
|
||||
void Alloc(size_t Items);
|
||||
void Reset();
|
||||
void SoftReset();
|
||||
void operator = (Array<T> &Src);
|
||||
void Push(T Item);
|
||||
T* Addr() {return(Buffer);}
|
||||
};
|
||||
|
||||
template <class T> void Array<T>::CleanData()
|
||||
{
|
||||
Buffer=NULL;
|
||||
BufSize=0;
|
||||
AllocSize=0;
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::Array()
|
||||
{
|
||||
CleanData();
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::Array(size_t Size)
|
||||
{
|
||||
Buffer=(T *)malloc(sizeof(T)*Size);
|
||||
if (Buffer==NULL && Size!=0)
|
||||
ErrHandler.MemoryError();
|
||||
|
||||
AllocSize=BufSize=Size;
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::~Array()
|
||||
{
|
||||
if (Buffer!=NULL)
|
||||
free(Buffer);
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T& Array<T>::operator [](size_t Item)
|
||||
{
|
||||
return(Buffer[Item]);
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline size_t Array<T>::Size()
|
||||
{
|
||||
return(BufSize);
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Add(size_t Items)
|
||||
{
|
||||
BufSize+=Items;
|
||||
if (BufSize>AllocSize)
|
||||
{
|
||||
size_t Suggested=AllocSize+AllocSize/4+32;
|
||||
size_t NewSize=Max(BufSize,Suggested);
|
||||
|
||||
Buffer=(T *)realloc(Buffer,NewSize*sizeof(T));
|
||||
if (Buffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
AllocSize=NewSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Alloc(size_t Items)
|
||||
{
|
||||
if (Items>AllocSize)
|
||||
Add(Items-BufSize);
|
||||
else
|
||||
BufSize=Items;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Reset()
|
||||
{
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
free(Buffer);
|
||||
Buffer=NULL;
|
||||
}
|
||||
BufSize=0;
|
||||
AllocSize=0;
|
||||
}
|
||||
|
||||
|
||||
// Reste buffer size, but preserve already allocated memory if any,
|
||||
// so we can reuse it without wasting time to allocation.
|
||||
template <class T> void Array<T>::SoftReset()
|
||||
{
|
||||
BufSize=0;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::operator =(Array<T> &Src)
|
||||
{
|
||||
Reset();
|
||||
Alloc(Src.BufSize);
|
||||
if (Src.BufSize!=0)
|
||||
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Push(T Item)
|
||||
{
|
||||
Add(1);
|
||||
(*this)[Size()-1]=Item;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,113 +0,0 @@
|
||||
|
||||
|
||||
void ExtractBeEA(Archive &Arc,char *FileName)
|
||||
{
|
||||
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
|
||||
{
|
||||
Log(Arc.FileName,St(MEAUnknHeader),FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
ComprDataIO DataIO;
|
||||
Unpack Unpack(&DataIO);
|
||||
Unpack.Init();
|
||||
|
||||
Array<byte> UnpData(Arc.EAHead.UnpSize);
|
||||
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
|
||||
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetFiles(&Arc,NULL);
|
||||
Unpack.SetDestSize(Arc.EAHead.UnpSize);
|
||||
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
|
||||
|
||||
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
int fd = open(FileName,O_WRONLY);
|
||||
if (fd==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
int AttrPos=0;
|
||||
while (AttrPos<Arc.EAHead.UnpSize)
|
||||
{
|
||||
unsigned char *CurItem=&UnpData[AttrPos];
|
||||
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||
char Name[1024];
|
||||
if (NameSize>=sizeof(Name))
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
memcpy(Name,CurItem+10,NameSize);
|
||||
Name[NameSize]=0;
|
||||
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
AttrPos+=10+NameSize+Size;
|
||||
}
|
||||
close(fd);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
|
||||
void ExtractBeEANew(Archive &Arc,char *FileName)
|
||||
{
|
||||
Array<byte> SubData;
|
||||
if (!Arc.ReadSubData(&SubData,NULL))
|
||||
return;
|
||||
|
||||
int fd = open(FileName,O_WRONLY);
|
||||
if (fd==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
int AttrPos=0;
|
||||
while (AttrPos<Arc.EAHead.UnpSize)
|
||||
{
|
||||
unsigned char *CurItem=&SubData[AttrPos];
|
||||
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||
char Name[1024];
|
||||
if (NameSize>=sizeof(Name))
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
memcpy(Name,CurItem+10,NameSize);
|
||||
Name[NameSize]=0;
|
||||
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
AttrPos+=10+NameSize+Size;
|
||||
}
|
||||
close(fd);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,64 +0,0 @@
|
||||
#ifndef _RAR_CMDDATA_
|
||||
#define _RAR_CMDDATA_
|
||||
|
||||
|
||||
#define DefaultStoreList "7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lzh;mp3;rar;taz;tgz;z;zip"
|
||||
|
||||
enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS};
|
||||
|
||||
class CommandData:public RAROptions
|
||||
{
|
||||
private:
|
||||
void ProcessSwitchesString(char *Str);
|
||||
void ProcessSwitch(const char *Switch,const wchar *SwitchW=NULL);
|
||||
void BadSwitch(const char *Switch);
|
||||
bool ExclCheckArgs(StringList *Args,bool Dir,char *CheckName,bool CheckFullPath,int MatchMode);
|
||||
uint GetExclAttr(const char *Str);
|
||||
|
||||
bool FileLists;
|
||||
bool NoMoreSwitches;
|
||||
RAR_CMD_LIST_MODE ListMode;
|
||||
bool BareOutput;
|
||||
public:
|
||||
CommandData();
|
||||
~CommandData();
|
||||
void Init();
|
||||
void Close();
|
||||
|
||||
void PreprocessCommandLine(int argc, char *argv[]);
|
||||
void ParseCommandLine(int argc, char *argv[]);
|
||||
void ParseArg(char *Arg,wchar *ArgW);
|
||||
void ParseDone();
|
||||
void ParseEnvVar();
|
||||
void ReadConfig();
|
||||
bool PreprocessSwitch(const char *Switch);
|
||||
void OutTitle();
|
||||
void OutHelp(RAR_EXIT ExitCode);
|
||||
bool IsSwitch(int Ch);
|
||||
bool ExclCheck(char *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList);
|
||||
bool ExclDirByAttr(uint FileAttr);
|
||||
bool TimeCheck(RarTime &ft);
|
||||
bool SizeCheck(int64 Size);
|
||||
bool AnyFiltersActive();
|
||||
int IsProcessFile(FileHeader &NewLhd,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH);
|
||||
void ProcessCommand();
|
||||
void AddArcName(const char *Name,const wchar *NameW);
|
||||
bool GetArcName(char *Name,wchar *NameW,int MaxSize);
|
||||
bool CheckWinSize();
|
||||
|
||||
int GetRecoverySize(const char *Str,int DefSize);
|
||||
|
||||
char Command[NM+16];
|
||||
wchar CommandW[NM+16];
|
||||
|
||||
char ArcName[NM];
|
||||
wchar ArcNameW[NM];
|
||||
|
||||
StringList *FileArgs;
|
||||
StringList *ExclArgs;
|
||||
StringList *InclArgs;
|
||||
StringList *ArcNames;
|
||||
StringList *StoreArgs;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,48 +0,0 @@
|
||||
|
||||
|
||||
inline unsigned int RangeCoder::GetChar()
|
||||
{
|
||||
return(UnpackRead->GetChar());
|
||||
}
|
||||
|
||||
|
||||
void RangeCoder::InitDecoder(Unpack *UnpackRead)
|
||||
{
|
||||
RangeCoder::UnpackRead=UnpackRead;
|
||||
|
||||
low=code=0;
|
||||
range=uint(-1);
|
||||
for (int i=0;i < 4;i++)
|
||||
code=(code << 8) | GetChar();
|
||||
}
|
||||
|
||||
|
||||
// (int) cast before "low" added only to suppress compiler warnings.
|
||||
#define ARI_DEC_NORMALIZE(code,low,range,read) \
|
||||
{ \
|
||||
while ((low^(low+range))<TOP || range<BOT && ((range=-(int)low&(BOT-1)),1)) \
|
||||
{ \
|
||||
code=(code << 8) | read->GetChar(); \
|
||||
range <<= 8; \
|
||||
low <<= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
inline int RangeCoder::GetCurrentCount()
|
||||
{
|
||||
return (code-low)/(range /= SubRange.scale);
|
||||
}
|
||||
|
||||
|
||||
inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT)
|
||||
{
|
||||
return (code-low)/(range >>= SHIFT);
|
||||
}
|
||||
|
||||
|
||||
inline void RangeCoder::Decode()
|
||||
{
|
||||
low += range*SubRange.LowCount;
|
||||
range *= SubRange.HighCount-SubRange.LowCount;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Contents: 'Carryless rangecoder' by Dmitry Subbotin *
|
||||
****************************************************************************/
|
||||
|
||||
const uint TOP=1 << 24, BOT=1 << 15;
|
||||
|
||||
|
||||
class RangeCoder
|
||||
{
|
||||
public:
|
||||
void InitDecoder(Unpack *UnpackRead);
|
||||
inline int GetCurrentCount();
|
||||
inline uint GetCurrentShiftCount(uint SHIFT);
|
||||
inline void Decode();
|
||||
inline void PutChar(unsigned int c);
|
||||
inline unsigned int GetChar();
|
||||
|
||||
uint low, code, range;
|
||||
struct SUBRANGE
|
||||
{
|
||||
uint LowCount, HighCount, scale;
|
||||
} SubRange;
|
||||
|
||||
Unpack *UnpackRead;
|
||||
};
|
||||
@ -1,40 +0,0 @@
|
||||
#ifndef _RAR_COMPRESS_
|
||||
#define _RAR_COMPRESS_
|
||||
|
||||
class ComprDataIO;
|
||||
class PackingFileTable;
|
||||
|
||||
#define MAX_LZ_MATCH 0x101
|
||||
|
||||
#define MAXWINSIZE 0x400000
|
||||
#define MAXWINMASK (MAXWINSIZE-1)
|
||||
|
||||
#define LOW_DIST_REP_COUNT 16
|
||||
|
||||
#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
#define DC 60
|
||||
#define LDC 17
|
||||
#define RC 28
|
||||
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
|
||||
#define BC 20
|
||||
|
||||
#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
#define DC20 48
|
||||
#define RC20 28
|
||||
#define BC20 19
|
||||
#define MC20 257
|
||||
|
||||
// Largest alphabet size among all values listed above.
|
||||
#define LARGEST_TABLE_SIZE 299
|
||||
|
||||
enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
|
||||
CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA};
|
||||
|
||||
|
||||
enum FilterType {
|
||||
FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
|
||||
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
|
||||
FILTER_ITANIUM, FILTER_E8E9V2
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,319 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifndef GUI
|
||||
#include "log.cpp"
|
||||
#endif
|
||||
|
||||
static int KbdAnsi(char *Addr,int Size);
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
static void RawPrint(char *Msg,MESSAGE_TYPE MessageType);
|
||||
static byte GetKey();
|
||||
#endif
|
||||
|
||||
static MESSAGE_TYPE MsgStream=MSG_STDOUT;
|
||||
static bool Sound=false;
|
||||
const int MaxMsgSize=2*NM+2048;
|
||||
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound)
|
||||
{
|
||||
::MsgStream=MsgStream;
|
||||
::Sound=Sound;
|
||||
}
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
void mprintf(const char *fmt,...)
|
||||
{
|
||||
if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY)
|
||||
return;
|
||||
char Msg[MaxMsgSize];
|
||||
va_list argptr;
|
||||
va_start(argptr,fmt);
|
||||
vsnprintf(Msg,ASIZE(Msg),fmt,argptr);
|
||||
|
||||
// Different vsnprintf implementation can return either -1 or >=MaxMsgSize
|
||||
// if string is truncated. So we do not check exit code and always zero
|
||||
// terminate the string for safety. It is faster than check for error.
|
||||
Msg[ASIZE(Msg)-1] = 0;
|
||||
|
||||
RawPrint(Msg,MsgStream);
|
||||
va_end(argptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
void eprintf(const char *fmt,...)
|
||||
{
|
||||
if (MsgStream==MSG_NULL)
|
||||
return;
|
||||
safebuf char Msg[MaxMsgSize];
|
||||
va_list argptr;
|
||||
va_start(argptr,fmt);
|
||||
vsnprintf(Msg,ASIZE(Msg),fmt,argptr);
|
||||
|
||||
// Different vsnprintf implementation can return either -1 or >=MaxMsgSize
|
||||
// if string is truncated. So we do not check exit code and always zero
|
||||
// terminate the string for safety. It is faster than check for error.
|
||||
Msg[ASIZE(Msg)-1] = 0;
|
||||
|
||||
RawPrint(Msg,MSG_STDERR);
|
||||
va_end(argptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
void RawPrint(char *Msg,MESSAGE_TYPE MessageType)
|
||||
{
|
||||
File OutFile;
|
||||
switch(MessageType)
|
||||
{
|
||||
case MSG_STDOUT:
|
||||
OutFile.SetHandleType(FILE_HANDLESTD);
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
case MSG_ERRONLY:
|
||||
OutFile.SetHandleType(FILE_HANDLEERR);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
#ifdef _WIN_ALL
|
||||
CharToOemA(Msg,Msg);
|
||||
|
||||
char OutMsg[MaxMsgSize];
|
||||
size_t OutPos=0;
|
||||
for (size_t I=0;Msg[I]!=0;I++)
|
||||
{
|
||||
if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r') && OutPos<ASIZE(OutMsg)-1)
|
||||
OutMsg[OutPos++]='\r';
|
||||
if (OutPos<ASIZE(OutMsg)-1)
|
||||
OutMsg[OutPos++]=Msg[I];
|
||||
}
|
||||
OutMsg[OutPos]=0;
|
||||
strcpy(Msg,OutMsg);
|
||||
#endif
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
char OutMsg[MaxMsgSize],*OutPos=OutMsg;
|
||||
for (size_t I=0;Msg[I]!=0;I++)
|
||||
if (Msg[I]!='\r')
|
||||
*(OutPos++)=Msg[I];
|
||||
*OutPos=0;
|
||||
strcpy(Msg,OutMsg);
|
||||
#endif
|
||||
|
||||
OutFile.Write(Msg,strlen(Msg));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
void Alarm()
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
if (Sound)
|
||||
putchar('\007');
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
#ifndef GUI
|
||||
void GetPasswordText(wchar *Str,uint MaxLength)
|
||||
{
|
||||
if (MaxLength==0)
|
||||
return;
|
||||
#ifdef _WIN_ALL
|
||||
HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD ConInMode,ConOutMode;
|
||||
DWORD Read=0;
|
||||
GetConsoleMode(hConIn,&ConInMode);
|
||||
GetConsoleMode(hConOut,&ConOutMode);
|
||||
SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
|
||||
SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||
|
||||
ReadConsoleW(hConIn,Str,MaxLength-1,&Read,NULL);
|
||||
Str[Read]=0;
|
||||
SetConsoleMode(hConIn,ConInMode);
|
||||
SetConsoleMode(hConOut,ConOutMode);
|
||||
#else
|
||||
char StrA[MAXPASSWORD];
|
||||
#if defined(_EMX) || defined(_BEOS) || defined(__sparc) || defined(sparc) || defined (__VMS)
|
||||
fgets(StrA,ASIZE(StrA)-1,stdin);
|
||||
#else
|
||||
strncpyz(StrA,getpass(""),ASIZE(StrA));
|
||||
#endif
|
||||
CharToWide(StrA,Str,MaxLength);
|
||||
cleandata(StrA,sizeof(StrA));
|
||||
#endif
|
||||
Str[MaxLength-1]=0;
|
||||
RemoveLF(Str);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,const wchar *FileNameW,
|
||||
SecPassword *Password)
|
||||
{
|
||||
Alarm();
|
||||
while (true)
|
||||
{
|
||||
char PromptStr[NM+256];
|
||||
#if defined(_EMX) || defined(_BEOS)
|
||||
strcpy(PromptStr,St(MAskPswEcho));
|
||||
#else
|
||||
strcpy(PromptStr,St(MAskPsw));
|
||||
#endif
|
||||
if (Type!=PASSWORD_GLOBAL)
|
||||
{
|
||||
strcat(PromptStr,St(MFor));
|
||||
char *NameOnly=PointToName(FileName);
|
||||
if (strlen(PromptStr)+strlen(NameOnly)<ASIZE(PromptStr))
|
||||
strcat(PromptStr,NameOnly);
|
||||
}
|
||||
eprintf("\n%s: ",PromptStr);
|
||||
|
||||
wchar PlainPsw[MAXPASSWORD];
|
||||
GetPasswordText(PlainPsw,ASIZE(PlainPsw));
|
||||
if (*PlainPsw==0 && Type==PASSWORD_GLOBAL)
|
||||
return(false);
|
||||
if (Type==PASSWORD_GLOBAL)
|
||||
{
|
||||
eprintf(St(MReAskPsw));
|
||||
wchar CmpStr[MAXPASSWORD];
|
||||
GetPasswordText(CmpStr,ASIZE(CmpStr));
|
||||
if (*CmpStr==0 || wcscmp(PlainPsw,CmpStr)!=0)
|
||||
{
|
||||
eprintf(St(MNotMatchPsw));
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
cleandata(CmpStr,sizeof(CmpStr));
|
||||
continue;
|
||||
}
|
||||
cleandata(CmpStr,sizeof(CmpStr));
|
||||
}
|
||||
Password->Set(PlainPsw);
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
break;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
byte GetKey()
|
||||
{
|
||||
char Str[80];
|
||||
bool EndOfFile;
|
||||
#if defined(__GNUC__) || defined(sun)
|
||||
EndOfFile=(fgets(Str,sizeof(Str),stdin)==NULL);
|
||||
#else
|
||||
File SrcFile;
|
||||
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||
EndOfFile=(SrcFile.Read(Str,sizeof(Str))==0);
|
||||
#endif
|
||||
if (EndOfFile)
|
||||
{
|
||||
// Looks like stdin is a null device. We can enter to infinite loop
|
||||
// calling Ask(), so let's better exit.
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
return (byte)Str[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
int Ask(const char *AskStr)
|
||||
{
|
||||
const int MaxItems=10;
|
||||
char Item[MaxItems][40];
|
||||
int ItemKeyPos[MaxItems],NumItems=0;
|
||||
|
||||
for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_'))
|
||||
{
|
||||
char *CurItem=Item[NumItems];
|
||||
strncpyz(CurItem,NextItem+1,ASIZE(Item[0]));
|
||||
char *EndItem=strchr(CurItem,'_');
|
||||
if (EndItem!=NULL)
|
||||
*EndItem=0;
|
||||
int KeyPos=0,CurKey;
|
||||
while ((CurKey=CurItem[KeyPos])!=0)
|
||||
{
|
||||
bool Found=false;
|
||||
for (int I=0;I<NumItems && !Found;I++)
|
||||
if (loctoupper(Item[I][ItemKeyPos[I]])==loctoupper(CurKey))
|
||||
Found=true;
|
||||
if (!Found && CurKey!=' ')
|
||||
break;
|
||||
KeyPos++;
|
||||
}
|
||||
ItemKeyPos[NumItems]=KeyPos;
|
||||
NumItems++;
|
||||
}
|
||||
|
||||
for (int I=0;I<NumItems;I++)
|
||||
{
|
||||
eprintf(I==0 ? (NumItems>4 ? "\n":" "):", ");
|
||||
int KeyPos=ItemKeyPos[I];
|
||||
for (int J=0;J<KeyPos;J++)
|
||||
eprintf("%c",Item[I][J]);
|
||||
eprintf("[%c]%s",Item[I][KeyPos],&Item[I][KeyPos+1]);
|
||||
}
|
||||
eprintf(" ");
|
||||
byte Ch=GetKey();
|
||||
#if defined(_WIN_ALL)
|
||||
OemToCharBuffA((LPCSTR)&Ch,(LPSTR)&Ch,1);
|
||||
#endif
|
||||
Ch=loctoupper(Ch);
|
||||
for (int I=0;I<NumItems;I++)
|
||||
if (Ch==(byte)Item[I][ItemKeyPos[I]])
|
||||
return(I+1);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int KbdAnsi(char *Addr,size_t Size)
|
||||
{
|
||||
int RetCode=0;
|
||||
#ifndef GUI
|
||||
for (size_t I=0;I<Size;I++)
|
||||
if (Addr[I]==27 && Addr[I+1]=='[')
|
||||
{
|
||||
for (size_t J=I+2;J<Size;J++)
|
||||
{
|
||||
if (Addr[J]=='\"')
|
||||
return(2);
|
||||
if (!IsDigit(Addr[J]) && Addr[J]!=';')
|
||||
break;
|
||||
}
|
||||
RetCode=1;
|
||||
}
|
||||
#endif
|
||||
return(RetCode);
|
||||
}
|
||||
|
||||
|
||||
void OutComment(char *Comment,size_t Size)
|
||||
{
|
||||
#ifndef GUI
|
||||
if (KbdAnsi(Comment,Size)==2)
|
||||
return;
|
||||
const size_t MaxOutSize=0x400;
|
||||
for (size_t I=0;I<Size;I+=MaxOutSize)
|
||||
{
|
||||
char Msg[MaxOutSize+1];
|
||||
size_t CopySize=Min(MaxOutSize,Size-I);
|
||||
strncpy(Msg,Comment+I,CopySize);
|
||||
Msg[CopySize]=0;
|
||||
mprintf("%s",Msg);
|
||||
}
|
||||
mprintf("\n");
|
||||
#endif
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
#ifndef _RAR_CONSIO_
|
||||
#define _RAR_CONSIO_
|
||||
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
enum {SOUND_OK,SOUND_ALARM,SOUND_ERROR,SOUND_QUESTION};
|
||||
#endif
|
||||
|
||||
enum PASSWORD_TYPE {PASSWORD_GLOBAL,PASSWORD_FILE,PASSWORD_ARCHIVE};
|
||||
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound);
|
||||
|
||||
#ifndef SILENT
|
||||
void mprintf(const char *fmt,...);
|
||||
void eprintf(const char *fmt,...);
|
||||
void Alarm();
|
||||
void GetPasswordText(wchar *Str,uint MaxLength);
|
||||
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,const wchar *FileNameW,SecPassword *Password);
|
||||
int Ask(const char *AskStr);
|
||||
#endif
|
||||
|
||||
void OutComment(char *Comment,size_t Size);
|
||||
|
||||
#ifdef SILENT
|
||||
#ifdef __GNUC__
|
||||
#define mprintf(args...)
|
||||
#define eprintf(args...)
|
||||
#else
|
||||
inline void mprintf(const char *fmt,...) {}
|
||||
inline void eprintf(const char *fmt,...) {}
|
||||
#endif
|
||||
inline void Alarm() {}
|
||||
inline void GetPasswordText(wchar *Str,uint MaxLength) {}
|
||||
inline bool GetPassword(PASSWORD_TYPE Type,const char *FileName,const wchar *FileNameW,SecPassword *Password) {return(false);}
|
||||
inline int Ask(const char *AskStr) {return(0);}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,91 +0,0 @@
|
||||
// This CRC function is based on Intel Slicing-by-8 algorithm.
|
||||
//
|
||||
// Original Intel Slicing-by-8 code is available here:
|
||||
//
|
||||
// http://sourceforge.net/projects/slicing-by-8/
|
||||
//
|
||||
// Original Intel Slicing-by-8 code is licensed as:
|
||||
//
|
||||
// Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved
|
||||
//
|
||||
// This software program is licensed subject to the BSD License,
|
||||
// available at http://www.opensource.org/licenses/bsd-license.html
|
||||
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
// CRCTab duplicates crc_tables[0], but we still need it to decrypt
|
||||
// old version RAR archives. GUI code might use it for ZIP encryption.
|
||||
uint CRCTab[256];
|
||||
|
||||
static uint crc_tables[8][256]; // Tables for Slicing-by-8.
|
||||
|
||||
void InitCRC()
|
||||
{
|
||||
for (uint I=0;I<256;I++) // Build the classic CRC32 lookup table.
|
||||
{
|
||||
uint C=I;
|
||||
for (uint J=0;J<8;J++)
|
||||
C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1);
|
||||
CRCTab[I]=crc_tables[0][I]=C;
|
||||
}
|
||||
|
||||
for (uint I=0;I<256;I++) // Build additional lookup tables.
|
||||
{
|
||||
uint C=crc_tables[0][I];
|
||||
for (uint J=1;J<8;J++)
|
||||
{
|
||||
C=crc_tables[0][(byte)C]^(C>>8);
|
||||
crc_tables[J][I]=C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint CRC(uint StartCRC,const void *Addr,size_t Size)
|
||||
{
|
||||
if (CRCTab[1]==0)
|
||||
InitCRC();
|
||||
byte *Data=(byte *)Addr;
|
||||
|
||||
// Align Data to 8 for better performance.
|
||||
for (;Size>0 && ((long)Data & 7);Size--,Data++)
|
||||
StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
|
||||
|
||||
for (;Size>=8;Size-=8,Data+=8)
|
||||
{
|
||||
#ifdef BIG_ENDIAN
|
||||
StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24);
|
||||
#else
|
||||
StartCRC ^= *(uint32 *) Data;
|
||||
#endif
|
||||
StartCRC = crc_tables[7][(byte) StartCRC ] ^
|
||||
crc_tables[6][(byte)(StartCRC >> 8) ] ^
|
||||
crc_tables[5][(byte)(StartCRC >> 16)] ^
|
||||
crc_tables[4][(byte)(StartCRC >> 24)] ^
|
||||
crc_tables[3][Data[4]] ^
|
||||
crc_tables[2][Data[5]] ^
|
||||
crc_tables[1][Data[6]] ^
|
||||
crc_tables[0][Data[7]];
|
||||
}
|
||||
|
||||
for (;Size>0;Size--,Data++) // Process left data.
|
||||
StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
|
||||
|
||||
return(StartCRC);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// For RAR 1.4 archives in case somebody still has them.
|
||||
ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size)
|
||||
{
|
||||
byte *Data=(byte *)Addr;
|
||||
for (size_t I=0;I<Size;I++)
|
||||
{
|
||||
StartCRC=(StartCRC+Data[I])&0xffff;
|
||||
StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
|
||||
}
|
||||
return(StartCRC);
|
||||
}
|
||||
#endif
|
||||
@ -1,8 +0,0 @@
|
||||
#ifndef _RAR_CRC_
|
||||
#define _RAR_CRC_
|
||||
|
||||
void InitCRC();
|
||||
uint CRC(uint StartCRC,const void *Addr,size_t Size);
|
||||
ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size);
|
||||
|
||||
#endif
|
||||
@ -1,387 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
extern uint CRCTab[256];
|
||||
#endif
|
||||
|
||||
#define NROUNDS 32
|
||||
|
||||
#define rol(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
|
||||
#define ror(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
|
||||
|
||||
#define substLong(t) ( (uint)SubstTable[(uint)t&255] | \
|
||||
((uint)SubstTable[(int)(t>> 8)&255]<< 8) | \
|
||||
((uint)SubstTable[(int)(t>>16)&255]<<16) | \
|
||||
((uint)SubstTable[(int)(t>>24)&255]<<24) )
|
||||
|
||||
CryptKeyCacheItem CryptData::Cache[4];
|
||||
int CryptData::CachePos=0;
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
static byte InitSubstTable[256]={
|
||||
215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42,
|
||||
232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137,
|
||||
255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6,
|
||||
71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235,
|
||||
107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36,
|
||||
158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251,
|
||||
97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11,
|
||||
164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51,
|
||||
207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7,
|
||||
122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80,
|
||||
131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129,
|
||||
224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10,
|
||||
118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108,
|
||||
161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225,
|
||||
0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52,
|
||||
116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void CryptData::DecryptBlock(byte *Buf,size_t Size)
|
||||
{
|
||||
rin.blockDecrypt(Buf,Size,Buf);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void CryptData::EncryptBlock20(byte *Buf)
|
||||
{
|
||||
uint A,B,C,D,T,TA,TB;
|
||||
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
|
||||
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
|
||||
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
|
||||
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
|
||||
#else
|
||||
uint32 *BufPtr=(uint32 *)Buf;
|
||||
A=BufPtr[0]^Key[0];
|
||||
B=BufPtr[1]^Key[1];
|
||||
C=BufPtr[2]^Key[2];
|
||||
D=BufPtr[3]^Key[3];
|
||||
#endif
|
||||
for(int I=0;I<NROUNDS;I++)
|
||||
{
|
||||
T=((C+rol(D,11,32))^Key[I&3]);
|
||||
TA=A^substLong(T);
|
||||
T=((D^rol(C,17,32))+Key[I&3]);
|
||||
TB=B^substLong(T);
|
||||
A=C;
|
||||
B=D;
|
||||
C=TA;
|
||||
D=TB;
|
||||
}
|
||||
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||
C^=Key[0];
|
||||
Buf[0]=(byte)C;
|
||||
Buf[1]=(byte)(C>>8);
|
||||
Buf[2]=(byte)(C>>16);
|
||||
Buf[3]=(byte)(C>>24);
|
||||
D^=Key[1];
|
||||
Buf[4]=(byte)D;
|
||||
Buf[5]=(byte)(D>>8);
|
||||
Buf[6]=(byte)(D>>16);
|
||||
Buf[7]=(byte)(D>>24);
|
||||
A^=Key[2];
|
||||
Buf[8]=(byte)A;
|
||||
Buf[9]=(byte)(A>>8);
|
||||
Buf[10]=(byte)(A>>16);
|
||||
Buf[11]=(byte)(A>>24);
|
||||
B^=Key[3];
|
||||
Buf[12]=(byte)B;
|
||||
Buf[13]=(byte)(B>>8);
|
||||
Buf[14]=(byte)(B>>16);
|
||||
Buf[15]=(byte)(B>>24);
|
||||
#else
|
||||
BufPtr[0]=C^Key[0];
|
||||
BufPtr[1]=D^Key[1];
|
||||
BufPtr[2]=A^Key[2];
|
||||
BufPtr[3]=B^Key[3];
|
||||
#endif
|
||||
UpdKeys(Buf);
|
||||
}
|
||||
|
||||
|
||||
void CryptData::DecryptBlock20(byte *Buf)
|
||||
{
|
||||
byte InBuf[16];
|
||||
uint A,B,C,D,T,TA,TB;
|
||||
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
|
||||
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
|
||||
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
|
||||
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
|
||||
#else
|
||||
uint32 *BufPtr=(uint32 *)Buf;
|
||||
A=BufPtr[0]^Key[0];
|
||||
B=BufPtr[1]^Key[1];
|
||||
C=BufPtr[2]^Key[2];
|
||||
D=BufPtr[3]^Key[3];
|
||||
#endif
|
||||
memcpy(InBuf,Buf,sizeof(InBuf));
|
||||
for(int I=NROUNDS-1;I>=0;I--)
|
||||
{
|
||||
T=((C+rol(D,11,32))^Key[I&3]);
|
||||
TA=A^substLong(T);
|
||||
T=((D^rol(C,17,32))+Key[I&3]);
|
||||
TB=B^substLong(T);
|
||||
A=C;
|
||||
B=D;
|
||||
C=TA;
|
||||
D=TB;
|
||||
}
|
||||
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||
C^=Key[0];
|
||||
Buf[0]=(byte)C;
|
||||
Buf[1]=(byte)(C>>8);
|
||||
Buf[2]=(byte)(C>>16);
|
||||
Buf[3]=(byte)(C>>24);
|
||||
D^=Key[1];
|
||||
Buf[4]=(byte)D;
|
||||
Buf[5]=(byte)(D>>8);
|
||||
Buf[6]=(byte)(D>>16);
|
||||
Buf[7]=(byte)(D>>24);
|
||||
A^=Key[2];
|
||||
Buf[8]=(byte)A;
|
||||
Buf[9]=(byte)(A>>8);
|
||||
Buf[10]=(byte)(A>>16);
|
||||
Buf[11]=(byte)(A>>24);
|
||||
B^=Key[3];
|
||||
Buf[12]=(byte)B;
|
||||
Buf[13]=(byte)(B>>8);
|
||||
Buf[14]=(byte)(B>>16);
|
||||
Buf[15]=(byte)(B>>24);
|
||||
#else
|
||||
BufPtr[0]=C^Key[0];
|
||||
BufPtr[1]=D^Key[1];
|
||||
BufPtr[2]=A^Key[2];
|
||||
BufPtr[3]=B^Key[3];
|
||||
#endif
|
||||
UpdKeys(InBuf);
|
||||
}
|
||||
|
||||
|
||||
void CryptData::UpdKeys(byte *Buf)
|
||||
{
|
||||
for (int I=0;I<16;I+=4)
|
||||
{
|
||||
Key[0]^=CRCTab[Buf[I]];
|
||||
Key[1]^=CRCTab[Buf[I+1]];
|
||||
Key[2]^=CRCTab[Buf[I+2]];
|
||||
Key[3]^=CRCTab[Buf[I+3]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryptData::Swap(byte *Ch1,byte *Ch2)
|
||||
{
|
||||
byte Ch=*Ch1;
|
||||
*Ch1=*Ch2;
|
||||
*Ch2=Ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void CryptData::SetCryptKeys(SecPassword *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash)
|
||||
{
|
||||
if (!Password->IsSet())
|
||||
return;
|
||||
wchar PlainPsw[MAXPASSWORD];
|
||||
Password->Get(PlainPsw,ASIZE(PlainPsw));
|
||||
if (OldOnly)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
if (CRCTab[1]==0)
|
||||
InitCRC();
|
||||
char Psw[MAXPASSWORD];
|
||||
memset(Psw,0,sizeof(Psw));
|
||||
|
||||
// We need to use ASCII password for older encryption algorithms.
|
||||
WideToChar(PlainPsw,Psw,ASIZE(Psw));
|
||||
Psw[ASIZE(Psw)-1]=0;
|
||||
|
||||
size_t PswLength=strlen(Psw);
|
||||
|
||||
SetOldKeys(Psw);
|
||||
Key[0]=0xD3A3B879L;
|
||||
Key[1]=0x3F6D12F7L;
|
||||
Key[2]=0x7515A235L;
|
||||
Key[3]=0xA4E7F123L;
|
||||
|
||||
memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
|
||||
for (int J=0;J<256;J++)
|
||||
for (size_t I=0;I<PswLength;I+=2)
|
||||
{
|
||||
uint N1=(byte)CRCTab [ (byte(Psw[I]) - J) &0xff];
|
||||
uint N2=(byte)CRCTab [ (byte(Psw[I+1]) + J) &0xff];
|
||||
for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++)
|
||||
Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]);
|
||||
}
|
||||
for (size_t I=0;I<PswLength;I+=16)
|
||||
EncryptBlock20((byte *)&Psw[I]);
|
||||
cleandata(Psw,sizeof(Psw));
|
||||
#endif
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
return;
|
||||
}
|
||||
|
||||
bool Cached=false;
|
||||
for (uint I=0;I<ASIZE(Cache);I++)
|
||||
if (Cache[I].Password==*Password &&
|
||||
(Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
|
||||
Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0) &&
|
||||
Cache[I].HandsOffHash==HandsOffHash)
|
||||
{
|
||||
memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
|
||||
memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
|
||||
Cached=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Cached)
|
||||
{
|
||||
byte RawPsw[2*MAXPASSWORD+SALT_SIZE];
|
||||
WideToRaw(PlainPsw,RawPsw);
|
||||
size_t RawLength=2*wcslen(PlainPsw);
|
||||
if (Salt!=NULL)
|
||||
{
|
||||
memcpy(RawPsw+RawLength,Salt,SALT_SIZE);
|
||||
RawLength+=SALT_SIZE;
|
||||
}
|
||||
hash_context c;
|
||||
hash_initial(&c);
|
||||
|
||||
const int HashRounds=0x40000;
|
||||
for (int I=0;I<HashRounds;I++)
|
||||
{
|
||||
hash_process( &c, RawPsw, RawLength, HandsOffHash);
|
||||
byte PswNum[3];
|
||||
PswNum[0]=(byte)I;
|
||||
PswNum[1]=(byte)(I>>8);
|
||||
PswNum[2]=(byte)(I>>16);
|
||||
hash_process( &c, PswNum, 3, HandsOffHash);
|
||||
if (I%(HashRounds/16)==0)
|
||||
{
|
||||
hash_context tempc=c;
|
||||
uint32 digest[5];
|
||||
hash_final( &tempc, digest, HandsOffHash);
|
||||
AESInit[I/(HashRounds/16)]=(byte)digest[4];
|
||||
}
|
||||
}
|
||||
uint32 digest[5];
|
||||
hash_final( &c, digest, HandsOffHash);
|
||||
for (int I=0;I<4;I++)
|
||||
for (int J=0;J<4;J++)
|
||||
AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
|
||||
|
||||
Cache[CachePos].Password=*Password;
|
||||
if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
|
||||
memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE);
|
||||
Cache[CachePos].HandsOffHash=HandsOffHash;
|
||||
memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
|
||||
memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
|
||||
CachePos=(CachePos+1)%ASIZE(Cache);
|
||||
|
||||
cleandata(RawPsw,sizeof(RawPsw));
|
||||
}
|
||||
rin.init(Encrypt ? Rijndael::Encrypt : Rijndael::Decrypt,AESKey,AESInit);
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void CryptData::SetOldKeys(const char *Password)
|
||||
{
|
||||
uint PswCRC=CRC(0xffffffff,Password,strlen(Password));
|
||||
OldKey[0]=PswCRC&0xffff;
|
||||
OldKey[1]=(PswCRC>>16)&0xffff;
|
||||
OldKey[2]=OldKey[3]=0;
|
||||
PN1=PN2=PN3=0;
|
||||
byte Ch;
|
||||
while ((Ch=*Password)!=0)
|
||||
{
|
||||
PN1+=Ch;
|
||||
PN2^=Ch;
|
||||
PN3+=Ch;
|
||||
PN3=(byte)rol(PN3,1,8);
|
||||
OldKey[2]^=Ch^CRCTab[Ch];
|
||||
OldKey[3]+=Ch+(CRCTab[Ch]>>16);
|
||||
Password++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryptData::SetAV15Encryption()
|
||||
{
|
||||
OldKey[0]=0x4765;
|
||||
OldKey[1]=0x9021;
|
||||
OldKey[2]=0x7382;
|
||||
OldKey[3]=0x5215;
|
||||
}
|
||||
|
||||
|
||||
void CryptData::SetCmt13Encryption()
|
||||
{
|
||||
PN1=0;
|
||||
PN2=7;
|
||||
PN3=77;
|
||||
}
|
||||
|
||||
|
||||
void CryptData::Crypt(byte *Data,uint Count,int Method)
|
||||
{
|
||||
if (Method==OLD_DECODE)
|
||||
Decode13(Data,Count);
|
||||
else
|
||||
if (Method==OLD_ENCODE)
|
||||
Encode13(Data,Count);
|
||||
else
|
||||
Crypt15(Data,Count);
|
||||
}
|
||||
|
||||
|
||||
void CryptData::Encode13(byte *Data,uint Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
PN2+=PN3;
|
||||
PN1+=PN2;
|
||||
*Data+=PN1;
|
||||
Data++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryptData::Decode13(byte *Data,uint Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
PN2+=PN3;
|
||||
PN1+=PN2;
|
||||
*Data-=PN1;
|
||||
Data++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryptData::Crypt15(byte *Data,uint Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
OldKey[0]+=0x1234;
|
||||
OldKey[1]^=CRCTab[(OldKey[0] & 0x1fe)>>1];
|
||||
OldKey[2]-=CRCTab[(OldKey[0] & 0x1fe)>>1]>>16;
|
||||
OldKey[0]^=OldKey[2];
|
||||
OldKey[3]=ror(OldKey[3]&0xffff,1,16)^OldKey[1];
|
||||
OldKey[3]=ror(OldKey[3]&0xffff,1,16);
|
||||
OldKey[0]^=OldKey[3];
|
||||
*Data^=(byte)(OldKey[0]>>8);
|
||||
Data++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
#ifndef _RAR_CRYPT_
|
||||
#define _RAR_CRYPT_
|
||||
|
||||
enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 };
|
||||
|
||||
|
||||
struct CryptKeyCacheItem
|
||||
{
|
||||
#ifndef _SFX_RTL_
|
||||
CryptKeyCacheItem()
|
||||
{
|
||||
Password.Set(L"");
|
||||
}
|
||||
|
||||
~CryptKeyCacheItem()
|
||||
{
|
||||
memset(AESKey,0,sizeof(AESKey));
|
||||
memset(AESInit,0,sizeof(AESInit));
|
||||
memset(&Password,0,sizeof(Password));
|
||||
}
|
||||
#endif
|
||||
byte AESKey[16],AESInit[16];
|
||||
SecPassword Password;
|
||||
bool SaltPresent;
|
||||
byte Salt[SALT_SIZE];
|
||||
bool HandsOffHash;
|
||||
};
|
||||
|
||||
class CryptData
|
||||
{
|
||||
private:
|
||||
void Encode13(byte *Data,uint Count);
|
||||
void Decode13(byte *Data,uint Count);
|
||||
void Crypt15(byte *Data,uint Count);
|
||||
void UpdKeys(byte *Buf);
|
||||
void Swap(byte *Ch1,byte *Ch2);
|
||||
void SetOldKeys(const char *Password);
|
||||
|
||||
Rijndael rin;
|
||||
|
||||
byte SubstTable[256];
|
||||
uint Key[4];
|
||||
ushort OldKey[4];
|
||||
byte PN1,PN2,PN3;
|
||||
|
||||
byte AESKey[16],AESInit[16];
|
||||
|
||||
static CryptKeyCacheItem Cache[4];
|
||||
static int CachePos;
|
||||
public:
|
||||
void SetCryptKeys(SecPassword *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash);
|
||||
void SetAV15Encryption();
|
||||
void SetCmt13Encryption();
|
||||
void EncryptBlock20(byte *Buf);
|
||||
void DecryptBlock20(byte *Buf);
|
||||
void EncryptBlock(byte *Buf,size_t Size);
|
||||
void DecryptBlock(byte *Buf,size_t Size);
|
||||
void Crypt(byte *Data,uint Count,int Method);
|
||||
static void SetSalt(byte *Salt,int SaltSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,375 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
#include "dll.hpp"
|
||||
|
||||
static int RarErrorToDll(RAR_EXIT ErrCode);
|
||||
|
||||
struct DataSet
|
||||
{
|
||||
CommandData Cmd;
|
||||
CmdExtract Extract;
|
||||
Archive Arc;
|
||||
int OpenMode;
|
||||
int HeaderSize;
|
||||
|
||||
DataSet():Arc(&Cmd) {};
|
||||
};
|
||||
|
||||
|
||||
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *r)
|
||||
{
|
||||
RAROpenArchiveDataEx rx;
|
||||
memset(&rx,0,sizeof(rx));
|
||||
rx.ArcName=r->ArcName;
|
||||
rx.OpenMode=r->OpenMode;
|
||||
rx.CmtBuf=r->CmtBuf;
|
||||
rx.CmtBufSize=r->CmtBufSize;
|
||||
HANDLE hArc=RAROpenArchiveEx(&rx);
|
||||
r->OpenResult=rx.OpenResult;
|
||||
r->CmtSize=rx.CmtSize;
|
||||
r->CmtState=rx.CmtState;
|
||||
return(hArc);
|
||||
}
|
||||
|
||||
|
||||
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||
{
|
||||
DataSet *Data=NULL;
|
||||
try
|
||||
{
|
||||
r->OpenResult=0;
|
||||
Data=new DataSet;
|
||||
Data->Cmd.DllError=0;
|
||||
Data->OpenMode=r->OpenMode;
|
||||
Data->Cmd.FileArgs->AddString("*");
|
||||
|
||||
char an[NM];
|
||||
if (r->ArcName==NULL && r->ArcNameW!=NULL)
|
||||
{
|
||||
WideToChar(r->ArcNameW,an,NM);
|
||||
r->ArcName=an;
|
||||
}
|
||||
|
||||
Data->Cmd.AddArcName(r->ArcName,r->ArcNameW);
|
||||
Data->Cmd.Overwrite=OVERWRITE_ALL;
|
||||
Data->Cmd.VersionControl=1;
|
||||
|
||||
Data->Cmd.Callback=r->Callback;
|
||||
Data->Cmd.UserData=r->UserData;
|
||||
|
||||
if (!Data->Arc.Open(r->ArcName,r->ArcNameW,0))
|
||||
{
|
||||
r->OpenResult=ERAR_EOPEN;
|
||||
delete Data;
|
||||
return(NULL);
|
||||
}
|
||||
if (!Data->Arc.IsArchive(false))
|
||||
{
|
||||
r->OpenResult=Data->Cmd.DllError!=0 ? Data->Cmd.DllError:ERAR_BAD_ARCHIVE;
|
||||
delete Data;
|
||||
return(NULL);
|
||||
}
|
||||
r->Flags=Data->Arc.NewMhd.Flags;
|
||||
Array<byte> CmtData;
|
||||
if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtData,NULL))
|
||||
{
|
||||
r->Flags|=2;
|
||||
size_t Size=CmtData.Size()+1;
|
||||
r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
|
||||
r->CmtSize=(uint)Min(Size,r->CmtBufSize);
|
||||
memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
|
||||
if (Size<=r->CmtBufSize)
|
||||
r->CmtBuf[r->CmtSize-1]=0;
|
||||
}
|
||||
else
|
||||
r->CmtState=r->CmtSize=0;
|
||||
if (Data->Arc.Signed)
|
||||
r->Flags|=0x20;
|
||||
Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc);
|
||||
return((HANDLE)Data);
|
||||
}
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
if (Data!=NULL && Data->Cmd.DllError!=0)
|
||||
r->OpenResult=Data->Cmd.DllError;
|
||||
else
|
||||
r->OpenResult=RarErrorToDll(ErrCode);
|
||||
if (Data != NULL)
|
||||
delete Data;
|
||||
return(NULL);
|
||||
}
|
||||
catch (std::bad_alloc) // Catch 'new' exception.
|
||||
{
|
||||
r->OpenResult=ERAR_NO_MEMORY;
|
||||
if (Data != NULL)
|
||||
delete Data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARCloseArchive(HANDLE hArcData)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
bool Success=Data==NULL ? false:Data->Arc.Close();
|
||||
delete Data;
|
||||
return(Success ? 0:ERAR_ECLOSE);
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
|
||||
{
|
||||
struct RARHeaderDataEx X;
|
||||
memset(&X,0,sizeof(X));
|
||||
|
||||
int Code=RARReadHeaderEx(hArcData,&X);
|
||||
|
||||
strncpyz(D->ArcName,X.ArcName,ASIZE(D->ArcName));
|
||||
strncpyz(D->FileName,X.FileName,ASIZE(D->FileName));
|
||||
D->Flags=X.Flags;
|
||||
D->PackSize=X.PackSize;
|
||||
D->UnpSize=X.UnpSize;
|
||||
D->HostOS=X.HostOS;
|
||||
D->FileCRC=X.FileCRC;
|
||||
D->FileTime=X.FileTime;
|
||||
D->UnpVer=X.UnpVer;
|
||||
D->Method=X.Method;
|
||||
D->FileAttr=X.FileAttr;
|
||||
D->CmtSize=0;
|
||||
D->CmtState=0;
|
||||
|
||||
return Code;
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
try
|
||||
{
|
||||
if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0)
|
||||
{
|
||||
if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
|
||||
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
|
||||
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||
{
|
||||
Data->Extract.SignatureFound=false;
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
return(RARReadHeaderEx(hArcData,D));
|
||||
}
|
||||
else
|
||||
return(ERAR_EOPEN);
|
||||
return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
|
||||
}
|
||||
if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)!=0)
|
||||
{
|
||||
int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
|
||||
if (Code==0)
|
||||
return(RARReadHeaderEx(hArcData,D));
|
||||
else
|
||||
return(Code);
|
||||
}
|
||||
strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
|
||||
if (*Data->Arc.FileNameW)
|
||||
wcsncpy(D->ArcNameW,Data->Arc.FileNameW,ASIZE(D->ArcNameW));
|
||||
else
|
||||
CharToWide(Data->Arc.FileName,D->ArcNameW);
|
||||
strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
|
||||
if (*Data->Arc.NewLhd.FileNameW)
|
||||
wcsncpy(D->FileNameW,Data->Arc.NewLhd.FileNameW,ASIZE(D->FileNameW));
|
||||
else
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
char AnsiName[NM];
|
||||
OemToCharA(Data->Arc.NewLhd.FileName,AnsiName);
|
||||
if (!CharToWide(AnsiName,D->FileNameW,ASIZE(D->FileNameW)))
|
||||
*D->FileNameW=0;
|
||||
#else
|
||||
if (!CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW,ASIZE(D->FileNameW)))
|
||||
*D->FileNameW=0;
|
||||
#endif
|
||||
}
|
||||
D->Flags=Data->Arc.NewLhd.Flags;
|
||||
D->PackSize=Data->Arc.NewLhd.PackSize;
|
||||
D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize;
|
||||
D->UnpSize=Data->Arc.NewLhd.UnpSize;
|
||||
D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize;
|
||||
D->HostOS=Data->Arc.NewLhd.HostOS;
|
||||
D->FileCRC=Data->Arc.NewLhd.FileCRC;
|
||||
D->FileTime=Data->Arc.NewLhd.FileTime;
|
||||
D->UnpVer=Data->Arc.NewLhd.UnpVer;
|
||||
D->Method=Data->Arc.NewLhd.Method;
|
||||
D->FileAttr=Data->Arc.NewLhd.FileAttr;
|
||||
D->CmtSize=0;
|
||||
D->CmtState=0;
|
||||
}
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
return(Data->Cmd.DllError!=0 ? Data->Cmd.DllError:RarErrorToDll(ErrCode));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
try
|
||||
{
|
||||
Data->Cmd.DllError=0;
|
||||
if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT ||
|
||||
Operation==RAR_SKIP && !Data->Arc.Solid)
|
||||
{
|
||||
if (Data->Arc.Volume &&
|
||||
Data->Arc.GetHeaderType()==FILE_HEAD &&
|
||||
(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
|
||||
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||
{
|
||||
Data->Extract.SignatureFound=false;
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
return(ERAR_EOPEN);
|
||||
Data->Arc.SeekToNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
Data->Cmd.DllOpMode=Operation;
|
||||
|
||||
if (DestPath!=NULL || DestName!=NULL)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
OemToCharA(NullToEmpty(DestPath),Data->Cmd.ExtrPath);
|
||||
#else
|
||||
strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath));
|
||||
#endif
|
||||
AddEndSlash(Data->Cmd.ExtrPath);
|
||||
#ifdef _WIN_ALL
|
||||
OemToCharA(NullToEmpty(DestName),Data->Cmd.DllDestName);
|
||||
#else
|
||||
strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
*Data->Cmd.ExtrPath=0;
|
||||
*Data->Cmd.DllDestName=0;
|
||||
}
|
||||
|
||||
if (DestPathW!=NULL || DestNameW!=NULL)
|
||||
{
|
||||
wcsncpy(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
|
||||
AddEndSlash(Data->Cmd.ExtrPathW);
|
||||
wcsncpy(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1);
|
||||
|
||||
if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0)
|
||||
WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName);
|
||||
}
|
||||
else
|
||||
{
|
||||
*Data->Cmd.ExtrPathW=0;
|
||||
*Data->Cmd.DllDestNameW=0;
|
||||
}
|
||||
|
||||
strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T");
|
||||
Data->Cmd.Test=Operation!=RAR_EXTRACT;
|
||||
bool Repeat=false;
|
||||
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
|
||||
|
||||
// Now we process extra file information if any.
|
||||
//
|
||||
// Archive can be closed if we process volumes, next volume is missing
|
||||
// and current one is already removed or deleted. So we need to check
|
||||
// if archive is still open to avoid calling file operations on
|
||||
// the invalid file handle. Some of our file operations like Seek()
|
||||
// process such invalid handle correctly, some not.
|
||||
while (Data->Arc.IsOpened() && Data->Arc.ReadHeader()!=0 &&
|
||||
Data->Arc.GetHeaderType()==NEWSUB_HEAD)
|
||||
{
|
||||
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
|
||||
Data->Arc.SeekToNext();
|
||||
}
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
}
|
||||
}
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
return(Data->Cmd.DllError!=0 ? Data->Cmd.DllError:RarErrorToDll(ErrCode));
|
||||
}
|
||||
return(Data->Cmd.DllError);
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName)
|
||||
{
|
||||
return(ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL));
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar *DestPath,wchar *DestName)
|
||||
{
|
||||
return(ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName));
|
||||
}
|
||||
|
||||
|
||||
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
Data->Cmd.ChangeVolProc=ChangeVolProc;
|
||||
}
|
||||
|
||||
|
||||
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
Data->Cmd.Callback=Callback;
|
||||
Data->Cmd.UserData=UserData;
|
||||
}
|
||||
|
||||
|
||||
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
Data->Cmd.ProcessDataProc=ProcessDataProc;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RAR_NOCRYPT
|
||||
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
wchar PasswordW[MAXPASSWORD];
|
||||
GetWideName(Password,NULL,PasswordW,ASIZE(PasswordW));
|
||||
Data->Cmd.Password.Set(PasswordW);
|
||||
cleandata(PasswordW,sizeof(PasswordW));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int PASCAL RARGetDllVersion()
|
||||
{
|
||||
return(RAR_DLL_VERSION);
|
||||
}
|
||||
|
||||
|
||||
static int RarErrorToDll(RAR_EXIT ErrCode)
|
||||
{
|
||||
switch(ErrCode)
|
||||
{
|
||||
case RARX_FATAL:
|
||||
return(ERAR_EREAD);
|
||||
case RARX_CRC:
|
||||
return(ERAR_BAD_DATA);
|
||||
case RARX_WRITE:
|
||||
return(ERAR_EWRITE);
|
||||
case RARX_OPEN:
|
||||
return(ERAR_EOPEN);
|
||||
case RARX_CREATE:
|
||||
return(ERAR_ECREATE);
|
||||
case RARX_MEMORY:
|
||||
return(ERAR_NO_MEMORY);
|
||||
case RARX_SUCCESS:
|
||||
return(0);
|
||||
default:
|
||||
return(ERAR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
EXPORTS
|
||||
RAROpenArchive
|
||||
RAROpenArchiveEx
|
||||
RARCloseArchive
|
||||
RARReadHeader
|
||||
RARReadHeaderEx
|
||||
RARProcessFile
|
||||
RARSetCallback
|
||||
RARSetChangeVolProc
|
||||
RARSetProcessDataProc
|
||||
RARSetPassword
|
||||
RARGetDllVersion
|
||||
@ -1,147 +0,0 @@
|
||||
#ifndef _UNRAR_DLL_
|
||||
#define _UNRAR_DLL_
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define ERAR_END_ARCHIVE 10
|
||||
#define ERAR_NO_MEMORY 11
|
||||
#define ERAR_BAD_DATA 12
|
||||
#define ERAR_BAD_ARCHIVE 13
|
||||
#define ERAR_UNKNOWN_FORMAT 14
|
||||
#define ERAR_EOPEN 15
|
||||
#define ERAR_ECREATE 16
|
||||
#define ERAR_ECLOSE 17
|
||||
#define ERAR_EREAD 18
|
||||
#define ERAR_EWRITE 19
|
||||
#define ERAR_SMALL_BUF 20
|
||||
#define ERAR_UNKNOWN 21
|
||||
#define ERAR_MISSING_PASSWORD 22
|
||||
|
||||
#define RAR_OM_LIST 0
|
||||
#define RAR_OM_EXTRACT 1
|
||||
#define RAR_OM_LIST_INCSPLIT 2
|
||||
|
||||
#define RAR_SKIP 0
|
||||
#define RAR_TEST 1
|
||||
#define RAR_EXTRACT 2
|
||||
|
||||
#define RAR_VOL_ASK 0
|
||||
#define RAR_VOL_NOTIFY 1
|
||||
|
||||
#define RAR_DLL_VERSION 5
|
||||
|
||||
#ifdef _UNIX
|
||||
#define CALLBACK
|
||||
#define PASCAL
|
||||
#define LONG long
|
||||
#define HANDLE void *
|
||||
#define LPARAM long
|
||||
#define UINT unsigned int
|
||||
#endif
|
||||
|
||||
struct RARHeaderData
|
||||
{
|
||||
char ArcName[260];
|
||||
char FileName[260];
|
||||
unsigned int Flags;
|
||||
unsigned int PackSize;
|
||||
unsigned int UnpSize;
|
||||
unsigned int HostOS;
|
||||
unsigned int FileCRC;
|
||||
unsigned int FileTime;
|
||||
unsigned int UnpVer;
|
||||
unsigned int Method;
|
||||
unsigned int FileAttr;
|
||||
char *CmtBuf;
|
||||
unsigned int CmtBufSize;
|
||||
unsigned int CmtSize;
|
||||
unsigned int CmtState;
|
||||
};
|
||||
|
||||
|
||||
struct RARHeaderDataEx
|
||||
{
|
||||
char ArcName[1024];
|
||||
wchar_t ArcNameW[1024];
|
||||
char FileName[1024];
|
||||
wchar_t FileNameW[1024];
|
||||
unsigned int Flags;
|
||||
unsigned int PackSize;
|
||||
unsigned int PackSizeHigh;
|
||||
unsigned int UnpSize;
|
||||
unsigned int UnpSizeHigh;
|
||||
unsigned int HostOS;
|
||||
unsigned int FileCRC;
|
||||
unsigned int FileTime;
|
||||
unsigned int UnpVer;
|
||||
unsigned int Method;
|
||||
unsigned int FileAttr;
|
||||
char *CmtBuf;
|
||||
unsigned int CmtBufSize;
|
||||
unsigned int CmtSize;
|
||||
unsigned int CmtState;
|
||||
unsigned int Reserved[1024];
|
||||
};
|
||||
|
||||
|
||||
struct RAROpenArchiveData
|
||||
{
|
||||
char *ArcName;
|
||||
unsigned int OpenMode;
|
||||
unsigned int OpenResult;
|
||||
char *CmtBuf;
|
||||
unsigned int CmtBufSize;
|
||||
unsigned int CmtSize;
|
||||
unsigned int CmtState;
|
||||
};
|
||||
|
||||
typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2);
|
||||
|
||||
struct RAROpenArchiveDataEx
|
||||
{
|
||||
char *ArcName;
|
||||
wchar_t *ArcNameW;
|
||||
unsigned int OpenMode;
|
||||
unsigned int OpenResult;
|
||||
char *CmtBuf;
|
||||
unsigned int CmtBufSize;
|
||||
unsigned int CmtSize;
|
||||
unsigned int CmtState;
|
||||
unsigned int Flags;
|
||||
UNRARCALLBACK Callback;
|
||||
LPARAM UserData;
|
||||
unsigned int Reserved[28];
|
||||
};
|
||||
|
||||
enum UNRARCALLBACK_MESSAGES {
|
||||
UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD,UCM_CHANGEVOLUMEW,
|
||||
UCM_NEEDPASSWORDW
|
||||
};
|
||||
|
||||
typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode);
|
||||
typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData);
|
||||
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData);
|
||||
int PASCAL RARCloseArchive(HANDLE hArcData);
|
||||
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData);
|
||||
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData);
|
||||
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName);
|
||||
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName);
|
||||
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData);
|
||||
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc);
|
||||
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc);
|
||||
void PASCAL RARSetPassword(HANDLE hArcData,char *Password);
|
||||
int PASCAL RARGetDllVersion();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
@ -1,28 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4, 20, 100, 526
|
||||
PRODUCTVERSION 4, 20, 100, 526
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904E4"
|
||||
{
|
||||
VALUE "CompanyName", "Alexander Roshal\0"
|
||||
VALUE "ProductName", "RAR decompression library\0"
|
||||
VALUE "FileDescription", "RAR decompression library\0"
|
||||
VALUE "FileVersion", "4.20.0\0"
|
||||
VALUE "ProductVersion", "4.20.0\0"
|
||||
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2012\0"
|
||||
VALUE "OriginalFilename", "Unrar.dll\0"
|
||||
}
|
||||
}
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0, 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
EncodeFileName::EncodeFileName()
|
||||
{
|
||||
Flags=0;
|
||||
FlagBits=0;
|
||||
FlagsPos=0;
|
||||
DestSize=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EncodeFileName::Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,
|
||||
size_t MaxDecSize)
|
||||
{
|
||||
size_t EncPos=0,DecPos=0;
|
||||
byte HighByte=EncName[EncPos++];
|
||||
while (EncPos<EncSize && DecPos<MaxDecSize)
|
||||
{
|
||||
if (FlagBits==0)
|
||||
{
|
||||
Flags=EncName[EncPos++];
|
||||
FlagBits=8;
|
||||
}
|
||||
switch(Flags>>6)
|
||||
{
|
||||
case 0:
|
||||
NameW[DecPos++]=EncName[EncPos++];
|
||||
break;
|
||||
case 1:
|
||||
NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8);
|
||||
break;
|
||||
case 2:
|
||||
NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8);
|
||||
EncPos+=2;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
int Length=EncName[EncPos++];
|
||||
if (Length & 0x80)
|
||||
{
|
||||
byte Correction=EncName[EncPos++];
|
||||
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||
NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+(HighByte<<8);
|
||||
}
|
||||
else
|
||||
for (Length+=2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||
NameW[DecPos]=Name[DecPos];
|
||||
}
|
||||
break;
|
||||
}
|
||||
Flags<<=2;
|
||||
FlagBits-=2;
|
||||
}
|
||||
NameW[DecPos<MaxDecSize ? DecPos:MaxDecSize-1]=0;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _RAR_ENCNAME_
|
||||
#define _RAR_ENCNAME_
|
||||
|
||||
class EncodeFileName
|
||||
{
|
||||
private:
|
||||
void AddFlags(int Value);
|
||||
|
||||
byte *EncName;
|
||||
byte Flags;
|
||||
uint FlagBits;
|
||||
size_t FlagsPos;
|
||||
size_t DestSize;
|
||||
public:
|
||||
EncodeFileName();
|
||||
size_t Encode(char *Name,wchar *NameW,byte *EncName);
|
||||
void Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,size_t MaxDecSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,405 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
|
||||
static bool UserBreak;
|
||||
|
||||
ErrorHandler::ErrorHandler()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Clean()
|
||||
{
|
||||
ExitCode=RARX_SUCCESS;
|
||||
ErrCount=0;
|
||||
EnableBreak=true;
|
||||
Silent=false;
|
||||
DoShutdown=false;
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::MemoryError()
|
||||
{
|
||||
MemoryErrorMsg();
|
||||
Throw(RARX_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenError(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
OpenErrorMsg(FileName);
|
||||
Throw(RARX_OPEN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CloseError(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
if (!UserBreak)
|
||||
{
|
||||
ErrMsg(NULL,St(MErrFClose),FileName);
|
||||
SysErrMsg();
|
||||
}
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Throw(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ReadError(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
ReadErrorMsg(NULL,NULL,FileName,FileNameW);
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Throw(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool ErrorHandler::AskRepeatRead(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
|
||||
if (!Silent)
|
||||
{
|
||||
SysErrMsg();
|
||||
mprintf("\n");
|
||||
Log(NULL,St(MErrRead),FileName);
|
||||
return(Ask(St(MRetryAbort))==1);
|
||||
}
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::WriteError(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
WriteErrorMsg(ArcName,ArcNameW,FileName,FileNameW);
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Throw(RARX_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
void ErrorHandler::WriteErrorFAT(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
SysErrMsg();
|
||||
ErrMsg(NULL,St(MNTFSRequired),FileName);
|
||||
#endif
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
|
||||
Throw(RARX_WRITE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool ErrorHandler::AskRepeatWrite(const char *FileName,const wchar *FileNameW,bool DiskFull)
|
||||
{
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
if (!Silent)
|
||||
{
|
||||
SysErrMsg();
|
||||
mprintf("\n");
|
||||
Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
|
||||
return(Ask(St(MRetryAbort))==1);
|
||||
}
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SeekError(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
if (!UserBreak)
|
||||
{
|
||||
ErrMsg(NULL,St(MErrSeek),FileName);
|
||||
SysErrMsg();
|
||||
}
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Throw(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::GeneralErrMsg(const char *Msg)
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(NULL,"%s",Msg);
|
||||
SysErrMsg();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::MemoryErrorMsg()
|
||||
{
|
||||
#ifndef SILENT
|
||||
ErrMsg(NULL,St(MErrOutMem));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenErrorMsg(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
OpenErrorMsg(NULL,NULL,FileName,FileNameW);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
if (FileName!=NULL)
|
||||
Log(ArcName,St(MCannotOpen),FileName);
|
||||
Alarm();
|
||||
SysErrMsg();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CreateErrorMsg(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
CreateErrorMsg(NULL,NULL,FileName,FileNameW);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CreateErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
if (FileName!=NULL)
|
||||
Log(ArcName,St(MCannotCreate),FileName);
|
||||
Alarm();
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE) && defined(MAX_PATH)
|
||||
CheckLongPathErrMsg(FileName,FileNameW);
|
||||
#endif
|
||||
|
||||
SysErrMsg();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Check the path length and display the error message if it is too long.
|
||||
void ErrorHandler::CheckLongPathErrMsg(const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined (SILENT) && defined(MAX_PATH)
|
||||
if (GetLastError()==ERROR_PATH_NOT_FOUND)
|
||||
{
|
||||
wchar WideFileName[NM];
|
||||
GetWideName(FileName,FileNameW,WideFileName,ASIZE(WideFileName));
|
||||
size_t NameLength=wcslen(WideFileName);
|
||||
if (!IsFullPath(WideFileName))
|
||||
{
|
||||
wchar CurDir[NM];
|
||||
GetCurrentDirectoryW(ASIZE(CurDir),CurDir);
|
||||
NameLength+=wcslen(CurDir)+1;
|
||||
}
|
||||
if (NameLength>MAX_PATH)
|
||||
{
|
||||
Log(NULL,St(MMaxPathLimit),MAX_PATH);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ReadErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
ErrMsg(ArcName,St(MErrRead),FileName);
|
||||
SysErrMsg();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::WriteErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW)
|
||||
{
|
||||
#ifndef SILENT
|
||||
ErrMsg(ArcName,St(MErrWrite),FileName);
|
||||
SysErrMsg();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Exit(RAR_EXIT ExitCode)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
Alarm();
|
||||
#endif
|
||||
Throw(ExitCode);
|
||||
}
|
||||
|
||||
|
||||
#ifndef GUI
|
||||
void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
|
||||
{
|
||||
safebuf char Msg[NM+1024];
|
||||
va_list argptr;
|
||||
va_start(argptr,fmt);
|
||||
vsprintf(Msg,fmt,argptr);
|
||||
va_end(argptr);
|
||||
#ifdef _WIN_ALL
|
||||
if (UserBreak)
|
||||
Sleep(5000);
|
||||
#endif
|
||||
Alarm();
|
||||
if (*Msg)
|
||||
{
|
||||
Log(ArcName,"\n%s",Msg);
|
||||
mprintf("\n%s\n",St(MProgAborted));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ErrorHandler::SetErrorCode(RAR_EXIT Code)
|
||||
{
|
||||
switch(Code)
|
||||
{
|
||||
case RARX_WARNING:
|
||||
case RARX_USERBREAK:
|
||||
if (ExitCode==RARX_SUCCESS)
|
||||
ExitCode=Code;
|
||||
break;
|
||||
case RARX_FATAL:
|
||||
if (ExitCode==RARX_SUCCESS || ExitCode==RARX_WARNING)
|
||||
ExitCode=RARX_FATAL;
|
||||
break;
|
||||
default:
|
||||
ExitCode=Code;
|
||||
break;
|
||||
}
|
||||
ErrCount++;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(_SFX_RTL_)
|
||||
#ifdef _WIN_ALL
|
||||
BOOL __stdcall ProcessSignal(DWORD SigType)
|
||||
#else
|
||||
#if defined(__sun)
|
||||
extern "C"
|
||||
#endif
|
||||
void _stdfunction ProcessSignal(int SigType)
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// When a console application is run as a service, this allows the service
|
||||
// to continue running after the user logs off.
|
||||
if (SigType==CTRL_LOGOFF_EVENT)
|
||||
return(TRUE);
|
||||
#endif
|
||||
UserBreak=true;
|
||||
mprintf(St(MBreak));
|
||||
for (int I=0;!File::RemoveCreated() && I<3;I++)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
Sleep(100);
|
||||
#endif
|
||||
}
|
||||
#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE) && !defined(RARDLL)
|
||||
ExtRes.UnloadDLL();
|
||||
#endif
|
||||
exit(RARX_USERBREAK);
|
||||
#if defined(_WIN_ALL) && !defined(_MSC_VER)
|
||||
// never reached, just to avoid a compiler warning
|
||||
return(TRUE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ErrorHandler::SetSignalHandlers(bool Enable)
|
||||
{
|
||||
EnableBreak=Enable;
|
||||
#if !defined(GUI) && !defined(_SFX_RTL_)
|
||||
#ifdef _WIN_ALL
|
||||
SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
|
||||
// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
|
||||
#else
|
||||
signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
|
||||
signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Throw(RAR_EXIT Code)
|
||||
{
|
||||
if (Code==RARX_USERBREAK && !EnableBreak)
|
||||
return;
|
||||
ErrHandler.SetErrorCode(Code);
|
||||
#ifdef ALLOW_EXCEPTIONS
|
||||
throw Code;
|
||||
#else
|
||||
File::RemoveCreated();
|
||||
exit(Code);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SysErrMsg()
|
||||
{
|
||||
#if !defined(SFX_MODULE) && !defined(SILENT)
|
||||
#ifdef _WIN_ALL
|
||||
wchar *lpMsgBuf=NULL;
|
||||
int ErrType=GetLastError();
|
||||
if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,0,NULL))
|
||||
{
|
||||
wchar *CurMsg=lpMsgBuf;
|
||||
while (CurMsg!=NULL)
|
||||
{
|
||||
while (*CurMsg=='\r' || *CurMsg=='\n')
|
||||
CurMsg++;
|
||||
if (*CurMsg==0)
|
||||
break;
|
||||
wchar *EndMsg=wcschr(CurMsg,'\r');
|
||||
if (EndMsg==NULL)
|
||||
EndMsg=wcschr(CurMsg,'\n');
|
||||
if (EndMsg!=NULL)
|
||||
{
|
||||
*EndMsg=0;
|
||||
EndMsg++;
|
||||
}
|
||||
// We use ASCII for output in Windows console, so let's convert Unicode
|
||||
// message to single byte.
|
||||
size_t Length=wcslen(CurMsg)*2; // Must be enough for DBCS characters.
|
||||
char *MsgA=(char *)malloc(Length+2);
|
||||
if (MsgA!=NULL)
|
||||
{
|
||||
WideToChar(CurMsg,MsgA,Length+1);
|
||||
MsgA[Length]=0;
|
||||
Log(NULL,"\n%s",MsgA);
|
||||
free(MsgA);
|
||||
}
|
||||
CurMsg=EndMsg;
|
||||
}
|
||||
}
|
||||
LocalFree( lpMsgBuf );
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
if (errno!=0)
|
||||
{
|
||||
char *err=strerror(errno);
|
||||
if (err!=NULL)
|
||||
Log(NULL,"\n%s",err);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
#ifndef _RAR_ERRHANDLER_
|
||||
#define _RAR_ERRHANDLER_
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
#define ALLOW_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
enum RAR_EXIT // RAR exit code.
|
||||
{
|
||||
RARX_SUCCESS = 0,
|
||||
RARX_WARNING = 1,
|
||||
RARX_FATAL = 2,
|
||||
RARX_CRC = 3,
|
||||
RARX_LOCK = 4,
|
||||
RARX_WRITE = 5,
|
||||
RARX_OPEN = 6,
|
||||
RARX_USERERROR = 7,
|
||||
RARX_MEMORY = 8,
|
||||
RARX_CREATE = 9,
|
||||
RARX_NOFILES = 10,
|
||||
RARX_USERBREAK = 255
|
||||
};
|
||||
|
||||
class ErrorHandler
|
||||
{
|
||||
private:
|
||||
void ErrMsg(const char *ArcName,const char *fmt,...);
|
||||
|
||||
RAR_EXIT ExitCode;
|
||||
int ErrCount;
|
||||
bool EnableBreak;
|
||||
bool Silent;
|
||||
bool DoShutdown;
|
||||
public:
|
||||
ErrorHandler();
|
||||
void Clean();
|
||||
void MemoryError();
|
||||
void OpenError(const char *FileName,const wchar *FileNameW);
|
||||
void CloseError(const char *FileName,const wchar *FileNameW);
|
||||
void ReadError(const char *FileName,const wchar *FileNameW);
|
||||
bool AskRepeatRead(const char *FileName,const wchar *FileNameW);
|
||||
void WriteError(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW);
|
||||
void WriteErrorFAT(const char *FileName,const wchar *FileNameW);
|
||||
bool AskRepeatWrite(const char *FileName,const wchar *FileNameW,bool DiskFull);
|
||||
void SeekError(const char *FileName,const wchar *FileNameW);
|
||||
void GeneralErrMsg(const char *Msg);
|
||||
void MemoryErrorMsg();
|
||||
void OpenErrorMsg(const char *FileName,const wchar *FileNameW=NULL);
|
||||
void OpenErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW);
|
||||
void CreateErrorMsg(const char *FileName,const wchar *FileNameW=NULL);
|
||||
void CreateErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW);
|
||||
void CheckLongPathErrMsg(const char *FileName,const wchar *FileNameW);
|
||||
void ReadErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW);
|
||||
void WriteErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW);
|
||||
void Exit(RAR_EXIT ExitCode);
|
||||
void SetErrorCode(RAR_EXIT Code);
|
||||
RAR_EXIT GetErrorCode() {return(ExitCode);}
|
||||
int GetErrorCount() {return(ErrCount);}
|
||||
void SetSignalHandlers(bool Enable);
|
||||
void Throw(RAR_EXIT Code);
|
||||
void SetSilent(bool Mode) {Silent=Mode;};
|
||||
void SetShutdown(bool Mode) {DoShutdown=Mode;};
|
||||
void SysErrMsg();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,76 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
#include "win32acl.cpp"
|
||||
#include "win32stm.cpp"
|
||||
#endif
|
||||
#ifdef _BEOS
|
||||
#include "beosea.cpp"
|
||||
#endif
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
#include "os2ea.cpp"
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
#include "uowners.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
|
||||
{
|
||||
switch(Arc.SubBlockHead.SubType)
|
||||
{
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
case EA_HEAD:
|
||||
if (Cmd->ProcessEA)
|
||||
ExtractOS2EA(Arc,Name);
|
||||
break;
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
case UO_HEAD:
|
||||
if (Cmd->ProcessOwners)
|
||||
ExtractUnixOwner(Arc,Name);
|
||||
break;
|
||||
#endif
|
||||
#ifdef _BEOS
|
||||
case BEEA_HEAD:
|
||||
if (Cmd->ProcessEA)
|
||||
ExtractBeEA(Arc,Name);
|
||||
break;
|
||||
#endif
|
||||
#ifdef _WIN_ALL
|
||||
case NTACL_HEAD:
|
||||
if (Cmd->ProcessOwners)
|
||||
ExtractACL(Arc,Name,NameW);
|
||||
break;
|
||||
case STREAM_HEAD:
|
||||
ExtractStreams(Arc,Name,NameW);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
|
||||
{
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_OS2EA))
|
||||
ExtractOS2EANew(Arc,Name);
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
|
||||
ExtractUnixOwnerNew(Arc,Name);
|
||||
#endif
|
||||
#ifdef _BEOS
|
||||
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
|
||||
ExtractUnixOwnerNew(Arc,Name);
|
||||
#endif
|
||||
#ifdef _WIN_ALL
|
||||
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_ACL))
|
||||
ExtractACLNew(Arc,Name,NameW);
|
||||
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM))
|
||||
ExtractStreamsNew(Arc,Name,NameW);
|
||||
#endif
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
#ifndef _RAR_EXTINFO_
|
||||
#define _RAR_EXTINFO_
|
||||
|
||||
|
||||
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
|
||||
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
#ifndef _RAR_EXTRACT_
|
||||
#define _RAR_EXTRACT_
|
||||
|
||||
enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT};
|
||||
|
||||
class CmdExtract
|
||||
{
|
||||
private:
|
||||
EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd);
|
||||
RarTime StartTime; // time when extraction started
|
||||
|
||||
ComprDataIO DataIO;
|
||||
Unpack *Unp;
|
||||
unsigned long TotalFileCount;
|
||||
|
||||
unsigned long FileCount;
|
||||
unsigned long MatchedArgs;
|
||||
bool FirstFile;
|
||||
bool AllMatchesExact;
|
||||
bool ReconstructDone;
|
||||
|
||||
// If any non-zero solid file was successfully unpacked before current.
|
||||
// If true and if current encrypted file is broken, obviously
|
||||
// the password is correct and we can report broken CRC without
|
||||
// any wrong password hints.
|
||||
bool AnySolidDataUnpackedWell;
|
||||
|
||||
char ArcName[NM];
|
||||
wchar ArcNameW[NM];
|
||||
|
||||
SecPassword Password;
|
||||
bool PasswordAll;
|
||||
bool PrevExtracted;
|
||||
char DestFileName[NM];
|
||||
wchar DestFileNameW[NM];
|
||||
bool PasswordCancelled;
|
||||
public:
|
||||
CmdExtract();
|
||||
~CmdExtract();
|
||||
void DoExtract(CommandData *Cmd);
|
||||
void ExtractArchiveInit(CommandData *Cmd,Archive &Arc);
|
||||
bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,
|
||||
bool &Repeat);
|
||||
static void UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize);
|
||||
|
||||
bool SignatureFound;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,260 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
|
||||
OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize,
|
||||
uint FileTime,bool WriteOnly)
|
||||
{
|
||||
if (UserReject!=NULL)
|
||||
*UserReject=false;
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
bool ShortNameChanged=false;
|
||||
#endif
|
||||
while (FileExist(Name,NameW))
|
||||
{
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
if (!ShortNameChanged)
|
||||
{
|
||||
// Avoid the infinite loop if UpdateExistingShortName returns
|
||||
// the same name.
|
||||
ShortNameChanged=true;
|
||||
|
||||
// Maybe our long name matches the short name of existing file.
|
||||
// Let's check if we can change the short name.
|
||||
wchar WideName[NM];
|
||||
GetWideName(Name,NameW,WideName,ASIZE(WideName));
|
||||
if (UpdateExistingShortName(WideName))
|
||||
{
|
||||
if (Name!=NULL && *Name!=0)
|
||||
WideToChar(WideName,Name);
|
||||
if (NameW!=NULL && *NameW!=0)
|
||||
wcscpy(NameW,WideName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Allow short name check again. It is necessary, because rename and
|
||||
// autorename below can change the name, so we need to check it again.
|
||||
ShortNameChanged=false;
|
||||
#endif
|
||||
if (Mode==OVERWRITE_NONE)
|
||||
{
|
||||
if (UserReject!=NULL)
|
||||
*UserReject=true;
|
||||
return(false);
|
||||
}
|
||||
|
||||
// Must be before Cmd->AllYes check or -y switch would override -or.
|
||||
if (Mode==OVERWRITE_AUTORENAME)
|
||||
{
|
||||
if (!GetAutoRenamedName(Name,NameW))
|
||||
Mode=OVERWRITE_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef SILENT
|
||||
Mode=OVERWRITE_ALL;
|
||||
#endif
|
||||
|
||||
// This check must be after OVERWRITE_AUTORENAME processing or -y switch
|
||||
// would override -or.
|
||||
if (Cmd->AllYes || Mode==OVERWRITE_ALL)
|
||||
break;
|
||||
|
||||
if (Mode==OVERWRITE_DEFAULT || Mode==OVERWRITE_FORCE_ASK)
|
||||
{
|
||||
char NewName[NM];
|
||||
wchar NewNameW[NM];
|
||||
*NewNameW=0;
|
||||
eprintf(St(MFileExists),Name);
|
||||
int Choice=Ask(St(MYesNoAllRenQ));
|
||||
if (Choice==1)
|
||||
break;
|
||||
if (Choice==2)
|
||||
{
|
||||
if (UserReject!=NULL)
|
||||
*UserReject=true;
|
||||
return(false);
|
||||
}
|
||||
if (Choice==3)
|
||||
{
|
||||
Cmd->Overwrite=OVERWRITE_ALL;
|
||||
break;
|
||||
}
|
||||
if (Choice==4)
|
||||
{
|
||||
if (UserReject!=NULL)
|
||||
*UserReject=true;
|
||||
Cmd->Overwrite=OVERWRITE_NONE;
|
||||
return(false);
|
||||
}
|
||||
if (Choice==5)
|
||||
{
|
||||
#ifndef GUI
|
||||
mprintf(St(MAskNewName));
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
File SrcFile;
|
||||
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||
int Size=SrcFile.Read(NewName,sizeof(NewName)-1);
|
||||
NewName[Size]=0;
|
||||
OemToCharA(NewName,NewName);
|
||||
#else
|
||||
if (fgets(NewName,sizeof(NewName),stdin)==NULL)
|
||||
{
|
||||
// Process fgets failure as if user answered 'No'.
|
||||
if (UserReject!=NULL)
|
||||
*UserReject=true;
|
||||
return(false);
|
||||
}
|
||||
#endif
|
||||
RemoveLF(NewName);
|
||||
#endif
|
||||
if (PointToName(NewName)==NewName)
|
||||
strcpy(PointToName(Name),NewName);
|
||||
else
|
||||
strcpy(Name,NewName);
|
||||
|
||||
if (NameW!=NULL)
|
||||
if (PointToName(NewNameW)==NewNameW)
|
||||
wcscpy(PointToName(NameW),NewNameW);
|
||||
else
|
||||
wcscpy(NameW,NewNameW);
|
||||
continue;
|
||||
}
|
||||
if (Choice==6)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
}
|
||||
uint FileMode=WriteOnly ? FMF_WRITE|FMF_SHAREREAD:FMF_UPDATE|FMF_SHAREREAD;
|
||||
if (NewFile!=NULL && NewFile->Create(Name,NameW,FileMode))
|
||||
return(true);
|
||||
PrepareToDelete(Name,NameW);
|
||||
CreatePath(Name,NameW,true);
|
||||
return(NewFile!=NULL ? NewFile->Create(Name,NameW,FileMode):DelFile(Name,NameW));
|
||||
}
|
||||
|
||||
|
||||
bool GetAutoRenamedName(char *Name,wchar *NameW)
|
||||
{
|
||||
char NewName[NM];
|
||||
wchar NewNameW[NM];
|
||||
|
||||
if (Name!=NULL && strlen(Name)>ASIZE(NewName)-10 ||
|
||||
NameW!=NULL && wcslen(NameW)>ASIZE(NewNameW)-10)
|
||||
return(false);
|
||||
char *Ext=NULL;
|
||||
if (Name!=NULL && *Name!=0)
|
||||
{
|
||||
Ext=GetExt(Name);
|
||||
if (Ext==NULL)
|
||||
Ext=Name+strlen(Name);
|
||||
}
|
||||
wchar *ExtW=NULL;
|
||||
if (NameW!=NULL && *NameW!=0)
|
||||
{
|
||||
ExtW=GetExt(NameW);
|
||||
if (ExtW==NULL)
|
||||
ExtW=NameW+wcslen(NameW);
|
||||
}
|
||||
*NewName=0;
|
||||
*NewNameW=0;
|
||||
for (int FileVer=1;;FileVer++)
|
||||
{
|
||||
if (Name!=NULL && *Name!=0)
|
||||
sprintf(NewName,"%.*s(%d)%s",int(Ext-Name),Name,FileVer,Ext);
|
||||
if (NameW!=NULL && *NameW!=0)
|
||||
sprintfw(NewNameW,ASIZE(NewNameW),L"%.*s(%d)%s",int(ExtW-NameW),NameW,FileVer,ExtW);
|
||||
if (!FileExist(NewName,NewNameW))
|
||||
{
|
||||
if (Name!=NULL && *Name!=0)
|
||||
strcpy(Name,NewName);
|
||||
if (NameW!=NULL && *NameW!=0)
|
||||
wcscpy(NameW,NewNameW);
|
||||
break;
|
||||
}
|
||||
if (FileVer>=1000000)
|
||||
return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
// If we find a file, which short name is equal to 'Name', we try to change
|
||||
// its short name, while preserving the long name. It helps when unpacking
|
||||
// an archived file, which long name is equal to short name of already
|
||||
// existing file. Otherwise we would overwrite the already existing file,
|
||||
// even though its long name does not match the name of unpacking file.
|
||||
bool UpdateExistingShortName(wchar *Name)
|
||||
{
|
||||
// 'Name' is the name of file which we want to create. Let's check
|
||||
// if file with such name is exist. If it does not, we return.
|
||||
FindData fd;
|
||||
if (!FindFile::FastFind(NULL,Name,&fd))
|
||||
return(false);
|
||||
|
||||
// We continue only if file has a short name, which does not match its
|
||||
// long name, and this short name is equal to name of file which we need
|
||||
// to create.
|
||||
if (*fd.ShortName==0 || wcsicomp(PointToName(fd.NameW),fd.ShortName)==0 ||
|
||||
wcsicomp(PointToName(Name),fd.ShortName)!=0)
|
||||
return(false);
|
||||
|
||||
// Generate the temporary new name for existing file.
|
||||
wchar NewName[NM];
|
||||
*NewName=0;
|
||||
for (int I=0;I<10000 && *NewName==0;I+=123)
|
||||
{
|
||||
// Here we copy the path part of file to create. We'll make the temporary
|
||||
// file in the same folder.
|
||||
wcsncpyz(NewName,Name,ASIZE(NewName));
|
||||
|
||||
// Here we set the random name part.
|
||||
sprintfw(PointToName(NewName),ASIZE(NewName),L"rtmp%d",I);
|
||||
|
||||
// If such file is already exist, try next random name.
|
||||
if (FileExist(NULL,NewName))
|
||||
*NewName=0;
|
||||
}
|
||||
|
||||
// If we could not generate the name not used by any other file, we return.
|
||||
if (*NewName==0)
|
||||
return(false);
|
||||
|
||||
// FastFind returns the name without path, but we need the fully qualified
|
||||
// name for renaming, so we use the path from file to create and long name
|
||||
// from existing file.
|
||||
wchar FullName[NM];
|
||||
wcsncpyz(FullName,Name,ASIZE(FullName));
|
||||
wcscpy(PointToName(FullName),PointToName(fd.NameW));
|
||||
|
||||
// Rename the existing file to randomly generated name. Normally it changes
|
||||
// the short name too.
|
||||
if (!MoveFileW(FullName,NewName))
|
||||
return(false);
|
||||
|
||||
// Now we need to create the temporary empty file with same name as
|
||||
// short name of our already existing file. We do it to occupy its previous
|
||||
// short name and not allow to use it again when renaming the file back to
|
||||
// its original long name.
|
||||
File KeepShortFile;
|
||||
bool Created=false;
|
||||
if (!FileExist(NULL,Name))
|
||||
Created=KeepShortFile.Create(NULL,Name);
|
||||
|
||||
// Now we rename the existing file from temporary name to original long name.
|
||||
// Since its previous short name is occupied by another file, it should
|
||||
// get another short name.
|
||||
MoveFileW(NewName,FullName);
|
||||
|
||||
if (Created)
|
||||
{
|
||||
// Delete the temporary zero length file occupying the short name,
|
||||
KeepShortFile.Close();
|
||||
KeepShortFile.Delete();
|
||||
}
|
||||
// We successfully changed the short name. Maybe sometimes we'll simplify
|
||||
// this function by use of SetFileShortName Windows API call.
|
||||
// But SetFileShortName is not available in older Windows.
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
@ -1,13 +0,0 @@
|
||||
#ifndef _RAR_FILECREATE_
|
||||
#define _RAR_FILECREATE_
|
||||
|
||||
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
|
||||
OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize=INT64NDF,
|
||||
uint FileTime=0,bool WriteOnly=false);
|
||||
bool GetAutoRenamedName(char *Name,wchar *NameW);
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
bool UpdateExistingShortName(wchar *Name);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,710 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
static File *CreatedFiles[256];
|
||||
static int RemoveCreatedActive=0;
|
||||
|
||||
File::File()
|
||||
{
|
||||
hFile=BAD_HANDLE;
|
||||
*FileName=0;
|
||||
*FileNameW=0;
|
||||
NewFile=false;
|
||||
LastWrite=false;
|
||||
HandleType=FILE_HANDLENORMAL;
|
||||
SkipClose=false;
|
||||
IgnoreReadErrors=false;
|
||||
ErrorType=FILE_SUCCESS;
|
||||
OpenShared=false;
|
||||
AllowDelete=true;
|
||||
CloseCount=0;
|
||||
AllowExceptions=true;
|
||||
#ifdef _WIN_ALL
|
||||
NoSequentialRead=false;
|
||||
CreateMode=FMF_UNDEFINED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
File::~File()
|
||||
{
|
||||
if (hFile!=BAD_HANDLE && !SkipClose)
|
||||
if (NewFile)
|
||||
Delete();
|
||||
else
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
void File::operator = (File &SrcFile)
|
||||
{
|
||||
hFile=SrcFile.hFile;
|
||||
strcpy(FileName,SrcFile.FileName);
|
||||
NewFile=SrcFile.NewFile;
|
||||
LastWrite=SrcFile.LastWrite;
|
||||
HandleType=SrcFile.HandleType;
|
||||
SrcFile.SkipClose=true;
|
||||
}
|
||||
|
||||
|
||||
bool File::Open(const char *Name,const wchar *NameW,uint Mode)
|
||||
{
|
||||
ErrorType=FILE_SUCCESS;
|
||||
FileHandle hNewFile;
|
||||
bool OpenShared=File::OpenShared || (Mode & FMF_OPENSHARED)!=0;
|
||||
bool UpdateMode=(Mode & FMF_UPDATE)!=0;
|
||||
bool WriteMode=(Mode & FMF_WRITE)!=0;
|
||||
#ifdef _WIN_ALL
|
||||
uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ;
|
||||
if (UpdateMode)
|
||||
Access|=GENERIC_WRITE;
|
||||
uint ShareMode=FILE_SHARE_READ;
|
||||
if (OpenShared)
|
||||
ShareMode|=FILE_SHARE_WRITE;
|
||||
uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
|
||||
else
|
||||
hNewFile=CreateFileA(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
|
||||
|
||||
if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)
|
||||
ErrorType=FILE_NOTFOUND;
|
||||
#else
|
||||
int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
flags|=O_BINARY;
|
||||
#if defined(_AIX) && defined(_LARGE_FILE_API)
|
||||
flags|=O_LARGEFILE;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
int sflags=OpenShared ? SH_DENYNO:SH_DENYWR;
|
||||
int handle=sopen(Name,flags,sflags);
|
||||
#else
|
||||
int handle=open(Name,flags);
|
||||
#ifdef LOCK_EX
|
||||
|
||||
#ifdef _OSF_SOURCE
|
||||
extern "C" int flock(int, int);
|
||||
#endif
|
||||
|
||||
if (!OpenShared && UpdateMode && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
|
||||
{
|
||||
close(handle);
|
||||
return(false);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,UpdateMode ? UPDATEBINARY:READBINARY);
|
||||
if (hNewFile==BAD_HANDLE && errno==ENOENT)
|
||||
ErrorType=FILE_NOTFOUND;
|
||||
#endif
|
||||
NewFile=false;
|
||||
HandleType=FILE_HANDLENORMAL;
|
||||
SkipClose=false;
|
||||
bool Success=hNewFile!=BAD_HANDLE;
|
||||
if (Success)
|
||||
{
|
||||
hFile=hNewFile;
|
||||
|
||||
// We use memove instead of strcpy and wcscpy to avoid problems
|
||||
// with overlapped buffers. While we do not call this function with
|
||||
// really overlapped buffers yet, we do call it with Name equal to
|
||||
// FileName like Arc.Open(Arc.FileName,Arc.FileNameW,...).
|
||||
if (NameW!=NULL)
|
||||
memmove(FileNameW,NameW,(wcslen(NameW)+1)*sizeof(*NameW));
|
||||
else
|
||||
*FileNameW=0;
|
||||
if (Name!=NULL)
|
||||
memmove(FileName,Name,strlen(Name)+1);
|
||||
else
|
||||
WideToChar(NameW,FileName);
|
||||
AddFileToList(hFile);
|
||||
}
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
void File::TOpen(const char *Name,const wchar *NameW)
|
||||
{
|
||||
if (!WOpen(Name,NameW))
|
||||
ErrHandler.Exit(RARX_OPEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool File::WOpen(const char *Name,const wchar *NameW)
|
||||
{
|
||||
if (Open(Name,NameW))
|
||||
return(true);
|
||||
ErrHandler.OpenErrorMsg(Name,NameW);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool File::Create(const char *Name,const wchar *NameW,uint Mode)
|
||||
{
|
||||
// OpenIndiana based NAS and CIFS shares fail to set the file time if file
|
||||
// was created in read+write mode and some data was written and not flushed
|
||||
// before SetFileTime call. So we should use the write only mode if we plan
|
||||
// SetFileTime call and do not need to read from file.
|
||||
bool WriteMode=(Mode & FMF_WRITE)!=0;
|
||||
bool ShareRead=(Mode & FMF_SHAREREAD)!=0 || File::OpenShared;
|
||||
#ifdef _WIN_ALL
|
||||
CreateMode=Mode;
|
||||
uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ|GENERIC_WRITE;
|
||||
DWORD ShareMode=ShareRead ? FILE_SHARE_READ:0;
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
hFile=CreateFileW(NameW,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL);
|
||||
else
|
||||
hFile=CreateFileA(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL);
|
||||
#else
|
||||
hFile=fopen(Name,WriteMode ? WRITEBINARY:CREATEBINARY);
|
||||
#endif
|
||||
NewFile=true;
|
||||
HandleType=FILE_HANDLENORMAL;
|
||||
SkipClose=false;
|
||||
if (NameW!=NULL)
|
||||
wcscpy(FileNameW,NameW);
|
||||
else
|
||||
*FileNameW=0;
|
||||
if (Name!=NULL)
|
||||
strcpy(FileName,Name);
|
||||
else
|
||||
WideToChar(NameW,FileName);
|
||||
AddFileToList(hFile);
|
||||
return(hFile!=BAD_HANDLE);
|
||||
}
|
||||
|
||||
|
||||
void File::AddFileToList(FileHandle hFile)
|
||||
{
|
||||
if (hFile!=BAD_HANDLE)
|
||||
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||
if (CreatedFiles[I]==NULL)
|
||||
{
|
||||
CreatedFiles[I]=this;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
void File::TCreate(const char *Name,const wchar *NameW,uint Mode)
|
||||
{
|
||||
if (!WCreate(Name,NameW,Mode))
|
||||
ErrHandler.Exit(RARX_FATAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool File::WCreate(const char *Name,const wchar *NameW,uint Mode)
|
||||
{
|
||||
if (Create(Name,NameW,Mode))
|
||||
return(true);
|
||||
ErrHandler.SetErrorCode(RARX_CREATE);
|
||||
ErrHandler.CreateErrorMsg(Name,NameW);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool File::Close()
|
||||
{
|
||||
bool Success=true;
|
||||
if (HandleType!=FILE_HANDLENORMAL)
|
||||
HandleType=FILE_HANDLENORMAL;
|
||||
else
|
||||
if (hFile!=BAD_HANDLE)
|
||||
{
|
||||
if (!SkipClose)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
Success=CloseHandle(hFile)==TRUE;
|
||||
#else
|
||||
Success=fclose(hFile)!=EOF;
|
||||
#endif
|
||||
if (Success || !RemoveCreatedActive)
|
||||
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||
if (CreatedFiles[I]==this)
|
||||
{
|
||||
CreatedFiles[I]=NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hFile=BAD_HANDLE;
|
||||
if (!Success && AllowExceptions)
|
||||
ErrHandler.CloseError(FileName,FileNameW);
|
||||
}
|
||||
CloseCount++;
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
void File::Flush()
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
FlushFileBuffers(hFile);
|
||||
#else
|
||||
fflush(hFile);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool File::Delete()
|
||||
{
|
||||
if (HandleType!=FILE_HANDLENORMAL)
|
||||
return(false);
|
||||
if (hFile!=BAD_HANDLE)
|
||||
Close();
|
||||
if (!AllowDelete)
|
||||
return(false);
|
||||
return(DelFile(FileName,FileNameW));
|
||||
}
|
||||
|
||||
|
||||
bool File::Rename(const char *NewName,const wchar *NewNameW)
|
||||
{
|
||||
// we do not need to rename if names are already same
|
||||
bool Success=strcmp(FileName,NewName)==0;
|
||||
if (Success && *FileNameW!=0 && *NullToEmpty(NewNameW)!=0)
|
||||
Success=wcscmp(FileNameW,NewNameW)==0;
|
||||
|
||||
if (!Success)
|
||||
Success=RenameFile(FileName,FileNameW,NewName,NewNameW);
|
||||
|
||||
if (Success)
|
||||
{
|
||||
// renamed successfully, storing the new name
|
||||
strcpy(FileName,NewName);
|
||||
wcscpy(FileNameW,NullToEmpty(NewNameW));
|
||||
}
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
void File::Write(const void *Data,size_t Size)
|
||||
{
|
||||
if (Size==0)
|
||||
return;
|
||||
#ifndef _WIN_CE
|
||||
if (HandleType!=FILE_HANDLENORMAL)
|
||||
switch(HandleType)
|
||||
{
|
||||
case FILE_HANDLESTD:
|
||||
#ifdef _WIN_ALL
|
||||
hFile=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#else
|
||||
hFile=stdout;
|
||||
#endif
|
||||
break;
|
||||
case FILE_HANDLEERR:
|
||||
#ifdef _WIN_ALL
|
||||
hFile=GetStdHandle(STD_ERROR_HANDLE);
|
||||
#else
|
||||
hFile=stderr;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
bool Success=false;
|
||||
#ifdef _WIN_ALL
|
||||
DWORD Written=0;
|
||||
if (HandleType!=FILE_HANDLENORMAL)
|
||||
{
|
||||
// writing to stdout can fail in old Windows if data block is too large
|
||||
const size_t MaxSize=0x4000;
|
||||
for (size_t I=0;I<Size;I+=MaxSize)
|
||||
{
|
||||
Success=WriteFile(hFile,(byte *)Data+I,(DWORD)Min(Size-I,MaxSize),&Written,NULL)==TRUE;
|
||||
if (!Success)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Success=WriteFile(hFile,Data,(DWORD)Size,&Written,NULL)==TRUE;
|
||||
#else
|
||||
int Written=fwrite(Data,1,Size,hFile);
|
||||
Success=Written==Size && !ferror(hFile);
|
||||
#endif
|
||||
if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)
|
||||
{
|
||||
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(RARDLL)
|
||||
int ErrCode=GetLastError();
|
||||
int64 FilePos=Tell();
|
||||
uint64 FreeSize=GetFreeDisk(FileName);
|
||||
SetLastError(ErrCode);
|
||||
if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)
|
||||
ErrHandler.WriteErrorFAT(FileName,FileNameW);
|
||||
#endif
|
||||
if (ErrHandler.AskRepeatWrite(FileName,FileNameW,false))
|
||||
{
|
||||
#ifndef _WIN_ALL
|
||||
clearerr(hFile);
|
||||
#endif
|
||||
if (Written<Size && Written>0)
|
||||
Seek(Tell()-Written,SEEK_SET);
|
||||
continue;
|
||||
}
|
||||
ErrHandler.WriteError(NULL,NULL,FileName,FileNameW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
LastWrite=true;
|
||||
}
|
||||
|
||||
|
||||
int File::Read(void *Data,size_t Size)
|
||||
{
|
||||
int64 FilePos=0; // Initialized only to suppress some compilers warning.
|
||||
|
||||
if (IgnoreReadErrors)
|
||||
FilePos=Tell();
|
||||
int ReadSize;
|
||||
while (true)
|
||||
{
|
||||
ReadSize=DirectRead(Data,Size);
|
||||
if (ReadSize==-1)
|
||||
{
|
||||
ErrorType=FILE_READERROR;
|
||||
if (AllowExceptions)
|
||||
if (IgnoreReadErrors)
|
||||
{
|
||||
ReadSize=0;
|
||||
for (size_t I=0;I<Size;I+=512)
|
||||
{
|
||||
Seek(FilePos+I,SEEK_SET);
|
||||
size_t SizeToRead=Min(Size-I,512);
|
||||
int ReadCode=DirectRead(Data,SizeToRead);
|
||||
ReadSize+=(ReadCode==-1) ? 512:ReadCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName,FileNameW))
|
||||
continue;
|
||||
ErrHandler.ReadError(FileName,FileNameW);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return(ReadSize);
|
||||
}
|
||||
|
||||
|
||||
// Returns -1 in case of error.
|
||||
int File::DirectRead(void *Data,size_t Size)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
const size_t MaxDeviceRead=20000;
|
||||
#endif
|
||||
#ifndef _WIN_CE
|
||||
if (HandleType==FILE_HANDLESTD)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (Size>MaxDeviceRead)
|
||||
Size=MaxDeviceRead;
|
||||
hFile=GetStdHandle(STD_INPUT_HANDLE);
|
||||
#else
|
||||
hFile=stdin;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN_ALL
|
||||
DWORD Read;
|
||||
if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL))
|
||||
{
|
||||
if (IsDevice() && Size>MaxDeviceRead)
|
||||
return(DirectRead(Data,MaxDeviceRead));
|
||||
if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
|
||||
return(0);
|
||||
return(-1);
|
||||
}
|
||||
return(Read);
|
||||
#else
|
||||
if (LastWrite)
|
||||
{
|
||||
fflush(hFile);
|
||||
LastWrite=false;
|
||||
}
|
||||
clearerr(hFile);
|
||||
size_t ReadSize=fread(Data,1,Size,hFile);
|
||||
if (ferror(hFile))
|
||||
return(-1);
|
||||
return((int)ReadSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::Seek(int64 Offset,int Method)
|
||||
{
|
||||
if (!RawSeek(Offset,Method) && AllowExceptions)
|
||||
ErrHandler.SeekError(FileName,FileNameW);
|
||||
}
|
||||
|
||||
|
||||
bool File::RawSeek(int64 Offset,int Method)
|
||||
{
|
||||
if (hFile==BAD_HANDLE)
|
||||
return(true);
|
||||
if (Offset<0 && Method!=SEEK_SET)
|
||||
{
|
||||
Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;
|
||||
Method=SEEK_SET;
|
||||
}
|
||||
#ifdef _WIN_ALL
|
||||
LONG HighDist=(LONG)(Offset>>32);
|
||||
if (SetFilePointer(hFile,(LONG)Offset,&HighDist,Method)==0xffffffff &&
|
||||
GetLastError()!=NO_ERROR)
|
||||
return(false);
|
||||
#else
|
||||
LastWrite=false;
|
||||
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS)
|
||||
if (fseeko(hFile,Offset,Method)!=0)
|
||||
#else
|
||||
if (fseek(hFile,(long)Offset,Method)!=0)
|
||||
#endif
|
||||
return(false);
|
||||
#endif
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
int64 File::Tell()
|
||||
{
|
||||
if (hFile==BAD_HANDLE)
|
||||
if (AllowExceptions)
|
||||
ErrHandler.SeekError(FileName,FileNameW);
|
||||
else
|
||||
return(-1);
|
||||
#ifdef _WIN_ALL
|
||||
LONG HighDist=0;
|
||||
uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);
|
||||
if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)
|
||||
if (AllowExceptions)
|
||||
ErrHandler.SeekError(FileName,FileNameW);
|
||||
else
|
||||
return(-1);
|
||||
return(INT32TO64(HighDist,LowDist));
|
||||
#else
|
||||
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE)
|
||||
return(ftello(hFile));
|
||||
#else
|
||||
return(ftell(hFile));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::Prealloc(int64 Size)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (RawSeek(Size,SEEK_SET))
|
||||
{
|
||||
Truncate();
|
||||
Seek(0,SEEK_SET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) && defined(USE_FALLOCATE)
|
||||
// fallocate is rather new call. Only latest kernels support it.
|
||||
// So we are not using it by default yet.
|
||||
int fd = fileno(hFile);
|
||||
if (fd >= 0)
|
||||
fallocate(fd, 0, 0, Size);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
byte File::GetByte()
|
||||
{
|
||||
byte Byte=0;
|
||||
Read(&Byte,1);
|
||||
return(Byte);
|
||||
}
|
||||
|
||||
|
||||
void File::PutByte(byte Byte)
|
||||
{
|
||||
Write(&Byte,1);
|
||||
}
|
||||
|
||||
|
||||
bool File::Truncate()
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
return(SetEndOfFile(hFile)==TRUE);
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// Workaround for OpenIndiana NAS time bug. If we cannot create a file
|
||||
// in write only mode, we need to flush the write buffer before calling
|
||||
// SetFileTime or file time will not be changed.
|
||||
if (CreateMode!=FMF_UNDEFINED && (CreateMode & FMF_WRITE)==0)
|
||||
FlushFileBuffers(hFile);
|
||||
|
||||
bool sm=ftm!=NULL && ftm->IsSet();
|
||||
bool sc=ftc!=NULL && ftc->IsSet();
|
||||
bool sa=fta!=NULL && fta->IsSet();
|
||||
FILETIME fm,fc,fa;
|
||||
if (sm)
|
||||
ftm->GetWin32(&fm);
|
||||
if (sc)
|
||||
ftc->GetWin32(&fc);
|
||||
if (sa)
|
||||
fta->GetWin32(&fa);
|
||||
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::SetCloseFileTime(RarTime *ftm,RarTime *fta)
|
||||
{
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
SetCloseFileTimeByName(FileName,ftm,fta);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta)
|
||||
{
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
bool setm=ftm!=NULL && ftm->IsSet();
|
||||
bool seta=fta!=NULL && fta->IsSet();
|
||||
if (setm || seta)
|
||||
{
|
||||
utimbuf ut;
|
||||
if (setm)
|
||||
ut.modtime=ftm->GetUnix();
|
||||
else
|
||||
ut.modtime=fta->GetUnix();
|
||||
if (seta)
|
||||
ut.actime=fta->GetUnix();
|
||||
else
|
||||
ut.actime=ut.modtime;
|
||||
utime(Name,&ut);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::GetOpenFileTime(RarTime *ft)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
FILETIME FileTime;
|
||||
GetFileTime(hFile,NULL,NULL,&FileTime);
|
||||
*ft=FileTime;
|
||||
#endif
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
struct stat st;
|
||||
fstat(fileno(hFile),&st);
|
||||
*ft=st.st_mtime;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int64 File::FileLength()
|
||||
{
|
||||
SaveFilePos SavePos(*this);
|
||||
Seek(0,SEEK_END);
|
||||
return(Tell());
|
||||
}
|
||||
|
||||
|
||||
void File::SetHandleType(FILE_HANDLETYPE Type)
|
||||
{
|
||||
HandleType=Type;
|
||||
}
|
||||
|
||||
|
||||
bool File::IsDevice()
|
||||
{
|
||||
if (hFile==BAD_HANDLE)
|
||||
return(false);
|
||||
#ifdef _WIN_ALL
|
||||
uint Type=GetFileType(hFile);
|
||||
return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);
|
||||
#else
|
||||
return(isatty(fileno(hFile)));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void File::fprintf(const char *fmt,...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr,fmt);
|
||||
safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];
|
||||
vsprintf(Msg,fmt,argptr);
|
||||
#ifdef _WIN_ALL
|
||||
for (int Src=0,Dest=0;;Src++)
|
||||
{
|
||||
char CurChar=Msg[Src];
|
||||
if (CurChar=='\n')
|
||||
OutMsg[Dest++]='\r';
|
||||
OutMsg[Dest++]=CurChar;
|
||||
if (CurChar==0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
strcpy(OutMsg,Msg);
|
||||
#endif
|
||||
Write(OutMsg,strlen(OutMsg));
|
||||
va_end(argptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool File::RemoveCreated()
|
||||
{
|
||||
RemoveCreatedActive++;
|
||||
bool RetCode=true;
|
||||
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||
if (CreatedFiles[I]!=NULL)
|
||||
{
|
||||
CreatedFiles[I]->SetExceptions(false);
|
||||
bool Success;
|
||||
if (CreatedFiles[I]->NewFile)
|
||||
Success=CreatedFiles[I]->Delete();
|
||||
else
|
||||
Success=CreatedFiles[I]->Close();
|
||||
if (Success)
|
||||
CreatedFiles[I]=NULL;
|
||||
else
|
||||
RetCode=false;
|
||||
}
|
||||
RemoveCreatedActive--;
|
||||
return(RetCode);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int64 File::Copy(File &Dest,int64 Length)
|
||||
{
|
||||
Array<char> Buffer(0x10000);
|
||||
int64 CopySize=0;
|
||||
bool CopyAll=(Length==INT64NDF);
|
||||
|
||||
while (CopyAll || Length>0)
|
||||
{
|
||||
Wait();
|
||||
size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size();
|
||||
int ReadSize=Read(&Buffer[0],SizeToRead);
|
||||
if (ReadSize==0)
|
||||
break;
|
||||
Dest.Write(&Buffer[0],ReadSize);
|
||||
CopySize+=ReadSize;
|
||||
if (!CopyAll)
|
||||
Length-=ReadSize;
|
||||
}
|
||||
return(CopySize);
|
||||
}
|
||||
#endif
|
||||
@ -1,120 +0,0 @@
|
||||
#ifndef _RAR_FILE_
|
||||
#define _RAR_FILE_
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
typedef HANDLE FileHandle;
|
||||
#define BAD_HANDLE INVALID_HANDLE_VALUE
|
||||
#else
|
||||
typedef FILE* FileHandle;
|
||||
#define BAD_HANDLE NULL
|
||||
#endif
|
||||
|
||||
class RAROptions;
|
||||
|
||||
enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR};
|
||||
|
||||
enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
|
||||
|
||||
struct FileStat
|
||||
{
|
||||
uint FileAttr;
|
||||
uint FileTime;
|
||||
int64 FileSize;
|
||||
bool IsDir;
|
||||
};
|
||||
|
||||
|
||||
enum FILE_MODE_FLAGS {
|
||||
// Request read only access to file. Default for Open.
|
||||
FMF_READ=0,
|
||||
|
||||
// Request both read and write access to file. Default for Create.
|
||||
FMF_UPDATE=1,
|
||||
|
||||
// Request write only access to file.
|
||||
FMF_WRITE=2,
|
||||
|
||||
// Open files which are already opened for write by other programs.
|
||||
FMF_OPENSHARED=4,
|
||||
|
||||
// Provide read access to created file for other programs.
|
||||
FMF_SHAREREAD=8,
|
||||
|
||||
// Mode flags are not defined yet.
|
||||
FMF_UNDEFINED=256
|
||||
};
|
||||
|
||||
|
||||
class File
|
||||
{
|
||||
private:
|
||||
void AddFileToList(FileHandle hFile);
|
||||
|
||||
FileHandle hFile;
|
||||
bool LastWrite;
|
||||
FILE_HANDLETYPE HandleType;
|
||||
bool SkipClose;
|
||||
bool IgnoreReadErrors;
|
||||
bool NewFile;
|
||||
bool AllowDelete;
|
||||
bool AllowExceptions;
|
||||
#ifdef _WIN_ALL
|
||||
bool NoSequentialRead;
|
||||
uint CreateMode;
|
||||
#endif
|
||||
protected:
|
||||
bool OpenShared; // Set by 'Archive' class.
|
||||
public:
|
||||
char FileName[NM];
|
||||
wchar FileNameW[NM];
|
||||
|
||||
FILE_ERRORTYPE ErrorType;
|
||||
|
||||
uint CloseCount;
|
||||
public:
|
||||
File();
|
||||
virtual ~File();
|
||||
void operator = (File &SrcFile);
|
||||
bool Open(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_READ);
|
||||
void TOpen(const char *Name,const wchar *NameW=NULL);
|
||||
bool WOpen(const char *Name,const wchar *NameW=NULL);
|
||||
virtual bool Create(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid
|
||||
virtual void TCreate(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid
|
||||
virtual bool WCreate(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid
|
||||
virtual bool Close(); // virtual added by Kovid
|
||||
virtual void Flush(); // virtual added by Kovid
|
||||
virtual bool Delete(); // virtual added by Kovid
|
||||
virtual bool Rename(const char *NewName,const wchar *NewNameW=NULL); // virtual added by Kovid
|
||||
virtual void Write(const void *Data,size_t Size); // virtual added by Kovid
|
||||
virtual int Read(void *Data,size_t Size); // virtual added by Kovid
|
||||
virtual int DirectRead(void *Data,size_t Size); // virtual added by Kovid
|
||||
virtual void Seek(int64 Offset,int Method); // virtual added by Kovid
|
||||
virtual bool RawSeek(int64 Offset,int Method); // virtual added by Kovid
|
||||
virtual int64 Tell(); // virtual added by Kovid
|
||||
virtual void Prealloc(int64 Size); // virtual added by Kovid
|
||||
virtual byte GetByte(); // virtual added by Kovid
|
||||
virtual void PutByte(byte Byte); // virtual added by Kovid
|
||||
virtual bool Truncate(); // virtual added by Kovid
|
||||
virtual void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL); // virtual added by Kovid
|
||||
virtual void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL); // virtual added by Kovid
|
||||
static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta);
|
||||
virtual void GetOpenFileTime(RarTime *ft); // virtual added by Kovid
|
||||
virtual bool IsOpened() {return(hFile!=BAD_HANDLE);}; // virtual added by Kovid
|
||||
virtual int64 FileLength(); // virtual added by Kovid
|
||||
virtual void SetHandleType(FILE_HANDLETYPE Type); // virtual added by Kovid
|
||||
virtual FILE_HANDLETYPE GetHandleType() {return(HandleType);}; // virtual added by Kovid
|
||||
virtual bool IsDevice(); // virtual added by Kovid
|
||||
virtual void fprintf(const char *fmt,...); // virtual added by Kovid
|
||||
static bool RemoveCreated();
|
||||
virtual FileHandle GetHandle() {return(hFile);}; // virtual added by Kovid
|
||||
virtual void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;}; // virtual added by Kovid
|
||||
virtual char *GetName() {return(FileName);} // virtual added by Kovid
|
||||
virtual int64 Copy(File &Dest,int64 Length=INT64NDF); // virtual added by Kovid
|
||||
virtual void SetAllowDelete(bool Allow) {AllowDelete=Allow;} // virtual added by Kovid
|
||||
virtual void SetExceptions(bool Allow) {AllowExceptions=Allow;} // virtual added by Kovid
|
||||
#ifdef _WIN_ALL
|
||||
virtual void RemoveSequentialFlag() {NoSequentialRead=true;} // virtual added by Kovid
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,564 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
BOOL RetCode;
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
RetCode=CreateDirectoryW(NameW,NULL);
|
||||
else
|
||||
if (Name!=NULL)
|
||||
RetCode=CreateDirectoryA(Name,NULL);
|
||||
else
|
||||
return(MKDIR_BADPATH);
|
||||
if (RetCode!=0) // Non-zero return code means success for CreateDirectory.
|
||||
{
|
||||
if (SetAttr)
|
||||
SetFileAttr(Name,NameW,Attr);
|
||||
return(MKDIR_SUCCESS);
|
||||
}
|
||||
int ErrCode=GetLastError();
|
||||
if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
|
||||
return(MKDIR_BADPATH);
|
||||
return(MKDIR_ERROR);
|
||||
#else
|
||||
|
||||
// No Unicode in the rest of function, so Name must be not NULL.
|
||||
if (Name==NULL)
|
||||
return(MKDIR_BADPATH);
|
||||
#endif
|
||||
|
||||
#ifdef _EMX
|
||||
#ifdef _DJGPP
|
||||
if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0)
|
||||
#else
|
||||
if (__mkdir(Name)==0)
|
||||
#endif
|
||||
{
|
||||
if (SetAttr)
|
||||
SetFileAttr(Name,NameW,Attr);
|
||||
return(MKDIR_SUCCESS);
|
||||
}
|
||||
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
|
||||
#endif
|
||||
|
||||
#ifdef _UNIX
|
||||
mode_t uattr=SetAttr ? (mode_t)Attr:0777;
|
||||
int ErrCode=mkdir(Name,uattr);
|
||||
if (ErrCode==-1)
|
||||
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
|
||||
return(MKDIR_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool CreatePath(const char *Path,bool SkipLastName)
|
||||
{
|
||||
if (Path==NULL || *Path==0)
|
||||
return(false);
|
||||
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
uint DirAttr=0;
|
||||
#else
|
||||
uint DirAttr=0777;
|
||||
#endif
|
||||
|
||||
bool Success=true;
|
||||
|
||||
for (const char *s=Path;*s!=0;s=charnext(s))
|
||||
{
|
||||
if (s-Path>=NM)
|
||||
break;
|
||||
|
||||
// Process all kinds of path separators, so user can enter Unix style
|
||||
// path in Windows or Windows in Unix.
|
||||
if (IsPathDiv(*s))
|
||||
{
|
||||
char DirName[NM];
|
||||
strncpy(DirName,Path,s-Path);
|
||||
DirName[s-Path]=0;
|
||||
|
||||
if (MakeDir(DirName,NULL,true,DirAttr)==MKDIR_SUCCESS)
|
||||
{
|
||||
#ifndef GUI
|
||||
mprintf(St(MCreatDir),DirName);
|
||||
mprintf(" %s",St(MOk));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
Success=false;
|
||||
}
|
||||
}
|
||||
if (!SkipLastName)
|
||||
if (!IsPathDiv(*PointToLastChar(Path)))
|
||||
if (MakeDir(Path,NULL,true,DirAttr)!=MKDIR_SUCCESS)
|
||||
Success=false;
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
bool CreatePath(const wchar *Path,bool SkipLastName)
|
||||
{
|
||||
if (Path==NULL || *Path==0)
|
||||
return(false);
|
||||
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
uint DirAttr=0;
|
||||
#else
|
||||
uint DirAttr=0777;
|
||||
#endif
|
||||
|
||||
bool Success=true;
|
||||
|
||||
for (const wchar *s=Path;*s!=0;s++)
|
||||
{
|
||||
if (s-Path>=NM)
|
||||
break;
|
||||
|
||||
// Process all kinds of path separators, so user can enter Unix style
|
||||
// path in Windows or Windows in Unix.
|
||||
if (IsPathDiv(*s))
|
||||
{
|
||||
wchar DirName[NM];
|
||||
wcsncpy(DirName,Path,s-Path);
|
||||
DirName[s-Path]=0;
|
||||
|
||||
if (MakeDir(NULL,DirName,true,DirAttr)==MKDIR_SUCCESS)
|
||||
{
|
||||
#ifndef GUI
|
||||
char DirNameA[NM];
|
||||
WideToChar(DirName,DirNameA,ASIZE(DirNameA));
|
||||
DirNameA[ASIZE(DirNameA)-1]=0;
|
||||
mprintf(St(MCreatDir),DirNameA);
|
||||
mprintf(" %s",St(MOk));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
Success=false;
|
||||
}
|
||||
}
|
||||
if (!SkipLastName)
|
||||
if (!IsPathDiv(*PointToLastChar(Path)))
|
||||
if (MakeDir(NULL,Path,true,DirAttr)!=MKDIR_SUCCESS)
|
||||
Success=false;
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// If we are in Windows, let's try Unicode path first. In Unix we do not
|
||||
// need it (Unix MakeDir will fails with Unicode only name).
|
||||
if (PathW!=NULL && *PathW!=0)
|
||||
return(CreatePath(PathW,SkipLastName));
|
||||
#endif
|
||||
if (Path!=NULL && *Path!=0)
|
||||
return(CreatePath(Path,SkipLastName));
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (!WinNT())
|
||||
return;
|
||||
|
||||
bool sm=ftm!=NULL && ftm->IsSet();
|
||||
bool sc=ftc!=NULL && ftc->IsSet();
|
||||
bool sa=fta!=NULL && fta->IsSet();
|
||||
|
||||
unsigned int DirAttr=GetFileAttr(Name,NameW);
|
||||
bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0);
|
||||
if (ResetAttr)
|
||||
SetFileAttr(Name,NameW,0);
|
||||
|
||||
wchar DirNameW[NM];
|
||||
GetWideName(Name,NameW,DirNameW,ASIZE(DirNameW));
|
||||
HANDLE hFile=CreateFileW(DirNameW,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
|
||||
if (hFile==INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
FILETIME fm,fc,fa;
|
||||
if (sm)
|
||||
ftm->GetWin32(&fm);
|
||||
if (sc)
|
||||
ftc->GetWin32(&fc);
|
||||
if (sa)
|
||||
fta->GetWin32(&fa);
|
||||
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
|
||||
CloseHandle(hFile);
|
||||
if (ResetAttr)
|
||||
SetFileAttr(Name,NameW,DirAttr);
|
||||
#endif
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
File::SetCloseFileTimeByName(Name,ftm,fta);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool IsRemovable(const char *Name)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
char Root[NM];
|
||||
GetPathRoot(Name,Root);
|
||||
int Type=GetDriveTypeA(*Root!=0 ? Root:NULL);
|
||||
return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
|
||||
#elif defined(_EMX)
|
||||
char Drive=etoupper(Name[0]);
|
||||
return((Drive=='A' || Drive=='B') && Name[1]==':');
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int64 GetFreeDisk(const char *Name)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
char Root[NM];
|
||||
GetPathRoot(Name,Root);
|
||||
|
||||
typedef BOOL (WINAPI *GETDISKFREESPACEEX)(
|
||||
LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER
|
||||
);
|
||||
static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL;
|
||||
|
||||
if (pGetDiskFreeSpaceEx==NULL)
|
||||
{
|
||||
HMODULE hKernel=GetModuleHandleW(L"kernel32.dll");
|
||||
if (hKernel!=NULL)
|
||||
pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA");
|
||||
}
|
||||
if (pGetDiskFreeSpaceEx!=NULL)
|
||||
{
|
||||
GetFilePath(Name,Root,ASIZE(Root));
|
||||
ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
|
||||
uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
|
||||
if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
|
||||
uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
|
||||
return(INT32TO64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
|
||||
}
|
||||
|
||||
// We are here if we failed to load GetDiskFreeSpaceExA.
|
||||
DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
|
||||
if (!GetDiskFreeSpaceA(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters))
|
||||
return(1457664);
|
||||
int64 FreeSize=SectorsPerCluster*BytesPerSector;
|
||||
FreeSize=FreeSize*FreeClusters;
|
||||
return(FreeSize);
|
||||
#elif defined(_BEOS)
|
||||
char Root[NM];
|
||||
GetFilePath(Name,Root,ASIZE(Root));
|
||||
dev_t Dev=dev_for_path(*Root ? Root:".");
|
||||
if (Dev<0)
|
||||
return(1457664);
|
||||
fs_info Info;
|
||||
if (fs_stat_dev(Dev,&Info)!=0)
|
||||
return(1457664);
|
||||
int64 FreeSize=Info.block_size;
|
||||
FreeSize=FreeSize*Info.free_blocks;
|
||||
return(FreeSize);
|
||||
#elif defined(_UNIX)
|
||||
return(1457664);
|
||||
#elif defined(_EMX)
|
||||
int Drive=IsDiskLetter(Name) ? etoupper(Name[0])-'A'+1:0;
|
||||
#ifndef _DJGPP
|
||||
if (_osmode == OS2_MODE)
|
||||
{
|
||||
FSALLOCATE fsa;
|
||||
if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0)
|
||||
return(1457664);
|
||||
int64 FreeSize=fsa.cSectorUnit*fsa.cbSector;
|
||||
FreeSize=FreeSize*fsa.cUnitAvail;
|
||||
return(FreeSize);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
union REGS regs,outregs;
|
||||
memset(®s,0,sizeof(regs));
|
||||
regs.h.ah=0x36;
|
||||
regs.h.dl=Drive;
|
||||
#ifdef _DJGPP
|
||||
int86 (0x21,®s,&outregs);
|
||||
#else
|
||||
_int86 (0x21,®s,&outregs);
|
||||
#endif
|
||||
if (outregs.x.ax==0xffff)
|
||||
return(1457664);
|
||||
int64 FreeSize=outregs.x.ax*outregs.x.cx;
|
||||
FreeSize=FreeSize*outregs.x.bx;
|
||||
return(FreeSize);
|
||||
}
|
||||
#else
|
||||
#define DISABLEAUTODETECT
|
||||
return(1457664);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool FileExist(const char *Name,const wchar *NameW)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
return(GetFileAttributesW(NameW)!=0xffffffff);
|
||||
else
|
||||
return(Name!=NULL && GetFileAttributesA(Name)!=0xffffffff);
|
||||
#elif defined(ENABLE_ACCESS)
|
||||
return(access(Name,0)==0);
|
||||
#else
|
||||
FindData FD;
|
||||
return(FindFile::FastFind(Name,NameW,&FD));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool FileExist(const wchar *Name)
|
||||
{
|
||||
return FileExist(NULL,Name);
|
||||
}
|
||||
|
||||
|
||||
bool WildFileExist(const char *Name,const wchar *NameW)
|
||||
{
|
||||
if (IsWildcard(Name,NameW))
|
||||
{
|
||||
FindFile Find;
|
||||
Find.SetMask(Name);
|
||||
Find.SetMaskW(NameW);
|
||||
FindData fd;
|
||||
return(Find.Next(&fd));
|
||||
}
|
||||
return(FileExist(Name,NameW));
|
||||
}
|
||||
|
||||
|
||||
bool IsDir(uint Attr)
|
||||
{
|
||||
#if defined (_WIN_ALL) || defined(_EMX)
|
||||
return(Attr!=0xffffffff && (Attr & 0x10)!=0);
|
||||
#endif
|
||||
#if defined(_UNIX)
|
||||
return((Attr & 0xF000)==0x4000);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool IsUnreadable(uint Attr)
|
||||
{
|
||||
#if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
|
||||
return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool IsLabel(uint Attr)
|
||||
{
|
||||
#if defined (_WIN_ALL) || defined(_EMX)
|
||||
return((Attr & 8)!=0);
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool IsLink(uint Attr)
|
||||
{
|
||||
#ifdef _UNIX
|
||||
return((Attr & 0xF000)==0xA000);
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IsDeleteAllowed(uint FileAttr)
|
||||
{
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0);
|
||||
#else
|
||||
return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PrepareToDelete(const char *Name,const wchar *NameW)
|
||||
{
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
SetFileAttr(Name,NameW,0);
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
if (Name!=NULL)
|
||||
chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint GetFileAttr(const char *Name,const wchar *NameW)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
return(GetFileAttributesW(NameW));
|
||||
else
|
||||
return(GetFileAttributesA(Name));
|
||||
#elif defined(_DJGPP)
|
||||
return(_chmod(Name,0));
|
||||
#else
|
||||
struct stat st;
|
||||
if (stat(Name,&st)!=0)
|
||||
return(0);
|
||||
#ifdef _EMX
|
||||
return(st.st_attr);
|
||||
#else
|
||||
return(st.st_mode);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr)
|
||||
{
|
||||
bool Success;
|
||||
#ifdef _WIN_ALL
|
||||
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||
Success=SetFileAttributesW(NameW,Attr)!=0;
|
||||
else
|
||||
if (Name!=NULL)
|
||||
Success=SetFileAttributesA(Name,Attr)!=0;
|
||||
else
|
||||
Success=false;
|
||||
#elif defined(_DJGPP)
|
||||
Success=_chmod(Name,1,Attr)!=-1;
|
||||
#elif defined(_EMX)
|
||||
Success=__chmod(Name,1,Attr)!=-1;
|
||||
#elif defined(_UNIX)
|
||||
Success=chmod(Name,(mode_t)Attr)==0;
|
||||
#else
|
||||
Success=false;
|
||||
#endif
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
uint CalcFileCRC(File *SrcFile,int64 Size,CALCCRC_SHOWMODE ShowMode)
|
||||
{
|
||||
SaveFilePos SavePos(*SrcFile);
|
||||
const size_t BufSize=0x10000;
|
||||
Array<byte> Data(BufSize);
|
||||
int64 BlockCount=0;
|
||||
uint DataCRC=0xffffffff;
|
||||
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
int64 FileLength=SrcFile->FileLength();
|
||||
if (ShowMode!=CALCCRC_SHOWNONE)
|
||||
{
|
||||
mprintf(St(MCalcCRC));
|
||||
mprintf(" ");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SrcFile->Seek(0,SEEK_SET);
|
||||
while (true)
|
||||
{
|
||||
size_t SizeToRead;
|
||||
if (Size==INT64NDF) // If we process the entire file.
|
||||
SizeToRead=BufSize; // Then always attempt to read the entire buffer.
|
||||
else
|
||||
SizeToRead=(size_t)Min((int64)BufSize,Size);
|
||||
int ReadSize=SrcFile->Read(&Data[0],SizeToRead);
|
||||
if (ReadSize==0)
|
||||
break;
|
||||
|
||||
++BlockCount;
|
||||
if ((BlockCount & 15)==0)
|
||||
{
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
if (ShowMode==CALCCRC_SHOWALL)
|
||||
mprintf("\b\b\b\b%3d%%",ToPercent(BlockCount*int64(BufSize),FileLength));
|
||||
#endif
|
||||
Wait();
|
||||
}
|
||||
DataCRC=CRC(DataCRC,&Data[0],ReadSize);
|
||||
if (Size!=INT64NDF)
|
||||
Size-=ReadSize;
|
||||
}
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
if (ShowMode==CALCCRC_SHOWALL)
|
||||
mprintf("\b\b\b\b ");
|
||||
#endif
|
||||
return(DataCRC^0xffffffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW)
|
||||
{
|
||||
return(rename(SrcName,DestName)==0);
|
||||
}
|
||||
|
||||
|
||||
bool DelFile(const char *Name)
|
||||
{
|
||||
return(DelFile(Name,NULL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool DelFile(const char *Name,const wchar *NameW)
|
||||
{
|
||||
return(Name!=NULL && remove(Name)==0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE)
|
||||
bool SetFileCompression(char *Name,wchar *NameW,bool State)
|
||||
{
|
||||
wchar FileNameW[NM];
|
||||
GetWideName(Name,NameW,FileNameW,ASIZE(FileNameW));
|
||||
HANDLE hFile=CreateFileW(FileNameW,FILE_READ_DATA|FILE_WRITE_DATA,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
|
||||
if (hFile==INVALID_HANDLE_VALUE)
|
||||
return(false);
|
||||
SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE;
|
||||
DWORD Result;
|
||||
int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState,
|
||||
sizeof(NewState),NULL,0,&Result,NULL);
|
||||
CloseHandle(hFile);
|
||||
return(RetCode!=0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
#ifndef _RAR_FILEFN_
|
||||
#define _RAR_FILEFN_
|
||||
|
||||
enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
|
||||
|
||||
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr);
|
||||
bool CreatePath(const char *Path,bool SkipLastName);
|
||||
bool CreatePath(const wchar *Path,bool SkipLastName);
|
||||
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
|
||||
void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta);
|
||||
bool IsRemovable(const char *Name);
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int64 GetFreeDisk(const char *Name);
|
||||
#endif
|
||||
|
||||
|
||||
bool FileExist(const char *Name,const wchar *NameW=NULL);
|
||||
bool FileExist(const wchar *Name);
|
||||
bool WildFileExist(const char *Name,const wchar *NameW=NULL);
|
||||
bool IsDir(uint Attr);
|
||||
bool IsUnreadable(uint Attr);
|
||||
bool IsLabel(uint Attr);
|
||||
bool IsLink(uint Attr);
|
||||
void SetSFXMode(const char *FileName);
|
||||
void EraseDiskContents(const char *FileName);
|
||||
bool IsDeleteAllowed(uint FileAttr);
|
||||
void PrepareToDelete(const char *Name,const wchar *NameW=NULL);
|
||||
uint GetFileAttr(const char *Name,const wchar *NameW=NULL);
|
||||
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr);
|
||||
|
||||
enum CALCCRC_SHOWMODE {CALCCRC_SHOWNONE,CALCCRC_SHOWTEXT,CALCCRC_SHOWALL};
|
||||
uint CalcFileCRC(File *SrcFile,int64 Size=INT64NDF,CALCCRC_SHOWMODE ShowMode=CALCCRC_SHOWNONE);
|
||||
|
||||
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW);
|
||||
bool DelFile(const char *Name);
|
||||
bool DelFile(const char *Name,const wchar *NameW);
|
||||
bool DelDir(const char *Name);
|
||||
bool DelDir(const char *Name,const wchar *NameW);
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
bool SetFileCompression(char *Name,wchar *NameW,bool State);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,208 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
static bool IsUnicode(byte *Data,int Size);
|
||||
|
||||
bool ReadTextFile(
|
||||
const char *Name,
|
||||
const wchar *NameW,
|
||||
StringList *List,
|
||||
bool Config,
|
||||
bool AbortOnError,
|
||||
RAR_CHARSET SrcCharset,
|
||||
bool Unquote,
|
||||
bool SkipComments,
|
||||
bool ExpandEnvStr)
|
||||
{
|
||||
char FileName[NM];
|
||||
*FileName=0;
|
||||
if (Name!=NULL)
|
||||
if (Config)
|
||||
GetConfigName(Name,FileName,true);
|
||||
else
|
||||
strcpy(FileName,Name);
|
||||
|
||||
wchar FileNameW[NM];
|
||||
*FileNameW=0;
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
if (NameW!=NULL)
|
||||
if (Config)
|
||||
GetConfigName(NameW,FileNameW,true);
|
||||
else
|
||||
wcscpy(FileNameW,NameW);
|
||||
#endif
|
||||
|
||||
File SrcFile;
|
||||
if (FileName!=NULL && *FileName!=0 || FileNameW!=NULL && *FileNameW!=0)
|
||||
{
|
||||
bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName,FileNameW):SrcFile.Open(FileName,FileNameW,0);
|
||||
|
||||
if (!OpenCode)
|
||||
{
|
||||
if (AbortOnError)
|
||||
ErrHandler.Exit(RARX_OPEN);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||
|
||||
unsigned int DataSize=0,ReadSize;
|
||||
const int ReadBlock=1024;
|
||||
Array<char> Data(ReadBlock+5);
|
||||
while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0)
|
||||
{
|
||||
DataSize+=ReadSize;
|
||||
Data.Add(ReadSize);
|
||||
}
|
||||
|
||||
memset(&Data[DataSize],0,5);
|
||||
|
||||
if (SrcCharset==RCH_UNICODE ||
|
||||
SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize))
|
||||
{
|
||||
// Unicode in native system format, can be more than 2 bytes per character.
|
||||
Array<wchar> DataW(Data.Size()/2+1);
|
||||
for (size_t I=2;I<Data.Size()-1;I+=2)
|
||||
{
|
||||
// Need to convert Data to (byte) first to prevent the sign extension
|
||||
// to higher bytes.
|
||||
DataW[(I-2)/2]=(wchar)((byte)Data[I])+(wchar)((byte)Data[I+1])*256;
|
||||
}
|
||||
|
||||
wchar *CurStr=&DataW[0];
|
||||
Array<char> AnsiName;
|
||||
|
||||
while (*CurStr!=0)
|
||||
{
|
||||
wchar *NextStr=CurStr,*CmtPtr=NULL;
|
||||
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
|
||||
{
|
||||
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
|
||||
{
|
||||
*NextStr=0;
|
||||
CmtPtr=NextStr;
|
||||
}
|
||||
NextStr++;
|
||||
}
|
||||
*NextStr=0;
|
||||
for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
|
||||
{
|
||||
if (*SpacePtr!=' ' && *SpacePtr!='\t')
|
||||
break;
|
||||
*SpacePtr=0;
|
||||
}
|
||||
if (*CurStr)
|
||||
{
|
||||
// Length and AddSize must be defined as signed, because AddSize
|
||||
// can be negative.
|
||||
int Length=(int)wcslen(CurStr);
|
||||
int AddSize=4*(Length-(int)AnsiName.Size()+1);
|
||||
|
||||
if (AddSize>0)
|
||||
AnsiName.Add(AddSize);
|
||||
if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"')
|
||||
{
|
||||
CurStr[Length-1]=0;
|
||||
CurStr++;
|
||||
}
|
||||
WideToChar(CurStr,&AnsiName[0],AnsiName.Size());
|
||||
|
||||
bool Expanded=false;
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
if (ExpandEnvStr && *CurStr=='%')
|
||||
{
|
||||
// Expanding environment variables in Windows version.
|
||||
|
||||
char ExpName[NM];
|
||||
wchar ExpNameW[NM];
|
||||
*ExpNameW=0;
|
||||
int ret,retw=1;
|
||||
ret=ExpandEnvironmentStringsA(&AnsiName[0],ExpName,ASIZE(ExpName));
|
||||
if (ret!=0 && WinNT())
|
||||
retw=ExpandEnvironmentStringsW(CurStr,ExpNameW,ASIZE(ExpNameW));
|
||||
Expanded=ret!=0 && ret<ASIZE(ExpName) &&
|
||||
retw!=0 && retw<ASIZE(ExpNameW);
|
||||
if (Expanded)
|
||||
List->AddString(ExpName,ExpNameW);
|
||||
}
|
||||
#endif
|
||||
if (!Expanded)
|
||||
List->AddString(&AnsiName[0],CurStr);
|
||||
}
|
||||
CurStr=NextStr+1;
|
||||
while (*CurStr=='\r' || *CurStr=='\n')
|
||||
CurStr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *CurStr=&Data[0];
|
||||
while (*CurStr!=0)
|
||||
{
|
||||
char *NextStr=CurStr,*CmtPtr=NULL;
|
||||
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
|
||||
{
|
||||
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
|
||||
{
|
||||
*NextStr=0;
|
||||
CmtPtr=NextStr;
|
||||
}
|
||||
NextStr++;
|
||||
}
|
||||
*NextStr=0;
|
||||
for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
|
||||
{
|
||||
if (*SpacePtr!=' ' && *SpacePtr!='\t')
|
||||
break;
|
||||
*SpacePtr=0;
|
||||
}
|
||||
if (*CurStr)
|
||||
{
|
||||
if (Unquote && *CurStr=='\"')
|
||||
{
|
||||
size_t Length=strlen(CurStr);
|
||||
if (CurStr[Length-1]=='\"')
|
||||
{
|
||||
CurStr[Length-1]=0;
|
||||
CurStr++;
|
||||
}
|
||||
}
|
||||
#if defined(_WIN_ALL)
|
||||
if (SrcCharset==RCH_OEM)
|
||||
OemToCharA(CurStr,CurStr);
|
||||
#endif
|
||||
|
||||
bool Expanded=false;
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
if (ExpandEnvStr && *CurStr=='%')
|
||||
{
|
||||
// Expanding environment variables in Windows version.
|
||||
char ExpName[NM];
|
||||
int ret=ExpandEnvironmentStringsA(CurStr,ExpName,ASIZE(ExpName));
|
||||
Expanded=ret!=0 && ret<ASIZE(ExpName);
|
||||
if (Expanded)
|
||||
List->AddString(ExpName);
|
||||
}
|
||||
#endif
|
||||
if (!Expanded)
|
||||
List->AddString(CurStr);
|
||||
}
|
||||
CurStr=NextStr+1;
|
||||
while (*CurStr=='\r' || *CurStr=='\n')
|
||||
CurStr++;
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool IsUnicode(byte *Data,int Size)
|
||||
{
|
||||
if (Size<4 || Data[0]!=0xff || Data[1]!=0xfe)
|
||||
return(false);
|
||||
for (int I=2;I<Size;I++)
|
||||
if (Data[I]<32 && Data[I]!='\r' && Data[I]!='\n')
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef _RAR_FILESTR_
|
||||
#define _RAR_FILESTR_
|
||||
|
||||
bool ReadTextFile(
|
||||
const char *Name,
|
||||
const wchar *NameW,
|
||||
StringList *List,
|
||||
bool Config,
|
||||
bool AbortOnError=false,
|
||||
RAR_CHARSET SrcCharset=RCH_DEFAULT,
|
||||
bool Unquote=false,
|
||||
bool SkipComments=false,
|
||||
bool ExpandEnvStr=false
|
||||
);
|
||||
|
||||
#endif
|
||||
@ -1,291 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
FindFile::FindFile()
|
||||
{
|
||||
*FindMask=0;
|
||||
*FindMaskW=0;
|
||||
FirstCall=true;
|
||||
#ifdef _WIN_ALL
|
||||
hFind=INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
dirp=NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FindFile::~FindFile()
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if (hFind!=INVALID_HANDLE_VALUE)
|
||||
FindClose(hFind);
|
||||
#else
|
||||
if (dirp!=NULL)
|
||||
closedir(dirp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FindFile::SetMask(const char *FindMask)
|
||||
{
|
||||
strcpy(FindFile::FindMask,NullToEmpty(FindMask));
|
||||
if (*FindMaskW==0)
|
||||
CharToWide(FindMask,FindMaskW);
|
||||
FirstCall=true;
|
||||
}
|
||||
|
||||
|
||||
void FindFile::SetMaskW(const wchar *FindMaskW)
|
||||
{
|
||||
if (FindMaskW==NULL)
|
||||
return;
|
||||
wcscpy(FindFile::FindMaskW,FindMaskW);
|
||||
if (*FindMask==0)
|
||||
WideToChar(FindMaskW,FindMask);
|
||||
FirstCall=true;
|
||||
}
|
||||
|
||||
|
||||
bool FindFile::Next(struct FindData *fd,bool GetSymLink)
|
||||
{
|
||||
fd->Error=false;
|
||||
if (*FindMask==0)
|
||||
return(false);
|
||||
#ifdef _WIN_ALL
|
||||
if (FirstCall)
|
||||
{
|
||||
if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
|
||||
return(false);
|
||||
#else
|
||||
if (FirstCall)
|
||||
{
|
||||
char DirName[NM];
|
||||
strcpy(DirName,FindMask);
|
||||
RemoveNameFromPath(DirName);
|
||||
if (*DirName==0)
|
||||
strcpy(DirName,".");
|
||||
if ((dirp=opendir(DirName))==NULL)
|
||||
{
|
||||
fd->Error=(errno!=ENOENT);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
struct dirent *ent=readdir(dirp);
|
||||
if (ent==NULL)
|
||||
return(false);
|
||||
if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
|
||||
continue;
|
||||
if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
|
||||
{
|
||||
char FullName[NM];
|
||||
strcpy(FullName,FindMask);
|
||||
*PointToName(FullName)=0;
|
||||
if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1)
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(NULL,"\n%s%s",FullName,ent->d_name);
|
||||
Log(NULL,St(MPathTooLong));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
strcat(FullName,ent->d_name);
|
||||
if (!FastFind(FullName,NULL,fd,GetSymLink))
|
||||
{
|
||||
ErrHandler.OpenErrorMsg(FullName);
|
||||
continue;
|
||||
}
|
||||
strcpy(fd->Name,FullName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*fd->NameW=0;
|
||||
#ifdef _APPLE
|
||||
if (!LowAscii(fd->Name))
|
||||
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
|
||||
#elif defined(UNICODE_SUPPORTED)
|
||||
if (!LowAscii(fd->Name) && UnicodeEnabled())
|
||||
CharToWide(fd->Name,fd->NameW);
|
||||
#endif
|
||||
#endif
|
||||
fd->Flags=0;
|
||||
fd->IsDir=IsDir(fd->FileAttr);
|
||||
FirstCall=false;
|
||||
char *Name=PointToName(fd->Name);
|
||||
if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
|
||||
return(Next(fd));
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,FindData *fd,bool GetSymLink)
|
||||
{
|
||||
fd->Error=false;
|
||||
#ifndef _UNIX
|
||||
if (IsWildcard(FindMask,FindMaskW))
|
||||
return(false);
|
||||
#endif
|
||||
#ifdef _WIN_ALL
|
||||
HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
|
||||
if (hFind==INVALID_HANDLE_VALUE)
|
||||
return(false);
|
||||
FindClose(hFind);
|
||||
#else
|
||||
struct stat st;
|
||||
if (GetSymLink)
|
||||
{
|
||||
#ifdef SAVE_LINKS
|
||||
if (lstat(FindMask,&st)!=0)
|
||||
#else
|
||||
if (stat(FindMask,&st)!=0)
|
||||
#endif
|
||||
{
|
||||
fd->Error=(errno!=ENOENT);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (stat(FindMask,&st)!=0)
|
||||
{
|
||||
fd->Error=(errno!=ENOENT);
|
||||
return(false);
|
||||
}
|
||||
#ifdef _DJGPP
|
||||
fd->FileAttr=_chmod(FindMask,0);
|
||||
#elif defined(_EMX)
|
||||
fd->FileAttr=st.st_attr;
|
||||
#else
|
||||
fd->FileAttr=st.st_mode;
|
||||
#endif
|
||||
fd->IsDir=IsDir(st.st_mode);
|
||||
fd->Size=st.st_size;
|
||||
fd->mtime=st.st_mtime;
|
||||
fd->atime=st.st_atime;
|
||||
fd->ctime=st.st_ctime;
|
||||
fd->FileTime=fd->mtime.GetDos();
|
||||
strcpy(fd->Name,FindMask);
|
||||
|
||||
*fd->NameW=0;
|
||||
#ifdef _APPLE
|
||||
if (!LowAscii(fd->Name))
|
||||
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
|
||||
#elif defined(UNICODE_SUPPORTED)
|
||||
if (!LowAscii(fd->Name) && UnicodeEnabled())
|
||||
CharToWide(fd->Name,fd->NameW);
|
||||
#endif
|
||||
#endif
|
||||
fd->Flags=0;
|
||||
fd->IsDir=IsDir(fd->FileAttr);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,FindData *fd)
|
||||
{
|
||||
#ifndef _WIN_CE
|
||||
if (WinNT())
|
||||
#endif
|
||||
{
|
||||
wchar WideMask[NM];
|
||||
if (MaskW!=NULL && *MaskW!=0)
|
||||
wcscpy(WideMask,MaskW);
|
||||
else
|
||||
CharToWide(Mask,WideMask);
|
||||
|
||||
WIN32_FIND_DATAW FindData;
|
||||
if (hFind==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hFind=FindFirstFileW(WideMask,&FindData);
|
||||
if (hFind==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int SysErr=GetLastError();
|
||||
fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
|
||||
SysErr!=ERROR_PATH_NOT_FOUND &&
|
||||
SysErr!=ERROR_NO_MORE_FILES);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!FindNextFileW(hFind,&FindData))
|
||||
{
|
||||
hFind=INVALID_HANDLE_VALUE;
|
||||
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
if (hFind!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
wcscpy(fd->NameW,WideMask);
|
||||
wcscpy(PointToName(fd->NameW),FindData.cFileName);
|
||||
WideToChar(fd->NameW,fd->Name);
|
||||
fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
|
||||
fd->FileAttr=FindData.dwFileAttributes;
|
||||
wcscpy(fd->ShortName,FindData.cAlternateFileName);
|
||||
fd->ftCreationTime=FindData.ftCreationTime;
|
||||
fd->ftLastAccessTime=FindData.ftLastAccessTime;
|
||||
fd->ftLastWriteTime=FindData.ftLastWriteTime;
|
||||
fd->mtime=FindData.ftLastWriteTime;
|
||||
fd->ctime=FindData.ftCreationTime;
|
||||
fd->atime=FindData.ftLastAccessTime;
|
||||
fd->FileTime=fd->mtime.GetDos();
|
||||
|
||||
#ifndef _WIN_CE
|
||||
// if (LowAscii(fd->NameW))
|
||||
// *fd->NameW=0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef _WIN_CE
|
||||
else
|
||||
{
|
||||
char CharMask[NM];
|
||||
if (Mask!=NULL && *Mask!=0)
|
||||
strcpy(CharMask,Mask);
|
||||
else
|
||||
WideToChar(MaskW,CharMask);
|
||||
|
||||
WIN32_FIND_DATAA FindData;
|
||||
if (hFind==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hFind=FindFirstFileA(CharMask,&FindData);
|
||||
if (hFind==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int SysErr=GetLastError();
|
||||
fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!FindNextFileA(hFind,&FindData))
|
||||
{
|
||||
hFind=INVALID_HANDLE_VALUE;
|
||||
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
if (hFind!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
strcpy(fd->Name,CharMask);
|
||||
strcpy(PointToName(fd->Name),FindData.cFileName);
|
||||
CharToWide(fd->Name,fd->NameW);
|
||||
fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
|
||||
fd->FileAttr=FindData.dwFileAttributes;
|
||||
CharToWide(FindData.cAlternateFileName,fd->ShortName);
|
||||
fd->ftCreationTime=FindData.ftCreationTime;
|
||||
fd->ftLastAccessTime=FindData.ftLastAccessTime;
|
||||
fd->ftLastWriteTime=FindData.ftLastWriteTime;
|
||||
fd->mtime=FindData.ftLastWriteTime;
|
||||
fd->ctime=FindData.ftCreationTime;
|
||||
fd->atime=FindData.ftLastAccessTime;
|
||||
fd->FileTime=fd->mtime.GetDos();
|
||||
// if (LowAscii(fd->Name))
|
||||
// *fd->NameW=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fd->Flags=0;
|
||||
return(hFind);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
#ifndef _RAR_FINDDATA_
|
||||
#define _RAR_FINDDATA_
|
||||
|
||||
enum FINDDATA_FLAGS {
|
||||
FDDF_SECONDDIR=1 // Second encounter of same directory in SCAN_GETDIRSTWICE ScanTree mode.
|
||||
};
|
||||
|
||||
struct FindData
|
||||
{
|
||||
char Name[NM];
|
||||
wchar NameW[NM];
|
||||
int64 Size;
|
||||
uint FileAttr;
|
||||
uint FileTime;
|
||||
bool IsDir;
|
||||
RarTime mtime;
|
||||
RarTime ctime;
|
||||
RarTime atime;
|
||||
#ifdef _WIN_ALL
|
||||
wchar ShortName[NM];
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
#endif
|
||||
uint Flags;
|
||||
bool Error;
|
||||
};
|
||||
|
||||
class FindFile
|
||||
{
|
||||
private:
|
||||
#ifdef _WIN_ALL
|
||||
static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd);
|
||||
#endif
|
||||
|
||||
char FindMask[NM];
|
||||
wchar FindMaskW[NM];
|
||||
bool FirstCall;
|
||||
#ifdef _WIN_ALL
|
||||
HANDLE hFind;
|
||||
#else
|
||||
DIR *dirp;
|
||||
#endif
|
||||
public:
|
||||
FindFile();
|
||||
~FindFile();
|
||||
void SetMask(const char *FindMask);
|
||||
void SetMaskW(const wchar *FindMaskW);
|
||||
bool Next(FindData *fd,bool GetSymLink=false);
|
||||
static bool FastFind(const char *FindMask,const wchar *FindMaskW,FindData *fd,bool GetSymLink=false);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,35 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
BitInput::BitInput()
|
||||
{
|
||||
// getbits attempts to read data from InAddr, InAddr+1, InAddr+2 positions.
|
||||
// So let's allocate two additional bytes for situation, when we need to
|
||||
// read only 1 byte from the last position of buffer and avoid a crash
|
||||
// from access to next 2 bytes, which contents we do not need.
|
||||
size_t BufSize=MAX_SIZE+2;
|
||||
InBuf=new byte[BufSize];
|
||||
|
||||
// Ensure that we get predictable results when accessing bytes in area
|
||||
// not filled with read data.
|
||||
memset(InBuf,0,BufSize);
|
||||
}
|
||||
|
||||
|
||||
BitInput::~BitInput()
|
||||
{
|
||||
delete[] InBuf;
|
||||
}
|
||||
|
||||
|
||||
void BitInput::faddbits(uint Bits)
|
||||
{
|
||||
// Function wrapped version of inline addbits to save code size.
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
|
||||
uint BitInput::fgetbits()
|
||||
{
|
||||
// Function wrapped version of inline getbits to save code size.
|
||||
return(getbits());
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
#ifndef _RAR_GETBITS_
|
||||
#define _RAR_GETBITS_
|
||||
|
||||
class BitInput
|
||||
{
|
||||
public:
|
||||
enum BufferSize {MAX_SIZE=0x8000}; // Size of input buffer.
|
||||
protected:
|
||||
int InAddr; // Curent byte position in the buffer.
|
||||
int InBit; // Current bit position in the current byte.
|
||||
public:
|
||||
BitInput();
|
||||
~BitInput();
|
||||
|
||||
byte *InBuf; // Dynamically allocated input buffer.
|
||||
|
||||
void InitBitInput()
|
||||
{
|
||||
InAddr=InBit=0;
|
||||
}
|
||||
|
||||
// Move forward by 'Bits' bits.
|
||||
void addbits(uint Bits)
|
||||
{
|
||||
Bits+=InBit;
|
||||
InAddr+=Bits>>3;
|
||||
InBit=Bits&7;
|
||||
}
|
||||
|
||||
// Return 16 bits from current position in the buffer.
|
||||
// Bit at (InAddr,InBit) has the highest position in returning data.
|
||||
uint getbits()
|
||||
{
|
||||
uint BitField=(uint)InBuf[InAddr] << 16;
|
||||
BitField|=(uint)InBuf[InAddr+1] << 8;
|
||||
BitField|=(uint)InBuf[InAddr+2];
|
||||
BitField >>= (8-InBit);
|
||||
return(BitField & 0xffff);
|
||||
}
|
||||
|
||||
void faddbits(uint Bits);
|
||||
uint fgetbits();
|
||||
|
||||
// Check if buffer has enough space for IncPtr bytes. Returns 'true'
|
||||
// if buffer will be overflown.
|
||||
bool Overflow(uint IncPtr)
|
||||
{
|
||||
return(InAddr+IncPtr>=MAX_SIZE);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@ -1,4 +0,0 @@
|
||||
#define INCLUDEGLOBAL
|
||||
|
||||
|
||||
#include "rar.hpp"
|
||||
@ -1,15 +0,0 @@
|
||||
#ifndef _RAR_GLOBAL_
|
||||
#define _RAR_GLOBAL_
|
||||
|
||||
#ifdef INCLUDEGLOBAL
|
||||
#define EXTVAR
|
||||
#else
|
||||
#define EXTVAR extern
|
||||
#endif
|
||||
|
||||
EXTVAR ErrorHandler ErrHandler;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,327 +0,0 @@
|
||||
#ifndef _RAR_HEADERS_
|
||||
#define _RAR_HEADERS_
|
||||
|
||||
#define SIZEOF_MARKHEAD 7
|
||||
#define SIZEOF_OLDMHD 7
|
||||
#define SIZEOF_NEWMHD 13
|
||||
#define SIZEOF_OLDLHD 21
|
||||
#define SIZEOF_NEWLHD 32
|
||||
#define SIZEOF_SHORTBLOCKHEAD 7
|
||||
#define SIZEOF_LONGBLOCKHEAD 11
|
||||
#define SIZEOF_SUBBLOCKHEAD 14
|
||||
#define SIZEOF_COMMHEAD 13
|
||||
#define SIZEOF_PROTECTHEAD 26
|
||||
#define SIZEOF_AVHEAD 14
|
||||
#define SIZEOF_SIGNHEAD 15
|
||||
#define SIZEOF_UOHEAD 18
|
||||
#define SIZEOF_MACHEAD 22
|
||||
#define SIZEOF_EAHEAD 24
|
||||
#define SIZEOF_BEEAHEAD 24
|
||||
#define SIZEOF_STREAMHEAD 26
|
||||
|
||||
#define PACK_VER 29
|
||||
#define PACK_CRYPT_VER 29
|
||||
#define UNP_VER 36
|
||||
#define CRYPT_VER 29
|
||||
#define AV_VER 20
|
||||
#define PROTECT_VER 20
|
||||
|
||||
|
||||
#define MHD_VOLUME 0x0001U
|
||||
|
||||
// Old style main archive comment embed into main archive header. Must not
|
||||
// be used in new archives anymore. Must never be used with MHD_ENCRYPTVER
|
||||
// or other flags changing the size of main header. RAR expects the fixed
|
||||
// size of main header preceding the comment if MHD_COMMENT is found.
|
||||
#define MHD_COMMENT 0x0002U
|
||||
|
||||
#define MHD_LOCK 0x0004U
|
||||
#define MHD_SOLID 0x0008U
|
||||
#define MHD_PACK_COMMENT 0x0010U
|
||||
#define MHD_NEWNUMBERING 0x0010U
|
||||
#define MHD_AV 0x0020U
|
||||
#define MHD_PROTECT 0x0040U
|
||||
#define MHD_PASSWORD 0x0080U
|
||||
#define MHD_FIRSTVOLUME 0x0100U
|
||||
#define MHD_ENCRYPTVER 0x0200U
|
||||
|
||||
#define LHD_SPLIT_BEFORE 0x0001U
|
||||
#define LHD_SPLIT_AFTER 0x0002U
|
||||
#define LHD_PASSWORD 0x0004U
|
||||
|
||||
// Old style file comment embed into file header. Must not be used
|
||||
// in new archives anymore.
|
||||
#define LHD_COMMENT 0x0008U
|
||||
|
||||
#define LHD_SOLID 0x0010U
|
||||
|
||||
|
||||
#define LHD_WINDOWMASK 0x00e0U
|
||||
#define LHD_WINDOW64 0x0000U
|
||||
#define LHD_WINDOW128 0x0020U
|
||||
#define LHD_WINDOW256 0x0040U
|
||||
#define LHD_WINDOW512 0x0060U
|
||||
#define LHD_WINDOW1024 0x0080U
|
||||
#define LHD_WINDOW2048 0x00a0U
|
||||
#define LHD_WINDOW4096 0x00c0U
|
||||
#define LHD_DIRECTORY 0x00e0U
|
||||
|
||||
#define LHD_LARGE 0x0100U
|
||||
#define LHD_UNICODE 0x0200U
|
||||
#define LHD_SALT 0x0400U
|
||||
#define LHD_VERSION 0x0800U
|
||||
#define LHD_EXTTIME 0x1000U
|
||||
#define LHD_EXTAREA 0x2000U
|
||||
|
||||
#define SKIP_IF_UNKNOWN 0x4000U
|
||||
#define LONG_BLOCK 0x8000U
|
||||
|
||||
#define EARC_NEXT_VOLUME 0x0001U // Not last volume.
|
||||
#define EARC_DATACRC 0x0002U // Store CRC32 of RAR archive (now is used only in volumes).
|
||||
#define EARC_REVSPACE 0x0004U // Reserve space for end of REV file 7 byte record.
|
||||
#define EARC_VOLNUMBER 0x0008U // Store a number of current volume.
|
||||
|
||||
enum HEADER_TYPE {
|
||||
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
|
||||
SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
|
||||
ENDARC_HEAD=0x7b
|
||||
};
|
||||
|
||||
enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103,
|
||||
NTACL_HEAD=0x104,STREAM_HEAD=0x105 };
|
||||
|
||||
enum HOST_SYSTEM {
|
||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||
HOST_BEOS=5,HOST_MAX
|
||||
};
|
||||
|
||||
#define SUBHEAD_TYPE_CMT "CMT"
|
||||
#define SUBHEAD_TYPE_ACL "ACL"
|
||||
#define SUBHEAD_TYPE_STREAM "STM"
|
||||
#define SUBHEAD_TYPE_UOWNER "UOW"
|
||||
#define SUBHEAD_TYPE_AV "AV"
|
||||
#define SUBHEAD_TYPE_RR "RR"
|
||||
#define SUBHEAD_TYPE_OS2EA "EA2"
|
||||
#define SUBHEAD_TYPE_BEOSEA "EABE"
|
||||
|
||||
/* new file inherits a subblock when updating a host file */
|
||||
#define SUBHEAD_FLAGS_INHERITED 0x80000000
|
||||
|
||||
#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001
|
||||
|
||||
struct OldMainHeader
|
||||
{
|
||||
byte Mark[4];
|
||||
ushort HeadSize;
|
||||
byte Flags;
|
||||
};
|
||||
|
||||
|
||||
struct OldFileHeader
|
||||
{
|
||||
uint PackSize;
|
||||
uint UnpSize;
|
||||
ushort FileCRC;
|
||||
ushort HeadSize;
|
||||
uint FileTime;
|
||||
byte FileAttr;
|
||||
byte Flags;
|
||||
byte UnpVer;
|
||||
byte NameSize;
|
||||
byte Method;
|
||||
};
|
||||
|
||||
|
||||
struct MarkHeader
|
||||
{
|
||||
byte Mark[7];
|
||||
};
|
||||
|
||||
|
||||
struct BaseBlock
|
||||
{
|
||||
ushort HeadCRC;
|
||||
HEADER_TYPE HeadType; // 1 byte.
|
||||
ushort Flags;
|
||||
ushort HeadSize;
|
||||
|
||||
bool IsSubBlock()
|
||||
{
|
||||
if (HeadType==SUB_HEAD)
|
||||
return(true);
|
||||
if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0)
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
};
|
||||
|
||||
struct BlockHeader:BaseBlock
|
||||
{
|
||||
union {
|
||||
uint DataSize;
|
||||
uint PackSize;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct MainHeader:BaseBlock
|
||||
{
|
||||
ushort HighPosAV;
|
||||
uint PosAV;
|
||||
byte EncryptVer;
|
||||
};
|
||||
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
struct FileHeader:BlockHeader
|
||||
{
|
||||
uint UnpSize;
|
||||
byte HostOS;
|
||||
uint FileCRC;
|
||||
uint FileTime;
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
ushort NameSize;
|
||||
union {
|
||||
uint FileAttr;
|
||||
uint SubFlags;
|
||||
};
|
||||
/* optional */
|
||||
uint HighPackSize;
|
||||
uint HighUnpSize;
|
||||
/* names */
|
||||
char FileName[NM];
|
||||
wchar FileNameW[NM];
|
||||
/* optional */
|
||||
Array<byte> SubData;
|
||||
byte Salt[SALT_SIZE];
|
||||
|
||||
RarTime mtime;
|
||||
RarTime ctime;
|
||||
RarTime atime;
|
||||
RarTime arctime;
|
||||
/* dummy */
|
||||
int64 FullPackSize;
|
||||
int64 FullUnpSize;
|
||||
|
||||
void Clear(size_t SubDataSize)
|
||||
{
|
||||
SubData.Alloc(SubDataSize);
|
||||
Flags=LONG_BLOCK;
|
||||
SubFlags=0;
|
||||
}
|
||||
|
||||
bool CmpName(const char *Name)
|
||||
{
|
||||
return(strcmp(FileName,Name)==0);
|
||||
}
|
||||
|
||||
FileHeader& operator = (FileHeader &hd)
|
||||
{
|
||||
SubData.Reset();
|
||||
memcpy(this,&hd,sizeof(*this));
|
||||
SubData.CleanData();
|
||||
SubData=hd.SubData;
|
||||
return(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct EndArcHeader:BaseBlock
|
||||
{
|
||||
// Optional CRC32 of entire archive up to start of EndArcHeader block.
|
||||
// Present if EARC_DATACRC flag is set.
|
||||
uint ArcDataCRC;
|
||||
|
||||
// Optional number of current volume.
|
||||
// Present if EARC_VOLNUMBER flag is set.
|
||||
ushort VolNumber;
|
||||
|
||||
// 7 additional zero bytes can be stored here if EARC_REVSPACE is set.
|
||||
};
|
||||
|
||||
|
||||
// SubBlockHeader and its successors were used in RAR 2.x format.
|
||||
// RAR 3.x uses FileHeader with NEWSUB_HEAD HeadType for subblocks.
|
||||
struct SubBlockHeader:BlockHeader
|
||||
{
|
||||
ushort SubType;
|
||||
byte Level;
|
||||
};
|
||||
|
||||
|
||||
struct CommentHeader:BaseBlock
|
||||
{
|
||||
ushort UnpSize;
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
ushort CommCRC;
|
||||
};
|
||||
|
||||
|
||||
struct ProtectHeader:BlockHeader
|
||||
{
|
||||
byte Version;
|
||||
ushort RecSectors;
|
||||
uint TotalBlocks;
|
||||
byte Mark[8];
|
||||
};
|
||||
|
||||
|
||||
struct AVHeader:BaseBlock
|
||||
{
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
byte AVVer;
|
||||
uint AVInfoCRC;
|
||||
};
|
||||
|
||||
|
||||
struct SignHeader:BaseBlock
|
||||
{
|
||||
uint CreationTime;
|
||||
ushort ArcNameSize;
|
||||
ushort UserNameSize;
|
||||
};
|
||||
|
||||
|
||||
struct UnixOwnersHeader:SubBlockHeader
|
||||
{
|
||||
ushort OwnerNameSize;
|
||||
ushort GroupNameSize;
|
||||
/* dummy */
|
||||
char OwnerName[NM];
|
||||
char GroupName[NM];
|
||||
};
|
||||
|
||||
|
||||
struct EAHeader:SubBlockHeader
|
||||
{
|
||||
uint UnpSize;
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
uint EACRC;
|
||||
};
|
||||
|
||||
|
||||
struct StreamHeader:SubBlockHeader
|
||||
{
|
||||
uint UnpSize;
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
uint StreamCRC;
|
||||
ushort StreamNameSize;
|
||||
/* dummy */
|
||||
byte StreamName[NM];
|
||||
};
|
||||
|
||||
|
||||
struct MacFInfoHeader:SubBlockHeader
|
||||
{
|
||||
uint fileType;
|
||||
uint fileCreator;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,24 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
DWORD WinNT()
|
||||
{
|
||||
static int dwPlatformId=-1;
|
||||
static DWORD dwMajorVersion,dwMinorVersion;
|
||||
if (dwPlatformId==-1)
|
||||
{
|
||||
OSVERSIONINFO WinVer;
|
||||
WinVer.dwOSVersionInfoSize=sizeof(WinVer);
|
||||
GetVersionEx(&WinVer);
|
||||
dwPlatformId=WinVer.dwPlatformId;
|
||||
dwMajorVersion=WinVer.dwMajorVersion;
|
||||
dwMinorVersion=WinVer.dwMinorVersion;
|
||||
}
|
||||
DWORD Result=0;
|
||||
if (dwPlatformId==VER_PLATFORM_WIN32_NT)
|
||||
Result=dwMajorVersion*0x100+dwMinorVersion;
|
||||
|
||||
|
||||
return(Result);
|
||||
}
|
||||
#endif
|
||||
@ -1,11 +0,0 @@
|
||||
#ifndef _RAR_ISNT_
|
||||
#define _RAR_ISNT_
|
||||
|
||||
enum WINNT_VERSION {
|
||||
WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500,
|
||||
WNT_WXP=0x0501,WNT_W2003=0x0502,WNT_VISTA=0x0600,WNT_W7=0x0601
|
||||
};
|
||||
|
||||
DWORD WinNT();
|
||||
|
||||
#endif
|
||||
@ -1,42 +0,0 @@
|
||||
****** ***** ****** UnRAR - free utility for RAR archives
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
****** ******* ****** License for use and distribution of
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
** ** ** ** ** ** FREE portable version
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The source code of UnRAR utility is freeware. This means:
|
||||
|
||||
1. All copyrights to RAR and the utility UnRAR are exclusively
|
||||
owned by the author - Alexander Roshal.
|
||||
|
||||
2. UnRAR source code may be used in any software to handle
|
||||
RAR archives without limitations free of charge, but cannot be
|
||||
used to develop RAR (WinRAR) compatible archiver and to
|
||||
re-create RAR compression algorithm, which is proprietary.
|
||||
Distribution of modified UnRAR source code in separate form
|
||||
or as a part of other software is permitted, provided that
|
||||
full text of this paragraph, starting from "UnRAR source code"
|
||||
words, is included in license, or in documentation if license
|
||||
is not available, and in source code comments of resulting package.
|
||||
|
||||
3. The UnRAR utility may be freely distributed. It is allowed
|
||||
to distribute UnRAR inside of other software packages.
|
||||
|
||||
4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS".
|
||||
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
|
||||
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
|
||||
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
|
||||
OR MISUSING THIS SOFTWARE.
|
||||
|
||||
5. Installing and using the UnRAR utility signifies acceptance of
|
||||
these terms and conditions of the license.
|
||||
|
||||
6. If you don't agree with terms of the license you must remove
|
||||
UnRAR files from your storage devices and cease to use the
|
||||
utility.
|
||||
|
||||
Thank you for your interest in RAR and UnRAR.
|
||||
|
||||
|
||||
Alexander L. Roshal
|
||||
@ -1,391 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
static void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare);
|
||||
static void ListSymLink(Archive &Arc);
|
||||
static void ListFileAttr(uint A,int HostOS);
|
||||
static void ListOldSubHeader(Archive &Arc);
|
||||
static void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical);
|
||||
|
||||
void ListArchive(CommandData *Cmd)
|
||||
{
|
||||
int64 SumPackSize=0,SumUnpSize=0;
|
||||
uint ArcCount=0,SumFileCount=0;
|
||||
bool Technical=(Cmd->Command[1]=='T');
|
||||
bool Bare=(Cmd->Command[1]=='B');
|
||||
bool Verbose=(*Cmd->Command=='V');
|
||||
|
||||
char ArcName[NM];
|
||||
wchar ArcNameW[NM];
|
||||
|
||||
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
|
||||
{
|
||||
Archive Arc(Cmd);
|
||||
#ifdef _WIN_ALL
|
||||
Arc.RemoveSequentialFlag();
|
||||
#endif
|
||||
if (!Arc.WOpen(ArcName,ArcNameW))
|
||||
continue;
|
||||
bool FileMatched=true;
|
||||
while (1)
|
||||
{
|
||||
int64 TotalPackSize=0,TotalUnpSize=0;
|
||||
uint FileCount=0;
|
||||
if (Arc.IsArchive(true))
|
||||
{
|
||||
// if (!Arc.IsOpened())
|
||||
// break;
|
||||
bool TitleShown=false;
|
||||
if (!Bare)
|
||||
{
|
||||
Arc.ViewComment();
|
||||
mprintf("\n");
|
||||
if (Arc.Solid)
|
||||
mprintf(St(MListSolid));
|
||||
if (Arc.SFXSize>0)
|
||||
mprintf(St(MListSFX));
|
||||
if (Arc.Volume)
|
||||
if (Arc.Solid)
|
||||
mprintf(St(MListVol1));
|
||||
else
|
||||
mprintf(St(MListVol2));
|
||||
else
|
||||
if (Arc.Solid)
|
||||
mprintf(St(MListArc1));
|
||||
else
|
||||
mprintf(St(MListArc2));
|
||||
mprintf(" %s\n",Arc.FileName);
|
||||
if (Technical)
|
||||
{
|
||||
if (Arc.Protected)
|
||||
mprintf(St(MListRecRec));
|
||||
if (Arc.Locked)
|
||||
mprintf(St(MListLock));
|
||||
}
|
||||
}
|
||||
while(Arc.ReadHeader()>0)
|
||||
{
|
||||
int HeaderType=Arc.GetHeaderType();
|
||||
if (HeaderType==ENDARC_HEAD)
|
||||
break;
|
||||
switch(HeaderType)
|
||||
{
|
||||
case FILE_HEAD:
|
||||
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
|
||||
FileMatched=Cmd->IsProcessFile(Arc.NewLhd)!=0;
|
||||
if (FileMatched)
|
||||
{
|
||||
ListFileHeader(Arc.NewLhd,Verbose,Technical,TitleShown,Bare);
|
||||
if (!(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
|
||||
{
|
||||
TotalUnpSize+=Arc.NewLhd.FullUnpSize;
|
||||
FileCount++;
|
||||
}
|
||||
TotalPackSize+=Arc.NewLhd.FullPackSize;
|
||||
if (Technical)
|
||||
ListSymLink(Arc);
|
||||
#ifndef SFX_MODULE
|
||||
if (Verbose)
|
||||
Arc.ViewFileComment();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#ifndef SFX_MODULE
|
||||
case SUB_HEAD:
|
||||
if (Technical && FileMatched && !Bare)
|
||||
ListOldSubHeader(Arc);
|
||||
break;
|
||||
#endif
|
||||
case NEWSUB_HEAD:
|
||||
if (FileMatched && !Bare)
|
||||
{
|
||||
if (Technical)
|
||||
ListFileHeader(Arc.SubHead,Verbose,true,TitleShown,false);
|
||||
ListNewSubHeader(Cmd,Arc,Technical);
|
||||
}
|
||||
break;
|
||||
}
|
||||
Arc.SeekToNext();
|
||||
}
|
||||
if (!Bare)
|
||||
if (TitleShown)
|
||||
{
|
||||
mprintf("\n");
|
||||
for (int I=0;I<79;I++)
|
||||
mprintf("-");
|
||||
char UnpSizeText[20];
|
||||
itoa(TotalUnpSize,UnpSizeText);
|
||||
|
||||
char PackSizeText[20];
|
||||
itoa(TotalPackSize,PackSizeText);
|
||||
|
||||
mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText,
|
||||
PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize));
|
||||
SumFileCount+=FileCount;
|
||||
SumUnpSize+=TotalUnpSize;
|
||||
SumPackSize+=TotalPackSize;
|
||||
#ifndef SFX_MODULE
|
||||
if (Arc.EndArcHead.Flags & EARC_VOLNUMBER)
|
||||
{
|
||||
mprintf(" ");
|
||||
mprintf(St(MVolumeNumber),Arc.EndArcHead.VolNumber+1);
|
||||
}
|
||||
#endif
|
||||
mprintf("\n");
|
||||
}
|
||||
else
|
||||
mprintf(St(MListNoFiles));
|
||||
|
||||
ArcCount++;
|
||||
|
||||
#ifndef NOVOLUME
|
||||
if (Cmd->VolSize!=0 && ((Arc.NewLhd.Flags & LHD_SPLIT_AFTER) ||
|
||||
Arc.GetHeaderType()==ENDARC_HEAD &&
|
||||
(Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)!=0) &&
|
||||
MergeArchive(Arc,NULL,false,*Cmd->Command))
|
||||
{
|
||||
Arc.Seek(0,SEEK_SET);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Cmd->ArcNames->ItemsCount()<2 && !Bare)
|
||||
mprintf(St(MNotRAR),Arc.FileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ArcCount>1 && !Bare)
|
||||
{
|
||||
char UnpSizeText[20],PackSizeText[20];
|
||||
itoa(SumUnpSize,UnpSizeText);
|
||||
itoa(SumPackSize,PackSizeText);
|
||||
mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText,
|
||||
PackSizeText,ToPercentUnlim(SumPackSize,SumUnpSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare)
|
||||
{
|
||||
if (!Bare)
|
||||
{
|
||||
if (!TitleShown)
|
||||
{
|
||||
if (Verbose)
|
||||
mprintf(St(MListPathComm));
|
||||
else
|
||||
mprintf(St(MListName));
|
||||
mprintf(St(MListTitle));
|
||||
if (Technical)
|
||||
mprintf(St(MListTechTitle));
|
||||
for (int I=0;I<79;I++)
|
||||
mprintf("-");
|
||||
TitleShown=true;
|
||||
}
|
||||
|
||||
if (hd.HeadType==NEWSUB_HEAD)
|
||||
mprintf(St(MSubHeadType),hd.FileName);
|
||||
|
||||
mprintf("\n%c",(hd.Flags & LHD_PASSWORD) ? '*' : ' ');
|
||||
}
|
||||
|
||||
char *Name=hd.FileName;
|
||||
|
||||
#ifdef UNICODE_SUPPORTED
|
||||
char ConvertedName[NM];
|
||||
if ((hd.Flags & LHD_UNICODE)!=0 && *hd.FileNameW!=0 && UnicodeEnabled())
|
||||
{
|
||||
if (WideToChar(hd.FileNameW,ConvertedName) && *ConvertedName!=0)
|
||||
Name=ConvertedName;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Bare)
|
||||
{
|
||||
mprintf("%s\n",Verbose ? Name:PointToName(Name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
mprintf("%s\n%12s ",Name,"");
|
||||
else
|
||||
mprintf("%-12s",PointToName(Name));
|
||||
|
||||
char UnpSizeText[20],PackSizeText[20];
|
||||
if (hd.FullUnpSize==INT64NDF)
|
||||
strcpy(UnpSizeText,"?");
|
||||
else
|
||||
itoa(hd.FullUnpSize,UnpSizeText);
|
||||
itoa(hd.FullPackSize,PackSizeText);
|
||||
|
||||
mprintf(" %8s %8s ",UnpSizeText,PackSizeText);
|
||||
|
||||
if ((hd.Flags & LHD_SPLIT_BEFORE) && (hd.Flags & LHD_SPLIT_AFTER))
|
||||
mprintf(" <->");
|
||||
else
|
||||
if (hd.Flags & LHD_SPLIT_BEFORE)
|
||||
mprintf(" <--");
|
||||
else
|
||||
if (hd.Flags & LHD_SPLIT_AFTER)
|
||||
mprintf(" -->");
|
||||
else
|
||||
mprintf("%3d%%",ToPercentUnlim(hd.FullPackSize,hd.FullUnpSize));
|
||||
|
||||
char DateStr[50];
|
||||
hd.mtime.GetText(DateStr,false);
|
||||
mprintf(" %s ",DateStr);
|
||||
|
||||
if (hd.HeadType==NEWSUB_HEAD)
|
||||
mprintf(" %c....B ",(hd.SubFlags & SUBHEAD_FLAGS_INHERITED) ? 'I' : '.');
|
||||
else
|
||||
ListFileAttr(hd.FileAttr,hd.HostOS);
|
||||
|
||||
mprintf(" %8.8X",hd.FileCRC);
|
||||
mprintf(" m%d",hd.Method-0x30);
|
||||
if ((hd.Flags & LHD_WINDOWMASK)<=6*32)
|
||||
mprintf("%c",((hd.Flags&LHD_WINDOWMASK)>>5)+'a');
|
||||
else
|
||||
mprintf(" ");
|
||||
mprintf(" %d.%d",hd.UnpVer/10,hd.UnpVer%10);
|
||||
|
||||
static const char *RarOS[]={
|
||||
"DOS","OS/2","Windows","Unix","Mac OS","BeOS","WinCE","","",""
|
||||
};
|
||||
|
||||
if (Technical)
|
||||
mprintf("\n%22s %8s %4s",
|
||||
(hd.HostOS<ASIZE(RarOS) ? RarOS[hd.HostOS]:""),
|
||||
(hd.Flags & LHD_SOLID) ? St(MYes):St(MNo),
|
||||
(hd.Flags & LHD_VERSION) ? St(MYes):St(MNo));
|
||||
}
|
||||
|
||||
|
||||
void ListSymLink(Archive &Arc)
|
||||
{
|
||||
if (Arc.NewLhd.HostOS==HOST_UNIX && (Arc.NewLhd.FileAttr & 0xF000)==0xA000)
|
||||
if ((Arc.NewLhd.Flags & LHD_PASSWORD)==0)
|
||||
{
|
||||
char FileName[NM];
|
||||
int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
|
||||
Arc.Read(FileName,DataSize);
|
||||
FileName[DataSize]=0;
|
||||
mprintf("\n%22s %s","-->",FileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Link data are encrypted. We would need to ask for password
|
||||
// and initialize decryption routine to display the link target.
|
||||
mprintf("\n%22s %s","-->","*<-?->");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ListFileAttr(uint A,int HostOS)
|
||||
{
|
||||
switch(HostOS)
|
||||
{
|
||||
case HOST_MSDOS:
|
||||
case HOST_OS2:
|
||||
case HOST_WIN32:
|
||||
case HOST_MACOS:
|
||||
mprintf(" %c%c%c%c%c%c%c ",
|
||||
(A & 0x08) ? 'V' : '.',
|
||||
(A & 0x10) ? 'D' : '.',
|
||||
(A & 0x01) ? 'R' : '.',
|
||||
(A & 0x02) ? 'H' : '.',
|
||||
(A & 0x04) ? 'S' : '.',
|
||||
(A & 0x20) ? 'A' : '.',
|
||||
(A & 0x800) ? 'C' : '.');
|
||||
break;
|
||||
case HOST_UNIX:
|
||||
case HOST_BEOS:
|
||||
switch (A & 0xF000)
|
||||
{
|
||||
case 0x4000:
|
||||
mprintf("d");
|
||||
break;
|
||||
case 0xA000:
|
||||
mprintf("l");
|
||||
break;
|
||||
default:
|
||||
mprintf("-");
|
||||
break;
|
||||
}
|
||||
mprintf("%c%c%c%c%c%c%c%c%c",
|
||||
(A & 0x0100) ? 'r' : '-',
|
||||
(A & 0x0080) ? 'w' : '-',
|
||||
(A & 0x0040) ? ((A & 0x0800) ? 's':'x'):((A & 0x0800) ? 'S':'-'),
|
||||
(A & 0x0020) ? 'r' : '-',
|
||||
(A & 0x0010) ? 'w' : '-',
|
||||
(A & 0x0008) ? ((A & 0x0400) ? 's':'x'):((A & 0x0400) ? 'S':'-'),
|
||||
(A & 0x0004) ? 'r' : '-',
|
||||
(A & 0x0002) ? 'w' : '-',
|
||||
(A & 0x0001) ? 'x' : '-');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void ListOldSubHeader(Archive &Arc)
|
||||
{
|
||||
switch(Arc.SubBlockHead.SubType)
|
||||
{
|
||||
case EA_HEAD:
|
||||
mprintf(St(MListEAHead));
|
||||
break;
|
||||
case UO_HEAD:
|
||||
mprintf(St(MListUOHead),Arc.UOHead.OwnerName,Arc.UOHead.GroupName);
|
||||
break;
|
||||
case MAC_HEAD:
|
||||
mprintf(St(MListMACHead1),Arc.MACHead.fileType>>24,Arc.MACHead.fileType>>16,Arc.MACHead.fileType>>8,Arc.MACHead.fileType);
|
||||
mprintf(St(MListMACHead2),Arc.MACHead.fileCreator>>24,Arc.MACHead.fileCreator>>16,Arc.MACHead.fileCreator>>8,Arc.MACHead.fileCreator);
|
||||
break;
|
||||
case BEEA_HEAD:
|
||||
mprintf(St(MListBeEAHead));
|
||||
break;
|
||||
case NTACL_HEAD:
|
||||
mprintf(St(MListNTACLHead));
|
||||
break;
|
||||
case STREAM_HEAD:
|
||||
mprintf(St(MListStrmHead),Arc.StreamHead.StreamName);
|
||||
break;
|
||||
default:
|
||||
mprintf(St(MListUnkHead),Arc.SubBlockHead.SubType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical)
|
||||
{
|
||||
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
|
||||
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment)
|
||||
{
|
||||
Array<byte> CmtData;
|
||||
size_t ReadSize=Arc.ReadCommentData(&CmtData,NULL);
|
||||
if (ReadSize!=0)
|
||||
{
|
||||
mprintf(St(MFileComment));
|
||||
OutComment((char *)&CmtData[0],ReadSize);
|
||||
}
|
||||
}
|
||||
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM) &&
|
||||
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0)
|
||||
{
|
||||
size_t DestSize=Arc.SubHead.SubData.Size()/2;
|
||||
wchar DestNameW[NM];
|
||||
char DestName[NM];
|
||||
if (DestSize<sizeof(DestName))
|
||||
{
|
||||
RawToWide(&Arc.SubHead.SubData[0],DestNameW,DestSize);
|
||||
DestNameW[DestSize]=0;
|
||||
WideToChar(DestNameW,DestName);
|
||||
mprintf("\n %s",DestName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _RAR_LIST_
|
||||
#define _RAR_LIST_
|
||||
|
||||
void ListArchive(CommandData *Cmd);
|
||||
|
||||
#endif
|
||||
@ -1,357 +0,0 @@
|
||||
#define MYesNo "_Yes_No"
|
||||
#define MYesNoAll "_Yes_No_All"
|
||||
#define MYesNoAllQ "_Yes_No_All_nEver_Quit"
|
||||
#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit"
|
||||
#define MContinueQuit "_Continue_Quit"
|
||||
#define MRetryAbort "_Retry_Abort"
|
||||
#define MCopyright "\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d"
|
||||
#define MRegTo "\nRegistered to %s\n"
|
||||
#define MShare "\nTrial version Type RAR -? for help\n"
|
||||
#define MUCopyright "\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n"
|
||||
#define MBeta "beta"
|
||||
#define MMonthJan "Jan"
|
||||
#define MMonthFeb "Feb"
|
||||
#define MMonthMar "Mar"
|
||||
#define MMonthApr "Apr"
|
||||
#define MMonthMay "May"
|
||||
#define MMonthJun "Jun"
|
||||
#define MMonthJul "Jul"
|
||||
#define MMonthAug "Aug"
|
||||
#define MMonthSep "Sep"
|
||||
#define MMonthOct "Oct"
|
||||
#define MMonthNov "Nov"
|
||||
#define MMonthDec "Dec"
|
||||
#define MRARTitle1 "\nUsage: rar <command> -<switch 1> -<switch N> <archive> <files...>"
|
||||
#define MUNRARTitle1 "\nUsage: unrar <command> -<switch 1> -<switch N> <archive> <files...>"
|
||||
#define MRARTitle2 "\n <@listfiles...> <path_to_extract\\>"
|
||||
#define MCHelpCmd "\n\n<Commands>"
|
||||
#define MCHelpCmdA "\n a Add files to archive"
|
||||
#define MCHelpCmdC "\n c Add archive comment"
|
||||
#define MCHelpCmdCF "\n cf Add files comment"
|
||||
#define MCHelpCmdCH "\n ch Change archive parameters"
|
||||
#define MCHelpCmdCW "\n cw Write archive comment to file"
|
||||
#define MCHelpCmdD "\n d Delete files from archive"
|
||||
#define MCHelpCmdE "\n e Extract files to current directory"
|
||||
#define MCHelpCmdF "\n f Freshen files in archive"
|
||||
#define MCHelpCmdI "\n i[par]=<str> Find string in archives"
|
||||
#define MCHelpCmdK "\n k Lock archive"
|
||||
#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]"
|
||||
#define MCHelpCmdM "\n m[f] Move to archive [files only]"
|
||||
#define MCHelpCmdP "\n p Print file to stdout"
|
||||
#define MCHelpCmdR "\n r Repair archive"
|
||||
#define MCHelpCmdRC "\n rc Reconstruct missing volumes"
|
||||
#define MCHelpCmdRN "\n rn Rename archived files"
|
||||
#define MCHelpCmdRR "\n rr[N] Add data recovery record"
|
||||
#define MCHelpCmdRV "\n rv[N] Create recovery volumes"
|
||||
#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX"
|
||||
#define MCHelpCmdT "\n t Test archive files"
|
||||
#define MCHelpCmdU "\n u Update files in archive"
|
||||
#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]"
|
||||
#define MCHelpCmdX "\n x Extract files with full path"
|
||||
#define MCHelpSw "\n\n<Switches>"
|
||||
#define MCHelpSwm "\n - Stop switches scanning"
|
||||
#define MCHelpSwAT "\n @[+] Disable [enable] file lists"
|
||||
#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction"
|
||||
#define MCHelpSwAD "\n ad Append archive name to destination path"
|
||||
#define MCHelpSwAG "\n ag[format] Generate archive name using the current date"
|
||||
#define MCHelpSwAI "\n ai Ignore file attributes"
|
||||
#define MCHelpSwAO "\n ao Add files with Archive attribute set"
|
||||
#define MCHelpSwAP "\n ap<path> Set path inside archive"
|
||||
#define MCHelpSwAS "\n as Synchronize archive contents"
|
||||
#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)"
|
||||
#define MCHelpSwAVm "\n av- Disable authenticity verification check"
|
||||
#define MCHelpSwCm "\n c- Disable comments show"
|
||||
#define MCHelpSwCFGm "\n cfg- Disable read configuration"
|
||||
#define MCHelpSwCL "\n cl Convert names to lower case"
|
||||
#define MCHelpSwCU "\n cu Convert names to upper case"
|
||||
#define MCHelpSwDF "\n df Delete files after archiving"
|
||||
#define MCHelpSwDH "\n dh Open shared files"
|
||||
#define MCHelpSwDR "\n dr Delete files to Recycle Bin"
|
||||
#define MCHelpSwDS "\n ds Disable name sort for solid archive"
|
||||
#define MCHelpSwDW "\n dw Wipe files after archiving"
|
||||
#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes"
|
||||
#define MCHelpSwED "\n ed Do not add empty directories"
|
||||
#define MCHelpSwEE "\n ee Do not save and extract extended attributes"
|
||||
#define MCHelpSwEN "\n en Do not put 'end of archive' block"
|
||||
#define MCHelpSwEP "\n ep Exclude paths from names"
|
||||
#define MCHelpSwEP1 "\n ep1 Exclude base directory from names"
|
||||
#define MCHelpSwEP2 "\n ep2 Expand paths to full"
|
||||
#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter"
|
||||
#define MCHelpSwF "\n f Freshen files"
|
||||
#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers"
|
||||
#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages"
|
||||
#define MCHelpSwIEML "\n ieml[addr] Send archive by email"
|
||||
#define MCHelpSwIERR "\n ierr Send all messages to stderr"
|
||||
#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)"
|
||||
#define MCHelpSwINUL "\n inul Disable all messages"
|
||||
#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation"
|
||||
#define MCHelpSwISND "\n isnd Enable sound"
|
||||
#define MCHelpSwK "\n k Lock archive"
|
||||
#define MCHelpSwKB "\n kb Keep broken extracted files"
|
||||
#define MCHelpSwLog "\n log[f][=name] Write names to log file"
|
||||
#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)"
|
||||
#define MCHelpSwMC "\n mc<par> Set advanced compression parameters"
|
||||
#define MCHelpSwMD "\n md<size> Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)"
|
||||
#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store"
|
||||
#define MCHelpSwMT "\n mt<threads> Set the number of threads"
|
||||
#define MCHelpSwN "\n n<file> Include only specified file"
|
||||
#define MCHelpSwNa "\n n@ Read file names to include from stdin"
|
||||
#define MCHelpSwNal "\n n@<list> Include files listed in specified list file"
|
||||
#define MCHelpSwO "\n o[+|-] Set the overwrite mode"
|
||||
#define MCHelpSwOC "\n oc Set NTFS Compressed attribute"
|
||||
#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file"
|
||||
#define MCHelpSwOR "\n or Rename files automatically"
|
||||
#define MCHelpSwOS "\n os Save NTFS streams"
|
||||
#define MCHelpSwOW "\n ow Save or restore file owner and group"
|
||||
#define MCHelpSwP "\n p[password] Set password"
|
||||
#define MCHelpSwPm "\n p- Do not query password"
|
||||
#define MCHelpSwR "\n r Recurse subdirectories"
|
||||
#define MCHelpSwRm "\n r- Disable recursion"
|
||||
#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only"
|
||||
#define MCHelpSwRI "\n ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms"
|
||||
#define MCHelpSwRR "\n rr[N] Add data recovery record"
|
||||
#define MCHelpSwRV "\n rv[N] Create recovery volumes"
|
||||
#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive"
|
||||
#define MCHelpSwSm "\n s- Disable solid archiving"
|
||||
#define MCHelpSwSC "\n sc<chr>[obj] Specify the character set"
|
||||
#define MCHelpSwSFX "\n sfx[name] Create SFX archive"
|
||||
#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)"
|
||||
#define MCHelpSwSL "\n sl<size> Process files with size less than specified"
|
||||
#define MCHelpSwSM "\n sm<size> Process files with size more than specified"
|
||||
#define MCHelpSwT "\n t Test files after archiving"
|
||||
#define MCHelpSwTK "\n tk Keep original archive time"
|
||||
#define MCHelpSwTL "\n tl Set archive time to latest file"
|
||||
#define MCHelpSwTN "\n tn<time> Process files newer than <time>"
|
||||
#define MCHelpSwTO "\n to<time> Process files older than <time>"
|
||||
#define MCHelpSwTA "\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format"
|
||||
#define MCHelpSwTB "\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format"
|
||||
#define MCHelpSwTS "\n ts<m,c,a>[N] Save or restore file time (modification, creation, access)"
|
||||
#define MCHelpSwU "\n u Update files"
|
||||
#define MCHelpSwV "\n v Create volumes with size autodetection or list all volumes"
|
||||
#define MCHelpSwVUnr "\n v List all volumes"
|
||||
#define MCHelpSwVn "\n v<size>[k,b] Create volumes with size=<size>*1000 [*1024, *1]"
|
||||
#define MCHelpSwVD "\n vd Erase disk contents before creating volume"
|
||||
#define MCHelpSwVER "\n ver[n] File version control"
|
||||
#define MCHelpSwVN "\n vn Use the old style volume naming scheme"
|
||||
#define MCHelpSwVP "\n vp Pause before each volume"
|
||||
#define MCHelpSwW "\n w<path> Assign work directory"
|
||||
#define MCHelpSwX "\n x<file> Exclude specified file"
|
||||
#define MCHelpSwXa "\n x@ Read file names to exclude from stdin"
|
||||
#define MCHelpSwXal "\n x@<list> Exclude files listed in specified list file"
|
||||
#define MCHelpSwY "\n y Assume Yes on all queries"
|
||||
#define MCHelpSwZ "\n z[file] Read archive comment from file"
|
||||
#define MBadArc "\nERROR: Bad archive %s\n"
|
||||
#define MAskPsw "Enter password (will not be echoed)"
|
||||
#define MAskPswEcho "Enter password"
|
||||
#define MReAskPsw "\nReenter password: "
|
||||
#define MFor " for "
|
||||
#define MNotMatchPsw "\nERROR: Passwords do not match\n"
|
||||
#define MErrWrite "Write error in the file %s"
|
||||
#define MErrRead "Read error in the file %s"
|
||||
#define MErrSeek "Seek error in the file %s"
|
||||
#define MErrFClose "Cannot close the file %s"
|
||||
#define MErrOutMem "Not enough memory"
|
||||
#define MErrBrokenArc "Corrupt archive - use 'Repair' command"
|
||||
#define MProgAborted "Program aborted"
|
||||
#define MErrRename "\nCannot rename %s to %s"
|
||||
#define MAbsNextVol "\nCannot find volume %s"
|
||||
#define MBreak "\nUser break\n"
|
||||
#define MAskCreatVol "\nCreate next volume ?"
|
||||
#define MAskNextDisk "\nDisk full. Insert next"
|
||||
#define MCreatVol "\n\nCreating %sarchive %s\n"
|
||||
#define MAskNextVol "\nInsert disk with %s"
|
||||
#define MTestVol "\n\nTesting archive %s\n"
|
||||
#define MExtrVol "\n\nExtracting from %s\n"
|
||||
#define MConverting "\nConverting %s"
|
||||
#define MCvtToSFX "\nConvert archives to SFX"
|
||||
#define MCvtFromSFX "\nRemoving SFX module"
|
||||
#define MNotSFX "\n%s is not SFX archive"
|
||||
#define MNotRAR "\n%s is not RAR archive"
|
||||
#define MNotFirstVol "\n%s is not the first volume"
|
||||
#define MCvtOldFormat "\n%s - cannot convert to SFX archive with old format"
|
||||
#define MCannotCreate "\nCannot create %s"
|
||||
#define MCannotOpen "\nCannot open %s"
|
||||
#define MUnknownMeth "\nUnknown method in %s"
|
||||
#define MVerRequired "\nYou need RAR %d.%d to unpack it"
|
||||
#define MNewRarFormat "\nUnsupported archive format. Please update RAR to a newer version."
|
||||
#define MOk " OK"
|
||||
#define MDone "\nDone"
|
||||
#define MLockingArc "\nLocking archive"
|
||||
#define MNotMdfOld "\n\nERROR: Cannot modify old format archive"
|
||||
#define MNotMdfLock "\n\nERROR: Locked archive"
|
||||
#define MNotMdfVol "\n\nERROR: Cannot modify volume"
|
||||
#define MVerifyAV "\nVerifying authenticity information ... "
|
||||
#define MFailedAV " Failed\n"
|
||||
#define MStrAV1 "\n\nArchive %s"
|
||||
#define MStrAV2 "\ncreated at %s"
|
||||
#define MStrAV3 "\nby %s\n"
|
||||
#define MLogFailedAV "Invalid authenticity information"
|
||||
#define MAddingAV "\nAdding authenticity verification "
|
||||
#define MAVOldStyle "\n\nOld style authenticity information"
|
||||
#define MPackAskReg "\nEvaluation copy. Please register.\n"
|
||||
#define MCreateArchive "\nCreating %sarchive %s\n"
|
||||
#define MUpdateArchive "\nUpdating %sarchive %s\n"
|
||||
#define MAddSolid "solid "
|
||||
#define MAddFile "\nAdding %-58s "
|
||||
#define MUpdFile "\nUpdating %-58s "
|
||||
#define MAddPoints "\n... %-58s "
|
||||
#define MCannotUpdPswSolid "\nERROR: Cannot update solid archives with password\n"
|
||||
#define MMoveDelFiles "\n\nDeleting files %s..."
|
||||
#define MMoveDelDirs "and directories"
|
||||
#define MMoveDelFile "\nDeleting %-30s"
|
||||
#define MMoveDeleted " deleted"
|
||||
#define MMoveNotDeleted " NOT DELETED"
|
||||
#define MClearAttrib "\n\nClearing attributes..."
|
||||
#define MMoveDelDir "\nDeleting directory %-30s"
|
||||
#define MWarErrFOpen "\nWARNING: Cannot open %d %s"
|
||||
#define MErrOpenFiles "files"
|
||||
#define MErrOpenFile "file"
|
||||
#define MAddNoFiles "\nWARNING: No files"
|
||||
#define MMdfEncrSol "\n%s: encrypted"
|
||||
#define MCannotMdfEncrSol "\nCannot modify solid archive containing encrypted files"
|
||||
#define MAddAnalyze "\nAnalyzing archived files: "
|
||||
#define MRepacking "\nRepacking archived files: "
|
||||
#define MCRCFailed "\n%-20s - CRC failed"
|
||||
#define MExtrTest "\n\nTesting archive %s\n"
|
||||
#define MExtracting "\n\nExtracting from %s\n"
|
||||
#define MUseCurPsw "\n%s - use current password ?"
|
||||
#define MCreatDir "\nCreating %-56s"
|
||||
#define MExtrSkipFile "\nSkipping %-56s"
|
||||
#define MExtrTestFile "\nTesting %-56s"
|
||||
#define MExtrFile "\nExtracting %-56s"
|
||||
#define MExtrPoints "\n... %-56s"
|
||||
#define MExtrErrMkDir "\nCannot create directory %s"
|
||||
#define MExtrPrinting "\n------ Printing %s\n\n"
|
||||
#define MEncrBadCRC "\nCRC failed in the encrypted file %s. Corrupt file or wrong password."
|
||||
#define MExtrNoFiles "\nNo files to extract"
|
||||
#define MExtrAllOk "\nAll OK"
|
||||
#define MExtrTotalErr "\nTotal errors: %ld"
|
||||
#define MFileExists "\n\n%s already exists. Overwrite it ?"
|
||||
#define MAskOverwrite "\nOverwrite %s ?"
|
||||
#define MAskNewName "\nEnter new name: "
|
||||
#define MLogMainHead "\nThe archive header is corrupt"
|
||||
#define MLogFileHead "\n%s - the file header is corrupt"
|
||||
#define MLogCommHead "\nThe comment header is corrupt\n"
|
||||
#define MLogProtectHead "The data recovery header is corrupt"
|
||||
#define MReadStdinCmt "\nReading comment from stdin\n"
|
||||
#define MReadCommFrom "\nReading comment from %s"
|
||||
#define MDelComment "\nDeleting comment from %s"
|
||||
#define MAddComment "\nAdding comment to %s"
|
||||
#define MFCommAdd "\nAdding file comments"
|
||||
#define MAskFComm "\n\nReading comment for %s : %s from stdin\n"
|
||||
#define MLogCommBrk "\nThe archive comment is corrupt"
|
||||
#define MCommAskCont "\nPress 'Enter' to continue or 'Q' to quit:"
|
||||
#define MLogBrokFCmt "\nThe file comment is corrupt"
|
||||
#define MWriteCommTo "\nWrite comment to %s"
|
||||
#define MCommNotPres "\nComment is not present"
|
||||
#define MDelFrom "\nDeleting from %s"
|
||||
#define MDeleting "\nDeleting %s"
|
||||
#define MEraseArc "\nErasing empty archive %s"
|
||||
#define MNoDelFiles "\nNo files to delete"
|
||||
#define MLogTitle "\n\n-------- %2d %s %d, archive %s\n"
|
||||
#define MPathTooLong "\nERROR: Path too long\n"
|
||||
#define MListSolid "Solid "
|
||||
#define MListSFX "SFX "
|
||||
#define MListVol1 "volume"
|
||||
#define MListVol2 "Volume"
|
||||
#define MListArc1 "archive"
|
||||
#define MListArc2 "Archive"
|
||||
#define MListRecRec "\nRecovery record is present\n"
|
||||
#define MListLock "\nLock is present\n"
|
||||
#define MListPathComm "\nPathname/Comment\n "
|
||||
#define MListName "\n Name "
|
||||
#define MListTitle " Size Packed Ratio Date Time Attr CRC Meth Ver\n"
|
||||
#define MListTechTitle " Host OS Solid Old\n"
|
||||
#define MListEAHead "\n OS/2 extended attributes"
|
||||
#define MListUOHead "\n Unix Owner/Group data: %-14s %-14s"
|
||||
#define MListBeEAHead "\n BeOS extended attributes"
|
||||
#define MListNTACLHead "\n NTFS security data"
|
||||
#define MListStrmHead "\n NTFS stream: %s"
|
||||
#define MListUnkHead "\n Unknown subheader type: 0x%04x"
|
||||
#define MFileComment "\nComment: "
|
||||
#define MYes "Yes"
|
||||
#define MNo "No"
|
||||
#define MListNoFiles " 0 files\n"
|
||||
#define MRprReconstr "\nReconstructing %s"
|
||||
#define MRprBuild "\nBuilding %s"
|
||||
#define MRprOldFormat "\nCannot repair archive with old format"
|
||||
#define MRprFind "\nFound %s"
|
||||
#define MRprAskIsSol "\nThe archive header is corrupt. Mark archive as solid ?"
|
||||
#define MRprNoFiles "\nNo files found"
|
||||
#define MRprSuspEntry "\n\nSuspicious entry %s"
|
||||
#define MRprDir "\nDirectory"
|
||||
#define MRprSuspSize "\nSize %ld Packed %ld"
|
||||
#define MRprSuspAdd "\nAdd it to archive ?"
|
||||
#define MLogUnexpEOF "\nUnexpected end of archive"
|
||||
#define MRepAskReconst "\nReconstruct archive structure ?"
|
||||
#define MRecScanning "\nScanning..."
|
||||
#define MRecRNotFound "\nData recovery record not found"
|
||||
#define MRecRFound "\nData recovery record found"
|
||||
#define MRecSecDamage "\nSector %ld (offsets %lX...%lX) damaged"
|
||||
#define MRecCorrected " - data recovered"
|
||||
#define MRecFailed " - cannot recover data"
|
||||
#define MAddRecRec "\nAdding data recovery record"
|
||||
#define MEraseForVolume "\n\nErasing contents of drive %c:\n"
|
||||
#define MGetOwnersError "\nWARNING: Cannot get %s owner and group\n"
|
||||
#define MErrGetOwnerID "\nWARNING: Cannot get owner %s ID\n"
|
||||
#define MErrGetGroupID "\nWARNING: Cannot get group %s ID\n"
|
||||
#define MOwnersBroken "\nERROR: %s group and owner data are corrupt\n"
|
||||
#define MSetOwnersError "\nWARNING: Cannot set %s owner and group\n"
|
||||
#define MErrLnkRead "\nWARNING: Cannot read symbolic link %s"
|
||||
#define MErrCreateLnk "\nWARNING: Cannot create link %s"
|
||||
#define MSymLinkExists "\nWARNING: Symbolic link %s already exists"
|
||||
#define MAskRetryCreate "\nCannot create %s. Retry ?"
|
||||
#define MListMACHead1 "\n Mac OS file type: %c%c%c%c ; "
|
||||
#define MListMACHead2 "file creator: %c%c%c%c\n"
|
||||
#define MDataBadCRC "\n%-20s : packed data CRC failed in volume %s"
|
||||
#define MFileRO "\n%s is read-only"
|
||||
#define MACLGetError "\nWARNING: Cannot get %s security data\n"
|
||||
#define MACLSetError "\nWARNING: Cannot set %s security data\n"
|
||||
#define MACLBroken "\nERROR: %s security data are corrupt\n"
|
||||
#define MACLUnknown "\nWARNING: Unknown format of %s security data\n"
|
||||
#define MStreamBroken "\nERROR: %s stream data are corrupt\n"
|
||||
#define MStreamUnknown "\nWARNING: Unknown format of %s stream data\n"
|
||||
#define MInvalidName "\nERROR: Invalid file name %s"
|
||||
#define MEABroken "\nERROR: %s extended attributes are corrupt\n"
|
||||
#define MEAUnknHeader "\nWARNING: %s - unknown format of extended attributes\n"
|
||||
#define MCannotSetEA "\nWARNING: cannot set extended attributes to %s\n"
|
||||
#define MCannotGetEA "\nERROR: Cannot get extended attributes of %s\n"
|
||||
#define MShowEA " (+EA)"
|
||||
#define MSkipEA "\n...skipping extended attributes"
|
||||
#define MProcessArc "\n\nProcessing archive %s"
|
||||
#define MSyncScanError "\nFile search errors, cannot synchronize archive"
|
||||
#define MCorrectingName "\nWARNING: Attempting to correct the invalid file name"
|
||||
#define MUnpCannotMerge "\nWARNING: You need to start extraction from a previous volume to unpack %s"
|
||||
#define MUnknownOption "\nERROR: Unknown option: %s"
|
||||
#define MSubHeadCorrupt "\nERROR: Corrupt data header found, ignored"
|
||||
#define MSubHeadUnknown "\nWARNING: Unknown data header format, ignored"
|
||||
#define MSubHeadDataCRC "\nERROR: Corrupt %s data block"
|
||||
#define MSubHeadType "\nData header type: %s"
|
||||
#define MScanError "\nCannot read contents of %s"
|
||||
#define MNotVolume "\n%s is not volume"
|
||||
#define MRecVolDiffSets "\nERROR: %s and %s belong to different sets"
|
||||
#define MRecVolMissing "\n%d volumes missing"
|
||||
#define MRecVolFound "\n%d recovery volumes found"
|
||||
#define MRecVolAllExist "\nNothing to reconstruct"
|
||||
#define MRecVolCannotFix "\nReconstruction impossible"
|
||||
#define MReconstructing "\nReconstructing..."
|
||||
#define MCreating "\nCreating %s"
|
||||
#define MRenaming "\nRenaming %s to %s"
|
||||
#define MNTFSRequired "\nWrite error: only NTFS file system supports files larger than 4 GB"
|
||||
#define MErrChangeAttr "\nWARNING: Cannot change attributes of %s"
|
||||
#define MWrongSFXVer "\nERROR: default SFX module does not support RAR %d.%d archives"
|
||||
#define MCannotEncName "\nCannot encrypt archive already contained encrypted files"
|
||||
#define MCannotEmail "\nCannot email the file %s"
|
||||
#define MCopyrightS "\nRAR SFX archive"
|
||||
#define MSHelpCmd "\n\n<Commands>"
|
||||
#define MSHelpCmdE "\n -x Extract from archive (default)"
|
||||
#define MSHelpCmdT "\n -t Test archive files"
|
||||
#define MSHelpCmdV "\n -v Verbosely list contents of archive"
|
||||
#define MMaxPathLimit "\nTotal path and file name length must not exceed %d characters"
|
||||
#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255"
|
||||
#define MVolumeNumber "volume %d"
|
||||
#define MCannotDelete "\nCannot delete %s"
|
||||
#define MCalcCRC "\nCalculating the control sum"
|
||||
#define MTooLargeSFXArc "\nWARNING: Too large SFX archive. Windows cannot run the executable file exceeding 4 GB."
|
||||
#define MCalcCRCAllVol "\nCalculating control sums of all volumes."
|
||||
#define MNotEnoughDisk "\nERROR: Not enough disk space for %s."
|
||||
@ -1,24 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
|
||||
static char LogName[NM];
|
||||
|
||||
void InitLogOptions(char *LogName)
|
||||
{
|
||||
strcpy(::LogName,LogName);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
void Log(const char *ArcName,const char *Format,...)
|
||||
{
|
||||
safebuf char Msg[2*NM+1024];
|
||||
va_list ArgPtr;
|
||||
va_start(ArgPtr,Format);
|
||||
vsprintf(Msg,Format,ArgPtr);
|
||||
va_end(ArgPtr);
|
||||
eprintf("%s",Msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#ifndef _RAR_LOG_
|
||||
#define _RAR_LOG_
|
||||
|
||||
void InitLogOptions(char *LogName);
|
||||
|
||||
#ifndef SILENT
|
||||
void Log(const char *ArcName,const char *Format,...);
|
||||
#endif
|
||||
|
||||
#ifdef SILENT
|
||||
#ifdef __GNUC__
|
||||
#define Log(args...)
|
||||
#else
|
||||
inline void Log(const char *a,const char *b,const char *c=NULL,const char *d=NULL) {}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,493 +0,0 @@
|
||||
.AUTODEPEND
|
||||
|
||||
basepath = $(BASEPATHCC)
|
||||
binpath = $(basepath)\bin
|
||||
libpath = $(basepath)\lib
|
||||
rarpath = .
|
||||
incpath = $(basepath)\include;$(rarpath)
|
||||
|
||||
cc = $(binpath)\bcc32
|
||||
link = $(binpath)\ilink32
|
||||
|
||||
objpath = .
|
||||
guiopt = -WC -H=$(objpath)\rar.csm
|
||||
|
||||
!ifdef SFX_MODULE
|
||||
guiopt=$(guiopt) -x-
|
||||
!endif
|
||||
|
||||
!ifdef DEBUG
|
||||
optdeb=-Od -k -vi- -DDEBUG
|
||||
!else
|
||||
# -O is not safe to use with -pr and int64 return values, so let's turn it off
|
||||
optdeb=-O1 -O- -k-
|
||||
#optdeb=-Ob -Oe -Og -Oi -Ol -Om -Op -OS -Ov -Z -Oc
|
||||
!endif
|
||||
|
||||
|
||||
optunrar=-DUNRAR
|
||||
linkdest=unrar.exe
|
||||
|
||||
!ifdef SFX_MODULE
|
||||
optunrar=-DUNRAR -DSFX_MODULE
|
||||
linkdest=sfx.exe
|
||||
!endif
|
||||
|
||||
linkopt = -L$(libpath) -ap -c -v -s -V4.0 -Gn
|
||||
compopt = -P -c -I$(incpath) -R -v -vi -w-pch -w-par -K -f-\
|
||||
-ff- -a4 -pr -RT- $(optdeb) $(guiopt) $(optunrar) -d -w-8072
|
||||
|
||||
!ifdef RARDLL
|
||||
SILENT=true
|
||||
linkdest=unrar.dll
|
||||
linkopt=$(linkopt) -Tpd
|
||||
compopt=$(compopt) -DRARDLL
|
||||
!else
|
||||
linkopt=$(linkopt) -Tpe -B:0x400000
|
||||
!endif
|
||||
|
||||
!ifdef SILENT
|
||||
compopt=$(compopt) -DSILENT
|
||||
!endif
|
||||
|
||||
|
||||
rar: $(linkdest)
|
||||
|
||||
Dep_SFX= \
|
||||
$(objpath)\strlist.obj\
|
||||
$(objpath)\strfn.obj\
|
||||
$(objpath)\pathfn.obj\
|
||||
$(objpath)\secpassword.obj\
|
||||
$(objpath)\cmddata.obj\
|
||||
$(objpath)\consio.obj\
|
||||
$(objpath)\savepos.obj\
|
||||
$(objpath)\smallfn.obj\
|
||||
$(objpath)\file.obj\
|
||||
$(objpath)\filefn.obj\
|
||||
$(objpath)\filcreat.obj\
|
||||
$(objpath)\sha1.obj\
|
||||
$(objpath)\archive.obj\
|
||||
$(objpath)\arcread.obj\
|
||||
$(objpath)\unicode.obj\
|
||||
$(objpath)\system.obj\
|
||||
$(objpath)\isnt.obj\
|
||||
$(objpath)\crc.obj\
|
||||
$(objpath)\crypt.obj\
|
||||
$(objpath)\rijndael.obj\
|
||||
$(objpath)\rawread.obj\
|
||||
$(objpath)\encname.obj\
|
||||
$(objpath)\resource.obj\
|
||||
$(objpath)\match.obj\
|
||||
$(objpath)\find.obj\
|
||||
$(objpath)\timefn.obj\
|
||||
$(objpath)\getbits.obj\
|
||||
$(objpath)\rarvm.obj\
|
||||
$(objpath)\rdwrfn.obj\
|
||||
$(objpath)\options.obj\
|
||||
$(objpath)\ulinks.obj\
|
||||
$(objpath)\errhnd.obj\
|
||||
$(objpath)\volume.obj\
|
||||
$(objpath)\rs.obj\
|
||||
$(objpath)\recvol.obj\
|
||||
$(objpath)\extinfo.obj\
|
||||
$(objpath)\extract.obj\
|
||||
$(objpath)\unpack.obj\
|
||||
$(objpath)\rar.obj\
|
||||
$(objpath)\global.obj
|
||||
|
||||
Dep_Unrar = \
|
||||
$(objpath)\filestr.obj\
|
||||
$(objpath)\scantree.obj
|
||||
|
||||
Dep_Dll = \
|
||||
$(objpath)\dll.obj
|
||||
|
||||
#Dep_SFXOnly = $(objpath)\rtl.obj
|
||||
|
||||
!ifndef GUI
|
||||
!ifndef SILENT
|
||||
Dep_Console = \
|
||||
$(objpath)\list.obj
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!ifdef SFX_MODULE
|
||||
Dep = $(Dep_SFX) $(Dep_SFXOnly)
|
||||
!else
|
||||
Dep = $(Dep_SFX) $(Dep_Unrar)
|
||||
!endif
|
||||
|
||||
!ifndef GUI
|
||||
Dep = $(Dep) $(Dep_Console)
|
||||
!endif
|
||||
|
||||
!ifdef RARDLL
|
||||
Dep = $(Dep) $(Dep_Dll)
|
||||
!endif
|
||||
|
||||
!ifdef GUI
|
||||
$(linkdest) : $(Dep)
|
||||
echo Done
|
||||
!else
|
||||
$(linkdest) : $(Dep)
|
||||
$(link) @&&|
|
||||
$(linkopt) +
|
||||
#!ifdef SFX_MODULE
|
||||
#$(objpath)\dummy.obj+
|
||||
#$(objpath)\ll.obj+
|
||||
#$(objpath)\rtl.obj+
|
||||
#!else
|
||||
!ifdef RARDLL
|
||||
$(libpath)\c0d32.obj+
|
||||
!else
|
||||
$(libpath)\c0x32.obj+
|
||||
!endif
|
||||
#!endif
|
||||
$(objpath)\strlist.obj+
|
||||
$(objpath)\strfn.obj+
|
||||
$(objpath)\pathfn.obj+
|
||||
$(objpath)\savepos.obj+
|
||||
$(objpath)\smallfn.obj+
|
||||
$(objpath)\global.obj+
|
||||
$(objpath)\file.obj+
|
||||
$(objpath)\filefn.obj+
|
||||
$(objpath)\filcreat.obj+
|
||||
$(objpath)\sha1.obj+
|
||||
$(objpath)\archive.obj+
|
||||
$(objpath)\arcread.obj+
|
||||
$(objpath)\unicode.obj+
|
||||
$(objpath)\system.obj+
|
||||
$(objpath)\isnt.obj+
|
||||
$(objpath)\crc.obj+
|
||||
$(objpath)\crypt.obj+
|
||||
$(objpath)\rijndael.obj+
|
||||
$(objpath)\rawread.obj+
|
||||
$(objpath)\encname.obj+
|
||||
$(objpath)\resource.obj+
|
||||
$(objpath)\match.obj+
|
||||
$(objpath)\find.obj+
|
||||
!ifndef SFX_MODULE
|
||||
$(objpath)\filestr.obj+
|
||||
$(objpath)\scantree.obj+
|
||||
!endif
|
||||
$(objpath)\timefn.obj+
|
||||
$(objpath)\getbits.obj+
|
||||
$(objpath)\rarvm.obj+
|
||||
$(objpath)\rdwrfn.obj+
|
||||
$(objpath)\consio.obj+
|
||||
$(objpath)\secpassword.obj+
|
||||
$(objpath)\cmddata.obj+
|
||||
$(objpath)\options.obj+
|
||||
$(objpath)\ulinks.obj+
|
||||
$(objpath)\volume.obj+
|
||||
$(objpath)\extinfo.obj+
|
||||
$(objpath)\extract.obj+
|
||||
$(objpath)\rs.obj+
|
||||
$(objpath)\recvol.obj+
|
||||
!ifndef SILENT
|
||||
!ifndef GUI
|
||||
$(objpath)\list.obj+
|
||||
!endif
|
||||
!endif
|
||||
!ifdef RARDLL
|
||||
$(objpath)\dll.obj+
|
||||
!endif
|
||||
$(objpath)\errhnd.obj+
|
||||
$(objpath)\unpack.obj+
|
||||
$(objpath)\rar.obj
|
||||
$<,$*
|
||||
$(libpath)\cw32.lib+
|
||||
$(libpath)\import32.lib
|
||||
!ifdef RARDLL
|
||||
$(rarpath)\dll.def
|
||||
!else
|
||||
|
||||
!endif
|
||||
|
|
||||
!endif
|
||||
|
||||
$(objpath)\rar.obj : $(rarpath)\rar.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rar.cpp
|
||||
|
|
||||
|
||||
$(objpath)\strlist.obj : $(rarpath)\strlist.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\strlist.cpp
|
||||
|
|
||||
|
||||
$(objpath)\strfn.obj : $(rarpath)\strfn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\strfn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\pathfn.obj : $(rarpath)\pathfn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\pathfn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\savepos.obj : $(rarpath)\savepos.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\savepos.cpp
|
||||
|
|
||||
|
||||
$(objpath)\smallfn.obj : $(rarpath)\smallfn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\smallfn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\global.obj : $(rarpath)\global.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -H- -o$@ $(rarpath)\global.cpp
|
||||
|
|
||||
|
||||
$(objpath)\file.obj : $(rarpath)\file.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\file.cpp
|
||||
|
|
||||
|
||||
$(objpath)\filefn.obj : $(rarpath)\filefn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\filefn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\filestr.obj : $(rarpath)\filestr.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\filestr.cpp
|
||||
|
|
||||
|
||||
$(objpath)\filcreat.obj : $(rarpath)\filcreat.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\filcreat.cpp
|
||||
|
|
||||
|
||||
$(objpath)\sha1.obj : $(rarpath)\sha1.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\sha1.cpp
|
||||
|
|
||||
|
||||
$(objpath)\archive.obj : $(rarpath)\archive.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\archive.cpp
|
||||
|
|
||||
|
||||
$(objpath)\arcread.obj : $(rarpath)\arcread.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\arcread.cpp
|
||||
|
|
||||
|
||||
$(objpath)\unicode.obj : $(rarpath)\unicode.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\unicode.cpp
|
||||
|
|
||||
|
||||
$(objpath)\system.obj : $(rarpath)\system.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\system.cpp
|
||||
|
|
||||
|
||||
$(objpath)\isnt.obj : $(rarpath)\isnt.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\isnt.cpp
|
||||
|
|
||||
|
||||
$(objpath)\crc.obj : $(rarpath)\crc.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\crc.cpp
|
||||
|
|
||||
|
||||
$(objpath)\crypt.obj : $(rarpath)\crypt.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\crypt.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rijndael.obj : $(rarpath)\rijndael.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rijndael.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rawread.obj : $(rarpath)\rawread.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rawread.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rawwrite.obj : $(rarpath)\rawwrite.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rawwrite.cpp
|
||||
|
|
||||
|
||||
$(objpath)\encname.obj : $(rarpath)\encname.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\encname.cpp
|
||||
|
|
||||
|
||||
$(objpath)\resource.obj : $(rarpath)\resource.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\resource.cpp
|
||||
|
|
||||
|
||||
$(objpath)\match.obj : $(rarpath)\match.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\match.cpp
|
||||
|
|
||||
|
||||
$(objpath)\find.obj : $(rarpath)\find.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\find.cpp
|
||||
|
|
||||
|
||||
$(objpath)\scantree.obj : $(rarpath)\scantree.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\scantree.cpp
|
||||
|
|
||||
|
||||
$(objpath)\timefn.obj : $(rarpath)\timefn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\timefn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\getbits.obj : $(rarpath)\getbits.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\getbits.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rarvm.obj : $(rarpath)\rarvm.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rarvm.cpp
|
||||
|
|
||||
|
||||
$(objpath)\putbits.obj : $(rarpath)\putbits.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\putbits.cpp
|
||||
|
|
||||
|
||||
$(objpath)\pack.obj : $(rarpath)\pack.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\pack.cpp
|
||||
|
|
||||
|
||||
$(objpath)\packbord.obj : $(rarpath)\packbord.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\packbord.cpp
|
||||
|
|
||||
|
||||
$(objpath)\packanlz.obj : $(rarpath)\packanlz.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\packanlz.cpp
|
||||
|
|
||||
|
||||
$(objpath)\cblock.obj : $(rarpath)\cblock.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\cblock.cpp
|
||||
|
|
||||
|
||||
$(objpath)\add.obj : $(rarpath)\add.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\add.cpp
|
||||
|
|
||||
|
||||
$(objpath)\addlist.obj : $(rarpath)\addlist.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\addlist.cpp
|
||||
|
|
||||
|
||||
$(objpath)\procarc.obj : $(rarpath)\procarc.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\procarc.cpp
|
||||
|
|
||||
|
||||
$(objpath)\sfx.obj : $(rarpath)\sfx.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\sfx.cpp
|
||||
|
|
||||
|
||||
$(objpath)\comment.obj : $(rarpath)\comment.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\comment.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rs.obj : $(rarpath)\rs.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rs.cpp
|
||||
|
|
||||
|
||||
$(objpath)\recvol.obj : $(rarpath)\recvol.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\recvol.cpp
|
||||
|
|
||||
|
||||
$(objpath)\repair.obj : $(rarpath)\repair.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\repair.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rdwrfn.obj : $(rarpath)\rdwrfn.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rdwrfn.cpp
|
||||
|
|
||||
|
||||
$(objpath)\consio.obj : $(rarpath)\consio.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\consio.cpp
|
||||
|
|
||||
|
||||
$(objpath)\secpassword.obj : $(rarpath)\secpassword.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\secpassword.cpp
|
||||
|
|
||||
|
||||
$(objpath)\cmddata.obj : $(rarpath)\cmddata.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\cmddata.cpp
|
||||
|
|
||||
|
||||
$(objpath)\options.obj : $(rarpath)\options.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\options.cpp
|
||||
|
|
||||
|
||||
$(objpath)\ulinks.obj : $(rarpath)\ulinks.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\ulinks.cpp
|
||||
|
|
||||
|
||||
$(objpath)\errhnd.obj : $(rarpath)\errhnd.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\errhnd.cpp
|
||||
|
|
||||
|
||||
$(objpath)\volume.obj : $(rarpath)\volume.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\volume.cpp
|
||||
|
|
||||
|
||||
$(objpath)\extinfo.obj : $(rarpath)\extinfo.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\extinfo.cpp
|
||||
|
|
||||
|
||||
|
||||
$(objpath)\extract.obj : $(rarpath)\extract.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\extract.cpp
|
||||
|
|
||||
|
||||
$(objpath)\list.obj : $(rarpath)\list.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\list.cpp
|
||||
|
|
||||
|
||||
$(objpath)\rtl.obj : $(rarpath)\rtl.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\rtl.cpp
|
||||
|
|
||||
|
||||
$(objpath)\unpack.obj : $(rarpath)\unpack.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\unpack.cpp
|
||||
|
|
||||
|
||||
$(objpath)\dll.obj : $(rarpath)\dll.cpp
|
||||
$(cc) -q @&&|
|
||||
$(compopt) -o$@ $(rarpath)\dll.cpp
|
||||
|
|
||||
@ -1,50 +0,0 @@
|
||||
#
|
||||
# Makefile for DJGPP - unrar
|
||||
#
|
||||
# Note: you have to 'make clean' before you can build
|
||||
# the sfx module
|
||||
#
|
||||
|
||||
# DOS32 using DJGPP 2.03 Patchlevel 2 and GCC 2.95.3
|
||||
CXX = gpp
|
||||
CXXFLAGS = -O2 -Wno-deprecated
|
||||
#DEFINES = -D_MSC_VER -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
|
||||
##########################
|
||||
|
||||
.PHONY: all clean veryclean
|
||||
|
||||
COMPILE=$(CXX) $(CXXFLAGS) $(DEFINES)
|
||||
LINK=$(CXX)
|
||||
|
||||
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
|
||||
|
||||
OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o \
|
||||
file.o filefn.o filcreat.o archive.o arcread.o unicode.o \
|
||||
system.o isnt.o crypt.o crc.o rawread.o encname.o \
|
||||
resource.o match.o timefn.o rdwrfn.o consio.o options.o \
|
||||
ulinks.o errhnd.o rarvm.o rijndael.o getbits.o sha1.o \
|
||||
extinfo.o extract.o volume.o list.o find.o unpack.o secpassword.o cmddata.o
|
||||
|
||||
.cpp.o:
|
||||
$(COMPILE) -D$(WHAT) -c $<
|
||||
|
||||
all: unrar
|
||||
|
||||
unrar: WHAT=UNRAR
|
||||
unrar: $(OBJECTS) $(UNRAR_OBJ)
|
||||
$(LINK) -Wl,-s -o unrar.exe $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
|
||||
exe2coff unrar.exe
|
||||
cp -u $(DJDIR)/bin/cwsdstub.exe .
|
||||
copy /b cwsdstub.exe+unrar unrar.exe
|
||||
-upx --ultra-brute unrar.exe
|
||||
|
||||
sfx: WHAT=SFX_MODULE
|
||||
sfx: $(OBJECTS)
|
||||
$(LINK) -Wl,-s -o default.sfx $(LDFLAGS) $(OBJECTS) -DSFX_MODULE
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) $(UNRAR_OBJ)
|
||||
|
||||
veryclean: clean
|
||||
$(RM) unrar.exe default.sfx cwsdstub.exe unrar
|
||||
@ -1,54 +0,0 @@
|
||||
# Makefile for Digital Mars C++ Compiler
|
||||
# http://www.rarlab.com
|
||||
# http://www.digitalmars.com
|
||||
#
|
||||
# DEFINES: UNRAR RARDLL GUI SFX_MODULE SILENT
|
||||
|
||||
NAME = unrar
|
||||
EXT = exe
|
||||
|
||||
CPP = dmc
|
||||
|
||||
LINK = link
|
||||
|
||||
# --------------
|
||||
# Release Build
|
||||
# --------------
|
||||
DEFINES = -DNDEBUG -D_MSC_VER -DUNRAR
|
||||
CPPFLAGS = -o+all -ff -Nc -g- -Ae
|
||||
LNKFLAGS = /EXETYPE:NT /MACHINE:i386 /SUBSYSTEM:CONSOLE /NOLOGO /NODEBUG /NOCODEVIEW /PACKFUNCTIONS
|
||||
|
||||
# --------------
|
||||
# Debug Build
|
||||
# --------------
|
||||
#DEFINES = -D_DEBUG -D_MSC_VER -DUNRAR
|
||||
#CPPFLAGS = -o+none -Nc -S -gf -Ae
|
||||
#LNKFLAGS = /EXETYPE:NT /MACHINE:i386 /SUBSYSTEM:CONSOLE /NOLOGO /DEBUG
|
||||
|
||||
OBJ = rar.obj strlist.obj strfn.obj pathfn.obj savepos.obj smallfn.o global.obj \
|
||||
file.obj filefn.obj filcreat.obj archive.obj arcread.obj unicode.obj \
|
||||
system.obj isnt.obj crypt.obj crc.obj rawread.obj encname.obj \
|
||||
resource.obj match.obj timefn.obj rdwrfn.obj consio.obj options.obj \
|
||||
ulinks.obj errhnd.obj rarvm.obj rijndael.obj getbits.obj sha1.obj \
|
||||
extinfo.obj extract.obj volume.obj find.obj unpack.obj cmddata.obj \
|
||||
secpassword.obj filestr.obj recvol.obj rs.obj scantree.obj \
|
||||
list.obj \
|
||||
# dll.obj \
|
||||
|
||||
LIB = kernel32.lib+user32.lib+advapi32.lib
|
||||
|
||||
#DEF = dll.def
|
||||
|
||||
link: $(OBJ)
|
||||
$(LINK) $(LNKFLAGS) $(OBJ), $(NAME).$(EXT), $(NAME).map, $(LIB), $(DEF)
|
||||
|
||||
.c.obj:
|
||||
$(CPP) $(CPPFLAGS) $(DEFINES) -c $< -o $@
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPFLAGS) $(DEFINES) -c $< -o $@
|
||||
|
||||
clean:
|
||||
del $(OBJ)
|
||||
del $(NAME).$(EXT)
|
||||
del $(NAME).map
|
||||
@ -1,146 +0,0 @@
|
||||
#
|
||||
# Makefile for UNIX - unrar
|
||||
|
||||
# Linux using GCC
|
||||
CXX=g++
|
||||
CXXFLAGS=-O2
|
||||
LIBFLAGS=-fPIC
|
||||
DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
STRIP=strip
|
||||
DESTDIR=/usr
|
||||
|
||||
# Linux using LCC
|
||||
#CXX=lcc
|
||||
#CXXFLAGS=-O2
|
||||
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# HP UX using aCC
|
||||
#CXX=aCC
|
||||
#CXXFLAGS=-AA +O2 +Onolimit
|
||||
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# IRIX using GCC
|
||||
#CXX=g++
|
||||
#CXXFLAGS=-O2
|
||||
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# IRIX using MIPSPro (experimental)
|
||||
#CXX=CC
|
||||
#CXXFLAGS=-O2 -mips3 -woff 1234,1156,3284 -LANG:std
|
||||
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -Dint64=int64_t
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# AIX using xlC (IBM VisualAge C++ 5.0)
|
||||
#CXX=xlC
|
||||
#CXXFLAGS=-O -qinline -qro -qroconst -qmaxmem=16384 -qcpluscmt
|
||||
#DEFINES=-D_LARGE_FILES -D_LARGE_FILE_API
|
||||
#LIBS=-lbsd
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# Solaris using CC
|
||||
#CXX=CC
|
||||
#CXXFLAGS=-fast -erroff=wvarhidemem
|
||||
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
#STRIP=strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# Solaris using GCC (optimized for UltraSPARC 1 CPU)
|
||||
#CXX=g++
|
||||
#CXXFLAGS=-O3 -mcpu=v9 -mtune=ultrasparc -m32
|
||||
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
#STRIP=/usr/ccs/bin/strip
|
||||
#DESTDIR=/usr
|
||||
|
||||
# Tru64 5.1B using GCC3
|
||||
#CXX=g++
|
||||
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_XOPEN_SOURCE=500
|
||||
#STRIP=strip
|
||||
#LDFLAGS=-rpath /usr/local/gcc/lib
|
||||
#DESTDIR=/usr
|
||||
|
||||
# Tru64 5.1B using DEC C++
|
||||
#CXX=cxx
|
||||
#CXXFLAGS=-O4 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dint64=long
|
||||
#STRIP=strip
|
||||
#LDFLAGS=
|
||||
#DESTDIR=/usr
|
||||
|
||||
# QNX 6.x using GCC
|
||||
#CXX=g++
|
||||
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fexceptions
|
||||
#STRIP=strip
|
||||
#LDFLAGS=-fexceptions
|
||||
#DESTDIR=/usr
|
||||
|
||||
# Cross-compile
|
||||
# Linux using arm-linux-g++
|
||||
#CXX=arm-linux-g++
|
||||
#CXXFLAGS=-O2
|
||||
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
#STRIP=arm-linux-strip
|
||||
#LDFLAGS=-static
|
||||
#DESTDIR=/usr
|
||||
|
||||
##########################
|
||||
|
||||
COMPILE=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES)
|
||||
LINK=$(CXX)
|
||||
|
||||
WHAT=UNRAR
|
||||
|
||||
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
|
||||
LIB_OBJ=filestr.o scantree.o dll.o
|
||||
|
||||
OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o file.o filefn.o filcreat.o \
|
||||
archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o encname.o \
|
||||
resource.o match.o timefn.o rdwrfn.o consio.o options.o ulinks.o errhnd.o rarvm.o secpassword.o \
|
||||
rijndael.o getbits.o sha1.o extinfo.o extract.o volume.o list.o find.o unpack.o cmddata.o
|
||||
|
||||
.cpp.o:
|
||||
$(COMPILE) -D$(WHAT) -c $<
|
||||
|
||||
all: unrar
|
||||
|
||||
install: install-unrar
|
||||
|
||||
uninstall: uninstall-unrar
|
||||
|
||||
clean:
|
||||
@rm -f *.o *.bak *~
|
||||
|
||||
unrar: clean $(OBJECTS) $(UNRAR_OBJ)
|
||||
@rm -f unrar
|
||||
$(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
|
||||
$(STRIP) unrar
|
||||
|
||||
sfx: WHAT=SFX_MODULE
|
||||
sfx: clean $(OBJECTS)
|
||||
@rm -f default.sfx
|
||||
$(LINK) -o default.sfx $(LDFLAGS) $(OBJECTS)
|
||||
$(STRIP) default.sfx
|
||||
|
||||
lib: WHAT=RARDLL
|
||||
lib: CXXFLAGS+=$(LIBFLAGS)
|
||||
lib: clean $(OBJECTS) $(LIB_OBJ)
|
||||
@rm -f libunrar.so
|
||||
$(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
|
||||
|
||||
install-unrar:
|
||||
install -D unrar $(DESTDIR)/bin/unrar
|
||||
|
||||
uninstall-unrar:
|
||||
rm -f $(DESTDIR)/bin/unrar
|
||||
|
||||
install-lib:
|
||||
install libunrar.so $(DESTDIR)/lib
|
||||
|
||||
uninstall-lib:
|
||||
rm -f $(DESTDIR)/lib/libunrar.so
|
||||
@ -1,300 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
static bool match(const char *pattern,const char *string,bool ForceCase);
|
||||
static bool match(const wchar *pattern,const wchar *string,bool ForceCase);
|
||||
|
||||
static int mstricompc(const char *Str1,const char *Str2,bool ForceCase);
|
||||
static int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase);
|
||||
static int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase);
|
||||
static int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase);
|
||||
|
||||
inline uint toupperc(byte ch,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(ch);
|
||||
#ifdef _WIN_ALL
|
||||
return((uint)(LPARAM)CharUpper((LPTSTR)(ch)));
|
||||
#elif defined(_UNIX)
|
||||
return(ch);
|
||||
#else
|
||||
return(toupper(ch));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline uint touppercw(uint ch,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(ch);
|
||||
#if defined(_UNIX)
|
||||
return(ch);
|
||||
#else
|
||||
return(toupperw(ch));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool CmpName(const char *Wildcard,const char *Name,int CmpMode)
|
||||
{
|
||||
bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0;
|
||||
|
||||
CmpMode&=MATCH_MODEMASK;
|
||||
|
||||
if (CmpMode!=MATCH_NAMES)
|
||||
{
|
||||
size_t WildLength=strlen(Wildcard);
|
||||
if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH &&
|
||||
mstrnicompc(Wildcard,Name,WildLength,ForceCase)==0)
|
||||
{
|
||||
// For all modes except MATCH_NAMES, MATCH_EXACT and MATCH_EXACTPATH
|
||||
// "path1" mask must match "path1\path2\filename.ext" and "path1" names.
|
||||
char NextCh=Name[WildLength];
|
||||
if (NextCh=='\\' || NextCh=='/' || NextCh==0)
|
||||
return(true);
|
||||
}
|
||||
|
||||
// Nothing more to compare for MATCH_SUBPATHONLY.
|
||||
if (CmpMode==MATCH_SUBPATHONLY)
|
||||
return(false);
|
||||
|
||||
char Path1[NM],Path2[NM];
|
||||
GetFilePath(Wildcard,Path1,ASIZE(Path1));
|
||||
GetFilePath(Name,Path2,ASIZE(Path1));
|
||||
|
||||
if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) &&
|
||||
mstricompc(Path1,Path2,ForceCase)!=0)
|
||||
return(false);
|
||||
if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH)
|
||||
if (IsWildcard(Path1))
|
||||
return(match(Wildcard,Name,ForceCase));
|
||||
else
|
||||
if (CmpMode==MATCH_SUBPATH || IsWildcard(Wildcard))
|
||||
{
|
||||
if (*Path1 && mstrnicompc(Path1,Path2,strlen(Path1),ForceCase)!=0)
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if (mstricompc(Path1,Path2,ForceCase)!=0)
|
||||
return(false);
|
||||
}
|
||||
char *Name1=PointToName(Wildcard);
|
||||
char *Name2=PointToName(Name);
|
||||
|
||||
// Always return false for RAR temporary files to exclude them
|
||||
// from archiving operations.
|
||||
if (mstrnicompc("__rar_",Name2,6,false)==0)
|
||||
return(false);
|
||||
|
||||
if (CmpMode==MATCH_EXACT)
|
||||
return(mstricompc(Name1,Name2,ForceCase)==0);
|
||||
|
||||
return(match(Name1,Name2,ForceCase));
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
bool CmpName(const wchar *Wildcard,const wchar *Name,int CmpMode)
|
||||
{
|
||||
bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0;
|
||||
|
||||
CmpMode&=MATCH_MODEMASK;
|
||||
|
||||
if (CmpMode!=MATCH_NAMES)
|
||||
{
|
||||
size_t WildLength=wcslen(Wildcard);
|
||||
if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH &&
|
||||
mwcsnicompc(Wildcard,Name,WildLength,ForceCase)==0)
|
||||
{
|
||||
// For all modes except MATCH_NAMES, MATCH_EXACT and MATCH_EXACTPATH
|
||||
// "path1" mask must match "path1\path2\filename.ext" and "path1" names.
|
||||
wchar NextCh=Name[WildLength];
|
||||
if (NextCh==L'\\' || NextCh==L'/' || NextCh==0)
|
||||
return(true);
|
||||
}
|
||||
|
||||
// Nothing more to compare for MATCH_SUBPATHONLY.
|
||||
if (CmpMode==MATCH_SUBPATHONLY)
|
||||
return(false);
|
||||
|
||||
wchar Path1[NM],Path2[NM];
|
||||
GetFilePath(Wildcard,Path1,ASIZE(Path1));
|
||||
GetFilePath(Name,Path2,ASIZE(Path2));
|
||||
|
||||
if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) &&
|
||||
mwcsicompc(Path1,Path2,ForceCase)!=0)
|
||||
return(false);
|
||||
if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH)
|
||||
if (IsWildcard(NULL,Path1))
|
||||
return(match(Wildcard,Name,ForceCase));
|
||||
else
|
||||
if (CmpMode==MATCH_SUBPATH || IsWildcard(NULL,Wildcard))
|
||||
{
|
||||
if (*Path1 && mwcsnicompc(Path1,Path2,wcslen(Path1),ForceCase)!=0)
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if (mwcsicompc(Path1,Path2,ForceCase)!=0)
|
||||
return(false);
|
||||
}
|
||||
wchar *Name1=PointToName(Wildcard);
|
||||
wchar *Name2=PointToName(Name);
|
||||
|
||||
// Always return false for RAR temporary files to exclude them
|
||||
// from archiving operations.
|
||||
if (mwcsnicompc(L"__rar_",Name2,6,false)==0)
|
||||
return(false);
|
||||
|
||||
if (CmpMode==MATCH_EXACT)
|
||||
return(mwcsicompc(Name1,Name2,ForceCase)==0);
|
||||
|
||||
return(match(Name1,Name2,ForceCase));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool match(const char *pattern,const char *string,bool ForceCase)
|
||||
{
|
||||
for (;; ++string)
|
||||
{
|
||||
char stringc=toupperc(*string,ForceCase);
|
||||
char patternc=toupperc(*pattern++,ForceCase);
|
||||
switch (patternc)
|
||||
{
|
||||
case 0:
|
||||
return(stringc==0);
|
||||
case '?':
|
||||
if (stringc == 0)
|
||||
return(false);
|
||||
break;
|
||||
case '*':
|
||||
if (*pattern==0)
|
||||
return(true);
|
||||
if (*pattern=='.')
|
||||
{
|
||||
if (pattern[1]=='*' && pattern[2]==0)
|
||||
return(true);
|
||||
const char *dot=strchr(string,'.');
|
||||
if (pattern[1]==0)
|
||||
return (dot==NULL || dot[1]==0);
|
||||
if (dot!=NULL)
|
||||
{
|
||||
string=dot;
|
||||
if (strpbrk(pattern,"*?")==NULL && strchr(string+1,'.')==NULL)
|
||||
return(mstricompc(pattern+1,string+1,ForceCase)==0);
|
||||
}
|
||||
}
|
||||
|
||||
while (*string)
|
||||
if (match(pattern,string++,ForceCase))
|
||||
return(true);
|
||||
return(false);
|
||||
default:
|
||||
if (patternc != stringc)
|
||||
{
|
||||
// Allow "name." mask match "name" and "name.\" match "name\".
|
||||
if (patternc=='.' && (stringc==0 || stringc=='\\' || stringc=='.'))
|
||||
return(match(pattern,string,ForceCase));
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
bool match(const wchar *pattern,const wchar *string,bool ForceCase)
|
||||
{
|
||||
for (;; ++string)
|
||||
{
|
||||
wchar stringc=touppercw(*string,ForceCase);
|
||||
wchar patternc=touppercw(*pattern++,ForceCase);
|
||||
switch (patternc)
|
||||
{
|
||||
case 0:
|
||||
return(stringc==0);
|
||||
case '?':
|
||||
if (stringc == 0)
|
||||
return(false);
|
||||
break;
|
||||
case '*':
|
||||
if (*pattern==0)
|
||||
return(true);
|
||||
if (*pattern=='.')
|
||||
{
|
||||
if (pattern[1]=='*' && pattern[2]==0)
|
||||
return(true);
|
||||
const wchar *dot=wcschr(string,'.');
|
||||
if (pattern[1]==0)
|
||||
return (dot==NULL || dot[1]==0);
|
||||
if (dot!=NULL)
|
||||
{
|
||||
string=dot;
|
||||
if (wcspbrk(pattern,L"*?")==NULL && wcschr(string+1,'.')==NULL)
|
||||
return(mwcsicompc(pattern+1,string+1,ForceCase)==0);
|
||||
}
|
||||
}
|
||||
|
||||
while (*string)
|
||||
if (match(pattern,string++,ForceCase))
|
||||
return(true);
|
||||
return(false);
|
||||
default:
|
||||
if (patternc != stringc)
|
||||
{
|
||||
// Allow "name." mask match "name" and "name.\" match "name\".
|
||||
if (patternc=='.' && (stringc==0 || stringc=='\\' || stringc=='.'))
|
||||
return(match(pattern,string,ForceCase));
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int mstricompc(const char *Str1,const char *Str2,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(strcmp(Str1,Str2));
|
||||
return(stricompc(Str1,Str2));
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(wcscmp(Str1,Str2));
|
||||
return(wcsicompc(Str1,Str2));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(strncmp(Str1,Str2,N));
|
||||
#if defined(_UNIX)
|
||||
return(strncmp(Str1,Str2,N));
|
||||
#else
|
||||
return(strnicomp(Str1,Str2,N));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase)
|
||||
{
|
||||
if (ForceCase)
|
||||
return(wcsncmp(Str1,Str2,N));
|
||||
#if defined(_UNIX)
|
||||
return(wcsncmp(Str1,Str2,N));
|
||||
#else
|
||||
return(wcsnicomp(Str1,Str2,N));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -1,35 +0,0 @@
|
||||
#ifndef _RAR_MATCH_
|
||||
#define _RAR_MATCH_
|
||||
|
||||
enum {
|
||||
MATCH_NAMES, // Paths are ignored.
|
||||
// Compares names only using wildcards.
|
||||
|
||||
MATCH_SUBPATHONLY, // Paths must match either exactly or path in wildcard
|
||||
// must be present in the beginning of file path.
|
||||
// For example, "c:\path1\*" or "c:\path1" will match
|
||||
// "c:\path1\path2\file".
|
||||
// Names are not compared.
|
||||
|
||||
MATCH_EXACT, // Paths must match exactly.
|
||||
// Names must match exactly.
|
||||
|
||||
MATCH_EXACTPATH, // Paths must match exactly.
|
||||
// Names are compared using wildcards.
|
||||
|
||||
MATCH_SUBPATH, // Names must be the same, but path in mask is allowed
|
||||
// to be only a part of name path. In other words,
|
||||
// we match all files matching the file mask
|
||||
// in current folder and subfolders.
|
||||
|
||||
MATCH_WILDSUBPATH // Works as MATCH_SUBPATH if file mask contains
|
||||
// wildcards and as MATCH_EXACTPATH otherwise.
|
||||
};
|
||||
|
||||
#define MATCH_MODEMASK 0x0000ffff
|
||||
#define MATCH_FORCECASESENSITIVE 0x80000000
|
||||
|
||||
bool CmpName(const char *Wildcard,const char *Name,int CmpMode);
|
||||
bool CmpName(const wchar *Wildcard,const wchar *Name,int CmpMode);
|
||||
|
||||
#endif
|
||||
@ -1,610 +0,0 @@
|
||||
/****************************************************************************
|
||||
* This file is part of PPMd project *
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2000 *
|
||||
* Contents: model description and encoding/decoding routines *
|
||||
****************************************************************************/
|
||||
|
||||
inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
|
||||
STATE& FirstState)
|
||||
{
|
||||
PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
|
||||
if ( pc )
|
||||
{
|
||||
pc->NumStats=1;
|
||||
pc->OneState=FirstState;
|
||||
pc->Suffix=this;
|
||||
pStats->Successor=pc;
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
||||
ModelPPM::ModelPPM()
|
||||
{
|
||||
MinContext=NULL;
|
||||
MaxContext=NULL;
|
||||
MedContext=NULL;
|
||||
}
|
||||
|
||||
|
||||
void ModelPPM::RestartModelRare()
|
||||
{
|
||||
int i, k, m;
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
SubAlloc.InitSubAllocator();
|
||||
InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
|
||||
MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
|
||||
MinContext->Suffix=NULL;
|
||||
OrderFall=MaxOrder;
|
||||
MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
|
||||
FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
|
||||
for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
|
||||
{
|
||||
MinContext->U.Stats[i].Symbol=i;
|
||||
MinContext->U.Stats[i].Freq=1;
|
||||
MinContext->U.Stats[i].Successor=NULL;
|
||||
}
|
||||
|
||||
static const ushort InitBinEsc[]={
|
||||
0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
|
||||
};
|
||||
|
||||
for (i=0;i < 128;i++)
|
||||
for (k=0;k < 8;k++)
|
||||
for (m=0;m < 64;m += 8)
|
||||
BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
|
||||
for (i=0;i < 25;i++)
|
||||
for (k=0;k < 16;k++)
|
||||
SEE2Cont[i][k].init(5*i+10);
|
||||
}
|
||||
|
||||
|
||||
void ModelPPM::StartModelRare(int MaxOrder)
|
||||
{
|
||||
int i, k, m ,Step;
|
||||
EscCount=1;
|
||||
/*
|
||||
if (MaxOrder < 2)
|
||||
{
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
OrderFall=ModelPPM::MaxOrder;
|
||||
MinContext=MaxContext;
|
||||
while (MinContext->Suffix != NULL)
|
||||
{
|
||||
MinContext=MinContext->Suffix;
|
||||
OrderFall--;
|
||||
}
|
||||
FoundState=MinContext->U.Stats;
|
||||
MinContext=MaxContext;
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
ModelPPM::MaxOrder=MaxOrder;
|
||||
RestartModelRare();
|
||||
NS2BSIndx[0]=2*0;
|
||||
NS2BSIndx[1]=2*1;
|
||||
memset(NS2BSIndx+2,2*2,9);
|
||||
memset(NS2BSIndx+11,2*3,256-11);
|
||||
for (i=0;i < 3;i++)
|
||||
NS2Indx[i]=i;
|
||||
for (m=i, k=Step=1;i < 256;i++)
|
||||
{
|
||||
NS2Indx[i]=m;
|
||||
if ( !--k )
|
||||
{
|
||||
k = ++Step;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
memset(HB2Flag,0,0x40);
|
||||
memset(HB2Flag+0x40,0x08,0x100-0x40);
|
||||
DummySEE2Cont.Shift=PERIOD_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PPM_CONTEXT::rescale(ModelPPM *Model)
|
||||
{
|
||||
int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
|
||||
STATE* p1, * p;
|
||||
for (p=Model->FoundState;p != U.Stats;p--)
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
U.Stats->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
EscFreq=U.SummFreq-p->Freq;
|
||||
Adder=(Model->OrderFall != 0);
|
||||
U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
|
||||
do
|
||||
{
|
||||
EscFreq -= (++p)->Freq;
|
||||
U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
|
||||
if (p[0].Freq > p[-1].Freq)
|
||||
{
|
||||
STATE tmp=*(p1=p);
|
||||
do
|
||||
{
|
||||
p1[0]=p1[-1];
|
||||
} while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
|
||||
*p1=tmp;
|
||||
}
|
||||
} while ( --i );
|
||||
if (p->Freq == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
i++;
|
||||
} while ((--p)->Freq == 0);
|
||||
EscFreq += i;
|
||||
if ((NumStats -= i) == 1)
|
||||
{
|
||||
STATE tmp=*U.Stats;
|
||||
do
|
||||
{
|
||||
tmp.Freq-=(tmp.Freq >> 1);
|
||||
EscFreq>>=1;
|
||||
} while (EscFreq > 1);
|
||||
Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
|
||||
*(Model->FoundState=&OneState)=tmp; return;
|
||||
}
|
||||
}
|
||||
U.SummFreq += (EscFreq -= (EscFreq >> 1));
|
||||
int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
|
||||
if (n0 != n1)
|
||||
U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
|
||||
Model->FoundState=U.Stats;
|
||||
}
|
||||
|
||||
|
||||
inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
|
||||
{
|
||||
#ifdef __ICL
|
||||
static
|
||||
#endif
|
||||
STATE UpState;
|
||||
PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
|
||||
STATE * p, * ps[MAX_O], ** pps=ps;
|
||||
if ( !Skip )
|
||||
{
|
||||
*pps++ = FoundState;
|
||||
if ( !pc->Suffix )
|
||||
goto NO_LOOP;
|
||||
}
|
||||
if ( p1 )
|
||||
{
|
||||
p=p1;
|
||||
pc=pc->Suffix;
|
||||
goto LOOP_ENTRY;
|
||||
}
|
||||
do
|
||||
{
|
||||
pc=pc->Suffix;
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != FoundState->Symbol);
|
||||
}
|
||||
else
|
||||
p=&(pc->OneState);
|
||||
LOOP_ENTRY:
|
||||
if (p->Successor != UpBranch)
|
||||
{
|
||||
pc=p->Successor;
|
||||
break;
|
||||
}
|
||||
*pps++ = p;
|
||||
} while ( pc->Suffix );
|
||||
NO_LOOP:
|
||||
if (pps == ps)
|
||||
return pc;
|
||||
UpState.Symbol=*(byte*) UpBranch;
|
||||
UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((byte*) pc <= SubAlloc.pText)
|
||||
return(NULL);
|
||||
if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != UpState.Symbol);
|
||||
uint cf=p->Freq-1;
|
||||
uint s0=pc->U.SummFreq-pc->NumStats-cf;
|
||||
UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
|
||||
}
|
||||
else
|
||||
UpState.Freq=pc->OneState.Freq;
|
||||
do
|
||||
{
|
||||
pc = pc->createChild(this,*--pps,UpState);
|
||||
if ( !pc )
|
||||
return NULL;
|
||||
} while (pps != ps);
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
||||
inline void ModelPPM::UpdateModel()
|
||||
{
|
||||
STATE fs = *FoundState, *p = NULL;
|
||||
PPM_CONTEXT *pc, *Successor;
|
||||
uint ns1, ns, cf, sf, s0;
|
||||
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
|
||||
{
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((p=pc->U.Stats)->Symbol != fs.Symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != fs.Symbol);
|
||||
if (p[0].Freq >= p[-1].Freq)
|
||||
{
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
p--;
|
||||
}
|
||||
}
|
||||
if (p->Freq < MAX_FREQ-9)
|
||||
{
|
||||
p->Freq += 2;
|
||||
pc->U.SummFreq += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p=&(pc->OneState);
|
||||
p->Freq += (p->Freq < 32);
|
||||
}
|
||||
}
|
||||
if ( !OrderFall )
|
||||
{
|
||||
MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p);
|
||||
if ( !MinContext )
|
||||
goto RESTART_MODEL;
|
||||
return;
|
||||
}
|
||||
*SubAlloc.pText++ = fs.Symbol;
|
||||
Successor = (PPM_CONTEXT*) SubAlloc.pText;
|
||||
if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
|
||||
goto RESTART_MODEL;
|
||||
if ( fs.Successor )
|
||||
{
|
||||
if ((byte*) fs.Successor <= SubAlloc.pText &&
|
||||
(fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
|
||||
goto RESTART_MODEL;
|
||||
if ( !--OrderFall )
|
||||
{
|
||||
Successor=fs.Successor;
|
||||
SubAlloc.pText -= (MaxContext != MinContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FoundState->Successor=Successor;
|
||||
fs.Successor=MinContext;
|
||||
}
|
||||
s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
|
||||
for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
|
||||
{
|
||||
if ((ns1=pc->NumStats) != 1)
|
||||
{
|
||||
if ((ns1 & 1) == 0)
|
||||
{
|
||||
pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
|
||||
if ( !pc->U.Stats )
|
||||
goto RESTART_MODEL;
|
||||
}
|
||||
pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
|
||||
}
|
||||
else
|
||||
{
|
||||
p=(STATE*) SubAlloc.AllocUnits(1);
|
||||
if ( !p )
|
||||
goto RESTART_MODEL;
|
||||
*p=pc->OneState;
|
||||
pc->U.Stats=p;
|
||||
if (p->Freq < MAX_FREQ/4-1)
|
||||
p->Freq += p->Freq;
|
||||
else
|
||||
p->Freq = MAX_FREQ-4;
|
||||
pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
|
||||
}
|
||||
cf=2*fs.Freq*(pc->U.SummFreq+6);
|
||||
sf=s0+pc->U.SummFreq;
|
||||
if (cf < 6*sf)
|
||||
{
|
||||
cf=1+(cf > sf)+(cf >= 4*sf);
|
||||
pc->U.SummFreq += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
|
||||
pc->U.SummFreq += cf;
|
||||
}
|
||||
p=pc->U.Stats+ns1;
|
||||
p->Successor=Successor;
|
||||
p->Symbol = fs.Symbol;
|
||||
p->Freq = cf;
|
||||
pc->NumStats=++ns1;
|
||||
}
|
||||
MaxContext=MinContext=fs.Successor;
|
||||
return;
|
||||
RESTART_MODEL:
|
||||
RestartModelRare();
|
||||
EscCount=0;
|
||||
}
|
||||
|
||||
|
||||
// Tabulated escapes for exponential symbol distribution
|
||||
static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
|
||||
|
||||
|
||||
|
||||
inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
|
||||
{
|
||||
STATE& rs=OneState;
|
||||
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||
ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
|
||||
Model->NS2BSIndx[Suffix->NumStats-1]+
|
||||
Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
|
||||
((Model->RunLength >> 26) & 0x20)];
|
||||
if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
|
||||
{
|
||||
Model->FoundState=&rs;
|
||||
rs.Freq += (rs.Freq < 128);
|
||||
Model->Coder.SubRange.LowCount=0;
|
||||
Model->Coder.SubRange.HighCount=bs;
|
||||
bs = GET_SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
|
||||
Model->PrevSuccess=1;
|
||||
Model->RunLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Model->Coder.SubRange.LowCount=bs;
|
||||
bs = GET_SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2));
|
||||
Model->Coder.SubRange.HighCount=BIN_SCALE;
|
||||
Model->InitEsc=ExpEscape[bs >> 10];
|
||||
Model->NumMasked=1;
|
||||
Model->CharMask[rs.Symbol]=Model->EscCount;
|
||||
Model->PrevSuccess=0;
|
||||
Model->FoundState=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
|
||||
{
|
||||
(Model->FoundState=p)->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
if (p[0].Freq > p[-1].Freq)
|
||||
{
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
Model->FoundState=--p;
|
||||
if (p->Freq > MAX_FREQ)
|
||||
rescale(Model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
|
||||
{
|
||||
Model->Coder.SubRange.scale=U.SummFreq;
|
||||
STATE* p=U.Stats;
|
||||
int i, HiCnt;
|
||||
int count=Model->Coder.GetCurrentCount();
|
||||
if (count>=(int)Model->Coder.SubRange.scale)
|
||||
return(false);
|
||||
if (count < (HiCnt=p->Freq))
|
||||
{
|
||||
Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
|
||||
Model->RunLength += Model->PrevSuccess;
|
||||
(Model->FoundState=p)->Freq=(HiCnt += 4);
|
||||
U.SummFreq += 4;
|
||||
if (HiCnt > MAX_FREQ)
|
||||
rescale(Model);
|
||||
Model->Coder.SubRange.LowCount=0;
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
if (Model->FoundState==NULL)
|
||||
return(false);
|
||||
Model->PrevSuccess=0;
|
||||
i=NumStats-1;
|
||||
while ((HiCnt += (++p)->Freq) <= count)
|
||||
if (--i == 0)
|
||||
{
|
||||
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||
Model->Coder.SubRange.LowCount=HiCnt;
|
||||
Model->CharMask[p->Symbol]=Model->EscCount;
|
||||
i=(Model->NumMasked=NumStats)-1;
|
||||
Model->FoundState=NULL;
|
||||
do
|
||||
{
|
||||
Model->CharMask[(--p)->Symbol]=Model->EscCount;
|
||||
} while ( --i );
|
||||
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||
return(true);
|
||||
}
|
||||
Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||
update1(Model,p);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
|
||||
{
|
||||
(Model->FoundState=p)->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
if (p->Freq > MAX_FREQ)
|
||||
rescale(Model);
|
||||
Model->EscCount++;
|
||||
Model->RunLength=Model->InitRL;
|
||||
}
|
||||
|
||||
|
||||
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
|
||||
{
|
||||
SEE2_CONTEXT* psee2c;
|
||||
if (NumStats != 256)
|
||||
{
|
||||
psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
|
||||
(Diff < Suffix->NumStats-NumStats)+
|
||||
2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
|
||||
Model->HiBitsFlag;
|
||||
Model->Coder.SubRange.scale=psee2c->getMean();
|
||||
}
|
||||
else
|
||||
{
|
||||
psee2c=&Model->DummySEE2Cont;
|
||||
Model->Coder.SubRange.scale=1;
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
|
||||
{
|
||||
int count, HiCnt, i=NumStats-Model->NumMasked;
|
||||
SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
|
||||
STATE* ps[256], ** pps=ps, * p=U.Stats-1;
|
||||
HiCnt=0;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (Model->CharMask[p->Symbol] == Model->EscCount);
|
||||
HiCnt += p->Freq;
|
||||
*pps++ = p;
|
||||
} while ( --i );
|
||||
Model->Coder.SubRange.scale += HiCnt;
|
||||
count=Model->Coder.GetCurrentCount();
|
||||
if (count>=(int)Model->Coder.SubRange.scale)
|
||||
return(false);
|
||||
p=*(pps=ps);
|
||||
if (count < HiCnt)
|
||||
{
|
||||
HiCnt=0;
|
||||
while ((HiCnt += p->Freq) <= count)
|
||||
p=*++pps;
|
||||
Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||
psee2c->update();
|
||||
update2(Model,p);
|
||||
}
|
||||
else
|
||||
{
|
||||
Model->Coder.SubRange.LowCount=HiCnt;
|
||||
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||
i=NumStats-Model->NumMasked;
|
||||
pps--;
|
||||
do
|
||||
{
|
||||
Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
|
||||
} while ( --i );
|
||||
psee2c->Summ += Model->Coder.SubRange.scale;
|
||||
Model->NumMasked = NumStats;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
inline void ModelPPM::ClearMask()
|
||||
{
|
||||
EscCount=1;
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// reset PPM variables after data error allowing safe resuming
|
||||
// of further data processing
|
||||
void ModelPPM::CleanUp()
|
||||
{
|
||||
SubAlloc.StopSubAllocator();
|
||||
SubAlloc.StartSubAllocator(1);
|
||||
StartModelRare(2);
|
||||
}
|
||||
|
||||
|
||||
bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
|
||||
{
|
||||
int MaxOrder=UnpackRead->GetChar();
|
||||
bool Reset=(MaxOrder & 0x20)!=0;
|
||||
|
||||
int MaxMB;
|
||||
if (Reset)
|
||||
MaxMB=UnpackRead->GetChar();
|
||||
else
|
||||
if (SubAlloc.GetAllocatedMemory()==0)
|
||||
return(false);
|
||||
if (MaxOrder & 0x40)
|
||||
EscChar=UnpackRead->GetChar();
|
||||
Coder.InitDecoder(UnpackRead);
|
||||
if (Reset)
|
||||
{
|
||||
MaxOrder=(MaxOrder & 0x1f)+1;
|
||||
if (MaxOrder>16)
|
||||
MaxOrder=16+(MaxOrder-16)*3;
|
||||
if (MaxOrder==1)
|
||||
{
|
||||
SubAlloc.StopSubAllocator();
|
||||
return(false);
|
||||
}
|
||||
SubAlloc.StartSubAllocator(MaxMB+1);
|
||||
StartModelRare(MaxOrder);
|
||||
}
|
||||
return(MinContext!=NULL);
|
||||
}
|
||||
|
||||
|
||||
int ModelPPM::DecodeChar()
|
||||
{
|
||||
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
if (MinContext->NumStats != 1)
|
||||
{
|
||||
if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
if (!MinContext->decodeSymbol1(this))
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
MinContext->decodeBinSymbol(this);
|
||||
Coder.Decode();
|
||||
while ( !FoundState )
|
||||
{
|
||||
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
do
|
||||
{
|
||||
OrderFall++;
|
||||
MinContext=MinContext->Suffix;
|
||||
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
} while (MinContext->NumStats == NumMasked);
|
||||
if (!MinContext->decodeSymbol2(this))
|
||||
return(-1);
|
||||
Coder.Decode();
|
||||
}
|
||||
int Symbol=FoundState->Symbol;
|
||||
if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
|
||||
MinContext=MaxContext=FoundState->Successor;
|
||||
else
|
||||
{
|
||||
UpdateModel();
|
||||
if (EscCount == 0)
|
||||
ClearMask();
|
||||
}
|
||||
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
return(Symbol);
|
||||
}
|
||||
@ -1,132 +0,0 @@
|
||||
#ifndef _RAR_PPMMODEL_
|
||||
#define _RAR_PPMMODEL_
|
||||
|
||||
#include "coder.hpp"
|
||||
#include "suballoc.hpp"
|
||||
|
||||
const int MAX_O=64; /* maximum allowed model order */
|
||||
|
||||
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
|
||||
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
|
||||
|
||||
#ifndef STRICT_ALIGNMENT_REQUIRED
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
struct SEE2_CONTEXT
|
||||
{ // SEE-contexts for PPM-contexts with masked symbols
|
||||
ushort Summ;
|
||||
byte Shift, Count;
|
||||
void init(int InitVal)
|
||||
{
|
||||
Summ=InitVal << (Shift=PERIOD_BITS-4);
|
||||
Count=4;
|
||||
}
|
||||
uint getMean()
|
||||
{
|
||||
uint RetVal=GET_SHORT16(Summ) >> Shift;
|
||||
Summ -= RetVal;
|
||||
return RetVal+(RetVal == 0);
|
||||
}
|
||||
void update()
|
||||
{
|
||||
if (Shift < PERIOD_BITS && --Count == 0)
|
||||
{
|
||||
Summ += Summ;
|
||||
Count=3 << Shift++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ModelPPM;
|
||||
struct PPM_CONTEXT;
|
||||
|
||||
struct STATE
|
||||
{
|
||||
byte Symbol;
|
||||
byte Freq;
|
||||
PPM_CONTEXT* Successor;
|
||||
};
|
||||
|
||||
struct FreqData
|
||||
{
|
||||
ushort SummFreq;
|
||||
STATE _PACK_ATTR * Stats;
|
||||
};
|
||||
|
||||
struct PPM_CONTEXT
|
||||
{
|
||||
ushort NumStats;
|
||||
union
|
||||
{
|
||||
FreqData U;
|
||||
STATE OneState;
|
||||
};
|
||||
|
||||
PPM_CONTEXT* Suffix;
|
||||
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
|
||||
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
|
||||
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
|
||||
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
|
||||
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
|
||||
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
|
||||
inline void update1(ModelPPM *Model,STATE* p); // CD suffix
|
||||
inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
|
||||
void rescale(ModelPPM *Model);
|
||||
inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
|
||||
inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
|
||||
};
|
||||
|
||||
#ifndef STRICT_ALIGNMENT_REQUIRED
|
||||
#ifdef _AIX
|
||||
#pragma pack(pop)
|
||||
#else
|
||||
#pragma pack()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
|
||||
const uint FIXED_UNIT_SIZE=12;
|
||||
|
||||
/*
|
||||
inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
|
||||
NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
|
||||
inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
|
||||
|
||||
|
||||
class ModelPPM
|
||||
{
|
||||
private:
|
||||
friend struct PPM_CONTEXT;
|
||||
|
||||
SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
|
||||
|
||||
struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
|
||||
STATE* FoundState; // found next state transition
|
||||
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
|
||||
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
byte EscCount, PrevSuccess, HiBitsFlag;
|
||||
ushort BinSumm[128][64]; // binary SEE-contexts
|
||||
|
||||
RangeCoder Coder;
|
||||
SubAllocator SubAlloc;
|
||||
|
||||
void RestartModelRare();
|
||||
void StartModelRare(int MaxOrder);
|
||||
inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
|
||||
|
||||
inline void UpdateModel();
|
||||
inline void ClearMask();
|
||||
public:
|
||||
ModelPPM();
|
||||
void CleanUp(); // reset PPM variables after data error
|
||||
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
|
||||
int DecodeChar();
|
||||
};
|
||||
|
||||
#endif
|
||||
2390
src/unrar/msc.dep
2390
src/unrar/msc.dep
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
RAROptions::RAROptions()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
RAROptions::~RAROptions()
|
||||
{
|
||||
// It is important for security reasons, so we do not have the unnecessary
|
||||
// password data left in memory.
|
||||
memset(this,0,sizeof(RAROptions));
|
||||
}
|
||||
|
||||
|
||||
void RAROptions::Init()
|
||||
{
|
||||
memset(this,0,sizeof(RAROptions));
|
||||
WinSize=0x400000;
|
||||
Overwrite=OVERWRITE_DEFAULT;
|
||||
Method=3;
|
||||
MsgStream=MSG_STDOUT;
|
||||
ConvertNames=NAMES_ORIGINALCASE;
|
||||
ProcessEA=true;
|
||||
xmtime=EXTTIME_HIGH3;
|
||||
CurVolNum=0;
|
||||
FileSizeLess=INT64NDF;
|
||||
FileSizeMore=INT64NDF;
|
||||
}
|
||||
@ -1,175 +0,0 @@
|
||||
#ifndef _RAR_OPTIONS_
|
||||
#define _RAR_OPTIONS_
|
||||
|
||||
#define DEFAULT_RECOVERY -1
|
||||
|
||||
#define DEFAULT_RECVOLUMES -10
|
||||
|
||||
#define VOLSIZE_AUTO INT64NDF // Automatically detect the volume size.
|
||||
|
||||
enum PATH_EXCL_MODE {
|
||||
EXCL_UNCHANGED=0, // Process paths as is (default).
|
||||
EXCL_SKIPWHOLEPATH, // -ep (exclude the path completely)
|
||||
EXCL_BASEPATH, // -ep1 (exclude the base part of path)
|
||||
EXCL_SAVEFULLPATH, // -ep2 (the full path without the disk letter)
|
||||
EXCL_ABSPATH, // -ep3 (the full path with the disk letter)
|
||||
|
||||
EXCL_SKIPABSPATH // Works as EXCL_BASEPATH for fully qualified paths
|
||||
// and as EXCL_UNCHANGED for relative paths.
|
||||
// Used by WinRAR GUI only.
|
||||
};
|
||||
|
||||
enum {SOLID_NONE=0,SOLID_NORMAL=1,SOLID_COUNT=2,SOLID_FILEEXT=4,
|
||||
SOLID_VOLUME_DEPENDENT=8,SOLID_VOLUME_INDEPENDENT=16};
|
||||
|
||||
enum {ARCTIME_NONE=0,ARCTIME_KEEP,ARCTIME_LATEST};
|
||||
|
||||
enum EXTTIME_MODE {
|
||||
EXTTIME_NONE=0,EXTTIME_1S,EXTTIME_HIGH1,EXTTIME_HIGH2,EXTTIME_HIGH3
|
||||
};
|
||||
|
||||
enum {NAMES_ORIGINALCASE=0,NAMES_UPPERCASE,NAMES_LOWERCASE};
|
||||
|
||||
enum MESSAGE_TYPE {MSG_STDOUT=0,MSG_STDERR,MSG_ERRONLY,MSG_NULL};
|
||||
|
||||
enum RECURSE_MODE
|
||||
{
|
||||
RECURSE_NONE=0, // no recurse switches
|
||||
RECURSE_DISABLE, // switch -r-
|
||||
RECURSE_ALWAYS, // switch -r
|
||||
RECURSE_WILDCARDS, // switch -r0
|
||||
};
|
||||
|
||||
enum OVERWRITE_MODE
|
||||
{
|
||||
OVERWRITE_DEFAULT=0, // ask for extraction, silently overwrite for archiving
|
||||
OVERWRITE_ALL,
|
||||
OVERWRITE_NONE,
|
||||
OVERWRITE_AUTORENAME,
|
||||
OVERWRITE_FORCE_ASK
|
||||
};
|
||||
|
||||
enum RAR_CHARSET { RCH_DEFAULT=0,RCH_ANSI,RCH_OEM,RCH_UNICODE };
|
||||
|
||||
#define MAX_FILTER_TYPES 16
|
||||
enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE};
|
||||
|
||||
|
||||
struct FilterMode
|
||||
{
|
||||
FilterState State;
|
||||
int Param1;
|
||||
int Param2;
|
||||
};
|
||||
|
||||
#define MAX_GENERATE_MASK 128
|
||||
|
||||
|
||||
class RAROptions
|
||||
{
|
||||
public:
|
||||
RAROptions();
|
||||
~RAROptions();
|
||||
void Init();
|
||||
|
||||
uint ExclFileAttr;
|
||||
uint InclFileAttr;
|
||||
bool InclAttrSet;
|
||||
uint WinSize;
|
||||
char TempPath[NM];
|
||||
bool ConfigDisabled; // Switch -cfg-.
|
||||
char ExtrPath[NM];
|
||||
wchar ExtrPathW[NM];
|
||||
char CommentFile[NM];
|
||||
wchar CommentFileW[NM];
|
||||
RAR_CHARSET CommentCharset;
|
||||
RAR_CHARSET FilelistCharset;
|
||||
char ArcPath[NM];
|
||||
wchar ArcPathW[NM];
|
||||
SecPassword Password;
|
||||
bool EncryptHeaders;
|
||||
char LogName[NM];
|
||||
MESSAGE_TYPE MsgStream;
|
||||
bool Sound;
|
||||
OVERWRITE_MODE Overwrite;
|
||||
int Method;
|
||||
int Recovery;
|
||||
int RecVolNumber;
|
||||
bool DisablePercentage;
|
||||
bool DisableCopyright;
|
||||
bool DisableDone;
|
||||
int Solid;
|
||||
int SolidCount;
|
||||
bool ClearArc;
|
||||
bool AddArcOnly;
|
||||
bool AV;
|
||||
bool DisableComment;
|
||||
bool FreshFiles;
|
||||
bool UpdateFiles;
|
||||
PATH_EXCL_MODE ExclPath;
|
||||
RECURSE_MODE Recurse;
|
||||
int64 VolSize;
|
||||
Array<int64> NextVolSizes;
|
||||
uint CurVolNum;
|
||||
bool AllYes;
|
||||
bool DisableViewAV;
|
||||
bool DisableSortSolid;
|
||||
int ArcTime;
|
||||
int ConvertNames;
|
||||
bool ProcessOwners;
|
||||
bool SaveLinks;
|
||||
int Priority;
|
||||
int SleepTime;
|
||||
bool KeepBroken;
|
||||
bool OpenShared;
|
||||
bool DeleteFiles;
|
||||
#ifndef SFX_MODULE
|
||||
bool GenerateArcName;
|
||||
char GenerateMask[MAX_GENERATE_MASK];
|
||||
#endif
|
||||
bool SyncFiles;
|
||||
bool ProcessEA;
|
||||
bool SaveStreams;
|
||||
bool SetCompressedAttr;
|
||||
bool IgnoreGeneralAttr;
|
||||
RarTime FileTimeBefore;
|
||||
RarTime FileTimeAfter;
|
||||
int64 FileSizeLess;
|
||||
int64 FileSizeMore;
|
||||
bool OldNumbering;
|
||||
bool Lock;
|
||||
bool Test;
|
||||
bool VolumePause;
|
||||
FilterMode FilterModes[MAX_FILTER_TYPES];
|
||||
char EmailTo[NM];
|
||||
uint VersionControl;
|
||||
bool NoEndBlock;
|
||||
bool AppendArcNameToPath;
|
||||
bool Shutdown;
|
||||
EXTTIME_MODE xmtime;
|
||||
EXTTIME_MODE xctime;
|
||||
EXTTIME_MODE xatime;
|
||||
EXTTIME_MODE xarctime;
|
||||
char CompressStdin[NM];
|
||||
|
||||
#ifdef RAR_SMP
|
||||
uint Threads;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef RARDLL
|
||||
char DllDestName[NM];
|
||||
wchar DllDestNameW[NM];
|
||||
int DllOpMode;
|
||||
int DllError;
|
||||
LPARAM UserData;
|
||||
UNRARCALLBACK Callback;
|
||||
CHANGEVOLPROC ChangeVolProc;
|
||||
PROCESSDATAPROC ProcessDataProc;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
254
src/unrar/os.hpp
254
src/unrar/os.hpp
@ -1,254 +0,0 @@
|
||||
#ifndef _RAR_OS_
|
||||
#define _RAR_OS_
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#ifdef __EMX__
|
||||
#define INCL_BASE
|
||||
#endif
|
||||
|
||||
#if defined(RARDLL) && !defined(SILENT)
|
||||
#define SILENT
|
||||
#endif
|
||||
|
||||
#define ENABLE_BAD_ALLOC // Undefine if std::bad_alloc is not supported.
|
||||
|
||||
#ifdef ENABLE_BAD_ALLOC
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN_ALL) || defined(_EMX)
|
||||
|
||||
#define LITTLE_ENDIAN
|
||||
#define NM 1024
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
|
||||
#define STRICT
|
||||
#define UNICODE
|
||||
#undef WINVER
|
||||
#undef _WIN32_WINNT
|
||||
#define WINVER 0x0501
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <prsht.h>
|
||||
#include <shlwapi.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
|
||||
|
||||
#endif // _WIN_ALL
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dos.h>
|
||||
|
||||
#if !defined(_EMX) && !defined(_MSC_VER)
|
||||
#include <dir.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER<1500
|
||||
#define for if (0) ; else for
|
||||
#endif
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
#ifdef _EMX
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
#ifdef _DJGPP
|
||||
#include <utime.h>
|
||||
#else
|
||||
#include <os2.h>
|
||||
#include <sys/utime.h>
|
||||
#include <emx/syscalls.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define ENABLE_ACCESS
|
||||
|
||||
#define DefConfigName "rar.ini"
|
||||
#define DefLogName "rar.log"
|
||||
|
||||
|
||||
#define PATHDIVIDER "\\"
|
||||
#define PATHDIVIDERW L"\\"
|
||||
#define CPATHDIVIDER '\\'
|
||||
#define MASKALL "*"
|
||||
#define MASKALLW L"*"
|
||||
|
||||
#define READBINARY "rb"
|
||||
#define READTEXT "rt"
|
||||
#define UPDATEBINARY "r+b"
|
||||
#define CREATEBINARY "w+b"
|
||||
#define WRITEBINARY "wb"
|
||||
#define APPENDTEXT "at"
|
||||
|
||||
#if defined(_WIN_ALL)
|
||||
#ifdef _MSC_VER
|
||||
#define _stdfunction __cdecl
|
||||
|
||||
#ifdef SFX_MODULE
|
||||
// We want to keep SFX module small, so let compiler to decide.
|
||||
#define _forceinline inline
|
||||
#else
|
||||
#define _forceinline __forceinline
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define _stdfunction _USERENTRY
|
||||
#define _forceinline inline
|
||||
#endif
|
||||
#else
|
||||
#define _stdfunction
|
||||
#define _forceinline inline
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _UNIX
|
||||
|
||||
#define NM 1024
|
||||
|
||||
#ifdef _BEOS
|
||||
#include <be/kernel/fs_info.h>
|
||||
#include <be/kernel/fs_attr.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#if defined(__QNXNTO__)
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if defined(RAR_SMP) && defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined(__APPLE__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#else
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <utime.h>
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef S_IFLNK
|
||||
#define SAVE_LINKS
|
||||
#endif
|
||||
|
||||
#define ENABLE_ACCESS
|
||||
|
||||
#define DefConfigName ".rarrc"
|
||||
#define DefLogName ".rarlog"
|
||||
|
||||
|
||||
#define PATHDIVIDER "/"
|
||||
#define PATHDIVIDERW L"/"
|
||||
#define CPATHDIVIDER '/'
|
||||
#define MASKALL "*"
|
||||
#define MASKALLW L"*"
|
||||
|
||||
#define READBINARY "r"
|
||||
#define READTEXT "r"
|
||||
#define UPDATEBINARY "r+"
|
||||
#define CREATEBINARY "w+"
|
||||
#define WRITEBINARY "w"
|
||||
#define APPENDTEXT "a"
|
||||
|
||||
#define _stdfunction
|
||||
#define _forceinline inline
|
||||
|
||||
#ifdef _APPLE
|
||||
#if defined(__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
|
||||
#define BIG_ENDIAN
|
||||
#undef LITTLE_ENDIAN
|
||||
#endif
|
||||
#if defined(__i386__) && !defined(LITTLE_ENDIAN)
|
||||
#define LITTLE_ENDIAN
|
||||
#undef BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__sparc) || defined(sparc) || defined(__hpux)
|
||||
#ifndef BIG_ENDIAN
|
||||
#define BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef const char* MSGID;
|
||||
|
||||
#define safebuf static
|
||||
|
||||
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||
#if defined(__i386) || defined(i386) || defined(__i386__)
|
||||
#define LITTLE_ENDIAN
|
||||
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN
|
||||
#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
|
||||
#define BIG_ENDIAN
|
||||
#else
|
||||
#error "Neither LITTLE_ENDIAN nor BIG_ENDIAN are defined. Define one of them."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
|
||||
#undef LITTLE_ENDIAN
|
||||
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
#undef BIG_ENDIAN
|
||||
#else
|
||||
#error "Both LITTLE_ENDIAN and BIG_ENDIAN are defined. Undef one of them."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BIG_ENDIAN) && !defined(_WIN_CE) && defined(_WIN_ALL)
|
||||
// Allow not aligned integer access, increases speed in some operations.
|
||||
#define ALLOW_NOT_ALIGNED_INT
|
||||
#endif
|
||||
|
||||
#if defined(__sparc) || defined(sparc) || defined(__sparcv9)
|
||||
// Prohibit not aligned access to data structures in text compression
|
||||
// algorithm, increases memory requirements
|
||||
#define STRICT_ALIGNMENT_REQUIRED
|
||||
#endif
|
||||
|
||||
#endif // _RAR_OS_
|
||||
@ -1,94 +0,0 @@
|
||||
#include <os2.h>
|
||||
|
||||
|
||||
|
||||
void ExtractOS2EA(Archive &Arc,char *FileName)
|
||||
{
|
||||
if (_osmode != OS2_MODE)
|
||||
{
|
||||
mprintf(St(MSkipEA));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
|
||||
{
|
||||
Log(Arc.FileName,St(MEAUnknHeader),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
struct StructEAOP2
|
||||
{
|
||||
char *GEAPtr;
|
||||
char *FEAPtr;
|
||||
unsigned long Error;
|
||||
} EAOP2;
|
||||
|
||||
ComprDataIO DataIO;
|
||||
Unpack Unpack(&DataIO);
|
||||
Unpack.Init();
|
||||
|
||||
Array<unsigned char> UnpData(Arc.EAHead.UnpSize);
|
||||
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
|
||||
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetFiles(&Arc,NULL);
|
||||
Unpack.SetDestSize(Arc.EAHead.UnpSize);
|
||||
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
|
||||
|
||||
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
|
||||
EAOP2.FEAPtr=(char *)&UnpData[0];
|
||||
EAOP2.GEAPtr=NULL;
|
||||
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
}
|
||||
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
|
||||
void ExtractOS2EANew(Archive &Arc,char *FileName)
|
||||
{
|
||||
if (_osmode != OS2_MODE)
|
||||
{
|
||||
mprintf(St(MSkipEA));
|
||||
return;
|
||||
}
|
||||
|
||||
Array<byte> SubData;
|
||||
if (!Arc.ReadSubData(&SubData,NULL))
|
||||
return;
|
||||
|
||||
struct StructEAOP2
|
||||
{
|
||||
char *GEAPtr;
|
||||
char *FEAPtr;
|
||||
unsigned long Error;
|
||||
} EAOP2;
|
||||
|
||||
EAOP2.FEAPtr=(char *)&SubData[0];
|
||||
EAOP2.GEAPtr=NULL;
|
||||
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
}
|
||||
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
1457
src/unrar/pathfn.cpp
1457
src/unrar/pathfn.cpp
File diff suppressed because it is too large
Load Diff
@ -1,66 +0,0 @@
|
||||
#ifndef _RAR_PATHFN_
|
||||
#define _RAR_PATHFN_
|
||||
|
||||
char* PointToName(const char *Path);
|
||||
wchar* PointToName(const wchar *Path);
|
||||
char* PointToLastChar(const char *Path);
|
||||
wchar* PointToLastChar(const wchar *Path);
|
||||
char* ConvertPath(const char *SrcPath,char *DestPath);
|
||||
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath);
|
||||
void SetExt(char *Name,const char *NewExt);
|
||||
void SetExt(wchar *Name,const wchar *NewExt);
|
||||
void SetSFXExt(char *SFXName);
|
||||
void SetSFXExt(wchar *SFXName);
|
||||
char *GetExt(const char *Name);
|
||||
wchar *GetExt(const wchar *Name);
|
||||
bool CmpExt(const char *Name,const char *Ext);
|
||||
bool CmpExt(const wchar *Name,const wchar *Ext);
|
||||
bool IsWildcard(const char *Str,const wchar *StrW=NULL);
|
||||
bool IsPathDiv(int Ch);
|
||||
bool IsDriveDiv(int Ch);
|
||||
int GetPathDisk(const char *Path);
|
||||
int GetPathDisk(const wchar *Path);
|
||||
void AddEndSlash(char *Path);
|
||||
void AddEndSlash(wchar *Path);
|
||||
void GetFilePath(const char *FullName,char *Path,int MaxLength);
|
||||
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength);
|
||||
void RemoveNameFromPath(char *Path);
|
||||
void RemoveNameFromPath(wchar *Path);
|
||||
void GetAppDataPath(char *Path);
|
||||
void GetAppDataPath(wchar *Path);
|
||||
void GetRarDataPath(char *Path);
|
||||
void GetRarDataPath(wchar *Path);
|
||||
bool EnumConfigPaths(wchar *Path,int Number);
|
||||
bool EnumConfigPaths(char *Path,int Number);
|
||||
void GetConfigName(const char *Name,char *FullName,bool CheckExist);
|
||||
void GetConfigName(const wchar *Name,wchar *FullName,bool CheckExist);
|
||||
char* GetVolNumPart(char *ArcName);
|
||||
wchar* GetVolNumPart(wchar *ArcName);
|
||||
void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering);
|
||||
bool IsNameUsable(const char *Name);
|
||||
bool IsNameUsable(const wchar *Name);
|
||||
void MakeNameUsable(char *Name,bool Extended);
|
||||
void MakeNameUsable(wchar *Name,bool Extended);
|
||||
char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
|
||||
char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
|
||||
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName=NULL,uint MaxLength=NM);
|
||||
wchar* DosSlashToUnix(wchar *SrcName,wchar *DestName=NULL,uint MaxLength=NM);
|
||||
void ConvertNameToFull(const char *Src,char *Dest);
|
||||
void ConvertNameToFull(const wchar *Src,wchar *Dest);
|
||||
bool IsFullPath(const char *Path);
|
||||
bool IsFullPath(const wchar *Path);
|
||||
bool IsDiskLetter(const char *Path);
|
||||
bool IsDiskLetter(const wchar *Path);
|
||||
void GetPathRoot(const char *Path,char *Root);
|
||||
void GetPathRoot(const wchar *Path,wchar *Root);
|
||||
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate);
|
||||
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering);
|
||||
wchar* VolNameToFirstName(const wchar *VolName,wchar *FirstName,bool NewNumbering);
|
||||
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW,size_t DestSize);
|
||||
char* GetAsciiName(const wchar *NameW,char *Name,size_t DestSize);
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void GenerateArchiveName(char *ArcName,wchar *ArcNameW,size_t MaxSize,char *GenerateMask,bool Archiving);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,144 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#if !defined(GUI) && !defined(RARDLL)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
#ifdef _UNIX
|
||||
setlocale(LC_ALL,"");
|
||||
#endif
|
||||
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
uni_init(0);
|
||||
#endif
|
||||
|
||||
#if !defined(_SFX_RTL_) && !defined(_WIN_ALL)
|
||||
setbuf(stdout,NULL);
|
||||
#endif
|
||||
|
||||
#if !defined(SFX_MODULE) && defined(_EMX)
|
||||
EnumConfigPaths(argv[0],-1);
|
||||
#endif
|
||||
|
||||
ErrHandler.SetSignalHandlers(true);
|
||||
|
||||
RARInitData();
|
||||
|
||||
#ifdef SFX_MODULE
|
||||
char ModuleNameA[NM];
|
||||
wchar ModuleNameW[NM];
|
||||
#ifdef _WIN_ALL
|
||||
GetModuleFileNameW(NULL,ModuleNameW,ASIZE(ModuleNameW));
|
||||
WideToChar(ModuleNameW,ModuleNameA);
|
||||
#else
|
||||
strcpy(ModuleNameA,argv[0]);
|
||||
*ModuleNameW=0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
// Must be initialized, normal initialization can be skipped in case of
|
||||
// exception.
|
||||
bool ShutdownOnClose=false;
|
||||
#endif
|
||||
|
||||
#ifdef ALLOW_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
|
||||
CommandData Cmd;
|
||||
#ifdef SFX_MODULE
|
||||
strcpy(Cmd.Command,"X");
|
||||
char *Switch=NULL;
|
||||
#ifdef _SFX_RTL_
|
||||
char *CmdLine=GetCommandLineA();
|
||||
if (CmdLine!=NULL && *CmdLine=='\"')
|
||||
CmdLine=strchr(CmdLine+1,'\"');
|
||||
if (CmdLine!=NULL && (CmdLine=strpbrk(CmdLine," /"))!=NULL)
|
||||
{
|
||||
while (IsSpace(*CmdLine))
|
||||
CmdLine++;
|
||||
Switch=CmdLine;
|
||||
}
|
||||
#else
|
||||
Switch=argc>1 ? argv[1]:NULL;
|
||||
#endif
|
||||
if (Switch!=NULL && Cmd.IsSwitch(Switch[0]))
|
||||
{
|
||||
int UpperCmd=etoupper(Switch[1]);
|
||||
switch(UpperCmd)
|
||||
{
|
||||
case 'T':
|
||||
case 'V':
|
||||
Cmd.Command[0]=UpperCmd;
|
||||
break;
|
||||
case '?':
|
||||
Cmd.OutHelp(RARX_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Cmd.AddArcName(ModuleNameA,ModuleNameW);
|
||||
Cmd.ParseDone();
|
||||
#else // !SFX_MODULE
|
||||
Cmd.PreprocessCommandLine(argc,argv);
|
||||
if (!Cmd.ConfigDisabled)
|
||||
{
|
||||
Cmd.ReadConfig();
|
||||
Cmd.ParseEnvVar();
|
||||
}
|
||||
Cmd.ParseCommandLine(argc,argv);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
ShutdownOnClose=Cmd.Shutdown;
|
||||
#endif
|
||||
|
||||
InitConsoleOptions(Cmd.MsgStream,Cmd.Sound);
|
||||
InitLogOptions(Cmd.LogName);
|
||||
ErrHandler.SetSilent(Cmd.AllYes || Cmd.MsgStream==MSG_NULL);
|
||||
ErrHandler.SetShutdown(Cmd.Shutdown);
|
||||
|
||||
Cmd.OutTitle();
|
||||
Cmd.ProcessCommand();
|
||||
}
|
||||
#ifdef ALLOW_EXCEPTIONS
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
ErrHandler.SetErrorCode(ErrCode);
|
||||
}
|
||||
#ifdef ENABLE_BAD_ALLOC
|
||||
catch (std::bad_alloc)
|
||||
{
|
||||
ErrHandler.MemoryErrorMsg();
|
||||
ErrHandler.SetErrorCode(RARX_MEMORY);
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
ErrHandler.SetErrorCode(RARX_FATAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
File::RemoveCreated();
|
||||
#if defined(SFX_MODULE) && defined(_DJGPP)
|
||||
_chmod(ModuleNameA,1,0x20);
|
||||
#endif
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
uni_done();
|
||||
#endif
|
||||
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
if (ShutdownOnClose)
|
||||
Shutdown();
|
||||
#endif
|
||||
return(ErrHandler.GetErrorCode());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
#ifndef _RAR_RARCOMMON_
|
||||
#define _RAR_RARCOMMON_
|
||||
|
||||
#include "raros.hpp"
|
||||
#include "os.hpp"
|
||||
|
||||
#ifdef RARDLL
|
||||
#include "dll.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WIN_CE
|
||||
#include "version.hpp"
|
||||
#endif
|
||||
#include "rartypes.hpp"
|
||||
#include "rardefs.hpp"
|
||||
#include "rarlang.hpp"
|
||||
#include "unicode.hpp"
|
||||
#include "errhnd.hpp"
|
||||
#include "array.hpp"
|
||||
#include "timefn.hpp"
|
||||
#include "secpassword.hpp"
|
||||
#include "options.hpp"
|
||||
#include "headers.hpp"
|
||||
#include "pathfn.hpp"
|
||||
#include "strfn.hpp"
|
||||
#include "strlist.hpp"
|
||||
#include "file.hpp"
|
||||
#include "sha1.hpp"
|
||||
#include "crc.hpp"
|
||||
#include "rijndael.hpp"
|
||||
#include "crypt.hpp"
|
||||
#include "filefn.hpp"
|
||||
#include "filestr.hpp"
|
||||
#include "find.hpp"
|
||||
#include "scantree.hpp"
|
||||
#include "savepos.hpp"
|
||||
#include "getbits.hpp"
|
||||
#include "rdwrfn.hpp"
|
||||
#include "archive.hpp"
|
||||
#include "match.hpp"
|
||||
#include "cmddata.hpp"
|
||||
#include "filcreat.hpp"
|
||||
#include "consio.hpp"
|
||||
#include "system.hpp"
|
||||
#ifdef _WIN_ALL
|
||||
#include "isnt.hpp"
|
||||
#endif
|
||||
#include "log.hpp"
|
||||
#include "rawread.hpp"
|
||||
#include "encname.hpp"
|
||||
#include "resource.hpp"
|
||||
#include "compress.hpp"
|
||||
|
||||
#include "rarvm.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
#include "unpack.hpp"
|
||||
|
||||
|
||||
|
||||
#include "extinfo.hpp"
|
||||
#include "extract.hpp"
|
||||
|
||||
|
||||
|
||||
#include "list.hpp"
|
||||
|
||||
|
||||
#include "rs.hpp"
|
||||
#include "recvol.hpp"
|
||||
#include "volume.hpp"
|
||||
#include "smallfn.hpp"
|
||||
#include "ulinks.hpp"
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,28 +0,0 @@
|
||||
#ifndef _RAR_DEFS_
|
||||
#define _RAR_DEFS_
|
||||
|
||||
#define Min(x,y) (((x)<(y)) ? (x):(y))
|
||||
#define Max(x,y) (((x)>(y)) ? (x):(y))
|
||||
|
||||
#define ASIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
// MAXPASSWORD is expected to be multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE (16)
|
||||
// for CryptProtectMemory in SecPassword.
|
||||
#define MAXPASSWORD 128
|
||||
|
||||
#define MAXSFXSIZE 0x100000
|
||||
|
||||
#define DefSFXName "default.sfx"
|
||||
#define DefSortListName "rarfiles.lst"
|
||||
|
||||
#ifndef FA_RDONLY
|
||||
#define FA_RDONLY 0x01
|
||||
#define FA_HIDDEN 0x02
|
||||
#define FA_SYSTEM 0x04
|
||||
#define FA_LABEL 0x08
|
||||
#define FA_DIREC 0x10
|
||||
#define FA_ARCH 0x20
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,10 +0,0 @@
|
||||
#ifndef _RAR_LANG_
|
||||
#define _RAR_LANG_
|
||||
|
||||
#ifdef USE_RC
|
||||
#include "rarres.hpp"
|
||||
#else
|
||||
#include "loclang.hpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,46 +0,0 @@
|
||||
#ifndef _RAR_RAROS_
|
||||
#define _RAR_RAROS_
|
||||
|
||||
#ifdef __EMX__
|
||||
#define _EMX
|
||||
#endif
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#define _DJGPP
|
||||
#define _EMX
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
#define _WIN_ALL // Defined for all Windows platforms, 32 and 64 bit, mobile and desktop.
|
||||
#ifdef _M_X64
|
||||
#define _WIN_64
|
||||
#else
|
||||
#define _WIN_32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define _WIN_ALL
|
||||
#define _WIN_CE
|
||||
#ifdef WM_FILECHANGEINFO
|
||||
#define PC2002
|
||||
#else
|
||||
#undef PC2002
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
#define _UNIX
|
||||
#define _BEOS
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _UNIX
|
||||
#define _APPLE
|
||||
#endif
|
||||
|
||||
#if !defined(_EMX) && !defined(_WIN_ALL) && !defined(_BEOS) && !defined(_APPLE)
|
||||
#define _UNIX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,2 +0,0 @@
|
||||
// We use rarpch.cpp to create precompiled headers for MS Visual C++.
|
||||
#include "rar.hpp"
|
||||
@ -1,47 +0,0 @@
|
||||
#ifndef _RAR_TYPES_
|
||||
#define _RAR_TYPES_
|
||||
|
||||
typedef unsigned char byte; // unsigned 8 bits
|
||||
typedef unsigned short ushort; // preferably 16 bits, but can be more
|
||||
typedef unsigned int uint; // 32 bits or more
|
||||
|
||||
#define PRESENT_INT32 // undefine if signed 32 bits is not available
|
||||
|
||||
typedef unsigned int uint32; // 32 bits exactly
|
||||
typedef signed int int32; // signed 32 bits exactly
|
||||
|
||||
// If compiler does not support 64 bit variables, we can define
|
||||
// uint64 and int64 as 32 bit, but it will limit the maximum processed
|
||||
// file size to 2 GB.
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
typedef unsigned __int64 uint64; // unsigned 64 bits
|
||||
typedef signed __int64 int64; // signed 64 bits
|
||||
#else
|
||||
typedef unsigned long long uint64; // unsigned 64 bits
|
||||
typedef signed long long int64; // signed 64 bits
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN_ALL) || defined(__GNUC__) || defined(__sgi) || defined(_AIX) || defined(__sun) || defined(__hpux) || defined(_OSF_SOURCE)
|
||||
typedef wchar_t wchar;
|
||||
#else
|
||||
typedef ushort wchar;
|
||||
#endif
|
||||
|
||||
// Get lowest 16 bits.
|
||||
#define GET_SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff))
|
||||
|
||||
// Get lowest 32 bits.
|
||||
#define GET_UINT32(x) (sizeof(uint32)==4 ? (uint32)(x):((x)&0xffffffff))
|
||||
|
||||
// Make 64 bit integer from two 32 bit.
|
||||
#define INT32TO64(high,low) ((((uint64)(high))<<32)+((uint64)low))
|
||||
|
||||
// Special int64 value, large enough to never be found in real life.
|
||||
// We use it in situations, when we need to indicate that parameter
|
||||
// is not defined and probably should be calculated inside of function.
|
||||
// Lower part is intentionally 0x7fffffff, not 0xffffffff, to make it
|
||||
// compatible with 32 bit int64.
|
||||
#define INT64NDF INT32TO64(0x7fffffff,0x7fffffff)
|
||||
|
||||
#endif
|
||||
1139
src/unrar/rarvm.cpp
1139
src/unrar/rarvm.cpp
File diff suppressed because it is too large
Load Diff
@ -1,113 +0,0 @@
|
||||
#ifndef _RAR_VM_
|
||||
#define _RAR_VM_
|
||||
|
||||
#define VM_STANDARDFILTERS
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
#define VM_OPTIMIZE
|
||||
#endif
|
||||
|
||||
|
||||
#define VM_MEMSIZE 0x40000
|
||||
#define VM_MEMMASK (VM_MEMSIZE-1)
|
||||
#define VM_GLOBALMEMADDR 0x3C000
|
||||
#define VM_GLOBALMEMSIZE 0x2000
|
||||
#define VM_FIXEDGLOBALSIZE 64
|
||||
|
||||
enum VM_Commands
|
||||
{
|
||||
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
|
||||
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
|
||||
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
|
||||
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
|
||||
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
|
||||
|
||||
#ifdef VM_OPTIMIZE
|
||||
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
|
||||
|
||||
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
|
||||
VM_NEGB, VM_NEGD,
|
||||
#endif
|
||||
|
||||
VM_STANDARD
|
||||
};
|
||||
|
||||
enum VM_StandardFilters {
|
||||
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
|
||||
VMSF_DELTA, VMSF_UPCASE
|
||||
};
|
||||
|
||||
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
|
||||
|
||||
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
|
||||
|
||||
struct VM_PreparedOperand
|
||||
{
|
||||
VM_OpType Type;
|
||||
uint Data;
|
||||
uint Base;
|
||||
uint *Addr;
|
||||
};
|
||||
|
||||
struct VM_PreparedCommand
|
||||
{
|
||||
VM_Commands OpCode;
|
||||
bool ByteMode;
|
||||
VM_PreparedOperand Op1,Op2;
|
||||
};
|
||||
|
||||
|
||||
struct VM_PreparedProgram
|
||||
{
|
||||
VM_PreparedProgram()
|
||||
{
|
||||
AltCmd=NULL;
|
||||
FilteredDataSize=0;
|
||||
CmdCount=0;
|
||||
}
|
||||
|
||||
Array<VM_PreparedCommand> Cmd;
|
||||
VM_PreparedCommand *AltCmd;
|
||||
int CmdCount;
|
||||
|
||||
Array<byte> GlobalData;
|
||||
Array<byte> StaticData; // static data contained in DB operators
|
||||
uint InitR[7];
|
||||
|
||||
byte *FilteredData;
|
||||
uint FilteredDataSize;
|
||||
};
|
||||
|
||||
class RarVM:private BitInput
|
||||
{
|
||||
private:
|
||||
inline uint GetValue(bool ByteMode,uint *Addr);
|
||||
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
|
||||
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
|
||||
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
|
||||
#ifdef VM_OPTIMIZE
|
||||
void Optimize(VM_PreparedProgram *Prg);
|
||||
#endif
|
||||
bool ExecuteCode(VM_PreparedCommand *PreparedCode,uint CodeSize);
|
||||
#ifdef VM_STANDARDFILTERS
|
||||
VM_StandardFilters IsStandardFilter(byte *Code,uint CodeSize);
|
||||
void ExecuteStandardFilter(VM_StandardFilters FilterType);
|
||||
uint FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
|
||||
void FilterItanium_SetBits(byte *Data,uint BitField,int BitPos,int BitCount);
|
||||
#endif
|
||||
|
||||
byte *Mem;
|
||||
uint R[8];
|
||||
uint Flags;
|
||||
public:
|
||||
RarVM();
|
||||
~RarVM();
|
||||
void Init();
|
||||
void Prepare(byte *Code,uint CodeSize,VM_PreparedProgram *Prg);
|
||||
void Execute(VM_PreparedProgram *Prg);
|
||||
void SetLowEndianValue(uint *Addr,uint Value);
|
||||
void SetMemory(uint Pos,byte *Data,uint DataSize);
|
||||
static uint ReadData(BitInput &Inp);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,53 +0,0 @@
|
||||
#define VMCF_OP0 0
|
||||
#define VMCF_OP1 1
|
||||
#define VMCF_OP2 2
|
||||
#define VMCF_OPMASK 3
|
||||
#define VMCF_BYTEMODE 4
|
||||
#define VMCF_JUMP 8
|
||||
#define VMCF_PROC 16
|
||||
#define VMCF_USEFLAGS 32
|
||||
#define VMCF_CHFLAGS 64
|
||||
|
||||
static byte VM_CmdFlags[]=
|
||||
{
|
||||
/* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JMP */ VMCF_OP1 | VMCF_JUMP ,
|
||||
/* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||
/* VM_PUSH */ VMCF_OP1 ,
|
||||
/* VM_POP */ VMCF_OP1 ,
|
||||
/* VM_CALL */ VMCF_OP1 | VMCF_PROC ,
|
||||
/* VM_RET */ VMCF_OP0 | VMCF_PROC ,
|
||||
/* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE ,
|
||||
/* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||
/* VM_PUSHA */ VMCF_OP0 ,
|
||||
/* VM_POPA */ VMCF_OP0 ,
|
||||
/* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS ,
|
||||
/* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS ,
|
||||
/* VM_MOVZX */ VMCF_OP2 ,
|
||||
/* VM_MOVSX */ VMCF_OP2 ,
|
||||
/* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||
/* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||
/* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||
/* VM_PRINT */ VMCF_OP0
|
||||
};
|
||||
@ -1,126 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
RawRead::RawRead(File *SrcFile)
|
||||
{
|
||||
RawRead::SrcFile=SrcFile;
|
||||
ReadPos=0;
|
||||
DataSize=0;
|
||||
#ifndef SHELL_EXT
|
||||
Crypt=NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Read(size_t Size)
|
||||
{
|
||||
#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
|
||||
if (Crypt!=NULL)
|
||||
{
|
||||
size_t CurSize=Data.Size();
|
||||
size_t SizeToRead=Size-(CurSize-DataSize);
|
||||
if (SizeToRead>0)
|
||||
{
|
||||
size_t AlignedReadSize=SizeToRead+((~SizeToRead+1)&0xf);
|
||||
Data.Add(AlignedReadSize);
|
||||
size_t ReadSize=SrcFile->Read(&Data[CurSize],AlignedReadSize);
|
||||
Crypt->DecryptBlock(&Data[CurSize],AlignedReadSize);
|
||||
DataSize+=ReadSize==0 ? 0:Size;
|
||||
}
|
||||
else
|
||||
DataSize+=Size;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (Size!=0)
|
||||
{
|
||||
Data.Add(Size);
|
||||
DataSize+=SrcFile->Read(&Data[DataSize],Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Read(byte *SrcData,size_t Size)
|
||||
{
|
||||
if (Size!=0)
|
||||
{
|
||||
Data.Add(Size);
|
||||
memcpy(&Data[DataSize],SrcData,Size);
|
||||
DataSize+=Size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(byte &Field)
|
||||
{
|
||||
if (ReadPos<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos];
|
||||
ReadPos++;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(ushort &Field)
|
||||
{
|
||||
if (ReadPos+1<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8);
|
||||
ReadPos+=2;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(uint &Field)
|
||||
{
|
||||
if (ReadPos+3<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
|
||||
(Data[ReadPos+3]<<24);
|
||||
ReadPos+=4;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get8(int64 &Field)
|
||||
{
|
||||
uint Low,High;
|
||||
Get(Low);
|
||||
Get(High);
|
||||
Field=INT32TO64(High,Low);
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(byte *Field,size_t Size)
|
||||
{
|
||||
if (ReadPos+Size-1<DataSize)
|
||||
{
|
||||
memcpy(Field,&Data[ReadPos],Size);
|
||||
ReadPos+=Size;
|
||||
}
|
||||
else
|
||||
memset(Field,0,Size);
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(wchar *Field,size_t Size)
|
||||
{
|
||||
if (ReadPos+2*Size-1<DataSize)
|
||||
{
|
||||
RawToWide(&Data[ReadPos],Field,Size);
|
||||
ReadPos+=sizeof(wchar)*Size;
|
||||
}
|
||||
else
|
||||
memset(Field,0,sizeof(wchar)*Size);
|
||||
}
|
||||
|
||||
|
||||
uint RawRead::GetCRC(bool ProcessedOnly)
|
||||
{
|
||||
return(DataSize>2 ? CRC(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2):0xffffffff);
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef _RAR_RAWREAD_
|
||||
#define _RAR_RAWREAD_
|
||||
|
||||
class RawRead
|
||||
{
|
||||
private:
|
||||
Array<byte> Data;
|
||||
File *SrcFile;
|
||||
size_t DataSize;
|
||||
size_t ReadPos;
|
||||
#ifndef SHELL_EXT
|
||||
CryptData *Crypt;
|
||||
#endif
|
||||
public:
|
||||
RawRead(File *SrcFile);
|
||||
void Read(size_t Size);
|
||||
void Read(byte *SrcData,size_t Size);
|
||||
void Get(byte &Field);
|
||||
void Get(ushort &Field);
|
||||
void Get(uint &Field);
|
||||
void Get8(int64 &Field);
|
||||
void Get(byte *Field,size_t Size);
|
||||
void Get(wchar *Field,size_t Size);
|
||||
uint GetCRC(bool ProcessedOnly);
|
||||
size_t Size() {return DataSize;}
|
||||
size_t PaddedSize() {return Data.Size()-DataSize;}
|
||||
#ifndef SHELL_EXT
|
||||
void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,295 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
ComprDataIO::ComprDataIO()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::Init()
|
||||
{
|
||||
UnpackFromMemory=false;
|
||||
UnpackToMemory=false;
|
||||
UnpPackedSize=0;
|
||||
ShowProgress=true;
|
||||
TestMode=false;
|
||||
SkipUnpCRC=false;
|
||||
PackVolume=false;
|
||||
UnpVolume=false;
|
||||
NextVolumeMissing=false;
|
||||
SrcFile=NULL;
|
||||
DestFile=NULL;
|
||||
UnpWrSize=0;
|
||||
Command=NULL;
|
||||
Encryption=0;
|
||||
Decryption=0;
|
||||
TotalPackRead=0;
|
||||
CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
|
||||
PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
|
||||
LastPercent=-1;
|
||||
SubHead=NULL;
|
||||
SubHeadPos=NULL;
|
||||
CurrentCommand=0;
|
||||
ProcessedArcSize=TotalArcSize=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int ComprDataIO::UnpRead(byte *Addr,size_t Count)
|
||||
{
|
||||
int RetCode=0,TotalRead=0;
|
||||
byte *ReadAddr;
|
||||
ReadAddr=Addr;
|
||||
while (Count > 0)
|
||||
{
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
|
||||
size_t ReadSize=((int64)Count>UnpPackedSize) ? (size_t)UnpPackedSize:Count;
|
||||
if (UnpackFromMemory)
|
||||
{
|
||||
memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
|
||||
RetCode=(int)UnpackFromMemorySize;
|
||||
UnpackFromMemorySize=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SrcFile->IsOpened())
|
||||
return(-1);
|
||||
RetCode=SrcFile->Read(ReadAddr,ReadSize);
|
||||
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
|
||||
if (hd->Flags & LHD_SPLIT_AFTER)
|
||||
PackedCRC=CRC(PackedCRC,ReadAddr,RetCode);
|
||||
}
|
||||
CurUnpRead+=RetCode;
|
||||
TotalRead+=RetCode;
|
||||
#ifndef NOVOLUME
|
||||
// These variable are not used in NOVOLUME mode, so it is better
|
||||
// to exclude commands below to avoid compiler warnings.
|
||||
ReadAddr+=RetCode;
|
||||
Count-=RetCode;
|
||||
#endif
|
||||
UnpPackedSize-=RetCode;
|
||||
if (UnpPackedSize == 0 && UnpVolume)
|
||||
{
|
||||
#ifndef NOVOLUME
|
||||
if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
|
||||
#endif
|
||||
{
|
||||
NextVolumeMissing=true;
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
if (SrcArc!=NULL)
|
||||
ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
|
||||
if (RetCode!=-1)
|
||||
{
|
||||
RetCode=TotalRead;
|
||||
#ifndef RAR_NOCRYPT
|
||||
if (Decryption)
|
||||
#ifndef SFX_MODULE
|
||||
if (Decryption<20)
|
||||
Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
|
||||
else
|
||||
if (Decryption==20)
|
||||
for (int I=0;I<RetCode;I+=16)
|
||||
Decrypt.DecryptBlock20(&Addr[I]);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
|
||||
Decrypt.DecryptBlock(Addr,CryptSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Wait();
|
||||
return(RetCode);
|
||||
}
|
||||
|
||||
|
||||
#if defined(RARDLL) && defined(_MSC_VER) && !defined(_WIN_64)
|
||||
// Disable the run time stack check for unrar.dll, so we can manipulate
|
||||
// with ProcessDataProc call type below. Run time check would intercept
|
||||
// a wrong ESP before we restore it.
|
||||
#pragma runtime_checks( "s", off )
|
||||
#endif
|
||||
|
||||
void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
|
||||
{
|
||||
|
||||
#ifdef RARDLL
|
||||
RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
|
||||
if (Cmd->DllOpMode!=RAR_SKIP)
|
||||
{
|
||||
if (Cmd->Callback!=NULL &&
|
||||
Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
if (Cmd->ProcessDataProc!=NULL)
|
||||
{
|
||||
// Here we preserve ESP value. It is necessary for those developers,
|
||||
// who still define ProcessDataProc callback as "C" type function,
|
||||
// even though in year 2001 we announced in unrar.dll whatsnew.txt
|
||||
// that it will be PASCAL type (for compatibility with Visual Basic).
|
||||
#if defined(_MSC_VER)
|
||||
#ifndef _WIN_64
|
||||
__asm mov ebx,esp
|
||||
#endif
|
||||
#elif defined(_WIN_ALL) && defined(__BORLANDC__)
|
||||
_EBX=_ESP;
|
||||
#endif
|
||||
int RetCode=Cmd->ProcessDataProc(Addr,(int)Count);
|
||||
|
||||
// Restore ESP after ProcessDataProc with wrongly defined calling
|
||||
// convention broken it.
|
||||
#if defined(_MSC_VER)
|
||||
#ifndef _WIN_64
|
||||
__asm mov esp,ebx
|
||||
#endif
|
||||
#elif defined(_WIN_ALL) && defined(__BORLANDC__)
|
||||
_ESP=_EBX;
|
||||
#endif
|
||||
if (RetCode==0)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
}
|
||||
#endif // RARDLL
|
||||
|
||||
UnpWrAddr=Addr;
|
||||
UnpWrSize=Count;
|
||||
if (UnpackToMemory)
|
||||
{
|
||||
if (Count <= UnpackToMemorySize)
|
||||
{
|
||||
memcpy(UnpackToMemoryAddr,Addr,Count);
|
||||
UnpackToMemoryAddr+=Count;
|
||||
UnpackToMemorySize-=Count;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!TestMode)
|
||||
DestFile->Write(Addr,Count);
|
||||
CurUnpWrite+=Count;
|
||||
if (!SkipUnpCRC)
|
||||
#ifndef SFX_MODULE
|
||||
if (((Archive *)SrcFile)->OldFormat)
|
||||
UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
|
||||
else
|
||||
#endif
|
||||
UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
|
||||
ShowUnpWrite();
|
||||
Wait();
|
||||
}
|
||||
|
||||
#if defined(RARDLL) && defined(_MSC_VER) && !defined(_WIN_64)
|
||||
// Restore the run time stack check for unrar.dll.
|
||||
#pragma runtime_checks( "s", restore )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ComprDataIO::ShowUnpRead(int64 ArcPos,int64 ArcSize)
|
||||
{
|
||||
if (ShowProgress && SrcFile!=NULL)
|
||||
{
|
||||
if (TotalArcSize!=0)
|
||||
{
|
||||
// important when processing several archives or multivolume archive
|
||||
ArcSize=TotalArcSize;
|
||||
ArcPos+=ProcessedArcSize;
|
||||
}
|
||||
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
RAROptions *Cmd=SrcArc->GetRAROptions();
|
||||
|
||||
int CurPercent=ToPercent(ArcPos,ArcSize);
|
||||
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
|
||||
{
|
||||
mprintf("\b\b\b\b%3d%%",CurPercent);
|
||||
LastPercent=CurPercent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::ShowUnpWrite()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
|
||||
{
|
||||
if (SrcFile!=NULL)
|
||||
ComprDataIO::SrcFile=SrcFile;
|
||||
if (DestFile!=NULL)
|
||||
ComprDataIO::DestFile=DestFile;
|
||||
LastPercent=-1;
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::GetUnpackedData(byte **Data,size_t *Size)
|
||||
{
|
||||
*Data=UnpWrAddr;
|
||||
*Size=UnpWrSize;
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::SetEncryption(int Method,SecPassword *Password,const byte *Salt,bool Encrypt,bool HandsOffHash)
|
||||
{
|
||||
if (Encrypt)
|
||||
{
|
||||
Encryption=Password->IsSet() ? Method:0;
|
||||
#ifndef RAR_NOCRYPT
|
||||
Crypt.SetCryptKeys(Password,Salt,Encrypt,false,HandsOffHash);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Decryption=Password->IsSet() ? Method:0;
|
||||
#ifndef RAR_NOCRYPT
|
||||
Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29,HandsOffHash);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
|
||||
void ComprDataIO::SetAV15Encryption()
|
||||
{
|
||||
Decryption=15;
|
||||
Decrypt.SetAV15Encryption();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
|
||||
void ComprDataIO::SetCmt13Encryption()
|
||||
{
|
||||
Decryption=13;
|
||||
Decrypt.SetCmt13Encryption();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
|
||||
{
|
||||
UnpackToMemory=true;
|
||||
UnpackToMemoryAddr=Addr;
|
||||
UnpackToMemorySize=Size;
|
||||
}
|
||||
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
#ifndef _RAR_DATAIO_
|
||||
#define _RAR_DATAIO_
|
||||
|
||||
class CmdAdd;
|
||||
class Unpack;
|
||||
|
||||
|
||||
class ComprDataIO
|
||||
{
|
||||
private:
|
||||
void ShowUnpRead(int64 ArcPos,int64 ArcSize);
|
||||
void ShowUnpWrite();
|
||||
|
||||
|
||||
bool UnpackFromMemory;
|
||||
size_t UnpackFromMemorySize;
|
||||
byte *UnpackFromMemoryAddr;
|
||||
|
||||
bool UnpackToMemory;
|
||||
size_t UnpackToMemorySize;
|
||||
byte *UnpackToMemoryAddr;
|
||||
|
||||
size_t UnpWrSize;
|
||||
byte *UnpWrAddr;
|
||||
|
||||
int64 UnpPackedSize;
|
||||
|
||||
bool ShowProgress;
|
||||
bool TestMode;
|
||||
bool SkipUnpCRC;
|
||||
|
||||
File *SrcFile;
|
||||
File *DestFile;
|
||||
|
||||
CmdAdd *Command;
|
||||
|
||||
FileHeader *SubHead;
|
||||
int64 *SubHeadPos;
|
||||
|
||||
#ifndef RAR_NOCRYPT
|
||||
CryptData Crypt;
|
||||
CryptData Decrypt;
|
||||
#endif
|
||||
|
||||
|
||||
int LastPercent;
|
||||
|
||||
char CurrentCommand;
|
||||
|
||||
public:
|
||||
ComprDataIO();
|
||||
void Init();
|
||||
int UnpRead(byte *Addr,size_t Count);
|
||||
void UnpWrite(byte *Addr,size_t Count);
|
||||
void EnableShowProgress(bool Show) {ShowProgress=Show;}
|
||||
void GetUnpackedData(byte **Data,size_t *Size);
|
||||
void SetPackedSizeToRead(int64 Size) {UnpPackedSize=Size;}
|
||||
void SetTestMode(bool Mode) {TestMode=Mode;}
|
||||
void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;}
|
||||
void SetFiles(File *SrcFile,File *DestFile);
|
||||
void SetCommand(CmdAdd *Cmd) {Command=Cmd;}
|
||||
void SetSubHeader(FileHeader *hd,int64 *Pos) {SubHead=hd;SubHeadPos=Pos;}
|
||||
void SetEncryption(int Method,SecPassword *Password,const byte *Salt,bool Encrypt,bool HandsOffHash);
|
||||
void SetAV15Encryption();
|
||||
void SetCmt13Encryption();
|
||||
void SetUnpackToMemory(byte *Addr,uint Size);
|
||||
void SetCurrentCommand(char Cmd) {CurrentCommand=Cmd;}
|
||||
|
||||
bool PackVolume;
|
||||
bool UnpVolume;
|
||||
bool NextVolumeMissing;
|
||||
int64 TotalPackRead;
|
||||
int64 UnpArcSize;
|
||||
int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite;
|
||||
|
||||
// Size of already processed archives.
|
||||
// Used to calculate the total operation progress.
|
||||
int64 ProcessedArcSize;
|
||||
|
||||
int64 TotalArcSize;
|
||||
|
||||
uint PackFileCRC,UnpFileCRC,PackedCRC;
|
||||
|
||||
int Encryption;
|
||||
int Decryption;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,66 +0,0 @@
|
||||
|
||||
Portable UnRAR version
|
||||
|
||||
|
||||
1. General
|
||||
|
||||
This package includes freeware Unrar C++ source and a few makefiles
|
||||
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
|
||||
is subset of RAR and generated from RAR source automatically,
|
||||
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
|
||||
Such method is not perfect and you may find some RAR related
|
||||
stuff unnecessary in Unrar, especially in header files.
|
||||
|
||||
If you wish to port Unrar to a new platform, you may need to edit
|
||||
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
|
||||
in rartypes.hpp.
|
||||
|
||||
if computer architecture does not allow not aligned data access,
|
||||
you need to undefine ALLOW_NOT_ALIGNED_INT and define
|
||||
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
|
||||
requirements.
|
||||
|
||||
If you use Borland C++ makefile (makefile.bcc), you need to define
|
||||
BASEPATHCC environment (or makefile) variable containing
|
||||
the path to Borland C++ installation.
|
||||
|
||||
Makefile.unix contains numerous compiler option sets.
|
||||
GCC Linux is selected by default. If you need to compile Unrar
|
||||
for other platforms, uncomment corresponding lines.
|
||||
|
||||
UnRAR.vcproj and UnRARDll.vcproj are projects for Microsoft Visual C++.
|
||||
UnRARDll.vcproj lets to build unrar.dll library.
|
||||
|
||||
|
||||
2. Unrar binaries
|
||||
|
||||
If you compiled Unrar for OS, which is not present in "Downloads"
|
||||
and "RAR extras" on www.rarlab.com, we will appreciate if you send
|
||||
us the compiled executable to place it to our site.
|
||||
|
||||
|
||||
3. Acknowledgements
|
||||
|
||||
This source includes parts of code written by the following authors:
|
||||
|
||||
Dmitry Shkarin PPMII v.H text compression
|
||||
Dmitry Subbotin Carryless rangecoder
|
||||
Szymon Stefanek AES encryption
|
||||
Brian Gladman AES encryption
|
||||
Steve Reid SHA-1 hash function
|
||||
Marcus Herbert makefile.unix file
|
||||
Tomasz Klim fixes for libunrar.so
|
||||
Robert Riebisch makefile.dj and patches for DJGPP
|
||||
|
||||
|
||||
4. Legal stuff
|
||||
|
||||
Unrar source may be used in any software to handle RAR archives
|
||||
without limitations free of charge, but cannot be used to re-create
|
||||
the RAR compression algorithm, which is proprietary. Distribution
|
||||
of modified Unrar source in separate form or as a part of other
|
||||
software is permitted, provided that it is clearly stated in
|
||||
the documentation and source comments that the code may not be used
|
||||
to develop a RAR (WinRAR) compatible archiver.
|
||||
|
||||
More detailed license text is available in license.txt.
|
||||
@ -1,572 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
// Buffer size for all volumes involved.
|
||||
static const size_t TotalBufferSize=0x4000000;
|
||||
|
||||
class RSEncode // Encode or decode data area, one object per one thread.
|
||||
{
|
||||
private:
|
||||
RSCoder RSC;
|
||||
public:
|
||||
void EncodeBuf();
|
||||
void DecodeBuf();
|
||||
|
||||
void Init(int RecVolNumber) {RSC.Init(RecVolNumber);}
|
||||
byte *Buf;
|
||||
byte *OutBuf;
|
||||
int BufStart;
|
||||
int BufEnd;
|
||||
int FileNumber;
|
||||
int RecVolNumber;
|
||||
size_t RecBufferSize;
|
||||
int *Erasures;
|
||||
int EraSize;
|
||||
};
|
||||
|
||||
|
||||
#ifdef RAR_SMP
|
||||
THREAD_PROC(RSEncodeThread)
|
||||
{
|
||||
RSEncode *rs=(RSEncode *)Data;
|
||||
rs->EncodeBuf();
|
||||
}
|
||||
|
||||
THREAD_PROC(RSDecodeThread)
|
||||
{
|
||||
RSEncode *rs=(RSEncode *)Data;
|
||||
rs->DecodeBuf();
|
||||
}
|
||||
#endif
|
||||
|
||||
RecVolumes::RecVolumes()
|
||||
{
|
||||
Buf.Alloc(TotalBufferSize);
|
||||
memset(SrcFile,0,sizeof(SrcFile));
|
||||
}
|
||||
|
||||
|
||||
RecVolumes::~RecVolumes()
|
||||
{
|
||||
for (int I=0;I<ASIZE(SrcFile);I++)
|
||||
delete SrcFile[I];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RSEncode::EncodeBuf()
|
||||
{
|
||||
for (int BufPos=BufStart;BufPos<BufEnd;BufPos++)
|
||||
{
|
||||
byte Data[256],Code[256];
|
||||
for (int I=0;I<FileNumber;I++)
|
||||
Data[I]=Buf[I*RecBufferSize+BufPos];
|
||||
RSC.Encode(Data,FileNumber,Code);
|
||||
for (int I=0;I<RecVolNumber;I++)
|
||||
OutBuf[I*RecBufferSize+BufPos]=Code[I];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
|
||||
const wchar *NameW,bool Silent)
|
||||
{
|
||||
char ArcName[NM];
|
||||
wchar ArcNameW[NM];
|
||||
strcpy(ArcName,Name);
|
||||
wcscpy(ArcNameW,NameW);
|
||||
char *Ext=GetExt(ArcName);
|
||||
bool NewStyle=false;
|
||||
bool RevName=Ext!=NULL && stricomp(Ext,".rev")==0;
|
||||
if (RevName)
|
||||
{
|
||||
for (int DigitGroup=0;Ext>ArcName && DigitGroup<3;Ext--)
|
||||
if (!IsDigit(*Ext))
|
||||
if (IsDigit(*(Ext-1)) && (*Ext=='_' || DigitGroup<2))
|
||||
DigitGroup++;
|
||||
else
|
||||
if (DigitGroup<2)
|
||||
{
|
||||
NewStyle=true;
|
||||
break;
|
||||
}
|
||||
while (IsDigit(*Ext) && Ext>ArcName+1)
|
||||
Ext--;
|
||||
strcpy(Ext,"*.*");
|
||||
|
||||
if (*ArcNameW!=0)
|
||||
{
|
||||
wchar *ExtW=GetExt(ArcNameW);
|
||||
for (int DigitGroup=0;ExtW>ArcNameW && DigitGroup<3;ExtW--)
|
||||
if (!IsDigit(*ExtW))
|
||||
if (IsDigit(*(ExtW-1)) && (*ExtW=='_' || DigitGroup<2))
|
||||
DigitGroup++;
|
||||
else
|
||||
if (DigitGroup<2)
|
||||
{
|
||||
NewStyle=true;
|
||||
break;
|
||||
}
|
||||
while (IsDigit(*ExtW) && ExtW>ArcNameW+1)
|
||||
ExtW--;
|
||||
wcscpy(ExtW,L"*.*");
|
||||
}
|
||||
|
||||
FindFile Find;
|
||||
Find.SetMask(ArcName);
|
||||
Find.SetMaskW(ArcNameW);
|
||||
FindData fd;
|
||||
while (Find.Next(&fd))
|
||||
{
|
||||
Archive Arc(Cmd);
|
||||
if (Arc.WOpen(fd.Name,fd.NameW) && Arc.IsArchive(true))
|
||||
{
|
||||
strcpy(ArcName,fd.Name);
|
||||
wcscpy(ArcNameW,fd.NameW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Archive Arc(Cmd);
|
||||
if (!Arc.WCheckOpen(ArcName,ArcNameW))
|
||||
return(false);
|
||||
if (!Arc.Volume)
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(ArcName,St(MNotVolume),ArcName);
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
bool NewNumbering=(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0;
|
||||
Arc.Close();
|
||||
|
||||
char *VolNumStart=VolNameToFirstName(ArcName,ArcName,NewNumbering);
|
||||
char RecVolMask[NM];
|
||||
strcpy(RecVolMask,ArcName);
|
||||
size_t BaseNamePartLength=VolNumStart-ArcName;
|
||||
strcpy(RecVolMask+BaseNamePartLength,"*.rev");
|
||||
|
||||
wchar RecVolMaskW[NM];
|
||||
size_t BaseNamePartLengthW=0;
|
||||
*RecVolMaskW=0;
|
||||
if (*ArcNameW!=0)
|
||||
{
|
||||
wchar *VolNumStartW=VolNameToFirstName(ArcNameW,ArcNameW,NewNumbering);
|
||||
wcscpy(RecVolMaskW,ArcNameW);
|
||||
BaseNamePartLengthW=VolNumStartW-ArcNameW;
|
||||
wcscpy(RecVolMaskW+BaseNamePartLengthW,L"*.rev");
|
||||
}
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
int64 RecFileSize=0;
|
||||
#endif
|
||||
|
||||
// We cannot display "Calculating CRC..." message here, because we do not
|
||||
// know if we'll find any recovery volumes. We'll display it after finding
|
||||
// the first recovery volume.
|
||||
bool CalcCRCMessageDone=false;
|
||||
|
||||
FindFile Find;
|
||||
Find.SetMask(RecVolMask);
|
||||
Find.SetMaskW(RecVolMaskW);
|
||||
FindData RecData;
|
||||
int FileNumber=0,RecVolNumber=0,FoundRecVolumes=0,MissingVolumes=0;
|
||||
char PrevName[NM];
|
||||
wchar PrevNameW[NM];
|
||||
while (Find.Next(&RecData))
|
||||
{
|
||||
char *CurName=RecData.Name;
|
||||
wchar *CurNameW=RecData.NameW;
|
||||
int P[3];
|
||||
if (!RevName && !NewStyle)
|
||||
{
|
||||
NewStyle=true;
|
||||
|
||||
char *Dot=GetExt(CurName);
|
||||
if (Dot!=NULL)
|
||||
{
|
||||
int LineCount=0;
|
||||
Dot--;
|
||||
while (Dot>CurName && *Dot!='.')
|
||||
{
|
||||
if (*Dot=='_')
|
||||
LineCount++;
|
||||
Dot--;
|
||||
}
|
||||
if (LineCount==2)
|
||||
NewStyle=false;
|
||||
}
|
||||
|
||||
wchar *DotW=GetExt(CurNameW);
|
||||
if (DotW!=NULL)
|
||||
{
|
||||
int LineCount=0;
|
||||
DotW--;
|
||||
while (DotW>CurNameW && *DotW!='.')
|
||||
{
|
||||
if (*DotW=='_')
|
||||
LineCount++;
|
||||
DotW--;
|
||||
}
|
||||
if (LineCount==2)
|
||||
NewStyle=false;
|
||||
}
|
||||
}
|
||||
if (NewStyle)
|
||||
{
|
||||
if (!CalcCRCMessageDone)
|
||||
{
|
||||
#ifndef SILENT
|
||||
mprintf(St(MCalcCRCAllVol));
|
||||
#endif
|
||||
CalcCRCMessageDone=true;
|
||||
}
|
||||
|
||||
#ifndef SILENT
|
||||
mprintf("\r\n%s",CurName);
|
||||
#endif
|
||||
|
||||
File CurFile;
|
||||
CurFile.TOpen(CurName,CurNameW);
|
||||
CurFile.Seek(0,SEEK_END);
|
||||
int64 Length=CurFile.Tell();
|
||||
CurFile.Seek(Length-7,SEEK_SET);
|
||||
for (int I=0;I<3;I++)
|
||||
P[2-I]=CurFile.GetByte()+1;
|
||||
uint FileCRC=0;
|
||||
for (int I=0;I<4;I++)
|
||||
FileCRC|=CurFile.GetByte()<<(I*8);
|
||||
if (FileCRC!=CalcFileCRC(&CurFile,Length-4))
|
||||
{
|
||||
#ifndef SILENT
|
||||
mprintf(St(MCRCFailed),CurName);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *Dot=GetExt(CurName);
|
||||
if (Dot==NULL)
|
||||
continue;
|
||||
bool WrongParam=false;
|
||||
for (int I=0;I<ASIZE(P);I++)
|
||||
{
|
||||
do
|
||||
{
|
||||
Dot--;
|
||||
} while (IsDigit(*Dot) && Dot>=CurName+BaseNamePartLength);
|
||||
P[I]=atoi(Dot+1);
|
||||
if (P[I]==0 || P[I]>255)
|
||||
WrongParam=true;
|
||||
}
|
||||
if (WrongParam)
|
||||
continue;
|
||||
}
|
||||
if (P[1]+P[2]>255)
|
||||
continue;
|
||||
if (RecVolNumber!=0 && RecVolNumber!=P[1] || FileNumber!=0 && FileNumber!=P[2])
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(NULL,St(MRecVolDiffSets),CurName,PrevName);
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
RecVolNumber=P[1];
|
||||
FileNumber=P[2];
|
||||
strcpy(PrevName,CurName);
|
||||
wcscpy(PrevNameW,CurNameW);
|
||||
File *NewFile=new File;
|
||||
NewFile->TOpen(CurName,CurNameW);
|
||||
SrcFile[FileNumber+P[0]-1]=NewFile;
|
||||
FoundRecVolumes++;
|
||||
#ifndef SILENT
|
||||
if (RecFileSize==0)
|
||||
RecFileSize=NewFile->FileLength();
|
||||
#endif
|
||||
}
|
||||
#ifndef SILENT
|
||||
if (!Silent || FoundRecVolumes!=0)
|
||||
{
|
||||
mprintf(St(MRecVolFound),FoundRecVolumes);
|
||||
}
|
||||
#endif
|
||||
if (FoundRecVolumes==0)
|
||||
return(false);
|
||||
|
||||
bool WriteFlags[256];
|
||||
memset(WriteFlags,0,sizeof(WriteFlags));
|
||||
|
||||
char LastVolName[NM];
|
||||
*LastVolName=0;
|
||||
wchar LastVolNameW[NM];
|
||||
*LastVolNameW=0;
|
||||
|
||||
for (int CurArcNum=0;CurArcNum<FileNumber;CurArcNum++)
|
||||
{
|
||||
Archive *NewFile=new Archive;
|
||||
bool ValidVolume=FileExist(ArcName,ArcNameW);
|
||||
if (ValidVolume)
|
||||
{
|
||||
NewFile->TOpen(ArcName,ArcNameW);
|
||||
ValidVolume=NewFile->IsArchive(false);
|
||||
if (ValidVolume)
|
||||
{
|
||||
while (NewFile->ReadHeader()!=0)
|
||||
{
|
||||
if (NewFile->GetHeaderType()==ENDARC_HEAD)
|
||||
{
|
||||
#ifndef SILENT
|
||||
mprintf("\r\n%s",ArcName);
|
||||
#endif
|
||||
if ((NewFile->EndArcHead.Flags&EARC_DATACRC)!=0 &&
|
||||
NewFile->EndArcHead.ArcDataCRC!=CalcFileCRC(NewFile,NewFile->CurBlockPos))
|
||||
{
|
||||
ValidVolume=false;
|
||||
#ifndef SILENT
|
||||
mprintf(St(MCRCFailed),ArcName);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
NewFile->SeekToNext();
|
||||
}
|
||||
}
|
||||
if (!ValidVolume)
|
||||
{
|
||||
NewFile->Close();
|
||||
char NewName[NM];
|
||||
strcpy(NewName,ArcName);
|
||||
strcat(NewName,".bad");
|
||||
|
||||
wchar NewNameW[NM];
|
||||
wcscpy(NewNameW,ArcNameW);
|
||||
if (*NewNameW!=0)
|
||||
wcscat(NewNameW,L".bad");
|
||||
#ifndef SILENT
|
||||
mprintf(St(MBadArc),ArcName);
|
||||
mprintf(St(MRenaming),ArcName,NewName);
|
||||
#endif
|
||||
RenameFile(ArcName,ArcNameW,NewName,NewNameW);
|
||||
}
|
||||
NewFile->Seek(0,SEEK_SET);
|
||||
}
|
||||
if (!ValidVolume)
|
||||
{
|
||||
// It is important to return 'false' instead of aborting here,
|
||||
// so if we are called from extraction, we will be able to continue
|
||||
// extracting. It may happen if .rar and .rev are on read-only disks
|
||||
// like CDs.
|
||||
if (!NewFile->Create(ArcName,ArcNameW))
|
||||
{
|
||||
// We need to display the title of operation before the error message,
|
||||
// to make clear for user that create error is related to recovery
|
||||
// volumes. This is why we cannot use WCreate call here. Title must be
|
||||
// before create error, not after that.
|
||||
#ifndef SILENT
|
||||
mprintf(St(MReconstructing));
|
||||
#endif
|
||||
ErrHandler.CreateErrorMsg(ArcName,ArcNameW);
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteFlags[CurArcNum]=true;
|
||||
MissingVolumes++;
|
||||
|
||||
if (CurArcNum==FileNumber-1)
|
||||
{
|
||||
strcpy(LastVolName,ArcName);
|
||||
wcscpy(LastVolNameW,ArcNameW);
|
||||
}
|
||||
|
||||
#ifndef SILENT
|
||||
mprintf(St(MAbsNextVol),ArcName);
|
||||
#endif
|
||||
}
|
||||
SrcFile[CurArcNum]=(File*)NewFile;
|
||||
NextVolumeName(ArcName,ArcNameW,ASIZE(ArcName),!NewNumbering);
|
||||
}
|
||||
|
||||
#ifndef SILENT
|
||||
mprintf(St(MRecVolMissing),MissingVolumes);
|
||||
#endif
|
||||
|
||||
if (MissingVolumes==0)
|
||||
{
|
||||
#ifndef SILENT
|
||||
mprintf(St(MRecVolAllExist));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (MissingVolumes>FoundRecVolumes)
|
||||
{
|
||||
#ifndef SILENT
|
||||
mprintf(St(MRecVolCannotFix));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
#ifndef SILENT
|
||||
mprintf(St(MReconstructing));
|
||||
#endif
|
||||
|
||||
int TotalFiles=FileNumber+RecVolNumber;
|
||||
int Erasures[256],EraSize=0;
|
||||
|
||||
for (int I=0;I<TotalFiles;I++)
|
||||
if (WriteFlags[I] || SrcFile[I]==NULL)
|
||||
Erasures[EraSize++]=I;
|
||||
|
||||
#ifndef SILENT
|
||||
int64 ProcessedSize=0;
|
||||
#ifndef GUI
|
||||
int LastPercent=-1;
|
||||
mprintf(" ");
|
||||
#endif
|
||||
#endif
|
||||
// Size of per file buffer.
|
||||
size_t RecBufferSize=TotalBufferSize/TotalFiles;
|
||||
|
||||
#ifdef RAR_SMP
|
||||
uint ThreadNumber=Cmd->Threads;
|
||||
RSEncode rse[MaxPoolThreads];
|
||||
uint WaitHandles[MaxPoolThreads];
|
||||
#else
|
||||
uint ThreadNumber=1;
|
||||
RSEncode rse[1];
|
||||
#endif
|
||||
for (uint I=0;I<ThreadNumber;I++)
|
||||
rse[I].Init(RecVolNumber);
|
||||
|
||||
while (true)
|
||||
{
|
||||
Wait();
|
||||
int MaxRead=0;
|
||||
for (int I=0;I<TotalFiles;I++)
|
||||
if (WriteFlags[I] || SrcFile[I]==NULL)
|
||||
memset(&Buf[I*RecBufferSize],0,RecBufferSize);
|
||||
else
|
||||
{
|
||||
int ReadSize=SrcFile[I]->Read(&Buf[I*RecBufferSize],RecBufferSize);
|
||||
if (ReadSize!=RecBufferSize)
|
||||
memset(&Buf[I*RecBufferSize+ReadSize],0,RecBufferSize-ReadSize);
|
||||
if (ReadSize>MaxRead)
|
||||
MaxRead=ReadSize;
|
||||
}
|
||||
if (MaxRead==0)
|
||||
break;
|
||||
#ifndef SILENT
|
||||
int CurPercent=ToPercent(ProcessedSize,RecFileSize);
|
||||
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
|
||||
{
|
||||
mprintf("\b\b\b\b%3d%%",CurPercent);
|
||||
LastPercent=CurPercent;
|
||||
}
|
||||
ProcessedSize+=MaxRead;
|
||||
#endif
|
||||
|
||||
|
||||
int BlockStart=0;
|
||||
int BlockSize=MaxRead/ThreadNumber;
|
||||
if (BlockSize<0x100)
|
||||
BlockSize=MaxRead;
|
||||
uint CurThread=0;
|
||||
|
||||
while (BlockStart<MaxRead)
|
||||
{
|
||||
// Last thread processes all left data including increasement
|
||||
// from rounding error.
|
||||
if (CurThread==ThreadNumber-1)
|
||||
BlockSize=MaxRead-BlockStart;
|
||||
|
||||
RSEncode *curenc=rse+CurThread;
|
||||
curenc->Buf=&Buf[0];
|
||||
curenc->BufStart=BlockStart;
|
||||
curenc->BufEnd=BlockStart+BlockSize;
|
||||
curenc->FileNumber=TotalFiles;
|
||||
curenc->RecBufferSize=RecBufferSize;
|
||||
curenc->Erasures=Erasures;
|
||||
curenc->EraSize=EraSize;
|
||||
|
||||
#ifdef RAR_SMP
|
||||
if (ThreadNumber>1)
|
||||
{
|
||||
uint Handle=RSThreadPool.Start(RSDecodeThread,(void*)curenc);
|
||||
WaitHandles[CurThread++]=Handle;
|
||||
}
|
||||
else
|
||||
curenc->DecodeBuf();
|
||||
#else
|
||||
curenc->DecodeBuf();
|
||||
#endif
|
||||
|
||||
BlockStart+=BlockSize;
|
||||
}
|
||||
|
||||
#ifdef RAR_SMP
|
||||
if (CurThread>0)
|
||||
RSThreadPool.Wait(WaitHandles,CurThread);
|
||||
#endif // RAR_SMP
|
||||
|
||||
for (int I=0;I<FileNumber;I++)
|
||||
if (WriteFlags[I])
|
||||
SrcFile[I]->Write(&Buf[I*RecBufferSize],MaxRead);
|
||||
}
|
||||
for (int I=0;I<RecVolNumber+FileNumber;I++)
|
||||
if (SrcFile[I]!=NULL)
|
||||
{
|
||||
File *CurFile=SrcFile[I];
|
||||
if (NewStyle && WriteFlags[I])
|
||||
{
|
||||
int64 Length=CurFile->Tell();
|
||||
CurFile->Seek(Length-7,SEEK_SET);
|
||||
for (int J=0;J<7;J++)
|
||||
CurFile->PutByte(0);
|
||||
}
|
||||
CurFile->Close();
|
||||
SrcFile[I]=NULL;
|
||||
}
|
||||
if (*LastVolName!=0 || *LastVolNameW!=0)
|
||||
{
|
||||
// Truncate the last volume to its real size.
|
||||
Archive Arc(Cmd);
|
||||
if (Arc.Open(LastVolName,LastVolNameW,FMF_UPDATE) && Arc.IsArchive(true) &&
|
||||
Arc.SearchBlock(ENDARC_HEAD))
|
||||
{
|
||||
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
|
||||
char Buf[8192];
|
||||
int ReadSize=Arc.Read(Buf,sizeof(Buf));
|
||||
int ZeroCount=0;
|
||||
while (ZeroCount<ReadSize && Buf[ZeroCount]==0)
|
||||
ZeroCount++;
|
||||
if (ZeroCount==ReadSize)
|
||||
{
|
||||
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
|
||||
Arc.Truncate();
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !defined(GUI) && !defined(SILENT)
|
||||
if (!Cmd->DisablePercentage)
|
||||
mprintf("\b\b\b\b100%%");
|
||||
if (!Silent && !Cmd->DisableDone)
|
||||
mprintf(St(MDone));
|
||||
#endif
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
void RSEncode::DecodeBuf()
|
||||
{
|
||||
for (int BufPos=BufStart;BufPos<BufEnd;BufPos++)
|
||||
{
|
||||
byte Data[256];
|
||||
for (int I=0;I<FileNumber;I++)
|
||||
Data[I]=Buf[I*RecBufferSize+BufPos];
|
||||
RSC.Decode(Data,FileNumber,Erasures,EraSize);
|
||||
for (int I=0;I<EraSize;I++)
|
||||
Buf[Erasures[I]*RecBufferSize+BufPos]=Data[Erasures[I]];
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
#ifndef _RAR_RECVOL_
|
||||
#define _RAR_RECVOL_
|
||||
|
||||
class RecVolumes
|
||||
{
|
||||
private:
|
||||
File *SrcFile[256];
|
||||
Array<byte> Buf;
|
||||
|
||||
#ifdef RAR_SMP
|
||||
ThreadPool RSThreadPool;
|
||||
#endif
|
||||
public:
|
||||
RecVolumes();
|
||||
~RecVolumes();
|
||||
void Make(RAROptions *Cmd,char *ArcName,wchar *ArcNameW);
|
||||
bool Restore(RAROptions *Cmd,const char *Name,const wchar *NameW,bool Silent);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,27 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
|
||||
|
||||
#ifndef RARDLL
|
||||
const char *St(MSGID StringId)
|
||||
{
|
||||
return(StringId);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef RARDLL
|
||||
const wchar *StW(MSGID StringId)
|
||||
{
|
||||
static wchar StrTable[8][512];
|
||||
static int StrNum=0;
|
||||
if (++StrNum >= sizeof(StrTable)/sizeof(StrTable[0]))
|
||||
StrNum=0;
|
||||
wchar *Str=StrTable[StrNum];
|
||||
*Str=0;
|
||||
CharToWide(StringId,Str,ASIZE(StrTable[0]));
|
||||
return(Str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
#ifndef _RAR_RESOURCE_
|
||||
#define _RAR_RESOURCE_
|
||||
|
||||
#ifdef RARDLL
|
||||
#define St(x) ( "")
|
||||
#define StW(x) (L"")
|
||||
#else
|
||||
const char *St (MSGID StringId);
|
||||
const wchar *StW (MSGID StringId);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,298 +0,0 @@
|
||||
/**************************************************************************
|
||||
* This code is based on Szymon Stefanek AES implementation: *
|
||||
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
|
||||
* *
|
||||
* Dynamic tables generation is based on the Brian Gladman work: *
|
||||
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
|
||||
**************************************************************************/
|
||||
#include "rar.hpp"
|
||||
|
||||
const int uKeyLenInBytes=16, m_uRounds=10;
|
||||
|
||||
static byte S[256],S5[256],rcon[30];
|
||||
static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
|
||||
static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
|
||||
static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
|
||||
|
||||
|
||||
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2)
|
||||
{
|
||||
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||
((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
|
||||
((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
|
||||
((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
|
||||
((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
|
||||
#else
|
||||
for (int I=0;I<16;I++)
|
||||
dest[I]=arg1[I]^arg2[I];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
|
||||
const byte *arg3,const byte *arg4)
|
||||
{
|
||||
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||
(*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
|
||||
#else
|
||||
for (int I=0;I<4;I++)
|
||||
dest[I]=arg1[I]^arg2[I]^arg3[I]^arg4[I];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void Copy128(byte *dest,const byte *src)
|
||||
{
|
||||
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||
((uint32*)dest)[0]=((uint32*)src)[0];
|
||||
((uint32*)dest)[1]=((uint32*)src)[1];
|
||||
((uint32*)dest)[2]=((uint32*)src)[2];
|
||||
((uint32*)dest)[3]=((uint32*)src)[3];
|
||||
#else
|
||||
for (int I=0;I<16;I++)
|
||||
dest[I]=src[I];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Rijndael::Rijndael()
|
||||
{
|
||||
if (S[0]==0)
|
||||
GenerateTables();
|
||||
}
|
||||
|
||||
|
||||
void Rijndael::init(Direction dir,const byte * key,byte * initVector)
|
||||
{
|
||||
m_direction = dir;
|
||||
|
||||
byte keyMatrix[_MAX_KEY_COLUMNS][4];
|
||||
|
||||
for(uint i = 0;i < uKeyLenInBytes;i++)
|
||||
keyMatrix[i >> 2][i & 3] = key[i];
|
||||
|
||||
for(int i = 0;i < MAX_IV_SIZE;i++)
|
||||
m_initVector[i] = initVector[i];
|
||||
|
||||
keySched(keyMatrix);
|
||||
|
||||
if(m_direction == Decrypt)
|
||||
keyEncToDec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
|
||||
{
|
||||
if (input == 0 || inputLen <= 0)
|
||||
return 0;
|
||||
|
||||
byte block[16], iv[4][4];
|
||||
memcpy(iv,m_initVector,16);
|
||||
|
||||
size_t numBlocks=inputLen/16;
|
||||
for (size_t i = numBlocks; i > 0; i--)
|
||||
{
|
||||
decrypt(input, block);
|
||||
Xor128(block,block,(byte*)iv);
|
||||
#if STRICT_ALIGN
|
||||
memcpy(iv, input, 16);
|
||||
memcpy(outBuf, block, 16);
|
||||
#else
|
||||
Copy128((byte*)iv,input);
|
||||
Copy128(outBuffer,block);
|
||||
#endif
|
||||
input += 16;
|
||||
outBuffer += 16;
|
||||
}
|
||||
|
||||
memcpy(m_initVector,iv,16);
|
||||
|
||||
return 16*numBlocks;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ALGORITHM
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void Rijndael::keySched(byte key[_MAX_KEY_COLUMNS][4])
|
||||
{
|
||||
int j,rconpointer = 0;
|
||||
|
||||
// Calculate the necessary round keys
|
||||
// The number of calculations depends on keyBits and blockBits
|
||||
int uKeyColumns = m_uRounds - 6;
|
||||
|
||||
byte tempKey[_MAX_KEY_COLUMNS][4];
|
||||
|
||||
// Copy the input key to the temporary key matrix
|
||||
|
||||
memcpy(tempKey,key,sizeof(tempKey));
|
||||
|
||||
int r = 0;
|
||||
int t = 0;
|
||||
|
||||
// copy values into round key array
|
||||
for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
|
||||
{
|
||||
for(;(j < uKeyColumns) && (t < 4); j++, t++)
|
||||
for (int k=0;k<4;k++)
|
||||
m_expandedKey[r][t][k]=tempKey[j][k];
|
||||
|
||||
if(t == 4)
|
||||
{
|
||||
r++;
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while(r <= m_uRounds)
|
||||
{
|
||||
tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
|
||||
tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
|
||||
tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
|
||||
tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
|
||||
tempKey[0][0] ^= rcon[rconpointer++];
|
||||
|
||||
if (uKeyColumns != 8)
|
||||
for(j = 1; j < uKeyColumns; j++)
|
||||
for (int k=0;k<4;k++)
|
||||
tempKey[j][k] ^= tempKey[j-1][k];
|
||||
else
|
||||
{
|
||||
for(j = 1; j < uKeyColumns/2; j++)
|
||||
for (int k=0;k<4;k++)
|
||||
tempKey[j][k] ^= tempKey[j-1][k];
|
||||
|
||||
tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
|
||||
tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
|
||||
tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
|
||||
tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
|
||||
for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
|
||||
for (int k=0;k<4;k++)
|
||||
tempKey[j][k] ^= tempKey[j-1][k];
|
||||
}
|
||||
for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
|
||||
{
|
||||
for(; (j < uKeyColumns) && (t < 4); j++, t++)
|
||||
for (int k=0;k<4;k++)
|
||||
m_expandedKey[r][t][k] = tempKey[j][k];
|
||||
if(t == 4)
|
||||
{
|
||||
r++;
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rijndael::keyEncToDec()
|
||||
{
|
||||
for(int r = 1; r < m_uRounds; r++)
|
||||
{
|
||||
byte n_expandedKey[4][4];
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
{
|
||||
byte *w=m_expandedKey[r][j];
|
||||
n_expandedKey[j][i]=U1[w[0]][i]^U2[w[1]][i]^U3[w[2]][i]^U4[w[3]][i];
|
||||
}
|
||||
memcpy(m_expandedKey[r],n_expandedKey,sizeof(m_expandedKey[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rijndael::decrypt(const byte a[16], byte b[16])
|
||||
{
|
||||
int r;
|
||||
byte temp[4][4];
|
||||
|
||||
Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]);
|
||||
|
||||
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
|
||||
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
|
||||
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
|
||||
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
|
||||
|
||||
for(r = m_uRounds-1; r > 1; r--)
|
||||
{
|
||||
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]);
|
||||
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
|
||||
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
|
||||
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
|
||||
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
|
||||
}
|
||||
|
||||
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]);
|
||||
b[ 0] = S5[temp[0][0]];
|
||||
b[ 1] = S5[temp[3][1]];
|
||||
b[ 2] = S5[temp[2][2]];
|
||||
b[ 3] = S5[temp[1][3]];
|
||||
b[ 4] = S5[temp[1][0]];
|
||||
b[ 5] = S5[temp[0][1]];
|
||||
b[ 6] = S5[temp[3][2]];
|
||||
b[ 7] = S5[temp[2][3]];
|
||||
b[ 8] = S5[temp[2][0]];
|
||||
b[ 9] = S5[temp[1][1]];
|
||||
b[10] = S5[temp[0][2]];
|
||||
b[11] = S5[temp[3][3]];
|
||||
b[12] = S5[temp[3][0]];
|
||||
b[13] = S5[temp[2][1]];
|
||||
b[14] = S5[temp[1][2]];
|
||||
b[15] = S5[temp[0][3]];
|
||||
Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]);
|
||||
}
|
||||
|
||||
#define ff_poly 0x011b
|
||||
#define ff_hi 0x80
|
||||
|
||||
#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
|
||||
|
||||
#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
|
||||
#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
|
||||
#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
|
||||
#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
|
||||
#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
|
||||
#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
|
||||
#define fwd_affine(x) \
|
||||
(w = (uint)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), (byte)(0x63^(w^(w>>8))))
|
||||
|
||||
#define inv_affine(x) \
|
||||
(w = (uint)x, w = (w<<1)^(w<<3)^(w<<6), (byte)(0x05^(w^(w>>8))))
|
||||
|
||||
void Rijndael::GenerateTables()
|
||||
{
|
||||
unsigned char pow[512],log[256];
|
||||
int i = 0, w = 1;
|
||||
do
|
||||
{
|
||||
pow[i] = (byte)w;
|
||||
pow[i + 255] = (byte)w;
|
||||
log[w] = (byte)i++;
|
||||
w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
||||
} while (w != 1);
|
||||
|
||||
for (int i = 0,w = 1; i < sizeof(rcon)/sizeof(rcon[0]); i++)
|
||||
{
|
||||
rcon[i] = w;
|
||||
w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
||||
}
|
||||
for(int i = 0; i < 256; ++i)
|
||||
{
|
||||
unsigned char b=S[i]=fwd_affine(FFinv((byte)i));
|
||||
T1[i][1]=T1[i][2]=T2[i][2]=T2[i][3]=T3[i][0]=T3[i][3]=T4[i][0]=T4[i][1]=b;
|
||||
T1[i][0]=T2[i][1]=T3[i][2]=T4[i][3]=FFmul02(b);
|
||||
T1[i][3]=T2[i][0]=T3[i][1]=T4[i][2]=FFmul03(b);
|
||||
S5[i] = b = FFinv(inv_affine((byte)i));
|
||||
U1[b][3]=U2[b][0]=U3[b][1]=U4[b][2]=T5[i][3]=T6[i][0]=T7[i][1]=T8[i][2]=FFmul0b(b);
|
||||
U1[b][1]=U2[b][2]=U3[b][3]=U4[b][0]=T5[i][1]=T6[i][2]=T7[i][3]=T8[i][0]=FFmul09(b);
|
||||
U1[b][2]=U2[b][3]=U3[b][0]=U4[b][1]=T5[i][2]=T6[i][3]=T7[i][0]=T8[i][1]=FFmul0d(b);
|
||||
U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[i][0]=T6[i][1]=T7[i][2]=T8[i][3]=FFmul0e(b);
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
#ifndef _RIJNDAEL_H_
|
||||
#define _RIJNDAEL_H_
|
||||
|
||||
/**************************************************************************
|
||||
* This code is based on Szymon Stefanek AES implementation: *
|
||||
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
|
||||
* *
|
||||
* Dynamic tables generation is based on the Brian Gladman's work: *
|
||||
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
|
||||
**************************************************************************/
|
||||
|
||||
#define _MAX_KEY_COLUMNS (256/32)
|
||||
#define _MAX_ROUNDS 14
|
||||
#define MAX_IV_SIZE 16
|
||||
|
||||
class Rijndael
|
||||
{
|
||||
public:
|
||||
enum Direction { Encrypt , Decrypt };
|
||||
private:
|
||||
void keySched(byte key[_MAX_KEY_COLUMNS][4]);
|
||||
void keyEncToDec();
|
||||
void encrypt(const byte a[16], byte b[16]);
|
||||
void decrypt(const byte a[16], byte b[16]);
|
||||
void GenerateTables();
|
||||
|
||||
Direction m_direction;
|
||||
byte m_initVector[MAX_IV_SIZE];
|
||||
byte m_expandedKey[_MAX_ROUNDS+1][4][4];
|
||||
public:
|
||||
Rijndael();
|
||||
void init(Direction dir,const byte *key,byte *initVector);
|
||||
size_t blockEncrypt(const byte *input, size_t inputLen, byte *outBuffer);
|
||||
size_t blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer);
|
||||
};
|
||||
|
||||
#endif // _RIJNDAEL_H_
|
||||
172
src/unrar/rs.cpp
172
src/unrar/rs.cpp
@ -1,172 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#define Clean(D,S) {for (int I=0;I<(S);I++) (D)[I]=0;}
|
||||
|
||||
void RSCoder::Init(int ParSize)
|
||||
{
|
||||
RSCoder::ParSize=ParSize; // Store the number of recovery volumes.
|
||||
FirstBlockDone=false;
|
||||
gfInit();
|
||||
pnInit();
|
||||
}
|
||||
|
||||
|
||||
// Initialize logarithms and exponents Galois field tables.
|
||||
void RSCoder::gfInit()
|
||||
{
|
||||
for (int I=0,J=1;I<MAXPAR;I++)
|
||||
{
|
||||
gfLog[J]=I;
|
||||
gfExp[I]=J;
|
||||
J<<=1;
|
||||
if (J & 0x100)
|
||||
J^=0x11D; // 0x11D field-generator polynomial (x^8+x^4+x^3+x^2+1).
|
||||
}
|
||||
for (int I=MAXPAR;I<MAXPOL;I++)
|
||||
gfExp[I]=gfExp[I-MAXPAR];
|
||||
}
|
||||
|
||||
|
||||
// Multiplication over Galois field.
|
||||
inline int RSCoder::gfMult(int a,int b)
|
||||
{
|
||||
return(a==0 || b == 0 ? 0:gfExp[gfLog[a]+gfLog[b]]);
|
||||
}
|
||||
|
||||
|
||||
// Create the generator polynomial g(x).
|
||||
// g(x)=(x-a)(x-a^2)(x-a^3)..(x-a^N)
|
||||
void RSCoder::pnInit()
|
||||
{
|
||||
int p2[MAXPAR+1]; // Currently calculated part of g(x).
|
||||
|
||||
Clean(p2,ParSize);
|
||||
p2[0]=1; // Set p2 polynomial to 1.
|
||||
|
||||
for (int I=1;I<=ParSize;I++)
|
||||
{
|
||||
int p1[MAXPAR+1]; // We use p1 as current (x+a^i) expression.
|
||||
Clean(p1,ParSize);
|
||||
p1[0]=gfExp[I];
|
||||
p1[1]=1; // Set p1 polynomial to x+a^i.
|
||||
|
||||
// Multiply the already calucated part of g(x) to next (x+a^i).
|
||||
pnMult(p1,p2,GXPol);
|
||||
|
||||
// p2=g(x).
|
||||
for (int J=0;J<ParSize;J++)
|
||||
p2[J]=GXPol[J];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Multiply polynomial 'p1' to 'p2' and store the result in 'r'.
|
||||
void RSCoder::pnMult(int *p1,int *p2,int *r)
|
||||
{
|
||||
Clean(r,ParSize);
|
||||
for (int I=0;I<ParSize;I++)
|
||||
if (p1[I]!=0)
|
||||
for(int J=0;J<ParSize-I;J++)
|
||||
r[I+J]^=gfMult(p1[I],p2[J]);
|
||||
}
|
||||
|
||||
|
||||
void RSCoder::Encode(byte *Data,int DataSize,byte *DestData)
|
||||
{
|
||||
int ShiftReg[MAXPAR+1]; // Linear Feedback Shift Register.
|
||||
|
||||
Clean(ShiftReg,ParSize+1);
|
||||
for (int I=0;I<DataSize;I++)
|
||||
{
|
||||
int D=Data[I]^ShiftReg[ParSize-1];
|
||||
|
||||
// Use g(x) to define feedback taps.
|
||||
for (int J=ParSize-1;J>0;J--)
|
||||
ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D);
|
||||
ShiftReg[0]=gfMult(GXPol[0],D);
|
||||
}
|
||||
for (int I=0;I<ParSize;I++)
|
||||
DestData[I]=ShiftReg[ParSize-I-1];
|
||||
}
|
||||
|
||||
|
||||
bool RSCoder::Decode(byte *Data,int DataSize,int *EraLoc,int EraSize)
|
||||
{
|
||||
int SynData[MAXPOL]; // Syndrome data.
|
||||
|
||||
bool AllZeroes=true;
|
||||
for (int I=0;I<ParSize;I++)
|
||||
{
|
||||
int Sum=Data[0],J=1,Exp=gfExp[I+1];
|
||||
for (;J+8<=DataSize;J+=8) // Unroll the loop for speed.
|
||||
{
|
||||
Sum=Data[J]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+1]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+2]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+3]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+4]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+5]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+6]^gfMult(Exp,Sum);
|
||||
Sum=Data[J+7]^gfMult(Exp,Sum);
|
||||
}
|
||||
|
||||
for (;J<DataSize;J++)
|
||||
Sum=Data[J]^gfMult(Exp,Sum);
|
||||
if ((SynData[I]=Sum)!=0)
|
||||
AllZeroes=false;
|
||||
}
|
||||
|
||||
// If all syndrome numbers are zero, message does not have errors.
|
||||
if (AllZeroes)
|
||||
return(true);
|
||||
|
||||
if (!FirstBlockDone) // Do things which we need to do once for all data.
|
||||
{
|
||||
FirstBlockDone=true;
|
||||
|
||||
// Calculate the error locator polynomial.
|
||||
Clean(ELPol,ParSize+1);
|
||||
ELPol[0]=1;
|
||||
|
||||
for (int EraPos=0;EraPos<EraSize;EraPos++)
|
||||
for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--)
|
||||
ELPol[I]^=gfMult(M,ELPol[I-1]);
|
||||
|
||||
ErrCount=0;
|
||||
|
||||
// Find roots of error locator polynomial.
|
||||
for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++)
|
||||
{
|
||||
int Sum=0;
|
||||
for (int B=0;B<ParSize+1;B++)
|
||||
Sum^=gfMult(gfExp[(B*Root)%MAXPAR],ELPol[B]);
|
||||
if (Sum==0) // Root found.
|
||||
{
|
||||
ErrorLocs[ErrCount]=MAXPAR-Root; // Location of error.
|
||||
|
||||
// Calculate the denominator for every error location.
|
||||
Dnm[ErrCount]=0;
|
||||
for (int I=1;I<ParSize+1;I+=2)
|
||||
Dnm[ErrCount]^= gfMult(ELPol[I],gfExp[Root*(I-1)%MAXPAR]);
|
||||
|
||||
ErrCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EEPol[MAXPOL]; // Error Evaluator Polynomial.
|
||||
pnMult(ELPol,SynData,EEPol);
|
||||
// If errors are present and their number is correctable.
|
||||
if ((ErrCount<=ParSize) && ErrCount>0)
|
||||
for (int I=0;I<ErrCount;I++)
|
||||
{
|
||||
int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0;
|
||||
for (int J=0;J<ParSize;J++)
|
||||
N^=gfMult(EEPol[J],gfExp[DLoc*J%MAXPAR]);
|
||||
int DataPos=DataSize-Loc-1;
|
||||
// Perform bounds check and correct the data error.
|
||||
if (DataPos>=0 && DataPos<DataSize)
|
||||
Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dnm[I]]]);
|
||||
}
|
||||
return(ErrCount<=ParSize); // Return true if success.
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef _RAR_RS_
|
||||
#define _RAR_RS_
|
||||
|
||||
#define MAXPAR 255 // Maximum parity data size.
|
||||
#define MAXPOL 512 // Maximum polynomial degree.
|
||||
|
||||
class RSCoder
|
||||
{
|
||||
private:
|
||||
void gfInit();
|
||||
int gfMult(int a,int b);
|
||||
void pnInit();
|
||||
void pnMult(int *p1,int *p2,int *r);
|
||||
|
||||
int gfExp[MAXPOL]; // Galois field exponents.
|
||||
int gfLog[MAXPAR+1]; // Galois field logarithms.
|
||||
|
||||
int GXPol[MAXPOL*2]; // Generator polynomial g(x).
|
||||
|
||||
int ErrorLocs[MAXPAR+1],ErrCount;
|
||||
int Dnm[MAXPAR+1];
|
||||
|
||||
int ParSize; // Parity bytes size and so the number of recovery volumes.
|
||||
int ELPol[MAXPOL]; // Error locator polynomial.
|
||||
bool FirstBlockDone;
|
||||
public:
|
||||
void Init(int ParSize);
|
||||
void Encode(byte *Data,int DataSize,byte *DestData);
|
||||
bool Decode(byte *Data,int DataSize,int *EraLoc,int EraSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,15 +0,0 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
SaveFilePos::SaveFilePos(File &SaveFile)
|
||||
{
|
||||
SaveFilePos::SaveFile=&SaveFile;
|
||||
SavePos=SaveFile.Tell();
|
||||
CloseCount=SaveFile.CloseCount;
|
||||
}
|
||||
|
||||
|
||||
SaveFilePos::~SaveFilePos()
|
||||
{
|
||||
if (CloseCount==SaveFile->CloseCount)
|
||||
SaveFile->Seek(SavePos,SEEK_SET);
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
#ifndef _RAR_SAVEPOS_
|
||||
#define _RAR_SAVEPOS_
|
||||
|
||||
class SaveFilePos
|
||||
{
|
||||
private:
|
||||
File *SaveFile;
|
||||
int64 SavePos;
|
||||
uint CloseCount;
|
||||
public:
|
||||
SaveFilePos(File &SaveFile);
|
||||
~SaveFilePos();
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user