Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/rarfilesource.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOctaneSnail <os@v12pwr.com>2008-12-13 21:54:51 +0300
committerOctaneSnail <os@v12pwr.com>2008-12-13 22:54:08 +0300
commit0978b5dd252cfdfed9813af201d634aa9e79d949 (patch)
tree9b1e7b457c1ddca08146682a7a2f1502d836deae
parent75ed77126304e38d098fc4f5845e552a48999734 (diff)
Fix handling of archives and media files larger than 4 gigabytes.
Based on a patch from OV2.
-rw-r--r--OutputPin.cpp14
-rw-r--r--RAR.cpp44
-rw-r--r--RAR.h8
-rw-r--r--RFS.cpp32
-rw-r--r--RFS.h2
-rw-r--r--Utils.cpp4
6 files changed, 49 insertions, 55 deletions
diff --git a/OutputPin.cpp b/OutputPin.cpp
index acee509..4090a52 100644
--- a/OutputPin.cpp
+++ b/OutputPin.cpp
@@ -275,7 +275,8 @@ STDMETHODIMP CRFSOutputPin::Request (IMediaSample* pSample, DWORD_PTR dwUser)
}
LARGE_INTEGER offset;
- DWORD to_read, acc = 0, offset2;
+ DWORD to_read, acc = 0;
+ LONGLONG offset2;
int pos = FindStartPart (llPosition);
if (pos == -1)
@@ -294,7 +295,7 @@ STDMETHODIMP CRFSOutputPin::Request (IMediaSample* pSample, DWORD_PTR dwUser)
FilePart *part = m_file->array + pos;
- offset2 = (DWORD) (llPosition - part->in_file_offset);
+ offset2 = llPosition - part->in_file_offset;
offset.QuadPart = part->in_rar_offset + offset2;
while (true)
@@ -310,7 +311,7 @@ STDMETHODIMP CRFSOutputPin::Request (IMediaSample* pSample, DWORD_PTR dwUser)
request->subreqs.InsertLast (sr);
request->count ++;
- to_read = min (lLength, part->size - offset2);
+ to_read = min (lLength, (DWORD) (part->size - offset2));
sr->file = part->file;
sr->expected = to_read;
@@ -552,7 +553,8 @@ HRESULT CRFSOutputPin::SyncRead (LONGLONG llPosition, DWORD lLength, BYTE* pBuff
{
OVERLAPPED o;
LARGE_INTEGER offset;
- DWORD to_read, read, acc = 0, offset2;
+ DWORD to_read, read, acc = 0;
+ LONGLONG offset2;
int pos;
#ifdef _DEBUG
static int last_pos = -1;
@@ -583,7 +585,7 @@ HRESULT CRFSOutputPin::SyncRead (LONGLONG llPosition, DWORD lLength, BYTE* pBuff
#endif
FilePart *part = m_file->array + pos;
- offset2 = (DWORD) (llPosition - part->in_file_offset);
+ offset2 = llPosition - part->in_file_offset;
offset.QuadPart = part->in_rar_offset + offset2;
memset (&o, 0, sizeof (o));
@@ -597,7 +599,7 @@ HRESULT CRFSOutputPin::SyncRead (LONGLONG llPosition, DWORD lLength, BYTE* pBuff
while (true)
{
read = 0;
- to_read = min (lLength, part->size - offset2);
+ to_read = min (lLength, (DWORD) (part->size - offset2));
o.Offset = offset.LowPart;
o.OffsetHigh = offset.HighPart;
diff --git a/RAR.cpp b/RAR.cpp
index fb659f3..310c2e3 100644
--- a/RAR.cpp
+++ b/RAR.cpp
@@ -44,7 +44,8 @@ DWORD ReadHeader (HANDLE file, rar_header_t *dest)
{
fixed_header_t fh;
fixed_file_header_t ffh;
- DWORD read, acc = 0, dword;
+ DWORD read, dword;
+ LONGLONG acc = 0;
// Read fixed archive header.
READ_ITEM (fh);
@@ -56,16 +57,13 @@ DWORD ReadHeader (HANDLE file, rar_header_t *dest)
if (fh.flags & LONG_BLOCK)
{
READ_ITEM (dword);
-
- if ((MAXDWORD - dword) < fh.size)
- {
- ErrorMsg (0, L"Variable overflow while reading RAR header.");
- return S_FALSE;
- }
- dest->ch.size = dword + fh.size;
+ dest->ch.size.QuadPart = (LONGLONG) dword + fh.size;
}
else
- dest->ch.size = fh.size;
+ {
+ dest->ch.size.HighPart = 0;
+ dest->ch.size.LowPart = fh.size;
+ }
switch (fh.type)
{
@@ -76,7 +74,7 @@ DWORD ReadHeader (HANDLE file, rar_header_t *dest)
case HEADER_TYPE_FILE:
READ_ITEM (ffh);
- dest->fh.low_size = ffh.size;
+ dest->fh.size.LowPart = ffh.size;
dest->fh.os = ffh.os;
dest->fh.crc = ffh.crc;
dest->fh.timestamp = ffh.timestamp;
@@ -87,16 +85,13 @@ DWORD ReadHeader (HANDLE file, rar_header_t *dest)
if (fh.flags & LHD_LARGE)
{
- READ_ITEM (dword);
- dest->fh.high_size = dword;
- dest->fh.size = ((DWORD64) dword << 32) | ffh.size;
- READ_ITEM (dword);
+ READ_ITEM (dword); // Packed size high dword
+ dest->ch.size.HighPart += dword;
+ READ_ITEM (dword); // Unpacked size high dword
+ dest->fh.size.HighPart = dword;
}
else
- {
- dest->fh.high_size = 0;
- dest->fh.size = ffh.size;
- }
+ dest->fh.size.HighPart = 0;
dest->fh.filename = new char [dest->fh.name_len + 1];
if (!dest->fh.filename)
@@ -136,20 +131,21 @@ DWORD ReadHeader (HANDLE file, rar_header_t *dest)
}
}
- if (acc > dest->ch.size)
+ if (acc > dest->ch.size.QuadPart)
{
ErrorMsg (0, L"Overrun while reading RAR header.");
return S_FALSE;
}
- if (fh.type != HEADER_TYPE_FILE && acc < dest->ch.size)
+ if (fh.type != HEADER_TYPE_FILE && acc < dest->ch.size.QuadPart)
{
- SetFilePointer (file, dest->ch.size - acc, 0, FILE_CURRENT);
-// DbgLog ((LOG_TRACE, 2, L"Skipped over %d header bytes.", dest->ch.size - acc));
- dest->bytesRemaining = 0;
+ LARGE_INTEGER li;
+ li.QuadPart = dest->ch.size.QuadPart - acc;
+ SetFilePointerEx (file, li, NULL, FILE_CURRENT);
+ dest->bytesRemaining.QuadPart = 0;
}
else
- dest->bytesRemaining = dest->ch.size - acc;
+ dest->bytesRemaining.QuadPart = dest->ch.size.QuadPart - acc;
return ERROR_SUCCESS;
}
diff --git a/RAR.h b/RAR.h
index b6241cd..c4b5834 100644
--- a/RAR.h
+++ b/RAR.h
@@ -60,7 +60,7 @@ typedef struct
WORD crc;
BYTE type;
WORD flags;
- DWORD size;
+ LARGE_INTEGER size;
} common_header_t;
typedef struct
@@ -71,9 +71,7 @@ typedef struct
typedef struct
{
- DWORD64 size;
- DWORD low_size;
- DWORD high_size;
+ LARGE_INTEGER size;
DWORD crc;
DWORD timestamp;
@@ -108,7 +106,7 @@ typedef struct
end_header_t eh;
};
- DWORD bytesRemaining;
+ LARGE_INTEGER bytesRemaining;
} rar_header_t;
DWORD ReadHeader (HANDLE file, rar_header_t *dest);
diff --git a/RFS.cpp b/RFS.cpp
index 75f67af..b2271a9 100644
--- a/RFS.cpp
+++ b/RFS.cpp
@@ -228,13 +228,12 @@ STDMETHODIMP CRARFileSource::NonDelegatingQueryInterface (REFIID riid, void **pp
#define HEADER_SKIP_FILE \
delete [] rh.fh.filename; \
- SetFilePointer (hFile, rh.bytesRemaining, 0, FILE_CURRENT); \
+ SetFilePointerEx (hFile, rh.bytesRemaining, NULL, FILE_CURRENT); \
continue;
int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, int *ok_files_found)
{
DWORD dwBytesRead;
- DWORD mem_offset = 0;
char *filename = NULL;
wchar_t *current_rar_filename = NULL, *rar_ext;
bool first_archive_file = true;
@@ -243,13 +242,14 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
BYTE marker [7];
BYTE expected [7] = { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00 };
FilePart *new_part, *prev_part;
- LONGLONG collect = 0;
+ LONGLONG collected;
DWORD ret;
DWORD files = 0, volumes = 0;
int volume_digits;
File *file = NULL;
*ok_files_found = 0;
+ LARGE_INTEGER zero = {0};
Anchor<File> af (&file);
ArrayAnchor<wchar_t> acrf (&current_rar_filename);
@@ -398,13 +398,13 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
}
if (rh.ch.type != HEADER_TYPE_FILE)
{
- SetFilePointer (hFile, rh.bytesRemaining, 0, FILE_CURRENT);
+ SetFilePointerEx (hFile, rh.bytesRemaining, NULL, FILE_CURRENT);
DbgLog ((LOG_TRACE, 2,L"Skipping unknown header type %02x.", rh.ch.type));
continue;
}
- DbgLog ((LOG_TRACE, 2, L"SIZE %d,%d OS %02x CRC %08x TIMESTAMP %08x VERSION %d METHOD %02x LEN %04x ATTRIB %08x",
- rh.fh.low_size, rh.fh.high_size, rh.fh.os, rh.fh.crc, rh.fh.timestamp, rh.fh.version, rh.fh.method, rh.fh.name_len, rh.fh.attributes));
+ DbgLog ((LOG_TRACE, 2, L"SIZE %08x %08x OS %02x CRC %08x TIMESTAMP %08x VERSION %d METHOD %02x LEN %04x ATTRIB %08x",
+ rh.fh.size.HighPart, rh.fh.size.LowPart, rh.fh.os, rh.fh.crc, rh.fh.timestamp, rh.fh.version, rh.fh.method, rh.fh.name_len, rh.fh.attributes));
DbgLog ((LOG_TRACE, 2, L"FILENAME \"%S\"", rh.fh.filename));
@@ -437,8 +437,7 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
}
files ++;
- mem_offset = 0;
- collect = 0;
+ collected = 0;
ASSERT (!file);
@@ -447,7 +446,7 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
file->media_type.SetType (&MEDIATYPE_Stream);
file->media_type.SetSubtype (&MEDIASUBTYPE_NULL);
file->filename = rh.fh.filename;
- file->size = rh.fh.size;
+ file->size = rh.fh.size.QuadPart;
filename = rh.fh.filename;
if (rh.ch.flags & LHD_PASSWORD)
@@ -512,9 +511,9 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
}
prev_part = new_part;
- new_part->in_rar_offset = SetFilePointer (hFile, 0, 0, FILE_CURRENT);
- new_part->in_file_offset = mem_offset;
- new_part->size = rh.bytesRemaining;
+ SetFilePointerEx (hFile, zero, (LARGE_INTEGER*) &new_part->in_rar_offset, FILE_CURRENT);
+ new_part->in_file_offset = collected;
+ new_part->size = rh.bytesRemaining.QuadPart;
new_part->file = CreateFile (current_rar_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (new_part->file == INVALID_HANDLE_VALUE)
@@ -524,15 +523,14 @@ int CRARFileSource::ScanArchive (wchar_t *archive_name, List<File> *file_list, i
}
}
- collect += rh.bytesRemaining;
- mem_offset += rh.bytesRemaining;
- SetFilePointer (hFile, rh.bytesRemaining, 0, FILE_CURRENT);
+ collected += rh.bytesRemaining.QuadPart;
+ SetFilePointerEx (hFile, rh.bytesRemaining, NULL, FILE_CURRENT);
// Is file complete?
if (!(rh.ch.flags & LHD_SPLIT_AFTER))
{
- if (!file->unsupported && (file->size != collect || file->size != mem_offset))
- DbgLog ((LOG_TRACE, 2, L"The file is not the sum of it's parts. expected = %d, actual = %d", file->size, collect));
+ if (!file->unsupported && file->size != collected)
+ DbgLog ((LOG_TRACE, 2, L"The file is not the sum of it's parts. expected = %lld, actual = %lld", file->size, collected));
if (file->parts)
{
diff --git a/RFS.h b/RFS.h
index cb976c5..f76c7af 100644
--- a/RFS.h
+++ b/RFS.h
@@ -31,7 +31,7 @@ public:
LONGLONG in_rar_offset;
LONGLONG in_file_offset;
- DWORD size;
+ LONGLONG size;
};
class File : public Node<File>
diff --git a/Utils.cpp b/Utils.cpp
index d068416..7e84604 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -95,8 +95,8 @@ void LogHeader (rar_header_t *rh)
int i;
WORD flags = rh->ch.flags;
- DbgLog ((LOG_TRACE, 2, L"Header CRC %04x TYPE %02x FLAGS %04x SIZE %08x",
- rh->ch.crc, rh->ch.type, rh->ch.flags, rh->ch.size));
+ DbgLog ((LOG_TRACE, 2, L"Header CRC %04x TYPE %02x FLAGS %04x SIZE %08x %08x",
+ rh->ch.crc, rh->ch.type, rh->ch.flags, rh->ch.size.HighPart, rh->ch.size.LowPart));
switch (rh->ch.type)
{