|
|
|
|
@ -91,10 +91,10 @@ static bool BaseFile_Create(TFileStream * pStream)
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
{ |
|
|
|
|
intptr_t handle; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handle = open(pStream->szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
|
|
|
|
if(handle == -1) |
|
|
|
|
{ |
|
|
|
|
@ -102,7 +102,7 @@ static bool BaseFile_Create(TFileStream * pStream)
|
|
|
|
|
pStream->Base.File.hFile = INVALID_HANDLE_VALUE; // BUGFIX (devilutionX)
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pStream->Base.File.hFile = (HANDLE)handle; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
@ -141,7 +141,7 @@ static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
{ |
|
|
|
|
struct stat64 fileinfo; |
|
|
|
|
int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR; |
|
|
|
|
@ -212,7 +212,7 @@ static bool BaseFile_Read(
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
{ |
|
|
|
|
ssize_t bytes_read; |
|
|
|
|
|
|
|
|
|
@ -233,7 +233,7 @@ static bool BaseFile_Read(
|
|
|
|
|
nLastError = errno; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dwBytesRead = (DWORD)(size_t)bytes_read; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -283,7 +283,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
{ |
|
|
|
|
ssize_t bytes_written; |
|
|
|
|
|
|
|
|
|
@ -302,7 +302,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
|
|
|
|
|
nLastError = errno; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dwBytesWritten = (DWORD)(size_t)bytes_written; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
@ -349,15 +349,15 @@ static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize)
|
|
|
|
|
return bResult; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
{ |
|
|
|
|
if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1) |
|
|
|
|
{ |
|
|
|
|
nLastError = errno; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pStream->Base.File.FileSize = NewFileSize; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
@ -394,14 +394,14 @@ static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream)
|
|
|
|
|
return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
// "rename" on Linux also works if the target file exists
|
|
|
|
|
if(rename(pNewStream->szFileName, pStream->szFileName) == -1) |
|
|
|
|
{ |
|
|
|
|
nLastError = errno; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
@ -414,7 +414,7 @@ static void BaseFile_Close(TFileStream * pStream)
|
|
|
|
|
CloseHandle(pStream->Base.File.hFile); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
close((intptr_t)pStream->Base.File.hFile); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
@ -493,7 +493,7 @@ static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
|
|
|
|
|
return false; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) |
|
|
|
|
struct stat64 fileinfo; |
|
|
|
|
intptr_t handle; |
|
|
|
|
bool bResult = false; |
|
|
|
|
@ -505,6 +505,7 @@ static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
|
|
|
|
|
// Get the file size
|
|
|
|
|
if(fstat64(handle, &fileinfo) != -1) |
|
|
|
|
{ |
|
|
|
|
#if !defined(PLATFORM_AMIGA) |
|
|
|
|
pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0); |
|
|
|
|
if(pStream->Base.Map.pbFile != NULL) |
|
|
|
|
{ |
|
|
|
|
@ -516,6 +517,7 @@ static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
|
|
|
|
|
pStream->Base.Map.FilePos = 0; |
|
|
|
|
bResult = true; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
close(handle); |
|
|
|
|
} |
|
|
|
|
@ -562,7 +564,7 @@ static void BaseMap_Close(TFileStream * pStream)
|
|
|
|
|
UnmapViewOfFile(pStream->Base.Map.pbFile); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU) |
|
|
|
|
#if (defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) || defined(PLATFORM_HAIKU)) && !defined(__AMIGA__) //Todo(Amiga): Fix a proper solution for this
|
|
|
|
|
if(pStream->Base.Map.pbFile != NULL) |
|
|
|
|
munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize); |
|
|
|
|
#endif |
|
|
|
|
@ -1025,7 +1027,7 @@ static TFileStream * AllocateFileStream(
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Open the master file
|
|
|
|
|
pMaster = FileStream_OpenFile(szNextFile + 1, STREAM_FLAG_READ_ONLY); |
|
|
|
|
} |
|
|
|
|
@ -1083,7 +1085,7 @@ static DWORD FlatStream_CheckFile(TBlockStream * pStream)
|
|
|
|
|
static bool FlatStream_LoadBitmap(TBlockStream * pStream) |
|
|
|
|
{ |
|
|
|
|
FILE_BITMAP_FOOTER Footer; |
|
|
|
|
ULONGLONG ByteOffset;
|
|
|
|
|
ULONGLONG ByteOffset; |
|
|
|
|
LPBYTE FileBitmap; |
|
|
|
|
DWORD BlockCount; |
|
|
|
|
DWORD BitmapSize; |
|
|
|
|
@ -1191,7 +1193,7 @@ static bool FlatStream_BlockCheck(
|
|
|
|
|
// Sanity checks
|
|
|
|
|
assert((BlockOffset & (pStream->BlockSize - 1)) == 0); |
|
|
|
|
assert(FileBitmap != NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate the index of the block
|
|
|
|
|
BlockIndex = (DWORD)(BlockOffset / pStream->BlockSize); |
|
|
|
|
BitMask = (BYTE)(1 << (BlockIndex & 0x07)); |
|
|
|
|
@ -1252,7 +1254,7 @@ static void FlatStream_Close(TBlockStream * pStream)
|
|
|
|
|
{ |
|
|
|
|
// Write the file bitmap
|
|
|
|
|
pStream->BaseWrite(pStream, &pStream->StreamSize, pStream->FileBitmap, pStream->BitmapSize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare and write the file footer
|
|
|
|
|
Footer.Signature = ID_FILE_BITMAP_FOOTER; |
|
|
|
|
Footer.Version = 3; |
|
|
|
|
@ -1347,7 +1349,7 @@ static bool FlatStream_CreateMirror(TBlockStream * pStream)
|
|
|
|
|
|
|
|
|
|
static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) |
|
|
|
|
{ |
|
|
|
|
TBlockStream * pStream;
|
|
|
|
|
TBlockStream * pStream; |
|
|
|
|
ULONGLONG ByteOffset = 0; |
|
|
|
|
|
|
|
|
|
// Create new empty stream
|
|
|
|
|
@ -1571,7 +1573,7 @@ static bool PartStream_BlockCheck(
|
|
|
|
|
// Sanity checks
|
|
|
|
|
assert((BlockOffset & (pStream->BlockSize - 1)) == 0); |
|
|
|
|
assert(pStream->FileBitmap != NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate the block map entry
|
|
|
|
|
FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (BlockOffset / pStream->BlockSize); |
|
|
|
|
|
|
|
|
|
@ -1667,7 +1669,7 @@ static void PartStream_Close(TBlockStream * pStream)
|
|
|
|
|
PartHeader.FileSizeHi = (DWORD)(pStream->StreamSize >> 0x20); |
|
|
|
|
PartHeader.FileSizeLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF); |
|
|
|
|
PartHeader.BlockSize = pStream->BlockSize; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure that the header is properly BSWAPed
|
|
|
|
|
BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER)); |
|
|
|
|
sprintf(PartHeader.GameBuildNumber, "%u", (unsigned int)pStream->BuildNumber); |
|
|
|
|
@ -1832,7 +1834,7 @@ static const char * AuthCodeArray[] =
|
|
|
|
|
"S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U", // SC2 Heart of the Swarm-all : "expand 32-byte kQAKQ0000FM3UN5XE000073FD6CDT0000LJBJS48B0000DJND"
|
|
|
|
|
|
|
|
|
|
// Diablo III: Agent.exe (1.0.0.954)
|
|
|
|
|
// Address of decryption routine: 00502b00
|
|
|
|
|
// Address of decryption routine: 00502b00
|
|
|
|
|
// Pointer to decryptor object: ECX
|
|
|
|
|
// Pointer to key: ECX+0x5C
|
|
|
|
|
// Authentication code URL: http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
|
|
|
|
|
@ -1938,7 +1940,7 @@ static void DecryptFileChunk(
|
|
|
|
|
KeyShuffled[0x04] = KeyMirror[0x0D]; |
|
|
|
|
KeyShuffled[0x01] = KeyMirror[0x0E]; |
|
|
|
|
KeyShuffled[0x00] = KeyMirror[0x0F]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Shuffle the key - part 2
|
|
|
|
|
for(DWORD i = 0; i < RoundCount; i += 2) |
|
|
|
|
{ |
|
|
|
|
@ -2284,7 +2286,7 @@ static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamF
|
|
|
|
|
assert(FileSize <= BLOCK4_MAX_FSIZE); |
|
|
|
|
RemainderBlock = FileSize % (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE); |
|
|
|
|
BlockCount = FileSize / (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Increment the stream size and number of blocks
|
|
|
|
|
pStream->StreamSize += (BlockCount * BLOCK4_BLOCK_SIZE); |
|
|
|
|
pStream->BlockCount += (DWORD)BlockCount; |
|
|
|
|
@ -2502,7 +2504,7 @@ size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider)
|
|
|
|
|
dwProvider |= BASE_PROVIDER_MAP; |
|
|
|
|
nPrefixLength2 = 4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("http:"), 5)) |
|
|
|
|
{ |
|
|
|
|
dwProvider |= BASE_PROVIDER_HTTP; |
|
|
|
|
@ -2710,7 +2712,7 @@ bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
|
|
|
|
|
* \a NewFileSize File size to set |
|
|
|
|
*/ |
|
|
|
|
bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize) |
|
|
|
|
{
|
|
|
|
|
{ |
|
|
|
|
if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) |
|
|
|
|
{ |
|
|
|
|
SetLastError(ERROR_ACCESS_DENIED); |
|
|
|
|
@ -2822,7 +2824,7 @@ void FileStream_Close(TFileStream * pStream)
|
|
|
|
|
// Close the stream provider ...
|
|
|
|
|
if(pStream->StreamClose != NULL) |
|
|
|
|
pStream->StreamClose(pStream); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ... or close base stream, if any
|
|
|
|
|
else if(pStream->BaseClose != NULL) |
|
|
|
|
pStream->BaseClose(pStream); |
|
|
|
|
|