solocraft + dynamicxp
This commit is contained in:
63
dep/CascLib/CMakeLists.txt
Normal file
63
dep/CascLib/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
set(HEADER_FILES
|
||||
src/CascCommon.h
|
||||
src/CascLib.h
|
||||
src/CascMndx.h
|
||||
src/CascPort.h
|
||||
src/common/Common.h
|
||||
src/common/FileStream.h
|
||||
src/common/ListFile.h
|
||||
src/common/Map.h
|
||||
src/jenkins/lookup.h
|
||||
)
|
||||
|
||||
set(SRC_FILES
|
||||
src/common/Common.cpp
|
||||
src/common/Directory.cpp
|
||||
src/common/DumpContext.cpp
|
||||
src/common/DynamicArray.cpp
|
||||
src/common/FileStream.cpp
|
||||
src/common/ListFile.cpp
|
||||
src/common/Map.cpp
|
||||
src/common/RootHandler.cpp
|
||||
src/jenkins/lookup3.c
|
||||
src/CascCommon.cpp
|
||||
src/CascDecompress.cpp
|
||||
src/CascDecrypt.cpp
|
||||
src/CascDumpData.cpp
|
||||
src/CascFiles.cpp
|
||||
src/CascFindFile.cpp
|
||||
src/CascOpenFile.cpp
|
||||
src/CascOpenStorage.cpp
|
||||
src/CascReadFile.cpp
|
||||
src/CascRootFile_Diablo3.cpp
|
||||
src/CascRootFile_Mndx.cpp
|
||||
src/CascRootFile_Ovr.cpp
|
||||
src/CascRootFile_SC1.cpp
|
||||
src/CascRootFile_WoW6.cpp
|
||||
)
|
||||
|
||||
set(TOMCRYPT_FILES
|
||||
src/libtomcrypt/src/hashes/hash_memory.c
|
||||
src/libtomcrypt/src/hashes/md5.c
|
||||
src/libtomcrypt/src/misc/crypt_argchk.c
|
||||
src/libtomcrypt/src/misc/crypt_hash_descriptor.c
|
||||
src/libtomcrypt/src/misc/crypt_hash_is_valid.c
|
||||
src/libtomcrypt/src/misc/crypt_libc.c
|
||||
)
|
||||
|
||||
add_library(casc STATIC ${SRC_FILES} ${TOMCRYPT_FILES})
|
||||
|
||||
target_include_directories(casc
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/dep)
|
||||
|
||||
target_link_libraries(casc
|
||||
PUBLIC
|
||||
zlib)
|
||||
|
||||
set_target_properties(casc
|
||||
PROPERTIES
|
||||
FOLDER
|
||||
"dep")
|
||||
21
dep/CascLib/LICENSE
Normal file
21
dep/CascLib/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Ladislav Zezula
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
4
dep/CascLib/README.md
Normal file
4
dep/CascLib/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
CascLib
|
||||
=======
|
||||
|
||||
An open-source implementation of library for reading CASC storage from Blizzard games since 2014
|
||||
6
dep/CascLib/doc/history.txt
Normal file
6
dep/CascLib/doc/history.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
CascLib history
|
||||
===============
|
||||
|
||||
Version 1.00
|
||||
|
||||
- Created
|
||||
90
dep/CascLib/src/CascCommon.cpp
Normal file
90
dep/CascLib/src/CascCommon.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*****************************************************************************/
|
||||
/* CascCommon.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of CascCommon.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Conversion of big-endian to integer
|
||||
|
||||
// Read the 24-bit big-endian offset into ULONGLONG
|
||||
DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes)
|
||||
{
|
||||
DWORD Value = 0;
|
||||
|
||||
Value = (Value << 0x08) | ValueAsBytes[0];
|
||||
Value = (Value << 0x08) | ValueAsBytes[1];
|
||||
Value = (Value << 0x08) | ValueAsBytes[2];
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
// Read the 32-bit big-endian offset into ULONGLONG
|
||||
DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes)
|
||||
{
|
||||
DWORD Value = 0;
|
||||
|
||||
Value = (Value << 0x08) | ValueAsBytes[0];
|
||||
Value = (Value << 0x08) | ValueAsBytes[1];
|
||||
Value = (Value << 0x08) | ValueAsBytes[2];
|
||||
Value = (Value << 0x08) | ValueAsBytes[3];
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes)
|
||||
{
|
||||
DWORD Value = 0;
|
||||
|
||||
Value = (Value << 0x08) | ValueAsBytes[3];
|
||||
Value = (Value << 0x08) | ValueAsBytes[2];
|
||||
Value = (Value << 0x08) | ValueAsBytes[1];
|
||||
Value = (Value << 0x08) | ValueAsBytes[0];
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
// Read the 40-bit big-endian offset into ULONGLONG
|
||||
ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes)
|
||||
{
|
||||
ULONGLONG Value = 0;
|
||||
|
||||
Value = (Value << 0x08) | ValueAsBytes[0];
|
||||
Value = (Value << 0x08) | ValueAsBytes[1];
|
||||
Value = (Value << 0x08) | ValueAsBytes[2];
|
||||
Value = (Value << 0x08) | ValueAsBytes[3];
|
||||
Value = (Value << 0x08) | ValueAsBytes[4];
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
void ConvertIntegerToBytes_4(DWORD Value, LPBYTE ValueAsBytes)
|
||||
{
|
||||
ValueAsBytes[0] = (Value >> 0x18) & 0xFF;
|
||||
ValueAsBytes[1] = (Value >> 0x10) & 0xFF;
|
||||
ValueAsBytes[2] = (Value >> 0x08) & 0xFF;
|
||||
ValueAsBytes[3] = (Value >> 0x00) & 0xFF;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common fre routine of a CASC blob
|
||||
|
||||
void FreeCascBlob(PQUERY_KEY pBlob)
|
||||
{
|
||||
if(pBlob != NULL)
|
||||
{
|
||||
if(pBlob->pbData != NULL)
|
||||
CASC_FREE(pBlob->pbData);
|
||||
|
||||
pBlob->pbData = NULL;
|
||||
pBlob->cbData = 0;
|
||||
}
|
||||
}
|
||||
363
dep/CascLib/src/CascCommon.h
Normal file
363
dep/CascLib/src/CascCommon.h
Normal file
@@ -0,0 +1,363 @@
|
||||
/*****************************************************************************/
|
||||
/* CascCommon.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of CascCommon.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __CASCCOMMON_H__
|
||||
#define __CASCCOMMON_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compression support
|
||||
|
||||
// Include functions from zlib
|
||||
#ifndef __SYS_ZLIB
|
||||
#include "zlib/zlib.h"
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "CascPort.h"
|
||||
#include "common/Common.h"
|
||||
#include "common/DynamicArray.h"
|
||||
#include "common/Map.h"
|
||||
#include "common/FileStream.h"
|
||||
#include "common/Directory.h"
|
||||
#include "common/ListFile.h"
|
||||
#include "common/DumpContext.h"
|
||||
#include "common/RootHandler.h"
|
||||
|
||||
// Headers from LibTomCrypt
|
||||
#include "libtomcrypt/src/headers/tomcrypt.h"
|
||||
|
||||
// For HashStringJenkins
|
||||
#include "jenkins/lookup.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CascLib private defines
|
||||
|
||||
#define CASC_GAME_HOTS 0x00010000 // Heroes of the Storm
|
||||
#define CASC_GAME_WOW6 0x00020000 // World of Warcraft - Warlords of Draenor
|
||||
#define CASC_GAME_DIABLO3 0x00030000 // Diablo 3 since PTR 2.2.0
|
||||
#define CASC_GAME_OVERWATCH 0x00040000 // Overwatch since PTR 24919
|
||||
#define CASC_GAME_STARCRAFT2 0x00050000 // Starcraft II - Legacy of the Void, since build 38996
|
||||
#define CASC_GAME_STARCRAFT1 0x00060000 // Starcraft 1 (remastered)
|
||||
#define CASC_GAME_MASK 0xFFFF0000 // Mask for getting game ID
|
||||
|
||||
#define CASC_INDEX_COUNT 0x10
|
||||
#define CASC_FILE_KEY_SIZE 0x09 // Size of the file key
|
||||
#define CASC_MAX_DATA_FILES 0x100
|
||||
#define CASC_EXTRA_FILES 0x20 // Number of extra entries to be reserved for additionally inserted files
|
||||
|
||||
#define CASC_SEARCH_HAVE_NAME 0x0001 // Indicated that previous search found a name
|
||||
|
||||
#define BLTE_HEADER_SIGNATURE 0x45544C42 // 'BLTE' header in the data files
|
||||
#define BLTE_HEADER_DELTA 0x1E // Distance of BLTE header from begin of the header area
|
||||
#define MAX_HEADER_AREA_SIZE 0x2A // Length of the file header area
|
||||
|
||||
// File header area in the data.nnn:
|
||||
// BYTE HeaderHash[MD5_HASH_SIZE]; // MD5 of the frame array
|
||||
// DWORD dwFileSize; // Size of the file (see comment before CascGetFileSize for details)
|
||||
// BYTE SomeSize[4]; // Some size (big endian)
|
||||
// BYTE Padding[6]; // Padding (?)
|
||||
// DWORD dwSignature; // Must be "BLTE"
|
||||
// BYTE HeaderSizeAsBytes[4]; // Header size in bytes (big endian)
|
||||
// BYTE MustBe0F; // Must be 0x0F. Optional, only if HeaderSizeAsBytes != 0
|
||||
// BYTE FrameCount[3]; // Frame count (big endian). Optional, only if HeaderSizeAsBytes != 0
|
||||
|
||||
// Prevent problems with CRT "min" and "max" functions,
|
||||
// as they are not defined on all platforms
|
||||
#define CASCLIB_MIN(a, b) ((a < b) ? a : b)
|
||||
#define CASCLIB_MAX(a, b) ((a > b) ? a : b)
|
||||
#define CASCLIB_UNUSED(p) ((void)(p))
|
||||
|
||||
#define CASC_PACKAGE_BUFFER 0x1000
|
||||
|
||||
#ifndef _maxchars
|
||||
#define _maxchars(buff) ((sizeof(buff) / sizeof(buff[0])) - 1)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// In-memory structures
|
||||
// See http://pxr.dk/wowdev/wiki/index.php?title=CASC for more information
|
||||
|
||||
struct TFileStream;
|
||||
|
||||
typedef enum _CBLD_TYPE
|
||||
{
|
||||
CascBuildNone = 0, // No build type found
|
||||
CascBuildInfo, // .build.info
|
||||
CascBuildDb, // .build.db (older storages)
|
||||
} CBLD_TYPE, *PCBLD_TYPE;
|
||||
|
||||
typedef struct _ENCODING_KEY
|
||||
{
|
||||
BYTE Value[MD5_HASH_SIZE]; // MD5 of the file
|
||||
|
||||
} ENCODING_KEY, *PENCODING_KEY;
|
||||
|
||||
typedef struct _CASC_INDEX_ENTRY
|
||||
{
|
||||
BYTE IndexKey[CASC_FILE_KEY_SIZE]; // The first 9 bytes of the encoding key
|
||||
BYTE FileOffsetBE[5]; // Index of data file and offset within (big endian).
|
||||
BYTE FileSizeLE[4]; // Size occupied in the storage file (data.###). See comment before CascGetFileSize for details
|
||||
} CASC_INDEX_ENTRY, *PCASC_INDEX_ENTRY;
|
||||
|
||||
typedef struct _CASC_MAPPING_TABLE
|
||||
{
|
||||
TCHAR * szFileName; // Name of the key mapping file
|
||||
LPBYTE pbFileData; // Pointer to the file data
|
||||
DWORD cbFileData; // Length of the file data
|
||||
BYTE ExtraBytes; // (?) Extra bytes in the key record
|
||||
BYTE SpanSizeBytes; // Size of field with file size
|
||||
BYTE SpanOffsBytes; // Size of field with file offset
|
||||
BYTE KeyBytes; // Size of the file key
|
||||
BYTE SegmentBits; // Number of bits for the file offset (rest is archive index)
|
||||
ULONGLONG MaxFileOffset;
|
||||
|
||||
PCASC_INDEX_ENTRY pIndexEntries; // Sorted array of index entries
|
||||
DWORD nIndexEntries; // Number of index entries
|
||||
|
||||
} CASC_MAPPING_TABLE, *PCASC_MAPPING_TABLE;
|
||||
|
||||
typedef struct _CASC_FILE_FRAME
|
||||
{
|
||||
DWORD FrameArchiveOffset; // Archive file pointer corresponding to the begin of the frame
|
||||
DWORD FrameFileOffset; // File pointer corresponding to the begin of the frame
|
||||
DWORD CompressedSize; // Compressed size of the file
|
||||
DWORD FrameSize; // Size of the frame
|
||||
BYTE md5[MD5_HASH_SIZE]; // MD5 hash of the file sector
|
||||
} CASC_FILE_FRAME, *PCASC_FILE_FRAME;
|
||||
|
||||
// The encoding file is in the form of:
|
||||
// * File header
|
||||
// * String block #1
|
||||
// * Table A header
|
||||
// * Table A entries
|
||||
// * Table B header
|
||||
// * Table B entries
|
||||
// * String block #2
|
||||
// http://pxr.dk/wowdev/wiki/index.php?title=CASC#Key_CASC_Files
|
||||
typedef struct _CASC_ENCODING_HEADER
|
||||
{
|
||||
BYTE Magic[2]; // "EN"
|
||||
BYTE Version; // Expected to be 1 by CascLib
|
||||
BYTE ChecksumSizeA; // The length of the checksums in Encoding Table
|
||||
BYTE ChecksumSizeB; // The length of the checksums in Encoding Layout Table
|
||||
BYTE Flags_TableA[2]; // Flags for Encoding Table
|
||||
BYTE Flags_TableB[2]; // Flags for Encoding Layout Table
|
||||
BYTE Entries_TableA[4]; // Number of segments in Encoding Table (big endian)
|
||||
BYTE Entries_TableB[4]; // Number of segments in Encoding Layout Table (big endian)
|
||||
BYTE field_11;
|
||||
BYTE Size_StringTable1[4]; // Size of the string block #1
|
||||
|
||||
} CASC_ENCODING_HEADER, *PCASC_ENCODING_HEADER;
|
||||
|
||||
typedef struct _CASC_ENCODING_ENTRY
|
||||
{
|
||||
USHORT KeyCount; // Number of index keys
|
||||
BYTE FileSizeBE[4]; // Compressed file size (header area + frame headers + compressed frames), in bytes
|
||||
BYTE EncodingKey[MD5_HASH_SIZE]; // File encoding key
|
||||
|
||||
// Followed by the index keys
|
||||
// (number of items = KeyCount)
|
||||
// Followed by the index keys (number of items = KeyCount)
|
||||
} CASC_ENCODING_ENTRY, *PCASC_ENCODING_ENTRY;
|
||||
|
||||
// A version of CASC_ENCODING_ENTRY with one index key
|
||||
typedef struct _CASC_ENCODING_ENTRY_1
|
||||
{
|
||||
USHORT KeyCount; // Number of index keys
|
||||
BYTE FileSizeBE[4]; // Compressed file size (header area + frame headers + compressed frames), in bytes
|
||||
BYTE EncodingKey[MD5_HASH_SIZE]; // File encoding key
|
||||
BYTE IndexKey[MD5_HASH_SIZE]; // File index key
|
||||
|
||||
} CASC_ENCODING_ENTRY_1, *PCASC_ENCODING_ENTRY_1;
|
||||
|
||||
#define GET_INDEX_KEY(pEncodingEntry) (pEncodingEntry->EncodingKey + MD5_HASH_SIZE)
|
||||
#define FAKE_ENCODING_ENTRY_SIZE (sizeof(CASC_ENCODING_ENTRY) + MD5_HASH_SIZE)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures for CASC storage and CASC file
|
||||
|
||||
typedef struct _TCascStorage
|
||||
{
|
||||
const char * szClassName; // "TCascStorage"
|
||||
const TCHAR * szIndexFormat; // Format of the index file name
|
||||
TCHAR * szRootPath; // This is the game directory
|
||||
TCHAR * szDataPath; // This is the directory where data files are
|
||||
TCHAR * szBuildFile; // Build file name (.build.info or .build.db)
|
||||
TCHAR * szIndexPath; // This is the directory where index files are
|
||||
TCHAR * szUrlPath; // URL to the Blizzard servers
|
||||
DWORD dwRefCount; // Number of references
|
||||
DWORD dwGameInfo; // Game type
|
||||
DWORD dwBuildNumber; // Game build number
|
||||
DWORD dwFileBeginDelta; // This is number of bytes to shift back from archive offset (from index entry) to actual begin of file data
|
||||
DWORD dwDefaultLocale; // Default locale, read from ".build.info"
|
||||
|
||||
CBLD_TYPE BuildFileType; // Type of the build file
|
||||
|
||||
QUERY_KEY CdnConfigKey;
|
||||
QUERY_KEY CdnBuildKey;
|
||||
QUERY_KEY ArchivesGroup; // Key array of the "archive-group"
|
||||
QUERY_KEY ArchivesKey; // Key array of the "archives"
|
||||
QUERY_KEY PatchArchivesKey; // Key array of the "patch-archives"
|
||||
QUERY_KEY PatchArchivesGroup; // Key array of the "patch-archive-group"
|
||||
QUERY_KEY RootKey;
|
||||
QUERY_KEY PatchKey;
|
||||
QUERY_KEY DownloadKey;
|
||||
QUERY_KEY InstallKey;
|
||||
QUERY_KEY EncodingKey;
|
||||
|
||||
TFileStream * DataFileArray[CASC_MAX_DATA_FILES]; // Data file handles
|
||||
|
||||
CASC_MAPPING_TABLE KeyMapping[CASC_INDEX_COUNT]; // Key mapping
|
||||
PCASC_MAP pIndexEntryMap; // Map of index entries
|
||||
|
||||
QUERY_KEY EncodingFile; // Content of the ENCODING file
|
||||
PCASC_MAP pEncodingMap; // Map of encoding entries
|
||||
DYNAMIC_ARRAY ExtraEntries; // Extra encoding entries
|
||||
|
||||
TRootHandler * pRootHandler; // Common handler for various ROOT file formats
|
||||
|
||||
} TCascStorage;
|
||||
|
||||
typedef struct _TCascFile
|
||||
{
|
||||
TCascStorage * hs; // Pointer to storage structure
|
||||
TFileStream * pStream; // An open data stream
|
||||
const char * szClassName; // "TCascFile"
|
||||
|
||||
DWORD FilePointer; // Current file pointer
|
||||
|
||||
DWORD ArchiveIndex; // Index of the archive (data.###)
|
||||
DWORD HeaderOffset; // Offset of the BLTE header, relative to the begin of the archive
|
||||
DWORD HeaderSize; // Length of the BLTE header
|
||||
DWORD FramesOffset; // Offset of the frame data, relative to the begin of the archive
|
||||
DWORD CompressedSize; // Compressed size of the file (in bytes)
|
||||
DWORD FileSize; // Size of file, in bytes
|
||||
BYTE FrameArrayHash[MD5_HASH_SIZE]; // MD5 hash of the frame array
|
||||
|
||||
PCASC_FILE_FRAME pFrames; // Array of file frames
|
||||
DWORD FrameCount; // Number of the file frames
|
||||
|
||||
LPBYTE pbFileCache; // Pointer to file cache
|
||||
DWORD cbFileCache; // Size of the file cache
|
||||
DWORD CacheStart; // Starting offset in the cache
|
||||
DWORD CacheEnd; // Ending offset in the cache
|
||||
|
||||
#ifdef CASCLIB_TEST // Extra fields for analyzing the file size problem
|
||||
DWORD FileSize_RootEntry; // File size, from the root entry
|
||||
DWORD FileSize_EncEntry; // File size, from the encoding entry
|
||||
DWORD FileSize_IdxEntry; // File size, from the index entry
|
||||
DWORD FileSize_HdrArea; // File size, as stated in the file header area
|
||||
DWORD FileSize_FrameSum; // File size as sum of frame sizes
|
||||
#endif
|
||||
|
||||
} TCascFile;
|
||||
|
||||
typedef struct _TCascSearch
|
||||
{
|
||||
TCascStorage * hs; // Pointer to the storage handle
|
||||
const char * szClassName; // Contains "TCascSearch"
|
||||
TCHAR * szListFile; // Name of the listfile
|
||||
void * pCache; // Listfile cache
|
||||
char * szMask; // Search mask
|
||||
char szFileName[MAX_PATH]; // Buffer for the file name
|
||||
|
||||
// Provider-specific data
|
||||
void * pRootContext; // Root-specific search context
|
||||
size_t IndexLevel1; // Root-specific search context
|
||||
size_t IndexLevel2; // Root-specific search context
|
||||
DWORD dwState; // Pointer to the search state (0 = listfile, 1 = nameless, 2 = done)
|
||||
|
||||
BYTE BitArray[1]; // Bit array of encoding keys. Set for each entry that has already been reported
|
||||
|
||||
} TCascSearch;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory management
|
||||
//
|
||||
// We use our own macros for allocating/freeing memory. If you want
|
||||
// to redefine them, please keep the following rules:
|
||||
//
|
||||
// - The memory allocation must return NULL if not enough memory
|
||||
// (i.e not to throw exception)
|
||||
// - The allocating function does not need to fill the allocated buffer with zeros
|
||||
// - The reallocating function must support NULL as the previous block
|
||||
// - Memory freeing function doesn't have to test the pointer to NULL
|
||||
//
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
|
||||
#define CASC_REALLOC(type, ptr, count) (type *)HeapReAlloc(GetProcessHeap(), 0, ptr, ((count) * sizeof(type)))
|
||||
#define CASC_ALLOC(type, count) (type *)HeapAlloc(GetProcessHeap(), 0, ((count) * sizeof(type)))
|
||||
#define CASC_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr)
|
||||
|
||||
#else
|
||||
|
||||
#define CASC_REALLOC(type, ptr, count) (type *)realloc(ptr, (count) * sizeof(type))
|
||||
#define CASC_ALLOC(type, count) (type *)malloc((count) * sizeof(type))
|
||||
#define CASC_FREE(ptr) free(ptr)
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Big endian number manipulation
|
||||
|
||||
DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes);
|
||||
DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes);
|
||||
DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes);
|
||||
ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes);
|
||||
|
||||
void ConvertIntegerToBytes_4(DWORD Value, LPBYTE ValueAsBytes);
|
||||
void FreeCascBlob(PQUERY_KEY pQueryKey);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Text file parsing (CascFiles.cpp)
|
||||
|
||||
int LoadBuildInfo(TCascStorage * hs);
|
||||
int CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory);
|
||||
|
||||
int GetRootVariableIndex(const char * szLinePtr, const char * szLineEnd, const char * szVariableName, int * PtrIndex);
|
||||
int ParseRootFileLine(const char * szLinePtr, const char * szLineEnd, int nFileNameIndex, PQUERY_KEY pEncodingKey, char * szFileName, size_t nMaxChars);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal file functions
|
||||
|
||||
TCascStorage * IsValidStorageHandle(HANDLE hStorage);
|
||||
TCascFile * IsValidFileHandle(HANDLE hFile);
|
||||
|
||||
PCASC_ENCODING_ENTRY FindEncodingEntry(TCascStorage * hs, PQUERY_KEY pEncodingKey, PDWORD PtrIndex);
|
||||
PCASC_INDEX_ENTRY FindIndexEntry(TCascStorage * hs, PQUERY_KEY pIndexKey);
|
||||
|
||||
int CascDecompress(LPBYTE pvOutBuffer, PDWORD pcbOutBuffer, LPBYTE pvInBuffer, DWORD cbInBuffer);
|
||||
int CascDecrypt (LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex);
|
||||
int CascDirectCopy(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for ROOT file
|
||||
|
||||
int RootHandler_CreateMNDX(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
|
||||
int RootHandler_CreateDiablo3(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
|
||||
int RootHandler_CreateOverwatch(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
|
||||
int RootHandler_CreateWoW6(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile, DWORD dwLocaleMask);
|
||||
int RootHandler_CreateSC1(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dumping CASC data structures
|
||||
|
||||
#ifdef _DEBUG
|
||||
void CascDumpSparseArray(const char * szFileName, void * pvSparseArray);
|
||||
void CascDumpNameFragTable(const char * szFileName, void * pvMarFile);
|
||||
void CascDumpFileNames(const char * szFileName, void * pvMarFile);
|
||||
void CascDumpIndexEntries(const char * szFileName, TCascStorage * hs);
|
||||
void CascDumpEncodingEntry(TCascStorage * hs, TDumpContext * dc, PCASC_ENCODING_ENTRY pEncodingEntry, int nDumpLevel);
|
||||
void CascDumpFile(const char * szFileName, HANDLE hFile);
|
||||
#endif // _DEBUG
|
||||
|
||||
#endif // __CASCCOMMON_H__
|
||||
46
dep/CascLib/src/CascDecompress.cpp
Normal file
46
dep/CascLib/src/CascDecompress.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*****************************************************************************/
|
||||
/* CascDecompress.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Decompression functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 02.05.14 1.00 Lad The first version of CascDecompress.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int CascDecompress(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer)
|
||||
{
|
||||
z_stream z; // Stream information for zlib
|
||||
int nResult;
|
||||
|
||||
// Fill the stream structure for zlib
|
||||
z.next_in = pbInBuffer;
|
||||
z.avail_in = cbInBuffer;
|
||||
z.total_in = cbInBuffer;
|
||||
z.next_out = pbOutBuffer;
|
||||
z.avail_out = *pcbOutBuffer;
|
||||
z.total_out = 0;
|
||||
z.zalloc = NULL;
|
||||
z.zfree = NULL;
|
||||
|
||||
// Initialize the decompression structure
|
||||
if((nResult = inflateInit(&z)) == Z_OK)
|
||||
{
|
||||
// Call zlib to decompress the data
|
||||
nResult = inflate(&z, Z_NO_FLUSH);
|
||||
inflateEnd(&z);
|
||||
|
||||
// Give the size of the uncompressed data
|
||||
*pcbOutBuffer = z.total_out;
|
||||
}
|
||||
|
||||
// Return an error code
|
||||
return (nResult == Z_OK || nResult == Z_STREAM_END) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
|
||||
}
|
||||
394
dep/CascLib/src/CascDecrypt.cpp
Normal file
394
dep/CascLib/src/CascDecrypt.cpp
Normal file
@@ -0,0 +1,394 @@
|
||||
/*****************************************************************************/
|
||||
/* CascDecrypt.cpp Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Decryption functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 31.10.15 1.00 Lad The first version of CascDecrypt.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures
|
||||
|
||||
typedef struct _CASC_ENCRYPTION_KEY
|
||||
{
|
||||
ULONGLONG KeyName; // "Name" of the key
|
||||
BYTE Key[0x10]; // The key itself
|
||||
} CASC_ENCRYPTION_KEY, *PCASC_ENCRYPTION_KEY;
|
||||
|
||||
typedef struct _CASC_SALSA20
|
||||
{
|
||||
DWORD Key[0x10];
|
||||
DWORD dwRounds;
|
||||
|
||||
} CASC_SALSA20, *PCASC_SALSA20;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Known encryption keys. See https://wowdev.wiki/CASC for updates
|
||||
|
||||
static CASC_ENCRYPTION_KEY CascKeys[] =
|
||||
{
|
||||
// Key Name Encryption key Seen in
|
||||
// ---------------------- ------------------------------------------------------------------------------------------------ -----------
|
||||
|
||||
// Battle.net app
|
||||
{ 0x2C547F26A2613E01ULL, { 0x37, 0xC5, 0x0C, 0x10, 0x2D, 0x4C, 0x9E, 0x3A, 0x5A, 0xC0, 0x69, 0xF0, 0x72, 0xB1, 0x41, 0x7D } }, // Battle.net App Alpha 1.5.0
|
||||
|
||||
// Overwatch
|
||||
{ 0xFB680CB6A8BF81F3ULL, { 0x62, 0xD9, 0x0E, 0xFA, 0x7F, 0x36, 0xD7, 0x1C, 0x39, 0x8A, 0xE2, 0xF1, 0xFE, 0x37, 0xBD, 0xB9 } }, // 0.8.0.24919_retailx64 (hardcoded)
|
||||
{ 0x402CD9D8D6BFED98ULL, { 0xAE, 0xB0, 0xEA, 0xDE, 0xA4, 0x76, 0x12, 0xFE, 0x6C, 0x04, 0x1A, 0x03, 0x95, 0x8D, 0xF2, 0x41 } }, // 0.8.0.24919_retailx64 (hardcoded)
|
||||
{ 0xDBD3371554F60306ULL, { 0x34, 0xE3, 0x97, 0xAC, 0xE6, 0xDD, 0x30, 0xEE, 0xFD, 0xC9, 0x8A, 0x2A, 0xB0, 0x93, 0xCD, 0x3C } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0x11A9203C9881710AULL, { 0x2E, 0x2C, 0xB8, 0xC3, 0x97, 0xC2, 0xF2, 0x4E, 0xD0, 0xB5, 0xE4, 0x52, 0xF1, 0x8D, 0xC2, 0x67 } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0xA19C4F859F6EFA54ULL, { 0x01, 0x96, 0xCB, 0x6F, 0x5E, 0xCB, 0xAD, 0x7C, 0xB5, 0x28, 0x38, 0x91, 0xB9, 0x71, 0x2B, 0x4B } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0x87AEBBC9C4E6B601ULL, { 0x68, 0x5E, 0x86, 0xC6, 0x06, 0x3D, 0xFD, 0xA6, 0xC9, 0xE8, 0x52, 0x98, 0x07, 0x6B, 0x3D, 0x42 } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0xDEE3A0521EFF6F03ULL, { 0xAD, 0x74, 0x0C, 0xE3, 0xFF, 0xFF, 0x92, 0x31, 0x46, 0x81, 0x26, 0x98, 0x57, 0x08, 0xE1, 0xB9 } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0x8C9106108AA84F07ULL, { 0x53, 0xD8, 0x59, 0xDD, 0xA2, 0x63, 0x5A, 0x38, 0xDC, 0x32, 0xE7, 0x2B, 0x11, 0xB3, 0x2F, 0x29 } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0x49166D358A34D815ULL, { 0x66, 0x78, 0x68, 0xCD, 0x94, 0xEA, 0x01, 0x35, 0xB9, 0xB1, 0x6C, 0x93, 0xB1, 0x12, 0x4A, 0xBA } }, // 0.8.0.24919_retailx64 (streamed from server)
|
||||
{ 0x1463A87356778D14ULL, { 0x69, 0xBD, 0x2A, 0x78, 0xD0, 0x5C, 0x50, 0x3E, 0x93, 0x99, 0x49, 0x59, 0xB3, 0x0E, 0x5A, 0xEC } }, // ? 1.0.3.0 (streamed from server)
|
||||
{ 0x5E152DE44DFBEE01ULL, { 0xE4, 0x5A, 0x17, 0x93, 0xB3, 0x7E, 0xE3, 0x1A, 0x8E, 0xB8, 0x5C, 0xEE, 0x0E, 0xEE, 0x1B, 0x68 } }, // ? 1.0.3.0 (streamed from server)
|
||||
{ 0x9B1F39EE592CA415ULL, { 0x54, 0xA9, 0x9F, 0x08, 0x1C, 0xAD, 0x0D, 0x08, 0xF7, 0xE3, 0x36, 0xF4, 0x36, 0x8E, 0x89, 0x4C } }, // ? 1.0.3.0 (streamed from server)
|
||||
{ 0x24C8B75890AD5917ULL, { 0x31, 0x10, 0x0C, 0x00, 0xFD, 0xE0, 0xCE, 0x18, 0xBB, 0xB3, 0x3F, 0x3A, 0xC1, 0x5B, 0x30, 0x9F } }, // ? 1.0.3.0 (included in game)
|
||||
{ 0xEA658B75FDD4890FULL, { 0xDE, 0xC7, 0xA4, 0xE7, 0x21, 0xF4, 0x25, 0xD1, 0x33, 0x03, 0x98, 0x95, 0xC3, 0x60, 0x36, 0xF8 } }, // ? 1.0.3.0 (included in game)
|
||||
{ 0x026FDCDF8C5C7105ULL, { 0x8F, 0x41, 0x80, 0x9D, 0xA5, 0x53, 0x66, 0xAD, 0x41, 0x6D, 0x3C, 0x33, 0x74, 0x59, 0xEE, 0xE3 } }, // (included in game)
|
||||
{ 0xCAE3FAC925F20402ULL, { 0x98, 0xB7, 0x8E, 0x87, 0x74, 0xBF, 0x27, 0x50, 0x93, 0xCB, 0x1B, 0x5F, 0xC7, 0x14, 0x51, 0x1B } }, // (included in game)
|
||||
{ 0x061581CA8496C80CULL, { 0xDA, 0x2E, 0xF5, 0x05, 0x2D, 0xB9, 0x17, 0x38, 0x0B, 0x8A, 0xA6, 0xEF, 0x7A, 0x5F, 0x8E, 0x6A } }, //
|
||||
{ 0xBE2CB0FAD3698123ULL, { 0x90, 0x2A, 0x12, 0x85, 0x83, 0x6C, 0xE6, 0xDA, 0x58, 0x95, 0x02, 0x0D, 0xD6, 0x03, 0xB0, 0x65 } }, //
|
||||
{ 0x57A5A33B226B8E0AULL, { 0xFD, 0xFC, 0x35, 0xC9, 0x9B, 0x9D, 0xB1, 0x1A, 0x32, 0x62, 0x60, 0xCA, 0x24, 0x6A, 0xCB, 0x41 } }, // 1.1.0.0.30200 Ana
|
||||
{ 0x42B9AB1AF5015920ULL, { 0xC6, 0x87, 0x78, 0x82, 0x3C, 0x96, 0x4C, 0x6F, 0x24, 0x7A, 0xCC, 0x0F, 0x4A, 0x25, 0x84, 0xF8 } }, // 1.2.0.1.30684 Summer Games
|
||||
{ 0x4F0FE18E9FA1AC1AULL, { 0x89, 0x38, 0x1C, 0x74, 0x8F, 0x65, 0x31, 0xBB, 0xFC, 0xD9, 0x77, 0x53, 0xD0, 0x6C, 0xC3, 0xCD } }, // 1.2.0.1.30684
|
||||
{ 0x7758B2CF1E4E3E1BULL, { 0x3D, 0xE6, 0x0D, 0x37, 0xC6, 0x64, 0x72, 0x35, 0x95, 0xF2, 0x7C, 0x5C, 0xDB, 0xF0, 0x8B, 0xFA } }, // 1.2.0.1.30684
|
||||
{ 0xE5317801B3561125ULL, { 0x7D, 0xD0, 0x51, 0x19, 0x9F, 0x84, 0x01, 0xF9, 0x5E, 0x4C, 0x03, 0xC8, 0x84, 0xDC, 0xEA, 0x33 } }, // 1.4.0.2.32143 Halloween Terror
|
||||
{ 0x16B866D7BA3A8036ULL, { 0x13, 0x95, 0xE8, 0x82, 0xBF, 0x25, 0xB4, 0x81, 0xF6, 0x1A, 0x4D, 0x62, 0x11, 0x41, 0xDA, 0x6E } }, // 1.4.1.0.31804 Bastion Blizzcon 2016 skin
|
||||
{ 0x11131FFDA0D18D30ULL, { 0xC3, 0x2A, 0xD1, 0xB8, 0x25, 0x28, 0xE0, 0xA4, 0x56, 0x89, 0x7B, 0x3C, 0xE1, 0xC2, 0xD2, 0x7E } }, // 1.5.0.1.32795 Sombra
|
||||
{ 0xCAC6B95B2724144AULL, { 0x73, 0xE4, 0xBE, 0xA1, 0x45, 0xDF, 0x2B, 0x89, 0xB6, 0x5A, 0xEF, 0x02, 0xF8, 0x3F, 0xA2, 0x60 } }, // 1.5.0.1.32795 Ecopoint: Antarctica
|
||||
{ 0xB7DBC693758A5C36ULL, { 0xBC, 0x3A, 0x92, 0xBF, 0xE3, 0x02, 0x51, 0x8D, 0x91, 0xCC, 0x30, 0x79, 0x06, 0x71, 0xBF, 0x10 } }, // 1.5.0.1.32795 Genji Oni skin
|
||||
{ 0x90CA73B2CDE3164BULL, { 0x5C, 0xBF, 0xF1, 0x1F, 0x22, 0x72, 0x0B, 0xAC, 0xC2, 0xAE, 0x6A, 0xAD, 0x8F, 0xE5, 0x33, 0x17 } }, // 1.6.1.0.33236 Oasis map
|
||||
{ 0x6DD3212FB942714AULL, { 0xE0, 0x2C, 0x16, 0x43, 0x60, 0x2E, 0xC1, 0x6C, 0x3A, 0xE2, 0xA4, 0xD2, 0x54, 0xA0, 0x8F, 0xD9 } }, // 1.6.1.0.33236
|
||||
{ 0x11DDB470ABCBA130ULL, { 0x66, 0x19, 0x87, 0x66, 0xB1, 0xC4, 0xAF, 0x75, 0x89, 0xEF, 0xD1, 0x3A, 0xD4, 0xDD, 0x66, 0x7A } }, // 1.6.1.0.33236 Winter Wonderland
|
||||
{ 0x5BEF27EEE95E0B4BULL, { 0x36, 0xBC, 0xD2, 0xB5, 0x51, 0xFF, 0x1C, 0x84, 0xAA, 0x3A, 0x39, 0x94, 0xCC, 0xEB, 0x03, 0x3E } }, //
|
||||
{ 0x9359B46E49D2DA42ULL, { 0x17, 0x3D, 0x65, 0xE7, 0xFC, 0xAE, 0x29, 0x8A, 0x93, 0x63, 0xBD, 0x6A, 0xA1, 0x89, 0xF2, 0x00 } }, // Diablo's 20th anniversary
|
||||
{ 0x1A46302EF8896F34ULL, { 0x80, 0x29, 0xAD, 0x54, 0x51, 0xD4, 0xBC, 0x18, 0xE9, 0xD0, 0xF5, 0xAC, 0x44, 0x9D, 0xC0, 0x55 } }, // 1.7.0.2.34156 Year of the Rooster
|
||||
{ 0x693529F7D40A064CULL, { 0xCE, 0x54, 0x87, 0x3C, 0x62, 0xDA, 0xA4, 0x8E, 0xFF, 0x27, 0xFC, 0xC0, 0x32, 0xBD, 0x07, 0xE3 } }, // 1.8.0.0.34470 CTF Maps
|
||||
{ 0x388B85AEEDCB685DULL, { 0xD9, 0x26, 0xE6, 0x59, 0xD0, 0x4A, 0x09, 0x6B, 0x24, 0xC1, 0x91, 0x51, 0x07, 0x6D, 0x37, 0x9A } }, // 1.8.0.0.34470 Numbani Update (Doomfist teaser)
|
||||
{ 0xE218F69AAC6C104DULL, { 0xF4, 0x3D, 0x12, 0xC9, 0x4A, 0x9A, 0x52, 0x84, 0x97, 0x97, 0x1F, 0x1C, 0xBE, 0x41, 0xAD, 0x4D } }, // 1.9.0.0.34986 Orisa
|
||||
{ 0xF432F0425363F250ULL, { 0xBA, 0x69, 0xF2, 0xB3, 0x3C, 0x27, 0x68, 0xF5, 0xF2, 0x9B, 0xFE, 0x78, 0xA5, 0xA1, 0xFA, 0xD5 } }, // 1.10.0.0.35455 Uprising
|
||||
{ 0x061D52F86830B35DULL, { 0xD7, 0x79, 0xF9, 0xC6, 0xCC, 0x9A, 0x4B, 0xE1, 0x03, 0xA4, 0xE9, 0x0A, 0x73, 0x38, 0xF7, 0x93 } }, // 1.10.0.0.35455 D.Va Officer Skin (HotS Nexus Challenge 2)
|
||||
{ 0x1275C84CF113EF65ULL, { 0xCF, 0x58, 0xB6, 0x93, 0x3E, 0xAF, 0x98, 0xAF, 0x53, 0xE7, 0x6F, 0x84, 0x26, 0xCC, 0x7E, 0x6C } }, //
|
||||
{ 0xD9C7C7AC0F14C868ULL, { 0x3A, 0xFD, 0xF6, 0x8E, 0x3A, 0x5D, 0x63, 0xBA, 0xBA, 0x1E, 0x68, 0x21, 0x88, 0x3F, 0x06, 0x7D } }, //
|
||||
{ 0xBD4E42661A432951ULL, { 0x6D, 0xE8, 0xE2, 0x8C, 0x85, 0x11, 0x64, 0x4D, 0x55, 0x95, 0xFC, 0x45, 0xE5, 0x35, 0x14, 0x72 } }, // 1.11.0.0.36376 Anniversary event
|
||||
{ 0xC43CB14355249451ULL, { 0x0E, 0xA2, 0xB4, 0x4F, 0x96, 0xA2, 0x69, 0xA3, 0x86, 0x85, 0x6D, 0x04, 0x9A, 0x3D, 0xEC, 0x86 } }, // 1.12.0.0.37104 Horizon Lunar Colony
|
||||
{ 0xE6D914F8E4744953ULL, { 0xC8, 0x47, 0x7C, 0x28, 0x9D, 0xCE, 0x66, 0xD9, 0x13, 0x65, 0x07, 0xA3, 0x3A, 0xA3, 0x33, 0x01 } }, // 1.13.0.0.37646 Doomfist
|
||||
{ 0x5694C503F8C80178ULL, { 0x7F, 0x4C, 0xF1, 0xC1, 0xFB, 0xBA, 0xD9, 0x2B, 0x18, 0x43, 0x36, 0xD6, 0x77, 0xEB, 0xF9, 0x37 } }, // 1.13.0.0.37646 Doomfist
|
||||
{ 0x21DBFD65F3E54269ULL, { 0xAB, 0x58, 0x0C, 0x38, 0x37, 0xCA, 0xF8, 0xA4, 0x61, 0xF2, 0x43, 0xA5, 0x66, 0xB2, 0xAE, 0x4D } }, // 1.13.0.0.37646 Summer Games 2017
|
||||
// { 0x27ABA5F88DD8D078ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 1.13.0.0.37646
|
||||
{ 0x21E1F90E71D33C71ULL, { 0x32, 0x87, 0x42, 0x33, 0x91, 0x62, 0xB3, 0x26, 0x76, 0xC8, 0x03, 0xC2, 0x25, 0x59, 0x31, 0xA6 } }, // 1.14.1.0.39083 Deathmatch
|
||||
{ 0xD9CB055BCDD40B6EULL, { 0x49, 0xFB, 0x44, 0x77, 0xA4, 0xA0, 0x82, 0x53, 0x27, 0xE9, 0xA7, 0x36, 0x82, 0xBE, 0xCD, 0x0C } }, // 1.15.0.0.????? Junkertown
|
||||
{ 0x8175CE3C694C6659ULL, { 0xE3, 0xF3, 0xFA, 0x77, 0x26, 0xC7, 0x0D, 0x26, 0xAE, 0x13, 0x0D, 0x96, 0x9D, 0xDD, 0xF3, 0x99 } }, // 1.16.0.0.40011 Halloween 2017
|
||||
{ 0xB8DE51690075435AULL, { 0xC0, 0x7E, 0x92, 0x60, 0xBB, 0x71, 0x12, 0x17, 0xE7, 0xDE, 0x6F, 0xED, 0x91, 0x1F, 0x42, 0x96 } }, // 1.16.0.0.????? Winston Blizzcon 2017 skin
|
||||
{ 0xF6CF23955B5D437DULL, { 0xAE, 0xBA, 0x22, 0x73, 0x28, 0xA5, 0xB0, 0xAA, 0x9F, 0x51, 0xDA, 0xE3, 0xF6, 0xA7, 0xDF, 0xE4 } }, // 1.17.0.2.41350 Moira
|
||||
|
||||
// Streamed WoW keys
|
||||
{ 0xFA505078126ACB3EULL, { 0xBD, 0xC5, 0x18, 0x62, 0xAB, 0xED, 0x79, 0xB2, 0xDE, 0x48, 0xC8, 0xE7, 0xE6, 0x6C, 0x62, 0x00 } }, // 15 WOW-20740patch7.0.1_Beta
|
||||
{ 0xFF813F7D062AC0BCULL, { 0xAA, 0x0B, 0x5C, 0x77, 0xF0, 0x88, 0xCC, 0xC2, 0xD3, 0x90, 0x49, 0xBD, 0x26, 0x7F, 0x06, 0x6D } }, // 25 WOW-20740patch7.0.1_Beta
|
||||
{ 0xD1E9B5EDF9283668ULL, { 0x8E, 0x4A, 0x25, 0x79, 0x89, 0x4E, 0x38, 0xB4, 0xAB, 0x90, 0x58, 0xBA, 0x5C, 0x73, 0x28, 0xEE } }, // 39 WOW-20740patch7.0.1_Beta Enchanted Torch pet
|
||||
{ 0xB76729641141CB34ULL, { 0x98, 0x49, 0xD1, 0xAA, 0x7B, 0x1F, 0xD0, 0x98, 0x19, 0xC5, 0xC6, 0x62, 0x83, 0xA3, 0x26, 0xEC } }, // 40 WOW-20740patch7.0.1_Beta Enchanted Pen pet
|
||||
{ 0xFFB9469FF16E6BF8ULL, { 0xD5, 0x14, 0xBD, 0x19, 0x09, 0xA9, 0xE5, 0xDC, 0x87, 0x03, 0xF4, 0xB8, 0xBB, 0x1D, 0xFD, 0x9A } }, // 41 WOW-20740patch7.0.1_Beta
|
||||
{ 0x23C5B5DF837A226CULL, { 0x14, 0x06, 0xE2, 0xD8, 0x73, 0xB6, 0xFC, 0x99, 0x21, 0x7A, 0x18, 0x08, 0x81, 0xDA, 0x8D, 0x62 } }, // 42 WOW-20740patch7.0.1_Beta Enchanted Cauldron pet
|
||||
// {0x3AE403EF40AC3037ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 51 WOW-21249patch7.0.3_Beta
|
||||
{ 0xE2854509C471C554ULL, { 0x43, 0x32, 0x65, 0xF0, 0xCD, 0xEB, 0x2F, 0x4E, 0x65, 0xC0, 0xEE, 0x70, 0x08, 0x71, 0x4D, 0x9E } }, // 52 WOW-21249patch7.0.3_Beta Warcraft movie items
|
||||
{ 0x8EE2CB82178C995AULL, { 0xDA, 0x6A, 0xFC, 0x98, 0x9E, 0xD6, 0xCA, 0xD2, 0x79, 0x88, 0x59, 0x92, 0xC0, 0x37, 0xA8, 0xEE } }, // 55 WOW-21531patch7.0.3_Beta BlizzCon 2016 Murlocs
|
||||
{ 0x5813810F4EC9B005ULL, { 0x01, 0xBE, 0x8B, 0x43, 0x14, 0x2D, 0xD9, 0x9A, 0x9E, 0x69, 0x0F, 0xAD, 0x28, 0x8B, 0x60, 0x82 } }, // 56 WOW-21531patch7.0.3_Beta Fel Kitten
|
||||
{ 0x7F9E217166ED43EAULL, { 0x05, 0xFC, 0x92, 0x7B, 0x9F, 0x4F, 0x5B, 0x05, 0x56, 0x81, 0x42, 0x91, 0x2A, 0x05, 0x2B, 0x0F } }, // 57 WOW-21531patch7.0.3_Beta Legion music
|
||||
{ 0xC4A8D364D23793F7ULL, { 0xD1, 0xAC, 0x20, 0xFD, 0x14, 0x95, 0x7F, 0xAB, 0xC2, 0x71, 0x96, 0xE9, 0xF6, 0xE7, 0x02, 0x4A } }, // 58 WOW-21691patch7.0.3_Beta Demon Hunter #1 cinematic (legion_dh1)
|
||||
{ 0x40A234AEBCF2C6E5ULL, { 0xC6, 0xC5, 0xF6, 0xC7, 0xF7, 0x35, 0xD7, 0xD9, 0x4C, 0x87, 0x26, 0x7F, 0xA4, 0x99, 0x4D, 0x45 } }, // 59 WOW-21691patch7.0.3_Beta Demon Hunter #2 cinematic (legion_dh2)
|
||||
{ 0x9CF7DFCFCBCE4AE5ULL, { 0x72, 0xA9, 0x7A, 0x24, 0xA9, 0x98, 0xE3, 0xA5, 0x50, 0x0F, 0x38, 0x71, 0xF3, 0x76, 0x28, 0xC0 } }, // 60 WOW-21691patch7.0.3_Beta Val'sharah #1 cinematic (legion_val_yd)
|
||||
{ 0x4E4BDECAB8485B4FULL, { 0x38, 0x32, 0xD7, 0xC4, 0x2A, 0xAC, 0x92, 0x68, 0xF0, 0x0B, 0xE7, 0xB6, 0xB4, 0x8E, 0xC9, 0xAF } }, // 61 WOW-21691patch7.0.3_Beta Val'sharah #2 cinematic (legion_val_yx)
|
||||
{ 0x94A50AC54EFF70E4ULL, { 0xC2, 0x50, 0x1A, 0x72, 0x65, 0x4B, 0x96, 0xF8, 0x63, 0x50, 0xC5, 0xA9, 0x27, 0x96, 0x2F, 0x7A } }, // 62 WOW-21691patch7.0.3_Beta Sylvanas warchief cinematic (legion_org_vs)
|
||||
{ 0xBA973B0E01DE1C2CULL, { 0xD8, 0x3B, 0xBC, 0xB4, 0x6C, 0xC4, 0x38, 0xB1, 0x7A, 0x48, 0xE7, 0x6C, 0x4F, 0x56, 0x54, 0xA3 } }, // 63 WOW-21691patch7.0.3_Beta Stormheim Sylvanas vs Greymane cinematic (legion_sth)
|
||||
{ 0x494A6F8E8E108BEFULL, { 0xF0, 0xFD, 0xE1, 0xD2, 0x9B, 0x27, 0x4F, 0x6E, 0x7D, 0xBD, 0xB7, 0xFF, 0x81, 0x5F, 0xE9, 0x10 } }, // 64 WOW-21691patch7.0.3_Beta Harbingers Gul'dan video (legion_hrb_g)
|
||||
{ 0x918D6DD0C3849002ULL, { 0x85, 0x70, 0x90, 0xD9, 0x26, 0xBB, 0x28, 0xAE, 0xDA, 0x4B, 0xF0, 0x28, 0xCA, 0xCC, 0x4B, 0xA3 } }, // 65 WOW-21691patch7.0.3_Beta Harbingers Khadgar video (legion_hrb_k)
|
||||
{ 0x0B5F6957915ADDCAULL, { 0x4D, 0xD0, 0xDC, 0x82, 0xB1, 0x01, 0xC8, 0x0A, 0xBA, 0xC0, 0xA4, 0xD5, 0x7E, 0x67, 0xF8, 0x59 } }, // 66 WOW-21691patch7.0.3_Beta Harbingers Illidan video (legion_hrb_i)
|
||||
{ 0x794F25C6CD8AB62BULL, { 0x76, 0x58, 0x3B, 0xDA, 0xCD, 0x52, 0x57, 0xA3, 0xF7, 0x3D, 0x15, 0x98, 0xA2, 0xCA, 0x2D, 0x99 } }, // 67 WOW-21846patch7.0.3_Beta Suramar cinematic (legion_su_i)
|
||||
{ 0xA9633A54C1673D21ULL, { 0x1F, 0x8D, 0x46, 0x7F, 0x5D, 0x6D, 0x41, 0x1F, 0x8A, 0x54, 0x8B, 0x63, 0x29, 0xA5, 0x08, 0x7E } }, // 68 WOW-21846patch7.0.3_Beta legion_su_r cinematic
|
||||
{ 0x5E5D896B3E163DEAULL, { 0x8A, 0xCE, 0x8D, 0xB1, 0x69, 0xE2, 0xF9, 0x8A, 0xC3, 0x6A, 0xD5, 0x2C, 0x08, 0x8E, 0x77, 0xC1 } }, // 69 WOW-21846patch7.0.3_Beta Broken Shore intro cinematic (legion_bs_i)
|
||||
{ 0x0EBE36B5010DFD7FULL, { 0x9A, 0x89, 0xCC, 0x7E, 0x3A, 0xCB, 0x29, 0xCF, 0x14, 0xC6, 0x0B, 0xC1, 0x3B, 0x1E, 0x46, 0x16 } }, // 70 WOW-21846patch7.0.3_Beta Alliance Broken Shore cinematic (legion_bs_a)
|
||||
{ 0x01E828CFFA450C0FULL, { 0x97, 0x2B, 0x6E, 0x74, 0x42, 0x0E, 0xC5, 0x19, 0xE6, 0xF9, 0xD9, 0x7D, 0x59, 0x4A, 0xA3, 0x7C } }, // 71 WOW-21846patch7.0.3_Beta Horde Broken Shore cinematic (legion_bs_h)
|
||||
{ 0x4A7BD170FE18E6AEULL, { 0xAB, 0x55, 0xAE, 0x1B, 0xF0, 0xC7, 0xC5, 0x19, 0xAF, 0xF0, 0x28, 0xC1, 0x56, 0x10, 0xA4, 0x5B } }, // 72 WOW-21846patch7.0.3_Beta Khadgar & Light's Heart cinematic (legion_iq_lv)
|
||||
{ 0x69549CB975E87C4FULL, { 0x7B, 0x6F, 0xA3, 0x82, 0xE1, 0xFA, 0xD1, 0x46, 0x5C, 0x85, 0x1E, 0x3F, 0x47, 0x34, 0xA1, 0xB3 } }, // 73 WOW-21846patch7.0.3_Beta legion_iq_id cinematic
|
||||
{ 0x460C92C372B2A166ULL, { 0x94, 0x6D, 0x56, 0x59, 0xF2, 0xFA, 0xF3, 0x27, 0xC0, 0xB7, 0xEC, 0x82, 0x8B, 0x74, 0x8A, 0xDB } }, // 74 WOW-21952patch7.0.3_Beta Stormheim Alliance cinematic (legion_g_a_sth)
|
||||
{ 0x8165D801CCA11962ULL, { 0xCD, 0x0C, 0x0F, 0xFA, 0xAD, 0x93, 0x63, 0xEC, 0x14, 0xDD, 0x25, 0xEC, 0xDD, 0x2A, 0x5B, 0x62 } }, // 75 WOW-21952patch7.0.3_Beta Stormheim Horde cinematic (legion_g_h_sth)
|
||||
{ 0xA3F1C999090ADAC9ULL, { 0xB7, 0x2F, 0xEF, 0x4A, 0x01, 0x48, 0x8A, 0x88, 0xFF, 0x02, 0x28, 0x0A, 0xA0, 0x7A, 0x92, 0xBB } }, // 81 WOW-22578patch7.1.0_PTR Firecat Mount
|
||||
// {0x18AFDF5191923610ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 82 WOW-22578patch7.1.0_PTR
|
||||
// {0x3C258426058FBD93ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 91 WOW-23436patch7.2.0_PTR
|
||||
{ 0x094E9A0474876B98ULL, { 0xE5, 0x33, 0xBB, 0x6D, 0x65, 0x72, 0x7A, 0x58, 0x32, 0x68, 0x0D, 0x62, 0x0B, 0x0B, 0xC1, 0x0B } }, // 92 WOW-23910patch7.2.5_PTR
|
||||
{ 0x3DB25CB86A40335EULL, { 0x02, 0x99, 0x0B, 0x12, 0x26, 0x0C, 0x1E, 0x9F, 0xDD, 0x73, 0xFE, 0x47, 0xCB, 0xAB, 0x70, 0x24 } }, // 93 WOW-23789patch7.2.0_PTR
|
||||
{ 0x0DCD81945F4B4686ULL, { 0x1B, 0x78, 0x9B, 0x87, 0xFB, 0x3C, 0x92, 0x38, 0xD5, 0x28, 0x99, 0x7B, 0xFA, 0xB4, 0x41, 0x86 } }, // 94 WOW-23789patch7.2.0_PTR
|
||||
{ 0x486A2A3A2803BE89ULL, { 0x32, 0x67, 0x9E, 0xA7, 0xB0, 0xF9, 0x9E, 0xBF, 0x4F, 0xA1, 0x70, 0xE8, 0x47, 0xEA, 0x43, 0x9A } }, // 95 WOW-23789patch7.2.0_PTR
|
||||
{ 0x71F69446AD848E06ULL, { 0xE7, 0x9A, 0xEB, 0x88, 0xB1, 0x50, 0x9F, 0x62, 0x8F, 0x38, 0x20, 0x82, 0x01, 0x74, 0x1C, 0x30 } }, // 97 WOW-24473patch7.3.0_PTR BlizzCon 2017 Mounts (AllianceShipMount and HordeZeppelinMount)
|
||||
{ 0x211FCD1265A928E9ULL, { 0xA7, 0x36, 0xFB, 0xF5, 0x8D, 0x58, 0x7B, 0x39, 0x72, 0xCE, 0x15, 0x4A, 0x86, 0xAE, 0x45, 0x40 } }, // 98 WOW-24473patch7.3.0_PTR "Shadow" fox pet (store)
|
||||
{ 0x0ADC9E327E42E98CULL, { 0x01, 0x7B, 0x34, 0x72, 0xC1, 0xDE, 0xE3, 0x04, 0xFA, 0x0B, 0x2F, 0xF8, 0xE5, 0x3F, 0xF7, 0xD6 } }, // 99 WOW-23910patch7.2.5_PTR
|
||||
{ 0xBAE9F621B60174F1ULL, { 0x38, 0xC3, 0xFB, 0x39, 0xB4, 0x97, 0x17, 0x60, 0xB4, 0xB9, 0x82, 0xFE, 0x9F, 0x09, 0x50, 0x14 } }, // 100 WOW-24473patch7.3.0_PTR Rejection of the Gift cinematic (legion_73_agi)
|
||||
{ 0x34DE1EEADC97115EULL, { 0x2E, 0x3A, 0x53, 0xD5, 0x9A, 0x49, 0x1E, 0x5C, 0xD1, 0x73, 0xF3, 0x37, 0xF7, 0xCD, 0x8C, 0x61 } }, // 101 WOW-24473patch7.3.0_PTR Resurrection of Alleria Windrunner cinematic (legion_73_avt)
|
||||
// { 0xE07E107F1390A3DFULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 102 WOW-25079patch7.3.2_PTR Tottle battle pet, Raptor mount, Horse mount (104 files)
|
||||
{ 0x32690BF74DE12530ULL, { 0xA2, 0x55, 0x62, 0x10, 0xAE, 0x54, 0x22, 0xE6, 0xD6, 0x1E, 0xDA, 0xAF, 0x12, 0x2C, 0xB6, 0x37 } }, // 103 WOW-24781patch7.3.0_PTR legion_73_pan
|
||||
{ 0xBF3734B1DCB04696ULL, { 0x48, 0x94, 0x61, 0x23, 0x05, 0x0B, 0x00, 0xA7, 0xEF, 0xB1, 0xC0, 0x29, 0xEE, 0x6C, 0xC4, 0x38 } }, // 104 WOW-25079patch7.3.2_PTR legion_73_afn
|
||||
{ 0x74F4F78002A5A1BEULL, { 0xC1, 0x4E, 0xEC, 0x8D, 0x5A, 0xEE, 0xF9, 0x3F, 0xA8, 0x11, 0xD4, 0x50, 0xB4, 0xE4, 0x6E, 0x91 } }, // 105 WOW-25079patch7.3.2_PTR SilithusPhase01 map
|
||||
// { 0x423F07656CA27D23ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0x0691678F83E8A75DULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0xC02C78F40BEF5998ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0x324498590F550556ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0x8E00C6F405873583ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0x78482170E4CFD4A6ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
// { 0xB1EB52A64BFAF7BFULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // WOW-25600patch7.3.5_PTR
|
||||
{ 0, { 0 } }
|
||||
};
|
||||
|
||||
static const char * szKeyConstant16 = "expand 16-byte k";
|
||||
static const char * szKeyConstant32 = "expand 32-byte k";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
|
||||
{
|
||||
return (dwValue << dwRolCount) | (dwValue >> (32 - dwRolCount));
|
||||
}
|
||||
|
||||
static LPBYTE FindCascKey(ULONGLONG KeyName)
|
||||
{
|
||||
// Search the known keys
|
||||
for(size_t i = 0; CascKeys[i].KeyName != 0; i++)
|
||||
{
|
||||
if(CascKeys[i].KeyName == KeyName)
|
||||
return CascKeys[i].Key;
|
||||
}
|
||||
|
||||
// Key not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Initialize(PCASC_SALSA20 pState, LPBYTE pbKey, DWORD cbKeyLength, LPBYTE pbVector)
|
||||
{
|
||||
const char * szConstants = (cbKeyLength == 32) ? szKeyConstant32 : szKeyConstant16;
|
||||
DWORD KeyIndex = cbKeyLength - 0x10;
|
||||
|
||||
memset(pState, 0, sizeof(CASC_SALSA20));
|
||||
pState->Key[0] = *(PDWORD)(szConstants + 0x00);
|
||||
pState->Key[1] = *(PDWORD)(pbKey + 0x00);
|
||||
pState->Key[2] = *(PDWORD)(pbKey + 0x04);
|
||||
pState->Key[3] = *(PDWORD)(pbKey + 0x08);
|
||||
pState->Key[4] = *(PDWORD)(pbKey + 0x0C);
|
||||
pState->Key[5] = *(PDWORD)(szConstants + 0x04);
|
||||
pState->Key[6] = *(PDWORD)(pbVector + 0x00);
|
||||
pState->Key[7] = *(PDWORD)(pbVector + 0x04);
|
||||
pState->Key[8] = 0;
|
||||
pState->Key[9] = 0;
|
||||
pState->Key[10] = *(PDWORD)(szConstants + 0x08);
|
||||
pState->Key[11] = *(PDWORD)(pbKey + KeyIndex + 0x00);
|
||||
pState->Key[12] = *(PDWORD)(pbKey + KeyIndex + 0x04);
|
||||
pState->Key[13] = *(PDWORD)(pbKey + KeyIndex + 0x08);
|
||||
pState->Key[14] = *(PDWORD)(pbKey + KeyIndex + 0x0C);
|
||||
pState->Key[15] = *(PDWORD)(szConstants + 0x0C);
|
||||
|
||||
pState->dwRounds = 20;
|
||||
}
|
||||
|
||||
static int Decrypt(PCASC_SALSA20 pState, LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer)
|
||||
{
|
||||
LPBYTE pbXorValue;
|
||||
DWORD KeyMirror[0x10];
|
||||
DWORD XorValue[0x10];
|
||||
DWORD BlockSize;
|
||||
DWORD i;
|
||||
|
||||
// Repeat until we have data to read
|
||||
while(cbInBuffer > 0)
|
||||
{
|
||||
// Create the copy of the key
|
||||
memcpy(KeyMirror, pState->Key, sizeof(KeyMirror));
|
||||
|
||||
// Shuffle the key
|
||||
for(i = 0; i < pState->dwRounds; i += 2)
|
||||
{
|
||||
KeyMirror[0x04] ^= Rol32((KeyMirror[0x00] + KeyMirror[0x0C]), 0x07);
|
||||
KeyMirror[0x08] ^= Rol32((KeyMirror[0x04] + KeyMirror[0x00]), 0x09);
|
||||
KeyMirror[0x0C] ^= Rol32((KeyMirror[0x08] + KeyMirror[0x04]), 0x0D);
|
||||
KeyMirror[0x00] ^= Rol32((KeyMirror[0x0C] + KeyMirror[0x08]), 0x12);
|
||||
|
||||
KeyMirror[0x09] ^= Rol32((KeyMirror[0x05] + KeyMirror[0x01]), 0x07);
|
||||
KeyMirror[0x0D] ^= Rol32((KeyMirror[0x09] + KeyMirror[0x05]), 0x09);
|
||||
KeyMirror[0x01] ^= Rol32((KeyMirror[0x0D] + KeyMirror[0x09]), 0x0D);
|
||||
KeyMirror[0x05] ^= Rol32((KeyMirror[0x01] + KeyMirror[0x0D]), 0x12);
|
||||
|
||||
KeyMirror[0x0E] ^= Rol32((KeyMirror[0x0A] + KeyMirror[0x06]), 0x07);
|
||||
KeyMirror[0x02] ^= Rol32((KeyMirror[0x0E] + KeyMirror[0x0A]), 0x09);
|
||||
KeyMirror[0x06] ^= Rol32((KeyMirror[0x02] + KeyMirror[0x0E]), 0x0D);
|
||||
KeyMirror[0x0A] ^= Rol32((KeyMirror[0x06] + KeyMirror[0x02]), 0x12);
|
||||
|
||||
KeyMirror[0x03] ^= Rol32((KeyMirror[0x0F] + KeyMirror[0x0B]), 0x07);
|
||||
KeyMirror[0x07] ^= Rol32((KeyMirror[0x03] + KeyMirror[0x0F]), 0x09);
|
||||
KeyMirror[0x0B] ^= Rol32((KeyMirror[0x07] + KeyMirror[0x03]), 0x0D);
|
||||
KeyMirror[0x0F] ^= Rol32((KeyMirror[0x0B] + KeyMirror[0x07]), 0x12);
|
||||
|
||||
KeyMirror[0x01] ^= Rol32((KeyMirror[0x00] + KeyMirror[0x03]), 0x07);
|
||||
KeyMirror[0x02] ^= Rol32((KeyMirror[0x01] + KeyMirror[0x00]), 0x09);
|
||||
KeyMirror[0x03] ^= Rol32((KeyMirror[0x02] + KeyMirror[0x01]), 0x0D);
|
||||
KeyMirror[0x00] ^= Rol32((KeyMirror[0x03] + KeyMirror[0x02]), 0x12);
|
||||
|
||||
KeyMirror[0x06] ^= Rol32((KeyMirror[0x05] + KeyMirror[0x04]), 0x07);
|
||||
KeyMirror[0x07] ^= Rol32((KeyMirror[0x06] + KeyMirror[0x05]), 0x09);
|
||||
KeyMirror[0x04] ^= Rol32((KeyMirror[0x07] + KeyMirror[0x06]), 0x0D);
|
||||
KeyMirror[0x05] ^= Rol32((KeyMirror[0x04] + KeyMirror[0x07]), 0x12);
|
||||
|
||||
KeyMirror[0x0B] ^= Rol32((KeyMirror[0x0A] + KeyMirror[0x09]), 0x07);
|
||||
KeyMirror[0x08] ^= Rol32((KeyMirror[0x0B] + KeyMirror[0x0A]), 0x09);
|
||||
KeyMirror[0x09] ^= Rol32((KeyMirror[0x08] + KeyMirror[0x0B]), 0x0D);
|
||||
KeyMirror[0x0A] ^= Rol32((KeyMirror[0x09] + KeyMirror[0x08]), 0x12);
|
||||
|
||||
KeyMirror[0x0C] ^= Rol32((KeyMirror[0x0F] + KeyMirror[0x0E]), 0x07);
|
||||
KeyMirror[0x0D] ^= Rol32((KeyMirror[0x0C] + KeyMirror[0x0F]), 0x09);
|
||||
KeyMirror[0x0E] ^= Rol32((KeyMirror[0x0D] + KeyMirror[0x0C]), 0x0D);
|
||||
KeyMirror[0x0F] ^= Rol32((KeyMirror[0x0E] + KeyMirror[0x0D]), 0x12);
|
||||
}
|
||||
|
||||
// Set the number of remaining bytes
|
||||
pbXorValue = (LPBYTE)XorValue;
|
||||
BlockSize = (DWORD)CASCLIB_MIN(cbInBuffer, 0x40);
|
||||
|
||||
// Prepare the XOR constants
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
XorValue[i] = KeyMirror[i] + pState->Key[i];
|
||||
}
|
||||
|
||||
// Decrypt the block
|
||||
for(i = 0; i < BlockSize; i++)
|
||||
{
|
||||
pbOutBuffer[i] = pbInBuffer[i] ^ pbXorValue[i];
|
||||
}
|
||||
|
||||
pState->Key[8] = pState->Key[8] + 1;
|
||||
if(pState->Key[8] == 0)
|
||||
pState->Key[9] = pState->Key[9] + 1;
|
||||
|
||||
// Adjust buffers
|
||||
pbOutBuffer += BlockSize;
|
||||
pbInBuffer += BlockSize;
|
||||
cbInBuffer -= BlockSize;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static int Decrypt_Salsa20(LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer, LPBYTE pbKey, DWORD cbKeySize, LPBYTE pbVector)
|
||||
{
|
||||
CASC_SALSA20 SalsaState;
|
||||
|
||||
Initialize(&SalsaState, pbKey, cbKeySize, pbVector);
|
||||
return Decrypt(&SalsaState, pbOutBuffer, pbInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int CascDecrypt(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex)
|
||||
{
|
||||
ULONGLONG KeyName = 0;
|
||||
LPBYTE pbBufferEnd = pbInBuffer + cbInBuffer;
|
||||
LPBYTE pbKey;
|
||||
DWORD KeyNameSize;
|
||||
DWORD dwShift = 0;
|
||||
DWORD IVSize;
|
||||
BYTE Vector[0x08];
|
||||
BYTE EncryptionType;
|
||||
int nError;
|
||||
|
||||
// Verify and retrieve the key name size
|
||||
if(pbInBuffer >= pbBufferEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
if(pbInBuffer[0] != 0 && pbInBuffer[0] != 8)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
KeyNameSize = *pbInBuffer++;
|
||||
|
||||
// Copy the key name
|
||||
if((pbInBuffer + KeyNameSize) >= pbBufferEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
memcpy(&KeyName, pbInBuffer, KeyNameSize);
|
||||
pbInBuffer += KeyNameSize;
|
||||
|
||||
// Verify and retrieve the Vector size
|
||||
if(pbInBuffer >= pbBufferEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
if(pbInBuffer[0] != 4 && pbInBuffer[0] != 8)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
IVSize = *pbInBuffer++;
|
||||
|
||||
// Copy the initialization vector
|
||||
if((pbInBuffer + IVSize) >= pbBufferEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
memset(Vector, 0, sizeof(Vector));
|
||||
memcpy(Vector, pbInBuffer, IVSize);
|
||||
pbInBuffer += IVSize;
|
||||
|
||||
// Verify and retrieve the encryption type
|
||||
if(pbInBuffer >= pbBufferEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
if(pbInBuffer[0] != 'S' && pbInBuffer[0] != 'A')
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
EncryptionType = *pbInBuffer++;
|
||||
|
||||
// Do we have enough space in the output buffer?
|
||||
if((DWORD)(pbBufferEnd - pbInBuffer) > pcbOutBuffer[0])
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
|
||||
// Check if we know the key
|
||||
pbKey = FindCascKey(KeyName);
|
||||
if(pbKey == NULL)
|
||||
return ERROR_FILE_ENCRYPTED;
|
||||
|
||||
// Shuffle the Vector with the block index
|
||||
// Note that there's no point to go beyond 32 bits, unless the file has
|
||||
// more than 0xFFFFFFFF frames.
|
||||
for(int i = 0; i < sizeof(dwFrameIndex); i++)
|
||||
{
|
||||
Vector[i] = Vector[i] ^ (BYTE)((dwFrameIndex >> dwShift) & 0xFF);
|
||||
dwShift += 8;
|
||||
}
|
||||
|
||||
// Perform the decryption-specific action
|
||||
switch(EncryptionType)
|
||||
{
|
||||
case 'S': // Salsa20
|
||||
nError = Decrypt_Salsa20(pbOutBuffer, pbInBuffer, (pbBufferEnd - pbInBuffer), pbKey, 0x10, Vector);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Supply the size of the output buffer
|
||||
pcbOutBuffer[0] = (DWORD)(pbBufferEnd - pbInBuffer);
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
// case 'A':
|
||||
// return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int CascDirectCopy(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer)
|
||||
{
|
||||
// Check the buffer size
|
||||
if((cbInBuffer - 1) > pcbOutBuffer[0])
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
|
||||
// Copy the data
|
||||
memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
|
||||
pcbOutBuffer[0] = cbInBuffer;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
335
dep/CascLib/src/CascDumpData.cpp
Normal file
335
dep/CascLib/src/CascDumpData.cpp
Normal file
@@ -0,0 +1,335 @@
|
||||
/*****************************************************************************/
|
||||
/* CascDumpData.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* System-dependent directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 07.05.14 1.00 Lad The first version of CascDumpData.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
#include "CascMndx.h"
|
||||
|
||||
#ifdef _DEBUG // The entire feature is only valid for debug purposes
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward definitions
|
||||
|
||||
//LPBYTE VerifyLocaleBlock(PROOT_BLOCK_INFO pBlockInfo, LPBYTE pbFilePointer, LPBYTE pbFileEnd);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort compare functions
|
||||
|
||||
static int CompareIndexEntries_FilePos(const void *, const void * pvIndexEntry1, const void * pvIndexEntry2)
|
||||
{
|
||||
PCASC_INDEX_ENTRY pIndexEntry1 = (PCASC_INDEX_ENTRY)pvIndexEntry1;
|
||||
PCASC_INDEX_ENTRY pIndexEntry2 = (PCASC_INDEX_ENTRY)pvIndexEntry2;
|
||||
ULONGLONG FileOffset1 = ConvertBytesToInteger_5(pIndexEntry1->FileOffsetBE);
|
||||
ULONGLONG FileOffset2 = ConvertBytesToInteger_5(pIndexEntry2->FileOffsetBE);
|
||||
DWORD ArchIndex1 = (DWORD)(FileOffset1 >> 0x1E);
|
||||
DWORD ArchIndex2 = (DWORD)(FileOffset2 >> 0x1E);
|
||||
|
||||
// First, compare the archive index
|
||||
if(ArchIndex1 < ArchIndex2)
|
||||
return -1;
|
||||
if(ArchIndex1 > ArchIndex2)
|
||||
return +1;
|
||||
|
||||
// Second, compare the archive offset
|
||||
FileOffset1 &= 0x3FFFFFFF;
|
||||
FileOffset2 &= 0x3FFFFFFF;
|
||||
if(FileOffset1 < FileOffset2)
|
||||
return -1;
|
||||
if(FileOffset1 > FileOffset2)
|
||||
return +1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
void CascDumpSparseArray(const char * szFileName, void * pvSparseArray)
|
||||
{
|
||||
TSparseArray * pSparseArray = (TSparseArray *)pvSparseArray;
|
||||
FILE * fp;
|
||||
|
||||
// Create the dump file
|
||||
fp = fopen(szFileName, "wt");
|
||||
if(fp != NULL)
|
||||
{
|
||||
// Write header
|
||||
fprintf(fp, "## Value\n-- -----\n");
|
||||
|
||||
// Write the values
|
||||
for(DWORD i = 0; i < pSparseArray->TotalItemCount; i++)
|
||||
{
|
||||
DWORD Value = 0;
|
||||
|
||||
if(pSparseArray->IsItemPresent(i))
|
||||
{
|
||||
Value = pSparseArray->GetItemValue(i);
|
||||
fprintf(fp, "%02X %02X\n", i, Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(fp, "%02X --\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void CascDumpNameFragTable(const char * szFileName, void * pMarFile)
|
||||
{
|
||||
TFileNameDatabase * pDB = ((PMAR_FILE)pMarFile)->pDatabasePtr->pDB;
|
||||
FILE * fp;
|
||||
|
||||
// Create the dump file
|
||||
fp = fopen(szFileName, "wt");
|
||||
if(fp != NULL)
|
||||
{
|
||||
PNAME_FRAG pNameTable = pDB->NameFragTable.NameFragArray;
|
||||
const char * szNames = pDB->IndexStruct_174.NameFragments.CharArray;
|
||||
const char * szLastEntry;
|
||||
char szMatchType[0x100];
|
||||
|
||||
// Dump the table header
|
||||
fprintf(fp, "Indx ThisHash NextHash FragOffs\n");
|
||||
fprintf(fp, "---- -------- -------- --------\n");
|
||||
|
||||
// Dump all name entries
|
||||
for(DWORD i = 0; i < pDB->NameFragTable.ItemCount; i++)
|
||||
{
|
||||
// Reset both match types
|
||||
szMatchType[0] = 0;
|
||||
szLastEntry = "";
|
||||
|
||||
// Only if the table entry is not empty
|
||||
if(pNameTable->ItemIndex != 0xFFFFFFFF)
|
||||
{
|
||||
// Prepare the entry
|
||||
if(IS_SINGLE_CHAR_MATCH(pDB->NameFragTable, i))
|
||||
sprintf(szMatchType, "SINGLE_CHAR (\'%c\')", (pNameTable->FragOffs & 0xFF));
|
||||
else
|
||||
sprintf(szMatchType, "NAME_FRAGMT (\"%s\")", szNames + pNameTable->FragOffs);
|
||||
}
|
||||
|
||||
// Dump the entry
|
||||
fprintf(fp, "0x%02X %08x %08x %08x %s%s\n", i, pNameTable->ItemIndex,
|
||||
pNameTable->NextIndex,
|
||||
pNameTable->FragOffs,
|
||||
szMatchType,
|
||||
szLastEntry);
|
||||
pNameTable++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void CascDumpFileNames(const char * szFileName, void * pvMarFile)
|
||||
{
|
||||
TMndxFindResult Struct1C;
|
||||
PMAR_FILE pMarFile = (PMAR_FILE)pvMarFile;
|
||||
FILE * fp;
|
||||
char szNameBuff[0x200];
|
||||
bool bFindResult;
|
||||
|
||||
// Create the dump file
|
||||
fp = fopen(szFileName, "wt");
|
||||
if(fp != NULL)
|
||||
{
|
||||
// Set an empty path as search mask (?)
|
||||
Struct1C.SetSearchPath("", 0);
|
||||
|
||||
// Keep searching
|
||||
for(;;)
|
||||
{
|
||||
// Search the next file name
|
||||
pMarFile->pDatabasePtr->sub_1956CE0(&Struct1C, &bFindResult);
|
||||
|
||||
// Stop the search in case of failure
|
||||
if(!bFindResult)
|
||||
break;
|
||||
|
||||
// Printf the found file name
|
||||
memcpy(szNameBuff, Struct1C.szFoundPath, Struct1C.cchFoundPath);
|
||||
szNameBuff[Struct1C.cchFoundPath] = 0;
|
||||
fprintf(fp, "%s\n", szNameBuff);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// Free the search structures
|
||||
Struct1C.FreeStruct40();
|
||||
}
|
||||
|
||||
void CascDumpIndexEntry(
|
||||
TCascStorage * /* hs */,
|
||||
TDumpContext * dc,
|
||||
PCASC_INDEX_ENTRY pIndexEntry,
|
||||
int /* nDumpLevel */)
|
||||
{
|
||||
if(pIndexEntry != NULL)
|
||||
{
|
||||
ULONGLONG FileOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffsetBE);
|
||||
DWORD ArchIndex = (DWORD)(FileOffset >> 0x1E);
|
||||
DWORD FileSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSizeLE);
|
||||
|
||||
// Mask the file offset
|
||||
FileOffset &= 0x3FFFFFFF;
|
||||
dump_print(dc, " data.%03u at 0x%08x (0x%lx bytes)\n",
|
||||
ArchIndex,
|
||||
(DWORD)FileOffset,
|
||||
FileSize);
|
||||
|
||||
//if(nDumpLevel > 2)
|
||||
//{
|
||||
// QueryKey.pbData = pIndexEntry->IndexKey;
|
||||
// QueryKey.cbData = MD5_HASH_SIZE;
|
||||
// if(CascOpenFileByIndexKey((HANDLE)hs, &QueryKey, 0, &hFile))
|
||||
// {
|
||||
// // Make sure that the data file is open and frame header loaded
|
||||
// CascGetFileSize(hFile, NULL);
|
||||
// hf = IsValidFileHandle(hFile);
|
||||
// assert(hf->pStream != NULL);
|
||||
|
||||
// // Read the header area
|
||||
// FileOffset = hf->HeaderOffset - BLTE_HEADER_DELTA;
|
||||
// FileStream_Read(hf->pStream, &FileOffset, HeaderArea, sizeof(HeaderArea));
|
||||
// CascCloseFile(hFile);
|
||||
|
||||
// // Dump the header area
|
||||
// dump_print(dc, " FileSize: %X Rest: %s\n",
|
||||
// ConvertBytesToInteger_4_LE(&HeaderArea[0x10]),
|
||||
// StringFromBinary(&HeaderArea[0x14], 10, szBuffer));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_print(dc, " NO INDEX ENTRY\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CascDumpEncodingEntry(
|
||||
TCascStorage * hs,
|
||||
TDumpContext * dc,
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry,
|
||||
int nDumpLevel)
|
||||
{
|
||||
PCASC_INDEX_ENTRY pIndexEntry;
|
||||
QUERY_KEY QueryKey;
|
||||
LPBYTE pbIndexKey;
|
||||
char szMd5[MD5_STRING_SIZE+1];
|
||||
|
||||
// If the encoding key exists
|
||||
if(pEncodingEntry != NULL)
|
||||
{
|
||||
dump_print(dc, " Size %lx Key Count: %u\n",
|
||||
ConvertBytesToInteger_4(pEncodingEntry->FileSizeBE),
|
||||
pEncodingEntry->KeyCount);
|
||||
|
||||
// Dump all index keys
|
||||
pbIndexKey = pEncodingEntry->EncodingKey + MD5_HASH_SIZE;
|
||||
for(DWORD j = 0; j < pEncodingEntry->KeyCount; j++, pbIndexKey += MD5_HASH_SIZE)
|
||||
{
|
||||
// Dump the index key
|
||||
dump_print(dc, " %s\n", StringFromMD5(pbIndexKey, szMd5));
|
||||
|
||||
// Dump the index entry as well
|
||||
if(nDumpLevel >= DUMP_LEVEL_INDEX_ENTRIES)
|
||||
{
|
||||
QueryKey.pbData = pbIndexKey;
|
||||
QueryKey.cbData = MD5_HASH_SIZE;
|
||||
pIndexEntry = FindIndexEntry(hs, &QueryKey);
|
||||
CascDumpIndexEntry(hs, dc, pIndexEntry, nDumpLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_print(dc, " NO ENCODING KEYS\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CascDumpIndexEntries(const char * szFileName, TCascStorage * hs)
|
||||
{
|
||||
PCASC_INDEX_ENTRY * ppIndexEntries;
|
||||
FILE * fp;
|
||||
size_t nIndexEntries = hs->pIndexEntryMap->ItemCount;
|
||||
char szIndexKey[0x40];
|
||||
|
||||
// Create the dump file
|
||||
fp = fopen(szFileName, "wt");
|
||||
if(fp != NULL)
|
||||
{
|
||||
// Create linear aray
|
||||
ppIndexEntries = CASC_ALLOC(PCASC_INDEX_ENTRY, nIndexEntries);
|
||||
if(ppIndexEntries != NULL)
|
||||
{
|
||||
// Obtain the linear array of index entries
|
||||
Map_EnumObjects(hs->pIndexEntryMap, (void **)ppIndexEntries);
|
||||
|
||||
// Sort the array by archive number and archive offset
|
||||
qsort_pointer_array((void **)ppIndexEntries, nIndexEntries, CompareIndexEntries_FilePos, NULL);
|
||||
|
||||
// Parse the array
|
||||
fprintf(fp, "ArNo ArOffset FileSize IndexKey\n==== ======== ======== ================================\n");
|
||||
for(size_t i = 0; i < nIndexEntries; i++)
|
||||
{
|
||||
PCASC_INDEX_ENTRY pIndexEntry = ppIndexEntries[i];
|
||||
ULONGLONG ArchOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffsetBE);
|
||||
DWORD ArchIndex = (DWORD)(ArchOffset >> 0x1E);
|
||||
DWORD FileSize;
|
||||
|
||||
FileSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSizeLE);
|
||||
ArchOffset &= 0x3FFFFFFF;
|
||||
|
||||
fprintf(fp, " %02X %08X %08X %s\n", ArchIndex, (DWORD)ArchOffset, FileSize, StringFromBinary(pIndexEntry->IndexKey, CASC_FILE_KEY_SIZE, szIndexKey));
|
||||
}
|
||||
|
||||
CASC_FREE(ppIndexEntries);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void CascDumpFile(const char * szFileName, HANDLE hFile)
|
||||
{
|
||||
FILE * fp;
|
||||
DWORD dwBytesRead = 1;
|
||||
DWORD dwFilePos = CascSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||||
BYTE Buffer[0x1000];
|
||||
|
||||
// Create the dump file
|
||||
fp = fopen(szFileName, "wb");
|
||||
if(fp != NULL)
|
||||
{
|
||||
// Read data as long as we can, write as long as we can
|
||||
while(dwBytesRead != 0)
|
||||
{
|
||||
// Read from the source file
|
||||
if(!CascReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead))
|
||||
break;
|
||||
|
||||
// Write to the destination file
|
||||
if(fwrite(Buffer, 1, dwBytesRead, fp) != dwBytesRead)
|
||||
break;
|
||||
}
|
||||
|
||||
// Close the local file
|
||||
fclose(fp);
|
||||
|
||||
// Restore the file pointer
|
||||
CascSetFilePointer(hFile, dwFilePos, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _DEBUG
|
||||
1017
dep/CascLib/src/CascFiles.cpp
Normal file
1017
dep/CascLib/src/CascFiles.cpp
Normal file
File diff suppressed because it is too large
Load Diff
326
dep/CascLib/src/CascFindFile.cpp
Normal file
326
dep/CascLib/src/CascFindFile.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
/*****************************************************************************/
|
||||
/* CascFindFile.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* System-dependent directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 10.05.14 1.00 Lad The first version of CascFindFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static TCascSearch * IsValidSearchHandle(HANDLE hFind)
|
||||
{
|
||||
TCascSearch * pSearch = (TCascSearch *)hFind;
|
||||
|
||||
return (pSearch != NULL && pSearch->szClassName != NULL && !strcmp(pSearch->szClassName, "TCascSearch") && pSearch->szMask != NULL) ? pSearch : NULL;
|
||||
}
|
||||
|
||||
static void FreeSearchHandle(TCascSearch * pSearch)
|
||||
{
|
||||
// Only if the storage handle is valid
|
||||
assert(pSearch != NULL);
|
||||
|
||||
// Close (dereference) the archive handle
|
||||
if(pSearch->hs != NULL)
|
||||
{
|
||||
// Give root handler chance to free their stuff
|
||||
RootHandler_EndSearch(pSearch->hs->pRootHandler, pSearch);
|
||||
|
||||
// Dereference the storage handle
|
||||
CascCloseStorage((HANDLE)pSearch->hs);
|
||||
pSearch->hs = NULL;
|
||||
}
|
||||
|
||||
// Free the file cache and frame array
|
||||
if(pSearch->szMask != NULL)
|
||||
CASC_FREE(pSearch->szMask);
|
||||
if(pSearch->szListFile != NULL)
|
||||
CASC_FREE(pSearch->szListFile);
|
||||
// if(pSearch->pStruct1C != NULL)
|
||||
// delete pSearch->pStruct1C;
|
||||
if(pSearch->pCache != NULL)
|
||||
ListFile_Free(pSearch->pCache);
|
||||
|
||||
// Free the structure itself
|
||||
pSearch->szClassName = NULL;
|
||||
CASC_FREE(pSearch);
|
||||
}
|
||||
|
||||
static TCascSearch * AllocateSearchHandle(TCascStorage * hs, const TCHAR * szListFile, const char * szMask)
|
||||
{
|
||||
TCascSearch * pSearch;
|
||||
size_t cbToAllocate;
|
||||
|
||||
// When using the MNDX info, do not allocate the extra bit array
|
||||
cbToAllocate = sizeof(TCascSearch) + ((hs->pEncodingMap->TableSize + 7) / 8);
|
||||
pSearch = (TCascSearch *)CASC_ALLOC(BYTE, cbToAllocate);
|
||||
if(pSearch != NULL)
|
||||
{
|
||||
// Initialize the structure
|
||||
memset(pSearch, 0, cbToAllocate);
|
||||
pSearch->szClassName = "TCascSearch";
|
||||
|
||||
// Save the search handle
|
||||
pSearch->hs = hs;
|
||||
hs->dwRefCount++;
|
||||
|
||||
// If the mask was not given, use default
|
||||
if(szMask == NULL)
|
||||
szMask = "*";
|
||||
|
||||
// Save the other variables
|
||||
if(szListFile != NULL)
|
||||
{
|
||||
pSearch->szListFile = CascNewStr(szListFile, 0);
|
||||
if(pSearch->szListFile == NULL)
|
||||
{
|
||||
FreeSearchHandle(pSearch);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the search mask
|
||||
pSearch->szMask = CascNewStr(szMask, 0);
|
||||
if(pSearch->szMask == NULL)
|
||||
{
|
||||
FreeSearchHandle(pSearch);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pSearch;
|
||||
}
|
||||
|
||||
// Perform searching using root-specific provider.
|
||||
// The provider may need the listfile
|
||||
static bool DoStorageSearch_RootFile(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
|
||||
{
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry;
|
||||
PCASC_INDEX_ENTRY pIndexEntry;
|
||||
QUERY_KEY EncodingKey;
|
||||
QUERY_KEY IndexKey;
|
||||
LPBYTE pbEncodingKey;
|
||||
DWORD EncodingIndex = 0;
|
||||
DWORD ByteIndex;
|
||||
DWORD BitMask;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
DWORD LocaleFlags = 0;
|
||||
DWORD FileDataId = CASC_INVALID_ID;
|
||||
DWORD FileSize = CASC_INVALID_SIZE;
|
||||
|
||||
// Attempt to find (the next) file from the root entry
|
||||
pbEncodingKey = RootHandler_Search(pSearch->hs->pRootHandler, pSearch, &FileSize, &LocaleFlags, &FileDataId);
|
||||
if(pbEncodingKey == NULL)
|
||||
return false;
|
||||
|
||||
// Verify whether the encoding key exists in the encoding table
|
||||
EncodingKey.pbData = pbEncodingKey;
|
||||
EncodingKey.cbData = MD5_HASH_SIZE;
|
||||
pEncodingEntry = FindEncodingEntry(pSearch->hs, &EncodingKey, &EncodingIndex);
|
||||
if(pEncodingEntry != NULL)
|
||||
{
|
||||
// Mark the item as already found
|
||||
// Note: Duplicate items are allowed while we are searching using file names
|
||||
// Do not exclude items from search if they were found before
|
||||
ByteIndex = (DWORD)(EncodingIndex / 8);
|
||||
BitMask = 1 << (EncodingIndex & 0x07);
|
||||
pSearch->BitArray[ByteIndex] |= BitMask;
|
||||
|
||||
// Locate the index entry
|
||||
IndexKey.pbData = GET_INDEX_KEY(pEncodingEntry);
|
||||
IndexKey.cbData = MD5_HASH_SIZE;
|
||||
pIndexEntry = FindIndexEntry(pSearch->hs, &IndexKey);
|
||||
if(pIndexEntry == NULL)
|
||||
continue;
|
||||
|
||||
// If we retrieved the file size directly from the root provider, use it
|
||||
// Otherwise, we need to retrieve it from the encoding entry
|
||||
if(FileSize == CASC_INVALID_SIZE)
|
||||
FileSize = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBE);
|
||||
|
||||
// Fill-in the found file
|
||||
strcpy(pFindData->szFileName, pSearch->szFileName);
|
||||
memcpy(pFindData->EncodingKey, pEncodingEntry->EncodingKey, MD5_HASH_SIZE);
|
||||
pFindData->szPlainName = (char *)GetPlainFileName(pFindData->szFileName);
|
||||
pFindData->dwLocaleFlags = LocaleFlags;
|
||||
pFindData->dwFileDataId = FileDataId;
|
||||
pFindData->dwFileSize = FileSize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool DoStorageSearch_EncodingKey(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
|
||||
{
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry;
|
||||
PCASC_INDEX_ENTRY pIndexEntry;
|
||||
TCascStorage * hs = pSearch->hs;
|
||||
QUERY_KEY IndexKey;
|
||||
DWORD ByteIndex;
|
||||
DWORD BitMask;
|
||||
|
||||
// Check for encoding keys that haven't been found yet
|
||||
while(pSearch->IndexLevel1 < hs->pEncodingMap->TableSize)
|
||||
{
|
||||
// Check if that entry has been reported before
|
||||
ByteIndex = (DWORD)(pSearch->IndexLevel1 / 8);
|
||||
BitMask = 1 << (pSearch->IndexLevel1 & 0x07);
|
||||
if((pSearch->BitArray[ByteIndex] & BitMask) == 0)
|
||||
{
|
||||
// Locate the index entry
|
||||
pEncodingEntry = (PCASC_ENCODING_ENTRY)hs->pEncodingMap->HashTable[pSearch->IndexLevel1];
|
||||
if(pEncodingEntry != NULL)
|
||||
{
|
||||
IndexKey.pbData = GET_INDEX_KEY(pEncodingEntry);
|
||||
IndexKey.cbData = MD5_HASH_SIZE;
|
||||
pIndexEntry = FindIndexEntry(pSearch->hs, &IndexKey);
|
||||
if(pIndexEntry != NULL)
|
||||
{
|
||||
// Fill-in the found file
|
||||
memcpy(pFindData->EncodingKey, pEncodingEntry->EncodingKey, MD5_HASH_SIZE);
|
||||
pFindData->szFileName[0] = 0;
|
||||
pFindData->szPlainName = pFindData->szFileName;
|
||||
pFindData->dwLocaleFlags = CASC_LOCALE_NONE;
|
||||
pFindData->dwFileSize = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBE);
|
||||
|
||||
// Mark the entry as already-found
|
||||
pSearch->BitArray[ByteIndex] |= BitMask;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go to the next encoding entry
|
||||
pSearch->IndexLevel1++;
|
||||
}
|
||||
|
||||
// Nameless search ended
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DoStorageSearch(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
|
||||
{
|
||||
// State 0: No search done yet
|
||||
if(pSearch->dwState == 0)
|
||||
{
|
||||
// Does the search specify listfile?
|
||||
if(pSearch->szListFile != NULL)
|
||||
pSearch->pCache = ListFile_OpenExternal(pSearch->szListFile);
|
||||
|
||||
// Move the search phase to the listfile searching
|
||||
pSearch->IndexLevel1 = 0;
|
||||
pSearch->dwState++;
|
||||
}
|
||||
|
||||
// State 1: Searching the list file
|
||||
if(pSearch->dwState == 1)
|
||||
{
|
||||
if(DoStorageSearch_RootFile(pSearch, pFindData))
|
||||
return true;
|
||||
|
||||
// Move to the nameless search state
|
||||
pSearch->IndexLevel1 = 0;
|
||||
pSearch->dwState++;
|
||||
}
|
||||
|
||||
// State 2: Searching the remaining entries
|
||||
if(pSearch->dwState == 2 && (pSearch->szMask == NULL || !strcmp(pSearch->szMask, "*")))
|
||||
{
|
||||
if(DoStorageSearch_EncodingKey(pSearch, pFindData))
|
||||
return true;
|
||||
|
||||
// Move to the final search state
|
||||
pSearch->dwState++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
HANDLE WINAPI CascFindFirstFile(
|
||||
HANDLE hStorage,
|
||||
const char * szMask,
|
||||
PCASC_FIND_DATA pFindData,
|
||||
const TCHAR * szListFile)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
TCascSearch * pSearch = NULL;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check parameters
|
||||
if((hs = IsValidStorageHandle(hStorage)) == NULL)
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(szMask == NULL || pFindData == NULL)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Init the search structure and search handle
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Clear the entire search structure
|
||||
memset(pFindData, 0, sizeof(CASC_FIND_DATA));
|
||||
|
||||
// Allocate the search handle
|
||||
pSearch = AllocateSearchHandle(hs, szListFile, szMask);
|
||||
if(pSearch == NULL)
|
||||
nError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Perform search
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(!DoStorageSearch(pSearch, pFindData))
|
||||
nError = ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
if(pSearch != NULL)
|
||||
FreeSearchHandle(pSearch);
|
||||
pSearch = (TCascSearch *)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return (HANDLE)pSearch;
|
||||
}
|
||||
|
||||
bool WINAPI CascFindNextFile(
|
||||
HANDLE hFind,
|
||||
PCASC_FIND_DATA pFindData)
|
||||
{
|
||||
TCascSearch * pSearch;
|
||||
|
||||
pSearch = IsValidSearchHandle(hFind);
|
||||
if(pSearch == NULL || pFindData == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform search
|
||||
return DoStorageSearch(pSearch, pFindData);
|
||||
}
|
||||
|
||||
bool WINAPI CascFindClose(HANDLE hFind)
|
||||
{
|
||||
TCascSearch * pSearch;
|
||||
|
||||
pSearch = IsValidSearchHandle(hFind);
|
||||
if(pSearch == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeSearchHandle(pSearch);
|
||||
return true;
|
||||
}
|
||||
29
dep/CascLib/src/CascLib.def
Normal file
29
dep/CascLib/src/CascLib.def
Normal file
@@ -0,0 +1,29 @@
|
||||
;
|
||||
; Export file for Windows
|
||||
; Copyright (c) 2015 Ladislav Zezula
|
||||
; ladik@zezula.net
|
||||
;
|
||||
|
||||
LIBRARY CascLib.dll
|
||||
|
||||
EXPORTS
|
||||
|
||||
CascOpenStorage
|
||||
CascGetStorageInfo
|
||||
CascCloseStorage
|
||||
|
||||
CascOpenFileByIndexKey
|
||||
CascOpenFileByEncodingKey
|
||||
CascOpenFile
|
||||
CascGetFileSize
|
||||
CascSetFilePointer
|
||||
CascReadFile
|
||||
CascCloseFile
|
||||
|
||||
CascFindFirstFile
|
||||
CascFindNextFile
|
||||
CascFindClose
|
||||
|
||||
GetLastError=Kernel32.GetLastError
|
||||
SetLastError=Kernel32.SetLastError
|
||||
|
||||
180
dep/CascLib/src/CascLib.h
Normal file
180
dep/CascLib/src/CascLib.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*****************************************************************************/
|
||||
/* CascLib.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* CascLib library v 1.00 */
|
||||
/* */
|
||||
/* Author : Ladislav Zezula */
|
||||
/* E-mail : ladik@zezula.net */
|
||||
/* WWW : http://www.zezula.net */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __CASCLIB_H__
|
||||
#define __CASCLIB_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4668) // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
|
||||
#pragma warning(disable:4820) // 'XXX' : '2' bytes padding added after data member 'XXX::yyy'
|
||||
#endif
|
||||
|
||||
#include "CascPort.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define CASCLIB_VERSION 0x0100 // Current version of CascLib (1.0)
|
||||
#define CASCLIB_VERSION_STRING "1.00" // String version of CascLib version
|
||||
|
||||
// Values for CascOpenStorage
|
||||
#define CASC_STOR_XXXXX 0x00000001 // Not used
|
||||
|
||||
// Values for CascOpenFile
|
||||
#define CASC_OPEN_BY_ENCODING_KEY 0x00000001 // The name is just the encoding key; skip ROOT file processing
|
||||
|
||||
#define CASC_LOCALE_ALL 0xFFFFFFFF
|
||||
#define CASC_LOCALE_NONE 0x00000000
|
||||
#define CASC_LOCALE_UNKNOWN1 0x00000001
|
||||
#define CASC_LOCALE_ENUS 0x00000002
|
||||
#define CASC_LOCALE_KOKR 0x00000004
|
||||
#define CASC_LOCALE_RESERVED 0x00000008
|
||||
#define CASC_LOCALE_FRFR 0x00000010
|
||||
#define CASC_LOCALE_DEDE 0x00000020
|
||||
#define CASC_LOCALE_ZHCN 0x00000040
|
||||
#define CASC_LOCALE_ESES 0x00000080
|
||||
#define CASC_LOCALE_ZHTW 0x00000100
|
||||
#define CASC_LOCALE_ENGB 0x00000200
|
||||
#define CASC_LOCALE_ENCN 0x00000400
|
||||
#define CASC_LOCALE_ENTW 0x00000800
|
||||
#define CASC_LOCALE_ESMX 0x00001000
|
||||
#define CASC_LOCALE_RURU 0x00002000
|
||||
#define CASC_LOCALE_PTBR 0x00004000
|
||||
#define CASC_LOCALE_ITIT 0x00008000
|
||||
#define CASC_LOCALE_PTPT 0x00010000
|
||||
|
||||
#define CASC_LOCALE_BIT_ENUS 0x01
|
||||
#define CASC_LOCALE_BIT_KOKR 0x02
|
||||
#define CASC_LOCALE_BIT_RESERVED 0x03
|
||||
#define CASC_LOCALE_BIT_FRFR 0x04
|
||||
#define CASC_LOCALE_BIT_DEDE 0x05
|
||||
#define CASC_LOCALE_BIT_ZHCN 0x06
|
||||
#define CASC_LOCALE_BIT_ESES 0x07
|
||||
#define CASC_LOCALE_BIT_ZHTW 0x08
|
||||
#define CASC_LOCALE_BIT_ENGB 0x09
|
||||
#define CASC_LOCALE_BIT_ENCN 0x0A
|
||||
#define CASC_LOCALE_BIT_ENTW 0x0B
|
||||
#define CASC_LOCALE_BIT_ESMX 0x0C
|
||||
#define CASC_LOCALE_BIT_RURU 0x0D
|
||||
#define CASC_LOCALE_BIT_PTBR 0x0E
|
||||
#define CASC_LOCALE_BIT_ITIT 0x0F
|
||||
#define CASC_LOCALE_BIT_PTPT 0x10
|
||||
|
||||
|
||||
#define MAX_CASC_KEY_LENGTH 0x10 // Maximum length of the key (equal to MD5 hash)
|
||||
|
||||
#ifndef MD5_HASH_SIZE
|
||||
#define MD5_HASH_SIZE 0x10
|
||||
#define MD5_STRING_SIZE 0x20
|
||||
#endif
|
||||
|
||||
#ifndef SHA1_DIGEST_SIZE
|
||||
#define SHA1_DIGEST_SIZE 0x14 // 160 bits
|
||||
#endif
|
||||
|
||||
#ifndef LANG_NEUTRAL
|
||||
#define LANG_NEUTRAL 0x00 // Neutral locale
|
||||
#endif
|
||||
|
||||
// Return value for CascGetFileSize and CascSetFilePointer
|
||||
#define CASC_INVALID_SIZE 0xFFFFFFFF
|
||||
#define CASC_INVALID_POS 0xFFFFFFFF
|
||||
#define CASC_INVALID_ID 0xFFFFFFFF
|
||||
|
||||
// Flags for CascGetStorageInfo
|
||||
#define CASC_FEATURE_LISTFILE 0x00000001 // The storage supports listfile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures
|
||||
|
||||
typedef enum _CASC_STORAGE_INFO_CLASS
|
||||
{
|
||||
CascStorageFileCount,
|
||||
CascStorageFeatures,
|
||||
CascStorageGameInfo,
|
||||
CascStorageGameBuild,
|
||||
CascStorageInstalledLocales,
|
||||
CascStorageInfoClassMax
|
||||
|
||||
} CASC_STORAGE_INFO_CLASS, *PCASC_STORAGE_INFO_CLASS;
|
||||
|
||||
|
||||
typedef struct _QUERY_KEY
|
||||
{
|
||||
LPBYTE pbData;
|
||||
DWORD cbData;
|
||||
} QUERY_KEY, *PQUERY_KEY;
|
||||
|
||||
// Structure for SFileFindFirstFile and SFileFindNextFile
|
||||
typedef struct _CASC_FIND_DATA
|
||||
{
|
||||
char szFileName[MAX_PATH]; // Full name of the found file
|
||||
char * szPlainName; // Plain name of the found file
|
||||
BYTE EncodingKey[MD5_HASH_SIZE]; // Encoding key
|
||||
DWORD dwLocaleFlags; // Locale flags (WoW only)
|
||||
DWORD dwFileDataId; // File data ID (WoW only)
|
||||
DWORD dwFileSize; // Size of the file
|
||||
|
||||
} CASC_FIND_DATA, *PCASC_FIND_DATA;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback functions
|
||||
|
||||
typedef struct TFileStream TFileStream;
|
||||
typedef void (WINAPI * STREAM_DOWNLOAD_CALLBACK)(void * pvUserData, ULONGLONG ByteOffset, DWORD dwTotalBytes);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// We have our own qsort implementation, optimized for sorting array of pointers
|
||||
|
||||
void qsort_pointer_array(void ** base, size_t num, int (*compare)(const void *, const void *, const void *), const void * context);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for storage manipulation
|
||||
|
||||
bool WINAPI CascOpenStorage(const TCHAR * szDataPath, DWORD dwLocaleMask, HANDLE * phStorage);
|
||||
bool WINAPI CascGetStorageInfo(HANDLE hStorage, CASC_STORAGE_INFO_CLASS InfoClass, void * pvStorageInfo, size_t cbStorageInfo, size_t * pcbLengthNeeded);
|
||||
bool WINAPI CascCloseStorage(HANDLE hStorage);
|
||||
|
||||
bool WINAPI CascOpenFileByIndexKey(HANDLE hStorage, PQUERY_KEY pIndexKey, DWORD dwFlags, HANDLE * phFile);
|
||||
bool WINAPI CascOpenFileByEncodingKey(HANDLE hStorage, PQUERY_KEY pEncodingKey, DWORD dwFlags, HANDLE * phFile);
|
||||
bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocale, DWORD dwFlags, HANDLE * phFile);
|
||||
DWORD WINAPI CascGetFileSize(HANDLE hFile, PDWORD pdwFileSizeHigh);
|
||||
DWORD WINAPI CascGetFileId(HANDLE hStorage, const char * szFileName);
|
||||
DWORD WINAPI CascSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod);
|
||||
bool WINAPI CascReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, PDWORD pdwRead);
|
||||
bool WINAPI CascCloseFile(HANDLE hFile);
|
||||
|
||||
HANDLE WINAPI CascFindFirstFile(HANDLE hStorage, const char * szMask, PCASC_FIND_DATA pFindData, const TCHAR * szListFile);
|
||||
bool WINAPI CascFindNextFile(HANDLE hFind, PCASC_FIND_DATA pFindData);
|
||||
bool WINAPI CascFindClose(HANDLE hFind);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GetLastError/SetLastError support for non-Windows platform
|
||||
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
|
||||
int GetLastError();
|
||||
void SetLastError(int nError);
|
||||
|
||||
#endif // PLATFORM_WINDOWS
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __CASCLIB_H__
|
||||
359
dep/CascLib/src/CascMndx.h
Normal file
359
dep/CascLib/src/CascMndx.h
Normal file
@@ -0,0 +1,359 @@
|
||||
/*****************************************************************************/
|
||||
/* CascMndxRoot.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Interface file for MNDX structures */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 15.05.14 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __CASC_MNDX_ROOT__
|
||||
#define __CASC_MNDX_ROOT__
|
||||
|
||||
class TFileNameDatabase;
|
||||
|
||||
#define CASC_MAX_MAR_FILES 3 // Maximum of 3 MAR files are supported
|
||||
#define CASC_MNDX_SIGNATURE 0x58444E4D // 'MNDX'
|
||||
|
||||
#define CASC_MAX_ENTRIES(type) (0xFFFFFFFF / sizeof(type))
|
||||
|
||||
#define CASC_SEARCH_INITIALIZING 0
|
||||
#define CASC_SEARCH_SEARCHING 2
|
||||
#define CASC_SEARCH_FINISHED 4
|
||||
|
||||
typedef struct _TRIPLET
|
||||
{
|
||||
DWORD BaseValue;
|
||||
DWORD Value2;
|
||||
DWORD Value3;
|
||||
} TRIPLET, *PTRIPLET;
|
||||
|
||||
typedef struct _NAME_FRAG
|
||||
{
|
||||
DWORD ItemIndex; // Back index to various tables
|
||||
DWORD NextIndex; // The following item index
|
||||
DWORD FragOffs; // Higher 24 bits are 0xFFFFFF00 --> A single matching character
|
||||
// Otherwise --> Offset to the name fragment table
|
||||
} NAME_FRAG, *PNAME_FRAG;
|
||||
|
||||
typedef struct _PATH_STOP
|
||||
{
|
||||
DWORD ItemIndex;
|
||||
DWORD field_4;
|
||||
DWORD field_8;
|
||||
DWORD field_C;
|
||||
DWORD field_10;
|
||||
} PATH_STOP, *PPATH_STOP;
|
||||
|
||||
typedef union _ARRAY_POINTER
|
||||
{
|
||||
LPBYTE Bytes; // Pointer to an octet
|
||||
char * Chars; // Pointer to a character
|
||||
PDWORD Uint32s; // Pointer to a DWORD
|
||||
PTRIPLET Triplets; // Pointer to TRIPLET
|
||||
PNAME_FRAG NameFrags; // Pointer to name fragment entry
|
||||
PPATH_STOP PathStopPtr; // Pointer to path checkpoint
|
||||
PULONGLONG Int64Ptr; // Pointer to 64-bit integer
|
||||
|
||||
} ARRAY_POINTER, *PARRAY_POINTER;
|
||||
|
||||
// Simple access to various tables within TGenericArray
|
||||
#define ByteArray ArrayPointer.Bytes
|
||||
#define CharArray ArrayPointer.Chars
|
||||
#define Uint32Array ArrayPointer.Uint32s
|
||||
#define TripletArray ArrayPointer.Triplets
|
||||
#define NameFragArray ArrayPointer.NameFrags
|
||||
|
||||
class TByteStream
|
||||
{
|
||||
public:
|
||||
|
||||
TByteStream();
|
||||
|
||||
void ExchangeWith(TByteStream & Target);
|
||||
int GetBytes(DWORD cbByteCount, PARRAY_POINTER PtrArray);
|
||||
int SkipBytes(DWORD cbByteCount);
|
||||
int SetByteBuffer(LPBYTE pbNewMarData, DWORD cbNewMarData);
|
||||
int GetValue_DWORD(DWORD & Value);
|
||||
int GetValue_ItemCount(DWORD & NumberOfBytes, DWORD & ItemCount, DWORD ItemSize);
|
||||
int GetArray_DWORDs(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
||||
int GetArray_Triplets(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
||||
int GetArray_NameTable(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
||||
int GetArray_BYTES(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
||||
|
||||
LPBYTE pbByteData;
|
||||
void * pvMappedFile;
|
||||
DWORD cbByteData;
|
||||
DWORD field_C;
|
||||
HANDLE hFile;
|
||||
HANDLE hMap;
|
||||
};
|
||||
|
||||
class TGenericArray
|
||||
{
|
||||
public:
|
||||
|
||||
TGenericArray();
|
||||
~TGenericArray();
|
||||
|
||||
int SetArrayValid();
|
||||
|
||||
void ExchangeWith(TGenericArray & Target);
|
||||
void CopyFrom(TGenericArray & Source);
|
||||
|
||||
void SetMaxItems_CHARS(DWORD NewMaxItemCount);
|
||||
void SetMaxItems_PATH_STOP(DWORD NewMaxItemCount);
|
||||
|
||||
void InsertOneItem_CHAR(char OneChar);
|
||||
void InsertOneItem_PATH_STOP(PATH_STOP & NewItem);
|
||||
|
||||
void sub_19583A0(DWORD NewItemCount);
|
||||
|
||||
int LoadDwordsArray(TByteStream & InStream);
|
||||
int LoadTripletsArray(TByteStream & InStream);
|
||||
int LoadByteArray(TByteStream & InStream);
|
||||
int LoadFragmentInfos(TByteStream & InStream);
|
||||
int LoadStrings(TByteStream & InStream);
|
||||
|
||||
int LoadDwordsArray_Copy(TByteStream & InStream);
|
||||
int LoadTripletsArray_Copy(TByteStream & InStream);
|
||||
int LoadBytes_Copy(TByteStream & InStream);
|
||||
int LoadFragmentInfos_Copy(TByteStream & InStream);
|
||||
int LoadStringsWithCopy(TByteStream & InStream);
|
||||
|
||||
ARRAY_POINTER DataBuffer;
|
||||
ARRAY_POINTER FirstValid;
|
||||
|
||||
ARRAY_POINTER ArrayPointer;
|
||||
DWORD ItemCount; // Number of items in the array
|
||||
DWORD MaxItemCount; // Capacity of the array
|
||||
bool bIsValidArray;
|
||||
};
|
||||
|
||||
class TBitEntryArray : public TGenericArray
|
||||
{
|
||||
public:
|
||||
|
||||
TBitEntryArray();
|
||||
~TBitEntryArray();
|
||||
|
||||
DWORD GetBitEntry(DWORD EntryIndex)
|
||||
{
|
||||
DWORD dwItemIndex = (EntryIndex * BitsPerEntry) >> 0x05;
|
||||
DWORD dwStartBit = (EntryIndex * BitsPerEntry) & 0x1F;
|
||||
DWORD dwEndBit = dwStartBit + BitsPerEntry;
|
||||
DWORD dwResult;
|
||||
|
||||
// If the end bit index is greater than 32,
|
||||
// we also need to load from the next 32-bit item
|
||||
if(dwEndBit > 0x20)
|
||||
{
|
||||
dwResult = (Uint32Array[dwItemIndex + 1] << (0x20 - dwStartBit)) | (Uint32Array[dwItemIndex] >> dwStartBit);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwResult = Uint32Array[dwItemIndex] >> dwStartBit;
|
||||
}
|
||||
|
||||
// Now we also need to mask the result by the bit mask
|
||||
return dwResult & EntryBitMask;
|
||||
}
|
||||
|
||||
void ExchangeWith(TBitEntryArray & Target);
|
||||
int LoadFromStream(TByteStream & InStream);
|
||||
int LoadFromStream_Exchange(TByteStream & InStream);
|
||||
|
||||
DWORD BitsPerEntry;
|
||||
DWORD EntryBitMask;
|
||||
DWORD TotalEntries;
|
||||
};
|
||||
|
||||
class TStruct40
|
||||
{
|
||||
public:
|
||||
|
||||
TStruct40();
|
||||
|
||||
void InitSearchBuffers();
|
||||
|
||||
TGenericArray array_00;
|
||||
TGenericArray PathStops; // Array of path checkpoints
|
||||
DWORD ItemIndex; // Current name fragment: Index to various tables
|
||||
DWORD CharIndex;
|
||||
DWORD ItemCount;
|
||||
DWORD SearchPhase; // 0 = initializing, 2 = searching, 4 = finished
|
||||
};
|
||||
|
||||
class TMndxFindResult
|
||||
{
|
||||
public:
|
||||
|
||||
TMndxFindResult();
|
||||
~TMndxFindResult();
|
||||
|
||||
int CreateStruct40();
|
||||
void FreeStruct40();
|
||||
|
||||
int SetSearchPath(const char * szNewSearchPath, size_t cchNewSearchPath);
|
||||
|
||||
const char * szSearchMask; // Search mask without wildcards
|
||||
size_t cchSearchMask; // Length of the search mask
|
||||
DWORD field_8;
|
||||
const char * szFoundPath; // Found path name
|
||||
size_t cchFoundPath; // Length of the found path name
|
||||
DWORD FileNameIndex; // Index of the file name
|
||||
TStruct40 * pStruct40;
|
||||
};
|
||||
|
||||
class TSparseArray
|
||||
{
|
||||
public:
|
||||
|
||||
TSparseArray();
|
||||
|
||||
void ExchangeWith(TSparseArray & TargetObject);
|
||||
int LoadFromStream(TByteStream & InStream);
|
||||
int LoadFromStream_Exchange(TByteStream & InStream);
|
||||
|
||||
// Returns true if the item at n-th position is present
|
||||
DWORD IsItemPresent(DWORD ItemIndex)
|
||||
{
|
||||
return (ItemBits.Uint32Array[ItemIndex >> 0x05] & (1 << (ItemIndex & 0x1F)));
|
||||
}
|
||||
|
||||
DWORD GetItemValue(DWORD ItemIndex);
|
||||
|
||||
TGenericArray ItemBits; // Bit array for each item (1 = item is present)
|
||||
DWORD TotalItemCount; // Total number of items in the array
|
||||
DWORD ValidItemCount; // Number of present items in the array
|
||||
TGenericArray BaseValues; // Array of base values for item indexes >= 0x200
|
||||
TGenericArray ArrayDwords_38;
|
||||
TGenericArray ArrayDwords_50;
|
||||
};
|
||||
|
||||
class TNameIndexStruct
|
||||
{
|
||||
public:
|
||||
|
||||
TNameIndexStruct();
|
||||
~TNameIndexStruct();
|
||||
|
||||
bool CheckNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
||||
bool CheckAndCopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
||||
void CopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
||||
|
||||
void ExchangeWith(TNameIndexStruct & Target);
|
||||
int LoadFromStream(TByteStream & InStream);
|
||||
int LoadFromStream_Exchange(TByteStream & InStream);
|
||||
|
||||
TGenericArray NameFragments;
|
||||
TSparseArray Struct68;
|
||||
};
|
||||
|
||||
class TStruct10
|
||||
{
|
||||
public:
|
||||
|
||||
TStruct10();
|
||||
|
||||
void CopyFrom(TStruct10 & Target);
|
||||
int sub_1956FD0(DWORD dwBitMask);
|
||||
int sub_1957050(DWORD dwBitMask);
|
||||
int sub_19572E0(DWORD dwBitMask);
|
||||
int sub_1957800(DWORD dwBitMask);
|
||||
|
||||
DWORD field_0;
|
||||
DWORD field_4;
|
||||
DWORD field_8;
|
||||
DWORD field_C;
|
||||
};
|
||||
|
||||
class TFileNameDatabasePtr
|
||||
{
|
||||
public:
|
||||
|
||||
TFileNameDatabasePtr();
|
||||
~TFileNameDatabasePtr();
|
||||
|
||||
int FindFileInDatabase(TMndxFindResult * pStruct1C);
|
||||
int sub_1956CE0(TMndxFindResult * pStruct1C, bool * pbFindResult);
|
||||
|
||||
int GetFileNameCount(PDWORD PtrFileNameCount);
|
||||
int CreateDatabase(LPBYTE pbMarData, DWORD cbMarData);
|
||||
int SetDatabase(TFileNameDatabase * pNewDB);
|
||||
|
||||
TFileNameDatabase * pDB;
|
||||
};
|
||||
|
||||
class TFileNameDatabase
|
||||
{
|
||||
public:
|
||||
|
||||
TFileNameDatabase();
|
||||
|
||||
void ExchangeWith(TFileNameDatabase & Target);
|
||||
int LoadFromStream(TByteStream & InStream);
|
||||
int LoadFromStream_Exchange(TByteStream & InStream);
|
||||
|
||||
DWORD sub_1959CB0(DWORD dwHashValue);
|
||||
DWORD sub_1959F50(DWORD arg_0);
|
||||
|
||||
// Retrieves the name fragment distance
|
||||
// HOTS: 19573D0/inlined
|
||||
DWORD GetNameFragmentOffsetEx(DWORD LoBitsIndex, DWORD HiBitsIndex)
|
||||
{
|
||||
return (FrgmDist_HiBits.GetBitEntry(HiBitsIndex) << 0x08) | FrgmDist_LoBits.ByteArray[LoBitsIndex];
|
||||
}
|
||||
|
||||
// HOTS: 1957350, inlined
|
||||
DWORD GetNameFragmentOffset(DWORD LoBitsIndex)
|
||||
{
|
||||
return GetNameFragmentOffsetEx(LoBitsIndex, Struct68_D0.GetItemValue(LoBitsIndex));
|
||||
}
|
||||
|
||||
bool sub_1957B80(TMndxFindResult * pStruct1C, DWORD dwKey);
|
||||
bool CheckNextPathFragment(TMndxFindResult * pStruct1C);
|
||||
bool FindFileInDatabase(TMndxFindResult * pStruct1C);
|
||||
|
||||
void sub_1958D70(TMndxFindResult * pStruct1C, DWORD arg_4);
|
||||
bool sub_1959010(TMndxFindResult * pStruct1C, DWORD arg_4);
|
||||
bool sub_1958B00(TMndxFindResult * pStruct1C);
|
||||
bool sub_1959460(TMndxFindResult * pStruct1C);
|
||||
|
||||
TSparseArray Struct68_00;
|
||||
TSparseArray FileNameIndexes; // Array of file name indexes
|
||||
TSparseArray Struct68_D0;
|
||||
|
||||
// This pair of arrays serves for fast conversion from name hash to fragment offset
|
||||
TGenericArray FrgmDist_LoBits; // Array of lower 8 bits of name fragment offset
|
||||
TBitEntryArray FrgmDist_HiBits; // Array of upper x bits of name fragment offset
|
||||
|
||||
TNameIndexStruct IndexStruct_174;
|
||||
TFileNameDatabasePtr NextDB;
|
||||
|
||||
TGenericArray NameFragTable;
|
||||
|
||||
DWORD NameFragIndexMask;
|
||||
DWORD field_214;
|
||||
TStruct10 Struct10;
|
||||
TByteStream MarStream;
|
||||
};
|
||||
|
||||
typedef struct _MAR_FILE
|
||||
{
|
||||
TFileNameDatabasePtr * pDatabasePtr;
|
||||
LPBYTE pbMarData;
|
||||
DWORD cbMarData;
|
||||
} MAR_FILE, *PMAR_FILE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros
|
||||
|
||||
// Returns nonzero if the name fragment match is a single-char match
|
||||
inline bool IS_SINGLE_CHAR_MATCH(TGenericArray & Table, DWORD ItemIndex)
|
||||
{
|
||||
return ((Table.NameFragArray[ItemIndex].FragOffs & 0xFFFFFF00) == 0xFFFFFF00);
|
||||
}
|
||||
|
||||
#endif // __CASC_MNDX_ROOT__
|
||||
322
dep/CascLib/src/CascOpenFile.cpp
Normal file
322
dep/CascLib/src/CascOpenFile.cpp
Normal file
@@ -0,0 +1,322 @@
|
||||
/*****************************************************************************/
|
||||
/* CascOpenFile.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* System-dependent directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 01.05.14 1.00 Lad The first version of CascOpenFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
TCascFile * IsValidFileHandle(HANDLE hFile)
|
||||
{
|
||||
TCascFile * hf = (TCascFile *)hFile;
|
||||
|
||||
return (hf != NULL && hf->hs != NULL && hf->szClassName != NULL && !strcmp(hf->szClassName, "TCascFile")) ? hf : NULL;
|
||||
}
|
||||
|
||||
PCASC_INDEX_ENTRY FindIndexEntry(TCascStorage * hs, PQUERY_KEY pIndexKey)
|
||||
{
|
||||
PCASC_INDEX_ENTRY pIndexEntry = NULL;
|
||||
|
||||
if(hs->pIndexEntryMap != NULL)
|
||||
pIndexEntry = (PCASC_INDEX_ENTRY)Map_FindObject(hs->pIndexEntryMap, pIndexKey->pbData, NULL);
|
||||
|
||||
return pIndexEntry;
|
||||
}
|
||||
|
||||
PCASC_ENCODING_ENTRY FindEncodingEntry(TCascStorage * hs, PQUERY_KEY pEncodingKey, PDWORD PtrIndex)
|
||||
{
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry = NULL;
|
||||
|
||||
if(hs->pEncodingMap != NULL)
|
||||
pEncodingEntry = (PCASC_ENCODING_ENTRY)Map_FindObject(hs->pEncodingMap, pEncodingKey->pbData, PtrIndex);
|
||||
|
||||
return pEncodingEntry;
|
||||
}
|
||||
|
||||
static TCascFile * CreateFileHandle(TCascStorage * hs, PCASC_INDEX_ENTRY pIndexEntry)
|
||||
{
|
||||
ULONGLONG FileOffsMask = ((ULONGLONG)1 << hs->KeyMapping[0].SegmentBits) - 1;
|
||||
ULONGLONG FileOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffsetBE);
|
||||
TCascFile * hf;
|
||||
|
||||
// Allocate the CASC file structure
|
||||
hf = (TCascFile *)CASC_ALLOC(TCascFile, 1);
|
||||
if(hf != NULL)
|
||||
{
|
||||
// Initialize the structure
|
||||
memset(hf, 0, sizeof(TCascFile));
|
||||
hf->ArchiveIndex = (DWORD)(FileOffset >> hs->KeyMapping[0].SegmentBits);
|
||||
hf->HeaderOffset = (DWORD)(FileOffset & FileOffsMask);
|
||||
hf->szClassName = "TCascFile";
|
||||
|
||||
// Copy the file size. Note that for all files except ENCODING,
|
||||
// this is the compressed file size
|
||||
hf->CompressedSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSizeLE);
|
||||
|
||||
// For now, we set the file size to be equal to compressed size
|
||||
// This is used when loading the ENCODING file, which does not
|
||||
// have entry in the encoding table
|
||||
hf->FileSize = hf->CompressedSize;
|
||||
|
||||
// Increment the number of references to the archive
|
||||
hs->dwRefCount++;
|
||||
hf->hs = hs;
|
||||
}
|
||||
|
||||
return hf;
|
||||
}
|
||||
|
||||
static bool OpenFileByIndexKey(TCascStorage * hs, PQUERY_KEY pIndexKey, DWORD dwFlags, TCascFile ** ppCascFile)
|
||||
{
|
||||
PCASC_INDEX_ENTRY pIndexEntry;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
CASCLIB_UNUSED(dwFlags);
|
||||
|
||||
// Find the key entry in the array of file keys
|
||||
pIndexEntry = FindIndexEntry(hs, pIndexKey);
|
||||
if(pIndexEntry == NULL)
|
||||
nError = ERROR_FILE_NOT_FOUND;
|
||||
|
||||
// Create the file handle structure
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
ppCascFile[0] = CreateFileHandle(hs, pIndexEntry);
|
||||
if(ppCascFile[0] == NULL)
|
||||
nError = ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef CASCLIB_TEST
|
||||
if(nError == ERROR_SUCCESS && ppCascFile[0] != NULL)
|
||||
{
|
||||
ppCascFile[0]->FileSize_IdxEntry = ConvertBytesToInteger_4_LE(pIndexEntry->FileSizeLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
return (nError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static bool OpenFileByEncodingKey(TCascStorage * hs, PQUERY_KEY pEncodingKey, DWORD dwFlags, TCascFile ** ppCascFile)
|
||||
{
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry;
|
||||
QUERY_KEY IndexKey;
|
||||
|
||||
// Find the encoding entry
|
||||
pEncodingEntry = FindEncodingEntry(hs, pEncodingKey, NULL);
|
||||
if(pEncodingEntry == NULL)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare the file index and open the file by index
|
||||
// Note: We don't know what to do if there is more than just one index key
|
||||
// We always take the first file present. Is that correct?
|
||||
IndexKey.pbData = GET_INDEX_KEY(pEncodingEntry);
|
||||
IndexKey.cbData = MD5_HASH_SIZE;
|
||||
if(OpenFileByIndexKey(hs, &IndexKey, dwFlags, ppCascFile))
|
||||
{
|
||||
// Check if the file handle was created
|
||||
if(ppCascFile[0] != NULL)
|
||||
{
|
||||
// Fill-in the file size. For all files except ENCODING,
|
||||
// this overrides the value stored in the index entry.
|
||||
ppCascFile[0]->FileSize = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBE);
|
||||
|
||||
#ifdef CASCLIB_TEST
|
||||
ppCascFile[0]->FileSize_EncEntry = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBE);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
bool WINAPI CascOpenFileByIndexKey(HANDLE hStorage, PQUERY_KEY pIndexKey, DWORD dwFlags, HANDLE * phFile)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
|
||||
// Validate the storage handle
|
||||
hs = IsValidStorageHandle(hStorage);
|
||||
if(hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the other parameters
|
||||
if(pIndexKey == NULL || pIndexKey->pbData == NULL || pIndexKey->cbData == 0 || phFile == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the internal function to open the file
|
||||
return OpenFileByIndexKey(hs, pIndexKey, dwFlags, (TCascFile **)phFile);
|
||||
}
|
||||
|
||||
bool WINAPI CascOpenFileByEncodingKey(HANDLE hStorage, PQUERY_KEY pEncodingKey, DWORD dwFlags, HANDLE * phFile)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
|
||||
// Validate the storage handle
|
||||
hs = IsValidStorageHandle(hStorage);
|
||||
if(hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the other parameters
|
||||
if(pEncodingKey == NULL || pEncodingKey->pbData == NULL || pEncodingKey->cbData == 0 || phFile == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the internal function fo open the file
|
||||
return OpenFileByEncodingKey(hs, pEncodingKey, dwFlags, (TCascFile **)phFile);
|
||||
}
|
||||
|
||||
bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocale, DWORD dwFlags, HANDLE * phFile)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
QUERY_KEY EncodingKey;
|
||||
LPBYTE pbEncodingKey;
|
||||
BYTE KeyBuffer[MD5_HASH_SIZE];
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
CASCLIB_UNUSED(dwLocale);
|
||||
|
||||
// Validate the storage handle
|
||||
hs = IsValidStorageHandle(hStorage);
|
||||
if(hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the other parameters
|
||||
if(szFileName == NULL || szFileName[0] == 0 || phFile == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the user is opening the file via encoding key, skip the ROOT file processing
|
||||
if((dwFlags & CASC_OPEN_BY_ENCODING_KEY) == 0)
|
||||
{
|
||||
// Let the root directory provider get us the encoding key
|
||||
pbEncodingKey = RootHandler_GetKey(hs->pRootHandler, szFileName);
|
||||
if(pbEncodingKey == NULL)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup the encoding key
|
||||
EncodingKey.pbData = pbEncodingKey;
|
||||
EncodingKey.cbData = MD5_HASH_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check the length of the file name
|
||||
if(strlen(szFileName) < MD5_STRING_SIZE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert the file name to binary blob
|
||||
EncodingKey.pbData = KeyBuffer;
|
||||
EncodingKey.cbData = MD5_HASH_SIZE;
|
||||
nError = ConvertStringToBinary(szFileName, MD5_STRING_SIZE, KeyBuffer);
|
||||
}
|
||||
|
||||
// Use the encoding key to find the file in the encoding table entry
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(!OpenFileByEncodingKey(hs, &EncodingKey, dwFlags, (TCascFile **)phFile))
|
||||
{
|
||||
assert(GetLastError() != ERROR_SUCCESS);
|
||||
nError = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CASCLIB_TEST
|
||||
// if(phFile[0] != NULL && pRootEntryMndx != NULL)
|
||||
// {
|
||||
// ((TCascFile *)(phFile[0]))->FileSize_RootEntry = pRootEntryMndx->FileSize;
|
||||
// }
|
||||
#endif
|
||||
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
return (nError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
DWORD WINAPI CascGetFileId(HANDLE hStorage, const char * szFileName)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
|
||||
// Validate the storage handle
|
||||
hs = IsValidStorageHandle(hStorage);
|
||||
if (hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the other parameters
|
||||
if (szFileName == NULL || szFileName[0] == 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
return RootHandler_GetFileId(hs->pRootHandler, szFileName);
|
||||
}
|
||||
|
||||
bool WINAPI CascCloseFile(HANDLE hFile)
|
||||
{
|
||||
TCascFile * hf;
|
||||
|
||||
hf = IsValidFileHandle(hFile);
|
||||
if(hf != NULL)
|
||||
{
|
||||
// Close (dereference) the archive handle
|
||||
if(hf->hs != NULL)
|
||||
CascCloseStorage((HANDLE)hf->hs);
|
||||
hf->hs = NULL;
|
||||
|
||||
// Free the file cache and frame array
|
||||
if(hf->pbFileCache != NULL)
|
||||
CASC_FREE(hf->pbFileCache);
|
||||
if(hf->pFrames != NULL)
|
||||
CASC_FREE(hf->pFrames);
|
||||
|
||||
// Free the structure itself
|
||||
hf->szClassName = NULL;
|
||||
CASC_FREE(hf);
|
||||
return true;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
1200
dep/CascLib/src/CascOpenStorage.cpp
Normal file
1200
dep/CascLib/src/CascOpenStorage.cpp
Normal file
File diff suppressed because it is too large
Load Diff
276
dep/CascLib/src/CascPort.h
Normal file
276
dep/CascLib/src/CascPort.h
Normal file
@@ -0,0 +1,276 @@
|
||||
/*****************************************************************************/
|
||||
/* CascPort.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Portability module for the CascLib library. Contains a wrapper symbols */
|
||||
/* to make the compilation under Linux work */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __CASCPORT_H__
|
||||
#define __CASCPORT_H__
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define bool char
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines for Windows
|
||||
|
||||
#if !defined(PLATFORM_DEFINED) && (defined(_WIN32) || defined(_WIN64))
|
||||
|
||||
// In MSVC 8.0, there are some functions declared as deprecated.
|
||||
#if _MSC_VER >= 1400
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#define _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <tchar.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include <sys/types.h>
|
||||
#define PLATFORM_LITTLE_ENDIAN
|
||||
|
||||
#ifdef _WIN64
|
||||
#define PLATFORM_64BIT
|
||||
#else
|
||||
#define PLATFORM_32BIT
|
||||
#endif
|
||||
|
||||
#define PATH_SEPARATOR '\\'
|
||||
#define CREATE_DIRECTORY(name) CreateDirectory(name, NULL);
|
||||
|
||||
#define PLATFORM_WINDOWS
|
||||
#define PLATFORM_DEFINED // The platform is known now
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines for Mac
|
||||
|
||||
#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac BSD API
|
||||
|
||||
// Macintosh
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Support for PowerPC on Max OS X
|
||||
#if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1)
|
||||
#include <stdint.h>
|
||||
#include <CoreFoundation/CFByteOrder.h>
|
||||
#endif
|
||||
|
||||
#define PKEXPORT
|
||||
#define __SYS_ZLIB
|
||||
#define __SYS_BZLIB
|
||||
|
||||
#ifndef __BIG_ENDIAN__
|
||||
#define PLATFORM_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#define PATH_SEPARATOR '/'
|
||||
#define CREATE_DIRECTORY(name) mkdir(name, 0755)
|
||||
|
||||
#define PLATFORM_MAC
|
||||
#define PLATFORM_DEFINED // The platform is known now
|
||||
|
||||
#define FIELD_OFFSET(t,f) offsetof(t,f)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin*
|
||||
|
||||
#if !defined(PLATFORM_DEFINED)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define PATH_SEPARATOR '/'
|
||||
#define CREATE_DIRECTORY(name) mkdir(name, 0755)
|
||||
|
||||
#define PLATFORM_LITTLE_ENDIAN
|
||||
#define PLATFORM_LINUX
|
||||
#define PLATFORM_DEFINED
|
||||
|
||||
#define FIELD_OFFSET(t,f) offsetof(t,f)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Definition of Windows-specific types for non-Windows platforms
|
||||
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
#if __LP64__
|
||||
#define PLATFORM_64BIT
|
||||
#else
|
||||
#define PLATFORM_32BIT
|
||||
#endif
|
||||
|
||||
// Typedefs for ANSI C
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short USHORT;
|
||||
typedef int LONG;
|
||||
typedef unsigned int DWORD;
|
||||
typedef unsigned long DWORD_PTR;
|
||||
typedef long LONG_PTR;
|
||||
typedef long INT_PTR;
|
||||
typedef long long LONGLONG;
|
||||
typedef unsigned long long ULONGLONG;
|
||||
typedef unsigned long long *PULONGLONG;
|
||||
typedef void * HANDLE;
|
||||
typedef void * LPOVERLAPPED; // Unsupported on Linux and Mac
|
||||
typedef char TCHAR;
|
||||
typedef unsigned int LCID;
|
||||
typedef LONG * PLONG;
|
||||
typedef DWORD * PDWORD;
|
||||
typedef BYTE * LPBYTE;
|
||||
typedef char * LPSTR;
|
||||
|
||||
#ifdef PLATFORM_32BIT
|
||||
#define _LZMA_UINT32_IS_ULONG
|
||||
#endif
|
||||
|
||||
// Some Windows-specific defines
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
#define WINAPI
|
||||
|
||||
#define FILE_BEGIN SEEK_SET
|
||||
#define FILE_CURRENT SEEK_CUR
|
||||
#define FILE_END SEEK_END
|
||||
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
|
||||
|
||||
#define _T(x) x
|
||||
#define _tcslen strlen
|
||||
#define _tcscpy strcpy
|
||||
#define _tcscat strcat
|
||||
#define _tcschr strchr
|
||||
#define _tcsrchr strrchr
|
||||
#define _tcsstr strstr
|
||||
#define _tcsspn strspn
|
||||
#define _tcsncmp strncmp
|
||||
#define _tprintf printf
|
||||
#define _stprintf sprintf
|
||||
#define _tremove remove
|
||||
#define _tmkdir mkdir
|
||||
|
||||
#define _stricmp strcasecmp
|
||||
#define _strnicmp strncasecmp
|
||||
#define _tcsicmp strcasecmp
|
||||
#define _tcsnicmp strncasecmp
|
||||
|
||||
#endif // !PLATFORM_WINDOWS
|
||||
|
||||
// 64-bit calls are supplied by "normal" calls on Mac
|
||||
#if defined(PLATFORM_MAC)
|
||||
#define stat64 stat
|
||||
#define fstat64 fstat
|
||||
#define lseek64 lseek
|
||||
#define ftruncate64 ftruncate
|
||||
#define off64_t off_t
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
// Platform-specific error codes for UNIX-based platforms
|
||||
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
|
||||
#define ERROR_SUCCESS 0
|
||||
#define ERROR_FILE_NOT_FOUND ENOENT
|
||||
#define ERROR_ACCESS_DENIED EPERM
|
||||
#define ERROR_INVALID_HANDLE EBADF
|
||||
#define ERROR_NOT_ENOUGH_MEMORY ENOMEM
|
||||
#define ERROR_NOT_SUPPORTED ENOTSUP
|
||||
#define ERROR_INVALID_PARAMETER EINVAL
|
||||
#define ERROR_DISK_FULL ENOSPC
|
||||
#define ERROR_ALREADY_EXISTS EEXIST
|
||||
#define ERROR_INSUFFICIENT_BUFFER ENOBUFS
|
||||
#define ERROR_BAD_FORMAT 1000 // No such error code under Linux
|
||||
#define ERROR_NO_MORE_FILES 1001 // No such error code under Linux
|
||||
#define ERROR_HANDLE_EOF 1002 // No such error code under Linux
|
||||
#define ERROR_CAN_NOT_COMPLETE 1003 // No such error code under Linux
|
||||
#define ERROR_FILE_CORRUPT 1004 // No such error code under Linux
|
||||
#define ERROR_FILE_ENCRYPTED 1005 // Returned by encrypted stream when can't find file key
|
||||
#endif
|
||||
|
||||
#ifndef ERROR_FILE_INCOMPLETE
|
||||
#define ERROR_FILE_INCOMPLETE 1006 // The required file part is missing
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swapping functions
|
||||
|
||||
#ifdef PLATFORM_LITTLE_ENDIAN
|
||||
#define BSWAP_INT16_UNSIGNED(a) (a)
|
||||
#define BSWAP_INT16_SIGNED(a) (a)
|
||||
#define BSWAP_INT32_UNSIGNED(a) (a)
|
||||
#define BSWAP_INT32_SIGNED(a) (a)
|
||||
#define BSWAP_INT64_SIGNED(a) (a)
|
||||
#define BSWAP_INT64_UNSIGNED(a) (a)
|
||||
#define BSWAP_ARRAY16_UNSIGNED(a,b) {}
|
||||
#define BSWAP_ARRAY32_UNSIGNED(a,b) {}
|
||||
#define BSWAP_ARRAY64_UNSIGNED(a,b) {}
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int16_t SwapInt16(uint16_t);
|
||||
uint16_t SwapUInt16(uint16_t);
|
||||
int32_t SwapInt32(uint32_t);
|
||||
uint32_t SwapUInt32(uint32_t);
|
||||
int64_t SwapInt64(uint64_t);
|
||||
uint64_t SwapUInt64(uint64_t);
|
||||
void ConvertUInt16Buffer(void * ptr, size_t length);
|
||||
void ConvertUInt32Buffer(void * ptr, size_t length);
|
||||
void ConvertUInt64Buffer(void * ptr, size_t length);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#define BSWAP_INT16_SIGNED(a) SwapInt16((a))
|
||||
#define BSWAP_INT16_UNSIGNED(a) SwapUInt16((a))
|
||||
#define BSWAP_INT32_SIGNED(a) SwapInt32((a))
|
||||
#define BSWAP_INT32_UNSIGNED(a) SwapUInt32((a))
|
||||
#define BSWAP_INT64_SIGNED(a) SwapInt64((a))
|
||||
#define BSWAP_INT64_UNSIGNED(a) SwapUInt64((a))
|
||||
#define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUInt16Buffer((a),(b))
|
||||
#define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUInt32Buffer((a),(b))
|
||||
#define BSWAP_ARRAY64_UNSIGNED(a,b) ConvertUInt64Buffer((a),(b))
|
||||
#endif
|
||||
|
||||
#endif // __CASCPORT_H__
|
||||
620
dep/CascLib/src/CascReadFile.cpp
Normal file
620
dep/CascLib/src/CascReadFile.cpp
Normal file
@@ -0,0 +1,620 @@
|
||||
/*****************************************************************************/
|
||||
/* CascOpenFile.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* System-dependent directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 01.05.14 1.00 Lad The first version of CascOpenFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures
|
||||
|
||||
typedef struct _BLTE_FRAME
|
||||
{
|
||||
BYTE CompressedSize[4]; // Compressed file size as big endian
|
||||
BYTE FrameSize[4]; // File size as big endian
|
||||
BYTE md5[MD5_HASH_SIZE]; // Hash of the compressed frame
|
||||
|
||||
} BLTE_FRAME, *PBLTE_FRAME;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
TCascFile * IsValidFileHandle(HANDLE hFile); // In CascOpenFile.cpp
|
||||
|
||||
static int EnsureDataStreamIsOpen(TCascFile * hf)
|
||||
{
|
||||
TCascStorage * hs = hf->hs;
|
||||
TFileStream * pStream = NULL;
|
||||
TCHAR * szDataFile;
|
||||
TCHAR szPlainName[0x40];
|
||||
|
||||
// If the file is not open yet, do it
|
||||
if(hs->DataFileArray[hf->ArchiveIndex] == NULL)
|
||||
{
|
||||
// Prepare the name of the data file
|
||||
_stprintf(szPlainName, _T("data.%03u"), hf->ArchiveIndex);
|
||||
szDataFile = CombinePath(hs->szIndexPath, szPlainName);
|
||||
|
||||
// Open the data file
|
||||
if(szDataFile != NULL)
|
||||
{
|
||||
// Open the stream
|
||||
pStream = FileStream_OpenFile(szDataFile, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
|
||||
hs->DataFileArray[hf->ArchiveIndex] = pStream;
|
||||
CASC_FREE(szDataFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Return error or success
|
||||
hf->pStream = hs->DataFileArray[hf->ArchiveIndex];
|
||||
return (hf->pStream != NULL) ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int LoadFileFrames(TCascFile * hf)
|
||||
{
|
||||
PBLTE_FRAME pFileFrames;
|
||||
PBLTE_FRAME pFileFrame;
|
||||
ULONGLONG ArchiveFileOffset;
|
||||
DWORD FrameOffset = 0;
|
||||
DWORD FileSize = 0;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
assert(hf != NULL);
|
||||
assert(hf->pStream != NULL);
|
||||
assert(hf->pFrames != NULL);
|
||||
|
||||
// Allocate frame array
|
||||
pFileFrames = pFileFrame = CASC_ALLOC(BLTE_FRAME, hf->FrameCount);
|
||||
if(pFileFrames != NULL)
|
||||
{
|
||||
// Load the frame array
|
||||
ArchiveFileOffset = hf->FramesOffset;
|
||||
if(FileStream_Read(hf->pStream, &ArchiveFileOffset, pFileFrames, hf->FrameCount * sizeof(BLTE_FRAME)))
|
||||
{
|
||||
// Move the raw archive offset
|
||||
ArchiveFileOffset += (hf->FrameCount * sizeof(BLTE_FRAME));
|
||||
|
||||
// Copy the frames to the file structure
|
||||
for(DWORD i = 0; i < hf->FrameCount; i++, pFileFrame++)
|
||||
{
|
||||
hf->pFrames[i].FrameArchiveOffset = (DWORD)ArchiveFileOffset;
|
||||
hf->pFrames[i].FrameFileOffset = FrameOffset;
|
||||
hf->pFrames[i].CompressedSize = ConvertBytesToInteger_4(pFileFrame->CompressedSize);
|
||||
hf->pFrames[i].FrameSize = ConvertBytesToInteger_4(pFileFrame->FrameSize);
|
||||
memcpy(hf->pFrames[i].md5, pFileFrame->md5, MD5_HASH_SIZE);
|
||||
|
||||
ArchiveFileOffset += hf->pFrames[i].CompressedSize;
|
||||
FrameOffset += hf->pFrames[i].FrameSize;
|
||||
FileSize += hf->pFrames[i].FrameSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
nError = GetLastError();
|
||||
|
||||
// Note: on ENCODING file, this value is almost always bigger
|
||||
// then the real size of ENCODING. We handle this problem
|
||||
// by calculating size of the ENCODIG file from its header.
|
||||
hf->FileSize = FileSize;
|
||||
|
||||
#ifdef CASCLIB_TEST
|
||||
hf->FileSize_FrameSum = FileSize;
|
||||
#endif
|
||||
|
||||
// Free the array
|
||||
CASC_FREE(pFileFrames);
|
||||
}
|
||||
else
|
||||
nError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
return nError;
|
||||
}
|
||||
|
||||
static int EnsureHeaderAreaIsLoaded(TCascFile * hf)
|
||||
{
|
||||
TCascStorage * hs = hf->hs;
|
||||
ULONGLONG FileOffset = hf->HeaderOffset;
|
||||
LPBYTE pbHeaderArea;
|
||||
DWORD FileSignature;
|
||||
DWORD FileSize;
|
||||
BYTE HeaderArea[MAX_HEADER_AREA_SIZE];
|
||||
int nError;
|
||||
|
||||
// We need the data file to be open
|
||||
nError = EnsureDataStreamIsOpen(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Make sure that we already know the shift
|
||||
// to the begin of file data.
|
||||
// Note that older builds of Heroes of the Storm have entries pointing
|
||||
// to the beginning of the header area.
|
||||
// Newer versions of HOTS have encoding entries pointing directly to
|
||||
// the BLTE header
|
||||
if(hs->dwFileBeginDelta == 0xFFFFFFFF)
|
||||
{
|
||||
FileSignature = 0;
|
||||
FileOffset = hf->HeaderOffset;
|
||||
if(!FileStream_Read(hf->pStream, &FileOffset, &FileSignature, sizeof(DWORD)))
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
hs->dwFileBeginDelta = (FileSignature == BLTE_HEADER_SIGNATURE) ? BLTE_HEADER_DELTA : 0;
|
||||
}
|
||||
|
||||
// If the file size is not loaded yet, do it
|
||||
if(hf->FrameCount == 0)
|
||||
{
|
||||
// Load the part before BLTE header + header itself
|
||||
FileOffset = hf->HeaderOffset - hs->dwFileBeginDelta;
|
||||
if(!FileStream_Read(hf->pStream, &FileOffset, HeaderArea, sizeof(HeaderArea)))
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
// Copy the MD5 hash of the frame array
|
||||
memcpy(hf->FrameArrayHash, HeaderArea, MD5_HASH_SIZE);
|
||||
pbHeaderArea = HeaderArea + MD5_HASH_SIZE;
|
||||
|
||||
// Copy the file size
|
||||
FileSize = ConvertBytesToInteger_4_LE(pbHeaderArea);
|
||||
pbHeaderArea += 0x0E;
|
||||
|
||||
// Verify the BLTE signature
|
||||
if(ConvertBytesToInteger_4_LE(pbHeaderArea) != BLTE_HEADER_SIGNATURE)
|
||||
return ERROR_BAD_FORMAT;
|
||||
pbHeaderArea += sizeof(DWORD);
|
||||
|
||||
// Load the size of the frame headers
|
||||
hf->HeaderSize = ConvertBytesToInteger_4(pbHeaderArea);
|
||||
if(hf->HeaderSize & 0x80000000)
|
||||
return ERROR_BAD_FORMAT;
|
||||
pbHeaderArea += sizeof(DWORD);
|
||||
|
||||
// Read the header size
|
||||
assert(hs->dwFileBeginDelta <= BLTE_HEADER_DELTA);
|
||||
hf->HeaderOffset += (BLTE_HEADER_DELTA - hs->dwFileBeginDelta);
|
||||
hf->FrameCount = 1;
|
||||
|
||||
// Retrieve the frame count, if different from 1
|
||||
if(hf->HeaderSize != 0)
|
||||
{
|
||||
// The next byte must be 0x0F
|
||||
if(pbHeaderArea[0] != 0x0F)
|
||||
return ERROR_BAD_FORMAT;
|
||||
pbHeaderArea++;
|
||||
|
||||
// Next three bytes form number of frames
|
||||
hf->FrameCount = ConvertBytesToInteger_3(pbHeaderArea);
|
||||
}
|
||||
|
||||
#ifdef CASCLIB_TEST
|
||||
hf->FileSize_HdrArea = FileSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static int EnsureFrameHeadersLoaded(TCascFile * hf)
|
||||
{
|
||||
int nError;
|
||||
|
||||
// Make sure we have header area loaded
|
||||
nError = EnsureHeaderAreaIsLoaded(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// If the frame headers are not loaded yet, do it
|
||||
if(hf->pFrames == NULL)
|
||||
{
|
||||
// Allocate the frame array
|
||||
hf->pFrames = CASC_ALLOC(CASC_FILE_FRAME, hf->FrameCount);
|
||||
if(hf->pFrames != NULL)
|
||||
{
|
||||
// Either load the frames from the file or supply them on our own
|
||||
if(hf->HeaderSize != 0)
|
||||
{
|
||||
hf->FramesOffset = hf->HeaderOffset + sizeof(DWORD) + sizeof(DWORD) + sizeof(DWORD);
|
||||
nError = LoadFileFrames(hf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Offset of the first frame is right after the file frames
|
||||
hf->FramesOffset = hf->HeaderOffset + sizeof(DWORD) + sizeof(DWORD);
|
||||
|
||||
hf->pFrames[0].FrameArchiveOffset = hf->FramesOffset;
|
||||
hf->pFrames[0].FrameFileOffset = 0;
|
||||
hf->pFrames[0].CompressedSize = hf->CompressedSize;
|
||||
hf->pFrames[0].FrameSize = hf->FileSize;
|
||||
memset(hf->pFrames[0].md5, 0, MD5_HASH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Return result
|
||||
return (hf->pFrames != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static PCASC_FILE_FRAME FindFileFrame(TCascFile * hf, DWORD FilePointer)
|
||||
{
|
||||
PCASC_FILE_FRAME pFrame = hf->pFrames;
|
||||
DWORD FrameBegin;
|
||||
DWORD FrameEnd;
|
||||
|
||||
// Sanity checks
|
||||
assert(hf->pFrames != NULL);
|
||||
assert(hf->FrameCount != 0);
|
||||
|
||||
// Find the frame where to read from
|
||||
for(DWORD i = 0; i < hf->FrameCount; i++, pFrame++)
|
||||
{
|
||||
// Does the read request fit into the current frame?
|
||||
FrameBegin = pFrame->FrameFileOffset;
|
||||
FrameEnd = FrameBegin + pFrame->FrameSize;
|
||||
if(FrameBegin <= FilePointer && FilePointer < FrameEnd)
|
||||
return pFrame;
|
||||
}
|
||||
|
||||
// Not found, sorry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ProcessFileFrame(
|
||||
LPBYTE pbOutBuffer,
|
||||
DWORD cbOutBuffer,
|
||||
LPBYTE pbInBuffer,
|
||||
DWORD cbInBuffer,
|
||||
DWORD dwFrameIndex)
|
||||
{
|
||||
LPBYTE pbTempBuffer;
|
||||
LPBYTE pbWorkBuffer;
|
||||
DWORD cbTempBuffer = CASCLIB_MAX(cbInBuffer, cbOutBuffer);
|
||||
DWORD cbWorkBuffer = cbOutBuffer + 1;
|
||||
DWORD dwStepCount = 0;
|
||||
bool bWorkComplete = false;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Allocate the temporary buffer that will serve as output
|
||||
pbWorkBuffer = pbTempBuffer = CASC_ALLOC(BYTE, cbTempBuffer);
|
||||
if(pbWorkBuffer == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Perform the loop
|
||||
for(;;)
|
||||
{
|
||||
// Set the output buffer.
|
||||
// Even operations: extract to temporary buffer
|
||||
// Odd operations: extract to output buffer
|
||||
pbWorkBuffer = (dwStepCount & 0x01) ? pbOutBuffer : pbTempBuffer;
|
||||
cbWorkBuffer = (dwStepCount & 0x01) ? cbOutBuffer : cbTempBuffer;
|
||||
|
||||
// Perform the operation specific to the operation ID
|
||||
switch(pbInBuffer[0])
|
||||
{
|
||||
case 'E': // Encrypted files
|
||||
nError = CascDecrypt(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1, dwFrameIndex);
|
||||
bWorkComplete = (nError != ERROR_SUCCESS);
|
||||
break;
|
||||
|
||||
case 'Z': // ZLIB compressed files
|
||||
nError = CascDecompress(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1);
|
||||
bWorkComplete = true;
|
||||
break;
|
||||
|
||||
case 'N': // Normal stored files
|
||||
nError = CascDirectCopy(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1);
|
||||
bWorkComplete = true;
|
||||
break;
|
||||
|
||||
case 'F': // Recursive frames - not supported
|
||||
default: // Unrecognized - if we unpacked something, we consider it done
|
||||
nError = ERROR_NOT_SUPPORTED;
|
||||
bWorkComplete = true;
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Are we done?
|
||||
if(bWorkComplete)
|
||||
break;
|
||||
|
||||
// Set the input buffer to the work buffer
|
||||
pbInBuffer = pbWorkBuffer;
|
||||
cbInBuffer = cbWorkBuffer;
|
||||
dwStepCount++;
|
||||
}
|
||||
|
||||
// If the data are currently in the temporary buffer,
|
||||
// we need to copy them to output buffer
|
||||
if(nError == ERROR_SUCCESS && pbWorkBuffer != pbOutBuffer)
|
||||
{
|
||||
if(cbWorkBuffer != cbOutBuffer)
|
||||
nError = ERROR_INSUFFICIENT_BUFFER;
|
||||
memcpy(pbOutBuffer, pbWorkBuffer, cbOutBuffer);
|
||||
}
|
||||
|
||||
// Free the temporary buffer
|
||||
CASC_FREE(pbTempBuffer);
|
||||
return nError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
//
|
||||
// THE FILE SIZE PROBLEM
|
||||
//
|
||||
// There are members called "FileSize" in many CASC-related structure
|
||||
// For various files, these variables have different meaning.
|
||||
//
|
||||
// Storage FileName FileSize FrameSum HdrArea IdxEntry EncEntry RootEntry
|
||||
// ----------- -------- ---------- -------- -------- -------- -------- ---------
|
||||
// HotS(29049) ENCODING 0x0024BA45 - 0x0024b98a 0x0024BA45 0x0024BA45 n/a n/a
|
||||
// HotS(29049) ROOT 0x00193340 - 0x00193340 0x0010db65 0x0010db65 0x00193340 n/a
|
||||
// HotS(29049) (other) 0x00001080 - 0x00001080 0x000008eb 0x000008eb 0x00001080 0x00001080
|
||||
//
|
||||
// WoW(18888) ENCODING 0x030d487b - 0x030dee79 0x030d487b 0x030d487b n/a n/a
|
||||
// WoW(18888) ROOT 0x016a9800 - n/a 0x0131313d 0x0131313d 0x016a9800 n/a
|
||||
// WoW(18888) (other) 0x000007d0 - 0x000007d0 0x00000397 0x00000397 0x000007d0 n/a
|
||||
//
|
||||
|
||||
DWORD WINAPI CascGetFileSize(HANDLE hFile, PDWORD pdwFileSizeHigh)
|
||||
{
|
||||
TCascFile * hf;
|
||||
int nError;
|
||||
|
||||
CASCLIB_UNUSED(pdwFileSizeHigh);
|
||||
|
||||
// Validate the file handle
|
||||
if((hf = IsValidFileHandle(hFile)) == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return CASC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
// Make sure that the file header area is loaded
|
||||
nError = EnsureFrameHeadersLoaded(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(nError);
|
||||
return CASC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
// Give the file size to the caller
|
||||
if(pdwFileSizeHigh != NULL)
|
||||
*pdwFileSizeHigh = 0;
|
||||
return hf->FileSize;
|
||||
}
|
||||
|
||||
DWORD WINAPI CascSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod)
|
||||
{
|
||||
TCascFile * hf;
|
||||
ULONGLONG FilePosition;
|
||||
ULONGLONG MoveOffset;
|
||||
DWORD dwFilePosHi;
|
||||
|
||||
// If the hFile is not a valid file handle, return an error.
|
||||
hf = IsValidFileHandle(hFile);
|
||||
if(hf == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return CASC_INVALID_POS;
|
||||
}
|
||||
|
||||
// Get the relative point where to move from
|
||||
switch(dwMoveMethod)
|
||||
{
|
||||
case FILE_BEGIN:
|
||||
FilePosition = 0;
|
||||
break;
|
||||
|
||||
case FILE_CURRENT:
|
||||
FilePosition = hf->FilePointer;
|
||||
break;
|
||||
|
||||
case FILE_END:
|
||||
FilePosition = hf->FileSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return CASC_INVALID_POS;
|
||||
}
|
||||
|
||||
// Now get the move offset. Note that both values form
|
||||
// a signed 64-bit value (a file pointer can be moved backwards)
|
||||
if(plFilePosHigh != NULL)
|
||||
dwFilePosHi = *plFilePosHigh;
|
||||
else
|
||||
dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0;
|
||||
MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos);
|
||||
|
||||
// Now calculate the new file pointer
|
||||
// Do not allow the file pointer to overflow
|
||||
FilePosition = ((FilePosition + MoveOffset) >= FilePosition) ? (FilePosition + MoveOffset) : 0;
|
||||
|
||||
// CASC files can't be bigger than 4 GB.
|
||||
// We don't allow to go past 4 GB
|
||||
if(FilePosition >> 32)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return CASC_INVALID_POS;
|
||||
}
|
||||
|
||||
// Change the file position
|
||||
hf->FilePointer = (DWORD)FilePosition;
|
||||
|
||||
// Return the new file position
|
||||
if(plFilePosHigh != NULL)
|
||||
*plFilePosHigh = 0;
|
||||
return hf->FilePointer;
|
||||
}
|
||||
|
||||
bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDWORD pdwBytesRead)
|
||||
{
|
||||
PCASC_FILE_FRAME pFrame = NULL;
|
||||
ULONGLONG StreamSize;
|
||||
ULONGLONG FileOffset;
|
||||
TCascFile * hf;
|
||||
LPBYTE pbBuffer = (LPBYTE)pvBuffer;
|
||||
DWORD dwStartPointer = 0;
|
||||
DWORD dwFilePointer = 0;
|
||||
DWORD dwEndPointer = 0;
|
||||
DWORD dwFrameSize;
|
||||
bool bReadResult;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// The buffer must be valid
|
||||
if(pvBuffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the file handle
|
||||
if((hf = IsValidFileHandle(hFile)) == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the file frames are not loaded yet, do it now
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
nError = EnsureFrameHeadersLoaded(hf);
|
||||
}
|
||||
|
||||
// If the file position is at or beyond end of file, do nothing
|
||||
if(nError == ERROR_SUCCESS && hf->FilePointer >= hf->FileSize)
|
||||
{
|
||||
*pdwBytesRead = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the file frame where to read from
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Get the frame
|
||||
pFrame = FindFileFrame(hf, hf->FilePointer);
|
||||
if(pFrame == NULL || pFrame->CompressedSize < 1)
|
||||
nError = ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// Perform the read
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// If not enough bytes in the file remaining, cut them
|
||||
dwStartPointer = dwFilePointer = hf->FilePointer;
|
||||
dwEndPointer = dwStartPointer + dwBytesToRead;
|
||||
if(dwEndPointer > hf->FileSize)
|
||||
dwEndPointer = hf->FileSize;
|
||||
|
||||
// Perform block read from each file frame
|
||||
while(dwFilePointer < dwEndPointer)
|
||||
{
|
||||
LPBYTE pbFrameData = NULL;
|
||||
DWORD dwFrameStart = pFrame->FrameFileOffset;
|
||||
DWORD dwFrameEnd = pFrame->FrameFileOffset + pFrame->FrameSize;
|
||||
|
||||
// Shall we populate the cache with a new data?
|
||||
if(dwFrameStart != hf->CacheStart || hf->CacheEnd != dwFrameEnd)
|
||||
{
|
||||
// Shall we reallocate the cache buffer?
|
||||
if(pFrame->FrameSize > hf->cbFileCache)
|
||||
{
|
||||
if(hf->pbFileCache != NULL)
|
||||
CASC_FREE(hf->pbFileCache);
|
||||
|
||||
hf->pbFileCache = CASC_ALLOC(BYTE, pFrame->FrameSize);
|
||||
hf->cbFileCache = pFrame->FrameSize;
|
||||
}
|
||||
|
||||
// We also need to allocate buffer for the raw data
|
||||
pbFrameData = CASC_ALLOC(BYTE, pFrame->CompressedSize);
|
||||
if(pbFrameData == NULL)
|
||||
{
|
||||
nError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
// Load the raw file data to memory
|
||||
FileOffset = pFrame->FrameArchiveOffset;
|
||||
bReadResult = FileStream_Read(hf->pStream, &FileOffset, pbFrameData, pFrame->CompressedSize);
|
||||
|
||||
// Note: The raw file data size could be less than expected
|
||||
// Happened in WoW build 19342 with the ROOT file. MD5 in the frame header
|
||||
// is zeroed, which means it should not be checked
|
||||
// Frame File: data.029
|
||||
// Frame Offs: 0x013ED9F0 size 0x01325B32
|
||||
// Frame End: 0x02713522
|
||||
// File Size: 0x027134FC
|
||||
if(bReadResult == false && GetLastError() == ERROR_HANDLE_EOF && !IsValidMD5(pFrame->md5))
|
||||
{
|
||||
// Get the size of the remaining file
|
||||
FileStream_GetSize(hf->pStream, &StreamSize);
|
||||
dwFrameSize = (DWORD)(StreamSize - FileOffset);
|
||||
|
||||
// If the frame offset is before EOF and frame end is beyond EOF, correct it
|
||||
if(FileOffset < StreamSize && dwFrameSize < pFrame->CompressedSize)
|
||||
{
|
||||
memset(pbFrameData + dwFrameSize, 0, (pFrame->CompressedSize - dwFrameSize));
|
||||
bReadResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the read result failed, we cannot finish reading it
|
||||
if(bReadResult && VerifyDataBlockHash(pbFrameData, pFrame->CompressedSize, pFrame->md5))
|
||||
{
|
||||
// Convert the source frame to the file cache
|
||||
nError = ProcessFileFrame(hf->pbFileCache,
|
||||
pFrame->FrameSize,
|
||||
pbFrameData,
|
||||
pFrame->CompressedSize,
|
||||
(DWORD)(pFrame - hf->pFrames));
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Set the start and end of the cache
|
||||
hf->CacheStart = dwFrameStart;
|
||||
hf->CacheEnd = dwFrameEnd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nError = ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// Free the raw frame data
|
||||
CASC_FREE(pbFrameData);
|
||||
}
|
||||
|
||||
// Copy the decompressed data
|
||||
if(dwFrameEnd > dwEndPointer)
|
||||
dwFrameEnd = dwEndPointer;
|
||||
memcpy(pbBuffer, hf->pbFileCache + (dwFilePointer - dwFrameStart), (dwFrameEnd - dwFilePointer));
|
||||
pbBuffer += (dwFrameEnd - dwFilePointer);
|
||||
|
||||
// Move pointers
|
||||
dwFilePointer = dwFrameEnd;
|
||||
pFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the file position
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(pdwBytesRead != NULL)
|
||||
*pdwBytesRead = (dwFilePointer - dwStartPointer);
|
||||
hf->FilePointer = dwFilePointer;
|
||||
}
|
||||
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
return (nError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
1199
dep/CascLib/src/CascRootFile_Diablo3.cpp
Normal file
1199
dep/CascLib/src/CascRootFile_Diablo3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3624
dep/CascLib/src/CascRootFile_Mndx.cpp
Normal file
3624
dep/CascLib/src/CascRootFile_Mndx.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4369
dep/CascLib/src/CascRootFile_Mndx_x86.asm
Normal file
4369
dep/CascLib/src/CascRootFile_Mndx_x86.asm
Normal file
File diff suppressed because it is too large
Load Diff
213
dep/CascLib/src/CascRootFile_Ovr.cpp
Normal file
213
dep/CascLib/src/CascRootFile_Ovr.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/*****************************************************************************/
|
||||
/* CascRootFile_Ovr.cpp Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Support for loading Overwatch ROOT file */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 28.10.15 1.00 Lad The first version of CascRootFile_Ovr.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure definitions for Overwatch root file
|
||||
|
||||
typedef struct _CASC_FILE_ENTRY
|
||||
{
|
||||
ENCODING_KEY EncodingKey; // Encoding key
|
||||
ULONGLONG FileNameHash; // File name hash
|
||||
DWORD dwFileName; // Offset of the file name in the name cache
|
||||
} CASC_FILE_ENTRY, *PCASC_FILE_ENTRY;
|
||||
|
||||
struct TRootHandler_Ovr : public TRootHandler
|
||||
{
|
||||
// Linear global list of file entries
|
||||
DYNAMIC_ARRAY FileTable;
|
||||
|
||||
// Linear global list of names
|
||||
DYNAMIC_ARRAY FileNames;
|
||||
|
||||
// Global map of FileName -> FileEntry
|
||||
PCASC_MAP pRootMap;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static int InsertFileEntry(
|
||||
TRootHandler_Ovr * pRootHandler,
|
||||
const char * szFileName,
|
||||
LPBYTE pbEncodingKey)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
size_t nLength = strlen(szFileName);
|
||||
|
||||
// Attempt to insert the file name to the global buffer
|
||||
szFileName = (char *)Array_Insert(&pRootHandler->FileNames, szFileName, nLength + 1);
|
||||
if(szFileName == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Attempt to insert the entry to the array of file entries
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
|
||||
if(pFileEntry == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Fill the file entry
|
||||
pFileEntry->EncodingKey = *(PENCODING_KEY)pbEncodingKey;
|
||||
pFileEntry->FileNameHash = CalcFileNameHash(szFileName);
|
||||
pFileEntry->dwFileName = (DWORD)Array_IndexOf(&pRootHandler->FileNames, szFileName);
|
||||
|
||||
// Insert the file entry to the map
|
||||
assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL);
|
||||
Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of Overwatch root file
|
||||
|
||||
static int OvrHandler_Insert(
|
||||
TRootHandler_Ovr * pRootHandler,
|
||||
const char * szFileName,
|
||||
LPBYTE pbEncodingKey)
|
||||
{
|
||||
return InsertFileEntry(pRootHandler, szFileName, pbEncodingKey);
|
||||
}
|
||||
|
||||
static LPBYTE OvrHandler_Search(TRootHandler_Ovr * pRootHandler, TCascSearch * pSearch, PDWORD /* PtrFileSize */, PDWORD /* PtrLocaleFlags */, PDWORD /* PtrFileDataId */)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
|
||||
// Are we still inside the root directory range?
|
||||
while(pSearch->IndexLevel1 < pRootHandler->FileTable.ItemCount)
|
||||
{
|
||||
// Retrieve the file item
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_ItemAt(&pRootHandler->FileTable, pSearch->IndexLevel1);
|
||||
strcpy(pSearch->szFileName, (char *)Array_ItemAt(&pRootHandler->FileNames, pFileEntry->dwFileName));
|
||||
|
||||
// Prepare the pointer to the next search
|
||||
pSearch->IndexLevel1++;
|
||||
return pFileEntry->EncodingKey.Value;
|
||||
}
|
||||
|
||||
// No more entries
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OvrHandler_EndSearch(TRootHandler_Ovr * /* pRootHandler */, TCascSearch * /* pSearch */)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
static LPBYTE OvrHandler_GetKey(TRootHandler_Ovr * pRootHandler, const char * szFileName)
|
||||
{
|
||||
ULONGLONG FileNameHash = CalcFileNameHash(szFileName);
|
||||
|
||||
return (LPBYTE)Map_FindObject(pRootHandler->pRootMap, &FileNameHash, NULL);
|
||||
}
|
||||
|
||||
static DWORD OvrHandler_GetFileId(TRootHandler_Ovr * /* pRootHandler */, const char * /* szFileName */)
|
||||
{
|
||||
// Not implemented for Overwatch
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void OvrHandler_Close(TRootHandler_Ovr * pRootHandler)
|
||||
{
|
||||
if(pRootHandler != NULL)
|
||||
{
|
||||
// Free the file map
|
||||
if(pRootHandler->pRootMap)
|
||||
Map_Free(pRootHandler->pRootMap);
|
||||
pRootHandler->pRootMap = NULL;
|
||||
|
||||
// Free the array of the file names and file items
|
||||
Array_Free(&pRootHandler->FileTable);
|
||||
Array_Free(&pRootHandler->FileNames);
|
||||
|
||||
// Free the root file itself
|
||||
CASC_FREE(pRootHandler);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int RootHandler_CreateOverwatch(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile)
|
||||
{
|
||||
TRootHandler_Ovr * pRootHandler;
|
||||
ENCODING_KEY KeyBuffer;
|
||||
QUERY_KEY EncodingKey = {KeyBuffer.Value, MD5_HASH_SIZE};
|
||||
void * pTextFile;
|
||||
size_t nLength;
|
||||
char szOneLine[0x200];
|
||||
char szFileName[MAX_PATH+1];
|
||||
DWORD dwFileCountMax = (DWORD)hs->pEncodingMap->TableSize;
|
||||
int nFileNameIndex;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Allocate the root handler object
|
||||
hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_Ovr, 1);
|
||||
if(pRootHandler == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Fill-in the handler functions
|
||||
memset(pRootHandler, 0, sizeof(TRootHandler_Ovr));
|
||||
pRootHandler->Insert = (ROOT_INSERT)OvrHandler_Insert;
|
||||
pRootHandler->Search = (ROOT_SEARCH)OvrHandler_Search;
|
||||
pRootHandler->EndSearch = (ROOT_ENDSEARCH)OvrHandler_EndSearch;
|
||||
pRootHandler->GetKey = (ROOT_GETKEY)OvrHandler_GetKey;
|
||||
pRootHandler->Close = (ROOT_CLOSE)OvrHandler_Close;
|
||||
pRootHandler->GetFileId = (ROOT_GETFILEID)OvrHandler_GetFileId;
|
||||
|
||||
// Fill-in the flags
|
||||
pRootHandler->dwRootFlags |= ROOT_FLAG_HAS_NAMES;
|
||||
|
||||
// Allocate the linear array of file entries
|
||||
nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, 0x10000);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Allocate the buffer for the file names
|
||||
nError = Array_Create(&pRootHandler->FileNames, char, 0x10000);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Create map of ROOT_ENTRY -> FileEntry
|
||||
pRootHandler->pRootMap = Map_Create(dwFileCountMax, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash));
|
||||
if(pRootHandler->pRootMap == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Parse the ROOT file
|
||||
pTextFile = ListFile_FromBuffer(pbRootFile, cbRootFile);
|
||||
if(pTextFile != NULL)
|
||||
{
|
||||
// Get the initial line, containing variable names
|
||||
nLength = ListFile_GetNextLine(pTextFile, szOneLine, _maxchars(szOneLine));
|
||||
|
||||
// Determine the index of the "FILENAME" variable
|
||||
nError = GetRootVariableIndex(szOneLine, szOneLine + nLength, "FILENAME", &nFileNameIndex);
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Parse the next lines
|
||||
while((nLength = ListFile_GetNextLine(pTextFile, szOneLine, _maxchars(szOneLine))) > 0)
|
||||
{
|
||||
// Parse the line
|
||||
nError = ParseRootFileLine(szOneLine, szOneLine + nLength, nFileNameIndex, &EncodingKey, szFileName, _maxchars(szFileName));
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
InsertFileEntry(pRootHandler, szFileName, KeyBuffer.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Free the listfile
|
||||
ListFile_Free(pTextFile);
|
||||
}
|
||||
|
||||
// Succeeded
|
||||
return nError;
|
||||
}
|
||||
214
dep/CascLib/src/CascRootFile_SC1.cpp
Normal file
214
dep/CascLib/src/CascRootFile_SC1.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*****************************************************************************/
|
||||
/* CascRootFile_SC1.cpp Copyright (c) Ladislav Zezula 2017 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Support for loading Starcraft 1 ROOT file */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 28.10.15 1.00 Lad The first version of CascRootFile_SC1.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure definitions for Overwatch root file
|
||||
|
||||
typedef struct _CASC_FILE_ENTRY
|
||||
{
|
||||
ENCODING_KEY EncodingKey; // Encoding key
|
||||
ULONGLONG FileNameHash; // File name hash
|
||||
DWORD dwFileName; // Offset of the file name in the name cache
|
||||
} CASC_FILE_ENTRY, *PCASC_FILE_ENTRY;
|
||||
|
||||
struct TRootHandler_SC1 : public TRootHandler
|
||||
{
|
||||
// Linear global list of file entries
|
||||
DYNAMIC_ARRAY FileTable;
|
||||
|
||||
// Linear global list of names
|
||||
DYNAMIC_ARRAY FileNames;
|
||||
|
||||
// Global map of FileName -> FileEntry
|
||||
PCASC_MAP pRootMap;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static int InsertFileEntry(
|
||||
TRootHandler_SC1 * pRootHandler,
|
||||
const char * szFileName,
|
||||
LPBYTE pbEncodingKey)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
size_t nLength = strlen(szFileName);
|
||||
|
||||
// Attempt to insert the file name to the global buffer
|
||||
szFileName = (char *)Array_Insert(&pRootHandler->FileNames, szFileName, nLength + 1);
|
||||
if(szFileName == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Attempt to insert the entry to the array of file entries
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
|
||||
if(pFileEntry == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Fill the file entry
|
||||
pFileEntry->EncodingKey = *(PENCODING_KEY)pbEncodingKey;
|
||||
pFileEntry->FileNameHash = CalcFileNameHash(szFileName);
|
||||
pFileEntry->dwFileName = (DWORD)Array_IndexOf(&pRootHandler->FileNames, szFileName);
|
||||
|
||||
// Insert the file entry to the map
|
||||
assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL);
|
||||
Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of Overwatch root file
|
||||
|
||||
static int SC1Handler_Insert(
|
||||
TRootHandler_SC1 * pRootHandler,
|
||||
const char * szFileName,
|
||||
LPBYTE pbEncodingKey)
|
||||
{
|
||||
return InsertFileEntry(pRootHandler, szFileName, pbEncodingKey);
|
||||
}
|
||||
|
||||
static LPBYTE SC1Handler_Search(TRootHandler_SC1 * pRootHandler, TCascSearch * pSearch, PDWORD /* PtrFileSize */, PDWORD /* PtrLocaleFlags */, PDWORD /* PtrFileDataId */)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
|
||||
// Are we still inside the root directory range?
|
||||
while(pSearch->IndexLevel1 < pRootHandler->FileTable.ItemCount)
|
||||
{
|
||||
// Retrieve the file item
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_ItemAt(&pRootHandler->FileTable, pSearch->IndexLevel1);
|
||||
|
||||
// Prepare the pointer to the next search
|
||||
pSearch->IndexLevel1++;
|
||||
|
||||
char *filename = (char *)Array_ItemAt(&pRootHandler->FileNames, pFileEntry->dwFileName);
|
||||
if (CheckWildCard(filename, pSearch->szMask)) {
|
||||
strcpy(pSearch->szFileName, filename);
|
||||
return pFileEntry->EncodingKey.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// No more entries
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void SC1Handler_EndSearch(TRootHandler_SC1 * /* pRootHandler */, TCascSearch * /* pSearch */)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
static LPBYTE SC1Handler_GetKey(TRootHandler_SC1 * pRootHandler, const char * szFileName)
|
||||
{
|
||||
ULONGLONG FileNameHash = CalcFileNameHash(szFileName);
|
||||
|
||||
return (LPBYTE)Map_FindObject(pRootHandler->pRootMap, &FileNameHash, NULL);
|
||||
}
|
||||
|
||||
static DWORD SC1Handler_GetFileId(TRootHandler_SC1 * /* pRootHandler */, const char * /* szFileName */)
|
||||
{
|
||||
// Not implemented for Overwatch
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SC1Handler_Close(TRootHandler_SC1 * pRootHandler)
|
||||
{
|
||||
if(pRootHandler != NULL)
|
||||
{
|
||||
// Free the file map
|
||||
if(pRootHandler->pRootMap)
|
||||
Map_Free(pRootHandler->pRootMap);
|
||||
pRootHandler->pRootMap = NULL;
|
||||
|
||||
// Free the array of the file names and file items
|
||||
Array_Free(&pRootHandler->FileTable);
|
||||
Array_Free(&pRootHandler->FileNames);
|
||||
|
||||
// Free the root file itself
|
||||
CASC_FREE(pRootHandler);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int RootHandler_CreateSC1(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile)
|
||||
{
|
||||
TRootHandler_SC1 * pRootHandler;
|
||||
ENCODING_KEY KeyBuffer;
|
||||
QUERY_KEY EncodingKey = {KeyBuffer.Value, MD5_HASH_SIZE};
|
||||
void * pTextFile;
|
||||
size_t nLength;
|
||||
char szOneLine[0x200];
|
||||
DWORD dwFileCountMax = (DWORD)hs->pEncodingMap->TableSize;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Allocate the root handler object
|
||||
hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_SC1, 1);
|
||||
if(pRootHandler == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Fill-in the handler functions
|
||||
memset(pRootHandler, 0, sizeof(TRootHandler_SC1));
|
||||
pRootHandler->Insert = (ROOT_INSERT)SC1Handler_Insert;
|
||||
pRootHandler->Search = (ROOT_SEARCH)SC1Handler_Search;
|
||||
pRootHandler->EndSearch = (ROOT_ENDSEARCH)SC1Handler_EndSearch;
|
||||
pRootHandler->GetKey = (ROOT_GETKEY)SC1Handler_GetKey;
|
||||
pRootHandler->Close = (ROOT_CLOSE)SC1Handler_Close;
|
||||
pRootHandler->GetFileId = (ROOT_GETFILEID)SC1Handler_GetFileId;
|
||||
|
||||
// Fill-in the flags
|
||||
pRootHandler->dwRootFlags |= ROOT_FLAG_HAS_NAMES;
|
||||
|
||||
// Allocate the linear array of file entries
|
||||
nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, 0x10000);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Allocate the buffer for the file names
|
||||
nError = Array_Create(&pRootHandler->FileNames, char, 0x10000);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Create map of ROOT_ENTRY -> FileEntry
|
||||
pRootHandler->pRootMap = Map_Create(dwFileCountMax, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash));
|
||||
if(pRootHandler->pRootMap == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Parse the ROOT file
|
||||
pTextFile = ListFile_FromBuffer(pbRootFile, cbRootFile);
|
||||
if(pTextFile != NULL)
|
||||
{
|
||||
// Parse the next lines
|
||||
while((nLength = ListFile_GetNextLine(pTextFile, szOneLine, _maxchars(szOneLine))) > 0)
|
||||
{
|
||||
LPSTR szEncodingKey;
|
||||
BYTE EncodingKey[MD5_HASH_SIZE];
|
||||
|
||||
szEncodingKey = strchr(szOneLine, _T('|'));
|
||||
if(szEncodingKey != NULL)
|
||||
{
|
||||
// Split the name and encoding key
|
||||
*szEncodingKey++ = 0;
|
||||
|
||||
// Insert the entry to the map
|
||||
ConvertStringToBinary(szEncodingKey, MD5_STRING_SIZE, EncodingKey);
|
||||
InsertFileEntry(pRootHandler, szOneLine, EncodingKey);
|
||||
}
|
||||
}
|
||||
|
||||
// Free the listfile
|
||||
ListFile_Free(pTextFile);
|
||||
}
|
||||
|
||||
// Succeeded
|
||||
return nError;
|
||||
}
|
||||
595
dep/CascLib/src/CascRootFile_WoW6.cpp
Normal file
595
dep/CascLib/src/CascRootFile_WoW6.cpp
Normal file
@@ -0,0 +1,595 @@
|
||||
/*****************************************************************************/
|
||||
/* CascOpenStorage.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Storage functions for CASC */
|
||||
/* Note: WoW6 offsets refer to WoW.exe 6.0.3.19116 (32-bit) */
|
||||
/* SHA1: c10e9ffb7d040a37a356b96042657e1a0c95c0dd */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of CascOpenStorage.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "CascLib.h"
|
||||
#include "CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures
|
||||
|
||||
#define ROOT_SEARCH_PHASE_INITIALIZING 0
|
||||
#define ROOT_SEARCH_PHASE_LISTFILE 1
|
||||
#define ROOT_SEARCH_PHASE_NAMELESS 2
|
||||
#define ROOT_SEARCH_PHASE_FINISHED 2
|
||||
|
||||
// On-disk version of locale block
|
||||
typedef struct _FILE_LOCALE_BLOCK
|
||||
{
|
||||
DWORD NumberOfFiles; // Number of entries
|
||||
DWORD Flags;
|
||||
DWORD Locales; // File locale mask (CASC_LOCALE_XXX)
|
||||
|
||||
// Followed by a block of 32-bit integers (count: NumberOfFiles)
|
||||
// Followed by the MD5 and file name hash (count: NumberOfFiles)
|
||||
|
||||
} FILE_LOCALE_BLOCK, *PFILE_LOCALE_BLOCK;
|
||||
|
||||
// On-disk version of root entry
|
||||
typedef struct _FILE_ROOT_ENTRY
|
||||
{
|
||||
ENCODING_KEY EncodingKey; // MD5 of the file
|
||||
ULONGLONG FileNameHash; // Jenkins hash of the file name
|
||||
|
||||
} FILE_ROOT_ENTRY, *PFILE_ROOT_ENTRY;
|
||||
|
||||
|
||||
typedef struct _CASC_ROOT_BLOCK
|
||||
{
|
||||
PFILE_LOCALE_BLOCK pLocaleBlockHdr; // Pointer to the locale block
|
||||
PDWORD FileDataIds; // Pointer to the array of File Data IDs
|
||||
PFILE_ROOT_ENTRY pRootEntries;
|
||||
|
||||
} CASC_ROOT_BLOCK, *PCASC_ROOT_BLOCK;
|
||||
|
||||
// Root file entry for CASC storages without MNDX root file (World of Warcraft 6.0+)
|
||||
// Does not match to the in-file structure of the root entry
|
||||
typedef struct _CASC_FILE_ENTRY
|
||||
{
|
||||
ENCODING_KEY EncodingKey; // File encoding key (MD5)
|
||||
ULONGLONG FileNameHash; // Jenkins hash of the file name
|
||||
DWORD FileDataId; // File Data Index
|
||||
DWORD Locales; // Locale flags of the file
|
||||
|
||||
} CASC_FILE_ENTRY, *PCASC_FILE_ENTRY;
|
||||
|
||||
struct TRootHandler_WoW6 : public TRootHandler
|
||||
{
|
||||
// Linear global list of file entries
|
||||
DYNAMIC_ARRAY FileTable;
|
||||
DYNAMIC_ARRAY FileDataIdLookupTable;
|
||||
|
||||
// Global map of FileName -> FileEntry
|
||||
PCASC_MAP pRootMap;
|
||||
|
||||
// For counting files
|
||||
DWORD dwTotalFileCount;
|
||||
};
|
||||
|
||||
// Prototype for root file parsing routine
|
||||
typedef int (*PARSE_ROOT)(TRootHandler_WoW6 * pRootHandler, PCASC_ROOT_BLOCK pBlockInfo);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static bool IsFileDataIdName(const char * szFileName)
|
||||
{
|
||||
BYTE BinaryValue[4];
|
||||
|
||||
// File name must begin with "File", case insensitive
|
||||
if(AsciiToUpperTable_BkSlash[szFileName[0]] == 'F' &&
|
||||
AsciiToUpperTable_BkSlash[szFileName[1]] == 'I' &&
|
||||
AsciiToUpperTable_BkSlash[szFileName[2]] == 'L' &&
|
||||
AsciiToUpperTable_BkSlash[szFileName[3]] == 'E')
|
||||
{
|
||||
// Then, 8 hexadecimal digits must follow
|
||||
if(ConvertStringToBinary(szFileName + 4, 8, BinaryValue) == ERROR_SUCCESS)
|
||||
{
|
||||
// Must be followed by an extension or end-of-string
|
||||
return (szFileName[0x0C] == 0 || szFileName[0x0C] == '.');
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int FileDataIdCompare(const void *, const void * pvFile1, const void * pvFile2)
|
||||
{
|
||||
return ((PCASC_FILE_ENTRY)pvFile1)->FileDataId - ((PCASC_FILE_ENTRY)pvFile2)->FileDataId;
|
||||
}
|
||||
|
||||
// Search by FileDataId
|
||||
PCASC_FILE_ENTRY FindRootEntry(DYNAMIC_ARRAY & FileTable, DWORD FileDataId)
|
||||
{
|
||||
PCASC_FILE_ENTRY* pStartEntry = (PCASC_FILE_ENTRY*)FileTable.ItemArray;
|
||||
PCASC_FILE_ENTRY* pMidlEntry;
|
||||
PCASC_FILE_ENTRY* pEndEntry = pStartEntry + FileTable.ItemCount - 1;
|
||||
int nResult;
|
||||
|
||||
// Perform binary search on the table
|
||||
while(pStartEntry < pEndEntry)
|
||||
{
|
||||
// Calculate the middle of the interval
|
||||
pMidlEntry = pStartEntry + ((pEndEntry - pStartEntry) / 2);
|
||||
|
||||
// Did we find it?
|
||||
nResult = (int)FileDataId - (int)(*pMidlEntry)->FileDataId;
|
||||
if(nResult == 0)
|
||||
return *pMidlEntry;
|
||||
|
||||
// Move the interval to the left or right
|
||||
(nResult < 0) ? pEndEntry = pMidlEntry : pStartEntry = pMidlEntry + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Search by file name hash
|
||||
// Also used in CascSearchFile
|
||||
PCASC_FILE_ENTRY FindRootEntry(PCASC_MAP pRootMap, const char * szFileName, DWORD * PtrTableIndex)
|
||||
{
|
||||
// Calculate the HASH value of the normalized file name
|
||||
ULONGLONG FileNameHash = CalcFileNameHash(szFileName);
|
||||
|
||||
// Perform the hash search
|
||||
return (PCASC_FILE_ENTRY)Map_FindObject(pRootMap, &FileNameHash, PtrTableIndex);
|
||||
}
|
||||
|
||||
LPBYTE VerifyLocaleBlock(PCASC_ROOT_BLOCK pBlockInfo, LPBYTE pbFilePointer, LPBYTE pbFileEnd)
|
||||
{
|
||||
// Validate the file locale block
|
||||
pBlockInfo->pLocaleBlockHdr = (PFILE_LOCALE_BLOCK)pbFilePointer;
|
||||
pbFilePointer = (LPBYTE)(pBlockInfo->pLocaleBlockHdr + 1);
|
||||
if(pbFilePointer > pbFileEnd)
|
||||
return NULL;
|
||||
|
||||
// Validate the array of 32-bit integers
|
||||
pBlockInfo->FileDataIds = (PDWORD)pbFilePointer;
|
||||
pbFilePointer = (LPBYTE)(pBlockInfo->FileDataIds + pBlockInfo->pLocaleBlockHdr->NumberOfFiles);
|
||||
if(pbFilePointer > pbFileEnd)
|
||||
return NULL;
|
||||
|
||||
// Validate the array of root entries
|
||||
pBlockInfo->pRootEntries = (PFILE_ROOT_ENTRY)pbFilePointer;
|
||||
pbFilePointer = (LPBYTE)(pBlockInfo->pRootEntries + pBlockInfo->pLocaleBlockHdr->NumberOfFiles);
|
||||
if(pbFilePointer > pbFileEnd)
|
||||
return NULL;
|
||||
|
||||
// Return the position of the next block
|
||||
return pbFilePointer;
|
||||
}
|
||||
|
||||
static int ParseRoot_CountFiles(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
PCASC_ROOT_BLOCK pRootBlock)
|
||||
{
|
||||
// Add the file count to the total file count
|
||||
pRootHandler->dwTotalFileCount += pRootBlock->pLocaleBlockHdr->NumberOfFiles;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static int ParseRoot_AddRootEntries(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
PCASC_ROOT_BLOCK pRootBlock)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
DWORD dwFileDataId = 0;
|
||||
|
||||
// Sanity checks
|
||||
assert(pRootHandler->FileTable.ItemArray != NULL);
|
||||
assert(pRootHandler->FileTable.ItemCountMax != 0);
|
||||
assert(pRootHandler->FileDataIdLookupTable.ItemArray != NULL);
|
||||
assert(pRootHandler->FileDataIdLookupTable.ItemCountMax != 0);
|
||||
|
||||
// WoW.exe (build 19116): Blocks with zero files are skipped
|
||||
for(DWORD i = 0; i < pRootBlock->pLocaleBlockHdr->NumberOfFiles; i++)
|
||||
{
|
||||
// Create new entry, with overflow check
|
||||
if(pRootHandler->FileTable.ItemCount >= pRootHandler->FileTable.ItemCountMax)
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
|
||||
|
||||
if (pRootHandler->FileDataIdLookupTable.ItemCount >= pRootHandler->FileDataIdLookupTable.ItemCountMax)
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
Array_Insert(&pRootHandler->FileDataIdLookupTable, &pFileEntry, 1);
|
||||
|
||||
// (004147A3) Prepare the CASC_FILE_ENTRY structure
|
||||
pFileEntry->FileNameHash = pRootBlock->pRootEntries[i].FileNameHash;
|
||||
pFileEntry->FileDataId = dwFileDataId + pRootBlock->FileDataIds[i];
|
||||
pFileEntry->Locales = pRootBlock->pLocaleBlockHdr->Locales;
|
||||
pFileEntry->EncodingKey = pRootBlock->pRootEntries[i].EncodingKey;
|
||||
|
||||
// Also, insert the entry to the map
|
||||
Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
|
||||
|
||||
// Update the local File Data Id
|
||||
assert((pFileEntry->FileDataId + 1) > pFileEntry->FileDataId);
|
||||
dwFileDataId = pFileEntry->FileDataId + 1;
|
||||
|
||||
// Move to the next root entry
|
||||
pFileEntry++;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static int ParseWowRootFileInternal(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
PARSE_ROOT pfnParseRoot,
|
||||
LPBYTE pbRootFile,
|
||||
LPBYTE pbRootFileEnd,
|
||||
DWORD dwLocaleMask,
|
||||
BYTE bOverrideArchive,
|
||||
BYTE bAudioLocale)
|
||||
{
|
||||
CASC_ROOT_BLOCK RootBlock;
|
||||
|
||||
// Now parse the root file
|
||||
while(pbRootFile < pbRootFileEnd)
|
||||
{
|
||||
// Validate the file locale block
|
||||
pbRootFile = VerifyLocaleBlock(&RootBlock, pbRootFile, pbRootFileEnd);
|
||||
if(pbRootFile == NULL)
|
||||
break;
|
||||
|
||||
// WoW.exe (build 19116): Entries with flag 0x100 set are skipped
|
||||
if(RootBlock.pLocaleBlockHdr->Flags & 0x100)
|
||||
continue;
|
||||
|
||||
// WoW.exe (build 19116): Entries with flag 0x80 set are skipped if overrideArchive CVAR is set to FALSE (which is by default in non-chinese clients)
|
||||
if((RootBlock.pLocaleBlockHdr->Flags & 0x80) && bOverrideArchive == 0)
|
||||
continue;
|
||||
|
||||
// WoW.exe (build 19116): Entries with (flags >> 0x1F) not equal to bAudioLocale are skipped
|
||||
if((RootBlock.pLocaleBlockHdr->Flags >> 0x1F) != bAudioLocale)
|
||||
continue;
|
||||
|
||||
// WoW.exe (build 19116): Locales other than defined mask are skipped too
|
||||
if((RootBlock.pLocaleBlockHdr->Locales & dwLocaleMask) == 0)
|
||||
continue;
|
||||
|
||||
// Now call the custom function
|
||||
pfnParseRoot(pRootHandler, &RootBlock);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
// known dwRegion values returned from sub_661316 (7.0.3.22210 x86 win), also referred by lua GetCurrentRegion
|
||||
#define WOW_REGION_US 0x01
|
||||
#define WOW_REGION_KR 0x02
|
||||
#define WOW_REGION_EU 0x03
|
||||
#define WOW_REGION_TW 0x04
|
||||
#define WOW_REGION_CN 0x05
|
||||
|
||||
#define WOW_LOCALE_ENUS 0x00
|
||||
#define WOW_LOCALE_KOKR 0x01
|
||||
#define WOW_LOCALE_FRFR 0x02
|
||||
#define WOW_LOCALE_DEDE 0x03
|
||||
#define WOW_LOCALE_ZHCN 0x04
|
||||
#define WOW_LOCALE_ZHTW 0x05
|
||||
#define WOW_LOCALE_ESES 0x06
|
||||
#define WOW_LOCALE_ESMX 0x07
|
||||
#define WOW_LOCALE_RURU 0x08
|
||||
#define WOW_LOCALE_PTBR 0x0A
|
||||
#define WOW_LOCALE_ITIT 0x0B
|
||||
|
||||
// dwLocale is obtained from a WOW_LOCALE_* to CASC_LOCALE_BIT_* mapping (sub_6615D0 in 7.0.3.22210 x86 win)
|
||||
// because (ENUS, ENGB) and (PTBR, PTPT) pairs share the same value on WOW_LOCALE_* enum
|
||||
// dwRegion is used to distinguish them
|
||||
if(dwRegion == WOW_REGION_EU)
|
||||
{
|
||||
// Is this english version of WoW?
|
||||
if(dwLocale == CASC_LOCALE_BIT_ENUS)
|
||||
{
|
||||
LoadWowRootFileLocales(hs, pbRootFile, cbRootFile, CASC_LOCALE_ENGB, bOverrideArchive, bAudioLocale);
|
||||
LoadWowRootFileLocales(hs, pbRootFile, cbRootFile, CASC_LOCALE_ENUS, bOverrideArchive, bAudioLocale);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Is this portuguese version of WoW?
|
||||
if(dwLocale == CASC_LOCALE_BIT_PTBR)
|
||||
{
|
||||
LoadWowRootFileLocales(hs, pbRootFile, cbRootFile, CASC_LOCALE_PTPT, bOverrideArchive, bAudioLocale);
|
||||
LoadWowRootFileLocales(hs, pbRootFile, cbRootFile, CASC_LOCALE_PTBR, bOverrideArchive, bAudioLocale);
|
||||
}
|
||||
}
|
||||
else
|
||||
LoadWowRootFileLocales(hs, pbRootFile, cbRootFile, (1 << dwLocale), bOverrideArchive, bAudioLocale);
|
||||
*/
|
||||
|
||||
static int ParseWowRootFile2(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
PARSE_ROOT pfnParseRoot,
|
||||
LPBYTE pbRootFile,
|
||||
LPBYTE pbRootFileEnd,
|
||||
DWORD dwLocaleMask,
|
||||
BYTE bAudioLocale)
|
||||
{
|
||||
// Load the locale as-is
|
||||
ParseWowRootFileInternal(pRootHandler, pfnParseRoot, pbRootFile, pbRootFileEnd, dwLocaleMask, false, bAudioLocale);
|
||||
|
||||
// If we wanted enGB, we also load enUS for the missing files
|
||||
if(dwLocaleMask == CASC_LOCALE_ENGB)
|
||||
ParseWowRootFileInternal(pRootHandler, pfnParseRoot, pbRootFile, pbRootFileEnd, CASC_LOCALE_ENUS, false, bAudioLocale);
|
||||
|
||||
if(dwLocaleMask == CASC_LOCALE_PTPT)
|
||||
ParseWowRootFileInternal(pRootHandler, pfnParseRoot, pbRootFile, pbRootFileEnd, CASC_LOCALE_PTBR, false, bAudioLocale);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// WoW.exe: 004146C7 (BuildManifest::Load)
|
||||
static int ParseWowRootFile(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
PARSE_ROOT pfnParseRoot,
|
||||
LPBYTE pbRootFile,
|
||||
LPBYTE pbRootFileEnd,
|
||||
DWORD dwLocaleMask)
|
||||
{
|
||||
ParseWowRootFile2(pRootHandler, pfnParseRoot, pbRootFile, pbRootFileEnd, dwLocaleMask, 0);
|
||||
ParseWowRootFile2(pRootHandler, pfnParseRoot, pbRootFile, pbRootFileEnd, dwLocaleMask, 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of WoW6 root file
|
||||
|
||||
static int WowHandler_Insert(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
const char * szFileName,
|
||||
LPBYTE pbEncodingKey)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
DWORD FileDataId = 0;
|
||||
|
||||
// Don't let the number of items to overflow
|
||||
if(pRootHandler->FileTable.ItemCount >= pRootHandler->FileTable.ItemCountMax)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if (pRootHandler->FileDataIdLookupTable.ItemCount >= pRootHandler->FileDataIdLookupTable.ItemCountMax)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Insert the item to the linear file list
|
||||
pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
Array_Insert(&pRootHandler->FileDataIdLookupTable, &pFileEntry, 1);
|
||||
|
||||
// Get the file data ID of the previous item (0 if this is the first one)
|
||||
if(pRootHandler->FileTable.ItemCount > 1)
|
||||
FileDataId = pFileEntry[-1].FileDataId;
|
||||
|
||||
// Fill-in the new entry
|
||||
pFileEntry->EncodingKey = *(PENCODING_KEY)pbEncodingKey;
|
||||
pFileEntry->FileNameHash = CalcFileNameHash(szFileName);
|
||||
pFileEntry->FileDataId = FileDataId + 1;
|
||||
pFileEntry->Locales = CASC_LOCALE_ALL;
|
||||
|
||||
// Verify collisions (debug version only)
|
||||
assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL);
|
||||
|
||||
// Insert the entry to the map
|
||||
Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static LPBYTE WowHandler_Search(
|
||||
TRootHandler_WoW6 * pRootHandler,
|
||||
TCascSearch * pSearch,
|
||||
PDWORD /* PtrFileSize */,
|
||||
PDWORD PtrLocaleFlags,
|
||||
PDWORD PtrFileDataId)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
|
||||
// Only if we have a listfile
|
||||
if(pSearch->pCache != NULL)
|
||||
{
|
||||
// Keep going through the listfile
|
||||
while(ListFile_GetNext(pSearch->pCache, pSearch->szMask, pSearch->szFileName, MAX_PATH))
|
||||
{
|
||||
// Find the root entry
|
||||
pFileEntry = FindRootEntry(pRootHandler->pRootMap, pSearch->szFileName, NULL);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// Give the caller the locale mask
|
||||
if(PtrLocaleFlags != NULL)
|
||||
PtrLocaleFlags[0] = pFileEntry->Locales;
|
||||
if(PtrFileDataId != NULL)
|
||||
PtrFileDataId[0] = pFileEntry->FileDataId;
|
||||
return pFileEntry->EncodingKey.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No more files
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LPBYTE WowHandler_GetKey(TRootHandler_WoW6 * pRootHandler, const char * szFileName)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
DWORD FileDataId;
|
||||
BYTE FileDataIdLE[4];
|
||||
|
||||
// Open by FileDataId. The file name must be as following:
|
||||
// File########.unk, where '#' are hexa-decimal numbers (case insensitive).
|
||||
// Extension is ignored in that case
|
||||
if(IsFileDataIdName(szFileName))
|
||||
{
|
||||
ConvertStringToBinary(szFileName + 4, 8, FileDataIdLE);
|
||||
FileDataId = ConvertBytesToInteger_4(FileDataIdLE);
|
||||
|
||||
pFileEntry = FindRootEntry(pRootHandler->FileDataIdLookupTable, FileDataId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find by the file name hash
|
||||
pFileEntry = FindRootEntry(pRootHandler->pRootMap, szFileName, NULL);
|
||||
}
|
||||
|
||||
return (pFileEntry != NULL) ? pFileEntry->EncodingKey.Value : NULL;
|
||||
}
|
||||
|
||||
static void WowHandler_EndSearch(TRootHandler_WoW6 * /* pRootHandler */, TCascSearch * pSearch)
|
||||
{
|
||||
if(pSearch->pRootContext != NULL)
|
||||
CASC_FREE(pSearch->pRootContext);
|
||||
pSearch->pRootContext = NULL;
|
||||
}
|
||||
|
||||
static DWORD WowHandler_GetFileId(TRootHandler_WoW6 * pRootHandler, const char * szFileName)
|
||||
{
|
||||
PCASC_FILE_ENTRY pFileEntry;
|
||||
|
||||
// Find by the file name hash
|
||||
pFileEntry = FindRootEntry(pRootHandler->pRootMap, szFileName, NULL);
|
||||
return (pFileEntry != NULL) ? pFileEntry->FileDataId : 0;
|
||||
}
|
||||
|
||||
static void WowHandler_Close(TRootHandler_WoW6 * pRootHandler)
|
||||
{
|
||||
if(pRootHandler != NULL)
|
||||
{
|
||||
Array_Free(&pRootHandler->FileTable);
|
||||
Array_Free(&pRootHandler->FileDataIdLookupTable);
|
||||
Map_Free(pRootHandler->pRootMap);
|
||||
CASC_FREE(pRootHandler);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void TRootHandlerWoW6_Dump(
|
||||
TCascStorage * hs,
|
||||
TDumpContext * dc, // Pointer to an opened file
|
||||
LPBYTE pbRootFile,
|
||||
DWORD cbRootFile,
|
||||
const TCHAR * szListFile,
|
||||
int nDumpLevel)
|
||||
{
|
||||
PCASC_ENCODING_ENTRY pEncodingEntry;
|
||||
CASC_ROOT_BLOCK BlockInfo;
|
||||
PLISTFILE_MAP pListMap;
|
||||
QUERY_KEY EncodingKey;
|
||||
LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
|
||||
LPBYTE pbFilePointer;
|
||||
char szOneLine[0x100];
|
||||
DWORD i;
|
||||
|
||||
// Create the listfile map
|
||||
pListMap = ListFile_CreateMap(szListFile);
|
||||
|
||||
// Dump the root entries
|
||||
for(pbFilePointer = pbRootFile; pbFilePointer <= pbRootFileEnd; )
|
||||
{
|
||||
// Validate the root block
|
||||
pbFilePointer = VerifyLocaleBlock(&BlockInfo, pbFilePointer, pbRootFileEnd);
|
||||
if(pbFilePointer == NULL)
|
||||
break;
|
||||
|
||||
// Dump the locale block
|
||||
dump_print(dc, "Flags: %08X Locales: %08X NumberOfFiles: %u\n"
|
||||
"=========================================================\n",
|
||||
BlockInfo.pLocaleBlockHdr->Flags,
|
||||
BlockInfo.pLocaleBlockHdr->Locales,
|
||||
BlockInfo.pLocaleBlockHdr->NumberOfFiles);
|
||||
|
||||
// Dump the hashes and encoding keys
|
||||
for(i = 0; i < BlockInfo.pLocaleBlockHdr->NumberOfFiles; i++)
|
||||
{
|
||||
// Dump the entry
|
||||
dump_print(dc, "%08X %08X-%08X %s %s\n",
|
||||
(DWORD)(BlockInfo.FileDataIds[i]),
|
||||
(DWORD)(BlockInfo.pRootEntries[i].FileNameHash >> 0x20),
|
||||
(DWORD)(BlockInfo.pRootEntries[i].FileNameHash),
|
||||
StringFromMD5(BlockInfo.pRootEntries[i].EncodingKey.Value, szOneLine),
|
||||
ListFile_FindName(pListMap, BlockInfo.pRootEntries[i].FileNameHash));
|
||||
|
||||
// Find the encoding entry in the encoding table
|
||||
if(nDumpLevel >= DUMP_LEVEL_ENCODING_FILE)
|
||||
{
|
||||
EncodingKey.pbData = BlockInfo.pRootEntries[i].EncodingKey.Value;
|
||||
EncodingKey.cbData = MD5_HASH_SIZE;
|
||||
pEncodingEntry = FindEncodingEntry(hs, &EncodingKey, NULL);
|
||||
CascDumpEncodingEntry(hs, dc, pEncodingEntry, nDumpLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Put extra newline
|
||||
dump_print(dc, "\n");
|
||||
}
|
||||
|
||||
ListFile_FreeMap(pListMap);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int RootHandler_CreateWoW6(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile, DWORD dwLocaleMask)
|
||||
{
|
||||
TRootHandler_WoW6 * pRootHandler;
|
||||
LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
|
||||
int nError;
|
||||
|
||||
// Verify the size
|
||||
if(pbRootFile == NULL || cbRootFile <= sizeof(PFILE_LOCALE_BLOCK))
|
||||
nError = ERROR_FILE_CORRUPT;
|
||||
|
||||
// Allocate the root handler object
|
||||
hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_WoW6, 1);
|
||||
if(pRootHandler == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Fill-in the handler functions
|
||||
memset(pRootHandler, 0, sizeof(TRootHandler_WoW6));
|
||||
pRootHandler->Insert = (ROOT_INSERT)WowHandler_Insert;
|
||||
pRootHandler->Search = (ROOT_SEARCH)WowHandler_Search;
|
||||
pRootHandler->EndSearch = (ROOT_ENDSEARCH)WowHandler_EndSearch;
|
||||
pRootHandler->GetKey = (ROOT_GETKEY)WowHandler_GetKey;
|
||||
pRootHandler->Close = (ROOT_CLOSE)WowHandler_Close;
|
||||
pRootHandler->GetFileId = (ROOT_GETFILEID)WowHandler_GetFileId;
|
||||
|
||||
#ifdef _DEBUG
|
||||
pRootHandler->Dump = TRootHandlerWoW6_Dump; // Support for ROOT file dump
|
||||
#endif // _DEBUG
|
||||
|
||||
// Count the files that are going to be loaded
|
||||
ParseWowRootFile(pRootHandler, ParseRoot_CountFiles, pbRootFile, pbRootFileEnd, dwLocaleMask);
|
||||
pRootHandler->dwTotalFileCount += CASC_EXTRA_FILES;
|
||||
|
||||
// Create linear table that will contain all root items
|
||||
nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, pRootHandler->dwTotalFileCount);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Create sorted table that will contain all root items to lookup by FileDataId
|
||||
nError = Array_Create(&pRootHandler->FileDataIdLookupTable, PCASC_FILE_ENTRY, pRootHandler->dwTotalFileCount);
|
||||
if (nError != ERROR_SUCCESS)
|
||||
return nError;
|
||||
|
||||
// Create the map of FileHash ->FileEntry
|
||||
pRootHandler->pRootMap = Map_Create(pRootHandler->dwTotalFileCount, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash));
|
||||
if(pRootHandler->pRootMap == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Parse the root file again and insert all files to the map
|
||||
ParseWowRootFile(pRootHandler, ParseRoot_AddRootEntries, pbRootFile, pbRootFileEnd, dwLocaleMask);
|
||||
|
||||
// Sort entries by FileDataId for searches
|
||||
qsort_pointer_array((void**)pRootHandler->FileDataIdLookupTable.ItemArray, pRootHandler->FileDataIdLookupTable.ItemCount, &FileDataIdCompare, NULL);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
719
dep/CascLib/src/common/Common.cpp
Normal file
719
dep/CascLib/src/common/Common.cpp
Normal file
@@ -0,0 +1,719 @@
|
||||
/*****************************************************************************/
|
||||
/* CascCommon.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of CascCommon.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Conversion to uppercase/lowercase
|
||||
|
||||
// Converts ASCII characters to lowercase
|
||||
// Converts backslash (0x5C) to normal slash (0x2F)
|
||||
unsigned char AsciiToLowerTable_Slash[256] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x2F, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
// Converts ASCII characters to uppercase
|
||||
// Converts slash (0x2F) to backslash (0x5C)
|
||||
unsigned char AsciiToUpperTable_BkSlash[256] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
unsigned char IntToHexChar[] = "0123456789abcdef";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GetLastError/SetLastError support for non-Windows platform
|
||||
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
static int nLastError = ERROR_SUCCESS;
|
||||
|
||||
int GetLastError()
|
||||
{
|
||||
return nLastError;
|
||||
}
|
||||
|
||||
void SetLastError(int nError)
|
||||
{
|
||||
nLastError = nError;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String manipulation
|
||||
|
||||
void CopyString(char * szTarget, const char * szSource, size_t cchLength)
|
||||
{
|
||||
memcpy(szTarget, szSource, cchLength);
|
||||
szTarget[cchLength] = 0;
|
||||
}
|
||||
|
||||
void CopyString(wchar_t * szTarget, const char * szSource, size_t cchLength)
|
||||
{
|
||||
mbstowcs(szTarget, szSource, cchLength);
|
||||
szTarget[cchLength] = 0;
|
||||
}
|
||||
|
||||
void CopyString(char * szTarget, const wchar_t * szSource, size_t cchLength)
|
||||
{
|
||||
wcstombs(szTarget, szSource, cchLength);
|
||||
szTarget[cchLength] = 0;
|
||||
}
|
||||
|
||||
char * CascNewStr(const char * szString, size_t nCharsToReserve)
|
||||
{
|
||||
char * szNewString = NULL;
|
||||
size_t nLength;
|
||||
|
||||
if(szString != NULL)
|
||||
{
|
||||
nLength = strlen(szString);
|
||||
szNewString = CASC_ALLOC(char, nLength + nCharsToReserve + 1);
|
||||
if(szNewString != NULL)
|
||||
{
|
||||
memcpy(szNewString, szString, nLength);
|
||||
szNewString[nLength] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return szNewString;
|
||||
}
|
||||
|
||||
wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve)
|
||||
{
|
||||
wchar_t * szNewString = NULL;
|
||||
size_t nLength;
|
||||
|
||||
if(szString != NULL)
|
||||
{
|
||||
nLength = wcslen(szString);
|
||||
szNewString = CASC_ALLOC(wchar_t, nLength + nCharsToReserve + 1);
|
||||
if(szNewString != NULL)
|
||||
{
|
||||
memcpy(szNewString, szString, nLength * sizeof(wchar_t));
|
||||
szNewString[nLength] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return szNewString;
|
||||
}
|
||||
|
||||
TCHAR * CascNewStrFromAnsi(const char * szBegin, const char * szEnd)
|
||||
{
|
||||
TCHAR * szNewString = NULL;
|
||||
|
||||
// Only if the entry is valid
|
||||
if(szBegin != NULL && szEnd > szBegin)
|
||||
{
|
||||
// Allocate and copy the string
|
||||
szNewString = CASC_ALLOC(TCHAR, (szEnd - szBegin + 1));
|
||||
if(szNewString != NULL)
|
||||
CopyString(szNewString, szBegin, (szEnd - szBegin));
|
||||
}
|
||||
|
||||
// Return the string
|
||||
return szNewString;
|
||||
}
|
||||
|
||||
TCHAR * CombinePath(const TCHAR * szDirectory, const TCHAR * szSubDir)
|
||||
{
|
||||
TCHAR * szFullPath = NULL;
|
||||
TCHAR * szPathPtr;
|
||||
size_t nLength1 = 0;
|
||||
size_t nLength2 = 0;
|
||||
|
||||
// Calculate lengths of each part
|
||||
if(szDirectory != NULL)
|
||||
{
|
||||
// Get the length of the directory
|
||||
nLength1 = _tcslen(szDirectory);
|
||||
|
||||
// Cut all ending backslashes
|
||||
while(nLength1 > 0 && (szDirectory[nLength1 - 1] == _T('\\') || szDirectory[nLength1 - 1] == _T('/')))
|
||||
nLength1--;
|
||||
}
|
||||
|
||||
if(szSubDir != NULL)
|
||||
{
|
||||
// Cut all leading backslashes
|
||||
while(szSubDir[0] == _T(PATH_SEPARATOR))
|
||||
szSubDir++;
|
||||
|
||||
// Get the length of the subdir
|
||||
nLength2 = _tcslen(szSubDir);
|
||||
|
||||
// Cut all ending backslashes
|
||||
while(nLength2 > 0 && szSubDir[nLength2 - 1] == _T(PATH_SEPARATOR))
|
||||
nLength2--;
|
||||
}
|
||||
|
||||
// Allocate space for the full path
|
||||
szFullPath = szPathPtr = CASC_ALLOC(TCHAR, nLength1 + nLength2 + 2);
|
||||
if(szFullPath != NULL)
|
||||
{
|
||||
// Copy the directory
|
||||
if(szDirectory != NULL && nLength1 != 0)
|
||||
{
|
||||
memcpy(szPathPtr, szDirectory, (nLength1 * sizeof(TCHAR)));
|
||||
szPathPtr += nLength1;
|
||||
}
|
||||
|
||||
// Copy the sub-directory
|
||||
if(szSubDir != NULL && nLength2 != 0)
|
||||
{
|
||||
// Append backslash to the previous one
|
||||
if(szPathPtr > szFullPath)
|
||||
*szPathPtr++ = _T(PATH_SEPARATOR);
|
||||
|
||||
// Copy the string
|
||||
memcpy(szPathPtr, szSubDir, (nLength2 * sizeof(TCHAR)));
|
||||
szPathPtr += nLength2;
|
||||
}
|
||||
|
||||
// Terminate the string
|
||||
szPathPtr[0] = 0;
|
||||
}
|
||||
|
||||
return szFullPath;
|
||||
}
|
||||
|
||||
TCHAR * CombinePathAndString(const TCHAR * szPath, const char * szString, size_t nLength)
|
||||
{
|
||||
TCHAR * szFullPath = NULL;
|
||||
TCHAR * szSubDir;
|
||||
|
||||
// Create the subdir string
|
||||
szSubDir = CASC_ALLOC(TCHAR, nLength + 1);
|
||||
if(szSubDir != NULL)
|
||||
{
|
||||
CopyString(szSubDir, szString, nLength);
|
||||
szFullPath = CombinePath(szPath, szSubDir);
|
||||
CASC_FREE(szSubDir);
|
||||
}
|
||||
|
||||
return szFullPath;
|
||||
}
|
||||
|
||||
size_t NormalizeFileName(const unsigned char * NormTable, char * szNormName, const char * szFileName, size_t cchMaxChars)
|
||||
{
|
||||
char * szNormNameEnd = szNormName + cchMaxChars;
|
||||
size_t i;
|
||||
|
||||
// Normalize the file name: ToLower + BackSlashToSlash
|
||||
for(i = 0; szFileName[0] != 0 && szNormName < szNormNameEnd; i++)
|
||||
*szNormName++ = NormTable[*szFileName++];
|
||||
|
||||
// Terminate the string
|
||||
szNormName[0] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t NormalizeFileName_UpperBkSlash(char * szNormName, const char * szFileName, size_t cchMaxChars)
|
||||
{
|
||||
return NormalizeFileName(AsciiToUpperTable_BkSlash, szNormName, szFileName, cchMaxChars);
|
||||
}
|
||||
|
||||
size_t NormalizeFileName_LowerSlash(char * szNormName, const char * szFileName, size_t cchMaxChars)
|
||||
{
|
||||
return NormalizeFileName(AsciiToLowerTable_Slash, szNormName, szFileName, cchMaxChars);
|
||||
}
|
||||
|
||||
ULONGLONG CalcFileNameHash(const char * szFileName)
|
||||
{
|
||||
char szNormName[MAX_PATH+1];
|
||||
uint32_t dwHashHigh = 0;
|
||||
uint32_t dwHashLow = 0;
|
||||
size_t nLength;
|
||||
|
||||
// Normalize the file name - convert to uppercase, slashes to backslashes
|
||||
nLength = NormalizeFileName_UpperBkSlash(szNormName, szFileName, MAX_PATH);
|
||||
|
||||
// Calculate the HASH value of the normalized file name
|
||||
hashlittle2(szNormName, nLength, &dwHashHigh, &dwHashLow);
|
||||
return ((ULONGLONG)dwHashHigh << 0x20) | dwHashLow;
|
||||
}
|
||||
|
||||
int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue)
|
||||
{
|
||||
BYTE Digit;
|
||||
|
||||
Digit = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0'));
|
||||
if(Digit > 9)
|
||||
Digit -= 'A' - '9' - 1;
|
||||
|
||||
PtrValue[0] = Digit;
|
||||
return (Digit > 0x0F) ? ERROR_BAD_FORMAT : ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int ConvertStringToInt08(const char * szString, PDWORD PtrValue)
|
||||
{
|
||||
BYTE DigitOne = AsciiToUpperTable_BkSlash[szString[0]] - '0';
|
||||
BYTE DigitTwo = AsciiToUpperTable_BkSlash[szString[1]] - '0';
|
||||
|
||||
// Fix the digits
|
||||
if(DigitOne > 9)
|
||||
DigitOne -= 'A' - '9' - 1;
|
||||
if(DigitTwo > 9)
|
||||
DigitTwo -= 'A' - '9' - 1;
|
||||
|
||||
// Combine them into a value
|
||||
PtrValue[0] = (DigitOne << 0x04) | DigitTwo;
|
||||
return (DigitOne <= 0x0F && DigitTwo <= 0x0F) ? ERROR_SUCCESS : ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue)
|
||||
{
|
||||
// The number of digits must be even
|
||||
assert((nMaxDigits & 0x01) == 0);
|
||||
assert(nMaxDigits <= 8);
|
||||
|
||||
// Prepare the variables
|
||||
PtrValue[0] = 0;
|
||||
nMaxDigits >>= 1;
|
||||
|
||||
// Convert the string up to the number of digits
|
||||
for(size_t i = 0; i < nMaxDigits; i++)
|
||||
{
|
||||
BYTE DigitOne;
|
||||
BYTE DigitTwo;
|
||||
|
||||
DigitOne = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0'));
|
||||
if(DigitOne > 9)
|
||||
DigitOne -= 'A' - '9' - 1;
|
||||
|
||||
DigitTwo = (BYTE)(AsciiToUpperTable_BkSlash[szString[1]] - _T('0'));
|
||||
if(DigitTwo > 9)
|
||||
DigitTwo -= 'A' - '9' - 1;
|
||||
|
||||
if(DigitOne > 0x0F || DigitTwo > 0x0F)
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
PtrValue[0] = (PtrValue[0] << 0x08) | (DigitOne << 0x04) | DigitTwo;
|
||||
szString += 2;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Converts string blob to binary blob.
|
||||
int ConvertStringToBinary(
|
||||
const char * szString,
|
||||
size_t nMaxDigits,
|
||||
LPBYTE pbBinary)
|
||||
{
|
||||
const char * szStringEnd = szString + nMaxDigits;
|
||||
DWORD dwCounter = 0;
|
||||
BYTE DigitValue;
|
||||
BYTE ByteValue = 0;
|
||||
|
||||
// Convert the string
|
||||
while(szString < szStringEnd)
|
||||
{
|
||||
// Retrieve the digit converted to hexa
|
||||
DigitValue = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - '0');
|
||||
if(DigitValue > 9)
|
||||
DigitValue -= 'A' - '9' - 1;
|
||||
if(DigitValue > 0x0F)
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
// Insert the digit to the binary buffer
|
||||
ByteValue = (ByteValue << 0x04) | DigitValue;
|
||||
dwCounter++;
|
||||
|
||||
// If we reached the second digit, it means that we need
|
||||
// to flush the byte value and move on
|
||||
if((dwCounter & 0x01) == 0)
|
||||
*pbBinary++ = ByteValue;
|
||||
szString++;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
char * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, char * szBuffer)
|
||||
{
|
||||
char * szSaveBuffer = szBuffer;
|
||||
|
||||
// Convert the string to the array of MD5
|
||||
// Copy the blob data as text
|
||||
for(size_t i = 0; i < cbBinary; i++)
|
||||
{
|
||||
*szBuffer++ = IntToHexChar[pbBinary[0] >> 0x04];
|
||||
*szBuffer++ = IntToHexChar[pbBinary[0] & 0x0F];
|
||||
pbBinary++;
|
||||
}
|
||||
|
||||
// Terminate the string
|
||||
*szBuffer = 0;
|
||||
return szSaveBuffer;
|
||||
}
|
||||
|
||||
char * StringFromMD5(LPBYTE md5, char * szBuffer)
|
||||
{
|
||||
return StringFromBinary(md5, MD5_HASH_SIZE, szBuffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File name utilities
|
||||
|
||||
const wchar_t * GetPlainFileName(const wchar_t * szFileName)
|
||||
{
|
||||
const wchar_t * szPlainName = szFileName;
|
||||
|
||||
while(*szFileName != 0)
|
||||
{
|
||||
if(*szFileName == '\\' || *szFileName == '/')
|
||||
szPlainName = szFileName + 1;
|
||||
szFileName++;
|
||||
}
|
||||
|
||||
return szPlainName;
|
||||
}
|
||||
|
||||
const char * GetPlainFileName(const char * szFileName)
|
||||
{
|
||||
const char * szPlainName = szFileName;
|
||||
|
||||
while(*szFileName != 0)
|
||||
{
|
||||
if(*szFileName == '\\' || *szFileName == '/')
|
||||
szPlainName = szFileName + 1;
|
||||
szFileName++;
|
||||
}
|
||||
|
||||
return szPlainName;
|
||||
}
|
||||
|
||||
bool CheckWildCard(const char * szString, const char * szWildCard)
|
||||
{
|
||||
const char * szWildCardPtr;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// If there is '?' in the wildcard, we skip one char
|
||||
while(szWildCard[0] == '?')
|
||||
{
|
||||
if(szString[0] == 0)
|
||||
return false;
|
||||
|
||||
szWildCard++;
|
||||
szString++;
|
||||
}
|
||||
|
||||
// Handle '*'
|
||||
szWildCardPtr = szWildCard;
|
||||
if(szWildCardPtr[0] != 0)
|
||||
{
|
||||
if(szWildCardPtr[0] == '*')
|
||||
{
|
||||
szWildCardPtr++;
|
||||
|
||||
if(szWildCardPtr[0] == '*')
|
||||
continue;
|
||||
|
||||
if(szWildCardPtr[0] == 0)
|
||||
return true;
|
||||
|
||||
if(AsciiToUpperTable_BkSlash[szWildCardPtr[0]] == AsciiToUpperTable_BkSlash[szString[0]])
|
||||
{
|
||||
if(CheckWildCard(szString, szWildCardPtr))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AsciiToUpperTable_BkSlash[szWildCardPtr[0]] != AsciiToUpperTable_BkSlash[szString[0]])
|
||||
return false;
|
||||
|
||||
szWildCard = szWildCardPtr + 1;
|
||||
}
|
||||
|
||||
if(szString[0] == 0)
|
||||
return false;
|
||||
szString++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (szString[0] == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hashing functions
|
||||
|
||||
bool IsValidMD5(LPBYTE pbMd5)
|
||||
{
|
||||
BYTE BitSummary = 0;
|
||||
|
||||
// The MD5 is considered invalid of it is zeroed
|
||||
BitSummary |= pbMd5[0x00] | pbMd5[0x01] | pbMd5[0x02] | pbMd5[0x03] | pbMd5[0x04] | pbMd5[0x05] | pbMd5[0x06] | pbMd5[0x07];
|
||||
BitSummary |= pbMd5[0x08] | pbMd5[0x09] | pbMd5[0x0A] | pbMd5[0x0B] | pbMd5[0x0C] | pbMd5[0x0D] | pbMd5[0x0E] | pbMd5[0x0F];
|
||||
return (BitSummary != 0);
|
||||
}
|
||||
|
||||
bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
|
||||
{
|
||||
hash_state md5_state;
|
||||
BYTE md5_digest[MD5_HASH_SIZE];
|
||||
|
||||
// Don't verify the block if the MD5 is not valid.
|
||||
if(!IsValidMD5(expected_md5))
|
||||
return true;
|
||||
|
||||
// Calculate the MD5 of the data block
|
||||
md5_init(&md5_state);
|
||||
md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
|
||||
md5_done(&md5_state, md5_digest);
|
||||
|
||||
// Does the MD5's match?
|
||||
return (memcmp(md5_digest, expected_md5, MD5_HASH_SIZE) == 0);
|
||||
}
|
||||
|
||||
void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash)
|
||||
{
|
||||
hash_state md5_state;
|
||||
|
||||
md5_init(&md5_state);
|
||||
md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
|
||||
md5_done(&md5_state, md5_hash);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// We have our own qsort implementation, optimized for using array of pointers
|
||||
|
||||
#define STKSIZ (8*sizeof(void*) - 2)
|
||||
|
||||
#define SWAP_ENTRIES(index1, index2) \
|
||||
{ \
|
||||
temp = base[index1]; \
|
||||
base[index1] = base[index2]; \
|
||||
base[index2] = temp; \
|
||||
}
|
||||
|
||||
void qsort_pointer_array(void ** base, size_t num, int (*compare)(const void *, const void *, const void *), const void * context)
|
||||
{
|
||||
size_t lo, hi; /* ends of sub-array currently sorting */
|
||||
size_t mid; /* points to middle of subarray */
|
||||
size_t loguy, higuy; /* traveling pointers for partition step */
|
||||
size_t size; /* size of the sub-array */
|
||||
size_t lostk[STKSIZ], histk[STKSIZ];
|
||||
void * temp;
|
||||
int stkptr; /* stack for saving sub-array to be processed */
|
||||
|
||||
/* validation section */
|
||||
assert(base != NULL);
|
||||
assert(compare != NULL);
|
||||
|
||||
if (num < 2)
|
||||
return; /* nothing to do */
|
||||
|
||||
stkptr = 0; /* initialize stack */
|
||||
|
||||
lo = 0;
|
||||
hi = (num-1); /* initialize limits */
|
||||
|
||||
/* this entry point is for pseudo-recursion calling: setting
|
||||
lo and hi and jumping to here is like recursion, but stkptr is
|
||||
preserved, locals aren't, so we preserve stuff on the stack */
|
||||
recurse:
|
||||
|
||||
size = (hi - lo) + 1; /* number of el's to sort */
|
||||
|
||||
/* First we pick a partitioning element. The efficiency of the
|
||||
algorithm demands that we find one that is approximately the median
|
||||
of the values, but also that we select one fast. We choose the
|
||||
median of the first, middle, and last elements, to avoid bad
|
||||
performance in the face of already sorted data, or data that is made
|
||||
up of multiple sorted runs appended together. Testing shows that a
|
||||
median-of-three algorithm provides better performance than simply
|
||||
picking the middle element for the latter case. */
|
||||
|
||||
mid = lo + (size / 2); /* find middle element */
|
||||
|
||||
/* Sort the first, middle, last elements into order */
|
||||
if (compare(context, base[lo], base[mid]) > 0) {
|
||||
SWAP_ENTRIES(lo, mid);
|
||||
}
|
||||
if (compare(context, base[lo], base[hi]) > 0) {
|
||||
SWAP_ENTRIES(lo, hi);
|
||||
}
|
||||
if (compare(context, base[mid], base[hi]) > 0) {
|
||||
SWAP_ENTRIES(mid, hi);
|
||||
}
|
||||
|
||||
/* We now wish to partition the array into three pieces, one consisting
|
||||
of elements <= partition element, one of elements equal to the
|
||||
partition element, and one of elements > than it. This is done
|
||||
below; comments indicate conditions established at every step. */
|
||||
|
||||
loguy = lo;
|
||||
higuy = hi;
|
||||
|
||||
/* Note that higuy decreases and loguy increases on every iteration,
|
||||
so loop must terminate. */
|
||||
for (;;) {
|
||||
/* lo <= loguy < hi, lo < higuy <= hi,
|
||||
A[i] <= A[mid] for lo <= i <= loguy,
|
||||
A[i] > A[mid] for higuy <= i < hi,
|
||||
A[hi] >= A[mid] */
|
||||
|
||||
/* The doubled loop is to avoid calling comp(mid,mid), since some
|
||||
existing comparison funcs don't work when passed the same
|
||||
value for both pointers. */
|
||||
|
||||
if (mid > loguy) {
|
||||
do {
|
||||
loguy ++;
|
||||
} while (loguy < mid && compare(context, base[loguy], base[mid]) <= 0);
|
||||
}
|
||||
if (mid <= loguy) {
|
||||
do {
|
||||
loguy ++;
|
||||
} while (loguy <= hi && compare(context, base[loguy], base[mid]) <= 0);
|
||||
}
|
||||
|
||||
/* lo < loguy <= hi+1, A[i] <= A[mid] for lo <= i < loguy,
|
||||
either loguy > hi or A[loguy] > A[mid] */
|
||||
|
||||
do {
|
||||
higuy --;
|
||||
} while (higuy > mid && compare(context, base[higuy], base[mid]) > 0);
|
||||
|
||||
/* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi,
|
||||
either higuy == lo or A[higuy] <= A[mid] */
|
||||
|
||||
if (higuy < loguy)
|
||||
break;
|
||||
|
||||
/* if loguy > hi or higuy == lo, then we would have exited, so
|
||||
A[loguy] > A[mid], A[higuy] <= A[mid],
|
||||
loguy <= hi, higuy > lo */
|
||||
|
||||
SWAP_ENTRIES(loguy, higuy);
|
||||
|
||||
/* If the partition element was moved, follow it. Only need
|
||||
to check for mid == higuy, since before the swap,
|
||||
A[loguy] > A[mid] implies loguy != mid. */
|
||||
|
||||
if (mid == higuy)
|
||||
mid = loguy;
|
||||
|
||||
/* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition at top
|
||||
of loop is re-established */
|
||||
}
|
||||
|
||||
/* A[i] <= A[mid] for lo <= i < loguy,
|
||||
A[i] > A[mid] for higuy < i < hi,
|
||||
A[hi] >= A[mid]
|
||||
higuy < loguy
|
||||
implying:
|
||||
higuy == loguy-1
|
||||
or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] */
|
||||
|
||||
/* Find adjacent elements equal to the partition element. The
|
||||
doubled loop is to avoid calling comp(mid,mid), since some
|
||||
existing comparison funcs don't work when passed the same value
|
||||
for both pointers. */
|
||||
|
||||
higuy ++;
|
||||
if (mid < higuy) {
|
||||
do {
|
||||
higuy --;
|
||||
} while (higuy > mid && compare(context, base[higuy], base[mid]) == 0);
|
||||
}
|
||||
if (mid >= higuy) {
|
||||
do {
|
||||
higuy --;
|
||||
} while (higuy > lo && compare(context, base[higuy], base[mid]) == 0);
|
||||
}
|
||||
|
||||
/* OK, now we have the following:
|
||||
higuy < loguy
|
||||
lo <= higuy <= hi
|
||||
A[i] <= A[mid] for lo <= i <= higuy
|
||||
A[i] == A[mid] for higuy < i < loguy
|
||||
A[i] > A[mid] for loguy <= i < hi
|
||||
A[hi] >= A[mid] */
|
||||
|
||||
/* We've finished the partition, now we want to sort the subarrays
|
||||
[lo, higuy] and [loguy, hi].
|
||||
We do the smaller one first to minimize stack usage.
|
||||
We only sort arrays of length 2 or more.*/
|
||||
|
||||
if ( higuy - lo >= hi - loguy ) {
|
||||
if (lo < higuy) {
|
||||
lostk[stkptr] = lo;
|
||||
histk[stkptr] = higuy;
|
||||
++stkptr;
|
||||
} /* save big recursion for later */
|
||||
|
||||
if (loguy < hi) {
|
||||
lo = loguy;
|
||||
goto recurse; /* do small recursion */
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (loguy < hi) {
|
||||
lostk[stkptr] = loguy;
|
||||
histk[stkptr] = hi;
|
||||
++stkptr; /* save big recursion for later */
|
||||
}
|
||||
|
||||
if (lo < higuy) {
|
||||
hi = higuy;
|
||||
goto recurse; /* do small recursion */
|
||||
}
|
||||
}
|
||||
|
||||
/* We have sorted the array, except for any pending sorts on the stack.
|
||||
Check if there are any, and do them. */
|
||||
|
||||
--stkptr;
|
||||
if (stkptr >= 0) {
|
||||
lo = lostk[stkptr];
|
||||
hi = histk[stkptr];
|
||||
goto recurse; /* pop subarray from stack */
|
||||
}
|
||||
else
|
||||
return; /* all subarrays done */
|
||||
}
|
||||
89
dep/CascLib/src/common/Common.h
Normal file
89
dep/CascLib/src/common/Common.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*****************************************************************************/
|
||||
/* CascCommon.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of CascCommon.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common macros
|
||||
|
||||
// Macro for building 64-bit file offset from two 32-bit
|
||||
#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo)
|
||||
|
||||
#ifndef ALIGN_TO_SIZE
|
||||
#define ALIGN_TO_SIZE(x, a) (((x) + (a)-1) & ~((a)-1))
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Conversion tables
|
||||
|
||||
extern unsigned char AsciiToLowerTable_Slash[256];
|
||||
extern unsigned char AsciiToUpperTable_BkSlash[256];
|
||||
extern unsigned char IntToHexChar[];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String manipulation
|
||||
|
||||
void CopyString(char * szTarget, const char * szSource, size_t cchLength);
|
||||
void CopyString(wchar_t * szTarget, const char * szSource, size_t cchLength);
|
||||
void CopyString(char * szTarget, const wchar_t * szSource, size_t cchLength);
|
||||
|
||||
char * CascNewStr(const char * szString, size_t nCharsToReserve);
|
||||
wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve);
|
||||
|
||||
TCHAR * CascNewStrFromAnsi(const char * szBegin, const char * szEnd);
|
||||
|
||||
TCHAR * CombinePath(const TCHAR * szPath, const TCHAR * szSubDir);
|
||||
TCHAR * CombinePathAndString(const TCHAR * szPath, const char * szString, size_t nLength);
|
||||
|
||||
size_t NormalizeFileName_UpperBkSlash(char * szNormName, const char * szFileName, size_t cchMaxChars);
|
||||
size_t NormalizeFileName_LowerSlash(char * szNormName, const char * szFileName, size_t cchMaxChars);
|
||||
|
||||
ULONGLONG CalcFileNameHash(const char * szFileName);
|
||||
|
||||
int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue);
|
||||
int ConvertStringToInt08(const char * szString, PDWORD PtrValue);
|
||||
int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue);
|
||||
int ConvertStringToBinary(const char * szString, size_t nMaxDigits, LPBYTE pbBinary);
|
||||
char * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, char * szBuffer);
|
||||
char * StringFromMD5(LPBYTE md5, char * szBuffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File name utilities
|
||||
|
||||
bool CheckWildCard(const char * szString, const char * szWildCard);
|
||||
const wchar_t * GetPlainFileName(const wchar_t * szFileName);
|
||||
const char * GetPlainFileName(const char * szFileName);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hashing functions
|
||||
|
||||
ULONGLONG HashStringJenkins(const char * szFileName);
|
||||
|
||||
bool IsValidMD5(LPBYTE pbMd5);
|
||||
void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash);
|
||||
bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanning a directory
|
||||
|
||||
typedef bool (*INDEX_FILE_FOUND)(const TCHAR * szFileName, PDWORD IndexArray, PDWORD OldIndexArray, void * pvContext);
|
||||
|
||||
bool DirectoryExists(const TCHAR * szDirectory);
|
||||
|
||||
int ScanIndexDirectory(
|
||||
const TCHAR * szIndexPath,
|
||||
INDEX_FILE_FOUND pfnOnFileFound,
|
||||
PDWORD IndexArray,
|
||||
PDWORD OldIndexArray,
|
||||
void * pvContext
|
||||
);
|
||||
|
||||
#endif // __COMMON_H__
|
||||
102
dep/CascLib/src/common/Directory.cpp
Normal file
102
dep/CascLib/src/common/Directory.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*****************************************************************************/
|
||||
/* Directory.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* System-dependent directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 29.04.14 1.00 Lad The first version of Directory.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
bool DirectoryExists(const TCHAR * szDirectory)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
|
||||
DWORD dwAttributes = GetFileAttributes(szDirectory);
|
||||
if((dwAttributes != INVALID_FILE_ATTRIBUTES) && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
#else // PLATFORM_WINDOWS
|
||||
|
||||
DIR * dir = opendir(szDirectory);
|
||||
|
||||
if(dir != NULL)
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ScanIndexDirectory(
|
||||
const TCHAR * szIndexPath,
|
||||
INDEX_FILE_FOUND pfnOnFileFound,
|
||||
PDWORD MainIndexes,
|
||||
PDWORD OldIndexArray,
|
||||
void * pvContext)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
|
||||
WIN32_FIND_DATA wf;
|
||||
TCHAR * szSearchMask;
|
||||
HANDLE hFind;
|
||||
|
||||
// Prepare the search mask
|
||||
szSearchMask = CombinePath(szIndexPath, _T("*"));
|
||||
if(szSearchMask == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Prepare directory search
|
||||
hFind = FindFirstFile(szSearchMask, &wf);
|
||||
if(hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
// Skip the first file as it's always just "." or ".."
|
||||
while(FindNextFile(hFind, &wf))
|
||||
{
|
||||
// If the found object is a file, pass it to the handler
|
||||
if(!(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
// Let the callback scan the file name
|
||||
pfnOnFileFound(wf.cFileName, MainIndexes, OldIndexArray, pvContext);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the search handle
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
CASC_FREE(szSearchMask);
|
||||
|
||||
#else // PLATFORM_WINDOWS
|
||||
|
||||
struct dirent * dir_entry;
|
||||
DIR * dir;
|
||||
|
||||
dir = opendir(szIndexPath);
|
||||
if(dir != NULL)
|
||||
{
|
||||
while((dir_entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(dir_entry->d_type != DT_DIR)
|
||||
{
|
||||
pfnOnFileFound(dir_entry->d_name, MainIndexes, OldIndexArray, pvContext);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
29
dep/CascLib/src/common/Directory.h
Normal file
29
dep/CascLib/src/common/Directory.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*****************************************************************************/
|
||||
/* Directory.h Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Directory functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 30.10.15 1.00 Lad The first version of Directory.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __DIRECTORY_H__
|
||||
#define __DIRECTORY_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanning a directory
|
||||
|
||||
typedef bool (*INDEX_FILE_FOUND)(const TCHAR * szFileName, PDWORD IndexArray, PDWORD OldIndexArray, void * pvContext);
|
||||
|
||||
bool DirectoryExists(const TCHAR * szDirectory);
|
||||
|
||||
int ScanIndexDirectory(
|
||||
const TCHAR * szIndexPath,
|
||||
INDEX_FILE_FOUND pfnOnFileFound,
|
||||
PDWORD IndexArray,
|
||||
PDWORD OldIndexArray,
|
||||
void * pvContext
|
||||
);
|
||||
|
||||
#endif // __DIRECTORY_H__
|
||||
153
dep/CascLib/src/common/DumpContext.cpp
Normal file
153
dep/CascLib/src/common/DumpContext.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*****************************************************************************/
|
||||
/* DumpContext.cpp Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Implementation of dump context */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 16.03.15 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static TCHAR * FormatFileName(TCascStorage * hs, const TCHAR * szNameFormat)
|
||||
{
|
||||
TCHAR * szFileName;
|
||||
TCHAR * szSrc;
|
||||
TCHAR * szTrg;
|
||||
|
||||
// Create copy of the file name
|
||||
szFileName = szSrc = szTrg = CascNewStr(szNameFormat, 0);
|
||||
if(szFileName != NULL)
|
||||
{
|
||||
// Format the file name
|
||||
while(szSrc[0] != 0)
|
||||
{
|
||||
if(szSrc[0] == _T('%'))
|
||||
{
|
||||
// Replace "%build%" with a build number
|
||||
if(!_tcsncmp(szSrc, _T("%build%"), 7))
|
||||
{
|
||||
szTrg += _stprintf(szTrg, _T("%u"), hs->dwBuildNumber);
|
||||
szSrc += 7;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Just copy the character
|
||||
*szTrg++ = *szSrc++;
|
||||
}
|
||||
|
||||
// Terminate the target file name
|
||||
szTrg[0] = 0;
|
||||
}
|
||||
|
||||
return szFileName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
TDumpContext * CreateDumpContext(TCascStorage * hs, const TCHAR * szNameFormat)
|
||||
{
|
||||
TDumpContext * dc;
|
||||
TCHAR * szFileName;
|
||||
|
||||
// Validate the storage handle
|
||||
if(hs != NULL)
|
||||
{
|
||||
// Calculate the number of bytes needed for dump context
|
||||
dc = CASC_ALLOC(TDumpContext, 1);
|
||||
if(dc != NULL)
|
||||
{
|
||||
// Initialize the dump context
|
||||
memset(dc, 0, sizeof(TDumpContext));
|
||||
|
||||
// Format the real file name
|
||||
szFileName = FormatFileName(hs, szNameFormat);
|
||||
if(szFileName != NULL)
|
||||
{
|
||||
// Create the file
|
||||
dc->pStream = FileStream_CreateFile(szFileName, 0);
|
||||
if(dc->pStream != NULL)
|
||||
{
|
||||
// Initialize buffers
|
||||
dc->pbBufferBegin =
|
||||
dc->pbBufferPtr = dc->DumpBuffer;
|
||||
dc->pbBufferEnd = dc->DumpBuffer + CASC_DUMP_BUFFER_SIZE;
|
||||
|
||||
// Success
|
||||
CASC_FREE(szFileName);
|
||||
return dc;
|
||||
}
|
||||
|
||||
// File create failed --> delete the file name
|
||||
CASC_FREE(szFileName);
|
||||
}
|
||||
|
||||
// Free the dump context
|
||||
CASC_FREE(dc);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dump_print(TDumpContext * dc, const char * szFormat, ...)
|
||||
{
|
||||
va_list argList;
|
||||
char szBuffer[0x200];
|
||||
int nLength = 0;
|
||||
|
||||
// Only if the dump context is valid
|
||||
if(dc != NULL)
|
||||
{
|
||||
// Print the buffer using sprintf
|
||||
va_start(argList, szFormat);
|
||||
nLength = vsprintf(szBuffer, szFormat, argList);
|
||||
assert(nLength < 0x200);
|
||||
va_end(argList);
|
||||
|
||||
// Copy the string. Replace "\n" with "\n\r"
|
||||
for(int i = 0; i < nLength; i++)
|
||||
{
|
||||
// Flush the buffer, if needed
|
||||
if((dc->pbBufferPtr + 2) >= dc->pbBufferEnd)
|
||||
{
|
||||
FileStream_Write(dc->pStream, NULL, dc->pbBufferBegin, (DWORD)(dc->pbBufferPtr - dc->pbBufferBegin));
|
||||
dc->pbBufferPtr = dc->pbBufferBegin;
|
||||
}
|
||||
|
||||
// Copy the char
|
||||
if(szBuffer[i] == 0x0A)
|
||||
*dc->pbBufferPtr++ = 0x0D;
|
||||
*dc->pbBufferPtr++ = szBuffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nLength;
|
||||
}
|
||||
|
||||
int dump_close(TDumpContext * dc)
|
||||
{
|
||||
// Only if the dump context is valid
|
||||
if(dc != NULL)
|
||||
{
|
||||
// Flush the dump context if there are some data
|
||||
if(dc->pbBufferPtr > dc->pbBufferBegin)
|
||||
FileStream_Write(dc->pStream, NULL, dc->pbBufferBegin, (DWORD)(dc->pbBufferPtr - dc->pbBufferBegin));
|
||||
dc->pbBufferPtr = dc->pbBufferBegin;
|
||||
|
||||
// Free the file stream and the entire context
|
||||
if(dc->pStream != NULL)
|
||||
FileStream_Close(dc->pStream);
|
||||
CASC_FREE(dc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
38
dep/CascLib/src/common/DumpContext.h
Normal file
38
dep/CascLib/src/common/DumpContext.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*****************************************************************************/
|
||||
/* DumpContext.h Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Interface for TDumpContext */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 16.03.15 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __DUMP_CONTEXT_H__
|
||||
#define __DUMP_CONTEXT_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
// Size of the buffer for the dump context
|
||||
#define CASC_DUMP_BUFFER_SIZE 0x10000
|
||||
|
||||
// Structure for dump context
|
||||
struct TDumpContext
|
||||
{
|
||||
TFileStream * pStream; // Pointer to the open stream
|
||||
LPBYTE pbBufferBegin; // Begin of the dump buffer
|
||||
LPBYTE pbBufferPtr; // Current dump buffer pointer
|
||||
LPBYTE pbBufferEnd; // End of the dump buffer
|
||||
|
||||
BYTE DumpBuffer[CASC_DUMP_BUFFER_SIZE]; // Dump buffer
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dump context functions
|
||||
|
||||
TDumpContext * CreateDumpContext(struct _TCascStorage * hs, const TCHAR * szNameFormat);
|
||||
int dump_print(TDumpContext * dc, const char * szFormat, ...);
|
||||
int dump_close(TDumpContext * dc);
|
||||
|
||||
#endif // __DUMP_CONTEXT_H__
|
||||
101
dep/CascLib/src/common/DynamicArray.cpp
Normal file
101
dep/CascLib/src/common/DynamicArray.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************/
|
||||
/* DynamicArray.cpp Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 30.10.15 1.00 Lad The first version of DynamicArray.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static bool EnlargeArray(PDYNAMIC_ARRAY pArray, size_t NewItemCount)
|
||||
{
|
||||
char * NewItemArray;
|
||||
size_t ItemCountMax;
|
||||
|
||||
// We expect the array to be already allocated
|
||||
assert(pArray->ItemArray != NULL);
|
||||
assert(pArray->ItemCountMax != 0);
|
||||
|
||||
// Shall we enlarge the table?
|
||||
if(NewItemCount > pArray->ItemCountMax)
|
||||
{
|
||||
// Calculate new table size
|
||||
ItemCountMax = pArray->ItemCountMax;
|
||||
while(ItemCountMax < NewItemCount)
|
||||
ItemCountMax = ItemCountMax << 1;
|
||||
|
||||
// Allocate new table
|
||||
NewItemArray = CASC_REALLOC(char, pArray->ItemArray, pArray->ItemSize * ItemCountMax);
|
||||
if(NewItemArray == NULL)
|
||||
return false;
|
||||
|
||||
// Set the new table size
|
||||
pArray->ItemCountMax = ItemCountMax;
|
||||
pArray->ItemArray = NewItemArray;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int Array_Create_(PDYNAMIC_ARRAY pArray, size_t ItemSize, size_t ItemCountMax)
|
||||
{
|
||||
pArray->ItemArray = CASC_ALLOC(char, (ItemSize * ItemCountMax));
|
||||
if(pArray->ItemArray == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
pArray->ItemCountMax = ItemCountMax;
|
||||
pArray->ItemCount = 0;
|
||||
pArray->ItemSize = ItemSize;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void * Array_Insert(PDYNAMIC_ARRAY pArray, const void * NewItems, size_t NewItemCount)
|
||||
{
|
||||
char * NewItemPtr;
|
||||
|
||||
// Try to enlarge the buffer, if needed
|
||||
if(!EnlargeArray(pArray, pArray->ItemCount + NewItemCount))
|
||||
return NULL;
|
||||
NewItemPtr = pArray->ItemArray + (pArray->ItemCount * pArray->ItemSize);
|
||||
|
||||
// Copy the old item(s), if any
|
||||
if(NewItems != NULL)
|
||||
memcpy(NewItemPtr, NewItems, (NewItemCount * pArray->ItemSize));
|
||||
|
||||
// Increment the size of the array
|
||||
pArray->ItemCount += NewItemCount;
|
||||
return NewItemPtr;
|
||||
}
|
||||
|
||||
void * Array_ItemAt(PDYNAMIC_ARRAY pArray, size_t ItemIndex)
|
||||
{
|
||||
assert(ItemIndex < pArray->ItemCount);
|
||||
return pArray->ItemArray + (ItemIndex * pArray->ItemSize);
|
||||
}
|
||||
|
||||
size_t Array_IndexOf(PDYNAMIC_ARRAY pArray, const void * ArrayPtr)
|
||||
{
|
||||
char * ArrayItem = (char *)ArrayPtr;
|
||||
|
||||
assert(pArray->ItemArray <= ArrayItem && ArrayItem <= pArray->ItemArray + (pArray->ItemCount * pArray->ItemSize));
|
||||
return ((ArrayItem - pArray->ItemArray) / pArray->ItemSize);
|
||||
}
|
||||
|
||||
void Array_Free(PDYNAMIC_ARRAY pArray)
|
||||
{
|
||||
if(pArray != NULL && pArray->ItemArray != NULL)
|
||||
{
|
||||
CASC_FREE(pArray->ItemArray);
|
||||
}
|
||||
}
|
||||
37
dep/CascLib/src/common/DynamicArray.h
Normal file
37
dep/CascLib/src/common/DynamicArray.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*****************************************************************************/
|
||||
/* DynamicArray.h Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common array implementation */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 30.10.15 1.00 Lad The first version of DynamicArray.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __DYNAMIC_ARRAY_H__
|
||||
#define __DYNAMIC_ARRAY_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures
|
||||
|
||||
typedef struct _DYNAMIC_ARRAY
|
||||
{
|
||||
char * ItemArray; // Pointer to items
|
||||
size_t ItemCountMax; // Current number of items
|
||||
size_t ItemCount; // Total size of the buffer
|
||||
size_t ItemSize; // Size of the single item
|
||||
|
||||
} DYNAMIC_ARRAY, *PDYNAMIC_ARRAY;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for managing the array
|
||||
|
||||
int Array_Create_(PDYNAMIC_ARRAY pArray, size_t ItemSize, size_t ItemCountMax);
|
||||
void * Array_Insert(PDYNAMIC_ARRAY pArray, const void * NewItems, size_t NewItemCount);
|
||||
void * Array_ItemAt(PDYNAMIC_ARRAY pArray, size_t ItemIndex);
|
||||
size_t Array_IndexOf(PDYNAMIC_ARRAY pArray, const void * ArrayPtr);
|
||||
void Array_Free(PDYNAMIC_ARRAY pArray);
|
||||
|
||||
#define Array_Create(pArray, type, ItemCountMax) Array_Create_(pArray, sizeof(type), ItemCountMax)
|
||||
|
||||
#endif // __DYNAMIC_ARRAY__
|
||||
2739
dep/CascLib/src/common/FileStream.cpp
Normal file
2739
dep/CascLib/src/common/FileStream.cpp
Normal file
File diff suppressed because it is too large
Load Diff
260
dep/CascLib/src/common/FileStream.h
Normal file
260
dep/CascLib/src/common/FileStream.h
Normal file
@@ -0,0 +1,260 @@
|
||||
/*****************************************************************************/
|
||||
/* FileStream.h Copyright (c) Ladislav Zezula 2012 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: Definitions for FileStream object */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 14.04.12 1.00 Lad The first version of FileStream.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __FILESTREAM_H__
|
||||
#define __FILESTREAM_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Flags for file stream
|
||||
|
||||
#define BASE_PROVIDER_FILE 0x00000000 // Base data source is a file
|
||||
#define BASE_PROVIDER_MAP 0x00000001 // Base data source is memory-mapped file
|
||||
#define BASE_PROVIDER_HTTP 0x00000002 // Base data source is a file on web server
|
||||
#define BASE_PROVIDER_MASK 0x0000000F // Mask for base provider value
|
||||
|
||||
#define STREAM_PROVIDER_FLAT 0x00000000 // Stream is linear with no offset mapping
|
||||
#define STREAM_PROVIDER_PARTIAL 0x00000010 // Stream is partial file (.part)
|
||||
#define STREAM_PROVIDER_ENCRYPTED 0x00000020 // Stream is an encrypted archive
|
||||
#define STREAM_PROVIDER_BLOCK4 0x00000030 // 0x4000 per block, text MD5 after each block, max 0x2000 blocks per file
|
||||
#define STREAM_PROVIDER_MASK 0x000000F0 // Mask for stream provider value
|
||||
|
||||
#define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only
|
||||
#define STREAM_FLAG_WRITE_SHARE 0x00000200 // Allow write sharing when open for write
|
||||
#define STREAM_FLAG_USE_BITMAP 0x00000400 // If the file has a file bitmap, load it and use it
|
||||
#define STREAM_OPTIONS_MASK 0x0000FF00 // Mask for stream options
|
||||
|
||||
#define STREAM_PROVIDERS_MASK 0x000000FF // Mask to get stream providers
|
||||
#define STREAM_FLAGS_MASK 0x0000FFFF // Mask for all stream flags (providers+options)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function prototypes
|
||||
|
||||
typedef void (*STREAM_INIT)(
|
||||
struct TFileStream * pStream // Pointer to an unopened stream
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_CREATE)(
|
||||
struct TFileStream * pStream // Pointer to an unopened stream
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_OPEN)(
|
||||
struct TFileStream * pStream, // Pointer to an unopened stream
|
||||
const TCHAR * szFileName, // Pointer to file name to be open
|
||||
DWORD dwStreamFlags // Stream flags
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_READ)(
|
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
|
||||
void * pvBuffer, // Pointer to data to be read
|
||||
DWORD dwBytesToRead // Number of bytes to read from the file
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_WRITE)(
|
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position
|
||||
const void * pvBuffer, // Pointer to data to be written
|
||||
DWORD dwBytesToWrite // Number of bytes to read from the file
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_RESIZE)(
|
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG FileSize // New size for the file, in bytes
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_GETSIZE)(
|
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pFileSize // Receives the file size, in bytes
|
||||
);
|
||||
|
||||
typedef bool (*STREAM_GETPOS)(
|
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset // Pointer to store current file position
|
||||
);
|
||||
|
||||
typedef void (*STREAM_CLOSE)(
|
||||
struct TFileStream * pStream // Pointer to an open stream
|
||||
);
|
||||
|
||||
typedef bool (*BLOCK_READ)(
|
||||
struct TFileStream * pStream, // Pointer to a block-oriented stream
|
||||
ULONGLONG StartOffset, // Byte offset of start of the block array
|
||||
ULONGLONG EndOffset, // End offset (either end of the block or end of the file)
|
||||
LPBYTE BlockBuffer, // Pointer to block-aligned buffer
|
||||
DWORD BytesNeeded, // Number of bytes that are really needed
|
||||
bool bAvailable // true if the block is available
|
||||
);
|
||||
|
||||
typedef bool (*BLOCK_CHECK)(
|
||||
struct TFileStream * pStream, // Pointer to a block-oriented stream
|
||||
ULONGLONG BlockOffset // Offset of the file to check
|
||||
);
|
||||
|
||||
typedef void (*BLOCK_SAVEMAP)(
|
||||
struct TFileStream * pStream // Pointer to a block-oriented stream
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures - partial file structure and bitmap footer
|
||||
|
||||
#define ID_FILE_BITMAP_FOOTER 0x33767470 // Signature of the file bitmap footer ('ptv3')
|
||||
#define DEFAULT_BLOCK_SIZE 0x00004000 // Default size of the stream block
|
||||
#define DEFAULT_BUILD_NUMBER 10958 // Build number for newly created partial MPQs
|
||||
|
||||
typedef struct _PART_FILE_HEADER
|
||||
{
|
||||
DWORD PartialVersion; // Always set to 2
|
||||
char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ
|
||||
DWORD Flags; // Flags (details unknown)
|
||||
DWORD FileSizeLo; // Low 32 bits of the contained file size
|
||||
DWORD FileSizeHi; // High 32 bits of the contained file size
|
||||
DWORD BlockSize; // Size of one file block, in bytes
|
||||
|
||||
} PART_FILE_HEADER, *PPART_FILE_HEADER;
|
||||
|
||||
// Structure describing the block-to-file map entry
|
||||
typedef struct _PART_FILE_MAP_ENTRY
|
||||
{
|
||||
DWORD Flags; // 3 = the block is present in the file
|
||||
DWORD BlockOffsLo; // Low 32 bits of the block position in the file
|
||||
DWORD BlockOffsHi; // High 32 bits of the block position in the file
|
||||
DWORD LargeValueLo; // 64-bit value, meaning is unknown
|
||||
DWORD LargeValueHi;
|
||||
|
||||
} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY;
|
||||
|
||||
typedef struct _FILE_BITMAP_FOOTER
|
||||
{
|
||||
DWORD Signature; // 'ptv3' (ID_FILE_BITMAP_FOOTER)
|
||||
DWORD Version; // Unknown, seems to always have value of 3 (version?)
|
||||
DWORD BuildNumber; // Game build number for that MPQ
|
||||
DWORD MapOffsetLo; // Low 32-bits of the offset of the bit map
|
||||
DWORD MapOffsetHi; // High 32-bits of the offset of the bit map
|
||||
DWORD BlockSize; // Size of one block (usually 0x4000 bytes)
|
||||
|
||||
} FILE_BITMAP_FOOTER, *PFILE_BITMAP_FOOTER;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure for file stream
|
||||
|
||||
union TBaseProviderData
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
HANDLE hFile; // File handle
|
||||
} File;
|
||||
|
||||
struct
|
||||
{
|
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
LPBYTE pbFile; // Pointer to mapped view
|
||||
} Map;
|
||||
|
||||
struct
|
||||
{
|
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
HANDLE hInternet; // Internet handle
|
||||
HANDLE hConnect; // Connection to the internet server
|
||||
} Http;
|
||||
};
|
||||
|
||||
struct TFileStream
|
||||
{
|
||||
// Stream provider functions
|
||||
STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly.
|
||||
STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly.
|
||||
STREAM_RESIZE StreamResize; // Pointer to function changing file size
|
||||
STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size
|
||||
STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position
|
||||
STREAM_CLOSE StreamClose; // Pointer to function closing the stream
|
||||
|
||||
// Block-oriented functions
|
||||
BLOCK_READ BlockRead; // Pointer to function reading one or more blocks
|
||||
BLOCK_CHECK BlockCheck; // Pointer to function checking whether the block is present
|
||||
|
||||
// Base provider functions
|
||||
STREAM_CREATE BaseCreate; // Pointer to base create function
|
||||
STREAM_OPEN BaseOpen; // Pointer to base open function
|
||||
STREAM_READ BaseRead; // Read from the stream
|
||||
STREAM_WRITE BaseWrite; // Write to the stream
|
||||
STREAM_RESIZE BaseResize; // Pointer to function changing file size
|
||||
STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size
|
||||
STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position
|
||||
STREAM_CLOSE BaseClose; // Pointer to function closing the stream
|
||||
|
||||
// Base provider data (file size, file position)
|
||||
TBaseProviderData Base;
|
||||
|
||||
// Stream provider data
|
||||
TFileStream * pMaster; // Master stream (e.g. MPQ on a web server)
|
||||
TCHAR * szFileName; // File name (self-relative pointer)
|
||||
|
||||
ULONGLONG StreamSize; // Stream size (can be less than file size)
|
||||
ULONGLONG StreamPos; // Stream position
|
||||
DWORD BuildNumber; // Game build number
|
||||
DWORD dwFlags; // Stream flags
|
||||
|
||||
// Followed by stream provider data, with variable length
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures for block-oriented stream
|
||||
|
||||
struct TBlockStream : public TFileStream
|
||||
{
|
||||
STREAM_DOWNLOAD_CALLBACK pfnCallback; // Callback for downloading
|
||||
void * FileBitmap; // Array of bits for file blocks
|
||||
void * UserData; // User data to be passed to the download callback
|
||||
DWORD BitmapSize; // Size of the file bitmap (in bytes)
|
||||
DWORD BlockSize; // Size of one block, in bytes
|
||||
DWORD BlockCount; // Number of data blocks in the file
|
||||
DWORD IsComplete; // If nonzero, no blocks are missing
|
||||
DWORD IsModified; // nonzero if the bitmap has been modified
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure for encrypted stream
|
||||
|
||||
#define ENCRYPTED_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
|
||||
|
||||
struct TEncryptedStream : public TBlockStream
|
||||
{
|
||||
BYTE Key[ENCRYPTED_CHUNK_SIZE]; // File key
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions for file stream
|
||||
|
||||
TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags);
|
||||
TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags);
|
||||
const TCHAR * FileStream_GetFileName(TFileStream * pStream);
|
||||
size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider);
|
||||
|
||||
bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData);
|
||||
|
||||
bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead);
|
||||
bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite);
|
||||
bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize);
|
||||
bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize);
|
||||
bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset);
|
||||
bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT);
|
||||
bool FileStream_GetFlags(TFileStream * pStream, PDWORD pdwStreamFlags);
|
||||
bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream);
|
||||
void FileStream_Close(TFileStream * pStream);
|
||||
|
||||
|
||||
#endif // __FILESTREAM_H__
|
||||
360
dep/CascLib/src/common/ListFile.cpp
Normal file
360
dep/CascLib/src/common/ListFile.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
/*****************************************************************************/
|
||||
/* ListFile.cpp Copyright (c) Ladislav Zezula 2004 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 12.06.04 1.00 Lad The first version of ListFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Listfile cache structure
|
||||
|
||||
typedef struct _LISTFILE_CACHE
|
||||
{
|
||||
char * pBegin; // The begin of the listfile cache
|
||||
char * pPos; // Current position in the cache
|
||||
char * pEnd; // The last character in the file cache
|
||||
|
||||
// Followed by the cache (variable length)
|
||||
|
||||
} LISTFILE_CACHE, *PLISTFILE_CACHE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creating the listfile cache for the given amount of data
|
||||
|
||||
static PLISTFILE_CACHE CreateListFileCache(DWORD dwFileSize)
|
||||
{
|
||||
PLISTFILE_CACHE pCache;
|
||||
|
||||
// Allocate cache for one file block
|
||||
pCache = (PLISTFILE_CACHE)CASC_ALLOC(BYTE, sizeof(LISTFILE_CACHE) + dwFileSize);
|
||||
if(pCache != NULL)
|
||||
{
|
||||
// Set the initial pointers
|
||||
pCache->pBegin =
|
||||
pCache->pPos = (char *)(pCache + 1);
|
||||
pCache->pEnd = pCache->pBegin + dwFileSize;
|
||||
}
|
||||
|
||||
// Return the cache
|
||||
return pCache;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for parsing an external listfile
|
||||
|
||||
void * ListFile_OpenExternal(const TCHAR * szListFile)
|
||||
{
|
||||
PLISTFILE_CACHE pCache = NULL;
|
||||
TFileStream * pStream;
|
||||
ULONGLONG FileSize = 0;
|
||||
|
||||
// Open the external listfile
|
||||
pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY);
|
||||
if(pStream != NULL)
|
||||
{
|
||||
// Retrieve the size of the external listfile
|
||||
FileStream_GetSize(pStream, &FileSize);
|
||||
if(0 < FileSize && FileSize <= 0x30000000)
|
||||
{
|
||||
// Create the in-memory cache for the entire listfile
|
||||
// The listfile does not have any data loaded yet
|
||||
pCache = CreateListFileCache((DWORD)FileSize);
|
||||
if(pCache != NULL)
|
||||
{
|
||||
if(!FileStream_Read(pStream, NULL, pCache->pBegin, (DWORD)FileSize))
|
||||
{
|
||||
ListFile_Free(pCache);
|
||||
pCache = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close the file stream
|
||||
FileStream_Close(pStream);
|
||||
}
|
||||
|
||||
return pCache;
|
||||
}
|
||||
|
||||
void * ListFile_FromBuffer(LPBYTE pbBuffer, DWORD cbBuffer)
|
||||
{
|
||||
PLISTFILE_CACHE pCache = NULL;
|
||||
|
||||
// Create the in-memory cache for the entire listfile
|
||||
// The listfile does not have any data loaded yet
|
||||
pCache = CreateListFileCache(cbBuffer);
|
||||
if(pCache != NULL)
|
||||
memcpy(pCache->pBegin, pbBuffer, cbBuffer);
|
||||
|
||||
return pCache;
|
||||
}
|
||||
|
||||
// Performs the MD5-based check on the listfile
|
||||
bool ListFile_VerifyMD5(void * pvListFile, LPBYTE pbHashMD5)
|
||||
{
|
||||
PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
|
||||
|
||||
// Must be at the beginning
|
||||
assert(pCache->pPos == pCache->pBegin);
|
||||
|
||||
// Verify the MD5 hash for the entire block
|
||||
return VerifyDataBlockHash(pCache->pBegin, (DWORD)(pCache->pEnd - pCache->pBegin), pbHashMD5);
|
||||
}
|
||||
|
||||
size_t ListFile_GetNextLine(void * pvListFile, const char ** pszLineBegin, const char ** pszLineEnd)
|
||||
{
|
||||
PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
|
||||
char * szExtraString = NULL;
|
||||
char * szLineBegin;
|
||||
char * szLineEnd;
|
||||
|
||||
// Skip newlines, spaces, tabs and another non-printable stuff
|
||||
while(pCache->pPos < pCache->pEnd && pCache->pPos[0] <= 0x20)
|
||||
pCache->pPos++;
|
||||
|
||||
// Remember the begin of the line
|
||||
szLineBegin = pCache->pPos;
|
||||
|
||||
// Copy the remaining characters
|
||||
while(pCache->pPos < pCache->pEnd)
|
||||
{
|
||||
// If we have found a newline, stop loading
|
||||
if(pCache->pPos[0] == 0x0D || pCache->pPos[0] == 0x0A)
|
||||
break;
|
||||
|
||||
// Blizzard listfiles can also contain information about patch:
|
||||
// Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326)
|
||||
if(pCache->pPos[0] == '~')
|
||||
szExtraString = pCache->pPos;
|
||||
|
||||
// Move the position by one character forward
|
||||
pCache->pPos++;
|
||||
}
|
||||
|
||||
// Remember the end of the line
|
||||
szLineEnd = (szExtraString != NULL && szExtraString[0] == '~' && szExtraString[1] == 'P') ? szExtraString : pCache->pPos;
|
||||
|
||||
// Give the caller the positions of the begin and end of the line
|
||||
pszLineBegin[0] = szLineBegin;
|
||||
pszLineEnd[0] = szLineEnd;
|
||||
return (size_t)(szLineEnd - szLineBegin);
|
||||
}
|
||||
|
||||
size_t ListFile_GetNextLine(void * pvListFile, char * szBuffer, size_t nMaxChars)
|
||||
{
|
||||
const char * szLineBegin = NULL;
|
||||
const char * szLineEnd = NULL;
|
||||
size_t nLength;
|
||||
|
||||
// Retrieve the next line
|
||||
nLength = ListFile_GetNextLine(pvListFile, &szLineBegin, &szLineEnd);
|
||||
|
||||
// Check the length
|
||||
if(nLength > nMaxChars)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copy the line to the user buffer
|
||||
memcpy(szBuffer, szLineBegin, nLength);
|
||||
szBuffer[nLength] = 0;
|
||||
return nLength;
|
||||
}
|
||||
|
||||
size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars)
|
||||
{
|
||||
size_t nLength = 0;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check for parameters
|
||||
for(;;)
|
||||
{
|
||||
// Read the (next) line
|
||||
nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars);
|
||||
if(nLength == 0)
|
||||
{
|
||||
nError = ERROR_NO_MORE_FILES;
|
||||
break;
|
||||
}
|
||||
|
||||
// If some mask entered, check it
|
||||
if(CheckWildCard(szBuffer, szMask))
|
||||
{
|
||||
nError = ERROR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
return nLength;
|
||||
}
|
||||
|
||||
void ListFile_Free(void * pvListFile)
|
||||
{
|
||||
if(pvListFile != NULL)
|
||||
{
|
||||
CASC_FREE(pvListFile);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for creating a listfile map
|
||||
|
||||
#define LISTMAP_INITIAL 0x100000
|
||||
|
||||
static PLISTFILE_MAP ListMap_Create()
|
||||
{
|
||||
PLISTFILE_MAP pListMap;
|
||||
size_t cbToAllocate;
|
||||
|
||||
// Create buffer for the listfile
|
||||
// Note that because the listfile is quite big and CASC_REALLOC
|
||||
// is a costly operation, we want to have as few reallocs as possible.
|
||||
cbToAllocate = sizeof(LISTFILE_MAP) + LISTMAP_INITIAL;
|
||||
pListMap = (PLISTFILE_MAP)CASC_ALLOC(BYTE, cbToAllocate);
|
||||
if(pListMap != NULL)
|
||||
{
|
||||
// Fill the listfile buffer
|
||||
memset(pListMap, 0, sizeof(LISTFILE_MAP));
|
||||
pListMap->cbBufferMax = LISTMAP_INITIAL;
|
||||
}
|
||||
|
||||
return pListMap;
|
||||
}
|
||||
|
||||
static PLISTFILE_MAP ListMap_InsertName(PLISTFILE_MAP pListMap, const char * szFileName, size_t nLength)
|
||||
{
|
||||
PLISTFILE_ENTRY pListEntry;
|
||||
size_t cbToAllocate;
|
||||
size_t cbEntrySize;
|
||||
|
||||
// Make sure there is enough space in the list map
|
||||
cbEntrySize = sizeof(LISTFILE_ENTRY) + nLength;
|
||||
cbEntrySize = ALIGN_TO_SIZE(cbEntrySize, 8);
|
||||
if((pListMap->cbBuffer + cbEntrySize) > pListMap->cbBufferMax)
|
||||
{
|
||||
cbToAllocate = sizeof(LISTFILE_MAP) + (pListMap->cbBufferMax * 3) / 2;
|
||||
pListMap = (PLISTFILE_MAP)CASC_REALLOC(BYTE, pListMap, cbToAllocate);
|
||||
if(pListMap == NULL)
|
||||
return NULL;
|
||||
|
||||
pListMap->cbBufferMax = (pListMap->cbBufferMax * 3) / 2;
|
||||
}
|
||||
|
||||
// Get the pointer to the first entry
|
||||
pListEntry = (PLISTFILE_ENTRY)((LPBYTE)(pListMap + 1) + pListMap->cbBuffer);
|
||||
pListEntry->FileNameHash = CalcFileNameHash(szFileName);
|
||||
pListEntry->cbEntrySize = (DWORD)cbEntrySize;
|
||||
|
||||
// Copy the file name to the entry
|
||||
memcpy(pListEntry->szFileName, szFileName, nLength);
|
||||
pListEntry->szFileName[nLength] = 0;
|
||||
|
||||
// Move the next entry
|
||||
pListMap->cbBuffer += cbEntrySize;
|
||||
pListMap->nEntries++;
|
||||
return pListMap;
|
||||
}
|
||||
|
||||
static PLISTFILE_MAP ListMap_Finish(PLISTFILE_MAP pListMap)
|
||||
{
|
||||
PLISTFILE_ENTRY pListEntry;
|
||||
PCASC_MAP pMap;
|
||||
LPBYTE pbEntry;
|
||||
|
||||
// Sanity check
|
||||
assert(pListMap->pNameMap == NULL);
|
||||
|
||||
// Create the map
|
||||
pListMap->pNameMap = pMap = Map_Create((DWORD)pListMap->nEntries, sizeof(ULONGLONG), 0);
|
||||
if(pListMap->pNameMap == NULL)
|
||||
{
|
||||
ListFile_FreeMap(pListMap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fill the map
|
||||
pbEntry = (LPBYTE)(pListMap + 1);
|
||||
for(size_t i = 0; i < pListMap->nEntries; i++)
|
||||
{
|
||||
// Get the listfile entry
|
||||
pListEntry = (PLISTFILE_ENTRY)pbEntry;
|
||||
pbEntry += pListEntry->cbEntrySize;
|
||||
|
||||
// Insert the entry to the map
|
||||
Map_InsertObject(pMap, pListEntry, &pListEntry->FileNameHash);
|
||||
}
|
||||
|
||||
return pListMap;
|
||||
}
|
||||
|
||||
PLISTFILE_MAP ListFile_CreateMap(const TCHAR * szListFile)
|
||||
{
|
||||
PLISTFILE_MAP pListMap = NULL;
|
||||
void * pvListFile;
|
||||
char szFileName[MAX_PATH+1];
|
||||
size_t nLength;
|
||||
|
||||
// Only if the listfile name has been given
|
||||
if(szListFile != NULL)
|
||||
{
|
||||
// Create map for the listfile
|
||||
pListMap = ListMap_Create();
|
||||
if(pListMap != NULL)
|
||||
{
|
||||
// Open the external listfile
|
||||
pvListFile = ListFile_OpenExternal(szListFile);
|
||||
if(pvListFile != NULL)
|
||||
{
|
||||
// Go through the entire listfile and insert each name to the map
|
||||
while((nLength = ListFile_GetNext(pvListFile, "*", szFileName, MAX_PATH)) != 0)
|
||||
{
|
||||
// Insert the file name to the map
|
||||
pListMap = ListMap_InsertName(pListMap, szFileName, nLength);
|
||||
if(pListMap == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if(pListMap == NULL)
|
||||
{
|
||||
// Finish the listfile map
|
||||
pListMap = ListMap_Finish(pListMap);
|
||||
}
|
||||
|
||||
// Free the listfile
|
||||
ListFile_Free(pvListFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the created map
|
||||
return pListMap;
|
||||
}
|
||||
|
||||
const char * ListFile_FindName(PLISTFILE_MAP pListMap, ULONGLONG FileNameHash)
|
||||
{
|
||||
PLISTFILE_ENTRY pListEntry = NULL;
|
||||
|
||||
if(pListMap != NULL)
|
||||
pListEntry = (PLISTFILE_ENTRY)Map_FindObject(pListMap->pNameMap, &FileNameHash, NULL);
|
||||
return (pListEntry != NULL) ? pListEntry->szFileName : "";
|
||||
}
|
||||
|
||||
void ListFile_FreeMap(PLISTFILE_MAP pListMap)
|
||||
{
|
||||
if(pListMap != NULL)
|
||||
{
|
||||
if(pListMap->pNameMap != NULL)
|
||||
Map_Free(pListMap->pNameMap);
|
||||
CASC_FREE(pListMap);
|
||||
}
|
||||
}
|
||||
54
dep/CascLib/src/common/ListFile.h
Normal file
54
dep/CascLib/src/common/ListFile.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*****************************************************************************/
|
||||
/* ListFile.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 10.05.14 1.00 Lad The first version of ListFile.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __LISTFILE_H__
|
||||
#define __LISTFILE_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures
|
||||
|
||||
typedef struct _LISTFILE_ENTRY
|
||||
{
|
||||
ULONGLONG FileNameHash; // Hash of the file name
|
||||
DWORD cbEntrySize; // Length of this entry, in bytes
|
||||
char szFileName[1]; // File name, aligned to 8-byte boundary
|
||||
|
||||
} LISTFILE_ENTRY, *PLISTFILE_ENTRY;
|
||||
|
||||
typedef struct _LISTFILE_MAP
|
||||
{
|
||||
PCASC_MAP pNameMap; // Map of hash-to-name
|
||||
size_t cbBufferMax; // Total size of the buffer, in bytes
|
||||
size_t cbBuffer; // Current size of the buffer, in bytes
|
||||
size_t nEntries; // Number of entries
|
||||
|
||||
// First LISTFILE_ENTRY starts here
|
||||
|
||||
} LISTFILE_MAP, *PLISTFILE_MAP;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for parsing an external listfile
|
||||
|
||||
void * ListFile_OpenExternal(const TCHAR * szListFile);
|
||||
void * ListFile_FromBuffer(LPBYTE pbBuffer, DWORD cbBuffer);
|
||||
bool ListFile_VerifyMD5(void * pvListFile, LPBYTE pbHashMD5);
|
||||
size_t ListFile_GetNextLine(void * pvListFile, const char ** pszLineBegin, const char ** pszLineEnd);
|
||||
size_t ListFile_GetNextLine(void * pvListFile, char * szBuffer, size_t nMaxChars);
|
||||
size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars);
|
||||
void ListFile_Free(void * pvListFile);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions for creating a listfile map
|
||||
|
||||
PLISTFILE_MAP ListFile_CreateMap(const TCHAR * szListFile);
|
||||
const char * ListFile_FindName(PLISTFILE_MAP pListMap, ULONGLONG FileNameHash);
|
||||
void ListFile_FreeMap(PLISTFILE_MAP pListMap);
|
||||
|
||||
#endif // __LISTFILE_H__
|
||||
287
dep/CascLib/src/common/Map.cpp
Normal file
287
dep/CascLib/src/common/Map.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/*****************************************************************************/
|
||||
/* Map.cpp Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Implementation of map for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 10.06.14 1.00 Lad The first version of Map.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
// Returns the extension, right after "."
|
||||
static const char * String_GetExtension(const char * szString)
|
||||
{
|
||||
const char * szExtension = strrchr(szString, '.');
|
||||
return (szExtension != NULL) ? szExtension + 1 : NULL;
|
||||
}
|
||||
|
||||
static DWORD CalcHashIndex_Key(PCASC_MAP pMap, void * pvKey)
|
||||
{
|
||||
LPBYTE pbKey = (LPBYTE)pvKey;
|
||||
DWORD dwHash = 0x7EEE7EEE;
|
||||
|
||||
// Construct the hash from the first 8 digits
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[0];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[1];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[2];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[3];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[4];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[5];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[6];
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbKey[7];
|
||||
|
||||
// Return the hash limited by the table size
|
||||
return (dwHash % pMap->TableSize);
|
||||
}
|
||||
|
||||
static DWORD CalcHashIndex_String(PCASC_MAP pMap, const char * szString, const char * szStringEnd)
|
||||
{
|
||||
LPBYTE pbKeyEnd = (LPBYTE)szStringEnd;
|
||||
LPBYTE pbKey = (LPBYTE)szString;
|
||||
DWORD dwHash = 0x7EEE7EEE;
|
||||
|
||||
// Hash the string itself
|
||||
while(pbKey < pbKeyEnd)
|
||||
{
|
||||
dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ AsciiToUpperTable_BkSlash[pbKey[0]];
|
||||
pbKey++;
|
||||
}
|
||||
|
||||
// Return the hash limited by the table size
|
||||
return (dwHash % pMap->TableSize);
|
||||
}
|
||||
|
||||
static bool CompareObject_Key(PCASC_MAP pMap, void * pvObject, void * pvKey)
|
||||
{
|
||||
LPBYTE pbObjectKey = (LPBYTE)pvObject + pMap->KeyOffset;
|
||||
|
||||
return (memcmp(pbObjectKey, pvKey, pMap->KeyLength) == 0);
|
||||
}
|
||||
|
||||
static bool CompareObject_String(
|
||||
PCASC_MAP pMap,
|
||||
const char * szExistingString,
|
||||
const char * szString,
|
||||
const char * szStringEnd)
|
||||
{
|
||||
// Keep compiler happy
|
||||
CASCLIB_UNUSED(pMap);
|
||||
|
||||
// Compare the whole part, case insensitive
|
||||
while(szString < szStringEnd)
|
||||
{
|
||||
if(AsciiToUpperTable_BkSlash[*szExistingString] != AsciiToUpperTable_BkSlash[*szString])
|
||||
return false;
|
||||
|
||||
szExistingString++;
|
||||
szString++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
PCASC_MAP Map_Create(DWORD dwMaxItems, DWORD dwKeyLength, DWORD dwKeyOffset)
|
||||
{
|
||||
PCASC_MAP pMap;
|
||||
size_t cbToAllocate;
|
||||
size_t dwTableSize;
|
||||
|
||||
// Calculate the size of the table
|
||||
dwTableSize = (dwMaxItems * 3 / 2) | 0x01;
|
||||
|
||||
// Allocate new map for the objects
|
||||
cbToAllocate = sizeof(CASC_MAP) + (dwTableSize * sizeof(void *));
|
||||
pMap = (PCASC_MAP)CASC_ALLOC(LPBYTE, cbToAllocate);
|
||||
if(pMap != NULL)
|
||||
{
|
||||
memset(pMap, 0, cbToAllocate);
|
||||
pMap->KeyLength = dwKeyLength;
|
||||
pMap->TableSize = dwTableSize;
|
||||
pMap->KeyOffset = dwKeyOffset;
|
||||
}
|
||||
|
||||
// Return the allocated map
|
||||
return pMap;
|
||||
}
|
||||
|
||||
size_t Map_EnumObjects(PCASC_MAP pMap, void **ppvArray)
|
||||
{
|
||||
size_t nIndex = 0;
|
||||
|
||||
// Verify pointer to the map
|
||||
if(pMap != NULL && ppvArray != NULL)
|
||||
{
|
||||
// Enumerate all items in main table
|
||||
for(size_t i = 0; i < pMap->TableSize; i++)
|
||||
{
|
||||
// Is that cell valid?
|
||||
if(pMap->HashTable[i] != NULL)
|
||||
{
|
||||
ppvArray[nIndex++] = pMap->HashTable[i];
|
||||
}
|
||||
}
|
||||
|
||||
return pMap->ItemCount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * Map_FindObject(PCASC_MAP pMap, void * pvKey, PDWORD PtrIndex)
|
||||
{
|
||||
void * pvObject;
|
||||
DWORD dwHashIndex;
|
||||
|
||||
// Verify pointer to the map
|
||||
if(pMap != NULL)
|
||||
{
|
||||
// Construct the main index
|
||||
dwHashIndex = CalcHashIndex_Key(pMap, pvKey);
|
||||
while(pMap->HashTable[dwHashIndex] != NULL)
|
||||
{
|
||||
// Get the pointer at that position
|
||||
pvObject = pMap->HashTable[dwHashIndex];
|
||||
|
||||
// Compare the hash
|
||||
if(CompareObject_Key(pMap, pvObject, pvKey))
|
||||
{
|
||||
if(PtrIndex != NULL)
|
||||
PtrIndex[0] = dwHashIndex;
|
||||
return pvObject;
|
||||
}
|
||||
|
||||
// Move to the next entry
|
||||
dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found, sorry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Map_InsertObject(PCASC_MAP pMap, void * pvNewObject, void * pvKey)
|
||||
{
|
||||
void * pvExistingObject;
|
||||
DWORD dwHashIndex;
|
||||
|
||||
// Verify pointer to the map
|
||||
if(pMap != NULL)
|
||||
{
|
||||
// Limit check
|
||||
if((pMap->ItemCount + 1) >= pMap->TableSize)
|
||||
return false;
|
||||
|
||||
// Construct the hash index
|
||||
dwHashIndex = CalcHashIndex_Key(pMap, pvKey);
|
||||
while(pMap->HashTable[dwHashIndex] != NULL)
|
||||
{
|
||||
// Get the pointer at that position
|
||||
pvExistingObject = pMap->HashTable[dwHashIndex];
|
||||
|
||||
// Check if hash being inserted conflicts with an existing hash
|
||||
if(CompareObject_Key(pMap, pvExistingObject, pvKey))
|
||||
return false;
|
||||
|
||||
// Move to the next entry
|
||||
dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
|
||||
}
|
||||
|
||||
// Insert at that position
|
||||
pMap->HashTable[dwHashIndex] = pvNewObject;
|
||||
pMap->ItemCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map_InsertString(PCASC_MAP pMap, const char * szString, bool bCutExtension)
|
||||
{
|
||||
const char * szExistingString;
|
||||
const char * szStringEnd = NULL;
|
||||
DWORD dwHashIndex;
|
||||
|
||||
// Verify pointer to the map
|
||||
if(pMap != NULL)
|
||||
{
|
||||
// Limit check
|
||||
if((pMap->ItemCount + 1) >= pMap->TableSize)
|
||||
return false;
|
||||
|
||||
// Retrieve the length of the string without extension
|
||||
if(bCutExtension)
|
||||
szStringEnd = String_GetExtension(szString);
|
||||
if(szStringEnd == NULL)
|
||||
szStringEnd = szString + strlen(szString);
|
||||
|
||||
// Construct the hash index
|
||||
dwHashIndex = CalcHashIndex_String(pMap, szString, szStringEnd);
|
||||
while(pMap->HashTable[dwHashIndex] != NULL)
|
||||
{
|
||||
// Get the pointer at that position
|
||||
szExistingString = (const char *)pMap->HashTable[dwHashIndex];
|
||||
|
||||
// Check if hash being inserted conflicts with an existing hash
|
||||
if(CompareObject_String(pMap, szExistingString, szString, szStringEnd))
|
||||
return false;
|
||||
|
||||
// Move to the next entry
|
||||
dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
|
||||
}
|
||||
|
||||
// Insert at that position
|
||||
pMap->HashTable[dwHashIndex] = (void *)szString;
|
||||
pMap->ItemCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * Map_FindString(PCASC_MAP pMap, const char * szString, const char * szStringEnd)
|
||||
{
|
||||
const char * szExistingString;
|
||||
DWORD dwHashIndex;
|
||||
|
||||
// Verify pointer to the map
|
||||
if(pMap != NULL)
|
||||
{
|
||||
// Construct the main index
|
||||
dwHashIndex = CalcHashIndex_String(pMap, szString, szStringEnd);
|
||||
while(pMap->HashTable[dwHashIndex] != NULL)
|
||||
{
|
||||
// Get the pointer at that position
|
||||
szExistingString = (const char *)pMap->HashTable[dwHashIndex];
|
||||
|
||||
// Compare the hash
|
||||
if(CompareObject_String(pMap, szExistingString, szString, szStringEnd))
|
||||
return szExistingString;
|
||||
|
||||
// Move to the next entry
|
||||
dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found, sorry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Map_Free(PCASC_MAP pMap)
|
||||
{
|
||||
if(pMap != NULL)
|
||||
{
|
||||
CASC_FREE(pMap);
|
||||
}
|
||||
}
|
||||
42
dep/CascLib/src/common/Map.h
Normal file
42
dep/CascLib/src/common/Map.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************/
|
||||
/* Map.h Copyright (c) Ladislav Zezula 2014 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Interface of hash-to-ptr map for CascLib */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 10.06.14 1.00 Lad The first version of Map.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __HASHTOPTR_H__
|
||||
#define __HASHTOPTR_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures
|
||||
|
||||
#define KEY_LENGTH_STRING 0xFFFFFFFF // Pass this to Map_Create as dwKeyLength when you want map of string->object
|
||||
|
||||
typedef struct _CASC_MAP
|
||||
{
|
||||
size_t TableSize;
|
||||
size_t ItemCount; // Number of items in the map
|
||||
size_t KeyOffset; // How far is the hash from the begin of the structure (in bytes)
|
||||
size_t KeyLength; // Length of the hash key
|
||||
void * HashTable[1]; // Pointer table
|
||||
|
||||
} CASC_MAP, *PCASC_MAP;
|
||||
|
||||
typedef bool (*MAP_COMPARE)(PCASC_MAP pMap, void * pvObject, void * pvKey);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
PCASC_MAP Map_Create(DWORD dwMaxItems, DWORD dwKeyLength, DWORD dwKeyOffset);
|
||||
size_t Map_EnumObjects(PCASC_MAP pMap, void **ppvArray);
|
||||
void * Map_FindObject(PCASC_MAP pMap, void * pvKey, PDWORD PtrIndex);
|
||||
bool Map_InsertObject(PCASC_MAP pMap, void * pvNewObject, void * pvKey);
|
||||
const char * Map_FindString(PCASC_MAP pMap, const char * szString, const char * szStringEnd);
|
||||
bool Map_InsertString(PCASC_MAP pMap, const char * szString, bool bCutExtension);
|
||||
void Map_Free(PCASC_MAP pMap);
|
||||
|
||||
#endif // __HASHTOPTR_H__
|
||||
88
dep/CascLib/src/common/RootHandler.cpp
Normal file
88
dep/CascLib/src/common/RootHandler.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*****************************************************************************/
|
||||
/* RootHandler.cpp Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Implementation of root handler */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 09.03.15 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __CASCLIB_SELF__
|
||||
#include "../CascLib.h"
|
||||
#include "../CascCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common support
|
||||
|
||||
int RootHandler_Insert(TRootHandler * pRootHandler, const char * szFileName, LPBYTE pbEncodingKey)
|
||||
{
|
||||
if(pRootHandler == NULL || pRootHandler->Insert == NULL || pbEncodingKey == NULL)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
return pRootHandler->Insert(pRootHandler, szFileName, pbEncodingKey);
|
||||
}
|
||||
|
||||
LPBYTE RootHandler_Search(TRootHandler * pRootHandler, struct _TCascSearch * pSearch, PDWORD PtrFileSize, PDWORD PtrLocaleFlags, PDWORD PtrFileDataId)
|
||||
{
|
||||
// Check if the root structure is valid at all
|
||||
if(pRootHandler == NULL)
|
||||
return NULL;
|
||||
|
||||
return pRootHandler->Search(pRootHandler, pSearch, PtrFileSize, PtrLocaleFlags, PtrFileDataId);
|
||||
}
|
||||
|
||||
void RootHandler_EndSearch(TRootHandler * pRootHandler, struct _TCascSearch * pSearch)
|
||||
{
|
||||
// Check if the root structure is valid at all
|
||||
if(pRootHandler != NULL)
|
||||
{
|
||||
pRootHandler->EndSearch(pRootHandler, pSearch);
|
||||
}
|
||||
}
|
||||
|
||||
LPBYTE RootHandler_GetKey(TRootHandler * pRootHandler, const char * szFileName)
|
||||
{
|
||||
// Check if the root structure is valid at all
|
||||
if(pRootHandler == NULL)
|
||||
return NULL;
|
||||
|
||||
return pRootHandler->GetKey(pRootHandler, szFileName);
|
||||
}
|
||||
|
||||
void RootHandler_Dump(TCascStorage * hs, LPBYTE pbRootHandler, DWORD cbRootHandler, const TCHAR * szNameFormat, const TCHAR * szListFile, int nDumpLevel)
|
||||
{
|
||||
TDumpContext * dc;
|
||||
|
||||
// Only if the ROOT provider suports the dump option
|
||||
if(hs->pRootHandler != NULL && hs->pRootHandler->Dump != NULL)
|
||||
{
|
||||
// Create the dump file
|
||||
dc = CreateDumpContext(hs, szNameFormat);
|
||||
if(dc != NULL)
|
||||
{
|
||||
// Dump the content and close the file
|
||||
hs->pRootHandler->Dump(hs, dc, pbRootHandler, cbRootHandler, szListFile, nDumpLevel);
|
||||
dump_close(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RootHandler_Close(TRootHandler * pRootHandler)
|
||||
{
|
||||
// Check if the root structure is allocated at all
|
||||
if(pRootHandler != NULL)
|
||||
{
|
||||
pRootHandler->Close(pRootHandler);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD RootHandler_GetFileId(TRootHandler * pRootHandler, const char * szFileName)
|
||||
{
|
||||
// Check if the root structure is valid at all
|
||||
if(pRootHandler == NULL)
|
||||
return 0;
|
||||
|
||||
return pRootHandler->GetFileId(pRootHandler, szFileName);
|
||||
}
|
||||
|
||||
96
dep/CascLib/src/common/RootHandler.h
Normal file
96
dep/CascLib/src/common/RootHandler.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*****************************************************************************/
|
||||
/* RootHandler.h Copyright (c) Ladislav Zezula 2015 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Interface for root handlers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 09.03.15 1.00 Lad Created */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __ROOT_HANDLER_H__
|
||||
#define __ROOT_HANDLER_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define CASC_MNDX_ROOT_SIGNATURE 0x58444E4D // 'MNDX'
|
||||
#define CASC_DIABLO3_ROOT_SIGNATURE 0x8007D0C4
|
||||
#define CASC_OVERWATCH_ROOT_SIGNATURE 0x35444D23 // '#MD5'
|
||||
|
||||
#define ROOT_FLAG_HAS_NAMES 0x00000001 // The root file contains file names
|
||||
|
||||
#define DUMP_LEVEL_ROOT_FILE 1 // Dump root file
|
||||
#define DUMP_LEVEL_ENCODING_FILE 2 // Dump root file + encoding file
|
||||
#define DUMP_LEVEL_INDEX_ENTRIES 3 // Dump root file + encoding file + index entries
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Root file function prototypes
|
||||
|
||||
typedef int (*ROOT_INSERT)(
|
||||
struct TRootHandler * pRootHandler, // Pointer to an initialized root handler
|
||||
const char * szFileName, // Pointer to the file name
|
||||
LPBYTE pbEncodingKey // Pointer to the encoding key of the file name
|
||||
);
|
||||
|
||||
typedef LPBYTE (*ROOT_SEARCH)(
|
||||
struct TRootHandler * pRootHandler, // Pointer to an initialized root handler
|
||||
struct _TCascSearch * pSearch, // Pointer to the initialized search structure
|
||||
PDWORD PtrFileSize, // Pointer to receive file size (optional)
|
||||
PDWORD PtrLocaleFlags, // Pointer to receive locale flags (optional)
|
||||
PDWORD PtrFileDataId // Pointer to FileDataID (optional)
|
||||
);
|
||||
|
||||
typedef void (*ROOT_ENDSEARCH)(
|
||||
struct TRootHandler * pRootHandler, // Pointer to an initialized root handler
|
||||
struct _TCascSearch * pSearch // Pointer to the initialized search structure
|
||||
);
|
||||
|
||||
typedef LPBYTE (*ROOT_GETKEY)(
|
||||
struct TRootHandler * pRootHandler, // Pointer to an initialized root handler
|
||||
const char * szFileName // Pointer to the name of a file
|
||||
);
|
||||
|
||||
typedef void (*ROOT_DUMP)(
|
||||
struct _TCascStorage * hs, // Pointer to the open storage
|
||||
TDumpContext * dc, // Opened dump context
|
||||
LPBYTE pbRootHandler, // Pointer to the loaded ROOT file
|
||||
DWORD cbRootHandler, // Length of the loaded ROOT file
|
||||
const TCHAR * szListFile,
|
||||
int nDumpLevel
|
||||
);
|
||||
|
||||
typedef void (*ROOT_CLOSE)(
|
||||
struct TRootHandler * pRootHandler // Pointer to an initialized root handler
|
||||
);
|
||||
|
||||
typedef DWORD(*ROOT_GETFILEID)(
|
||||
struct TRootHandler * pRootHandler, // Pointer to an initialized root handler
|
||||
const char * szFileName // Pointer to the name of a file
|
||||
);
|
||||
|
||||
struct TRootHandler
|
||||
{
|
||||
ROOT_INSERT Insert; // Inserts an existing file name
|
||||
ROOT_SEARCH Search; // Performs the root file search
|
||||
ROOT_ENDSEARCH EndSearch; // Performs cleanup after searching
|
||||
ROOT_GETKEY GetKey; // Retrieves encoding key for a file name
|
||||
ROOT_DUMP Dump;
|
||||
ROOT_CLOSE Close; // Closing the root file
|
||||
ROOT_GETFILEID GetFileId; // Returns File Id for a given Filename
|
||||
|
||||
DWORD dwRootFlags; // Root flags - see the ROOT_FLAG_XXX
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int RootHandler_Insert(TRootHandler * pRootHandler, const char * szFileName, LPBYTE pbEncodingKey);
|
||||
LPBYTE RootHandler_Search(TRootHandler * pRootHandler, struct _TCascSearch * pSearch, PDWORD PtrFileSize, PDWORD PtrLocaleFlags, PDWORD PtrFileDataId);
|
||||
void RootHandler_EndSearch(TRootHandler * pRootHandler, struct _TCascSearch * pSearch);
|
||||
LPBYTE RootHandler_GetKey(TRootHandler * pRootHandler, const char * szFileName);
|
||||
void RootHandler_Dump(struct _TCascStorage * hs, LPBYTE pbRootHandler, DWORD cbRootHandler, const TCHAR * szNameFormat, const TCHAR * szListFile, int nDumpLevel);
|
||||
void RootHandler_Close(TRootHandler * pRootHandler);
|
||||
DWORD RootHandler_GetFileId(TRootHandler * pRootHandler, const char * szFileName);
|
||||
|
||||
#endif // __ROOT_HANDLER_H__
|
||||
24
dep/CascLib/src/jenkins/lookup.h
Normal file
24
dep/CascLib/src/jenkins/lookup.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __LOOKUP3_H__
|
||||
#define __LOOKUP3_H__
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#include <stdint.h> /* defines uint32_t etc */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
uint32_t hashlittle(const void *key, size_t length, uint32_t initval);
|
||||
void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LOOKUP3_H__
|
||||
1003
dep/CascLib/src/jenkins/lookup3.c
Normal file
1003
dep/CascLib/src/jenkins/lookup3.c
Normal file
File diff suppressed because it is too large
Load Diff
69
dep/CascLib/src/libtomcrypt/src/hashes/hash_memory.c
Normal file
69
dep/CascLib/src/libtomcrypt/src/hashes/hash_memory.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file hash_memory.c
|
||||
Hash memory helper, Tom St Denis
|
||||
*/
|
||||
|
||||
/**
|
||||
Hash a block of memory and store the digest.
|
||||
@param hash The index of the hash you wish to use
|
||||
@param in The data you wish to hash
|
||||
@param inlen The length of the data to hash (octets)
|
||||
@param out [out] Where to store the digest
|
||||
@param outlen [in/out] Max size and resulting size of the digest
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
hash_state *md;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (*outlen < hash_descriptor[hash].hashsize) {
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
md = XMALLOC(sizeof(hash_state));
|
||||
if (md == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
err = hash_descriptor[hash].done(md, out);
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
XFREE(md);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */
|
||||
/* $Revision: 1.6 $ */
|
||||
/* $Date: 2006/12/28 01:27:23 $ */
|
||||
368
dep/CascLib/src/libtomcrypt/src/hashes/md5.c
Normal file
368
dep/CascLib/src/libtomcrypt/src/hashes/md5.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
|
||||
/**
|
||||
@file md5.c
|
||||
LTC_MD5 hash function by Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MD5
|
||||
|
||||
const struct ltc_hash_descriptor md5_desc =
|
||||
{
|
||||
"md5",
|
||||
3,
|
||||
16,
|
||||
64,
|
||||
|
||||
/* OID */
|
||||
{ 1, 2, 840, 113549, 2, 5, },
|
||||
6,
|
||||
|
||||
&md5_init,
|
||||
&md5_process,
|
||||
&md5_done,
|
||||
&md5_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define G(x,y,z) (y ^ (z & (y ^ x)))
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y^(x|(~z)))
|
||||
|
||||
#ifdef LTC_SMALL_CODE
|
||||
|
||||
#define FF(a,b,c,d,M,s,t) \
|
||||
a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define GG(a,b,c,d,M,s,t) \
|
||||
a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define HH(a,b,c,d,M,s,t) \
|
||||
a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define II(a,b,c,d,M,s,t) \
|
||||
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
static const unsigned char Worder[64] = {
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||||
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
|
||||
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
|
||||
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
|
||||
};
|
||||
|
||||
static const unsigned char Rorder[64] = {
|
||||
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
|
||||
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
|
||||
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
|
||||
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
|
||||
};
|
||||
|
||||
static const ulong32 Korder[64] = {
|
||||
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
|
||||
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
|
||||
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
|
||||
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
|
||||
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
|
||||
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
|
||||
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
|
||||
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define FF(a,b,c,d,M,s,t) \
|
||||
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define GG(a,b,c,d,M,s,t) \
|
||||
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define HH(a,b,c,d,M,s,t) \
|
||||
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define II(a,b,c,d,M,s,t) \
|
||||
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int _md5_compress(hash_state *md, unsigned char *buf)
|
||||
#else
|
||||
static int md5_compress(hash_state *md, unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
ulong32 i, W[16], a, b, c, d;
|
||||
#ifdef LTC_SMALL_CODE
|
||||
ulong32 t;
|
||||
#endif
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(W[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = md->md5.state[0];
|
||||
b = md->md5.state[1];
|
||||
c = md->md5.state[2];
|
||||
d = md->md5.state[3];
|
||||
|
||||
#ifdef LTC_SMALL_CODE
|
||||
for (i = 0; i < 16; ++i) {
|
||||
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
|
||||
t = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 32; ++i) {
|
||||
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
|
||||
t = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 48; ++i) {
|
||||
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
|
||||
t = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 64; ++i) {
|
||||
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
|
||||
t = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
#else
|
||||
FF(a,b,c,d,W[0],7,0xd76aa478UL)
|
||||
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
|
||||
FF(c,d,a,b,W[2],17,0x242070dbUL)
|
||||
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
|
||||
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
|
||||
FF(d,a,b,c,W[5],12,0x4787c62aUL)
|
||||
FF(c,d,a,b,W[6],17,0xa8304613UL)
|
||||
FF(b,c,d,a,W[7],22,0xfd469501UL)
|
||||
FF(a,b,c,d,W[8],7,0x698098d8UL)
|
||||
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
|
||||
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
|
||||
FF(b,c,d,a,W[11],22,0x895cd7beUL)
|
||||
FF(a,b,c,d,W[12],7,0x6b901122UL)
|
||||
FF(d,a,b,c,W[13],12,0xfd987193UL)
|
||||
FF(c,d,a,b,W[14],17,0xa679438eUL)
|
||||
FF(b,c,d,a,W[15],22,0x49b40821UL)
|
||||
GG(a,b,c,d,W[1],5,0xf61e2562UL)
|
||||
GG(d,a,b,c,W[6],9,0xc040b340UL)
|
||||
GG(c,d,a,b,W[11],14,0x265e5a51UL)
|
||||
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
|
||||
GG(a,b,c,d,W[5],5,0xd62f105dUL)
|
||||
GG(d,a,b,c,W[10],9,0x02441453UL)
|
||||
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
|
||||
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
|
||||
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
|
||||
GG(d,a,b,c,W[14],9,0xc33707d6UL)
|
||||
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
|
||||
GG(b,c,d,a,W[8],20,0x455a14edUL)
|
||||
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
|
||||
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
|
||||
GG(c,d,a,b,W[7],14,0x676f02d9UL)
|
||||
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
|
||||
HH(a,b,c,d,W[5],4,0xfffa3942UL)
|
||||
HH(d,a,b,c,W[8],11,0x8771f681UL)
|
||||
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
|
||||
HH(b,c,d,a,W[14],23,0xfde5380cUL)
|
||||
HH(a,b,c,d,W[1],4,0xa4beea44UL)
|
||||
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
|
||||
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
|
||||
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
|
||||
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
|
||||
HH(d,a,b,c,W[0],11,0xeaa127faUL)
|
||||
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
|
||||
HH(b,c,d,a,W[6],23,0x04881d05UL)
|
||||
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
|
||||
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
|
||||
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
|
||||
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
|
||||
II(a,b,c,d,W[0],6,0xf4292244UL)
|
||||
II(d,a,b,c,W[7],10,0x432aff97UL)
|
||||
II(c,d,a,b,W[14],15,0xab9423a7UL)
|
||||
II(b,c,d,a,W[5],21,0xfc93a039UL)
|
||||
II(a,b,c,d,W[12],6,0x655b59c3UL)
|
||||
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
|
||||
II(c,d,a,b,W[10],15,0xffeff47dUL)
|
||||
II(b,c,d,a,W[1],21,0x85845dd1UL)
|
||||
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
|
||||
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
|
||||
II(c,d,a,b,W[6],15,0xa3014314UL)
|
||||
II(b,c,d,a,W[13],21,0x4e0811a1UL)
|
||||
II(a,b,c,d,W[4],6,0xf7537e82UL)
|
||||
II(d,a,b,c,W[11],10,0xbd3af235UL)
|
||||
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
|
||||
II(b,c,d,a,W[9],21,0xeb86d391UL)
|
||||
#endif
|
||||
|
||||
md->md5.state[0] = md->md5.state[0] + a;
|
||||
md->md5.state[1] = md->md5.state[1] + b;
|
||||
md->md5.state[2] = md->md5.state[2] + c;
|
||||
md->md5.state[3] = md->md5.state[3] + d;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int md5_compress(hash_state *md, unsigned char *buf)
|
||||
{
|
||||
int err;
|
||||
err = _md5_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 21);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int md5_init(hash_state * md)
|
||||
{
|
||||
LTC_ARGCHK(md != NULL);
|
||||
md->md5.state[0] = 0x67452301UL;
|
||||
md->md5.state[1] = 0xefcdab89UL;
|
||||
md->md5.state[2] = 0x98badcfeUL;
|
||||
md->md5.state[3] = 0x10325476UL;
|
||||
md->md5.curlen = 0;
|
||||
md->md5.length = 0;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
HASH_PROCESS(md5_process, md5_compress, md5, 64)
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (16 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int md5_done(hash_state * md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
LTC_ARGCHK(md != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
if (md->md5.curlen >= sizeof(md->md5.buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
/* increase the length of the message */
|
||||
md->md5.length += md->md5.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->md5.curlen > 56) {
|
||||
while (md->md5.curlen < 64) {
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
|
||||
}
|
||||
md5_compress(md, md->md5.buf);
|
||||
md->md5.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->md5.curlen < 56) {
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->md5.length, md->md5.buf+56);
|
||||
md5_compress(md, md->md5.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md->md5.state[i], out+(4*i));
|
||||
}
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Self-test the hash
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int md5_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
char *msg;
|
||||
unsigned char hash[16];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
||||
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
|
||||
{ "a",
|
||||
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
||||
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
|
||||
{ "abc",
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
||||
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
|
||||
{ "message digest",
|
||||
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
||||
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
||||
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
||||
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
||||
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
|
||||
{ NULL, { 0 } }
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char tmp[16];
|
||||
hash_state md;
|
||||
|
||||
for (i = 0; tests[i].msg != NULL; i++) {
|
||||
md5_init(&md);
|
||||
md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
|
||||
md5_done(&md, tmp);
|
||||
if (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */
|
||||
/* $Revision: 1.10 $ */
|
||||
/* $Date: 2007/05/12 14:25:28 $ */
|
||||
87
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt.h
Normal file
87
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef TOMCRYPT_H_
|
||||
#define TOMCRYPT_H_
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* use configuration data */
|
||||
#include "tomcrypt_custom.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0117
|
||||
#define SCRYPT "1.17"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
||||
/* descriptor table size */
|
||||
#define TAB_SIZE 32
|
||||
|
||||
/* error codes [will be expanded in future releases] */
|
||||
enum {
|
||||
CRYPT_OK=0, /* Result OK */
|
||||
CRYPT_ERROR, /* Generic Error */
|
||||
CRYPT_NOP, /* Not a failure but no operation was performed */
|
||||
|
||||
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
|
||||
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
|
||||
CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
|
||||
|
||||
CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
|
||||
CRYPT_INVALID_PACKET, /* Invalid input packet given */
|
||||
|
||||
CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
|
||||
CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
|
||||
|
||||
CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
|
||||
CRYPT_INVALID_HASH, /* Invalid hash specified */
|
||||
CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
|
||||
|
||||
CRYPT_MEM, /* Out of memory */
|
||||
|
||||
CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
|
||||
CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
|
||||
|
||||
CRYPT_INVALID_ARG, /* Generic invalid argument */
|
||||
CRYPT_FILE_NOTFOUND, /* File Not Found */
|
||||
|
||||
CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
|
||||
CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
|
||||
CRYPT_PK_DUP, /* Duplicate key already in key ring */
|
||||
CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
|
||||
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
|
||||
|
||||
CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
|
||||
CRYPT_PK_INVALID_PADDING /* Invalid padding on input */
|
||||
};
|
||||
|
||||
#include "tomcrypt_cfg.h"
|
||||
#include "tomcrypt_macros.h"
|
||||
#include "tomcrypt_cipher.h"
|
||||
#include "tomcrypt_hash.h"
|
||||
#include "tomcrypt_mac.h"
|
||||
#include "tomcrypt_prng.h"
|
||||
#include "tomcrypt_pk.h"
|
||||
#include "tomcrypt_math.h"
|
||||
#include "tomcrypt_misc.h"
|
||||
#include "tomcrypt_argchk.h"
|
||||
#include "tomcrypt_pkcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TOMCRYPT_H_ */
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */
|
||||
/* $Revision: 1.21 $ */
|
||||
/* $Date: 2006/12/16 19:34:05 $ */
|
||||
38
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h
Normal file
38
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Defines the LTC_ARGCHK macro used within the library */
|
||||
/* ARGTYPE is defined in mycrypt_cfg.h */
|
||||
#if ARGTYPE == 0
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/* this is the default LibTomCrypt macro */
|
||||
void crypt_argchk(char *v, char *s, int d);
|
||||
#define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
|
||||
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
|
||||
|
||||
#elif ARGTYPE == 1
|
||||
|
||||
/* fatal type of error */
|
||||
#define LTC_ARGCHK(x) assert((x))
|
||||
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
|
||||
|
||||
#elif ARGTYPE == 2
|
||||
|
||||
#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); }
|
||||
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
|
||||
|
||||
#elif ARGTYPE == 3
|
||||
|
||||
#define LTC_ARGCHK(x)
|
||||
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
|
||||
|
||||
#elif ARGTYPE == 4
|
||||
|
||||
#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG;
|
||||
#define LTC_ARGCHKVD(x) if (!(x)) return;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */
|
||||
/* $Revision: 1.5 $ */
|
||||
/* $Date: 2006/08/27 20:50:21 $ */
|
||||
136
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
Normal file
136
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/* This is the build config file.
|
||||
*
|
||||
* With this you can setup what to inlcude/exclude automatically during any build. Just comment
|
||||
* out the line that #define's the word for the thing you want to remove. phew!
|
||||
*/
|
||||
|
||||
#ifndef TOMCRYPT_CFG_H
|
||||
#define TOMCRYPT_CFG_H
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#define LTC_CALL __cdecl
|
||||
#else
|
||||
#ifndef LTC_CALL
|
||||
#define LTC_CALL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LTC_EXPORT
|
||||
#define LTC_EXPORT
|
||||
#endif
|
||||
|
||||
/* certain platforms use macros for these, making the prototypes broken */
|
||||
#ifndef LTC_NO_PROTOTYPES
|
||||
|
||||
/* you can change how memory allocation works ... */
|
||||
LTC_EXPORT void * LTC_CALL XMALLOC(size_t n);
|
||||
LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
|
||||
LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
|
||||
LTC_EXPORT void LTC_CALL XFREE(void *p);
|
||||
|
||||
LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
|
||||
|
||||
|
||||
/* change the clock function too */
|
||||
LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
|
||||
|
||||
/* various other functions */
|
||||
LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
|
||||
LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
|
||||
LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
|
||||
|
||||
LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
|
||||
|
||||
#endif
|
||||
|
||||
/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
|
||||
#ifndef ARGTYPE
|
||||
#define ARGTYPE 0
|
||||
#endif
|
||||
|
||||
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code
|
||||
*
|
||||
* Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
|
||||
* The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
|
||||
* use the portable [slower] macros.
|
||||
*/
|
||||
|
||||
/* detect x86-32 machines somewhat */
|
||||
#if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_32BITWORD
|
||||
#define LTC_FAST
|
||||
#define LTC_FAST_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
/* detects MIPS R5900 processors (PS2) */
|
||||
#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_64BITWORD
|
||||
#endif
|
||||
|
||||
/* detect amd64 */
|
||||
#if !defined(__STRICT_ANSI__) && defined(__x86_64__)
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_64BITWORD
|
||||
#define LTC_FAST
|
||||
#define LTC_FAST_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
/* detect PPC32 */
|
||||
#if !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
|
||||
#define ENDIAN_BIG
|
||||
#define ENDIAN_32BITWORD
|
||||
#define LTC_FAST
|
||||
#define LTC_FAST_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
/* detect sparc and sparc64 */
|
||||
#if defined(__sparc__)
|
||||
#define ENDIAN_BIG
|
||||
#if defined(__arch64__)
|
||||
#define ENDIAN_64BITWORD
|
||||
#else
|
||||
#define ENDIAN_32BITWORD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LTC_NO_FAST
|
||||
#ifdef LTC_FAST
|
||||
#undef LTC_FAST
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* No asm is a quick way to disable anything "not portable" */
|
||||
#ifdef LTC_NO_ASM
|
||||
#undef ENDIAN_LITTLE
|
||||
#undef ENDIAN_BIG
|
||||
#undef ENDIAN_32BITWORD
|
||||
#undef ENDIAN_64BITWORD
|
||||
#undef LTC_FAST
|
||||
#undef LTC_FAST_TYPE
|
||||
#define LTC_NO_ROLC
|
||||
#define LTC_NO_BSWAP
|
||||
#endif
|
||||
|
||||
/* #define ENDIAN_LITTLE */
|
||||
/* #define ENDIAN_BIG */
|
||||
|
||||
/* #define ENDIAN_32BITWORD */
|
||||
/* #define ENDIAN_64BITWORD */
|
||||
|
||||
#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
|
||||
#error You must specify a word size as well as endianess in tomcrypt_cfg.h
|
||||
#endif
|
||||
|
||||
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
|
||||
#define ENDIAN_NEUTRAL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */
|
||||
/* $Revision: 1.19 $ */
|
||||
/* $Date: 2006/12/04 02:19:48 $ */
|
||||
891
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h
Normal file
891
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h
Normal file
@@ -0,0 +1,891 @@
|
||||
/* ---- SYMMETRIC KEY STUFF -----
|
||||
*
|
||||
* We put each of the ciphers scheduled keys in their own structs then we put all of
|
||||
* the key formats in one union. This makes the function prototypes easier to use.
|
||||
*/
|
||||
#ifdef LTC_BLOWFISH
|
||||
struct blowfish_key {
|
||||
ulong32 S[4][256];
|
||||
ulong32 K[18];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC5
|
||||
struct rc5_key {
|
||||
int rounds;
|
||||
ulong32 K[50];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC6
|
||||
struct rc6_key {
|
||||
ulong32 K[44];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SAFERP
|
||||
struct saferp_key {
|
||||
unsigned char K[33][16];
|
||||
long rounds;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIJNDAEL
|
||||
struct rijndael_key {
|
||||
ulong32 eK[60], dK[60];
|
||||
int Nr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KSEED
|
||||
struct kseed_key {
|
||||
ulong32 K[32], dK[32];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KASUMI
|
||||
struct kasumi_key {
|
||||
ulong32 KLi1[8], KLi2[8],
|
||||
KOi1[8], KOi2[8], KOi3[8],
|
||||
KIi1[8], KIi2[8], KIi3[8];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_XTEA
|
||||
struct xtea_key {
|
||||
unsigned long A[32], B[32];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_TWOFISH
|
||||
#ifndef LTC_TWOFISH_SMALL
|
||||
struct twofish_key {
|
||||
ulong32 S[4][256], K[40];
|
||||
};
|
||||
#else
|
||||
struct twofish_key {
|
||||
ulong32 K[40];
|
||||
unsigned char S[32], start;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SAFER
|
||||
#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6
|
||||
#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10
|
||||
#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8
|
||||
#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10
|
||||
#define LTC_SAFER_MAX_NOF_ROUNDS 13
|
||||
#define LTC_SAFER_BLOCK_LEN 8
|
||||
#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS))
|
||||
typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN];
|
||||
typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN];
|
||||
struct safer_key { safer_key_t key; };
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC2
|
||||
struct rc2_key { unsigned xkey[64]; };
|
||||
#endif
|
||||
|
||||
#ifdef LTC_DES
|
||||
struct des_key {
|
||||
ulong32 ek[32], dk[32];
|
||||
};
|
||||
|
||||
struct des3_key {
|
||||
ulong32 ek[3][32], dk[3][32];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CAST5
|
||||
struct cast5_key {
|
||||
ulong32 K[32], keylen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_NOEKEON
|
||||
struct noekeon_key {
|
||||
ulong32 K[4], dK[4];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SKIPJACK
|
||||
struct skipjack_key {
|
||||
unsigned char key[10];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KHAZAD
|
||||
struct khazad_key {
|
||||
ulong64 roundKeyEnc[8 + 1];
|
||||
ulong64 roundKeyDec[8 + 1];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_ANUBIS
|
||||
struct anubis_key {
|
||||
int keyBits;
|
||||
int R;
|
||||
ulong32 roundKeyEnc[18 + 1][4];
|
||||
ulong32 roundKeyDec[18 + 1][4];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MULTI2
|
||||
struct multi2_key {
|
||||
int N;
|
||||
ulong32 uk[8];
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union Symmetric_key {
|
||||
#ifdef LTC_DES
|
||||
struct des_key des;
|
||||
struct des3_key des3;
|
||||
#endif
|
||||
#ifdef LTC_RC2
|
||||
struct rc2_key rc2;
|
||||
#endif
|
||||
#ifdef LTC_SAFER
|
||||
struct safer_key safer;
|
||||
#endif
|
||||
#ifdef LTC_TWOFISH
|
||||
struct twofish_key twofish;
|
||||
#endif
|
||||
#ifdef LTC_BLOWFISH
|
||||
struct blowfish_key blowfish;
|
||||
#endif
|
||||
#ifdef LTC_RC5
|
||||
struct rc5_key rc5;
|
||||
#endif
|
||||
#ifdef LTC_RC6
|
||||
struct rc6_key rc6;
|
||||
#endif
|
||||
#ifdef LTC_SAFERP
|
||||
struct saferp_key saferp;
|
||||
#endif
|
||||
#ifdef LTC_RIJNDAEL
|
||||
struct rijndael_key rijndael;
|
||||
#endif
|
||||
#ifdef LTC_XTEA
|
||||
struct xtea_key xtea;
|
||||
#endif
|
||||
#ifdef LTC_CAST5
|
||||
struct cast5_key cast5;
|
||||
#endif
|
||||
#ifdef LTC_NOEKEON
|
||||
struct noekeon_key noekeon;
|
||||
#endif
|
||||
#ifdef LTC_SKIPJACK
|
||||
struct skipjack_key skipjack;
|
||||
#endif
|
||||
#ifdef LTC_KHAZAD
|
||||
struct khazad_key khazad;
|
||||
#endif
|
||||
#ifdef LTC_ANUBIS
|
||||
struct anubis_key anubis;
|
||||
#endif
|
||||
#ifdef LTC_KSEED
|
||||
struct kseed_key kseed;
|
||||
#endif
|
||||
#ifdef LTC_KASUMI
|
||||
struct kasumi_key kasumi;
|
||||
#endif
|
||||
#ifdef LTC_MULTI2
|
||||
struct multi2_key multi2;
|
||||
#endif
|
||||
void *data;
|
||||
} symmetric_key;
|
||||
|
||||
#ifdef LTC_ECB_MODE
|
||||
/** A block cipher ECB structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen;
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_ECB;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CFB_MODE
|
||||
/** A block cipher CFB structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen,
|
||||
/** The padding offset */
|
||||
padlen;
|
||||
/** The current IV */
|
||||
unsigned char IV[MAXBLOCKSIZE],
|
||||
/** The pad used to encrypt/decrypt */
|
||||
pad[MAXBLOCKSIZE];
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_CFB;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_OFB_MODE
|
||||
/** A block cipher OFB structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen,
|
||||
/** The padding offset */
|
||||
padlen;
|
||||
/** The current IV */
|
||||
unsigned char IV[MAXBLOCKSIZE];
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_OFB;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CBC_MODE
|
||||
/** A block cipher CBC structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen;
|
||||
/** The current IV */
|
||||
unsigned char IV[MAXBLOCKSIZE];
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_CBC;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LTC_CTR_MODE
|
||||
/** A block cipher CTR structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen,
|
||||
/** The padding offset */
|
||||
padlen,
|
||||
/** The mode (endianess) of the CTR, 0==little, 1==big */
|
||||
mode,
|
||||
/** counter width */
|
||||
ctrlen;
|
||||
|
||||
/** The counter */
|
||||
unsigned char ctr[MAXBLOCKSIZE],
|
||||
/** The pad used to encrypt/decrypt */
|
||||
pad[MAXBLOCKSIZE];
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_CTR;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LTC_LRW_MODE
|
||||
/** A LRW structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen (must be a 128-bit block cipher) */
|
||||
int cipher;
|
||||
|
||||
/** The current IV */
|
||||
unsigned char IV[16],
|
||||
|
||||
/** the tweak key */
|
||||
tweak[16],
|
||||
|
||||
/** The current pad, it's the product of the first 15 bytes against the tweak key */
|
||||
pad[16];
|
||||
|
||||
/** The scheduled symmetric key */
|
||||
symmetric_key key;
|
||||
|
||||
#ifdef LRW_TABLES
|
||||
/** The pre-computed multiplication table */
|
||||
unsigned char PC[16][256][16];
|
||||
#endif
|
||||
} symmetric_LRW;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_F8_MODE
|
||||
/** A block cipher F8 structure */
|
||||
typedef struct {
|
||||
/** The index of the cipher chosen */
|
||||
int cipher,
|
||||
/** The block size of the given cipher */
|
||||
blocklen,
|
||||
/** The padding offset */
|
||||
padlen;
|
||||
/** The current IV */
|
||||
unsigned char IV[MAXBLOCKSIZE],
|
||||
MIV[MAXBLOCKSIZE];
|
||||
/** Current block count */
|
||||
ulong32 blockcnt;
|
||||
/** The scheduled key */
|
||||
symmetric_key key;
|
||||
} symmetric_F8;
|
||||
#endif
|
||||
|
||||
|
||||
/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */
|
||||
extern struct ltc_cipher_descriptor {
|
||||
/** name of cipher */
|
||||
char *name;
|
||||
/** internal ID */
|
||||
unsigned char ID;
|
||||
/** min keysize (octets) */
|
||||
int min_key_length,
|
||||
/** max keysize (octets) */
|
||||
max_key_length,
|
||||
/** block size (octets) */
|
||||
block_length,
|
||||
/** default number of rounds */
|
||||
default_rounds;
|
||||
/** Setup the cipher
|
||||
@param key The input symmetric key
|
||||
@param keylen The length of the input key (octets)
|
||||
@param num_rounds The requested number of rounds (0==default)
|
||||
@param skey [out] The destination of the scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
/** Encrypt a block
|
||||
@param pt The plaintext
|
||||
@param ct [out] The ciphertext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
/** Decrypt a block
|
||||
@param ct The ciphertext
|
||||
@param pt [out] The plaintext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
/** Test the block cipher
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
|
||||
*/
|
||||
int (*test)(void);
|
||||
|
||||
/** Terminate the context
|
||||
@param skey The scheduled key
|
||||
*/
|
||||
void (*done)(symmetric_key *skey);
|
||||
|
||||
/** Determine a key size
|
||||
@param keysize [in/out] The size of the key desired and the suggested size
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*keysize)(int *keysize);
|
||||
|
||||
/** Accelerators **/
|
||||
/** Accelerated ECB encryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated ECB decryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC encryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC decryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CTR encryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param mode little or big endian counter (mode=0 or mode=1)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
|
||||
|
||||
/** Accelerated LRW
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param tweak The LRW tweak
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
|
||||
|
||||
/** Accelerated LRW
|
||||
@param ct Ciphertext
|
||||
@param pt Plaintext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param tweak The LRW tweak
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CCM packet (one-shot)
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param uskey A previously scheduled key [optional can be NULL]
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@param headerlen The length of the header (octets)
|
||||
@param pt [out] The plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The ciphertext
|
||||
@param tag [out] The destination tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@param direction Encrypt or Decrypt direction (0 or 1)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*accel_ccm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
/** Accelerated GCM packet (one shot)
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key
|
||||
@param IV The initial vector
|
||||
@param IVlen The length of the initial vector
|
||||
@param adata The additional authentication data (header)
|
||||
@param adatalen The length of the adata
|
||||
@param pt The plaintext
|
||||
@param ptlen The length of the plaintext (ciphertext length is the same)
|
||||
@param ct The ciphertext
|
||||
@param tag [out] The MAC tag
|
||||
@param taglen [in/out] The MAC tag length
|
||||
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*accel_gcm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
/** Accelerated one shot LTC_OMAC
|
||||
@param key The secret key
|
||||
@param keylen The key length (octets)
|
||||
@param in The message
|
||||
@param inlen Length of message (octets)
|
||||
@param out [out] Destination for tag
|
||||
@param outlen [in/out] Initial and final size of out
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*omac_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
/** Accelerated one shot XCBC
|
||||
@param key The secret key
|
||||
@param keylen The key length (octets)
|
||||
@param in The message
|
||||
@param inlen Length of message (octets)
|
||||
@param out [out] Destination for tag
|
||||
@param outlen [in/out] Initial and final size of out
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*xcbc_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
/** Accelerated one shot F9
|
||||
@param key The secret key
|
||||
@param keylen The key length (octets)
|
||||
@param in The message
|
||||
@param inlen Length of message (octets)
|
||||
@param out [out] Destination for tag
|
||||
@param outlen [in/out] Initial and final size of out
|
||||
@return CRYPT_OK on success
|
||||
@remark Requires manual padding
|
||||
*/
|
||||
int (*f9_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
} cipher_descriptor[];
|
||||
|
||||
#ifdef LTC_BLOWFISH
|
||||
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int blowfish_test(void);
|
||||
void blowfish_done(symmetric_key *skey);
|
||||
int blowfish_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor blowfish_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC5
|
||||
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc5_test(void);
|
||||
void rc5_done(symmetric_key *skey);
|
||||
int rc5_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor rc5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC6
|
||||
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc6_test(void);
|
||||
void rc6_done(symmetric_key *skey);
|
||||
int rc6_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor rc6_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC2
|
||||
int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc2_test(void);
|
||||
void rc2_done(symmetric_key *skey);
|
||||
int rc2_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor rc2_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SAFERP
|
||||
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int saferp_test(void);
|
||||
void saferp_done(symmetric_key *skey);
|
||||
int saferp_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor saferp_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SAFER
|
||||
int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
int safer_k64_test(void);
|
||||
int safer_sk64_test(void);
|
||||
int safer_sk128_test(void);
|
||||
void safer_done(symmetric_key *skey);
|
||||
int safer_64_keysize(int *keysize);
|
||||
int safer_128_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIJNDAEL
|
||||
|
||||
/* make aes an alias */
|
||||
#define aes_setup rijndael_setup
|
||||
#define aes_ecb_encrypt rijndael_ecb_encrypt
|
||||
#define aes_ecb_decrypt rijndael_ecb_decrypt
|
||||
#define aes_test rijndael_test
|
||||
#define aes_done rijndael_done
|
||||
#define aes_keysize rijndael_keysize
|
||||
|
||||
#define aes_enc_setup rijndael_enc_setup
|
||||
#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
|
||||
#define aes_enc_keysize rijndael_enc_keysize
|
||||
|
||||
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rijndael_test(void);
|
||||
void rijndael_done(symmetric_key *skey);
|
||||
int rijndael_keysize(int *keysize);
|
||||
int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rijndael_enc_done(symmetric_key *skey);
|
||||
int rijndael_enc_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
|
||||
extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_XTEA
|
||||
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int xtea_test(void);
|
||||
void xtea_done(symmetric_key *skey);
|
||||
int xtea_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor xtea_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_TWOFISH
|
||||
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int twofish_test(void);
|
||||
void twofish_done(symmetric_key *skey);
|
||||
int twofish_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor twofish_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_DES
|
||||
int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des_test(void);
|
||||
void des_done(symmetric_key *skey);
|
||||
int des_keysize(int *keysize);
|
||||
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des3_test(void);
|
||||
void des3_done(symmetric_key *skey);
|
||||
int des3_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor des_desc, des3_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CAST5
|
||||
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int cast5_test(void);
|
||||
void cast5_done(symmetric_key *skey);
|
||||
int cast5_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor cast5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_NOEKEON
|
||||
int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int noekeon_test(void);
|
||||
void noekeon_done(symmetric_key *skey);
|
||||
int noekeon_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor noekeon_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SKIPJACK
|
||||
int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int skipjack_test(void);
|
||||
void skipjack_done(symmetric_key *skey);
|
||||
int skipjack_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor skipjack_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KHAZAD
|
||||
int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int khazad_test(void);
|
||||
void khazad_done(symmetric_key *skey);
|
||||
int khazad_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor khazad_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_ANUBIS
|
||||
int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int anubis_test(void);
|
||||
void anubis_done(symmetric_key *skey);
|
||||
int anubis_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor anubis_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KSEED
|
||||
int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int kseed_test(void);
|
||||
void kseed_done(symmetric_key *skey);
|
||||
int kseed_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor kseed_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KASUMI
|
||||
int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int kasumi_test(void);
|
||||
void kasumi_done(symmetric_key *skey);
|
||||
int kasumi_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor kasumi_desc;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LTC_MULTI2
|
||||
int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int multi2_test(void);
|
||||
void multi2_done(symmetric_key *skey);
|
||||
int multi2_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor multi2_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_ECB_MODE
|
||||
int ecb_start(int cipher, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_ECB *ecb);
|
||||
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb);
|
||||
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb);
|
||||
int ecb_done(symmetric_ECB *ecb);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CFB_MODE
|
||||
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CFB *cfb);
|
||||
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
|
||||
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
|
||||
int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
|
||||
int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
|
||||
int cfb_done(symmetric_CFB *cfb);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_OFB_MODE
|
||||
int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_OFB *ofb);
|
||||
int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
|
||||
int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
|
||||
int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
|
||||
int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
|
||||
int ofb_done(symmetric_OFB *ofb);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CBC_MODE
|
||||
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CBC *cbc);
|
||||
int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc);
|
||||
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc);
|
||||
int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
|
||||
int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
|
||||
int cbc_done(symmetric_CBC *cbc);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CTR_MODE
|
||||
|
||||
#define CTR_COUNTER_LITTLE_ENDIAN 0x0000
|
||||
#define CTR_COUNTER_BIG_ENDIAN 0x1000
|
||||
#define LTC_CTR_RFC3686 0x2000
|
||||
|
||||
int ctr_start( int cipher,
|
||||
const unsigned char *IV,
|
||||
const unsigned char *key, int keylen,
|
||||
int num_rounds, int ctr_mode,
|
||||
symmetric_CTR *ctr);
|
||||
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
|
||||
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
|
||||
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
|
||||
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
|
||||
int ctr_done(symmetric_CTR *ctr);
|
||||
int ctr_test(void);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_LRW_MODE
|
||||
|
||||
#define LRW_ENCRYPT 0
|
||||
#define LRW_DECRYPT 1
|
||||
|
||||
int lrw_start( int cipher,
|
||||
const unsigned char *IV,
|
||||
const unsigned char *key, int keylen,
|
||||
const unsigned char *tweak,
|
||||
int num_rounds,
|
||||
symmetric_LRW *lrw);
|
||||
int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw);
|
||||
int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw);
|
||||
int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw);
|
||||
int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw);
|
||||
int lrw_done(symmetric_LRW *lrw);
|
||||
int lrw_test(void);
|
||||
|
||||
/* don't call */
|
||||
int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_F8_MODE
|
||||
int f8_start( int cipher, const unsigned char *IV,
|
||||
const unsigned char *key, int keylen,
|
||||
const unsigned char *salt_key, int skeylen,
|
||||
int num_rounds, symmetric_F8 *f8);
|
||||
int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8);
|
||||
int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8);
|
||||
int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8);
|
||||
int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8);
|
||||
int f8_done(symmetric_F8 *f8);
|
||||
int f8_test_mode(void);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_XTS_MODE
|
||||
typedef struct {
|
||||
symmetric_key key1, key2;
|
||||
int cipher;
|
||||
} symmetric_xts;
|
||||
|
||||
int xts_start( int cipher,
|
||||
const unsigned char *key1,
|
||||
const unsigned char *key2,
|
||||
unsigned long keylen,
|
||||
int num_rounds,
|
||||
symmetric_xts *xts);
|
||||
|
||||
int xts_encrypt(
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
const unsigned char *tweak,
|
||||
symmetric_xts *xts);
|
||||
int xts_decrypt(
|
||||
const unsigned char *ct, unsigned long ptlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tweak,
|
||||
symmetric_xts *xts);
|
||||
|
||||
void xts_done(symmetric_xts *xts);
|
||||
int xts_test(void);
|
||||
void xts_mult_x(unsigned char *I);
|
||||
#endif
|
||||
|
||||
int find_cipher(const char *name);
|
||||
int find_cipher_any(const char *name, int blocklen, int keylen);
|
||||
int find_cipher_id(unsigned char ID);
|
||||
int register_cipher(const struct ltc_cipher_descriptor *cipher);
|
||||
int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
|
||||
int cipher_is_valid(int idx);
|
||||
|
||||
LTC_MUTEX_PROTO(ltc_cipher_mutex)
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */
|
||||
/* $Revision: 1.54 $ */
|
||||
/* $Date: 2007/05/12 14:37:41 $ */
|
||||
424
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_custom.h
Normal file
424
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_custom.h
Normal file
@@ -0,0 +1,424 @@
|
||||
#ifndef TOMCRYPT_CUSTOM_H_
|
||||
#define TOMCRYPT_CUSTOM_H_
|
||||
|
||||
#define LTC_NO_CIPHERS
|
||||
#define LTC_NO_HASHES
|
||||
#define LTC_NO_MACS
|
||||
#define LTC_NO_PRNGS
|
||||
#define LTC_NO_CURVES
|
||||
#define LTC_NO_MODES
|
||||
#define LTC_NO_PKCS
|
||||
#define LTC_NO_ROLC
|
||||
|
||||
#define LTC_SOURCE
|
||||
#define LTC_SHA1
|
||||
#define LTC_MD5
|
||||
#define LTC_DER
|
||||
#define LTC_RC4
|
||||
|
||||
#define USE_LTM
|
||||
#define LTM_DESC
|
||||
|
||||
/* macros for various libc functions you can change for embedded targets */
|
||||
#ifndef XMALLOC
|
||||
#ifdef malloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XMALLOC LibTomMalloc
|
||||
#endif
|
||||
#ifndef XREALLOC
|
||||
#ifdef realloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XREALLOC LibTomRealloc
|
||||
#endif
|
||||
#ifndef XCALLOC
|
||||
#ifdef calloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XCALLOC LibTomCalloc
|
||||
#endif
|
||||
#ifndef XFREE
|
||||
#ifdef free
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XFREE LibTomFree
|
||||
#endif
|
||||
|
||||
#ifndef XMEMSET
|
||||
#ifdef memset
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XMEMSET memset
|
||||
#endif
|
||||
#ifndef XMEMCPY
|
||||
#ifdef memcpy
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XMEMCPY memcpy
|
||||
#endif
|
||||
#ifndef XMEMCMP
|
||||
#ifdef memcmp
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XMEMCMP memcmp
|
||||
#endif
|
||||
#ifndef XSTRCMP
|
||||
#ifdef strcmp
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XSTRCMP strcmp
|
||||
#endif
|
||||
|
||||
#ifndef XCLOCK
|
||||
#define XCLOCK LibTomClock
|
||||
#endif
|
||||
#ifndef XCLOCKS_PER_SEC
|
||||
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
|
||||
#endif
|
||||
|
||||
#ifndef XQSORT
|
||||
#ifdef qsort
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XQSORT LibTomQsort
|
||||
#endif
|
||||
|
||||
/* Easy button? */
|
||||
#ifdef LTC_EASY
|
||||
#define LTC_NO_CIPHERS
|
||||
#define LTC_RIJNDAEL
|
||||
#define LTC_BLOWFISH
|
||||
#define LTC_DES
|
||||
#define LTC_CAST5
|
||||
|
||||
#define LTC_NO_MODES
|
||||
#define LTC_ECB_MODE
|
||||
#define LTC_CBC_MODE
|
||||
#define LTC_CTR_MODE
|
||||
|
||||
#define LTC_NO_HASHES
|
||||
#define LTC_SHA1
|
||||
#define LTC_SHA512
|
||||
#define LTC_SHA384
|
||||
#define LTC_SHA256
|
||||
#define LTC_SHA224
|
||||
|
||||
#define LTC_NO_MACS
|
||||
#define LTC_HMAC
|
||||
#define LTC_OMAC
|
||||
#define LTC_CCM_MODE
|
||||
|
||||
#define LTC_NO_PRNGS
|
||||
#define LTC_SPRNG
|
||||
#define LTC_YARROW
|
||||
#define LTC_DEVRANDOM
|
||||
#define TRY_URANDOM_FIRST
|
||||
|
||||
#define LTC_NO_PK
|
||||
#define LTC_MRSA
|
||||
#define LTC_MECC
|
||||
#endif
|
||||
|
||||
/* Use small code where possible */
|
||||
/* #define LTC_SMALL_CODE */
|
||||
|
||||
/* Enable self-test test vector checking */
|
||||
#ifndef LTC_NO_TEST
|
||||
#define LTC_TEST
|
||||
#endif
|
||||
|
||||
/* clean the stack of functions which put private information on stack */
|
||||
/* #define LTC_CLEAN_STACK */
|
||||
|
||||
/* disable all file related functions */
|
||||
/* #define LTC_NO_FILE */
|
||||
|
||||
/* disable all forms of ASM */
|
||||
/* #define LTC_NO_ASM */
|
||||
|
||||
/* disable FAST mode */
|
||||
/* #define LTC_NO_FAST */
|
||||
|
||||
/* disable BSWAP on x86 */
|
||||
/* #define LTC_NO_BSWAP */
|
||||
|
||||
/* ---> Symmetric Block Ciphers <--- */
|
||||
#ifndef LTC_NO_CIPHERS
|
||||
|
||||
#define LTC_BLOWFISH
|
||||
#define LTC_RC2
|
||||
#define LTC_RC5
|
||||
#define LTC_RC6
|
||||
#define LTC_SAFERP
|
||||
#define LTC_RIJNDAEL
|
||||
#define LTC_XTEA
|
||||
/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
|
||||
* (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
|
||||
#define LTC_TWOFISH
|
||||
#ifndef LTC_NO_TABLES
|
||||
#define LTC_TWOFISH_TABLES
|
||||
/* #define LTC_TWOFISH_ALL_TABLES */
|
||||
#else
|
||||
#define LTC_TWOFISH_SMALL
|
||||
#endif
|
||||
/* #define LTC_TWOFISH_SMALL */
|
||||
/* LTC_DES includes EDE triple-LTC_DES */
|
||||
#define LTC_DES
|
||||
#define LTC_CAST5
|
||||
#define LTC_NOEKEON
|
||||
#define LTC_SKIPJACK
|
||||
#define LTC_SAFER
|
||||
#define LTC_KHAZAD
|
||||
#define LTC_ANUBIS
|
||||
#define LTC_ANUBIS_TWEAK
|
||||
#define LTC_KSEED
|
||||
#define LTC_KASUMI
|
||||
|
||||
#endif /* LTC_NO_CIPHERS */
|
||||
|
||||
|
||||
/* ---> Block Cipher Modes of Operation <--- */
|
||||
#ifndef LTC_NO_MODES
|
||||
|
||||
#define LTC_CFB_MODE
|
||||
#define LTC_OFB_MODE
|
||||
#define LTC_ECB_MODE
|
||||
#define LTC_CBC_MODE
|
||||
#define LTC_CTR_MODE
|
||||
|
||||
/* F8 chaining mode */
|
||||
#define LTC_F8_MODE
|
||||
|
||||
/* LRW mode */
|
||||
#define LTC_LRW_MODE
|
||||
#ifndef LTC_NO_TABLES
|
||||
/* like GCM mode this will enable 16 8x128 tables [64KB] that make
|
||||
* seeking very fast.
|
||||
*/
|
||||
#define LRW_TABLES
|
||||
#endif
|
||||
|
||||
/* XTS mode */
|
||||
#define LTC_XTS_MODE
|
||||
|
||||
#endif /* LTC_NO_MODES */
|
||||
|
||||
/* ---> One-Way Hash Functions <--- */
|
||||
#ifndef LTC_NO_HASHES
|
||||
|
||||
#define LTC_CHC_HASH
|
||||
#define LTC_WHIRLPOOL
|
||||
#define LTC_SHA512
|
||||
#define LTC_SHA384
|
||||
#define LTC_SHA256
|
||||
#define LTC_SHA224
|
||||
#define LTC_TIGER
|
||||
#define LTC_SHA1
|
||||
#define LTC_MD5
|
||||
#define LTC_MD4
|
||||
#define LTC_MD2
|
||||
#define LTC_RIPEMD128
|
||||
#define LTC_RIPEMD160
|
||||
#define LTC_RIPEMD256
|
||||
#define LTC_RIPEMD320
|
||||
|
||||
#endif /* LTC_NO_HASHES */
|
||||
|
||||
/* ---> MAC functions <--- */
|
||||
#ifndef LTC_NO_MACS
|
||||
|
||||
#define LTC_HMAC
|
||||
#define LTC_OMAC
|
||||
#define LTC_PMAC
|
||||
#define LTC_XCBC
|
||||
#define LTC_F9_MODE
|
||||
#define LTC_PELICAN
|
||||
|
||||
#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL)
|
||||
#error Pelican-MAC requires LTC_RIJNDAEL
|
||||
#endif
|
||||
|
||||
/* ---> Encrypt + Authenticate Modes <--- */
|
||||
|
||||
#define LTC_EAX_MODE
|
||||
#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC))
|
||||
#error LTC_EAX_MODE requires CTR and LTC_OMAC mode
|
||||
#endif
|
||||
|
||||
#define LTC_OCB_MODE
|
||||
#define LTC_CCM_MODE
|
||||
#define LTC_GCM_MODE
|
||||
|
||||
/* Use 64KiB tables */
|
||||
#ifndef LTC_NO_TABLES
|
||||
#define LTC_GCM_TABLES
|
||||
#endif
|
||||
|
||||
/* USE SSE2? requires GCC works on x86_32 and x86_64*/
|
||||
#ifdef LTC_GCM_TABLES
|
||||
/* #define LTC_GCM_TABLES_SSE2 */
|
||||
#endif
|
||||
|
||||
#endif /* LTC_NO_MACS */
|
||||
|
||||
/* Various tidbits of modern neatoness */
|
||||
#define LTC_BASE64
|
||||
|
||||
/* --> Pseudo Random Number Generators <--- */
|
||||
#ifndef LTC_NO_PRNGS
|
||||
|
||||
/* Yarrow */
|
||||
#define LTC_YARROW
|
||||
/* which descriptor of AES to use? */
|
||||
/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */
|
||||
#define LTC_YARROW_AES 0
|
||||
|
||||
#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE)
|
||||
#error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined!
|
||||
#endif
|
||||
|
||||
/* a PRNG that simply reads from an available system source */
|
||||
#define LTC_SPRNG
|
||||
|
||||
/* The LTC_RC4 stream cipher */
|
||||
#define LTC_RC4
|
||||
|
||||
/* Fortuna PRNG */
|
||||
#define LTC_FORTUNA
|
||||
/* reseed every N calls to the read function */
|
||||
#define LTC_FORTUNA_WD 10
|
||||
/* number of pools (4..32) can save a bit of ram by lowering the count */
|
||||
#define LTC_FORTUNA_POOLS 32
|
||||
|
||||
/* Greg's LTC_SOBER128 PRNG ;-0 */
|
||||
#define LTC_SOBER128
|
||||
|
||||
/* the *nix style /dev/random device */
|
||||
#define LTC_DEVRANDOM
|
||||
/* try /dev/urandom before trying /dev/random */
|
||||
#define TRY_URANDOM_FIRST
|
||||
|
||||
#endif /* LTC_NO_PRNGS */
|
||||
|
||||
/* ---> math provider? <--- */
|
||||
#ifndef LTC_NO_MATH
|
||||
|
||||
/* LibTomMath */
|
||||
#define LTM_LTC_DESC
|
||||
|
||||
/* TomsFastMath */
|
||||
//#define TFM_LTC_DESC
|
||||
|
||||
#endif /* LTC_NO_MATH */
|
||||
|
||||
/* ---> Public Key Crypto <--- */
|
||||
#ifndef LTC_NO_PK
|
||||
|
||||
/* Include RSA support */
|
||||
#define LTC_MRSA
|
||||
|
||||
/* Include Katja (a Rabin variant like RSA) */
|
||||
/* #define MKAT */
|
||||
|
||||
/* Digital Signature Algorithm */
|
||||
#define LTC_MDSA
|
||||
|
||||
/* ECC */
|
||||
#define LTC_MECC
|
||||
|
||||
/* use Shamir's trick for point mul (speeds up signature verification) */
|
||||
#define LTC_ECC_SHAMIR
|
||||
|
||||
#if defined(TFM_LTC_DESC) && defined(LTC_MECC)
|
||||
#define LTC_MECC_ACCEL
|
||||
#endif
|
||||
|
||||
/* do we want fixed point ECC */
|
||||
/* #define LTC_MECC_FP */
|
||||
|
||||
/* Timing Resistant? */
|
||||
/* #define LTC_ECC_TIMING_RESISTANT */
|
||||
|
||||
#endif /* LTC_NO_PK */
|
||||
|
||||
/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */
|
||||
#ifndef LTC_NO_PKCS
|
||||
|
||||
#define LTC_PKCS_1
|
||||
#define LTC_PKCS_5
|
||||
|
||||
/* Include ASN.1 DER (required by DSA/RSA) */
|
||||
#define LTC_DER
|
||||
|
||||
#endif /* LTC_NO_PKCS */
|
||||
|
||||
/* cleanup */
|
||||
|
||||
#ifdef LTC_MECC
|
||||
/* Supported ECC Key Sizes */
|
||||
#ifndef LTC_NO_CURVES
|
||||
#define ECC112
|
||||
#define ECC128
|
||||
#define ECC160
|
||||
#define ECC192
|
||||
#define ECC224
|
||||
#define ECC256
|
||||
#define ECC384
|
||||
#define ECC521
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA)
|
||||
/* Include the MPI functionality? (required by the PK algorithms) */
|
||||
#define MPI
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MRSA
|
||||
#define LTC_PKCS_1
|
||||
#endif
|
||||
|
||||
#if defined(LTC_DER) && !defined(MPI)
|
||||
#error ASN.1 DER requires MPI functionality
|
||||
#endif
|
||||
|
||||
#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER)
|
||||
#error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
|
||||
#endif
|
||||
|
||||
/* THREAD management */
|
||||
#ifdef LTC_PTHREAD
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
|
||||
#define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
|
||||
#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
|
||||
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
|
||||
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
|
||||
|
||||
#else
|
||||
|
||||
/* default no functions */
|
||||
#define LTC_MUTEX_GLOBAL(x)
|
||||
#define LTC_MUTEX_PROTO(x)
|
||||
#define LTC_MUTEX_TYPE(x)
|
||||
#define LTC_MUTEX_INIT(x)
|
||||
#define LTC_MUTEX_LOCK(x)
|
||||
#define LTC_MUTEX_UNLOCK(x)
|
||||
|
||||
#endif
|
||||
|
||||
/* Debuggers */
|
||||
|
||||
/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */
|
||||
/* #define LTC_VALGRIND */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */
|
||||
/* $Revision: 1.73 $ */
|
||||
/* $Date: 2007/05/12 14:37:41 $ */
|
||||
378
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_hash.h
Normal file
378
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_hash.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/* ---- HASH FUNCTIONS ---- */
|
||||
#ifdef LTC_SHA512
|
||||
struct sha512_state {
|
||||
ulong64 length, state[8];
|
||||
unsigned long curlen;
|
||||
unsigned char buf[128];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA256
|
||||
struct sha256_state {
|
||||
ulong64 length;
|
||||
ulong32 state[8], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA1
|
||||
struct sha1_state {
|
||||
ulong64 length;
|
||||
ulong32 state[5], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD5
|
||||
struct md5_state {
|
||||
ulong64 length;
|
||||
ulong32 state[4], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD4
|
||||
struct md4_state {
|
||||
ulong64 length;
|
||||
ulong32 state[4], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_TIGER
|
||||
struct tiger_state {
|
||||
ulong64 state[3], length;
|
||||
unsigned long curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD2
|
||||
struct md2_state {
|
||||
unsigned char chksum[16], X[48], buf[16];
|
||||
unsigned long curlen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD128
|
||||
struct rmd128_state {
|
||||
ulong64 length;
|
||||
unsigned char buf[64];
|
||||
ulong32 curlen, state[4];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD160
|
||||
struct rmd160_state {
|
||||
ulong64 length;
|
||||
unsigned char buf[64];
|
||||
ulong32 curlen, state[5];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD256
|
||||
struct rmd256_state {
|
||||
ulong64 length;
|
||||
unsigned char buf[64];
|
||||
ulong32 curlen, state[8];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD320
|
||||
struct rmd320_state {
|
||||
ulong64 length;
|
||||
unsigned char buf[64];
|
||||
ulong32 curlen, state[10];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_WHIRLPOOL
|
||||
struct whirlpool_state {
|
||||
ulong64 length, state[8];
|
||||
unsigned char buf[64];
|
||||
ulong32 curlen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CHC_HASH
|
||||
struct chc_state {
|
||||
ulong64 length;
|
||||
unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE];
|
||||
ulong32 curlen;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union Hash_state {
|
||||
#ifdef LTC_CHC_HASH
|
||||
struct chc_state chc;
|
||||
#endif
|
||||
#ifdef LTC_WHIRLPOOL
|
||||
struct whirlpool_state whirlpool;
|
||||
#endif
|
||||
#ifdef LTC_SHA512
|
||||
struct sha512_state sha512;
|
||||
#endif
|
||||
#ifdef LTC_SHA256
|
||||
struct sha256_state sha256;
|
||||
#endif
|
||||
#ifdef LTC_SHA1
|
||||
struct sha1_state sha1;
|
||||
#endif
|
||||
#ifdef LTC_MD5
|
||||
struct md5_state md5;
|
||||
#endif
|
||||
#ifdef LTC_MD4
|
||||
struct md4_state md4;
|
||||
#endif
|
||||
#ifdef LTC_MD2
|
||||
struct md2_state md2;
|
||||
#endif
|
||||
#ifdef LTC_TIGER
|
||||
struct tiger_state tiger;
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD128
|
||||
struct rmd128_state rmd128;
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD160
|
||||
struct rmd160_state rmd160;
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD256
|
||||
struct rmd256_state rmd256;
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD320
|
||||
struct rmd320_state rmd320;
|
||||
#endif
|
||||
void *data;
|
||||
} hash_state;
|
||||
|
||||
/** hash descriptor */
|
||||
extern struct ltc_hash_descriptor {
|
||||
/** name of hash */
|
||||
char *name;
|
||||
/** internal ID */
|
||||
unsigned char ID;
|
||||
/** Size of digest in octets */
|
||||
unsigned long hashsize;
|
||||
/** Input block size in octets */
|
||||
unsigned long blocksize;
|
||||
/** ASN.1 OID */
|
||||
unsigned long OID[16];
|
||||
/** Length of DER encoding */
|
||||
unsigned long OIDlen;
|
||||
|
||||
/** Init a hash state
|
||||
@param hash The hash to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*init)(hash_state *hash);
|
||||
/** Process a block of data
|
||||
@param hash The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen);
|
||||
/** Produce the digest and store it
|
||||
@param hash The hash state
|
||||
@param out [out] The destination of the digest
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*done)(hash_state *hash, unsigned char *out);
|
||||
/** Self-test
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int (*test)(void);
|
||||
|
||||
/* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
|
||||
int (*hmac_block)(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
} hash_descriptor[];
|
||||
|
||||
#ifdef LTC_CHC_HASH
|
||||
int chc_register(int cipher);
|
||||
int chc_init(hash_state * md);
|
||||
int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int chc_done(hash_state * md, unsigned char *hash);
|
||||
int chc_test(void);
|
||||
extern const struct ltc_hash_descriptor chc_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_WHIRLPOOL
|
||||
int whirlpool_init(hash_state * md);
|
||||
int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int whirlpool_done(hash_state * md, unsigned char *hash);
|
||||
int whirlpool_test(void);
|
||||
extern const struct ltc_hash_descriptor whirlpool_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA512
|
||||
int sha512_init(hash_state * md);
|
||||
int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int sha512_done(hash_state * md, unsigned char *hash);
|
||||
int sha512_test(void);
|
||||
extern const struct ltc_hash_descriptor sha512_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA384
|
||||
#ifndef LTC_SHA512
|
||||
#error LTC_SHA512 is required for LTC_SHA384
|
||||
#endif
|
||||
int sha384_init(hash_state * md);
|
||||
#define sha384_process sha512_process
|
||||
int sha384_done(hash_state * md, unsigned char *hash);
|
||||
int sha384_test(void);
|
||||
extern const struct ltc_hash_descriptor sha384_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA256
|
||||
int sha256_init(hash_state * md);
|
||||
int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int sha256_done(hash_state * md, unsigned char *hash);
|
||||
int sha256_test(void);
|
||||
extern const struct ltc_hash_descriptor sha256_desc;
|
||||
|
||||
#ifdef LTC_SHA224
|
||||
#ifndef LTC_SHA256
|
||||
#error LTC_SHA256 is required for LTC_SHA224
|
||||
#endif
|
||||
int sha224_init(hash_state * md);
|
||||
#define sha224_process sha256_process
|
||||
int sha224_done(hash_state * md, unsigned char *hash);
|
||||
int sha224_test(void);
|
||||
extern const struct ltc_hash_descriptor sha224_desc;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SHA1
|
||||
int sha1_init(hash_state * md);
|
||||
int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int sha1_done(hash_state * md, unsigned char *hash);
|
||||
int sha1_test(void);
|
||||
extern const struct ltc_hash_descriptor sha1_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD5
|
||||
int md5_init(hash_state * md);
|
||||
int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int md5_done(hash_state * md, unsigned char *hash);
|
||||
int md5_test(void);
|
||||
extern const struct ltc_hash_descriptor md5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD4
|
||||
int md4_init(hash_state * md);
|
||||
int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int md4_done(hash_state * md, unsigned char *hash);
|
||||
int md4_test(void);
|
||||
extern const struct ltc_hash_descriptor md4_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MD2
|
||||
int md2_init(hash_state * md);
|
||||
int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int md2_done(hash_state * md, unsigned char *hash);
|
||||
int md2_test(void);
|
||||
extern const struct ltc_hash_descriptor md2_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_TIGER
|
||||
int tiger_init(hash_state * md);
|
||||
int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int tiger_done(hash_state * md, unsigned char *hash);
|
||||
int tiger_test(void);
|
||||
extern const struct ltc_hash_descriptor tiger_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD128
|
||||
int rmd128_init(hash_state * md);
|
||||
int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int rmd128_done(hash_state * md, unsigned char *hash);
|
||||
int rmd128_test(void);
|
||||
extern const struct ltc_hash_descriptor rmd128_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD160
|
||||
int rmd160_init(hash_state * md);
|
||||
int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int rmd160_done(hash_state * md, unsigned char *hash);
|
||||
int rmd160_test(void);
|
||||
extern const struct ltc_hash_descriptor rmd160_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD256
|
||||
int rmd256_init(hash_state * md);
|
||||
int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int rmd256_done(hash_state * md, unsigned char *hash);
|
||||
int rmd256_test(void);
|
||||
extern const struct ltc_hash_descriptor rmd256_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RIPEMD320
|
||||
int rmd320_init(hash_state * md);
|
||||
int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int rmd320_done(hash_state * md, unsigned char *hash);
|
||||
int rmd320_test(void);
|
||||
extern const struct ltc_hash_descriptor rmd320_desc;
|
||||
#endif
|
||||
|
||||
|
||||
int find_hash(const char *name);
|
||||
int find_hash_id(unsigned char ID);
|
||||
int find_hash_oid(const unsigned long *ID, unsigned long IDlen);
|
||||
int find_hash_any(const char *name, int digestlen);
|
||||
int register_hash(const struct ltc_hash_descriptor *hash);
|
||||
int unregister_hash(const struct ltc_hash_descriptor *hash);
|
||||
int hash_is_valid(int idx);
|
||||
|
||||
LTC_MUTEX_PROTO(ltc_hash_mutex)
|
||||
|
||||
int hash_memory(int hash,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
|
||||
int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen);
|
||||
|
||||
/* a simple macro for making hash "process" functions */
|
||||
#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
|
||||
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
|
||||
{ \
|
||||
unsigned long n; \
|
||||
int err; \
|
||||
LTC_ARGCHK(md != NULL); \
|
||||
LTC_ARGCHK(in != NULL); \
|
||||
if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
|
||||
return CRYPT_INVALID_ARG; \
|
||||
} \
|
||||
while (inlen > 0) { \
|
||||
if (md-> state_var .curlen == 0 && inlen >= block_size) { \
|
||||
if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
|
||||
return err; \
|
||||
} \
|
||||
md-> state_var .length += block_size * 8; \
|
||||
in += block_size; \
|
||||
inlen -= block_size; \
|
||||
} else { \
|
||||
n = MIN(inlen, (block_size - md-> state_var .curlen)); \
|
||||
memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
|
||||
md-> state_var .curlen += n; \
|
||||
in += n; \
|
||||
inlen -= n; \
|
||||
if (md-> state_var .curlen == block_size) { \
|
||||
if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
|
||||
return err; \
|
||||
} \
|
||||
md-> state_var .length += 8*block_size; \
|
||||
md-> state_var .curlen = 0; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
return CRYPT_OK; \
|
||||
}
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */
|
||||
/* $Revision: 1.22 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
384
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_mac.h
Normal file
384
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_mac.h
Normal file
@@ -0,0 +1,384 @@
|
||||
#ifdef LTC_HMAC
|
||||
typedef struct Hmac_state {
|
||||
hash_state md;
|
||||
int hash;
|
||||
hash_state hashstate;
|
||||
unsigned char *key;
|
||||
} hmac_state;
|
||||
|
||||
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
|
||||
int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen);
|
||||
int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen);
|
||||
int hmac_test(void);
|
||||
int hmac_memory(int hash,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int hmac_memory_multi(int hash,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
int hmac_file(int hash, const char *fname, const unsigned char *key,
|
||||
unsigned long keylen,
|
||||
unsigned char *dst, unsigned long *dstlen);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_OMAC
|
||||
|
||||
typedef struct {
|
||||
int cipher_idx,
|
||||
buflen,
|
||||
blklen;
|
||||
unsigned char block[MAXBLOCKSIZE],
|
||||
prev[MAXBLOCKSIZE],
|
||||
Lu[2][MAXBLOCKSIZE];
|
||||
symmetric_key key;
|
||||
} omac_state;
|
||||
|
||||
int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);
|
||||
int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen);
|
||||
int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen);
|
||||
int omac_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int omac_memory_multi(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
int omac_file(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const char *filename,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int omac_test(void);
|
||||
#endif /* LTC_OMAC */
|
||||
|
||||
#ifdef LTC_PMAC
|
||||
|
||||
typedef struct {
|
||||
unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
|
||||
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
|
||||
Lr[MAXBLOCKSIZE], /* L * x^-1 */
|
||||
block[MAXBLOCKSIZE], /* currently accumulated block */
|
||||
checksum[MAXBLOCKSIZE]; /* current checksum */
|
||||
|
||||
symmetric_key key; /* scheduled key for cipher */
|
||||
unsigned long block_index; /* index # for current block */
|
||||
int cipher_idx, /* cipher idx */
|
||||
block_len, /* length of block */
|
||||
buflen; /* number of bytes in the buffer */
|
||||
} pmac_state;
|
||||
|
||||
int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
|
||||
int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen);
|
||||
int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int pmac_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *msg, unsigned long msglen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int pmac_memory_multi(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
|
||||
int pmac_file(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const char *filename,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int pmac_test(void);
|
||||
|
||||
/* internal functions */
|
||||
int pmac_ntz(unsigned long x);
|
||||
void pmac_shift_xor(pmac_state *pmac);
|
||||
|
||||
#endif /* PMAC */
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
|
||||
#error LTC_EAX_MODE requires LTC_OMAC and CTR
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char N[MAXBLOCKSIZE];
|
||||
symmetric_CTR ctr;
|
||||
omac_state headeromac, ctomac;
|
||||
} eax_state;
|
||||
|
||||
int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen);
|
||||
|
||||
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
|
||||
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
|
||||
int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
|
||||
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
|
||||
|
||||
int eax_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen);
|
||||
|
||||
int eax_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
unsigned char *tag, unsigned long taglen,
|
||||
int *stat);
|
||||
|
||||
int eax_test(void);
|
||||
#endif /* EAX MODE */
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
typedef struct {
|
||||
unsigned char L[MAXBLOCKSIZE], /* L value */
|
||||
Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
|
||||
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
|
||||
Lr[MAXBLOCKSIZE], /* L * x^-1 */
|
||||
R[MAXBLOCKSIZE], /* R value */
|
||||
checksum[MAXBLOCKSIZE]; /* current checksum */
|
||||
|
||||
symmetric_key key; /* scheduled key for cipher */
|
||||
unsigned long block_index; /* index # for current block */
|
||||
int cipher, /* cipher idx */
|
||||
block_len; /* length of block */
|
||||
} ocb_state;
|
||||
|
||||
int ocb_init(ocb_state *ocb, int cipher,
|
||||
const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
|
||||
|
||||
int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
|
||||
int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
|
||||
|
||||
int ocb_done_encrypt(ocb_state *ocb,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen);
|
||||
|
||||
int ocb_done_decrypt(ocb_state *ocb,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen, int *stat);
|
||||
|
||||
int ocb_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen);
|
||||
|
||||
int ocb_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen,
|
||||
int *stat);
|
||||
|
||||
int ocb_test(void);
|
||||
|
||||
/* internal functions */
|
||||
void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
|
||||
int ocb_ntz(unsigned long x);
|
||||
int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
|
||||
|
||||
#endif /* LTC_OCB_MODE */
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
#define CCM_ENCRYPT 0
|
||||
#define CCM_DECRYPT 1
|
||||
|
||||
int ccm_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
int ccm_test(void);
|
||||
|
||||
#endif /* LTC_CCM_MODE */
|
||||
|
||||
#if defined(LRW_MODE) || defined(LTC_GCM_MODE)
|
||||
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
|
||||
#endif
|
||||
|
||||
|
||||
/* table shared between GCM and LRW */
|
||||
#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
|
||||
extern const unsigned char gcm_shift_table[];
|
||||
#endif
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
#define GCM_ENCRYPT 0
|
||||
#define GCM_DECRYPT 1
|
||||
|
||||
#define LTC_GCM_MODE_IV 0
|
||||
#define LTC_GCM_MODE_AAD 1
|
||||
#define LTC_GCM_MODE_TEXT 2
|
||||
|
||||
typedef struct {
|
||||
symmetric_key K;
|
||||
unsigned char H[16], /* multiplier */
|
||||
X[16], /* accumulator */
|
||||
Y[16], /* counter */
|
||||
Y_0[16], /* initial counter */
|
||||
buf[16]; /* buffer for stuff */
|
||||
|
||||
int cipher, /* which cipher */
|
||||
ivmode, /* Which mode is the IV in? */
|
||||
mode, /* mode the GCM code is in */
|
||||
buflen; /* length of data in buf */
|
||||
|
||||
ulong64 totlen, /* 64-bit counter used for IV and AAD */
|
||||
pttotlen; /* 64-bit counter for the PT */
|
||||
|
||||
#ifdef LTC_GCM_TABLES
|
||||
unsigned char PC[16][256][16] /* 16 tables of 8x128 */
|
||||
#ifdef LTC_GCM_TABLES_SSE2
|
||||
__attribute__ ((aligned (16)))
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
} gcm_state;
|
||||
|
||||
void gcm_mult_h(gcm_state *gcm, unsigned char *I);
|
||||
|
||||
int gcm_init(gcm_state *gcm, int cipher,
|
||||
const unsigned char *key, int keylen);
|
||||
|
||||
int gcm_reset(gcm_state *gcm);
|
||||
|
||||
int gcm_add_iv(gcm_state *gcm,
|
||||
const unsigned char *IV, unsigned long IVlen);
|
||||
|
||||
int gcm_add_aad(gcm_state *gcm,
|
||||
const unsigned char *adata, unsigned long adatalen);
|
||||
|
||||
int gcm_process(gcm_state *gcm,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
int direction);
|
||||
|
||||
int gcm_done(gcm_state *gcm,
|
||||
unsigned char *tag, unsigned long *taglen);
|
||||
|
||||
int gcm_memory( int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
int gcm_test(void);
|
||||
|
||||
#endif /* LTC_GCM_MODE */
|
||||
|
||||
#ifdef LTC_PELICAN
|
||||
|
||||
typedef struct pelican_state
|
||||
{
|
||||
symmetric_key K;
|
||||
unsigned char state[16];
|
||||
int buflen;
|
||||
} pelican_state;
|
||||
|
||||
int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
|
||||
int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
|
||||
int pelican_done(pelican_state *pelmac, unsigned char *out);
|
||||
int pelican_test(void);
|
||||
|
||||
int pelican_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LTC_XCBC
|
||||
|
||||
/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
|
||||
#define LTC_XCBC_PURE 0x8000UL
|
||||
|
||||
typedef struct {
|
||||
unsigned char K[3][MAXBLOCKSIZE],
|
||||
IV[MAXBLOCKSIZE];
|
||||
|
||||
symmetric_key key;
|
||||
|
||||
int cipher,
|
||||
buflen,
|
||||
blocksize;
|
||||
} xcbc_state;
|
||||
|
||||
int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
|
||||
int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
|
||||
int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
|
||||
int xcbc_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int xcbc_memory_multi(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
int xcbc_file(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const char *filename,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int xcbc_test(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LTC_F9_MODE
|
||||
|
||||
typedef struct {
|
||||
unsigned char akey[MAXBLOCKSIZE],
|
||||
ACC[MAXBLOCKSIZE],
|
||||
IV[MAXBLOCKSIZE];
|
||||
|
||||
symmetric_key key;
|
||||
|
||||
int cipher,
|
||||
buflen,
|
||||
keylen,
|
||||
blocksize;
|
||||
} f9_state;
|
||||
|
||||
int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
|
||||
int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
|
||||
int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
|
||||
int f9_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int f9_memory_multi(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...);
|
||||
int f9_file(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const char *filename,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int f9_test(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */
|
||||
/* $Revision: 1.23 $ */
|
||||
/* $Date: 2007/05/12 14:37:41 $ */
|
||||
424
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_macros.h
Normal file
424
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_macros.h
Normal file
@@ -0,0 +1,424 @@
|
||||
/* fix for MSVC ...evil! */
|
||||
#ifdef _MSC_VER
|
||||
#define CONST64(n) n ## ui64
|
||||
typedef unsigned __int64 ulong64;
|
||||
#else
|
||||
#define CONST64(n) n ## ULL
|
||||
typedef unsigned long long ulong64;
|
||||
#endif
|
||||
|
||||
/* this is the "32-bit at least" data type
|
||||
* Re-define it to suit your platform but it must be at least 32-bits
|
||||
*/
|
||||
#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
|
||||
typedef unsigned ulong32;
|
||||
#else
|
||||
typedef unsigned long ulong32;
|
||||
#endif
|
||||
|
||||
/* ---- HELPER MACROS ---- */
|
||||
#ifdef ENDIAN_NEUTRAL
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
|
||||
((unsigned long)((y)[2] & 255)<<16) | \
|
||||
((unsigned long)((y)[1] & 255)<<8) | \
|
||||
((unsigned long)((y)[0] & 255)); }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
|
||||
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#endif /* ENDIAN_NEUTRAL */
|
||||
|
||||
#ifdef ENDIAN_LITTLE
|
||||
|
||||
#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
asm __volatile__ ( \
|
||||
"bswapl %0 \n\t" \
|
||||
"movl %0,(%1)\n\t" \
|
||||
"bswapl %0 \n\t" \
|
||||
::"r"(x), "r"(y));
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
asm __volatile__ ( \
|
||||
"movl (%1),%0\n\t" \
|
||||
"bswapl %0\n\t" \
|
||||
:"=r"(x): "r"(y));
|
||||
|
||||
#else
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* x86_64 processor */
|
||||
#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
asm __volatile__ ( \
|
||||
"bswapq %0 \n\t" \
|
||||
"movq %0,(%1)\n\t" \
|
||||
"bswapq %0 \n\t" \
|
||||
::"r"(x), "r"(y));
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
asm __volatile__ ( \
|
||||
"movq (%1),%0\n\t" \
|
||||
"bswapq %0\n\t" \
|
||||
:"=r"(x): "r"(y));
|
||||
|
||||
#else
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
|
||||
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
XMEMCPY(&(x), y, 4);
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#else /* 64-bit words then */
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ XMEMCPY(&(x), y, 8); }
|
||||
|
||||
#endif /* ENDIAN_64BITWORD */
|
||||
|
||||
#endif /* ENDIAN_LITTLE */
|
||||
|
||||
#ifdef ENDIAN_BIG
|
||||
#define STORE32L(x, y) \
|
||||
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
|
||||
((unsigned long)((y)[2] & 255)<<16) | \
|
||||
((unsigned long)((y)[1] & 255)<<8) | \
|
||||
((unsigned long)((y)[0] & 255)); }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
XMEMCPY(&(x), y, 4);
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
|
||||
(((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#else /* 64-bit words then */
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ XMEMCPY(&(x), y, 8); }
|
||||
|
||||
#endif /* ENDIAN_64BITWORD */
|
||||
#endif /* ENDIAN_BIG */
|
||||
|
||||
#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
|
||||
((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
|
||||
|
||||
|
||||
/* 32-bit Rotates */
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/* instrinsic rotate */
|
||||
#include <stdlib.h>
|
||||
#pragma intrinsic(_lrotr,_lrotl)
|
||||
#define ROR(x,n) _lrotr(x,n)
|
||||
#define ROL(x,n) _lrotl(x,n)
|
||||
#define RORc(x,n) _lrotr(x,n)
|
||||
#define ROLc(x,n) _lrotl(x,n)
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
|
||||
|
||||
static inline unsigned ROL(unsigned word, int i)
|
||||
{
|
||||
asm ("roll %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned ROR(unsigned word, int i)
|
||||
{
|
||||
asm ("rorl %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#ifndef LTC_NO_ROLC
|
||||
|
||||
static inline unsigned ROLc(unsigned word, const int i)
|
||||
{
|
||||
asm ("roll %2,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned RORc(unsigned word, const int i)
|
||||
{
|
||||
asm ("rorl %2,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ROLc ROL
|
||||
#define RORc ROR
|
||||
|
||||
#endif
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
|
||||
|
||||
static inline unsigned ROL(unsigned word, int i)
|
||||
{
|
||||
asm ("rotlw %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"r" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned ROR(unsigned word, int i)
|
||||
{
|
||||
asm ("rotlw %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"r" (32-i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#ifndef LTC_NO_ROLC
|
||||
|
||||
static inline unsigned ROLc(unsigned word, const int i)
|
||||
{
|
||||
asm ("rotlwi %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned RORc(unsigned word, const int i)
|
||||
{
|
||||
asm ("rotrwi %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ROLc ROL
|
||||
#define RORc ROR
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* rotates the hard way */
|
||||
#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* 64-bit Rotates */
|
||||
#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
|
||||
|
||||
static inline unsigned long ROL64(unsigned long word, int i)
|
||||
{
|
||||
asm("rolq %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned long ROR64(unsigned long word, int i)
|
||||
{
|
||||
asm("rorq %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#ifndef LTC_NO_ROLC
|
||||
|
||||
static inline unsigned long ROL64c(unsigned long word, const int i)
|
||||
{
|
||||
asm("rolq %2,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"J" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned long ROR64c(unsigned long word, const int i)
|
||||
{
|
||||
asm("rorq %2,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"J" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#else /* LTC_NO_ROLC */
|
||||
|
||||
#define ROL64c ROL64
|
||||
#define ROR64c ROR64
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Not x86_64 */
|
||||
|
||||
#define ROL64(x, y) \
|
||||
( (((x)<<((ulong64)(y)&63)) | \
|
||||
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#define ROR64(x, y) \
|
||||
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
|
||||
((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#define ROL64c(x, y) \
|
||||
( (((x)<<((ulong64)(y)&63)) | \
|
||||
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#define ROR64c(x, y) \
|
||||
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
|
||||
((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) ( ((x)>(y))?(x):(y) )
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
|
||||
#endif
|
||||
|
||||
/* extract a byte portably */
|
||||
#ifdef _MSC_VER
|
||||
#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
|
||||
#else
|
||||
#define byte(x, n) (((x) >> (8 * (n))) & 255)
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */
|
||||
/* $Revision: 1.15 $ */
|
||||
/* $Date: 2006/11/29 23:43:57 $ */
|
||||
500
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_math.h
Normal file
500
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_math.h
Normal file
@@ -0,0 +1,500 @@
|
||||
/** math functions **/
|
||||
|
||||
#define LTC_MP_LT -1
|
||||
#define LTC_MP_EQ 0
|
||||
#define LTC_MP_GT 1
|
||||
|
||||
#define LTC_MP_NO 0
|
||||
#define LTC_MP_YES 1
|
||||
|
||||
#ifndef LTC_MECC
|
||||
typedef void ecc_point;
|
||||
#endif
|
||||
|
||||
#ifndef LTC_MRSA
|
||||
typedef void rsa_key;
|
||||
#endif
|
||||
|
||||
/** math descriptor */
|
||||
typedef struct {
|
||||
/** Name of the math provider */
|
||||
char *name;
|
||||
|
||||
/** Bits per digit, amount of bits must fit in an unsigned long */
|
||||
int bits_per_digit;
|
||||
|
||||
/* ---- init/deinit functions ---- */
|
||||
|
||||
/** initialize a bignum
|
||||
@param a The number to initialize
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*init)(void **a);
|
||||
|
||||
/** init copy
|
||||
@param dst The number to initialize and write to
|
||||
@param src The number to copy from
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*init_copy)(void **dst, void *src);
|
||||
|
||||
/** deinit
|
||||
@param a The number to free
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
void (*deinit)(void *a);
|
||||
|
||||
/* ---- data movement ---- */
|
||||
|
||||
/** negate
|
||||
@param src The number to negate
|
||||
@param dst The destination
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*neg)(void *src, void *dst);
|
||||
|
||||
/** copy
|
||||
@param src The number to copy from
|
||||
@param dst The number to write to
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*copy)(void *src, void *dst);
|
||||
|
||||
/* ---- trivial low level functions ---- */
|
||||
|
||||
/** set small constant
|
||||
@param a Number to write to
|
||||
@param n Source upto bits_per_digit (actually meant for very small constants)
|
||||
@return CRYPT_OK on succcess
|
||||
*/
|
||||
int (*set_int)(void *a, unsigned long n);
|
||||
|
||||
/** get small constant
|
||||
@param a Number to read, only fetches upto bits_per_digit from the number
|
||||
@return The lower bits_per_digit of the integer (unsigned)
|
||||
*/
|
||||
unsigned long (*get_int)(void *a);
|
||||
|
||||
/** get digit n
|
||||
@param a The number to read from
|
||||
@param n The number of the digit to fetch
|
||||
@return The bits_per_digit sized n'th digit of a
|
||||
*/
|
||||
unsigned long (*get_digit)(void *a, int n);
|
||||
|
||||
/** Get the number of digits that represent the number
|
||||
@param a The number to count
|
||||
@return The number of digits used to represent the number
|
||||
*/
|
||||
int (*get_digit_count)(void *a);
|
||||
|
||||
/** compare two integers
|
||||
@param a The left side integer
|
||||
@param b The right side integer
|
||||
@return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
|
||||
*/
|
||||
int (*compare)(void *a, void *b);
|
||||
|
||||
/** compare against int
|
||||
@param a The left side integer
|
||||
@param b The right side integer (upto bits_per_digit)
|
||||
@return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
|
||||
*/
|
||||
int (*compare_d)(void *a, unsigned long n);
|
||||
|
||||
/** Count the number of bits used to represent the integer
|
||||
@param a The integer to count
|
||||
@return The number of bits required to represent the integer
|
||||
*/
|
||||
int (*count_bits)(void * a);
|
||||
|
||||
/** Count the number of LSB bits which are zero
|
||||
@param a The integer to count
|
||||
@return The number of contiguous zero LSB bits
|
||||
*/
|
||||
int (*count_lsb_bits)(void *a);
|
||||
|
||||
/** Compute a power of two
|
||||
@param a The integer to store the power in
|
||||
@param n The power of two you want to store (a = 2^n)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*twoexpt)(void *a , int n);
|
||||
|
||||
/* ---- radix conversions ---- */
|
||||
|
||||
/** read ascii string
|
||||
@param a The integer to store into
|
||||
@param str The string to read
|
||||
@param radix The radix the integer has been represented in (2-64)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*read_radix)(void *a, const char *str, int radix);
|
||||
|
||||
/** write number to string
|
||||
@param a The integer to store
|
||||
@param str The destination for the string
|
||||
@param radix The radix the integer is to be represented in (2-64)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*write_radix)(void *a, char *str, int radix);
|
||||
|
||||
/** get size as unsigned char string
|
||||
@param a The integer to get the size (when stored in array of octets)
|
||||
@return The length of the integer
|
||||
*/
|
||||
unsigned long (*unsigned_size)(void *a);
|
||||
|
||||
/** store an integer as an array of octets
|
||||
@param src The integer to store
|
||||
@param dst The buffer to store the integer in
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*unsigned_write)(void *src, unsigned char *dst);
|
||||
|
||||
/** read an array of octets and store as integer
|
||||
@param dst The integer to load
|
||||
@param src The array of octets
|
||||
@param len The number of octets
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len);
|
||||
|
||||
/* ---- basic math ---- */
|
||||
|
||||
/** add two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer
|
||||
@param c The destination of "a + b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*add)(void *a, void *b, void *c);
|
||||
|
||||
|
||||
/** add two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer (single digit of upto bits_per_digit in length)
|
||||
@param c The destination of "a + b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*addi)(void *a, unsigned long b, void *c);
|
||||
|
||||
/** subtract two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer
|
||||
@param c The destination of "a - b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*sub)(void *a, void *b, void *c);
|
||||
|
||||
/** subtract two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer (single digit of upto bits_per_digit in length)
|
||||
@param c The destination of "a - b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*subi)(void *a, unsigned long b, void *c);
|
||||
|
||||
/** multiply two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer (single digit of upto bits_per_digit in length)
|
||||
@param c The destination of "a * b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*mul)(void *a, void *b, void *c);
|
||||
|
||||
/** multiply two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer (single digit of upto bits_per_digit in length)
|
||||
@param c The destination of "a * b"
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*muli)(void *a, unsigned long b, void *c);
|
||||
|
||||
/** Square an integer
|
||||
@param a The integer to square
|
||||
@param b The destination
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*sqr)(void *a, void *b);
|
||||
|
||||
/** Divide an integer
|
||||
@param a The dividend
|
||||
@param b The divisor
|
||||
@param c The quotient (can be NULL to signify don't care)
|
||||
@param d The remainder (can be NULL to signify don't care)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*mpdiv)(void *a, void *b, void *c, void *d);
|
||||
|
||||
/** divide by two
|
||||
@param a The integer to divide (shift right)
|
||||
@param b The destination
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*div_2)(void *a, void *b);
|
||||
|
||||
/** Get remainder (small value)
|
||||
@param a The integer to reduce
|
||||
@param b The modulus (upto bits_per_digit in length)
|
||||
@param c The destination for the residue
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*modi)(void *a, unsigned long b, unsigned long *c);
|
||||
|
||||
/** gcd
|
||||
@param a The first integer
|
||||
@param b The second integer
|
||||
@param c The destination for (a, b)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*gcd)(void *a, void *b, void *c);
|
||||
|
||||
/** lcm
|
||||
@param a The first integer
|
||||
@param b The second integer
|
||||
@param c The destination for [a, b]
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*lcm)(void *a, void *b, void *c);
|
||||
|
||||
/** Modular multiplication
|
||||
@param a The first source
|
||||
@param b The second source
|
||||
@param c The modulus
|
||||
@param d The destination (a*b mod c)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*mulmod)(void *a, void *b, void *c, void *d);
|
||||
|
||||
/** Modular squaring
|
||||
@param a The first source
|
||||
@param b The modulus
|
||||
@param c The destination (a*a mod b)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*sqrmod)(void *a, void *b, void *c);
|
||||
|
||||
/** Modular inversion
|
||||
@param a The value to invert
|
||||
@param b The modulus
|
||||
@param c The destination (1/a mod b)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*invmod)(void *, void *, void *);
|
||||
|
||||
/* ---- reduction ---- */
|
||||
|
||||
/** setup montgomery
|
||||
@param a The modulus
|
||||
@param b The destination for the reduction digit
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*montgomery_setup)(void *a, void **b);
|
||||
|
||||
/** get normalization value
|
||||
@param a The destination for the normalization value
|
||||
@param b The modulus
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*montgomery_normalization)(void *a, void *b);
|
||||
|
||||
/** reduce a number
|
||||
@param a The number [and dest] to reduce
|
||||
@param b The modulus
|
||||
@param c The value "b" from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*montgomery_reduce)(void *a, void *b, void *c);
|
||||
|
||||
/** clean up (frees memory)
|
||||
@param a The value "b" from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
void (*montgomery_deinit)(void *a);
|
||||
|
||||
/* ---- exponentiation ---- */
|
||||
|
||||
/** Modular exponentiation
|
||||
@param a The base integer
|
||||
@param b The power (can be negative) integer
|
||||
@param c The modulus integer
|
||||
@param d The destination
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*exptmod)(void *a, void *b, void *c, void *d);
|
||||
|
||||
/** Primality testing
|
||||
@param a The integer to test
|
||||
@param b The destination of the result (FP_YES if prime)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*isprime)(void *a, int *b);
|
||||
|
||||
/* ---- (optional) ecc point math ---- */
|
||||
|
||||
/** ECC GF(p) point multiplication (from the NIST curves)
|
||||
@param k The integer to multiply the point by
|
||||
@param G The point to multiply
|
||||
@param R The destination for kG
|
||||
@param modulus The modulus for the field
|
||||
@param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
|
||||
|
||||
/** ECC GF(p) point addition
|
||||
@param P The first point
|
||||
@param Q The second point
|
||||
@param R The destination of P + Q
|
||||
@param modulus The modulus
|
||||
@param mp The "b" value from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
|
||||
|
||||
/** ECC GF(p) point double
|
||||
@param P The first point
|
||||
@param R The destination of 2P
|
||||
@param modulus The modulus
|
||||
@param mp The "b" value from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
|
||||
|
||||
/** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
|
||||
@param P The point to map
|
||||
@param modulus The modulus
|
||||
@param mp The "b" value from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
@remark The mapping can be different but keep in mind a ecc_point only has three
|
||||
integers (x,y,z) so if you use a different mapping you have to make it fit.
|
||||
*/
|
||||
int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
|
||||
|
||||
/** Computes kA*A + kB*B = C using Shamir's Trick
|
||||
@param A First point to multiply
|
||||
@param kA What to multiple A by
|
||||
@param B Second point to multiply
|
||||
@param kB What to multiple B by
|
||||
@param C [out] Destination point (can overlap with A or B
|
||||
@param modulus Modulus for curve
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*ecc_mul2add)(ecc_point *A, void *kA,
|
||||
ecc_point *B, void *kB,
|
||||
ecc_point *C,
|
||||
void *modulus);
|
||||
|
||||
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
|
||||
|
||||
/** RSA Key Generation
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param size The size of the modulus (key size) desired (octets)
|
||||
@param e The "e" value (public key). e==65537 is a good choice
|
||||
@param key [out] Destination of a newly created private key pair
|
||||
@return CRYPT_OK if successful, upon error all allocated ram is freed
|
||||
*/
|
||||
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
|
||||
|
||||
|
||||
/** RSA exponentiation
|
||||
@param in The octet array representing the base
|
||||
@param inlen The length of the input
|
||||
@param out The destination (to be stored in an octet array format)
|
||||
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
|
||||
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
|
||||
@param key The RSA key to use
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*rsa_me)(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
rsa_key *key);
|
||||
} ltc_math_descriptor;
|
||||
|
||||
extern ltc_math_descriptor ltc_mp;
|
||||
|
||||
int ltc_init_multi(void **a, ...);
|
||||
void ltc_deinit_multi(void *a, ...);
|
||||
|
||||
#ifdef LTM_DESC
|
||||
extern const ltc_math_descriptor ltm_desc;
|
||||
#endif
|
||||
|
||||
#ifdef TFM_DESC
|
||||
extern const ltc_math_descriptor tfm_desc;
|
||||
#endif
|
||||
|
||||
#ifdef GMP_DESC
|
||||
extern const ltc_math_descriptor gmp_desc;
|
||||
#endif
|
||||
|
||||
#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
|
||||
|
||||
#define MP_DIGIT_BIT ltc_mp.bits_per_digit
|
||||
|
||||
/* some handy macros */
|
||||
#define mp_init(a) ltc_mp.init(a)
|
||||
#define mp_init_multi ltc_init_multi
|
||||
#define mp_clear(a) ltc_mp.deinit(a)
|
||||
#define mp_clear_multi ltc_deinit_multi
|
||||
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
|
||||
|
||||
#define mp_neg(a, b) ltc_mp.neg(a, b)
|
||||
#define mp_copy(a, b) ltc_mp.copy(a, b)
|
||||
|
||||
#define mp_set(a, b) ltc_mp.set_int(a, b)
|
||||
#define mp_set_int(a, b) ltc_mp.set_int(a, b)
|
||||
#define mp_get_int(a) ltc_mp.get_int(a)
|
||||
#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
|
||||
#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
|
||||
#define mp_cmp(a, b) ltc_mp.compare(a, b)
|
||||
#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
|
||||
#define mp_count_bits(a) ltc_mp.count_bits(a)
|
||||
#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
|
||||
#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
|
||||
|
||||
#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
|
||||
#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
|
||||
#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
|
||||
#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
|
||||
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
|
||||
|
||||
#define mp_add(a, b, c) ltc_mp.add(a, b, c)
|
||||
#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
|
||||
#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
|
||||
#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
|
||||
#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
|
||||
#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
|
||||
#define mp_sqr(a, b) ltc_mp.sqr(a, b)
|
||||
#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
|
||||
#define mp_div_2(a, b) ltc_mp.div_2(a, b)
|
||||
#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
|
||||
#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
|
||||
#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
|
||||
#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
|
||||
|
||||
#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
|
||||
#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
|
||||
#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
|
||||
|
||||
#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
|
||||
#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
|
||||
#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
|
||||
#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
|
||||
|
||||
#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
|
||||
#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c)
|
||||
|
||||
#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
|
||||
#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
|
||||
#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0);
|
||||
|
||||
#define mp_tohex(a, b) mp_toradix(a, b, 16)
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */
|
||||
/* $Revision: 1.44 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
23
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_misc.h
Normal file
23
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_misc.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* ---- LTC_BASE64 Routines ---- */
|
||||
#ifdef LTC_BASE64
|
||||
int base64_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int base64_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
/* ---- MEM routines ---- */
|
||||
void zeromem(void *dst, size_t len);
|
||||
void burn_stack(unsigned long len);
|
||||
|
||||
const char *error_to_string(int err);
|
||||
|
||||
extern const char *crypt_build_settings;
|
||||
|
||||
/* ---- HMM ---- */
|
||||
int crypt_fsa(void *mp, ...);
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */
|
||||
/* $Revision: 1.5 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
558
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pk.h
Normal file
558
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pk.h
Normal file
@@ -0,0 +1,558 @@
|
||||
/* ---- NUMBER THEORY ---- */
|
||||
|
||||
enum {
|
||||
PK_PUBLIC=0,
|
||||
PK_PRIVATE=1
|
||||
};
|
||||
|
||||
int rand_prime(void *N, long len, prng_state *prng, int wprng);
|
||||
|
||||
/* ---- RSA ---- */
|
||||
#ifdef LTC_MRSA
|
||||
|
||||
/* Min and Max RSA key sizes (in bits) */
|
||||
#define MIN_RSA_SIZE 1024
|
||||
#define MAX_RSA_SIZE 4096
|
||||
|
||||
/** RSA LTC_PKCS style key */
|
||||
typedef struct Rsa_key {
|
||||
/** Type of key, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
/** The public exponent */
|
||||
void *e;
|
||||
/** The private exponent */
|
||||
void *d;
|
||||
/** The modulus */
|
||||
void *N;
|
||||
/** The p factor of N */
|
||||
void *p;
|
||||
/** The q factor of N */
|
||||
void *q;
|
||||
/** The 1/q mod p CRT param */
|
||||
void *qP;
|
||||
/** The d mod (p - 1) CRT param */
|
||||
void *dP;
|
||||
/** The d mod (q - 1) CRT param */
|
||||
void *dQ;
|
||||
} rsa_key;
|
||||
|
||||
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
|
||||
|
||||
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
rsa_key *key);
|
||||
|
||||
void rsa_free(rsa_key *key);
|
||||
|
||||
/* These use LTC_PKCS #1 v2.0 padding */
|
||||
#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \
|
||||
rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key)
|
||||
|
||||
#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \
|
||||
rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key)
|
||||
|
||||
#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \
|
||||
rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key)
|
||||
|
||||
#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \
|
||||
rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key)
|
||||
|
||||
/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */
|
||||
int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key);
|
||||
|
||||
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
int hash_idx, int padding,
|
||||
int *stat, rsa_key *key);
|
||||
|
||||
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int padding,
|
||||
prng_state *prng, int prng_idx,
|
||||
int hash_idx, unsigned long saltlen,
|
||||
rsa_key *key);
|
||||
|
||||
int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int padding,
|
||||
int hash_idx, unsigned long saltlen,
|
||||
int *stat, rsa_key *key);
|
||||
|
||||
/* LTC_PKCS #1 import/export */
|
||||
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
|
||||
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
|
||||
|
||||
/* Ladik: Added for verifying Blizzard strong signature verification */
|
||||
int rsa_verify_simple(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat,
|
||||
rsa_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- Katja ---- */
|
||||
#ifdef MKAT
|
||||
|
||||
/* Min and Max KAT key sizes (in bits) */
|
||||
#define MIN_KAT_SIZE 1024
|
||||
#define MAX_KAT_SIZE 4096
|
||||
|
||||
/** Katja LTC_PKCS style key */
|
||||
typedef struct KAT_key {
|
||||
/** Type of key, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
/** The private exponent */
|
||||
void *d;
|
||||
/** The modulus */
|
||||
void *N;
|
||||
/** The p factor of N */
|
||||
void *p;
|
||||
/** The q factor of N */
|
||||
void *q;
|
||||
/** The 1/q mod p CRT param */
|
||||
void *qP;
|
||||
/** The d mod (p - 1) CRT param */
|
||||
void *dP;
|
||||
/** The d mod (q - 1) CRT param */
|
||||
void *dQ;
|
||||
/** The pq param */
|
||||
void *pq;
|
||||
} katja_key;
|
||||
|
||||
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
|
||||
|
||||
int katja_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
katja_key *key);
|
||||
|
||||
void katja_free(katja_key *key);
|
||||
|
||||
/* These use LTC_PKCS #1 v2.0 padding */
|
||||
int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
|
||||
|
||||
int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
int hash_idx, int *stat,
|
||||
katja_key *key);
|
||||
|
||||
/* LTC_PKCS #1 import/export */
|
||||
int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
|
||||
int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- ECC Routines ---- */
|
||||
#ifdef LTC_MECC
|
||||
|
||||
/* size of our temp buffers for exported keys */
|
||||
#define ECC_BUF_SIZE 256
|
||||
|
||||
/* max private key size */
|
||||
#define ECC_MAXSIZE 66
|
||||
|
||||
/** Structure defines a NIST GF(p) curve */
|
||||
typedef struct {
|
||||
/** The size of the curve in octets */
|
||||
int size;
|
||||
|
||||
/** name of curve */
|
||||
char *name;
|
||||
|
||||
/** The prime that defines the field the curve is in (encoded in hex) */
|
||||
char *prime;
|
||||
|
||||
/** The fields B param (hex) */
|
||||
char *B;
|
||||
|
||||
/** The order of the curve (hex) */
|
||||
char *order;
|
||||
|
||||
/** The x co-ordinate of the base point on the curve (hex) */
|
||||
char *Gx;
|
||||
|
||||
/** The y co-ordinate of the base point on the curve (hex) */
|
||||
char *Gy;
|
||||
} ltc_ecc_set_type;
|
||||
|
||||
/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
|
||||
typedef struct {
|
||||
/** The x co-ordinate */
|
||||
void *x;
|
||||
|
||||
/** The y co-ordinate */
|
||||
void *y;
|
||||
|
||||
/** The z co-ordinate */
|
||||
void *z;
|
||||
} ecc_point;
|
||||
|
||||
/** An ECC key */
|
||||
typedef struct {
|
||||
/** Type of key, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
|
||||
/** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
|
||||
int idx;
|
||||
|
||||
/** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
|
||||
const ltc_ecc_set_type *dp;
|
||||
|
||||
/** The public key */
|
||||
ecc_point pubkey;
|
||||
|
||||
/** The private key */
|
||||
void *k;
|
||||
} ecc_key;
|
||||
|
||||
/** the ECC params provided */
|
||||
extern const ltc_ecc_set_type ltc_ecc_sets[];
|
||||
|
||||
int ecc_test(void);
|
||||
void ecc_sizes(int *low, int *high);
|
||||
int ecc_get_size(ecc_key *key);
|
||||
|
||||
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
|
||||
int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
|
||||
void ecc_free(ecc_key *key);
|
||||
|
||||
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
|
||||
int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
|
||||
int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
|
||||
|
||||
int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
|
||||
int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
|
||||
int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
|
||||
|
||||
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key);
|
||||
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key);
|
||||
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key);
|
||||
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, ecc_key *key);
|
||||
|
||||
/* low level functions */
|
||||
ecc_point *ltc_ecc_new_point(void);
|
||||
void ltc_ecc_del_point(ecc_point *p);
|
||||
int ltc_ecc_is_valid_idx(int n);
|
||||
|
||||
/* point ops (mp == montgomery digit) */
|
||||
#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
|
||||
/* R = 2P */
|
||||
int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
|
||||
|
||||
/* R = P + Q */
|
||||
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
|
||||
#endif
|
||||
|
||||
#if defined(LTC_MECC_FP)
|
||||
/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
|
||||
int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
|
||||
|
||||
/* functions for saving/loading/freeing/adding to fixed point cache */
|
||||
int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
|
||||
int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
|
||||
void ltc_ecc_fp_free(void);
|
||||
int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
|
||||
|
||||
/* lock/unlock all points currently in fixed point cache */
|
||||
void ltc_ecc_fp_tablelock(int lock);
|
||||
#endif
|
||||
|
||||
/* R = kG */
|
||||
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
|
||||
|
||||
#ifdef LTC_ECC_SHAMIR
|
||||
/* kA*A + kB*B = C */
|
||||
int ltc_ecc_mul2add(ecc_point *A, void *kA,
|
||||
ecc_point *B, void *kB,
|
||||
ecc_point *C,
|
||||
void *modulus);
|
||||
|
||||
#ifdef LTC_MECC_FP
|
||||
/* Shamir's trick with optimized point multiplication using fixed point cache */
|
||||
int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
|
||||
ecc_point *B, void *kB,
|
||||
ecc_point *C, void *modulus);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* map P to affine from projective */
|
||||
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/* Max diff between group and modulus size in bytes */
|
||||
#define LTC_MDSA_DELTA 512
|
||||
|
||||
/* Max DSA group size in bytes (default allows 4k-bit groups) */
|
||||
#define LTC_MDSA_MAX_GROUP 512
|
||||
|
||||
/** DSA key structure */
|
||||
typedef struct {
|
||||
/** The key type, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
|
||||
/** The order of the sub-group used in octets */
|
||||
int qord;
|
||||
|
||||
/** The generator */
|
||||
void *g;
|
||||
|
||||
/** The prime used to generate the sub-group */
|
||||
void *q;
|
||||
|
||||
/** The large prime that generats the field the contains the sub-group */
|
||||
void *p;
|
||||
|
||||
/** The private key */
|
||||
void *x;
|
||||
|
||||
/** The public key */
|
||||
void *y;
|
||||
} dsa_key;
|
||||
|
||||
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
|
||||
void dsa_free(dsa_key *key);
|
||||
|
||||
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
|
||||
void *r, void *s,
|
||||
prng_state *prng, int wprng, dsa_key *key);
|
||||
|
||||
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dsa_key *key);
|
||||
|
||||
int dsa_verify_hash_raw( void *r, void *s,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dsa_key *key);
|
||||
|
||||
int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dsa_key *key);
|
||||
|
||||
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dsa_key *key);
|
||||
|
||||
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dsa_key *key);
|
||||
|
||||
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
|
||||
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
|
||||
int dsa_verify_key(dsa_key *key, int *stat);
|
||||
|
||||
int dsa_shared_secret(void *private_key, void *base,
|
||||
dsa_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_DER
|
||||
/* DER handling */
|
||||
|
||||
enum {
|
||||
LTC_ASN1_EOL,
|
||||
LTC_ASN1_BOOLEAN,
|
||||
LTC_ASN1_INTEGER,
|
||||
LTC_ASN1_SHORT_INTEGER,
|
||||
LTC_ASN1_BIT_STRING,
|
||||
LTC_ASN1_OCTET_STRING,
|
||||
LTC_ASN1_NULL,
|
||||
LTC_ASN1_OBJECT_IDENTIFIER,
|
||||
LTC_ASN1_IA5_STRING,
|
||||
LTC_ASN1_PRINTABLE_STRING,
|
||||
LTC_ASN1_UTF8_STRING,
|
||||
LTC_ASN1_UTCTIME,
|
||||
LTC_ASN1_CHOICE,
|
||||
LTC_ASN1_SEQUENCE,
|
||||
LTC_ASN1_SET,
|
||||
LTC_ASN1_SETOF
|
||||
};
|
||||
|
||||
/** A LTC ASN.1 list type */
|
||||
typedef struct ltc_asn1_list_ {
|
||||
/** The LTC ASN.1 enumerated type identifier */
|
||||
int type;
|
||||
/** The data to encode or place for decoding */
|
||||
void *data;
|
||||
/** The size of the input or resulting output */
|
||||
unsigned long size;
|
||||
/** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
|
||||
int used;
|
||||
/** prev/next entry in the list */
|
||||
struct ltc_asn1_list_ *prev, *next, *child, *parent;
|
||||
} ltc_asn1_list;
|
||||
|
||||
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
|
||||
do { \
|
||||
int LTC_MACRO_temp = (index); \
|
||||
ltc_asn1_list *LTC_MACRO_list = (list); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
|
||||
} while (0);
|
||||
|
||||
/* SEQUENCE */
|
||||
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int type_of);
|
||||
|
||||
#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
|
||||
|
||||
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||
ltc_asn1_list *list, unsigned long outlen, int ordered);
|
||||
|
||||
#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
|
||||
|
||||
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen);
|
||||
|
||||
/* SET */
|
||||
#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
|
||||
#define der_length_set der_length_sequence
|
||||
int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
/* VA list handy helpers with triplets of <type, size, data> */
|
||||
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
|
||||
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
|
||||
|
||||
/* FLEXI DECODER handle unknown list decoder */
|
||||
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
|
||||
void der_free_sequence_flexi(ltc_asn1_list *list);
|
||||
void der_sequence_free(ltc_asn1_list *in);
|
||||
|
||||
/* BOOLEAN */
|
||||
int der_length_boolean(unsigned long *outlen);
|
||||
int der_encode_boolean(int in,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_boolean(const unsigned char *in, unsigned long inlen,
|
||||
int *out);
|
||||
/* INTEGER */
|
||||
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
|
||||
int der_length_integer(void *num, unsigned long *len);
|
||||
|
||||
/* INTEGER -- handy for 0..2^32-1 values */
|
||||
int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
|
||||
int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
|
||||
int der_length_short_integer(unsigned long num, unsigned long *outlen);
|
||||
|
||||
/* BIT STRING */
|
||||
int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
|
||||
|
||||
/* OCTET STRING */
|
||||
int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
|
||||
|
||||
/* OBJECT IDENTIFIER */
|
||||
int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
|
||||
unsigned long *words, unsigned long *outlen);
|
||||
int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
|
||||
unsigned long der_object_identifier_bits(unsigned long x);
|
||||
|
||||
/* IA5 STRING */
|
||||
int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
|
||||
|
||||
int der_ia5_char_encode(int c);
|
||||
int der_ia5_value_decode(int v);
|
||||
|
||||
/* Printable STRING */
|
||||
int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
|
||||
|
||||
int der_printable_char_encode(int c);
|
||||
int der_printable_value_decode(int v);
|
||||
|
||||
/* UTF-8 */
|
||||
#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
|
||||
#include <wchar.h>
|
||||
#else
|
||||
typedef ulong32 wchar_t;
|
||||
#endif
|
||||
|
||||
int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
|
||||
wchar_t *out, unsigned long *outlen);
|
||||
unsigned long der_utf8_charsize(const wchar_t c);
|
||||
int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
|
||||
|
||||
|
||||
/* CHOICE */
|
||||
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_asn1_list *list, unsigned long outlen);
|
||||
|
||||
/* UTCTime */
|
||||
typedef struct {
|
||||
unsigned YY, /* year */
|
||||
MM, /* month */
|
||||
DD, /* day */
|
||||
hh, /* hour */
|
||||
mm, /* minute */
|
||||
ss, /* second */
|
||||
off_dir, /* timezone offset direction 0 == +, 1 == - */
|
||||
off_hh, /* timezone offset hours */
|
||||
off_mm; /* timezone offset minutes */
|
||||
} ltc_utctime;
|
||||
|
||||
int der_encode_utctime(ltc_utctime *utctime,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_utctime *out);
|
||||
|
||||
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */
|
||||
/* $Revision: 1.81 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
89
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
Normal file
89
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* LTC_PKCS Header Info */
|
||||
|
||||
/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */
|
||||
#ifdef LTC_PKCS_1
|
||||
|
||||
enum ltc_pkcs_1_v1_5_blocks
|
||||
{
|
||||
LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */
|
||||
LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */
|
||||
};
|
||||
|
||||
enum ltc_pkcs_1_paddings
|
||||
{
|
||||
LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */
|
||||
LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */
|
||||
LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */
|
||||
};
|
||||
|
||||
int pkcs_1_mgf1( int hash_idx,
|
||||
const unsigned char *seed, unsigned long seedlen,
|
||||
unsigned char *mask, unsigned long masklen);
|
||||
|
||||
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
|
||||
int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
|
||||
|
||||
/* *** v1.5 padding */
|
||||
int pkcs_1_v1_5_encode(const unsigned char *msg,
|
||||
unsigned long msglen,
|
||||
int block_type,
|
||||
unsigned long modulus_bitlen,
|
||||
prng_state *prng,
|
||||
int prng_idx,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen);
|
||||
|
||||
int pkcs_1_v1_5_decode(const unsigned char *msg,
|
||||
unsigned long msglen,
|
||||
int block_type,
|
||||
unsigned long modulus_bitlen,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen,
|
||||
int *is_valid);
|
||||
|
||||
/* *** v2.1 padding */
|
||||
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
unsigned long modulus_bitlen, prng_state *prng,
|
||||
int prng_idx, int hash_idx,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
unsigned long modulus_bitlen, int hash_idx,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int *res);
|
||||
|
||||
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
|
||||
unsigned long saltlen, prng_state *prng,
|
||||
int prng_idx, int hash_idx,
|
||||
unsigned long modulus_bitlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
|
||||
const unsigned char *sig, unsigned long siglen,
|
||||
unsigned long saltlen, int hash_idx,
|
||||
unsigned long modulus_bitlen, int *res);
|
||||
|
||||
#endif /* LTC_PKCS_1 */
|
||||
|
||||
/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */
|
||||
#ifdef LTC_PKCS_5
|
||||
|
||||
/* Algorithm #1 (old) */
|
||||
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
|
||||
const unsigned char *salt,
|
||||
int iteration_count, int hash_idx,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
/* Algorithm #2 (new) */
|
||||
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
|
||||
const unsigned char *salt, unsigned long salt_len,
|
||||
int iteration_count, int hash_idx,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#endif /* LTC_PKCS_5 */
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */
|
||||
/* $Revision: 1.8 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
199
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_prng.h
Normal file
199
dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_prng.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/* ---- PRNG Stuff ---- */
|
||||
#ifdef LTC_YARROW
|
||||
struct yarrow_prng {
|
||||
int cipher, hash;
|
||||
unsigned char pool[MAXBLOCKSIZE];
|
||||
symmetric_CTR ctr;
|
||||
LTC_MUTEX_TYPE(prng_lock)
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC4
|
||||
struct rc4_prng {
|
||||
int x, y;
|
||||
unsigned char buf[256];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_FORTUNA
|
||||
struct fortuna_prng {
|
||||
hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */
|
||||
|
||||
symmetric_key skey;
|
||||
|
||||
unsigned char K[32], /* the current key */
|
||||
IV[16]; /* IV for CTR mode */
|
||||
|
||||
unsigned long pool_idx, /* current pool we will add to */
|
||||
pool0_len, /* length of 0'th pool */
|
||||
wd;
|
||||
|
||||
ulong64 reset_cnt; /* number of times we have reset */
|
||||
LTC_MUTEX_TYPE(prng_lock)
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SOBER128
|
||||
struct sober128_prng {
|
||||
ulong32 R[17], /* Working storage for the shift register */
|
||||
initR[17], /* saved register contents */
|
||||
konst, /* key dependent constant */
|
||||
sbuf; /* partial word encryption buffer */
|
||||
|
||||
int nbuf, /* number of part-word stream bits buffered */
|
||||
flag, /* first add_entropy call or not? */
|
||||
set; /* did we call add_entropy to set key? */
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union Prng_state {
|
||||
char dummy[1];
|
||||
#ifdef LTC_YARROW
|
||||
struct yarrow_prng yarrow;
|
||||
#endif
|
||||
#ifdef LTC_RC4
|
||||
struct rc4_prng rc4;
|
||||
#endif
|
||||
#ifdef LTC_FORTUNA
|
||||
struct fortuna_prng fortuna;
|
||||
#endif
|
||||
#ifdef LTC_SOBER128
|
||||
struct sober128_prng sober128;
|
||||
#endif
|
||||
} prng_state;
|
||||
|
||||
/** PRNG descriptor */
|
||||
extern struct ltc_prng_descriptor {
|
||||
/** Name of the PRNG */
|
||||
char *name;
|
||||
/** size in bytes of exported state */
|
||||
int export_size;
|
||||
/** Start a PRNG state
|
||||
@param prng [out] The state to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*start)(prng_state *prng);
|
||||
/** Add entropy to the PRNG
|
||||
@param in The entropy
|
||||
@param inlen Length of the entropy (octets)\
|
||||
@param prng The PRNG state
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
/** Ready a PRNG state to read from
|
||||
@param prng The PRNG state to ready
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*ready)(prng_state *prng);
|
||||
/** Read from the PRNG
|
||||
@param out [out] Where to store the data
|
||||
@param outlen Length of data desired (octets)
|
||||
@param prng The PRNG state to read from
|
||||
@return Number of octets read
|
||||
*/
|
||||
unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
/** Terminate a PRNG state
|
||||
@param prng The PRNG state to terminate
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*done)(prng_state *prng);
|
||||
/** Export a PRNG state
|
||||
@param out [out] The destination for the state
|
||||
@param outlen [in/out] The max size and resulting size of the PRNG state
|
||||
@param prng The PRNG to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
/** Import a PRNG state
|
||||
@param in The data to import
|
||||
@param inlen The length of the data to import (octets)
|
||||
@param prng The PRNG to initialize/import
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
/** Self-test the PRNG
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
|
||||
*/
|
||||
int (*test)(void);
|
||||
} prng_descriptor[];
|
||||
|
||||
#ifdef LTC_YARROW
|
||||
int yarrow_start(prng_state *prng);
|
||||
int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int yarrow_ready(prng_state *prng);
|
||||
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
int yarrow_done(prng_state *prng);
|
||||
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int yarrow_test(void);
|
||||
extern const struct ltc_prng_descriptor yarrow_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_FORTUNA
|
||||
int fortuna_start(prng_state *prng);
|
||||
int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int fortuna_ready(prng_state *prng);
|
||||
unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
int fortuna_done(prng_state *prng);
|
||||
int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int fortuna_test(void);
|
||||
extern const struct ltc_prng_descriptor fortuna_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_RC4
|
||||
int rc4_start(prng_state *prng);
|
||||
int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int rc4_ready(prng_state *prng);
|
||||
unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
int rc4_done(prng_state *prng);
|
||||
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int rc4_test(void);
|
||||
extern const struct ltc_prng_descriptor rc4_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SPRNG
|
||||
int sprng_start(prng_state *prng);
|
||||
int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int sprng_ready(prng_state *prng);
|
||||
unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
int sprng_done(prng_state *prng);
|
||||
int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int sprng_test(void);
|
||||
extern const struct ltc_prng_descriptor sprng_desc;
|
||||
#endif
|
||||
|
||||
#ifdef LTC_SOBER128
|
||||
int sober128_start(prng_state *prng);
|
||||
int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int sober128_ready(prng_state *prng);
|
||||
unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
|
||||
int sober128_done(prng_state *prng);
|
||||
int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
|
||||
int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
|
||||
int sober128_test(void);
|
||||
extern const struct ltc_prng_descriptor sober128_desc;
|
||||
#endif
|
||||
|
||||
int find_prng(const char *name);
|
||||
int register_prng(const struct ltc_prng_descriptor *prng);
|
||||
int unregister_prng(const struct ltc_prng_descriptor *prng);
|
||||
int prng_is_valid(int idx);
|
||||
LTC_MUTEX_PROTO(ltc_prng_mutex)
|
||||
|
||||
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
|
||||
* might not work on all platforms as planned
|
||||
*/
|
||||
unsigned long rng_get_bytes(unsigned char *out,
|
||||
unsigned long outlen,
|
||||
void (*callback)(void));
|
||||
|
||||
int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */
|
||||
/* $Revision: 1.9 $ */
|
||||
/* $Date: 2007/05/12 14:32:35 $ */
|
||||
30
dep/CascLib/src/libtomcrypt/src/misc/crypt_argchk.c
Normal file
30
dep/CascLib/src/libtomcrypt/src/misc/crypt_argchk.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
#include <signal.h>
|
||||
|
||||
/**
|
||||
@file crypt_argchk.c
|
||||
Perform argument checking, Tom St Denis
|
||||
*/
|
||||
|
||||
#if (ARGTYPE == 0)
|
||||
void crypt_argchk(char *v, char *s, int d)
|
||||
{
|
||||
fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
|
||||
v, d, s);
|
||||
(void)raise(SIGABRT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */
|
||||
/* $Revision: 1.5 $ */
|
||||
/* $Date: 2006/12/28 01:27:24 $ */
|
||||
27
dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
Normal file
27
dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file crypt_hash_descriptor.c
|
||||
Stores the hash descriptor table, Tom St Denis
|
||||
*/
|
||||
|
||||
struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
|
||||
{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
LTC_MUTEX_GLOBAL(ltc_hash_mutex)
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */
|
||||
/* $Revision: 1.10 $ */
|
||||
/* $Date: 2006/12/28 01:27:24 $ */
|
||||
36
dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
Normal file
36
dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file crypt_hash_is_valid.c
|
||||
Determine if hash is valid, Tom St Denis
|
||||
*/
|
||||
|
||||
/*
|
||||
Test if a hash index is valid
|
||||
@param idx The index of the hash to search for
|
||||
@return CRYPT_OK if valid
|
||||
*/
|
||||
int hash_is_valid(int idx)
|
||||
{
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */
|
||||
/* $Revision: 1.6 $ */
|
||||
/* $Date: 2006/12/28 01:27:24 $ */
|
||||
43
dep/CascLib/src/libtomcrypt/src/misc/crypt_libc.c
Normal file
43
dep/CascLib/src/libtomcrypt/src/misc/crypt_libc.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************/
|
||||
/* crypt_libc.c Copyright (c) Ladislav Zezula 2010 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 05.05.10 1.00 Lad The first version of crypt_libc.c */
|
||||
/*****************************************************************************/
|
||||
|
||||
// LibTomCrypt header
|
||||
#include <stdlib.h>
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
void * LibTomMalloc(size_t n)
|
||||
{
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
void * LibTomCalloc(size_t n, size_t s)
|
||||
{
|
||||
return calloc(n, s);
|
||||
}
|
||||
|
||||
void * LibTomRealloc(void *p, size_t n)
|
||||
{
|
||||
return realloc(p, n);
|
||||
}
|
||||
|
||||
void LibTomFree(void * p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
clock_t LibTomClock(void)
|
||||
{
|
||||
return clock();
|
||||
}
|
||||
|
||||
void LibTomQsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
|
||||
{
|
||||
qsort(base, nmemb, size, compar);
|
||||
}
|
||||
Reference in New Issue
Block a user