mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-22 16:18:50 -05:00
Merge branch 'develop' into ShortBiggoron
This commit is contained in:
commit
45cb350b7a
@ -21,7 +21,7 @@
|
||||
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone git@github.com:HarbourMasters/ShipWright.git
|
||||
git clone https://github.com/HarbourMasters/Shipwright.git
|
||||
cd ShipWright
|
||||
# Copy the baserom to the OTRExporter folder
|
||||
cp <path to your ROM> OTRExporter
|
||||
|
212
Jenkinsfile
vendored
212
Jenkinsfile
vendored
@ -7,109 +7,119 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage ('Build Windows') {
|
||||
environment {
|
||||
MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe'
|
||||
CONFIG='Release'
|
||||
OTRPLATFORM='x64'
|
||||
PLATFORM='x86'
|
||||
ZIP='C:\\Program Files\\7-Zip\\7z.exe'
|
||||
PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe'
|
||||
CMAKE='C:\\Program Files\\CMake\\bin\\cmake.exe'
|
||||
TOOLSET='v142'
|
||||
}
|
||||
agent {
|
||||
label "SoH-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
bat """
|
||||
|
||||
"${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /restore /nodeReuse:false /m
|
||||
|
||||
xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\"
|
||||
|
||||
cd "OTRExporter"
|
||||
"${env.PYTHON}" ".\\extract_assets.py"
|
||||
cd "..\\"
|
||||
|
||||
"${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false /m
|
||||
|
||||
cd OTRGui
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
"${env.CMAKE}" ..
|
||||
"${env.CMAKE}" --build . --config Release
|
||||
|
||||
cd "..\\..\\"
|
||||
|
||||
move "soh\\Release\\soh.exe" ".\\"
|
||||
move "OTRGui\\build\\assets" ".\\"
|
||||
move ".\\OTRExporter\\x64\\Release\\ZAPD.exe" ".\\assets\\extractor\\"
|
||||
move ".\\OTRGui\\build\\Release\\OTRGui.exe" ".\\"
|
||||
rename README.md readme.txt
|
||||
|
||||
"${env.ZIP}" a soh.7z soh.exe OTRGui.exe assets readme.txt
|
||||
|
||||
"""
|
||||
archiveArtifacts artifacts: 'soh.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
stage('Build SoH') {
|
||||
parallel {
|
||||
stage ('Build Windows') {
|
||||
options {
|
||||
timeout(time: 20)
|
||||
}
|
||||
environment {
|
||||
MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe'
|
||||
CONFIG='Release'
|
||||
OTRPLATFORM='x64'
|
||||
PLATFORM='x86'
|
||||
ZIP='C:\\Program Files\\7-Zip\\7z.exe'
|
||||
PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe'
|
||||
CMAKE='C:\\Program Files\\CMake\\bin\\cmake.exe'
|
||||
TOOLSET='v142'
|
||||
}
|
||||
agent {
|
||||
label "SoH-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
bat """
|
||||
|
||||
"${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /restore /nodeReuse:false /m
|
||||
|
||||
xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\"
|
||||
|
||||
cd "OTRExporter"
|
||||
"${env.PYTHON}" ".\\extract_assets.py"
|
||||
cd "..\\"
|
||||
|
||||
"${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false /m
|
||||
|
||||
cd OTRGui
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
"${env.CMAKE}" ..
|
||||
"${env.CMAKE}" --build . --config Release
|
||||
|
||||
cd "..\\..\\"
|
||||
|
||||
move "soh\\Release\\soh.exe" ".\\"
|
||||
move "OTRGui\\build\\assets" ".\\"
|
||||
move ".\\OTRExporter\\x64\\Release\\ZAPD.exe" ".\\assets\\extractor\\"
|
||||
move ".\\OTRGui\\build\\Release\\OTRGui.exe" ".\\"
|
||||
rename README.md readme.txt
|
||||
|
||||
"${env.ZIP}" a soh.7z soh.exe OTRGui.exe assets readme.txt
|
||||
|
||||
"""
|
||||
archiveArtifacts artifacts: 'soh.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Build Linux') {
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
sh '''
|
||||
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
docker build . -t soh
|
||||
docker run --name sohcont -dit --rm -v $(pwd):/soh soh /bin/bash
|
||||
cp ../../buildsoh.bash soh
|
||||
docker exec sohcont soh/buildsoh.bash
|
||||
|
||||
mkdir build
|
||||
mv soh/soh.elf build/
|
||||
mv OTRGui/build/OTRGui build/
|
||||
mv OTRGui/build/assets build/
|
||||
mv ZAPDTR/ZAPD.out build/assets/extractor/
|
||||
mv README.md build/readme.txt
|
||||
cd build
|
||||
stage ('Build Linux') {
|
||||
options {
|
||||
timeout(time: 20)
|
||||
}
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
sh '''
|
||||
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
docker build . -t soh
|
||||
docker run --name sohcont -dit --rm -v $(pwd):/soh soh /bin/bash
|
||||
cp ../../buildsoh.bash soh
|
||||
docker exec sohcont soh/buildsoh.bash
|
||||
|
||||
mkdir build
|
||||
mv soh/soh.elf build/
|
||||
mv OTRGui/build/OTRGui build/
|
||||
mv OTRGui/build/assets build/
|
||||
mv ZAPDTR/ZAPD.out build/assets/extractor/
|
||||
mv README.md build/readme.txt
|
||||
cd build
|
||||
|
||||
7z a soh-linux.7z soh.elf OTRGui assets readme.txt
|
||||
mv soh-linux.7z ../
|
||||
|
||||
'''
|
||||
}
|
||||
sh 'sudo docker container stop sohcont'
|
||||
archiveArtifacts artifacts: 'soh-linux.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
7z a soh-linux.7z soh.elf OTRGui assets readme.txt
|
||||
mv soh-linux.7z ../
|
||||
|
||||
'''
|
||||
}
|
||||
sh 'sudo docker container stop sohcont'
|
||||
archiveArtifacts artifacts: 'soh-linux.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
OTRExporter/.gitignore
vendored
1
OTRExporter/.gitignore
vendored
@ -341,6 +341,7 @@ build/
|
||||
ZAPDUtils/build/
|
||||
ZAPD/BuildInfo.h
|
||||
baserom/
|
||||
baserom_ntsc/
|
||||
*.vtx.inc
|
||||
*.otr
|
||||
*.swp
|
||||
|
@ -11,6 +11,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "..\libultra
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055} = {78424708-1F6E-4D4B-920C-FB6D26847055}
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908} = {A2E01C3E-D647-45D1-9788-043DEBC1A908}
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306} = {A6103FD3-0709-4FC7-B066-1A6E056D6306}
|
||||
@ -18,6 +19,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "..\StormLib\StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -58,6 +61,14 @@ Global
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.ActiveCfg = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.Build.0 = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.ActiveCfg = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.Build.0 = ReleaseAS|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
192
OTRExporter/OTRExporter/AudioExporter.cpp
Normal file
192
OTRExporter/OTRExporter/AudioExporter.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include "AudioExporter.h"
|
||||
#include "Main.h"
|
||||
#include <Animation.h>
|
||||
#include <Utils/MemoryStream.h>
|
||||
#include <Globals.h>
|
||||
#include <Utils/File.h>
|
||||
#include "DisplayListExporter.h"
|
||||
|
||||
void OTRExporter_Audio::WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
||||
{
|
||||
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
||||
|
||||
if (entry != nullptr)
|
||||
{
|
||||
if (audio->sampleOffsets[entry->bankId].find(entry->sampleLoopOffset) != audio->sampleOffsets[entry->bankId].end())
|
||||
{
|
||||
if (audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].end())
|
||||
{
|
||||
writer->Write(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset][entry->sampleDataOffset].c_str()));
|
||||
}
|
||||
else
|
||||
writer->Write(entry->fileName);
|
||||
}
|
||||
else
|
||||
writer->Write(entry->fileName);
|
||||
}
|
||||
else
|
||||
writer->Write("");
|
||||
}
|
||||
|
||||
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer)
|
||||
{
|
||||
WriteHeader(nullptr, "", writer, Ship::ResourceType::AudioSample, Ship::Version::Rachael);
|
||||
|
||||
writer->Write(entry->codec);
|
||||
writer->Write(entry->medium);
|
||||
writer->Write(entry->unk_bit26);
|
||||
writer->Write(entry->unk_bit25);
|
||||
|
||||
writer->Write((uint32_t)entry->data.size());
|
||||
writer->Write((char*)entry->data.data(), entry->data.size());
|
||||
|
||||
writer->Write((uint32_t)(entry->loop.start));
|
||||
writer->Write((uint32_t)(entry->loop.end));
|
||||
writer->Write((uint32_t)(entry->loop.count));
|
||||
writer->Write((uint32_t)entry->loop.states.size());
|
||||
|
||||
for (size_t i = 0; i < entry->loop.states.size(); i++)
|
||||
writer->Write((entry->loop.states[i]));
|
||||
|
||||
writer->Write((uint32_t)(entry->book.order));
|
||||
writer->Write((uint32_t)(entry->book.npredictors));
|
||||
writer->Write((uint32_t)entry->book.books.size());
|
||||
|
||||
for (size_t i = 0; i < entry->book.books.size(); i++)
|
||||
writer->Write((entry->book.books[i]));
|
||||
}
|
||||
|
||||
void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer)
|
||||
{
|
||||
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
|
||||
|
||||
if (entry != nullptr)
|
||||
{
|
||||
WriteSampleEntryReference(audio, entry->sampleEntry, samples, writer);
|
||||
writer->Write(entry->tuning);
|
||||
}
|
||||
}
|
||||
|
||||
void OTRExporter_Audio::WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer)
|
||||
{
|
||||
writer->Write((uint32_t)envelopes.size());
|
||||
|
||||
for (auto env : envelopes)
|
||||
{
|
||||
writer->Write(env->delay);
|
||||
writer->Write(env->arg);
|
||||
}
|
||||
}
|
||||
|
||||
void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
|
||||
{
|
||||
ZAudio* audio = (ZAudio*)res;
|
||||
|
||||
WriteHeader(res, outPath, writer, Ship::ResourceType::Audio, Ship::Version::Rachael);
|
||||
|
||||
// Write Samples as individual files
|
||||
for (auto pair : audio->samples)
|
||||
{
|
||||
MemoryStream* sampleStream = new MemoryStream();
|
||||
BinaryWriter sampleWriter = BinaryWriter(sampleStream);
|
||||
|
||||
writer->Write((uint32_t)pair.first);
|
||||
WriteSampleEntry(pair.second, &sampleWriter);
|
||||
|
||||
std::string basePath = "";
|
||||
|
||||
if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleLoopOffset) != audio->sampleOffsets[pair.second->bankId].end())
|
||||
{
|
||||
if (audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].end())
|
||||
basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset][pair.second->sampleDataOffset].c_str());
|
||||
else
|
||||
basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first);
|
||||
}
|
||||
else
|
||||
basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first);
|
||||
|
||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath);
|
||||
AddFile(fName, sampleStream->ToVector());
|
||||
}
|
||||
|
||||
// Write the soundfont table
|
||||
for (size_t i = 0; i < audio->soundFontTable.size(); i++)
|
||||
{
|
||||
MemoryStream* fntStream = new MemoryStream();
|
||||
BinaryWriter fntWriter = BinaryWriter(fntStream);
|
||||
|
||||
WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont, Ship::Version::Rachael);
|
||||
|
||||
fntWriter.Write((uint32_t)i);
|
||||
fntWriter.Write(audio->soundFontTable[i].medium);
|
||||
fntWriter.Write(audio->soundFontTable[i].cachePolicy);
|
||||
fntWriter.Write(audio->soundFontTable[i].data1);
|
||||
fntWriter.Write(audio->soundFontTable[i].data2);
|
||||
fntWriter.Write(audio->soundFontTable[i].data3);
|
||||
|
||||
fntWriter.Write((uint32_t)audio->soundFontTable[i].drums.size());
|
||||
fntWriter.Write((uint32_t)audio->soundFontTable[i].instruments.size());
|
||||
fntWriter.Write((uint32_t)audio->soundFontTable[i].soundEffects.size());
|
||||
|
||||
for (size_t k = 0; k < audio->soundFontTable[i].drums.size(); k++)
|
||||
{
|
||||
fntWriter.Write(audio->soundFontTable[i].drums[k].releaseRate);
|
||||
fntWriter.Write(audio->soundFontTable[i].drums[k].pan);
|
||||
fntWriter.Write(audio->soundFontTable[i].drums[k].loaded);
|
||||
|
||||
WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter);
|
||||
|
||||
WriteSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample, audio->samples, &fntWriter);
|
||||
fntWriter.Write(audio->soundFontTable[i].drums[k].tuning);
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++)
|
||||
{
|
||||
fntWriter.Write((uint8_t)audio->soundFontTable[i].instruments[k].isValidInstrument);
|
||||
|
||||
fntWriter.Write(audio->soundFontTable[i].instruments[k].loaded);
|
||||
fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeLo);
|
||||
fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeHi);
|
||||
fntWriter.Write(audio->soundFontTable[i].instruments[k].releaseRate);
|
||||
|
||||
WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter);
|
||||
|
||||
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, &fntWriter);
|
||||
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, &fntWriter);
|
||||
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, audio->samples, &fntWriter);
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++)
|
||||
{
|
||||
WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter);
|
||||
}
|
||||
|
||||
//std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/font_%02X", i));
|
||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str()));
|
||||
AddFile(fName, fntStream->ToVector());
|
||||
}
|
||||
|
||||
// Write Sequences
|
||||
for (size_t i = 0; i < audio->sequences.size(); i++)
|
||||
{
|
||||
auto seq = audio->sequences[i];
|
||||
|
||||
MemoryStream* seqStream = new MemoryStream();
|
||||
BinaryWriter seqWriter = BinaryWriter(seqStream);
|
||||
|
||||
WriteHeader(nullptr, "", &seqWriter, Ship::ResourceType::AudioSequence, Ship::Version::Rachael);
|
||||
|
||||
seqWriter.Write((uint32_t)seq.size());
|
||||
seqWriter.Write(seq.data(), seq.size());
|
||||
seqWriter.Write((uint8_t)i);
|
||||
seqWriter.Write((uint8_t)audio->sequenceTable[i].medium);
|
||||
seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy);
|
||||
seqWriter.Write((uint32_t)audio->fontIndices[i].size());
|
||||
|
||||
for (size_t k = 0; k < audio->fontIndices[i].size(); k++)
|
||||
seqWriter.Write((uint8_t)audio->fontIndices[i][k]);
|
||||
|
||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str()));
|
||||
AddFile(fName, seqStream->ToVector());
|
||||
}
|
||||
}
|
16
OTRExporter/OTRExporter/AudioExporter.h
Normal file
16
OTRExporter/OTRExporter/AudioExporter.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZResource.h"
|
||||
#include "ZAudio.h"
|
||||
#include "Exporter.h"
|
||||
#include <Utils/BinaryWriter.h>
|
||||
|
||||
class OTRExporter_Audio : public OTRExporter
|
||||
{
|
||||
public:
|
||||
void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer);
|
||||
void WriteSampleEntryReference(ZAudio* audio, SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
||||
void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer);
|
||||
void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer);
|
||||
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||
};
|
@ -362,18 +362,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||
BinaryWriter dlWriter = BinaryWriter(dlStream);
|
||||
|
||||
Save(dList->otherDLists[i], outPath, &dlWriter);
|
||||
|
||||
#ifdef _DEBUG
|
||||
//if (otrArchive->HasFile(fName))
|
||||
//otrArchive->RemoveFile(fName);
|
||||
#endif
|
||||
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
|
||||
else
|
||||
files[fName] = dlStream->ToVector();
|
||||
|
||||
//otrArchive->AddFile(fName, (uintptr_t)dlStream->ToVector().data(), dlWriter.GetBaseAddress());
|
||||
AddFile(fName, dlStream->ToVector());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -460,10 +449,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||
|
||||
Save(dList->otherDLists[i], outPath, &dlWriter);
|
||||
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
|
||||
else
|
||||
files[fName] = dlStream->ToVector();
|
||||
AddFile(fName, dlStream->ToVector());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -827,10 +813,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||
}
|
||||
}
|
||||
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + fName, vtxStream->ToVector());
|
||||
else
|
||||
files[fName] = vtxStream->ToVector();
|
||||
AddFile(fName, vtxStream->ToVector());
|
||||
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "Exporter.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType)
|
||||
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion)
|
||||
{
|
||||
writer->Write((uint8_t)Endianess::Little); // 0x00
|
||||
writer->Write((uint8_t)0); // 0x01
|
||||
@ -9,7 +9,8 @@ void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWri
|
||||
writer->Write((uint8_t)0); // 0x03
|
||||
|
||||
writer->Write((uint32_t)resType); // 0x04
|
||||
writer->Write((uint32_t)MAJOR_VERSION); // 0x08
|
||||
//writer->Write((uint32_t)MAJOR_VERSION); // 0x08
|
||||
writer->Write((uint32_t)resVersion); // 0x08
|
||||
writer->Write((uint64_t)0xDEADBEEFDEADBEEF); // id, 0x0C
|
||||
writer->Write((uint32_t)resourceVersions[resType]); // 0x10
|
||||
writer->Write((uint64_t)0); // ROM CRC, 0x14
|
||||
|
@ -4,9 +4,10 @@
|
||||
//#include "OTRExporter.h"
|
||||
#include <Utils/BinaryWriter.h>
|
||||
#include <Resource.h>
|
||||
#include "VersionInfo.h"
|
||||
|
||||
class OTRExporter : public ZResourceExporter
|
||||
{
|
||||
protected:
|
||||
static void WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType);
|
||||
static void WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion = MAJOR_VERSION);
|
||||
};
|
@ -15,6 +15,7 @@
|
||||
#include "TextExporter.h"
|
||||
#include "BlobExporter.h"
|
||||
#include "MtxExporter.h"
|
||||
#include "AudioExporter.h"
|
||||
#include <Globals.h>
|
||||
#include <Utils/File.h>
|
||||
#include <Utils/Directory.h>
|
||||
@ -26,6 +27,7 @@ std::shared_ptr<Ship::Archive> otrArchive;
|
||||
BinaryWriter* fileWriter;
|
||||
std::chrono::steady_clock::time_point fileStart, resStart;
|
||||
std::map<std::string, std::vector<char>> files;
|
||||
std::mutex fileMutex;
|
||||
|
||||
void InitVersionInfo();
|
||||
|
||||
@ -45,7 +47,7 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM
|
||||
if (File::Exists(otrFileName))
|
||||
otrArchive = std::shared_ptr<Ship::Archive>(new Ship::Archive(otrFileName, true));
|
||||
else
|
||||
otrArchive = Ship::Archive::CreateArchive(otrFileName, 65536 / 2);
|
||||
otrArchive = Ship::Archive::CreateArchive(otrFileName, 40000);
|
||||
|
||||
auto lst = Directory::ListFiles("Extract");
|
||||
|
||||
@ -62,7 +64,7 @@ static void ExporterProgramEnd()
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
printf("Generating OTR Archive...\n");
|
||||
otrArchive = Ship::Archive::CreateArchive(otrFileName, 65536 / 2);
|
||||
otrArchive = Ship::Archive::CreateArchive(otrFileName, 40000);
|
||||
|
||||
for (auto item : files)
|
||||
{
|
||||
@ -79,9 +81,9 @@ static void ExporterProgramEnd()
|
||||
otrArchive->AddFile(StringHelper::Split(item, "Extract/")[1], (uintptr_t)fileData.data(), fileData.size());
|
||||
}
|
||||
|
||||
otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size());
|
||||
otrArchive->AddFile("Audioseq", (uintptr_t)Globals::Instance->GetBaseromFile("Audioseq").data(), Globals::Instance->GetBaseromFile("Audioseq").size());
|
||||
otrArchive->AddFile("Audiotable", (uintptr_t)Globals::Instance->GetBaseromFile("Audiotable").data(), Globals::Instance->GetBaseromFile("Audiotable").size());
|
||||
//otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size());
|
||||
//otrArchive->AddFile("Audioseq", (uintptr_t)Globals::Instance->GetBaseromFile("Audioseq").data(), Globals::Instance->GetBaseromFile("Audioseq").size());
|
||||
//otrArchive->AddFile("Audiotable", (uintptr_t)Globals::Instance->GetBaseromFile("Audiotable").data(), Globals::Instance->GetBaseromFile("Audiotable").size());
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +160,10 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
|
||||
fName = StringHelper::Sprintf("%s/%s", oName.c_str(), rName.c_str());
|
||||
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
std::unique_lock Lock(fileMutex);
|
||||
files[fName] = strem->ToVector();
|
||||
}
|
||||
else
|
||||
File::WriteAllBytes("Extract/" + fName, strem->ToVector());
|
||||
}
|
||||
@ -178,6 +183,17 @@ static void ExporterXMLEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void AddFile(std::string fName, std::vector<char> data)
|
||||
{
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + fName, data);
|
||||
else
|
||||
{
|
||||
std::unique_lock Lock(fileMutex);
|
||||
files[fName] = data;
|
||||
}
|
||||
}
|
||||
|
||||
static void ImportExporters()
|
||||
{
|
||||
// In this example we set up a new exporter called "EXAMPLE".
|
||||
@ -211,6 +227,7 @@ static void ImportExporters()
|
||||
exporterSet->exporters[ZResourceType::Text] = new OTRExporter_Text();
|
||||
exporterSet->exporters[ZResourceType::Blob] = new OTRExporter_Blob();
|
||||
exporterSet->exporters[ZResourceType::Mtx] = new OTRExporter_MtxExporter();
|
||||
exporterSet->exporters[ZResourceType::Audio] = new OTRExporter_Audio();
|
||||
|
||||
Globals::AddExporter("OTR", exporterSet);
|
||||
|
||||
|
@ -3,4 +3,6 @@
|
||||
#include <Archive.h>
|
||||
|
||||
extern std::shared_ptr<Ship::Archive> otrArchive;
|
||||
extern std::map<std::string, std::vector<char>> files;
|
||||
extern std::map<std::string, std::vector<char>> files;
|
||||
|
||||
void AddFile(std::string fName, std::vector<char> data);
|
@ -46,6 +46,7 @@ INC_DIRS := $(addprefix -I, \
|
||||
../../libultraship/libultraship \
|
||||
../../libultraship/libultraship/Lib/spdlog/include \
|
||||
../../libultraship/libultraship/Lib/Fast3D/U64 \
|
||||
../../StormLib/src \
|
||||
)
|
||||
|
||||
# create build directories
|
||||
|
@ -20,6 +20,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ArrayExporter.h" />
|
||||
<ClInclude Include="AudioExporter.h" />
|
||||
<ClInclude Include="BackgroundExporter.h" />
|
||||
<ClInclude Include="BlobExporter.h" />
|
||||
<ClInclude Include="CollisionExporter.h" />
|
||||
@ -44,6 +45,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ArrayExporter.cpp" />
|
||||
<ClCompile Include="AudioExporter.cpp" />
|
||||
<ClCompile Include="BackgroundExporter.cpp" />
|
||||
<ClCompile Include="BlobExporter.cpp" />
|
||||
<ClCompile Include="CollisionExporter.cpp" />
|
||||
@ -136,7 +138,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath)</LibraryPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
@ -144,7 +146,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath)</LibraryPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
|
@ -81,6 +81,9 @@
|
||||
<ClInclude Include="VersionInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AudioExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CollisionExporter.cpp">
|
||||
@ -140,5 +143,8 @@
|
||||
<ClCompile Include="VersionInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AudioExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -453,13 +453,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||
OTRExporter_Cutscene cs;
|
||||
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter);
|
||||
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + fName, csStream->ToVector());
|
||||
else
|
||||
files[fName] = csStream->ToVector();
|
||||
|
||||
//std::string fName = OTRExporter_DisplayList::GetPathToRes(res, vtxDecl->varName);
|
||||
//otrArchive->AddFile(fName, (uintptr_t)csStream->ToVector().data(), csWriter.GetBaseAddress());
|
||||
AddFile(fName, csStream->ToVector());
|
||||
}
|
||||
break;
|
||||
case RoomCommand::SetPathways:
|
||||
@ -480,14 +474,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||
OTRExporter_Path pathExp;
|
||||
pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter);
|
||||
|
||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||
File::WriteAllBytes("Extract/" + path, pathStream->ToVector());
|
||||
else
|
||||
files[path] = pathStream->ToVector();
|
||||
|
||||
//otrArchive->AddFile(path, (uintptr_t)pathStream->ToVector().data(), pathWriter.GetBaseAddress());
|
||||
|
||||
int bp = 0;
|
||||
AddFile(path, pathStream->ToVector());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
23
README.md
23
README.md
@ -48,7 +48,22 @@ If you still cannot get the tool to work, join our [Discord Server](https://disc
|
||||
|
||||
Launch the game. If the window immediately closes, or if there are visual artifacts, you may have selected the wrong rom in the OTRGui tool.
|
||||
|
||||
Currently, DirectX 11 and OpenGL is supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
|
||||
Default keyboard configuration:
|
||||
| N64 | A | B | Z | Start | Analog stick | C buttons | D-Pad |
|
||||
| - | - | - | - | - | - | - | - |
|
||||
| Keyboard | X | C | Z | Space | WASD | Arrow keys | TFGH |
|
||||
|
||||
Other shortcuts:
|
||||
| Keys | Action |
|
||||
| - | - |
|
||||
| F1 | Toggle menubar |
|
||||
| F5 | Save state |
|
||||
| F6 | Change state |
|
||||
| F7 | Load state |
|
||||
| F10 | Fullscreen (OpenGL) |
|
||||
| Alt+Enter | Fullscreen (DirectX) |
|
||||
|
||||
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
|
||||
|
||||
## Take The Survey
|
||||
Want to use cartridge readers in tandem with the OTRGui?
|
||||
@ -63,8 +78,8 @@ Official Discord: https://discord.com/invite/BtBmd55HVH
|
||||
Refer to the [building instructions](BUILDING.md) to compile SoH.
|
||||
|
||||
## Troubleshooting The Exporter
|
||||
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
|
||||
- Affirm that `zapd.exe` exists in the `/assets/extractor` folder
|
||||
- Confirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
|
||||
- Confirm that `zapd.exe` exists in the `/assets/extractor` folder
|
||||
|
||||
## Nightly Builds
|
||||
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
|
||||
@ -108,7 +123,7 @@ Nightly builds of Ship of Harkinian are available [here](https://builds.shipofha
|
||||
## Video Credits
|
||||
Kenix | Producer / Writer
|
||||
rainbow_fash | Executive Producer
|
||||
TheLegendOfXela | Editor
|
||||
ReveriePass | Editor
|
||||
MicTheMicrophone | Gwonam / The King
|
||||
Amphibibro | Link
|
||||
AceHeart | Zelda
|
||||
|
167
StormLib/.gitignore
vendored
Normal file
167
StormLib/.gitignore
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
*.o
|
||||
*.dylib
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
**/project.xcworkspace
|
||||
**/xcuserdata
|
22
StormLib/Info.plist
Normal file
22
StormLib/Info.plist
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.zezula.${PRODUCT_NAME:rfc1034Identifier}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>8.01</string>
|
||||
</dict>
|
||||
</plist>
|
21
StormLib/LICENSE
Normal file
21
StormLib/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 1999-2013 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.
|
34
StormLib/PostBuild.bat
Normal file
34
StormLib/PostBuild.bat
Normal file
@ -0,0 +1,34 @@
|
||||
@echo off
|
||||
rem Post-build batch for StormLib project
|
||||
rem Called as PostBuild.bat $(ProjectName) $(PlatformName) $(ConfigurationName) [vs2008]
|
||||
rem Example: PostBuild.bat StormLib_dll x64 Debug vs2008
|
||||
|
||||
rem Select build type
|
||||
if "%1" == "StormLib_dll" goto PostBuild_DLL
|
||||
if "%1" == "StormLib" goto PostBuild_LIB
|
||||
goto:eof
|
||||
|
||||
:PostBuild_DLL
|
||||
|
||||
rem Build steps for the DLL. On 32-bit Release version, increment the build number
|
||||
if not "x%2" == "xWin32" goto:eof
|
||||
if not "x%3" == "xRelease" goto:eof
|
||||
PostBuild.exe .\src\DllMain.rc
|
||||
goto:eof
|
||||
|
||||
:PostBuild_LIB
|
||||
|
||||
rem Set target folders
|
||||
if "x%2" == "xWin32" set TARGET_DIR_LEVEL2=lib32
|
||||
if "x%2" == "xx64" set TARGET_DIR_LEVEL2=lib64
|
||||
if "x%4" == "xvs2008" set TARGET_DIR_LEVEL3=vs2008
|
||||
|
||||
rem Check & create target folder structure
|
||||
if not exist ..\aaa goto:eof
|
||||
if not exist ..\aaa\%TARGET_DIR_LEVEL2% md ..\aaa\%TARGET_DIR_LEVEL2%
|
||||
if not exist ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3% md ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3%
|
||||
|
||||
rem Copy include and LIB files to the target folder
|
||||
copy /Y .\src\StormLib.h ..\aaa\inc >nul
|
||||
copy /Y .\src\StormPort.h ..\aaa\inc >nul
|
||||
copy /Y .\bin\%1\%2\%3\StormLib???.lib ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3% >nul
|
132
StormLib/Premake5.lua
Normal file
132
StormLib/Premake5.lua
Normal file
@ -0,0 +1,132 @@
|
||||
|
||||
solution 'StormLib'
|
||||
location 'build'
|
||||
language 'C++'
|
||||
configurations { 'Debug', 'Release', }
|
||||
platforms { 'x32', 'x64' }
|
||||
|
||||
targetdir 'bin'
|
||||
objdir 'bin'
|
||||
|
||||
files {
|
||||
'src/**.h',
|
||||
'src/**.c',
|
||||
'src/**.cpp',
|
||||
'doc/*.txt',
|
||||
}
|
||||
|
||||
removefiles {
|
||||
'src/adpcm/*_old.*',
|
||||
'src/huffman/*_old.*',
|
||||
'src/huffman/huff_patch.*',
|
||||
'src/pklib/crc32.c',
|
||||
'src/zlib/compress.c',
|
||||
}
|
||||
|
||||
filter 'configurations:Debug*'
|
||||
flags { 'Symbols' }
|
||||
defines { '_DEBUG' }
|
||||
optimize 'Debug'
|
||||
|
||||
filter 'configurations:Release*'
|
||||
defines { 'NDEBUG' }
|
||||
optimize 'Full'
|
||||
|
||||
filter 'system:windows'
|
||||
links { 'wininet', }
|
||||
defines { 'WINDOWS', '_WINDOWS' }
|
||||
|
||||
filter { 'system:windows', 'platforms:x32' }
|
||||
defines { 'WIN32', '_WIN32' }
|
||||
|
||||
filter { 'system:windows', 'platforms:x64' }
|
||||
defines { 'WIN64', '_WIN64' }
|
||||
|
||||
filter 'system:linux'
|
||||
defines { '_7ZIP_ST', 'BZ_STRICT_ANSI' }
|
||||
removefiles {
|
||||
'src/lzma/C/LzFindMt.*',
|
||||
'src/lzma/C/Threads.*',
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
project 'StormLib'
|
||||
kind 'StaticLib'
|
||||
|
||||
removefiles 'src/SBaseDumpData.cpp'
|
||||
|
||||
configurations {
|
||||
'DebugAD', -- Debug Ansi Dynamic
|
||||
'DebugAS', -- Debug Ansi Static
|
||||
'DebugUD', -- Debug Unicode Dynamic
|
||||
'DebugUS', -- Debug Unicode Static
|
||||
'ReleaseAD', -- Release Ansi Dynamic
|
||||
'ReleaseAS', -- Release Ansi Static
|
||||
'ReleaseUD', -- Release Unicode Dynamic'
|
||||
'ReleaseUS', -- Release Unicode Static
|
||||
}
|
||||
|
||||
configmap {
|
||||
['Debug'] = 'DebugUS',
|
||||
['Release'] = 'ReleaseUS',
|
||||
}
|
||||
|
||||
filter 'configurations:*S'
|
||||
flags { 'StaticRuntime' }
|
||||
|
||||
filter { 'configurations:*U*', 'action:vs*' }
|
||||
flags { 'Unicode' }
|
||||
|
||||
filter { 'configurations:*U*', 'not action:vs*' }
|
||||
defines { 'UNICODE', '_UNICODE' }
|
||||
|
||||
filter 'DebugAD'
|
||||
targetsuffix 'DAD'
|
||||
filter 'ReleaseAD'
|
||||
targetsuffix 'RAD'
|
||||
filter 'DebugAS'
|
||||
targetsuffix 'DAS'
|
||||
filter 'ReleaseAS'
|
||||
targetsuffix 'RAS'
|
||||
filter 'DebugUD'
|
||||
targetsuffix 'DUD'
|
||||
filter 'ReleaseUD'
|
||||
targetsuffix 'RUD'
|
||||
filter 'DebugUS'
|
||||
targetsuffix 'DUS'
|
||||
filter 'ReleaseUS'
|
||||
targetsuffix 'RUS'
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
project 'StormLib_dll'
|
||||
kind 'SharedLib'
|
||||
|
||||
targetname 'Stormlib'
|
||||
|
||||
files {
|
||||
'stormlib_dll/DllMain.c',
|
||||
'stormlib_dll/StormLib.def',
|
||||
}
|
||||
|
||||
removefiles 'src/SBaseDumpData.cpp'
|
||||
|
||||
filter { 'system:windows', 'action:gmake' }
|
||||
linkoptions {
|
||||
'-Xlinker --enable-stdcall-fixup',
|
||||
'../stormlib_dll/StormLib.def',
|
||||
}
|
||||
|
||||
filter 'Debug'
|
||||
targetsuffix '_d'
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
project 'StormLib_test'
|
||||
kind 'ConsoleApp'
|
||||
|
||||
files {
|
||||
'test/StormTest.cpp',
|
||||
}
|
||||
|
25
StormLib/Publish.bat
Normal file
25
StormLib/Publish.bat
Normal file
@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
rem This BAT file updates the ZIP file that is to be uploaded to web
|
||||
rem Only use when both 32-bit and 64-bit are properly compiled
|
||||
|
||||
set STORMLIB_NAME=stormlib-9.00
|
||||
|
||||
echo Creating %STORMLIB_NAME%.zip ...
|
||||
cd \Ladik\Appdir
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\doc\*
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\src\*
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\storm_dll\*
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\StormLib.xcodeproj\*
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\stormlib_dll\*
|
||||
zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\test\*
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\CMakeLists.txt
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\makefile.*
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\Info.plist
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.bat
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.sln
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcproj
|
||||
zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcxproj
|
||||
echo.
|
||||
|
||||
echo Press any key to exit ...
|
||||
pause >nul
|
39
StormLib/README.md
Normal file
39
StormLib/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# StormLib
|
||||
|
||||
This is official repository for the StomLib library, an open-source project that can work with Blizzard MPQ archives.
|
||||
|
||||
## Installation and basic usage
|
||||
### Linux
|
||||
1. Download latest release
|
||||
2. Install StormLib:
|
||||
```
|
||||
$ cd <path-to-StormLib>
|
||||
$ cmake CMakeLists.txt
|
||||
$ make
|
||||
$ make install
|
||||
```
|
||||
3. Include StormLib in your project: `#include <StormLib.h>`
|
||||
4. Make sure you compile your project with `-lstorm -lz -lbz2`
|
||||
|
||||
### Windows (Visual Studio 2008)
|
||||
1. Download the latest release of StormLib
|
||||
2. Open the solution file `StormLib_vs08.sln` in Visual Studio 2008
|
||||
3. Choose "Build / Batch Build" and select every build of "StormLib"
|
||||
4. Choose "Rebuild"
|
||||
5. The result libraries are in `.\bin\Win32` and `.\bin\x64`
|
||||
|
||||
### Windows (Visual Studio 2017 or 2019)
|
||||
0. Make sure you have SDK 10.0.17134.0 installed
|
||||
1. Download the latest release of StormLib
|
||||
2. Open the solution file `StormLib_vs19.sln` in Visual Studio 2017/2019
|
||||
3. Choose "Build / Batch Build" and select every build of "StormLib"
|
||||
4. Choose "Rebuild"
|
||||
5. The result libraries are in `.\bin\Win32` and `.\bin\x64`
|
||||
|
||||
### Windows (Test Project)
|
||||
1. Include the main StormLib header: `#include <StormLib.h>`
|
||||
2. Set the correct library directory for StormLibXYZ.lib:
|
||||
* X: D = Debug, R = Release
|
||||
* Y: A = ANSI build, U = Unicode build
|
||||
* Z: S = Using static CRT library, D = Using Dynamic CRT library
|
||||
3. Rebuild
|
3
StormLib/StormLib.kdev4
Normal file
3
StormLib/StormLib.kdev4
Normal file
@ -0,0 +1,3 @@
|
||||
[Project]
|
||||
Manager=KDevCMakeManager
|
||||
Name=StormLib
|
2104
StormLib/StormLib.xcodeproj/project.pbxproj
Normal file
2104
StormLib/StormLib.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
139
StormLib/StormLib_vs08.sln
Normal file
139
StormLib/StormLib_vs08.sln
Normal file
@ -0,0 +1,139 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib_vs08.vcproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_vs08_dll.vcproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_vs08_test.vcproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
DebugAD|Win32 = DebugAD|Win32
|
||||
DebugAD|x64 = DebugAD|x64
|
||||
DebugAS|Win32 = DebugAS|Win32
|
||||
DebugAS|x64 = DebugAS|x64
|
||||
DebugUD|Win32 = DebugUD|Win32
|
||||
DebugUD|x64 = DebugUD|x64
|
||||
DebugUS|Win32 = DebugUS|Win32
|
||||
DebugUS|x64 = DebugUS|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
ReleaseAD|Win32 = ReleaseAD|Win32
|
||||
ReleaseAD|x64 = ReleaseAD|x64
|
||||
ReleaseAS|Win32 = ReleaseAS|Win32
|
||||
ReleaseAS|x64 = ReleaseAS|x64
|
||||
ReleaseUD|Win32 = ReleaseUD|Win32
|
||||
ReleaseUD|x64 = ReleaseUD|x64
|
||||
ReleaseUS|Win32 = ReleaseUS|Win32
|
||||
ReleaseUS|x64 = ReleaseUS|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.ActiveCfg = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.Build.0 = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.ActiveCfg = DebugAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.Build.0 = DebugAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.ActiveCfg = DebugAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.Build.0 = DebugAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.ActiveCfg = DebugAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.Build.0 = DebugAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.ActiveCfg = DebugUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.Build.0 = DebugUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.ActiveCfg = DebugUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.Build.0 = DebugUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.ActiveCfg = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.Build.0 = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.ActiveCfg = ReleaseAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.Build.0 = ReleaseAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.ActiveCfg = ReleaseAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.Build.0 = ReleaseAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.ActiveCfg = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.Build.0 = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.ActiveCfg = ReleaseAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.Build.0 = ReleaseAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.ActiveCfg = ReleaseUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.Build.0 = ReleaseUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.ActiveCfg = ReleaseUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.Build.0 = ReleaseUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.ActiveCfg = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.Build.0 = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.Build.0 = ReleaseUS|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
5017
StormLib/StormLib_vs08.vcproj
Normal file
5017
StormLib/StormLib_vs08.vcproj
Normal file
File diff suppressed because it is too large
Load Diff
2663
StormLib/StormLib_vs08_dll.vcproj
Normal file
2663
StormLib/StormLib_vs08_dll.vcproj
Normal file
File diff suppressed because it is too large
Load Diff
2101
StormLib/StormLib_vs08_test.vcproj
Normal file
2101
StormLib/StormLib_vs08_test.vcproj
Normal file
File diff suppressed because it is too large
Load Diff
162
StormLib/StormLib_vs19.sln
Normal file
162
StormLib/StormLib_vs19.sln
Normal file
@ -0,0 +1,162 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28010.2050
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_vs19_dll.vcxproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_vs19_test.vcxproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
DebugAD|Win32 = DebugAD|Win32
|
||||
DebugAD|x64 = DebugAD|x64
|
||||
DebugAS|Win32 = DebugAS|Win32
|
||||
DebugAS|x64 = DebugAS|x64
|
||||
DebugUD|Win32 = DebugUD|Win32
|
||||
DebugUD|x64 = DebugUD|x64
|
||||
DebugUS|Win32 = DebugUS|Win32
|
||||
DebugUS|x64 = DebugUS|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
ReleaseAD|Win32 = ReleaseAD|Win32
|
||||
ReleaseAD|x64 = ReleaseAD|x64
|
||||
ReleaseAS|Win32 = ReleaseAS|Win32
|
||||
ReleaseAS|x64 = ReleaseAS|x64
|
||||
ReleaseUD|Win32 = ReleaseUD|Win32
|
||||
ReleaseUD|x64 = ReleaseUD|x64
|
||||
ReleaseUS|Win32 = ReleaseUS|Win32
|
||||
ReleaseUS|x64 = ReleaseUS|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.ActiveCfg = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.Build.0 = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.ActiveCfg = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.Build.0 = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.ActiveCfg = DebugAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.Build.0 = DebugAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.ActiveCfg = DebugAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.Build.0 = DebugAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.ActiveCfg = DebugAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.Build.0 = DebugAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.ActiveCfg = DebugUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.Build.0 = DebugUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.ActiveCfg = DebugUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.Build.0 = DebugUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.ActiveCfg = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.Build.0 = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.ActiveCfg = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.Build.0 = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.ActiveCfg = ReleaseAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.Build.0 = ReleaseAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.ActiveCfg = ReleaseAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.Build.0 = ReleaseAD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.ActiveCfg = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.Build.0 = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.ActiveCfg = ReleaseAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.Build.0 = ReleaseAS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.ActiveCfg = ReleaseUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.Build.0 = ReleaseUD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.ActiveCfg = ReleaseUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.Build.0 = ReleaseUD|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.ActiveCfg = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.Build.0 = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.Build.0 = ReleaseUS|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.ActiveCfg = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.Build.0 = Debug|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.ActiveCfg = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.Build.0 = Debug|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.Build.0 = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.ActiveCfg = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.Build.0 = Release|Win32
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.ActiveCfg = Release|x64
|
||||
{CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.ActiveCfg = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.Build.0 = Debug|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.ActiveCfg = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.Build.0 = Debug|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.Build.0 = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.ActiveCfg = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.Build.0 = Release|Win32
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.ActiveCfg = Release|x64
|
||||
{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {04583FA5-D423-4B0D-A42B-F7D44C70991C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
1187
StormLib/StormLib_vs19.vcxproj
Normal file
1187
StormLib/StormLib_vs19.vcxproj
Normal file
File diff suppressed because it is too large
Load Diff
830
StormLib/StormLib_vs19.vcxproj.filters
Normal file
830
StormLib/StormLib_vs19.vcxproj.filters
Normal file
@ -0,0 +1,830 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Doc Files">
|
||||
<UniqueIdentifier>{595d6bc1-89d0-4fb8-98f6-be35e73727c4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{721663d8-8692-476f-b0fd-71fdadf69929}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{9cc24144-d198-4bd1-b941-b946bd61b982}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adpcm">
|
||||
<UniqueIdentifier>{be0080d3-fc04-4442-9e28-b4cc2641177d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\bzip2">
|
||||
<UniqueIdentifier>{adb84a97-8a0c-4988-9473-452326110dff}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\huffman">
|
||||
<UniqueIdentifier>{87256d6a-e658-4f60-8759-6bff32a35eb2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt">
|
||||
<UniqueIdentifier>{d730d7c1-2960-49d2-ba0d-d1a91dd08964}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\hashes">
|
||||
<UniqueIdentifier>{13e5ccb1-06f1-4d10-bdc1-825b51c64dbf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\math">
|
||||
<UniqueIdentifier>{73f7f025-7366-4d76-8d60-4327e00b9d18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\misc">
|
||||
<UniqueIdentifier>{be21c641-7727-4d7b-919e-c895d801db17}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk">
|
||||
<UniqueIdentifier>{694a7758-f909-4b8e-aa13-4d06a8c70eff}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\asn1">
|
||||
<UniqueIdentifier>{3f01cae6-5676-4f33-bb38-215341eedfc4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\ecc">
|
||||
<UniqueIdentifier>{63d75851-c430-4c76-aa08-3398523aab4a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\pkcs1">
|
||||
<UniqueIdentifier>{11175e9e-e9f1-405c-961b-933e72503cdd}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\rsa">
|
||||
<UniqueIdentifier>{e30512f4-bdf8-4460-823d-475bd8f08d28}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtommath">
|
||||
<UniqueIdentifier>{d2889ef6-3f12-4a9b-8624-8d061748ff03}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\lzma">
|
||||
<UniqueIdentifier>{02c6dfb8-4a58-46c5-bb35-69ba6215a3a6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\pklib">
|
||||
<UniqueIdentifier>{563829a0-aaa3-4af2-88a2-8c6445d2754b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\sparse">
|
||||
<UniqueIdentifier>{e82b0d03-77ff-46dc-b5a4-5b469224222a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\zlib">
|
||||
<UniqueIdentifier>{cb92df18-9435-4db9-997a-e0e7d532cd26}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\jenkins">
|
||||
<UniqueIdentifier>{2920175c-439c-4fd5-b94e-8cf1d3aaadd3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="doc\History.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 0.9.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 1.0.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\StormCommon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\adpcm\adpcm.h">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\huffman\huff.h">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pklib\pklib.h">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\sparse\sparse.h">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\jenkins\lookup.h">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormLib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormPort.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\FileStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseCommon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseFileTable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SCompression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAddFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAttributes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCompactArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCreateArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileExtractFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileFindFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileGetFileInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileListFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenFileEx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFilePatchArchives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileReadFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileVerify.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\adpcm\adpcm.cpp">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\blocksort.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\bzlib.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\compress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\crctable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\decompress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\huffman.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\randtable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\huffman\huff.cpp">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\md5.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\sha1.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\multi.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\rand_prime.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\zeromem.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_2expt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_abs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_addmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_and.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clamp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_mag.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_count_bits.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_3.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exch.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_expt_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exteuclid.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fread.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fwrite.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_gcd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_get_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_grow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod_slow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_is_square.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_jacobi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lcm.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mulmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_n_root.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_neg.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_or.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_fermat.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_smap.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rand.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_radix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_shrink.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_submod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_xor.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_zero.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_prime_tab.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_reverse.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bncore.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFind.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFindMt.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaDec.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaEnc.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\Threads.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\explode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\implode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\sparse\sparse.cpp">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\adler32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\crc32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\deflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inffast.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inftrees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\trees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\zutil.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\jenkins\lookup3.c">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\compress_zlib.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseSubTypes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
537
StormLib/StormLib_vs19_dll.vcxproj
Normal file
537
StormLib/StormLib_vs19_dll.vcxproj
Normal file
@ -0,0 +1,537 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>StormLib_dll</ProjectName>
|
||||
<ProjectGuid>{CB385198-50B1-4CF4-883B-11F042DED6AA}</ProjectGuid>
|
||||
<RootNamespace>StormLib_dll</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>StormLib</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>StormLib</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>StormLib</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>StormLib</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)StormLib.dll</OutputFile>
|
||||
<ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)StormLib.dll</OutputFile>
|
||||
<ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)StormLib.dll</OutputFile>
|
||||
<ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)StormLib.dll</OutputFile>
|
||||
<ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="doc\History.txt" />
|
||||
<Text Include="doc\The MoPaQ File Format 0.9.txt" />
|
||||
<Text Include="doc\The MoPaQ File Format 1.0.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\adpcm\adpcm.h" />
|
||||
<ClInclude Include="src\huffman\huff.h" />
|
||||
<ClInclude Include="src\jenkins\lookup.h" />
|
||||
<ClInclude Include="src\pklib\pklib.h" />
|
||||
<ClInclude Include="src\sparse\sparse.h" />
|
||||
<ClInclude Include="src\StormCommon.h" />
|
||||
<ClInclude Include="src\StormLib.h" />
|
||||
<ClInclude Include="src\StormPort.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\adpcm\adpcm.cpp" />
|
||||
<ClCompile Include="src\bzip2\blocksort.c" />
|
||||
<ClCompile Include="src\bzip2\bzlib.c" />
|
||||
<ClCompile Include="src\bzip2\compress.c" />
|
||||
<ClCompile Include="src\bzip2\crctable.c" />
|
||||
<ClCompile Include="src\bzip2\decompress.c" />
|
||||
<ClCompile Include="src\bzip2\huffman.c" />
|
||||
<ClCompile Include="src\bzip2\randtable.c" />
|
||||
<ClCompile Include="src\FileStream.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\huffman\huff.cpp" />
|
||||
<ClCompile Include="src\jenkins\lookup3.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\md5.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\sha1.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\rand_prime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\zeromem.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c" />
|
||||
<ClCompile Include="src\libtommath\bncore.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_invmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_2expt.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_abs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_add.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_addmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_add_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_and.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clamp.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear_multi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_mag.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_copy.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_count_bits.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_3.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exch.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_expt_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exteuclid.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_fread.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_fwrite.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_gcd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_get_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_grow.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_copy.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_multi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod_slow.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_is_square.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_jacobi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_lcm.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_lshd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mulmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_neg.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_n_root.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_or.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_fermat.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_smap.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_rand.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_radix.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_rshd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_set.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_set_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_shrink.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrt.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_submod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_xor.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_zero.c" />
|
||||
<ClCompile Include="src\libtommath\bn_prime_tab.c" />
|
||||
<ClCompile Include="src\libtommath\bn_reverse.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_add.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_exptmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sub.c" />
|
||||
<ClCompile Include="src\lzma\C\LzFind.c" />
|
||||
<ClCompile Include="src\lzma\C\LzFindMt.c" />
|
||||
<ClCompile Include="src\lzma\C\LzmaDec.c" />
|
||||
<ClCompile Include="src\lzma\C\LzmaEnc.c" />
|
||||
<ClCompile Include="src\lzma\C\Threads.c" />
|
||||
<ClCompile Include="src\pklib\explode.c" />
|
||||
<ClCompile Include="src\pklib\implode.c" />
|
||||
<ClCompile Include="src\SBaseCommon.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseFileTable.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseSubTypes.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SCompression.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAddFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAttributes.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCompactArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCreateArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileExtractFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileFindFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileGetFileInfo.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileListFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenFileEx.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFilePatchArchives.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileReadFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileVerify.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\sparse\sparse.cpp" />
|
||||
<ClCompile Include="src\zlib\adler32.c" />
|
||||
<ClCompile Include="src\zlib\compress_zlib.c" />
|
||||
<ClCompile Include="src\zlib\crc32.c" />
|
||||
<ClCompile Include="src\zlib\deflate.c" />
|
||||
<ClCompile Include="src\zlib\inffast.c" />
|
||||
<ClCompile Include="src\zlib\inflate.c" />
|
||||
<ClCompile Include="src\zlib\inftrees.c" />
|
||||
<ClCompile Include="src\zlib\trees.c" />
|
||||
<ClCompile Include="src\zlib\zutil.c" />
|
||||
<ClCompile Include="src\DllMain.c">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\DllMain.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
838
StormLib/StormLib_vs19_dll.vcxproj.filters
Normal file
838
StormLib/StormLib_vs19_dll.vcxproj.filters
Normal file
@ -0,0 +1,838 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Doc Files">
|
||||
<UniqueIdentifier>{b352ea2c-4169-4b60-85bc-82eadd5a9d2e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{9171b211-949a-4dc1-a028-edf0a2ed4605}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{712a20a0-c7a8-4e56-947b-2cf030bbb287}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adpcm">
|
||||
<UniqueIdentifier>{83502600-f49c-43b1-afe6-038d3560a859}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\bzip2">
|
||||
<UniqueIdentifier>{ea8b08a3-5c21-48e0-b75f-78eaa2adbc22}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\huffman">
|
||||
<UniqueIdentifier>{593ac5e7-fe06-42b8-8025-e3bd725f95d8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt">
|
||||
<UniqueIdentifier>{9887a885-78fa-4164-80b9-9db6b0c11f86}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\hashes">
|
||||
<UniqueIdentifier>{7db62947-d38d-48e9-8b52-4cad226394a6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\math">
|
||||
<UniqueIdentifier>{b435fecf-9a65-4f2e-8d64-7dfc70de3137}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\misc">
|
||||
<UniqueIdentifier>{d8ad7878-9e42-427a-b5b6-ae51d92b92cf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk">
|
||||
<UniqueIdentifier>{07806629-c061-49ed-8212-0585d25fae23}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\asn1">
|
||||
<UniqueIdentifier>{ca554d9f-b602-452a-971e-86b537ee2ad1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\ecc">
|
||||
<UniqueIdentifier>{46e1697c-e6c2-4a8c-b4d2-0142311bb48b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\pkcs1">
|
||||
<UniqueIdentifier>{99279e07-2e33-44c9-8f37-0b810ee4ba25}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\rsa">
|
||||
<UniqueIdentifier>{04fbcfe0-3023-4fa0-8e36-26ab024a4abf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtommath">
|
||||
<UniqueIdentifier>{4720c7a0-f4aa-4737-978c-9efe8b429906}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\lzma">
|
||||
<UniqueIdentifier>{856c9964-4d85-40e9-8cbd-f4c672c07780}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\pklib">
|
||||
<UniqueIdentifier>{7ad3c876-768a-45bc-85b1-38cd492814ea}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\sparse">
|
||||
<UniqueIdentifier>{22e86a97-80e9-45a0-ac8e-70d7ea848f35}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\zlib">
|
||||
<UniqueIdentifier>{7b2ea923-8454-4073-bb9c-85de0f66caa1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\jenkins">
|
||||
<UniqueIdentifier>{5404ec38-706a-47f8-97b7-941c2574ddf2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="doc\History.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 0.9.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 1.0.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\StormCommon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormLib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormPort.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\adpcm\adpcm.h">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\huffman\huff.h">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pklib\pklib.h">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\sparse\sparse.h">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\jenkins\lookup.h">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\FileStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseCommon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseFileTable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseSubTypes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SCompression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAddFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAttributes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCompactArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCreateArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileExtractFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileFindFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileGetFileInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileListFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenFileEx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFilePatchArchives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileReadFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileVerify.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\adpcm\adpcm.cpp">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\blocksort.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\bzlib.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\compress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\crctable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\decompress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\huffman.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\randtable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\huffman\huff.cpp">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\md5.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\sha1.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\multi.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\rand_prime.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\zeromem.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_2expt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_abs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_addmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_and.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clamp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_mag.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_count_bits.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_3.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exch.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_expt_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exteuclid.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fread.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fwrite.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_gcd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_get_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_grow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod_slow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_is_square.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_jacobi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lcm.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mulmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_n_root.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_neg.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_or.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_fermat.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_smap.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rand.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_radix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_shrink.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_submod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_xor.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_zero.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_prime_tab.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_reverse.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bncore.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFind.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFindMt.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaDec.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaEnc.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\Threads.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\explode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\implode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\sparse\sparse.cpp">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\adler32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\compress_zlib.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\crc32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\deflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inffast.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inftrees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\trees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\zutil.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\jenkins\lookup3.c">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DllMain.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\DllMain.rc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
549
StormLib/StormLib_vs19_test.vcxproj
Normal file
549
StormLib/StormLib_vs19_test.vcxproj
Normal file
@ -0,0 +1,549 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>StormLib_test</ProjectName>
|
||||
<ProjectGuid>{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}</ProjectGuid>
|
||||
<RootNamespace>StormLib_test</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</OutDir>
|
||||
<IntDir>./bin/$(ProjectName)/$(Platform)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="doc\History.txt" />
|
||||
<Text Include="doc\The MoPaQ File Format 0.9.txt" />
|
||||
<Text Include="doc\The MoPaQ File Format 1.0.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\adpcm\adpcm.h" />
|
||||
<ClInclude Include="src\FileStream.h" />
|
||||
<ClInclude Include="src\huffman\huff.h" />
|
||||
<ClInclude Include="src\jenkins\lookup.h" />
|
||||
<ClInclude Include="src\pklib\pklib.h" />
|
||||
<ClInclude Include="src\sparse\sparse.h" />
|
||||
<ClInclude Include="src\StormCommon.h" />
|
||||
<ClInclude Include="src\StormLib.h" />
|
||||
<ClInclude Include="src\StormPort.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\adpcm\adpcm.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\blocksort.c" />
|
||||
<ClCompile Include="src\bzip2\bzlib.c" />
|
||||
<ClCompile Include="src\bzip2\compress.c" />
|
||||
<ClCompile Include="src\bzip2\crctable.c" />
|
||||
<ClCompile Include="src\bzip2\decompress.c" />
|
||||
<ClCompile Include="src\bzip2\huffman.c" />
|
||||
<ClCompile Include="src\bzip2\randtable.c" />
|
||||
<ClCompile Include="src\FileStream.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\huffman\huff.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\jenkins\lookup3.c">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level1</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level1</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\md5.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\sha1.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\math\rand_prime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\zeromem.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c" />
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c" />
|
||||
<ClCompile Include="src\libtommath\bncore.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_invmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_2expt.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_abs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_add.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_addmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_add_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_and.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clamp.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear_multi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_mag.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_copy.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_count_bits.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_3.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exch.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_expt_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_exteuclid.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_fread.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_fwrite.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_gcd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_get_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_grow.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_copy.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_multi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod_slow.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_is_square.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_jacobi.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_lcm.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_lshd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mulmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_neg.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_n_root.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_or.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_fermat.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_smap.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_rand.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_radix.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_setup.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_rshd.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_set.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_set_int.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_shrink.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrt.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_submod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub_d.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_mul.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_xor.c" />
|
||||
<ClCompile Include="src\libtommath\bn_mp_zero.c" />
|
||||
<ClCompile Include="src\libtommath\bn_prime_tab.c" />
|
||||
<ClCompile Include="src\libtommath\bn_reverse.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_add.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_exptmod.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sqr.c" />
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sub.c" />
|
||||
<ClCompile Include="src\lzma\C\LzFind.c" />
|
||||
<ClCompile Include="src\lzma\C\LzFindMt.c" />
|
||||
<ClCompile Include="src\lzma\C\LzmaDec.c" />
|
||||
<ClCompile Include="src\lzma\C\LzmaEnc.c" />
|
||||
<ClCompile Include="src\lzma\C\Threads.c" />
|
||||
<ClCompile Include="src\pklib\explode.c" />
|
||||
<ClCompile Include="src\pklib\implode.c" />
|
||||
<ClCompile Include="src\SBaseCommon.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseDumpData.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseFileTable.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseSubTypes.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SCompression.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAddFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAttributes.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCompactArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCreateArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileExtractFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileFindFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileGetFileInfo.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileListFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenArchive.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenFileEx.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFilePatchArchives.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileReadFile.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileVerify.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\sparse\sparse.cpp" />
|
||||
<ClCompile Include="src\zlib\adler32.c" />
|
||||
<ClCompile Include="src\zlib\compress_zlib.c" />
|
||||
<ClCompile Include="src\zlib\crc32.c" />
|
||||
<ClCompile Include="src\zlib\deflate.c" />
|
||||
<ClCompile Include="src\zlib\inffast.c" />
|
||||
<ClCompile Include="src\zlib\inflate.c" />
|
||||
<ClCompile Include="src\zlib\inftrees.c" />
|
||||
<ClCompile Include="src\zlib\trees.c" />
|
||||
<ClCompile Include="src\zlib\zutil.c" />
|
||||
<ClCompile Include="test\StormTest.cpp">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
839
StormLib/StormLib_vs19_test.vcxproj.filters
Normal file
839
StormLib/StormLib_vs19_test.vcxproj.filters
Normal file
@ -0,0 +1,839 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Doc Files">
|
||||
<UniqueIdentifier>{1dbbb48c-9db9-4fdb-a903-223ed233cc21}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{ab878eef-1074-4594-bac5-272c05774bd8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{640f063a-5028-4ba1-9007-96d98a634561}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adpcm">
|
||||
<UniqueIdentifier>{6e8cfdab-fca3-4737-8905-6154bc657e15}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\bzip2">
|
||||
<UniqueIdentifier>{a810fdb6-0d21-4279-8e39-b2de644170c0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\huffman">
|
||||
<UniqueIdentifier>{7861b4fb-1471-4573-92ea-08c06dc14b93}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt">
|
||||
<UniqueIdentifier>{8ba6c5c7-3ad0-44e6-8829-5020fce13d49}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\hashes">
|
||||
<UniqueIdentifier>{92cb0c1d-86f0-4735-9e4e-b07df664c359}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\math">
|
||||
<UniqueIdentifier>{f7fb3d55-94af-4a6e-be7b-76cb909e7325}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\misc">
|
||||
<UniqueIdentifier>{337159fe-94a7-45a8-a91b-fa8b9d06b2ae}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk">
|
||||
<UniqueIdentifier>{359bb3d3-71d5-47e7-967a-1fada7882e4d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\asn1">
|
||||
<UniqueIdentifier>{775dbb7e-ef06-4660-9d84-50ff2557ef54}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\ecc">
|
||||
<UniqueIdentifier>{2e5d39cc-482c-4775-8830-79f8314e72e4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\pkcs1">
|
||||
<UniqueIdentifier>{1e0ef267-228e-4c59-8d88-e3b33aeaff49}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtomcrypt\pk\rsa">
|
||||
<UniqueIdentifier>{98330deb-0b92-4f02-8016-8a33dc5f5d29}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libtommath">
|
||||
<UniqueIdentifier>{fa78c716-784a-43a0-a548-db413431973b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\lzma">
|
||||
<UniqueIdentifier>{5308566b-d3fd-4561-a7fb-982a63662793}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\pklib">
|
||||
<UniqueIdentifier>{d5371a5f-1630-4e79-9e7e-1ef654a2ddec}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\sparse">
|
||||
<UniqueIdentifier>{c2971fba-aff1-42ab-9f4f-71707edabf77}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\zlib">
|
||||
<UniqueIdentifier>{4f4fe3d6-6f2b-4c83-9cf9-f1d108ecd854}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\jenkins">
|
||||
<UniqueIdentifier>{5aaea51e-4b7c-4a35-b35c-96c2fc7750f1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="doc\History.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 0.9.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
<Text Include="doc\The MoPaQ File Format 1.0.txt">
|
||||
<Filter>Doc Files</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\FileStream.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormCommon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormLib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\StormPort.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\adpcm\adpcm.h">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\huffman\huff.h">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pklib\pklib.h">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\sparse\sparse.h">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\jenkins\lookup.h">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\FileStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseCommon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseDumpData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseFileTable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SBaseSubTypes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SCompression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAddFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileAttributes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCompactArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileCreateArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileExtractFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileFindFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileGetFileInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileListFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenArchive.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileOpenFileEx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFilePatchArchives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileReadFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SFileVerify.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\StormTest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\adpcm\adpcm.cpp">
|
||||
<Filter>Source Files\adpcm</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\blocksort.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\bzlib.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\compress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\crctable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\decompress.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\huffman.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\bzip2\randtable.c">
|
||||
<Filter>Source Files\bzip2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\huffman\huff.cpp">
|
||||
<Filter>Source Files\huffman</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\md5.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\hashes\sha1.c">
|
||||
<Filter>Source Files\libtomcrypt\hashes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\multi.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\math\rand_prime.c">
|
||||
<Filter>Source Files\libtomcrypt\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\misc\zeromem.c">
|
||||
<Filter>Source Files\libtomcrypt\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\asn1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c">
|
||||
<Filter>Source Files\libtomcrypt\pk\rsa</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_2expt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_abs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_add_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_addmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_and.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clamp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_clear_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cmp_mag.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_count_bits.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_3.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_div_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_dr_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exch.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_expt_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_exteuclid.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fread.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_fwrite.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_gcd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_get_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_grow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_copy.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_multi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_init_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_invmod_slow.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_is_square.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_jacobi.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lcm.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_lshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mod_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_2d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mul_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_mulmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_n_root.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_neg.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_or.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_fermat.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_radix_smap.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rand.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_radix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_reduce_setup.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_rshd.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_set_int.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_shrink.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sqrt.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_sub_d.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_submod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_mul.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toom_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_toradix_n.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_xor.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_mp_zero.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_prime_tab.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_reverse.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_add.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_exptmod.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sqr.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bn_s_mp_sub.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\libtommath\bncore.c">
|
||||
<Filter>Source Files\libtommath</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFind.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzFindMt.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaDec.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\LzmaEnc.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lzma\C\Threads.c">
|
||||
<Filter>Source Files\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\explode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pklib\implode.c">
|
||||
<Filter>Source Files\pklib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\sparse\sparse.cpp">
|
||||
<Filter>Source Files\sparse</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\adler32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\compress_zlib.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\crc32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\deflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inffast.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inflate.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\inftrees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\trees.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\zutil.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\jenkins\lookup3.c">
|
||||
<Filter>Source Files\jenkins</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
78
StormLib/doc/History.txt
Normal file
78
StormLib/doc/History.txt
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
StormLib history
|
||||
================
|
||||
|
||||
Version 9.11
|
||||
|
||||
- Fixed bug in processing HET table.
|
||||
|
||||
Version 9.10
|
||||
|
||||
- Support for weak-signing
|
||||
- Anti-protector: New Spazzler
|
||||
|
||||
Version 9.00
|
||||
|
||||
- Support for streaming (master-mirror)
|
||||
- Support for multi-file MPQs used by some WoW versions
|
||||
- Opening maps protected by Spazzler protector
|
||||
- Opening maps protected by BOBA protector
|
||||
|
||||
Version 8.02
|
||||
|
||||
- Support for UNICODE encoding for on-disk files
|
||||
- Optimized file deleting
|
||||
|
||||
Version 8.01
|
||||
|
||||
- SFileFindFirstFile and SFileFindNextFile no longer find files that have
|
||||
patch file in the oldest MPQ in the patch chain
|
||||
- Write support for MPQs version 4
|
||||
|
||||
Version 8.00
|
||||
|
||||
- Updated support for protected maps from Warcraft III
|
||||
|
||||
Version 7.11
|
||||
|
||||
- Support for MPQs v 3.0 (WOW-Cataclysm BETA)
|
||||
- StormLib now deals properly with files that have MPQ_SECTOR_CHECKSUM missing,
|
||||
but have sector checksum entry present in the sector offset table
|
||||
|
||||
Version 7.10
|
||||
|
||||
- Support for partial MPQs ("interface.MPQ.part")
|
||||
- The only operation that is externally allowed to do with internal files
|
||||
("(listfile)", "(attributes)" and "(signature)") is reading. Attempt to modify any of the file
|
||||
fails and GetLastError returns ERROR_INTERNAL_FILE
|
||||
- Fixed memory leak that has occured when writing more than one sector to the file at once
|
||||
|
||||
Version 7.01
|
||||
|
||||
- Support for adding files from memory
|
||||
- Fixed improper validation of handles to MPQ file and MPQ archive
|
||||
- Fixed bug where StormLib didn't save CRC32 of the file when added to archive
|
||||
|
||||
Version 7.00
|
||||
|
||||
- Properly deals with MPQs protected by w3xMaster
|
||||
- Major rewrite
|
||||
- Fixed support for (attributes)
|
||||
- Added file verification
|
||||
- Added MPQ signature verification
|
||||
|
||||
Version 6.22
|
||||
|
||||
- Properly deals with MPQs protected by w3xMaster
|
||||
|
||||
Version 6.21
|
||||
|
||||
- SFileRenameFile now properly re-crypts the file if necessary.
|
||||
- SFileFindFirstFile correctly deals with deleted files
|
||||
|
||||
Version 6.20
|
||||
|
||||
- Fixed lots of bugs when processing files with same names but different locales
|
||||
- Fixed bugs when repeately extracts the same file with MPQ_FILE_SINGLE_UNIT flag
|
||||
- Added SFileFlushArchive
|
||||
- Fixed issue opening AVI files renamed to MPQ using SFileCreateArchiveEx
|
318
StormLib/doc/The MoPaQ File Format 0.9.txt
Normal file
318
StormLib/doc/The MoPaQ File Format 0.9.txt
Normal file
@ -0,0 +1,318 @@
|
||||
THE MOPAQ ARCHIVE FORMAT
|
||||
v0.9 (Thursday, June 30, 2005)
|
||||
by Justin Olbrantz(Quantam)
|
||||
|
||||
Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quoting
|
||||
in other works is freely allowed, as long as the source and author of the quote is stated.
|
||||
|
||||
TABLE OF CONTENTS
|
||||
1. Introduction to the MoPaQ Format
|
||||
2. The MoPaQ Format
|
||||
2.1 General Archive Layout
|
||||
2.2 Archive Header
|
||||
2.3 Block Table
|
||||
2.4 Hash Table
|
||||
2.5 File Data
|
||||
2.6 Listfile
|
||||
2.7 Extended Attributes
|
||||
2.8 Weak (Old) Digital Signature
|
||||
2.9 Strong (New) Digital Signature
|
||||
3. Algorithm Source Code
|
||||
3.1 Encryption/Decryption
|
||||
3.2 Hashing
|
||||
3.3 Conversion of FILETIME and time_t
|
||||
|
||||
1. INTRODUCTION TO THE MOPAQ FORMAT
|
||||
The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard
|
||||
Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be
|
||||
a read-only game archive format, and excels at this role.
|
||||
|
||||
The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked.
|
||||
The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked.
|
||||
|
||||
2. THE MOPAQ FORMAT
|
||||
All numbers in the MoPaQ format are in little endian. Data types are listed either as int (integer, the number of bits specified),
|
||||
byte (8 bits), and char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise.
|
||||
Structure members are listed in the following general form:
|
||||
offset from the beginning of the structure: data type(array size) member name : member description
|
||||
|
||||
2.1 GENERAL ARCHIVE LAYOUT
|
||||
- Archive Header
|
||||
- File Data
|
||||
- File Data - Special Files
|
||||
- Hash Table
|
||||
- Block Table
|
||||
- Strong Digital signature
|
||||
|
||||
This is the usual archive format, and is not absolutely essential. Some archives have been observed placing the hash table
|
||||
and file table after the archive header, and before the file data.
|
||||
|
||||
2.2 ARCHIVE HEADER
|
||||
00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah.
|
||||
04h: int32 HeaderSize : Size of the archive header. Should be 32.
|
||||
08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present.
|
||||
This size is used, among other things, for determining the region to hash in computing the digital signature.
|
||||
0Ch: int16 Unknown : Unknown
|
||||
0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector
|
||||
in the archive. The size of each logical sector the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate
|
||||
that this should always be 3 (4096 byte sectors).
|
||||
10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive.
|
||||
14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive.
|
||||
18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16.
|
||||
1Ch: int32 BlockTableEntries : Number of entries in the block table.
|
||||
|
||||
The archive header is the first structure in the archive, at archive offset 0, but the archive does not need to be at offset
|
||||
0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not
|
||||
at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the
|
||||
archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer
|
||||
versions (due to the strong digital signature not being considered a part of the archive).
|
||||
|
||||
2.3 BLOCK TABLE
|
||||
The block table contains entries for each region in the archive. Regions may be either files or empty space, which may be
|
||||
overwritten by new files (typically this space is from deleted file data). The block table is encrypted, using the hash
|
||||
of "(block table)" as the key. Each entry is structured as follows:
|
||||
|
||||
00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. Meaningless if the block size is 0.
|
||||
04h: int32 BlockSize : Size of the block in the archive.
|
||||
08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file, otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data.
|
||||
0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified:
|
||||
80000000h: Block is a file, and follows the file data format; otherwise, block is free space, and may be overwritten. If the block is not a file, all other flags should be cleared.
|
||||
01000000h: File is stored as a single unit, rather than split into sectors.
|
||||
00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted.
|
||||
00010000h: File is encrypted.
|
||||
00000200h: File is compressed. Mutually exclusive to file imploded.
|
||||
00000100h: File is imploded. Mutually exclusive to file compressed.
|
||||
|
||||
2.4 HASH TABLE
|
||||
Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows:
|
||||
|
||||
00h: int32 FilePathHashA : The hash of the file path, using method A.
|
||||
04h: int32 FilePathHashB : The hash of the file path, using method B.
|
||||
08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral.
|
||||
0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed.
|
||||
0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values:
|
||||
FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file.
|
||||
FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file.
|
||||
|
||||
2.5 FILE DATA
|
||||
00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector's data, relative to the beginning of the file data. Not present if this information is calculatable (see details below).
|
||||
immediately following SectorOffsetTable: SectorData : Data of each sector in the file, packed end to end (see details below).
|
||||
|
||||
Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may be smaller than this, depending on the size of the file data. This sector size is the size of the raw file data; if the file is compressed, the compressed sector will be smaller or the same size as the uncompressed sector size. Individual sectors in a compressed file may be stored uncompressed; this occurs if and only if the sector could not be compressed by the algorithm used (if the compressed sector size was greater than or equal to the size of the raw data), and is indicated by the sector's compressed size in SectorOffsetTable being equal to the uncompressed size of the sector (which may be calculated from the FileSize).
|
||||
|
||||
If the sector is compressed (but not imploded), a bit mask byte of the compression algorithm(s) used to compress the sector is appended to the beginning of the compressed sector data. This additional byte counts towards the total size of the sector; if the size of the sector (including this byte) exceeds or matches the uncompressed size of the sector data, the sector will be stored uncompressed, and this byte omitted. Multiple compression algorithms may be used on the same sector; in this case, successive compression occurs in the order the algorithms are listed below, and decompression occurs in the opposite order. For implimentations of all of these algorithms, see StormLib.
|
||||
40h: IMA ADPCM mono
|
||||
80h: IMA ADPCM stereo
|
||||
01h: Huffman encoded
|
||||
02h: Deflated (see ZLib)
|
||||
08h: Imploded (see PKWare Data Compression Library)
|
||||
10h: BZip2 compressed (see BZip2)
|
||||
|
||||
If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which
|
||||
contains the entire file.
|
||||
|
||||
If the file is encrypted, each sector (after compression and appendage of the compression type byte, if applicable)
|
||||
is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the
|
||||
directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is
|
||||
adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset)
|
||||
XOR FileSize) (StormLib - an open-source implementation of the MoPaQ reading and writing functions,
|
||||
by Ladislav Zezula - incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the
|
||||
0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1.
|
||||
|
||||
The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize.
|
||||
This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors
|
||||
is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the
|
||||
SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously.
|
||||
Note that the SectorOffsetTable will always be present if the file is compressed/imploded and the file is not stored as
|
||||
a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the
|
||||
archive's sector size).
|
||||
|
||||
2.6 LISTFILE
|
||||
The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive.
|
||||
The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)",
|
||||
and is simply a non-Unix-style text file with one file path on each line, lines terminated with the bytes 0Dh 0Ah. The file
|
||||
"(listfile)" may not be listed in the listfile.
|
||||
|
||||
2.7 EXTENDED ATTRIBUTES
|
||||
The extended attributes are optional file attributes for files in the block table. These attributes were added at times after
|
||||
the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes.
|
||||
If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although
|
||||
the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the
|
||||
blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file,
|
||||
in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other
|
||||
structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some
|
||||
archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This
|
||||
file is structured as follows:
|
||||
|
||||
00h: int32 Version : Specifies the extended attributes format version. For now, must be 100.
|
||||
04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive:
|
||||
00000001h: File CRC32s.
|
||||
00000002h: File timestamps.
|
||||
00000004h: File MD5s.
|
||||
08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the
|
||||
archive does not have CRC32s. immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block
|
||||
in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps.
|
||||
immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive.
|
||||
Omitted if the archive does not have MD5s.
|
||||
|
||||
2.8 WEAK DIGITAL SIGNATURE
|
||||
The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation of the RSASSA-PKCS1-v1_5
|
||||
digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) RSA key (for more information about this
|
||||
protocol, see the RSA Labs PKCS1 specification). The public key and exponent are stored in a resource in Storm. The signature
|
||||
is stored uncompressed, unencrypted in the file "(signature)" in the archive. The archive is hashed from the beginning of the
|
||||
archive (ArchiveOffset in the containing file) to the end of the archive (the length indicated by ArchiveSize); the signature
|
||||
file is added to the archive before signing, and the space occupied by the file is considered to be all binary 0s during
|
||||
signing/verification. This file is structured as follows:
|
||||
|
||||
00h: int32 Unknown : Must be 0.
|
||||
04h: int32 Unknown : must be 0.
|
||||
08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored in little-endian order.
|
||||
|
||||
2.9 STRONG DIGITAL SIGNATURE
|
||||
The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and
|
||||
a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well.
|
||||
The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize
|
||||
bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format:
|
||||
|
||||
00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards).
|
||||
04h: int2048 Signature : The digital signature, stored in little-endian format.
|
||||
|
||||
When the Signature field is decrypted with the public key and exponent, and the result stored in little-endian order, it is structured as follows:
|
||||
|
||||
00h: byte Padding : Must be 0Bh.
|
||||
01h: byte(235) Padding : Must be BBh.
|
||||
ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 format.
|
||||
|
||||
3. ALGORITHM SOURCE CODE
|
||||
3.1 ENCRYPTION/DECRYPTION
|
||||
I believe this was derived at some point from code in StormLib. Assumes the long type to be 32 bits, and the machine to be little endian order.
|
||||
|
||||
unsigned long dwCryptTable[0x500];
|
||||
|
||||
void InitializeCryptTable()
|
||||
{
|
||||
unsigned long seed = 0x00100001;
|
||||
unsigned long index1 = 0;
|
||||
unsigned long index2 = 0;
|
||||
int i;
|
||||
|
||||
for (index1 = 0; index1 < 0x100; index1++)
|
||||
{
|
||||
for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
|
||||
{
|
||||
unsigned long temp1, temp2;
|
||||
|
||||
seed = (seed * 125 + 3) % 0x2AAAAB;
|
||||
temp1 = (seed & 0xFFFF) << 0x10;
|
||||
|
||||
seed = (seed * 125 + 3) % 0x2AAAAB;
|
||||
temp2 = (seed & 0xFFFF);
|
||||
|
||||
dwCryptTable[index2] = (temp1 | temp2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
|
||||
{
|
||||
unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
|
||||
unsigned long seed = 0xEEEEEEEE;
|
||||
unsigned long ch;
|
||||
|
||||
assert(lpbyBuffer);
|
||||
|
||||
dwLength /= sizeof(unsigned long);
|
||||
|
||||
while(dwLength-- > 0)
|
||||
{
|
||||
seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
|
||||
ch = *lpdwBuffer ^ (dwKey + seed);
|
||||
|
||||
dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
|
||||
seed = *lpdwBuffer + seed + (seed << 5) + 3;
|
||||
|
||||
*lpdwBuffer++ = ch;
|
||||
}
|
||||
}
|
||||
|
||||
void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
|
||||
{
|
||||
unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
|
||||
unsigned long seed = 0xEEEEEEEE;
|
||||
unsigned long ch;
|
||||
|
||||
assert(lpbyBuffer);
|
||||
|
||||
dwLength /= sizeof(unsigned long);
|
||||
|
||||
while(dwLength-- > 0)
|
||||
{
|
||||
seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
|
||||
ch = *lpdwBuffer ^ (dwKey + seed);
|
||||
|
||||
dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
|
||||
seed = ch + seed + (seed << 5) + 3;
|
||||
|
||||
*lpdwBuffer++ = ch;
|
||||
}
|
||||
}
|
||||
|
||||
3.2 HASHING
|
||||
Based on code from StormLib.
|
||||
|
||||
// Different types of hashes to make with HashString
|
||||
#define MPQ_HASH_TABLE_OFFSET 0
|
||||
#define MPQ_HASH_NAME_A 1
|
||||
#define MPQ_HASH_NAME_B 2
|
||||
#define MPQ_HASH_FILE_KEY 3
|
||||
|
||||
unsigned long HashString(const char *lpszString, unsigned long dwHashType)
|
||||
{
|
||||
unsigned long seed1 = 0x7FED7FED;
|
||||
unsigned long seed2 = 0xEEEEEEEE;
|
||||
int ch;
|
||||
|
||||
while (*lpszString != 0)
|
||||
{
|
||||
ch = toupper(*lpszString++);
|
||||
|
||||
seed1 = dwCryptTable[(dwHashType * 0xFF) + ch] ^ (seed1 + seed2);
|
||||
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
|
||||
}
|
||||
return seed1;
|
||||
}
|
||||
|
||||
3.3 CONVERSION OF FILETIME AND time_t
|
||||
|
||||
#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970
|
||||
|
||||
bool GetTimeFromFileTime(FILETIME &fileTime, time_t &time)
|
||||
{
|
||||
// The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601
|
||||
unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
|
||||
|
||||
if (nTime < EPOCH_OFFSET)
|
||||
return false;
|
||||
|
||||
nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970
|
||||
nTime /= 10000000ULL; // Convert 100 ns to sec
|
||||
|
||||
time = (time_t)nTime;
|
||||
|
||||
// Test for overflow (FILETIME is 64 bits, time_t is 32 bits)
|
||||
if ((nTime - (unsigned long long)time) > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetFileTimeFromTime(time_t &time, FILETIME &fileTime)
|
||||
{
|
||||
unsigned long long nTime = (unsigned long long)time;
|
||||
|
||||
nTime *= 10000000ULL;
|
||||
nTime += EPOCH_OFFSET;
|
||||
|
||||
fileTime.dwLowDateTime = (DWORD)nTime;
|
||||
fileTime.dwHighDateTime = (DWORD)(nTime >> 32);
|
||||
}
|
433
StormLib/doc/The MoPaQ File Format 1.0.txt
Normal file
433
StormLib/doc/The MoPaQ File Format 1.0.txt
Normal file
@ -0,0 +1,433 @@
|
||||
THE MOPAQ ARCHIVE FORMAT
|
||||
v1.0 (Friday, September 1, 2006)
|
||||
by Justin Olbrantz(Quantam)
|
||||
|
||||
Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quotation in other works is freely allowed, as long as the source and author of the quote are stated.
|
||||
|
||||
TABLE OF CONTENTS
|
||||
1. Introduction to the MoPaQ Format
|
||||
2. The MoPaQ Format
|
||||
2.1 General Archive Layout
|
||||
2.2 Archive Header
|
||||
2.3 Block Table
|
||||
2.4 Extended Block Table
|
||||
2.5 Hash Table
|
||||
2.6 File Data
|
||||
2.7 Listfile
|
||||
2.8 Extended Attributes
|
||||
2.9 Weak (Old) Digital Signature
|
||||
2.10 Strong (New) Digital Signature
|
||||
3. Algorithm Source Code
|
||||
3.1 Encryption/Decryption
|
||||
3.2 Hashing and File Key Computation
|
||||
3.3 Finding Files
|
||||
3.4 Deleting Files
|
||||
3.5 Conversion of FILETIME and time_t
|
||||
3.6 Forming a 64-bit Large Archive Offset from 32-bit and 16-bit Components
|
||||
4. Revision History
|
||||
|
||||
1. INTRODUCTION TO THE MOPAQ FORMAT
|
||||
The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be a read-only game archive format, and excels at this role.
|
||||
|
||||
The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked.
|
||||
|
||||
StormLib - mentioned several times in this specification - is an open-source MoPaQ reading and writing library written by Ladislav Zezula (no affiliation with Blizzard Entertainment). While it's a bit dated, and does not support all of the newer MoPaQ features, it contains source code to the more exotic compression methods used by MoPaQ, such as the PKWare implode algorithm, MoPaQ's huffman compression algorithm, and the IMA ADPCM compression used by MoPaQ.
|
||||
|
||||
2. THE MOPAQ FORMAT
|
||||
All numbers in the MoPaQ format are in little endian byte order; signed numbers use the two's complement system. Data types are listed either as int (integer, the number of bits specified), byte (8 bits), or char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. Structure members are listed in the following general form:
|
||||
offset from the beginning of the structure: data type(array size) member name : member description
|
||||
|
||||
2.1 GENERAL ARCHIVE LAYOUT
|
||||
- Archive Header
|
||||
- File Data
|
||||
- File Data - Special Files
|
||||
- Hash Table
|
||||
- Block Table
|
||||
- Extended Block Table
|
||||
- Strong Digital signature
|
||||
|
||||
This is the usual archive format, but it is not mandatory. Some archives have been observed placing the hash table and file table after the archive header, and before the file data.
|
||||
|
||||
2.2 ARCHIVE HEADER
|
||||
00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah.
|
||||
04h: int32 HeaderSize : Size of the archive header.
|
||||
08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. This size is used, among other things, for determining the region to hash in computing the digital signature. This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive is calculated as the size from the beginning of the archive to the end of the hash table, block table, or extended block table (whichever is largest).
|
||||
0Ch: int16 FormatVersion : MoPaQ format version. MPQAPI will not open archives where this is negative. Known versions:
|
||||
0000h: Original format. HeaderSize should be 20h, and large archives are not supported.
|
||||
0001h: Burning Crusade format. Header size should be 2Ch, and large archives are supported.
|
||||
0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors).
|
||||
10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive.
|
||||
14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive.
|
||||
18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
|
||||
1Ch: int32 BlockTableEntries : Number of entries in the block table.
|
||||
Fields only present in the Burning Crusade format and later:
|
||||
20h: int64 ExtendedBlockTableOffset : Offset to the beginning of the extended block table, relative to the beginning of the archive.
|
||||
28h: int16 HashTableOffsetHigh : High 16 bits of the hash table offset for large archives.
|
||||
2Ah: int16 BlockTableOffsetHigh : High 16 bits of the block table offset for large archives.
|
||||
|
||||
The archive header is the first structure in the archive, at archive offset 0; however, the archive does not need to be at offset 0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer versions (due to the strong digital signature not being considered a part of the archive).
|
||||
|
||||
2.3 BLOCK TABLE
|
||||
The block table contains entries for each region in the archive. Regions may be either files, empty space, which may be overwritten by new files (typically this space is from deleted file data), or unused block table entries. Empty space entries should have BlockOffset and BlockSize nonzero, and FileSize and Flags zero; unused block table entries should have BlockSize, FileSize, and Flags zero. The block table is encrypted, using the hash of "(block table)" as the key. Each entry is structured as follows:
|
||||
|
||||
00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive.
|
||||
04h: int32 BlockSize : Size of the block in the archive.
|
||||
08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file; otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data.
|
||||
0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified:
|
||||
80000000h: Block is a file, and follows the file data format; otherwise, block is free space or unused. If the block is not a file, all other flags should be cleared, and FileSize should be 0.
|
||||
01000000h: File is stored as a single unit, rather than split into sectors.
|
||||
00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted.
|
||||
00010000h: File is encrypted.
|
||||
00000200h: File is compressed. File cannot be imploded.
|
||||
00000100h: File is imploded. File cannot be compressed.
|
||||
|
||||
2.4 EXTENDED BLOCK TABLE
|
||||
The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes). The table contains the upper bits of the archive offsets for each block in the block table. It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block, with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size.
|
||||
|
||||
As of the Burning Crusade Friends and Family beta, this table is not encrypted.
|
||||
|
||||
2.5 HASH TABLE
|
||||
Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows:
|
||||
|
||||
00h: int32 FilePathHashA : The hash of the file path, using method A.
|
||||
04h: int32 FilePathHashB : The hash of the file path, using method B.
|
||||
08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral.
|
||||
0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed.
|
||||
0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values:
|
||||
FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file.
|
||||
FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file.
|
||||
|
||||
2.6 FILE DATA
|
||||
The data for each file is composed of the following structure:
|
||||
00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector, relative to the beginning of the file data. The last entry contains the file size, making it possible to easily calculate the size of any given sector. This table is not present if this information can be calculated (see details below).
|
||||
immediately following SectorOffsetTable: SECTOR Sectors(SectorsInFile) : Data of each sector in the file, packed end to end (see details below).
|
||||
|
||||
Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may contain less than this, depending on the size of the entire file's data. If the file is compressed or imploded, the sector will be smaller or the same size as the file data it contains. Individual sectors in a compressed or imploded file may be stored uncompressed; this occurs if and only if the file data the sector contains could not be compressed by the algorithm(s) used (if the compressed sector size was greater than or equal to the size of the file data), and is indicated by the sector's size in SectorOffsetTable being equal to the size of the file data in the sector (which may be calculated from the FileSize).
|
||||
|
||||
The format of each sector depends on the kind of sector it is. Uncompressed sectors are simply the the raw file data contained in the sector. Imploded sectors are the raw compressed data following compression with the implode algorithm (these sectors can only be in imploded files). Compressed sectors (only found in compressed - not imploded - files) are compressed with one or more compression algorithms, and have the following structure:
|
||||
00h: byte CompressionMask : Mask of the compression types applied to this sector. If multiple compression types are used, they are applied in the order listed below, and decompression is performed in the opposite order. This byte counts towards the total sector size, meaning that the sector will be stored uncompressed if the data cannot be compressed by at least two bytes; as well, this byte is encrypted with the sector data, if applicable. The following compression types are defined (for implementations of these algorithms, see StormLib):
|
||||
40h: IMA ADPCM mono
|
||||
80h: IMA ADPCM stereo
|
||||
01h: Huffman encoded
|
||||
02h: Deflated (see ZLib)
|
||||
08h: Imploded (see PKWare Data Compression Library)
|
||||
10h: BZip2 compressed (see BZip2)
|
||||
01h: byte(SectorSize - 1) SectorData : The compressed data for the sector.
|
||||
|
||||
If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which contains the entire file data.
|
||||
|
||||
If the file is encrypted, each sector (after compression/implosion, if applicable) is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) XOR FileSize) (StormLib incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the 0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1.
|
||||
|
||||
The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. However, the SectorOffsetTable will be present if the file is compressed/imploded and the file is not stored as a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the archive's sector size).
|
||||
|
||||
2.7 LISTFILE
|
||||
The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)" (default language and platform), and is simply a text file with file paths separated by ';', 0Dh, 0Ah, or some combination of these. The file "(listfile)" may not be listed in the listfile.
|
||||
|
||||
2.8 EXTENDED ATTRIBUTES
|
||||
The extended attributes are optional file attributes for files in the block table. These attributes were added at times after the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file (default language and platform), in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This file is structured as follows:
|
||||
|
||||
00h: int32 Version : Specifies the extended attributes format version. For now, must be 100.
|
||||
04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive:
|
||||
00000001h: File CRC32s.
|
||||
00000002h: File timestamps.
|
||||
00000004h: File MD5s.
|
||||
08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have CRC32s.
|
||||
immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps.
|
||||
immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have MD5s.
|
||||
|
||||
2.9 WEAK DIGITAL SIGNATURE
|
||||
The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation
|
||||
of the RSASSA-PKCS1-v1_5 digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak)
|
||||
RSA key (for more information about this protocol, see the RSA Labs PKCS1 specification). The public key
|
||||
and exponent are stored in a resource in Storm, the private key is stored in a separate file, whose filename
|
||||
is passed to MPQAPI (the private key is not stored in MPQAPI). The signature is stored uncompressed,
|
||||
unencrypted in the file "(signature)" (default language and platform) in the archive. The archive
|
||||
is hashed from the beginning of the archive (ArchiveOffset in the containing file) to the end of
|
||||
the archive (the length indicated by ArchiveSize, or calculated in the Burning Crusade MoPaQ format);
|
||||
the signature file is added to the archive before signing, and the space occupied by the file is considered
|
||||
to be all binary 0s during signing/verification. This file is structured as follows:
|
||||
|
||||
00h: int32 Unknown : Must be 0.
|
||||
04h: int32 Unknown : Must be 0.
|
||||
08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored
|
||||
in little-endian order. The structure of this, when decrypted, follows the RSASSA-PKCS1-v1_5 specification;
|
||||
this format is rather icky to work with (I wrote a program to verify this signature using nothing but an MD5
|
||||
function and huge integer functions; it wasn't pleasant), and best left to an encryption library such as Cryto++.
|
||||
|
||||
2.10 STRONG DIGITAL SIGNATURE
|
||||
The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format:
|
||||
|
||||
00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards).
|
||||
04h: int2048 Signature : The digital signature, stored in little-endian format.
|
||||
|
||||
When the Signature field is decrypted with the public key and exponent, and the resulting large integer is stored in little-endian order, it is structured as follows:
|
||||
|
||||
00h: byte Padding : Must be 0Bh.
|
||||
01h: byte(235) Padding : Must be BBh.
|
||||
ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 byte order.
|
||||
|
||||
3. ALGORITHM SOURCE CODE
|
||||
All of the sample code here assumes little endian machine byte order, that the short type is 16 bits, that the long type is 32 bits, and that the long long type is 64 bits. Adjustments must be made if these assumptions are not correct on a given platform. All code not credited otherwise was written by myself in the writing of this specification.
|
||||
|
||||
3.1 ENCRYPTION/DECRYPTION
|
||||
Based on code from StormLib.
|
||||
|
||||
unsigned long dwCryptTable[0x500];
|
||||
|
||||
// The encryption and hashing functions use a number table in their procedures. This table must be initialized before the functions are called the first time.
|
||||
void InitializeCryptTable()
|
||||
{
|
||||
unsigned long seed = 0x00100001;
|
||||
unsigned long index1 = 0;
|
||||
unsigned long index2 = 0;
|
||||
int i;
|
||||
|
||||
for (index1 = 0; index1 < 0x100; index1++)
|
||||
{
|
||||
for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
|
||||
{
|
||||
unsigned long temp1, temp2;
|
||||
|
||||
seed = (seed * 125 + 3) % 0x2AAAAB;
|
||||
temp1 = (seed & 0xFFFF) << 0x10;
|
||||
|
||||
seed = (seed * 125 + 3) % 0x2AAAAB;
|
||||
temp2 = (seed & 0xFFFF);
|
||||
|
||||
dwCryptTable[index2] = (temp1 | temp2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
|
||||
{
|
||||
assert(lpbyBuffer);
|
||||
|
||||
unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
|
||||
unsigned long seed = 0xEEEEEEEE;
|
||||
unsigned long ch;
|
||||
|
||||
dwLength /= sizeof(unsigned long);
|
||||
|
||||
while(dwLength-- > 0)
|
||||
{
|
||||
seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
|
||||
ch = *lpdwBuffer ^ (dwKey + seed);
|
||||
|
||||
dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
|
||||
seed = *lpdwBuffer + seed + (seed << 5) + 3;
|
||||
|
||||
*lpdwBuffer++ = ch;
|
||||
}
|
||||
}
|
||||
|
||||
void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
|
||||
{
|
||||
assert(lpbyBuffer);
|
||||
|
||||
unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
|
||||
unsigned long seed = 0xEEEEEEEEL;
|
||||
unsigned long ch;
|
||||
|
||||
dwLength /= sizeof(unsigned long);
|
||||
|
||||
while(dwLength-- > 0)
|
||||
{
|
||||
seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
|
||||
ch = *lpdwBuffer ^ (dwKey + seed);
|
||||
|
||||
dwKey = ((~dwKey << 0x15) + 0x11111111L) | (dwKey >> 0x0B);
|
||||
seed = ch + seed + (seed << 5) + 3;
|
||||
|
||||
*lpdwBuffer++ = ch;
|
||||
}
|
||||
}
|
||||
|
||||
3.2 HASHING AND FILE KEY COMPUTATION
|
||||
These functions may have been derived from StormLib code at some point in the very distant past. It was so long ago that I don't remember for certain.
|
||||
|
||||
// Different types of hashes to make with HashString
|
||||
#define MPQ_HASH_TABLE_OFFSET 0
|
||||
#define MPQ_HASH_NAME_A 1
|
||||
#define MPQ_HASH_NAME_B 2
|
||||
#define MPQ_HASH_FILE_KEY 3
|
||||
|
||||
// Based on code from StormLib.
|
||||
unsigned long HashString(const char *lpszString, unsigned long dwHashType)
|
||||
{
|
||||
assert(lpszString);
|
||||
assert(dwHashType <= MPQ_HASH_FILE_KEY);
|
||||
|
||||
unsigned long seed1 = 0x7FED7FEDL;
|
||||
unsigned long seed2 = 0xEEEEEEEEL;
|
||||
int ch;
|
||||
|
||||
while (*lpszString != 0)
|
||||
{
|
||||
ch = toupper(*lpszString++);
|
||||
|
||||
seed1 = dwCryptTable[(dwHashType * 0x100) + ch] ^ (seed1 + seed2);
|
||||
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
|
||||
}
|
||||
return seed1;
|
||||
}
|
||||
|
||||
#define BLOCK_OFFSET_ADJUSTED_KEY 0x00020000L
|
||||
|
||||
unsigned long ComputeFileKey(const char *lpszFilePath, const BlockTableEntry &blockEntry, unsigned long nArchiveOffset)
|
||||
{
|
||||
assert(lpszFilePath);
|
||||
|
||||
// Find the file name part of the path
|
||||
const char *lpszFileName = strrchr(lpszFilePath, '\\');
|
||||
if (lpszFileName)
|
||||
lpszFileName++; // Skip the \
|
||||
else
|
||||
lpszFileName = lpszFilePath;
|
||||
|
||||
// Hash the name to get the base key
|
||||
unsigned long nFileKey = HashString(lpszFileName, MPQ_HASH_FILE_KEY);
|
||||
|
||||
// Offset-adjust the key if necessary
|
||||
if (blockEntry.Flags & BLOCK_OFFSET_ADJUSTED_KEY)
|
||||
nFileKey = (nFileKey + blockEntry.BlockOffset) ^ blockEntry.FileSize;
|
||||
|
||||
return nFileKey;
|
||||
}
|
||||
|
||||
3.3 FINDING FILES
|
||||
|
||||
#define MPQ_HASH_ENTRY_EMPTY 0xFFFFFFFFL
|
||||
#define MPQ_HASH_ENTRY_DELETED 0xFFFFFFFEL
|
||||
|
||||
bool FindFileInHashTable(const HashTableEntry *lpHashTable, unsigned long nHashTableSize, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform, unsigned long &iFileHashEntry)
|
||||
{
|
||||
assert(lpHashTable);
|
||||
assert(nHashTableSize);
|
||||
assert(lpszFilePath);
|
||||
|
||||
// Find the home entry in the hash table for the file
|
||||
unsigned long iInitEntry = HashString(lpszFilePath, MPQ_HASH_TABLE_OFFSET) & (nHashTableSize - 1);
|
||||
|
||||
// Is there anything there at all?
|
||||
if (lpHashTable[iInitEntry].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY)
|
||||
return false;
|
||||
|
||||
// Compute the hashes to compare the hash table entry against
|
||||
unsigned long nNameHashA = HashString(lpszFilePath, MPQ_HASH_NAME_A),
|
||||
nNameHashB = HashString(lpszFilePath, MPQ_HASH_NAME_B),
|
||||
iCurEntry = iInitEntry;
|
||||
|
||||
// Check each entry in the hash table till a termination point is reached
|
||||
do
|
||||
{
|
||||
if (lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_DELETED)
|
||||
{
|
||||
if (lpHashTable[iCurEntry].FilePathHashA == nNameHashA
|
||||
&& lpHashTable[iCurEntry].FilePathHashB == nNameHashB
|
||||
&& lpHashTable[iCurEntry].Language == nLang
|
||||
&& lpHashTable[iCurEntry].Platform == nPlatform)
|
||||
{
|
||||
iFileHashEntry = iCurEntry;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
iCurEntry = (iCurEntry + 1) & (nHashTableSize - 1);
|
||||
} while (iCurEntry != iInitEntry && lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_EMPTY);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
3.4 DELETING FILES
|
||||
|
||||
bool DeleteFile(HashTableEntry *lpHashTable, unsigned long nHashTableSize, BlockTableEntry *lpBlockTable, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform)
|
||||
{
|
||||
assert(lpHashTable);
|
||||
assert(nHashTableSize);
|
||||
assert(lpBlockTable);
|
||||
|
||||
// Find the file in the hash table
|
||||
unsigned long iFileHashEntry;
|
||||
|
||||
if (!FindFileInHashTable(lpHashTable, nHashTableSize, lpszFilePath, nLang, nPlatform, iFileHashEntry))
|
||||
return false;
|
||||
|
||||
// Get the block table index before we nuke the hash table entry
|
||||
unsigned long iFileBlockEntry = lpHashTable[iFileHashEntry].FileBlockIndex;
|
||||
|
||||
// Delete the file's entry in the hash table
|
||||
memset(&lpHashTable[iFileHashEntry], 0xFF, sizeof(HashTableEntry));
|
||||
|
||||
// If the next entry is empty, mark this one as empty; otherwise, mark this as deleted.
|
||||
if (lpHashTable[(iFileHashEntry + 1) & (nHashTableSize - 1)].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY)
|
||||
lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_EMPTY;
|
||||
else
|
||||
lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_DELETED;
|
||||
|
||||
// If the block occupies space, mark the block as free space; otherwise, clear the block table entry.
|
||||
if (lpBlockTable[iFileBlockEntry].BlockSize > 0)
|
||||
{
|
||||
lpBlockTable[iFileBlockEntry].FileSize = 0;
|
||||
lpBlockTable[iFileBlockEntry].Flags = 0;
|
||||
}
|
||||
else
|
||||
memset(&lpBlockTable[iFileBlockEntry], 0, sizeof(BlockTableEntry);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
3.5 CONVERSION OF FILETIME AND time_t
|
||||
This code assumes that the base ("zero") date for time_t is 01/01/1970. This is true on Windows, Unix System V systems, and Mac OS X. It is unknown whether this is true on all other platforms. You'll need to research this yourself, if you plan on porting it somewhere else.
|
||||
|
||||
#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970
|
||||
|
||||
bool GetTimeFromFileTime(const FILETIME &fileTime, time_t &time)
|
||||
{
|
||||
// The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601
|
||||
unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
|
||||
|
||||
if (nTime < EPOCH_OFFSET)
|
||||
return false;
|
||||
|
||||
nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970
|
||||
nTime /= 10000000ULL; // Convert 100 ns to sec
|
||||
|
||||
time = (time_t)nTime;
|
||||
|
||||
// Test for overflow (FILETIME is 64 bits, time_t is 32 bits)
|
||||
if ((nTime - (unsigned long long)time) > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetFileTimeFromTime(const time_t &time, FILETIME &fileTime)
|
||||
{
|
||||
unsigned long long nTime = (unsigned long long)time;
|
||||
|
||||
nTime *= 10000000ULL;
|
||||
nTime += EPOCH_OFFSET;
|
||||
|
||||
fileTime.dwLowDateTime = (DWORD)nTime;
|
||||
fileTime.dwHighDateTime = (DWORD)(nTime >> 32);
|
||||
}
|
||||
|
||||
3.6 FORMING A 64-BIT LARGE ARCHIVE OFFSET FROM 32-BIT AND 16-BIT COMPONENTS
|
||||
unsigned long long MakeLargeArchiveOffset(unsigned long nOffsetLow, unsigned short nOffsetHigh)
|
||||
{
|
||||
return ((unsigned long long)nOffsetHigh << 32) + (unsigned long long)nOffsetLow;
|
||||
}
|
||||
|
||||
4. REVISION HISTORY
|
||||
1.0
|
||||
- Updated to include most of the changes found in the Burning Crusade Friends and Family beta
|
||||
|
||||
0.91.
|
||||
- Updated several structure member descriptions
|
||||
- Listed the full set of characters that can separate list file entries
|
||||
- Noted that (attributes), (listfile), and (signature) use the default language and platform codes
|
||||
- Redid part of the file data specs to clarify the format of sectors
|
||||
- Enhanced descriptions of the different kinds of block table entries
|
||||
- Added ComputeFileKey, FindFileInHashTable, and DeleteFile source
|
@ -0,0 +1 @@
|
||||
UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK
|
@ -0,0 +1 @@
|
||||
MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP
|
@ -0,0 +1 @@
|
||||
8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP
|
@ -0,0 +1 @@
|
||||
EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ
|
@ -0,0 +1 @@
|
||||
PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT
|
@ -0,0 +1 @@
|
||||
X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2
|
@ -0,0 +1 @@
|
||||
5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2
|
@ -0,0 +1 @@
|
||||
478JD2K56EVNVVY4XX8TDWYT5B8KB254
|
@ -0,0 +1 @@
|
||||
8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A
|
@ -0,0 +1 @@
|
||||
LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB
|
@ -0,0 +1 @@
|
||||
K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG
|
@ -0,0 +1 @@
|
||||
6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H
|
@ -0,0 +1 @@
|
||||
S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U
|
@ -0,0 +1 @@
|
||||
Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX
|
@ -0,0 +1 @@
|
||||
G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH
|
@ -0,0 +1 @@
|
||||
3DH5RE5NVM5GTFD85LXGWT6FK859ETR5
|
@ -0,0 +1 @@
|
||||
8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ
|
@ -0,0 +1 @@
|
||||
A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54
|
@ -0,0 +1 @@
|
||||
ZG7J9K938HJEFWPQUA768MA2PFER6EAJ
|
@ -0,0 +1 @@
|
||||
NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2
|
@ -0,0 +1 @@
|
||||
3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F
|
@ -0,0 +1 @@
|
||||
2NSFB8MELULJ83U6YHA3UP6K4MQD48L6
|
@ -0,0 +1 @@
|
||||
QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E
|
@ -0,0 +1 @@
|
||||
VHB378W64BAT9SH7D68VV9NLQDK9YEGT
|
@ -0,0 +1 @@
|
||||
U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE
|
60
StormLib/make-msvc.bat
Normal file
60
StormLib/make-msvc.bat
Normal file
@ -0,0 +1,60 @@
|
||||
:: Build file for Visual Studio 2008 and 2017
|
||||
@echo off
|
||||
|
||||
:: Save the values of INCLUDE, LIB and PATH
|
||||
set SAVE_INCLUDE=%INCLUDE%
|
||||
set SAVE_LIB=%LIB%
|
||||
set SAVE_PATH=%PATH%
|
||||
set LIB_NAME=StormLib
|
||||
|
||||
:: Determine where the program files are, both for 64-bit and 32-bit Windows
|
||||
if exist "%ProgramFiles%" set PROGRAM_FILES_DIR=%ProgramFiles%
|
||||
if exist "%ProgramFiles(x86)%" set PROGRAM_FILES_DIR=%ProgramFiles(x86)%
|
||||
|
||||
:: Determine the installed version of Visual Studio (Prioritize Enterprise over Professional)
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" set VCVARS_2008=%PROGRAM_FILES_DIR%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat
|
||||
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat
|
||||
|
||||
::Build all libraries using Visual Studio 2008 and 2017
|
||||
call :BuildLibs "%VCVARS_2008%" x86 %LIB_NAME%_vs08.sln
|
||||
call :BuildLibs "%VCVARS_2008%" x64 %LIB_NAME%_vs08.sln
|
||||
call :BuildLibs "%VCVARS_2019%" x86 %LIB_NAME%_vs19.sln
|
||||
call :BuildLibs "%VCVARS_2019%" x64 %LIB_NAME%_vs19.sln
|
||||
goto:eof
|
||||
|
||||
::-----------------------------------------------------------------------------
|
||||
:: Build all 8 configurations of the library
|
||||
::
|
||||
:: Parameters:
|
||||
::
|
||||
:: %1 Full path to the VCVARS.BAT file
|
||||
:: %2 Target build platform (x86 or x64)
|
||||
:: %3 Plain name of the /sln solution file
|
||||
::
|
||||
|
||||
:BuildLibs
|
||||
::set VSCMD_DEBUG=1
|
||||
call %1 %2
|
||||
if "%2" == "x86" set SLN_TRG=Win32
|
||||
if "%2" == "x64" set SLN_TRG=x64
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugAD|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugAS|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugUD|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugUS|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseAD|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseAS|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseUD|%SLN_TRG%"
|
||||
devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseUS|%SLN_TRG%"
|
||||
|
||||
:: Restore environment variables to the old level
|
||||
set INCLUDE=%SAVE_INCLUDE%
|
||||
set LIB=%SAVE_LIB%
|
||||
set PATH=%SAVE_PATH%
|
||||
set VSINSTALLDIR=
|
||||
set VCINSTALLDIR=
|
||||
set DevEnvDir=
|
46
StormLib/make.bat
Normal file
46
StormLib/make.bat
Normal file
@ -0,0 +1,46 @@
|
||||
@echo off
|
||||
if not "x%WDKDIR%" == "x" goto SELECT_LIB
|
||||
echo The WDKDIR environment variable is not set
|
||||
echo Set this variable to your WDK directory (without ending backslash)
|
||||
echo Example: set WDKDIR C:\WinDDK\6001
|
||||
pause
|
||||
goto:eof
|
||||
|
||||
:SELECT_LIB
|
||||
set PROJECT_DIR=%~dp0
|
||||
set LIBRARY_NAME=StormLibWDK
|
||||
|
||||
:PREPARE_SOURCES
|
||||
echo Preparing sources ...
|
||||
copy .\src\wdk\sources-cpp.cpp . >nul
|
||||
copy .\src\wdk\sources-wdk-* . >nul
|
||||
echo.
|
||||
|
||||
:BUILD_LIB_32
|
||||
echo Building %LIBRARY_NAME%.lib (32-bit) ...
|
||||
set DDKBUILDENV=
|
||||
call %WDKDIR%\bin\setenv.bat %WDKDIR%\ fre w2k
|
||||
cd %PROJECT_DIR%
|
||||
build.exe -czgw
|
||||
del buildfre_w2k_x86.log
|
||||
echo.
|
||||
|
||||
:BUILD_LIB_64
|
||||
echo Building %LIBRARY_NAME%.lib (64-bit) ...
|
||||
set DDKBUILDENV=
|
||||
call %WDKDIR%\bin\setenv.bat %WDKDIR%\ fre x64 WLH
|
||||
cd %PROJECT_DIR%
|
||||
build.exe -czgw
|
||||
del buildfre_wlh_amd64.log
|
||||
echo.
|
||||
|
||||
:COPY_LIBS
|
||||
copy /Y .\objfre_wlh_amd64\amd64\%LIBRARY_NAME%.lib ..\aaa\lib64\%LIBRARY_NAME%.lib >nul
|
||||
copy /Y .\objfre_w2k_x86\i386\%LIBRARY_NAME%.lib ..\aaa\lib32\%LIBRARY_NAME%.lib >nul
|
||||
copy /Y .\src\StormPort.h ..\aaa\inc >nul
|
||||
copy /Y .\src\StormLib.h ..\aaa\inc >nul
|
||||
|
||||
:CLEANUP
|
||||
if exist sources-cpp.cpp del sources-cpp.cpp
|
||||
if exist sources-wdk-* del sources-wdk-*
|
||||
if exist build.bat del build.bat
|
14
StormLib/sources
Normal file
14
StormLib/sources
Normal file
@ -0,0 +1,14 @@
|
||||
TARGETNAME=StormLibWDK
|
||||
TARGETTYPE=LIBRARY
|
||||
USE_MSVCRT=1
|
||||
|
||||
C_DEFINES=$(C_DEFINES) -DUNICODE -D_UNICODE -DWDK_BUILD
|
||||
|
||||
SOURCES=sources-cpp.cpp \
|
||||
sources-wdk-bzip2.c \
|
||||
sources-wdk-ltc.c \
|
||||
sources-wdk-lzma.c \
|
||||
sources-wdk-misc.c \
|
||||
sources-wdk-tomcrypt.c \
|
||||
sources-wdk-tommath.c \
|
||||
sources-wdk-zlib.c
|
24
StormLib/src/DllMain.c
Normal file
24
StormLib/src/DllMain.c
Normal file
@ -0,0 +1,24 @@
|
||||
/*****************************************************************************/
|
||||
/* DllMain.c Copyright (c) Ladislav Zezula 2006 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: DllMain for the StormLib.dll library */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 23.11.06 1.00 Lad The first version of DllMain.c */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DllMain
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hInst);
|
||||
UNREFERENCED_PARAMETER(dwReason);
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
|
||||
return TRUE;
|
||||
}
|
79
StormLib/src/DllMain.def
Normal file
79
StormLib/src/DllMain.def
Normal file
@ -0,0 +1,79 @@
|
||||
;
|
||||
; Export file for Windows
|
||||
; Copyright (c) 2007-2010 Ladislav Zezula
|
||||
; ladik@zezula.net
|
||||
;
|
||||
|
||||
LIBRARY StormLib.dll
|
||||
|
||||
EXPORTS
|
||||
|
||||
SFileSetLocale
|
||||
SFileGetLocale
|
||||
|
||||
SFileOpenArchive
|
||||
SFileCreateArchive
|
||||
SFileCreateArchive2
|
||||
SFileFlushArchive
|
||||
SFileCloseArchive
|
||||
|
||||
SFileAddListFile
|
||||
|
||||
SFileSetCompactCallback
|
||||
SFileCompactArchive
|
||||
|
||||
SFileGetMaxFileCount
|
||||
SFileSetMaxFileCount
|
||||
|
||||
SFileGetAttributes
|
||||
SFileSetAttributes
|
||||
SFileUpdateFileAttributes
|
||||
|
||||
SFileOpenPatchArchive
|
||||
SFileIsPatchedArchive
|
||||
|
||||
SFileOpenFileEx
|
||||
SFileGetFileSize
|
||||
SFileSetFilePointer
|
||||
SFileReadFile
|
||||
SFileCloseFile
|
||||
|
||||
SFileHasFile
|
||||
SFileGetFileName
|
||||
SFileGetFileInfo
|
||||
|
||||
SFileExtractFile
|
||||
|
||||
SFileVerifyFile
|
||||
SFileVerifyRawData
|
||||
SFileVerifyArchive
|
||||
|
||||
SFileFindFirstFile
|
||||
SFileFindNextFile
|
||||
SFileFindClose
|
||||
|
||||
SListFileFindFirstFile
|
||||
SListFileFindNextFile
|
||||
SListFileFindClose
|
||||
|
||||
SFileEnumLocales
|
||||
|
||||
SFileCreateFile
|
||||
SFileWriteFile
|
||||
SFileFinishFile
|
||||
SFileAddFileEx
|
||||
SFileAddFile
|
||||
SFileAddWave
|
||||
SFileRemoveFile
|
||||
SFileRenameFile
|
||||
SFileSetFileLocale
|
||||
SFileSetDataCompression
|
||||
SFileSetAddFileCallback
|
||||
|
||||
SCompImplode
|
||||
SCompExplode
|
||||
SCompCompress
|
||||
SCompDecompress
|
||||
|
||||
GetLastError=Kernel32.GetLastError
|
||||
SetLastError=Kernel32.SetLastError
|
114
StormLib/src/DllMain.rc
Normal file
114
StormLib/src/DllMain.rc
Normal file
@ -0,0 +1,114 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Neutral resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
#pragma code_page(1250)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 9,22,0,3
|
||||
PRODUCTVERSION 9,22,0,3
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x0L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040504b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "http://www.zezula.net/mpq.html"
|
||||
VALUE "FileDescription", "StormLib library for reading Blizzard MPQ archives"
|
||||
VALUE "FileVersion", "9, 22, 0, 3\0"
|
||||
VALUE "InternalName", "StormLib"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2014 - 2020 Ladislav Zezula"
|
||||
VALUE "OriginalFilename", "StormLib.dll"
|
||||
VALUE "ProductName", "StormLib"
|
||||
VALUE "ProductVersion", "9, 22, 0, 3\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x405, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // Neutral resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Czech resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
|
||||
#pragma code_page(1250)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Czech resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
2923
StormLib/src/FileStream.cpp
Normal file
2923
StormLib/src/FileStream.cpp
Normal file
File diff suppressed because it is too large
Load Diff
217
StormLib/src/FileStream.h
Normal file
217
StormLib/src/FileStream.h
Normal file
@ -0,0 +1,217 @@
|
||||
/*****************************************************************************/
|
||||
/* 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__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
{
|
||||
SFILE_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 MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
|
||||
|
||||
struct TEncryptedStream : public TBlockStream
|
||||
{
|
||||
BYTE Key[MPQE_CHUNK_SIZE]; // File key
|
||||
};
|
||||
|
||||
#endif // __FILESTREAM_H__
|
2045
StormLib/src/SBaseCommon.cpp
Normal file
2045
StormLib/src/SBaseCommon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
183
StormLib/src/SBaseDumpData.cpp
Normal file
183
StormLib/src/SBaseDumpData.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/*****************************************************************************/
|
||||
/* SBaseDumpData.cpp Copyright (c) Ladislav Zezula 2011 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description : */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 26.01.11 1.00 Lad The first version of SBaseDumpData.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
#ifdef __STORMLIB_DUMP_DATA__
|
||||
|
||||
void DumpMpqHeader(TMPQHeader * pHeader)
|
||||
{
|
||||
printf("== MPQ Header =================================\n");
|
||||
printf("DWORD dwID = %08X\n", pHeader->dwID);
|
||||
printf("DWORD dwHeaderSize = %08X\n", pHeader->dwHeaderSize);
|
||||
printf("DWORD dwArchiveSize = %08X\n", pHeader->dwArchiveSize);
|
||||
printf("USHORT wFormatVersion = %04X\n", pHeader->wFormatVersion);
|
||||
printf("USHORT wSectorSize = %04X\n", pHeader->wSectorSize);
|
||||
printf("DWORD dwHashTablePos = %08X\n", pHeader->dwHashTablePos);
|
||||
printf("DWORD dwBlockTablePos = %08X\n", pHeader->dwBlockTablePos);
|
||||
printf("DWORD dwHashTableSize = %08X\n", pHeader->dwHashTableSize);
|
||||
printf("DWORD dwBlockTableSize = %08X\n", pHeader->dwBlockTableSize);
|
||||
printf("ULONGLONG HiBlockTablePos64 = %016llX\n", pHeader->HiBlockTablePos64);
|
||||
printf("USHORT wHashTablePosHi = %04X\n", pHeader->wHashTablePosHi);
|
||||
printf("USHORT wBlockTablePosHi = %04X\n", pHeader->wBlockTablePosHi);
|
||||
printf("ULONGLONG ArchiveSize64 = %016llX\n", pHeader->ArchiveSize64);
|
||||
printf("ULONGLONG BetTablePos64 = %016llX\n", pHeader->BetTablePos64);
|
||||
printf("ULONGLONG HetTablePos64 = %016llX\n", pHeader->HetTablePos64);
|
||||
printf("ULONGLONG HashTableSize64 = %016llX\n", pHeader->HashTableSize64);
|
||||
printf("ULONGLONG BlockTableSize64 = %016llX\n", pHeader->BlockTableSize64);
|
||||
printf("ULONGLONG HiBlockTableSize64 = %016llX\n", pHeader->HiBlockTableSize64);
|
||||
printf("ULONGLONG HetTableSize64 = %016llX\n", pHeader->HetTableSize64);
|
||||
printf("ULONGLONG BetTableSize64 = %016llX\n", pHeader->BetTableSize64);
|
||||
printf("DWORD dwRawChunkSize = %08X\n", pHeader->dwRawChunkSize);
|
||||
printf("-----------------------------------------------\n\n");
|
||||
}
|
||||
|
||||
void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if(pHashTable == NULL || dwHashTableSize == 0)
|
||||
return;
|
||||
|
||||
printf("== Hash Table =================================\n");
|
||||
for(i = 0; i < dwHashTableSize; i++)
|
||||
{
|
||||
printf("[%08x] %08X %08X %04X %02X %08X\n", i,
|
||||
pHashTable[i].dwName1,
|
||||
pHashTable[i].dwName2,
|
||||
pHashTable[i].lcLocale,
|
||||
pHashTable[i].Platform,
|
||||
pHashTable[i].dwBlockIndex);
|
||||
}
|
||||
printf("-----------------------------------------------\n\n");
|
||||
}
|
||||
|
||||
void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if(pHetTable == NULL || pBetTable == NULL)
|
||||
return;
|
||||
|
||||
printf("== HET Header =================================\n");
|
||||
printf("ULONGLONG AndMask64 = %016llX\n", pHetTable->AndMask64);
|
||||
printf("ULONGLONG OrMask64 = %016llX\n", pHetTable->OrMask64);
|
||||
printf("DWORD dwEntryCount = %08X\n", pHetTable->dwEntryCount);
|
||||
printf("DWORD dwTotalCount = %08X\n", pHetTable->dwTotalCount);
|
||||
printf("DWORD dwNameHashBitSize = %08X\n", pHetTable->dwNameHashBitSize);
|
||||
printf("DWORD dwIndexSizeTotal = %08X\n", pHetTable->dwIndexSizeTotal);
|
||||
printf("DWORD dwIndexSizeExtra = %08X\n", pHetTable->dwIndexSizeExtra);
|
||||
printf("DWORD dwIndexSize = %08X\n", pHetTable->dwIndexSize);
|
||||
printf("-----------------------------------------------\n\n");
|
||||
|
||||
printf("== BET Header =================================\n");
|
||||
printf("DWORD dwTableEntrySize = %08X\n", pBetTable->dwTableEntrySize);
|
||||
printf("DWORD dwBitIndex_FilePos = %08X\n", pBetTable->dwBitIndex_FilePos);
|
||||
printf("DWORD dwBitIndex_FileSize = %08X\n", pBetTable->dwBitIndex_FileSize);
|
||||
printf("DWORD dwBitIndex_CmpSize = %08X\n", pBetTable->dwBitIndex_CmpSize);
|
||||
printf("DWORD dwBitIndex_FlagIndex = %08X\n", pBetTable->dwBitIndex_FlagIndex);
|
||||
printf("DWORD dwBitIndex_Unknown = %08X\n", pBetTable->dwBitIndex_Unknown);
|
||||
printf("DWORD dwBitCount_FilePos = %08X\n", pBetTable->dwBitCount_FilePos);
|
||||
printf("DWORD dwBitCount_FileSize = %08X\n", pBetTable->dwBitCount_FileSize);
|
||||
printf("DWORD dwBitCount_CmpSize = %08X\n", pBetTable->dwBitCount_CmpSize);
|
||||
printf("DWORD dwBitCount_FlagIndex = %08X\n", pBetTable->dwBitCount_FlagIndex);
|
||||
printf("DWORD dwBitCount_Unknown = %08X\n", pBetTable->dwBitCount_Unknown);
|
||||
printf("DWORD dwBitTotal_NameHash2 = %08X\n", pBetTable->dwBitTotal_NameHash2);
|
||||
printf("DWORD dwBitExtra_NameHash2 = %08X\n", pBetTable->dwBitExtra_NameHash2);
|
||||
printf("DWORD dwBitCount_NameHash2 = %08X\n", pBetTable->dwBitCount_NameHash2);
|
||||
printf("DWORD dwEntryCount = %08X\n", pBetTable->dwEntryCount);
|
||||
printf("DWORD dwFlagCount = %08X\n", pBetTable->dwFlagCount);
|
||||
printf("-----------------------------------------------\n\n");
|
||||
|
||||
printf("== HET & Bet Table ======================================================================\n\n");
|
||||
printf("HetIdx HetHash BetIdx BetHash ByteOffset FileSize CmpSize FlgIdx Flags \n");
|
||||
printf("------ ------- ------ ---------------- ---------------- -------- -------- ------ --------\n");
|
||||
for(i = 0; i < pHetTable->dwTotalCount; i++)
|
||||
{
|
||||
ULONGLONG ByteOffset = 0;
|
||||
ULONGLONG BetHash = 0;
|
||||
DWORD dwFileSize = 0;
|
||||
DWORD dwCmpSize = 0;
|
||||
DWORD dwFlagIndex = 0;
|
||||
DWORD dwFlags = 0;
|
||||
DWORD dwBetIndex = 0;
|
||||
|
||||
GetMPQBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal,
|
||||
pHetTable->dwIndexSize,
|
||||
&dwBetIndex, 4);
|
||||
|
||||
if(dwBetIndex < pHetTable->dwTotalCount)
|
||||
{
|
||||
DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex;
|
||||
|
||||
GetMPQBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2,
|
||||
pBetTable->dwBitCount_NameHash2,
|
||||
&BetHash, 8);
|
||||
|
||||
GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos,
|
||||
pBetTable->dwBitCount_FilePos,
|
||||
&ByteOffset, 8);
|
||||
|
||||
GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize,
|
||||
pBetTable->dwBitCount_FileSize,
|
||||
&dwFileSize, 4);
|
||||
|
||||
GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize,
|
||||
pBetTable->dwBitCount_CmpSize,
|
||||
&dwCmpSize, 4);
|
||||
|
||||
GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex,
|
||||
pBetTable->dwBitCount_FlagIndex,
|
||||
&dwFlagIndex, 4);
|
||||
|
||||
dwFlags = pBetTable->pFileFlags[dwFlagIndex];
|
||||
}
|
||||
|
||||
printf(" %04X %02lX %04X %016llX %016llX %08X %08X %04X %08X\n", i,
|
||||
pHetTable->pNameHashes[i],
|
||||
dwBetIndex,
|
||||
BetHash,
|
||||
ByteOffset,
|
||||
dwFileSize,
|
||||
dwCmpSize,
|
||||
dwFlagIndex,
|
||||
dwFlags);
|
||||
}
|
||||
printf("-----------------------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if(pFileTable == NULL || dwFileTableSize == 0)
|
||||
return;
|
||||
|
||||
printf("== File Table =================================\n");
|
||||
for(i = 0; i < dwFileTableSize; i++, pFileTable++)
|
||||
{
|
||||
printf("[%04u] %08X-%08X %08X-%08X %08X-%08X 0x%08X 0x%08X 0x%08X %s\n", i,
|
||||
(DWORD)(pFileTable->FileNameHash >> 0x20),
|
||||
(DWORD)(pFileTable->FileNameHash & 0xFFFFFFFF),
|
||||
(DWORD)(pFileTable->ByteOffset >> 0x20),
|
||||
(DWORD)(pFileTable->ByteOffset & 0xFFFFFFFF),
|
||||
(DWORD)(pFileTable->FileTime >> 0x20),
|
||||
(DWORD)(pFileTable->FileTime & 0xFFFFFFFF),
|
||||
pFileTable->dwFileSize,
|
||||
pFileTable->dwCmpSize,
|
||||
pFileTable->dwFlags,
|
||||
pFileTable->szFileName != NULL ? pFileTable->szFileName : "");
|
||||
}
|
||||
printf("-----------------------------------------------\n\n");
|
||||
}
|
||||
|
||||
#endif // __STORMLIB_DUMP_DATA__
|
3101
StormLib/src/SBaseFileTable.cpp
Normal file
3101
StormLib/src/SBaseFileTable.cpp
Normal file
File diff suppressed because it is too large
Load Diff
618
StormLib/src/SBaseSubTypes.cpp
Normal file
618
StormLib/src/SBaseSubTypes.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
/*****************************************************************************/
|
||||
/* SBaseSubTypes.cpp Copyright (c) Ladislav Zezula 2013 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Conversion routines for archive formats that are similar to MPQ format */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 02.11.11 1.00 Lad The first version of SBaseSubTypes.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Support for SQP file format (War of the Immortals) */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _TSQPHeader
|
||||
{
|
||||
// The ID_MPQ ('MPQ\x1A') signature
|
||||
DWORD dwID;
|
||||
|
||||
// Size of the archive header
|
||||
DWORD dwHeaderSize;
|
||||
|
||||
// 32-bit size of MPQ archive
|
||||
DWORD dwArchiveSize;
|
||||
|
||||
// Offset to the beginning of the hash table, relative to the beginning of the archive.
|
||||
DWORD dwHashTablePos;
|
||||
|
||||
// Offset to the beginning of the block table, relative to the beginning of the archive.
|
||||
DWORD dwBlockTablePos;
|
||||
|
||||
// Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
|
||||
// the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
|
||||
DWORD dwHashTableSize;
|
||||
|
||||
// Number of entries in the block table
|
||||
DWORD dwBlockTableSize;
|
||||
|
||||
// Must be zero for SQP files
|
||||
USHORT wFormatVersion;
|
||||
|
||||
// Power of two exponent specifying the number of 512-byte disk sectors in each file sector
|
||||
// in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize.
|
||||
USHORT wSectorSize;
|
||||
|
||||
} TSQPHeader;
|
||||
|
||||
typedef struct _TSQPHash
|
||||
{
|
||||
// Most likely the lcLocale+wPlatform.
|
||||
DWORD dwAlwaysZero;
|
||||
|
||||
// If the hash table entry is valid, this is the index into the block table of the file.
|
||||
// Otherwise, one of the following two values:
|
||||
// - FFFFFFFFh: Hash table entry is empty, and has always been empty.
|
||||
// Terminates searches for a given file.
|
||||
// - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
|
||||
// Does not terminate searches for a given file.
|
||||
DWORD dwBlockIndex;
|
||||
|
||||
// The hash of the file path, using method A.
|
||||
DWORD dwName1;
|
||||
|
||||
// The hash of the file path, using method B.
|
||||
DWORD dwName2;
|
||||
|
||||
} TSQPHash;
|
||||
|
||||
typedef struct _TSQPBlock
|
||||
{
|
||||
// Offset of the beginning of the file, relative to the beginning of the archive.
|
||||
DWORD dwFilePos;
|
||||
|
||||
// Flags for the file. See MPQ_FILE_XXXX constants
|
||||
DWORD dwFlags;
|
||||
|
||||
// Compressed file size
|
||||
DWORD dwCSize;
|
||||
|
||||
// Uncompressed file size
|
||||
DWORD dwFSize;
|
||||
|
||||
} TSQPBlock;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions - SQP file format
|
||||
|
||||
// This function converts SQP file header into MPQ file header
|
||||
DWORD ConvertSqpHeaderToFormat4(
|
||||
TMPQArchive * ha,
|
||||
ULONGLONG FileSize,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
TSQPHeader * pSqpHeader = (TSQPHeader *)ha->HeaderData;
|
||||
TMPQHeader Header;
|
||||
|
||||
// SQP files from War of the Immortal use MPQ file format with slightly
|
||||
// modified structure. These fields have different position:
|
||||
//
|
||||
// Offset TMPQHeader TSQPHeader
|
||||
// ------ ---------- -----------
|
||||
// 000C wFormatVersion dwHashTablePos (lo)
|
||||
// 000E wSectorSize dwHashTablePos (hi)
|
||||
// 001C dwBlockTableSize (lo) wBlockSize
|
||||
// 001E dwHashTableSize (hi) wFormatVersion
|
||||
|
||||
// Can't open the archive with certain flags
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
// The file must not be greater than 4 GB
|
||||
if((FileSize >> 0x20) != 0)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
// Translate the SQP header into a MPQ header
|
||||
memset(&Header, 0, sizeof(TMPQHeader));
|
||||
Header.dwID = BSWAP_INT32_UNSIGNED(pSqpHeader->dwID);
|
||||
Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHeaderSize);
|
||||
Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwArchiveSize);
|
||||
Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTablePos);
|
||||
Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTablePos);
|
||||
Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTableSize);
|
||||
Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTableSize);
|
||||
Header.wFormatVersion = BSWAP_INT16_UNSIGNED(pSqpHeader->wFormatVersion);
|
||||
Header.wSectorSize = BSWAP_INT16_UNSIGNED(pSqpHeader->wSectorSize);
|
||||
|
||||
// Verify the SQP header
|
||||
if(Header.dwID == g_dwMpqSignature && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize)
|
||||
{
|
||||
// Check for fixed values of version and sector size
|
||||
if(Header.wFormatVersion == MPQ_FORMAT_VERSION_1 && Header.wSectorSize == 3)
|
||||
{
|
||||
// Initialize the fields of 3.0 header
|
||||
Header.ArchiveSize64 = Header.dwArchiveSize;
|
||||
Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash);
|
||||
Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock);
|
||||
|
||||
// Copy the converted MPQ header back
|
||||
memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader));
|
||||
|
||||
// Mark this file as SQP file
|
||||
ha->pfnHashString = HashStringSlash;
|
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY;
|
||||
ha->dwSubType = MPQ_SUBTYPE_SQP;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
void * LoadSqpTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize, DWORD dwKey)
|
||||
{
|
||||
ULONGLONG ByteOffset;
|
||||
LPBYTE pbSqpTable;
|
||||
|
||||
// Allocate buffer for the table
|
||||
pbSqpTable = STORM_ALLOC(BYTE, cbTableSize);
|
||||
if(pbSqpTable != NULL)
|
||||
{
|
||||
// Load the table
|
||||
ByteOffset = ha->MpqPos + dwByteOffset;
|
||||
if(FileStream_Read(ha->pStream, &ByteOffset, pbSqpTable, cbTableSize))
|
||||
{
|
||||
// Decrypt the SQP table
|
||||
DecryptMpqBlock(pbSqpTable, cbTableSize, dwKey);
|
||||
return pbSqpTable;
|
||||
}
|
||||
|
||||
// Free the table
|
||||
STORM_FREE(pbSqpTable);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TMPQHash * LoadSqpHashTable(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
TSQPHash * pSqpHashTable;
|
||||
TSQPHash * pSqpHashEnd;
|
||||
TSQPHash * pSqpHash;
|
||||
TMPQHash * pMpqHash;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Load the hash table
|
||||
pSqpHashTable = (TSQPHash *)LoadSqpTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TSQPHash), MPQ_KEY_HASH_TABLE);
|
||||
if(pSqpHashTable != NULL)
|
||||
{
|
||||
// Parse the entire hash table and convert it to MPQ hash table
|
||||
pSqpHashEnd = pSqpHashTable + pHeader->dwHashTableSize;
|
||||
pMpqHash = (TMPQHash *)pSqpHashTable;
|
||||
for(pSqpHash = pSqpHashTable; pSqpHash < pSqpHashEnd; pSqpHash++, pMpqHash++)
|
||||
{
|
||||
// Ignore free entries
|
||||
if(pSqpHash->dwBlockIndex != HASH_ENTRY_FREE)
|
||||
{
|
||||
// Check block index against the size of the block table
|
||||
if(pHeader->dwBlockTableSize <= MPQ_BLOCK_INDEX(pSqpHash) && pSqpHash->dwBlockIndex < HASH_ENTRY_DELETED)
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
|
||||
// We do not support nonzero locale and platform ID
|
||||
if(pSqpHash->dwAlwaysZero != 0 && pSqpHash->dwAlwaysZero != HASH_ENTRY_FREE)
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
|
||||
// Store the file name hash
|
||||
pMpqHash->dwName1 = pSqpHash->dwName1;
|
||||
pMpqHash->dwName2 = pSqpHash->dwName2;
|
||||
|
||||
// Store the rest. Note that this must be done last,
|
||||
// because block index corresponds to pMpqHash->dwName2
|
||||
pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(pSqpHash);
|
||||
pMpqHash->Platform = 0;
|
||||
pMpqHash->lcLocale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If an error occured, we need to free the hash table
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
STORM_FREE(pSqpHashTable);
|
||||
pSqpHashTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the converted hash table (or NULL on failure)
|
||||
return (TMPQHash *)pSqpHashTable;
|
||||
}
|
||||
|
||||
// Loads the SQP Block table and converts it to a MPQ block table
|
||||
TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
TSQPBlock * pSqpBlockTable;
|
||||
TSQPBlock * pSqpBlockEnd;
|
||||
TSQPBlock * pSqpBlock;
|
||||
TMPQBlock * pMpqBlock;
|
||||
DWORD dwFlags;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Load the hash table
|
||||
pSqpBlockTable = (TSQPBlock *)LoadSqpTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TSQPBlock), MPQ_KEY_BLOCK_TABLE);
|
||||
if(pSqpBlockTable != NULL)
|
||||
{
|
||||
// Parse the entire hash table and convert it to MPQ hash table
|
||||
pSqpBlockEnd = pSqpBlockTable + pHeader->dwBlockTableSize;
|
||||
pMpqBlock = (TMPQBlock *)pSqpBlockTable;
|
||||
for(pSqpBlock = pSqpBlockTable; pSqpBlock < pSqpBlockEnd; pSqpBlock++, pMpqBlock++)
|
||||
{
|
||||
// Check for valid flags
|
||||
if(pSqpBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS)
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
|
||||
// Convert SQP block table entry to MPQ block table entry
|
||||
dwFlags = pSqpBlock->dwFlags;
|
||||
pMpqBlock->dwCSize = pSqpBlock->dwCSize;
|
||||
pMpqBlock->dwFSize = pSqpBlock->dwFSize;
|
||||
pMpqBlock->dwFlags = dwFlags;
|
||||
}
|
||||
|
||||
// If an error occured, we need to free the hash table
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
STORM_FREE(pSqpBlockTable);
|
||||
pSqpBlockTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the converted hash table (or NULL on failure)
|
||||
return (TMPQBlock *)pSqpBlockTable;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Support for MPK file format (Longwu Online) */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define MPK_FILE_UNKNOWN_0001 0x00000001 // Seems to be always present
|
||||
#define MPK_FILE_UNKNOWN_0010 0x00000010 // Seems to be always present
|
||||
#define MPK_FILE_COMPRESSED 0x00000100 // Indicates a compressed file
|
||||
#define MPK_FILE_UNKNOWN_2000 0x00002000 // Seems to be always present
|
||||
#define MPK_FILE_EXISTS 0x01000000 // Seems to be always present
|
||||
|
||||
typedef struct _TMPKHeader
|
||||
{
|
||||
// The ID_MPK ('MPK\x1A') signature
|
||||
DWORD dwID;
|
||||
|
||||
// Contains '2000'
|
||||
DWORD dwVersion;
|
||||
|
||||
// 32-bit size of the archive
|
||||
DWORD dwArchiveSize;
|
||||
|
||||
// Size of the archive header
|
||||
DWORD dwHeaderSize;
|
||||
|
||||
DWORD dwHashTablePos;
|
||||
DWORD dwHashTableSize;
|
||||
DWORD dwBlockTablePos;
|
||||
DWORD dwBlockTableSize;
|
||||
DWORD dwUnknownPos;
|
||||
DWORD dwUnknownSize;
|
||||
} TMPKHeader;
|
||||
|
||||
|
||||
typedef struct _TMPKHash
|
||||
{
|
||||
// The hash of the file path, using method A.
|
||||
DWORD dwName1;
|
||||
|
||||
// The hash of the file path, using method B.
|
||||
DWORD dwName2;
|
||||
|
||||
// The hash of the file path, using method C.
|
||||
DWORD dwName3;
|
||||
|
||||
// If the hash table entry is valid, this is the index into the block table of the file.
|
||||
// Otherwise, one of the following two values:
|
||||
// - FFFFFFFFh: Hash table entry is empty, and has always been empty.
|
||||
// Terminates searches for a given file.
|
||||
// - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
|
||||
// Does not terminate searches for a given file.
|
||||
DWORD dwBlockIndex;
|
||||
|
||||
} TMPKHash;
|
||||
|
||||
typedef struct _TMPKBlock
|
||||
{
|
||||
DWORD dwFlags; // 0x1121 - Compressed , 0x1120 - Not compressed
|
||||
DWORD dwFilePos; // Offset of the beginning of the file, relative to the beginning of the archive.
|
||||
DWORD dwFSize; // Uncompressed file size
|
||||
DWORD dwCSize; // Compressed file size
|
||||
DWORD dwUnknown; // 0x86364E6D
|
||||
} TMPKBlock;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local variables - MPK file format
|
||||
|
||||
static const unsigned char MpkDecryptionKey[512] =
|
||||
{
|
||||
0x60, 0x20, 0x29, 0xE1, 0x01, 0xCE, 0xAA, 0xFE, 0xA3, 0xAB, 0x8E, 0x30, 0xAF, 0x02, 0xD1, 0x7D,
|
||||
0x41, 0x24, 0x06, 0xBD, 0xAE, 0xBE, 0x43, 0xC3, 0xBA, 0xB7, 0x08, 0x13, 0x51, 0xCF, 0xF8, 0xF7,
|
||||
0x25, 0x42, 0xA5, 0x4A, 0xDA, 0x0F, 0x52, 0x1C, 0x90, 0x3B, 0x63, 0x49, 0x36, 0xF6, 0xDD, 0x1B,
|
||||
0xEA, 0x58, 0xD4, 0x40, 0x70, 0x61, 0x55, 0x09, 0xCD, 0x0B, 0xA2, 0x4B, 0x68, 0x2C, 0x8A, 0xF1,
|
||||
0x3C, 0x3A, 0x65, 0xBB, 0xA1, 0xA8, 0x23, 0x97, 0xFD, 0x15, 0x00, 0x94, 0x88, 0x33, 0x59, 0xE9,
|
||||
0xFB, 0x69, 0x21, 0xEF, 0x85, 0x5B, 0x57, 0x6C, 0xFA, 0xB5, 0xEE, 0xB8, 0x71, 0xDC, 0xB1, 0x38,
|
||||
0x0C, 0x0A, 0x5C, 0x56, 0xC9, 0xB4, 0x84, 0x17, 0x1E, 0xE5, 0xD3, 0x5A, 0xCC, 0xFC, 0x11, 0x86,
|
||||
0x7F, 0x45, 0x4F, 0x54, 0xC8, 0x8D, 0x73, 0x89, 0x79, 0x5D, 0xB3, 0xBF, 0xB9, 0xE3, 0x93, 0xE4,
|
||||
0x6F, 0x35, 0x2D, 0x46, 0xF2, 0x76, 0xC5, 0x7E, 0xE2, 0xA4, 0xE6, 0xD9, 0x6E, 0x48, 0x34, 0x2B,
|
||||
0xC6, 0x5F, 0xBC, 0xA0, 0x6D, 0x0D, 0x47, 0x6B, 0x95, 0x96, 0x92, 0x91, 0xB2, 0x27, 0xEB, 0x9E,
|
||||
0xEC, 0x8F, 0xDF, 0x9C, 0x74, 0x99, 0x64, 0xF5, 0xFF, 0x28, 0xB6, 0x37, 0xF3, 0x7C, 0x81, 0x03,
|
||||
0x44, 0x62, 0x1F, 0xDB, 0x04, 0x7B, 0xB0, 0x9B, 0x31, 0xA7, 0xDE, 0x78, 0x9F, 0xAD, 0x0E, 0x3F,
|
||||
0x3E, 0x4D, 0xC7, 0xD7, 0x39, 0x19, 0x5E, 0xC2, 0xD0, 0xAC, 0xE8, 0x1A, 0x87, 0x8B, 0x07, 0x05,
|
||||
0x22, 0xED, 0x72, 0x2E, 0x1D, 0xC1, 0xA9, 0xD6, 0xE0, 0x83, 0xD5, 0xD8, 0xCB, 0x80, 0xF0, 0x66,
|
||||
0x7A, 0x9D, 0x50, 0xF9, 0x10, 0x4E, 0x16, 0x14, 0x77, 0x75, 0x6A, 0x67, 0xD2, 0xC0, 0xA6, 0xC4,
|
||||
0x53, 0x8C, 0x32, 0xCA, 0x82, 0x2A, 0x18, 0x9A, 0xF4, 0x4C, 0x3D, 0x26, 0x12, 0xE7, 0x98, 0x2F,
|
||||
0x4A, 0x04, 0x0D, 0xAF, 0xB4, 0xCF, 0x12, 0xCE, 0x1A, 0x37, 0x61, 0x39, 0x60, 0x95, 0xBE, 0x25,
|
||||
0xE4, 0x6E, 0xFC, 0x1B, 0xE7, 0x49, 0xE6, 0x67, 0xF6, 0xC5, 0xCB, 0x2F, 0x27, 0xD4, 0x68, 0xB2,
|
||||
0x01, 0x52, 0xD0, 0x46, 0x11, 0x20, 0xFB, 0x9D, 0xA9, 0x02, 0xF5, 0x8F, 0x3D, 0x82, 0xD3, 0xFF,
|
||||
0x0B, 0xB8, 0xF2, 0x4D, 0x8E, 0x81, 0x2C, 0xAB, 0x5F, 0xC4, 0x41, 0x29, 0x40, 0xFA, 0xC0, 0xBF,
|
||||
0x33, 0x10, 0x21, 0x16, 0xB0, 0x71, 0x83, 0x96, 0x8D, 0x2B, 0x23, 0x3B, 0xF9, 0xC1, 0xE5, 0x72,
|
||||
0xE2, 0x1C, 0x26, 0xF0, 0x73, 0x36, 0x63, 0x56, 0x31, 0x4E, 0x6B, 0x55, 0x62, 0x79, 0xC6, 0x91,
|
||||
0x00, 0x35, 0xB1, 0x2A, 0xA6, 0x42, 0xDF, 0xEB, 0x3C, 0x51, 0xEA, 0x97, 0x57, 0x94, 0x8C, 0x80,
|
||||
0x34, 0x5C, 0xD2, 0x76, 0xA4, 0xE9, 0x85, 0xE8, 0xBB, 0x78, 0xE0, 0xB5, 0xAD, 0x0F, 0x87, 0x70,
|
||||
0xDD, 0xAE, 0xF4, 0xD9, 0x66, 0x54, 0x6F, 0xCC, 0x4C, 0x77, 0x3E, 0xCD, 0xF1, 0x75, 0x0A, 0xA1,
|
||||
0x28, 0x9B, 0x9A, 0x7E, 0x4B, 0x98, 0x99, 0x47, 0xFE, 0xA5, 0xF7, 0xB7, 0xA3, 0xE1, 0x9F, 0xBC,
|
||||
0x93, 0x44, 0x3A, 0x08, 0x89, 0x22, 0xEE, 0xB9, 0x45, 0xD6, 0x06, 0x09, 0xC9, 0xBD, 0x14, 0x0C,
|
||||
0xB6, 0x5E, 0x9C, 0x7A, 0x65, 0x59, 0xAA, 0x19, 0x5B, 0x7C, 0x18, 0x43, 0x92, 0x13, 0x15, 0x7B,
|
||||
0xED, 0xD5, 0xC7, 0x17, 0xEF, 0x86, 0x90, 0xC2, 0x74, 0x64, 0xF3, 0xDC, 0x6C, 0x38, 0x05, 0x1D,
|
||||
0xC8, 0x0E, 0xEC, 0x6A, 0x32, 0xDA, 0xD7, 0xC3, 0xDB, 0x8B, 0x24, 0xB3, 0x5D, 0x2E, 0xBA, 0xA2,
|
||||
0xD8, 0x03, 0x88, 0x7D, 0x7F, 0x69, 0x8A, 0xFD, 0xCA, 0x4F, 0x30, 0x9E, 0xA0, 0xD1, 0x5A, 0x53,
|
||||
0xDE, 0x3F, 0x84, 0xAC, 0xF8, 0xA7, 0x2D, 0x1F, 0x1E, 0xE3, 0x58, 0x50, 0x6D, 0x48, 0x07, 0xA8
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions - MPK file format
|
||||
|
||||
// This function converts MPK file header into MPQ file header
|
||||
DWORD ConvertMpkHeaderToFormat4(
|
||||
TMPQArchive * ha,
|
||||
ULONGLONG FileSize,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
TMPKHeader * pMpkHeader = (TMPKHeader *)ha->HeaderData;
|
||||
TMPQHeader Header;
|
||||
|
||||
// Can't open the archive with certain flags
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
// Translate the MPK header into a MPQ header
|
||||
// Note: Hash table size and block table size are in bytes, not in entries
|
||||
memset(&Header, 0, sizeof(TMPQHeader));
|
||||
Header.dwID = BSWAP_INT32_UNSIGNED(pMpkHeader->dwID);
|
||||
Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwArchiveSize);
|
||||
Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHeaderSize);
|
||||
Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTablePos);
|
||||
Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTableSize) / sizeof(TMPKHash);
|
||||
Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTablePos);
|
||||
Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTableSize) / sizeof(TMPKBlock);
|
||||
// Header.dwUnknownPos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownPos);
|
||||
// Header.dwUnknownSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownSize);
|
||||
assert(Header.dwHeaderSize == sizeof(TMPKHeader));
|
||||
|
||||
// Verify the MPK header
|
||||
if(Header.dwID == ID_MPK && Header.dwHeaderSize == sizeof(TMPKHeader) && Header.dwArchiveSize == (DWORD)FileSize)
|
||||
{
|
||||
// The header ID must be ID_MPQ
|
||||
Header.dwID = g_dwMpqSignature;
|
||||
Header.wFormatVersion = MPQ_FORMAT_VERSION_1;
|
||||
Header.wSectorSize = 3;
|
||||
|
||||
// Initialize the fields of 3.0 header
|
||||
Header.ArchiveSize64 = Header.dwArchiveSize;
|
||||
Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash);
|
||||
Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock);
|
||||
|
||||
// Copy the converted MPQ header back
|
||||
memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader));
|
||||
|
||||
// Mark this file as MPK file
|
||||
ha->pfnHashString = HashStringLower;
|
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY;
|
||||
ha->dwSubType = MPQ_SUBTYPE_MPK;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
return ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// Attempts to search a free hash entry in the hash table being converted.
|
||||
// The created hash table must always be of nonzero size,
|
||||
// should have no duplicated items and no deleted entries
|
||||
TMPQHash * FindFreeHashEntry(TMPQHash * pHashTable, DWORD dwHashTableSize, DWORD dwStartIndex)
|
||||
{
|
||||
TMPQHash * pHash;
|
||||
DWORD dwIndex;
|
||||
|
||||
// Set the initial index
|
||||
dwStartIndex = dwIndex = (dwStartIndex & (dwHashTableSize - 1));
|
||||
assert(dwHashTableSize != 0);
|
||||
|
||||
// Search the hash table and return the found entries in the following priority:
|
||||
for(;;)
|
||||
{
|
||||
// We are not expecting to find matching entry in the hash table being built
|
||||
// We are not expecting to find deleted entry either
|
||||
pHash = pHashTable + dwIndex;
|
||||
|
||||
// If we found a free entry, we need to stop searching
|
||||
if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
|
||||
return pHash;
|
||||
|
||||
// Move to the next hash entry.
|
||||
// If we reached the starting entry, it's failure.
|
||||
dwIndex = (dwIndex + 1) & (dwHashTableSize - 1);
|
||||
if(dwIndex == dwStartIndex)
|
||||
break;
|
||||
}
|
||||
|
||||
// We haven't found anything
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DecryptMpkTable(void * pvMpkTable, size_t cbSize)
|
||||
{
|
||||
LPBYTE pbMpkTable = (LPBYTE)pvMpkTable;
|
||||
|
||||
for(size_t i = 0; i < cbSize; i++)
|
||||
pbMpkTable[i] = MpkDecryptionKey[pbMpkTable[i]];
|
||||
}
|
||||
|
||||
void * LoadMpkTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize)
|
||||
{
|
||||
ULONGLONG ByteOffset;
|
||||
LPBYTE pbMpkTable = NULL;
|
||||
|
||||
// Allocate space for the table
|
||||
pbMpkTable = STORM_ALLOC(BYTE, cbTableSize);
|
||||
if(pbMpkTable != NULL)
|
||||
{
|
||||
// Load and the MPK hash table
|
||||
ByteOffset = ha->MpqPos + dwByteOffset;
|
||||
if(FileStream_Read(ha->pStream, &ByteOffset, pbMpkTable, cbTableSize))
|
||||
{
|
||||
// Decrypt the table
|
||||
DecryptMpkTable(pbMpkTable, cbTableSize);
|
||||
return pbMpkTable;
|
||||
}
|
||||
|
||||
// Free the MPK table
|
||||
STORM_FREE(pbMpkTable);
|
||||
pbMpkTable = NULL;
|
||||
}
|
||||
|
||||
// Return the table
|
||||
return pbMpkTable;
|
||||
}
|
||||
|
||||
TMPQHash * LoadMpkHashTable(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
TMPQHash * pHashTable = NULL;
|
||||
TMPKHash * pMpkHash;
|
||||
TMPQHash * pHash = NULL;
|
||||
DWORD dwHashTableSize = pHeader->dwHashTableSize;
|
||||
|
||||
// MPKs use different hash table searching.
|
||||
// Instead of using MPQ_HASH_TABLE_INDEX hash as index,
|
||||
// they store the value directly in the hash table.
|
||||
// Also for faster searching, the hash table is sorted ascending by the value
|
||||
|
||||
// Load and decrypt the MPK hash table.
|
||||
pMpkHash = (TMPKHash *)LoadMpkTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TMPKHash));
|
||||
if(pMpkHash != NULL)
|
||||
{
|
||||
// Calculate the hash table size as if it was real MPQ hash table
|
||||
pHeader->dwHashTableSize = GetNearestPowerOfTwo(pHeader->dwHashTableSize);
|
||||
pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash);
|
||||
|
||||
// Now allocate table that will serve like a true MPQ hash table,
|
||||
// so we translate the MPK hash table to MPQ hash table
|
||||
pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize);
|
||||
if(pHashTable != NULL)
|
||||
{
|
||||
// Set the entire hash table to free
|
||||
memset(pHashTable, 0xFF, (size_t)pHeader->HashTableSize64);
|
||||
|
||||
// Copy the MPK hash table into MPQ hash table
|
||||
for(DWORD i = 0; i < dwHashTableSize; i++)
|
||||
{
|
||||
// Finds the free hash entry in the hash table
|
||||
// We don't expect any errors here, because we are putting files to empty hash table
|
||||
pHash = FindFreeHashEntry(pHashTable, pHeader->dwHashTableSize, pMpkHash[i].dwName1);
|
||||
assert(pHash->dwBlockIndex == HASH_ENTRY_FREE);
|
||||
|
||||
// Copy the MPK hash entry to the hash table
|
||||
pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex;
|
||||
pHash->Platform = 0;
|
||||
pHash->lcLocale = 0;
|
||||
pHash->dwName1 = pMpkHash[i].dwName2;
|
||||
pHash->dwName2 = pMpkHash[i].dwName3;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the temporary hash table
|
||||
STORM_FREE(pMpkHash);
|
||||
}
|
||||
|
||||
return pHashTable;
|
||||
}
|
||||
|
||||
static DWORD ConvertMpkFlagsToMpqFlags(DWORD dwMpkFlags)
|
||||
{
|
||||
DWORD dwMpqFlags = MPQ_FILE_EXISTS;
|
||||
|
||||
// Check for flags that are always present
|
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_0001) != 0);
|
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_0010) != 0);
|
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_2000) != 0);
|
||||
assert((dwMpkFlags & MPK_FILE_EXISTS) != 0);
|
||||
|
||||
// Append the compressed flag
|
||||
dwMpqFlags |= (dwMpkFlags & MPK_FILE_COMPRESSED) ? MPQ_FILE_COMPRESS : 0;
|
||||
|
||||
// All files in the MPQ seem to be single unit files
|
||||
dwMpqFlags |= MPQ_FILE_ENCRYPTED | MPQ_FILE_SINGLE_UNIT;
|
||||
|
||||
return dwMpqFlags;
|
||||
}
|
||||
|
||||
TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
TMPKBlock * pMpkBlockTable;
|
||||
TMPKBlock * pMpkBlockEnd;
|
||||
TMPQBlock * pBlockTable = NULL;
|
||||
TMPKBlock * pMpkBlock;
|
||||
TMPQBlock * pMpqBlock;
|
||||
|
||||
// Load and decrypt the MPK block table
|
||||
pMpkBlockTable = pMpkBlock = (TMPKBlock *)LoadMpkTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TMPKBlock));
|
||||
if(pMpkBlockTable != NULL)
|
||||
{
|
||||
// Allocate buffer for MPQ-like block table
|
||||
pBlockTable = pMpqBlock = STORM_ALLOC(TMPQBlock, pHeader->dwBlockTableSize);
|
||||
if(pBlockTable != NULL)
|
||||
{
|
||||
// Convert the MPK block table to MPQ block table
|
||||
pMpkBlockEnd = pMpkBlockTable + pHeader->dwBlockTableSize;
|
||||
while(pMpkBlock < pMpkBlockEnd)
|
||||
{
|
||||
// Translate the MPK block table entry to MPQ block table entry
|
||||
pMpqBlock->dwFilePos = pMpkBlock->dwFilePos;
|
||||
pMpqBlock->dwCSize = pMpkBlock->dwCSize;
|
||||
pMpqBlock->dwFSize = pMpkBlock->dwFSize;
|
||||
pMpqBlock->dwFlags = ConvertMpkFlagsToMpqFlags(pMpkBlock->dwFlags);
|
||||
|
||||
// Move both
|
||||
pMpkBlock++;
|
||||
pMpqBlock++;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the MPK block table
|
||||
STORM_FREE(pMpkBlockTable);
|
||||
}
|
||||
|
||||
return pBlockTable;
|
||||
}
|
1124
StormLib/src/SCompression.cpp
Normal file
1124
StormLib/src/SCompression.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1316
StormLib/src/SFileAddFile.cpp
Normal file
1316
StormLib/src/SFileAddFile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
570
StormLib/src/SFileAttributes.cpp
Normal file
570
StormLib/src/SFileAttributes.cpp
Normal file
@ -0,0 +1,570 @@
|
||||
/*****************************************************************************/
|
||||
/* SAttrFile.cpp Copyright (c) Ladislav Zezula 2007 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 12.06.04 1.00 Lad The first version of SAttrFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures
|
||||
|
||||
typedef struct _MPQ_ATTRIBUTES_HEADER
|
||||
{
|
||||
DWORD dwVersion; // Version of the (attributes) file. Must be 100 (0x64)
|
||||
DWORD dwFlags; // See MPQ_ATTRIBUTE_XXXX
|
||||
|
||||
// Followed by an array of CRC32
|
||||
// Followed by an array of file times
|
||||
// Followed by an array of MD5
|
||||
// Followed by an array of patch bits
|
||||
|
||||
// Note: The MD5 in (attributes), if present, is a hash of the entire file.
|
||||
// In case the file is an incremental patch, it contains MD5 of the file
|
||||
// after being patched.
|
||||
|
||||
} MPQ_ATTRIBUTES_HEADER, *PMPQ_ATTRIBUTES_HEADER;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static DWORD GetSizeOfAttributesFile(DWORD dwAttrFlags, DWORD dwBlockTableSize)
|
||||
{
|
||||
DWORD cbAttrFile = sizeof(MPQ_ATTRIBUTES_HEADER);
|
||||
|
||||
// Calculate size of the (attributes) file
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
|
||||
cbAttrFile += dwBlockTableSize * sizeof(DWORD);
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
|
||||
cbAttrFile += dwBlockTableSize * sizeof(ULONGLONG);
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_MD5)
|
||||
cbAttrFile += dwBlockTableSize * MD5_DIGEST_SIZE;
|
||||
|
||||
// The bit array has been created without the last bit belonging to (attributes)
|
||||
// When the number of files is a multiplier of 8 plus one, then the size of (attributes)
|
||||
// if 1 byte less than expected.
|
||||
// Example: wow-update-13164.MPQ: BlockTableSize = 0x62E1, but there's only 0xC5C bytes
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
|
||||
cbAttrFile += (dwBlockTableSize + 6) / 8;
|
||||
|
||||
return cbAttrFile;
|
||||
}
|
||||
|
||||
static DWORD CheckSizeOfAttributesFile(DWORD cbAttrFile, DWORD dwAttrFlags, DWORD dwBlockTableSize)
|
||||
{
|
||||
DWORD cbHeaderSize = sizeof(MPQ_ATTRIBUTES_HEADER);
|
||||
DWORD cbChecksumSize1 = 0;
|
||||
DWORD cbChecksumSize2 = 0;
|
||||
DWORD cbFileTimeSize1 = 0;
|
||||
DWORD cbFileTimeSize2 = 0;
|
||||
DWORD cbFileHashSize1 = 0;
|
||||
DWORD cbFileHashSize2 = 0;
|
||||
DWORD cbPatchBitSize1 = 0;
|
||||
DWORD cbPatchBitSize2 = 0;
|
||||
DWORD cbPatchBitSize3 = 0;
|
||||
|
||||
//
|
||||
// Various variants with the patch bit
|
||||
//
|
||||
// interface.MPQ.part from WoW build 10958 has
|
||||
// the MPQ_ATTRIBUTE_PATCH_BIT set, but there's an array of DWORDs instead.
|
||||
// The array is filled with zeros, so we don't know what it should contain
|
||||
//
|
||||
// Zenith.SC2MAP has the MPQ_ATTRIBUTE_PATCH_BIT set, but the bit array is missing
|
||||
//
|
||||
// Elimination Tournament 2.w3x's (attributes) have one entry less
|
||||
//
|
||||
// There may be two variants: Either the (attributes) file has full
|
||||
// number of entries, or has one entry less
|
||||
//
|
||||
|
||||
// Get the expected size of CRC32 array
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
|
||||
{
|
||||
cbChecksumSize1 += dwBlockTableSize * sizeof(DWORD);
|
||||
cbChecksumSize2 += cbChecksumSize1 - sizeof(DWORD);
|
||||
}
|
||||
|
||||
// Get the expected size of FILETIME array
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
|
||||
{
|
||||
cbFileTimeSize1 += dwBlockTableSize * sizeof(ULONGLONG);
|
||||
cbFileTimeSize2 += cbFileTimeSize1 - sizeof(ULONGLONG);
|
||||
}
|
||||
|
||||
// Get the expected size of MD5 array
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_MD5)
|
||||
{
|
||||
cbFileHashSize1 += dwBlockTableSize * MD5_DIGEST_SIZE;
|
||||
cbFileHashSize2 += cbFileHashSize1 - MD5_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
// Get the expected size of patch bit array
|
||||
if(dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
|
||||
{
|
||||
cbPatchBitSize1 =
|
||||
cbPatchBitSize2 = ((dwBlockTableSize + 6) / 8);
|
||||
cbPatchBitSize3 = dwBlockTableSize * sizeof(DWORD);
|
||||
}
|
||||
|
||||
// Check if the (attributes) file entry count is equal to our file table size
|
||||
if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1 + cbPatchBitSize1))
|
||||
return dwBlockTableSize;
|
||||
|
||||
// Check if the (attributes) file entry count is equal to our file table size minus one
|
||||
if(cbAttrFile == (cbHeaderSize + cbChecksumSize2 + cbFileTimeSize2 + cbFileHashSize2 + cbPatchBitSize2))
|
||||
return dwBlockTableSize - 1;
|
||||
|
||||
// Zenith.SC2MAP has the MPQ_ATTRIBUTE_PATCH_BIT set, but the bit array is missing
|
||||
if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1))
|
||||
return dwBlockTableSize;
|
||||
|
||||
// interface.MPQ.part (WoW build 10958) has the MPQ_ATTRIBUTE_PATCH_BIT set
|
||||
// but there's an array of DWORDs (filled with zeros) instead of array of bits
|
||||
if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1 + cbPatchBitSize3))
|
||||
return dwBlockTableSize;
|
||||
|
||||
#ifdef __STORMLIB_TEST__
|
||||
// Invalid size of the (attributes) file
|
||||
// Note that many MPQs, especially Warcraft III maps have the size of (attributes) invalid.
|
||||
// We only perform this check if this is the STORMLIB testprogram itself
|
||||
// assert(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD LoadAttributesFile(TMPQArchive * ha, LPBYTE pbAttrFile, DWORD cbAttrFile)
|
||||
{
|
||||
LPBYTE pbAttrFileEnd = pbAttrFile + cbAttrFile;
|
||||
LPBYTE pbAttrPtr = pbAttrFile;
|
||||
DWORD dwAttributesEntries = 0;
|
||||
DWORD i;
|
||||
|
||||
// Load and verify the header
|
||||
if((pbAttrPtr + sizeof(MPQ_ATTRIBUTES_HEADER)) <= pbAttrFileEnd)
|
||||
{
|
||||
PMPQ_ATTRIBUTES_HEADER pAttrHeader = (PMPQ_ATTRIBUTES_HEADER)pbAttrPtr;
|
||||
|
||||
// Verify the header version
|
||||
BSWAP_ARRAY32_UNSIGNED(pAttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER));
|
||||
if(pAttrHeader->dwVersion != MPQ_ATTRIBUTES_V1)
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
// Verify the flags
|
||||
if(pAttrHeader->dwFlags & ~MPQ_ATTRIBUTE_ALL)
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
// Verify whether file size of (attributes) is expected
|
||||
dwAttributesEntries = CheckSizeOfAttributesFile(cbAttrFile, pAttrHeader->dwFlags, ha->pHeader->dwBlockTableSize);
|
||||
if(dwAttributesEntries == 0)
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
ha->dwAttrFlags = pAttrHeader->dwFlags;
|
||||
pbAttrPtr = (LPBYTE)(pAttrHeader + 1);
|
||||
}
|
||||
|
||||
// Load the CRC32 (if present)
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
|
||||
{
|
||||
LPDWORD ArrayCRC32 = (LPDWORD)pbAttrPtr;
|
||||
DWORD cbArraySize = dwAttributesEntries * sizeof(DWORD);
|
||||
|
||||
// Verify if there's enough data
|
||||
if((pbAttrPtr + cbArraySize) > pbAttrFileEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
BSWAP_ARRAY32_UNSIGNED(ArrayCRC32, cbCRC32Size);
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
ha->pFileTable[i].dwCrc32 = ArrayCRC32[i];
|
||||
pbAttrPtr += cbArraySize;
|
||||
}
|
||||
|
||||
// Load the FILETIME (if present)
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
|
||||
{
|
||||
ULONGLONG * ArrayFileTime = (ULONGLONG *)pbAttrPtr;
|
||||
DWORD cbArraySize = dwAttributesEntries * sizeof(ULONGLONG);
|
||||
|
||||
// Verify if there's enough data
|
||||
if((pbAttrPtr + cbArraySize) > pbAttrFileEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
BSWAP_ARRAY64_UNSIGNED(ArrayFileTime, cbFileTimeSize);
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
ha->pFileTable[i].FileTime = ArrayFileTime[i];
|
||||
pbAttrPtr += cbArraySize;
|
||||
}
|
||||
|
||||
// Load the MD5 (if present)
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5)
|
||||
{
|
||||
LPBYTE ArrayMd5 = pbAttrPtr;
|
||||
DWORD cbArraySize = dwAttributesEntries * MD5_DIGEST_SIZE;
|
||||
|
||||
// Verify if there's enough data
|
||||
if((pbAttrPtr + cbArraySize) > pbAttrFileEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
{
|
||||
memcpy(ha->pFileTable[i].md5, ArrayMd5, MD5_DIGEST_SIZE);
|
||||
ArrayMd5 += MD5_DIGEST_SIZE;
|
||||
}
|
||||
pbAttrPtr += cbArraySize;
|
||||
}
|
||||
|
||||
// Read the patch bit for each file (if present)
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
|
||||
{
|
||||
LPBYTE pbBitArray = pbAttrPtr;
|
||||
DWORD cbArraySize = (dwAttributesEntries + 7) / 8;
|
||||
DWORD dwByteIndex = 0;
|
||||
DWORD dwBitMask = 0x80;
|
||||
|
||||
// Verify if there's enough data
|
||||
if((pbAttrPtr + cbArraySize) == pbAttrFileEnd)
|
||||
{
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
{
|
||||
ha->pFileTable[i].dwFlags |= (pbBitArray[dwByteIndex] & dwBitMask) ? MPQ_FILE_PATCH_FILE : 0;
|
||||
dwByteIndex += (dwBitMask & 0x01);
|
||||
dwBitMask = (dwBitMask << 0x07) | (dwBitMask >> 0x01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
|
||||
{
|
||||
PMPQ_ATTRIBUTES_HEADER pAttrHeader;
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
LPBYTE pbAttrFile;
|
||||
LPBYTE pbAttrPtr;
|
||||
size_t cbAttrFile;
|
||||
|
||||
// Check if we need patch bits in the (attributes) file
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
|
||||
{
|
||||
ha->dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the buffer for holding the entire (attributes)
|
||||
// Allocate 1 byte more (See GetSizeOfAttributesFile for more info)
|
||||
cbAttrFile = GetSizeOfAttributesFile(ha->dwAttrFlags, ha->pHeader->dwBlockTableSize);
|
||||
pbAttrFile = pbAttrPtr = STORM_ALLOC(BYTE, cbAttrFile + 1);
|
||||
if(pbAttrFile != NULL)
|
||||
{
|
||||
// Make sure it's all zeroed
|
||||
memset(pbAttrFile, 0, cbAttrFile + 1);
|
||||
|
||||
// Write the header of the (attributes) file
|
||||
pAttrHeader = (PMPQ_ATTRIBUTES_HEADER)pbAttrPtr;
|
||||
pAttrHeader->dwVersion = BSWAP_INT32_UNSIGNED(100);
|
||||
pAttrHeader->dwFlags = BSWAP_INT32_UNSIGNED((ha->dwAttrFlags & MPQ_ATTRIBUTE_ALL));
|
||||
pbAttrPtr = (LPBYTE)(pAttrHeader + 1);
|
||||
|
||||
// Write the array of CRC32, if present
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
|
||||
{
|
||||
LPDWORD pArrayCRC32 = (LPDWORD)pbAttrPtr;
|
||||
|
||||
// Copy from file table
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
*pArrayCRC32++ = BSWAP_INT32_UNSIGNED(pFileEntry->dwCrc32);
|
||||
|
||||
// Update pointer
|
||||
pbAttrPtr = (LPBYTE)pArrayCRC32;
|
||||
}
|
||||
|
||||
// Write the array of file time
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
|
||||
{
|
||||
ULONGLONG * pArrayFileTime = (ULONGLONG *)pbAttrPtr;
|
||||
|
||||
// Copy from file table
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
*pArrayFileTime++ = BSWAP_INT64_UNSIGNED(pFileEntry->FileTime);
|
||||
|
||||
// Update pointer
|
||||
pbAttrPtr = (LPBYTE)pArrayFileTime;
|
||||
}
|
||||
|
||||
// Write the array of MD5s
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5)
|
||||
{
|
||||
LPBYTE pbArrayMD5 = pbAttrPtr;
|
||||
|
||||
// Copy from file table
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
memcpy(pbArrayMD5, pFileEntry->md5, MD5_DIGEST_SIZE);
|
||||
pbArrayMD5 += MD5_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
// Update pointer
|
||||
pbAttrPtr = pbArrayMD5;
|
||||
}
|
||||
|
||||
// Write the array of patch bits
|
||||
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
|
||||
{
|
||||
LPBYTE pbBitArray = pbAttrPtr;
|
||||
DWORD dwByteIndex = 0;
|
||||
BYTE dwBitMask = 0x80;
|
||||
|
||||
// Copy from file table
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
// Set the bit, if needed
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
|
||||
pbBitArray[dwByteIndex] |= dwBitMask;
|
||||
|
||||
// Update bit index and bit mask
|
||||
dwByteIndex += (dwBitMask & 0x01);
|
||||
dwBitMask = (dwBitMask << 0x07) | (dwBitMask >> 0x01);
|
||||
}
|
||||
|
||||
// Move past the bit array
|
||||
pbAttrPtr += (ha->pHeader->dwBlockTableSize + 6) / 8;
|
||||
}
|
||||
|
||||
// Now we expect that current position matches the estimated size
|
||||
// Note that if there is 1 extra bit above the byte size,
|
||||
// the table is actually 1 byte shorter in Blizzard MPQs. See GetSizeOfAttributesFile
|
||||
assert((size_t)(pbAttrPtr - pbAttrFile) == cbAttrFile);
|
||||
}
|
||||
|
||||
// Give away the attributes file
|
||||
if(pcbAttrFile != NULL)
|
||||
*pcbAttrFile = (DWORD)cbAttrFile;
|
||||
return pbAttrFile;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions (internal use by StormLib)
|
||||
|
||||
DWORD SAttrLoadAttributes(TMPQArchive * ha)
|
||||
{
|
||||
HANDLE hFile = NULL;
|
||||
LPBYTE pbAttrFile;
|
||||
DWORD dwBytesRead;
|
||||
DWORD cbAttrFile = 0;
|
||||
DWORD dwErrCode = ERROR_FILE_CORRUPT;
|
||||
|
||||
// File table must be initialized
|
||||
assert(ha->pFileTable != NULL);
|
||||
assert((ha->dwFlags & MPQ_FLAG_BLOCK_TABLE_CUT) == 0);
|
||||
|
||||
// Don't load the attributes file from malformed Warcraft III maps
|
||||
if(ha->dwFlags & MPQ_FLAG_MALFORMED)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
// Attempt to open the "(attributes)" file.
|
||||
if(SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, SFILE_OPEN_ANY_LOCALE, &hFile))
|
||||
{
|
||||
// Retrieve and check size of the (attributes) file
|
||||
cbAttrFile = SFileGetFileSize(hFile, NULL);
|
||||
|
||||
// Integer overflow check
|
||||
if((cbAttrFile + 1) > cbAttrFile)
|
||||
{
|
||||
// Size of the (attributes) might be 1 byte less than expected
|
||||
// See GetSizeOfAttributesFile for more info
|
||||
pbAttrFile = STORM_ALLOC(BYTE, cbAttrFile + 1);
|
||||
if(pbAttrFile != NULL)
|
||||
{
|
||||
// Set the last byte to 0 in case the size should be 1 byte greater
|
||||
pbAttrFile[cbAttrFile] = 0;
|
||||
|
||||
// Load the entire file to memory
|
||||
SFileReadFile(hFile, pbAttrFile, cbAttrFile, &dwBytesRead, NULL);
|
||||
if(dwBytesRead == cbAttrFile)
|
||||
dwErrCode = LoadAttributesFile(ha, pbAttrFile, cbAttrFile);
|
||||
|
||||
// Free the buffer
|
||||
STORM_FREE(pbAttrFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the attributes file
|
||||
SFileCloseFile(hFile);
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
// Saves the (attributes) to the MPQ
|
||||
DWORD SAttrFileSaveToMpq(TMPQArchive * ha)
|
||||
{
|
||||
TMPQFile * hf = NULL;
|
||||
LPBYTE pbAttrFile;
|
||||
DWORD cbAttrFile = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Only save the attributes if we should do so
|
||||
if(ha->dwFileFlags2 != 0)
|
||||
{
|
||||
// At this point, we expect to have at least one reserved entry in the file table
|
||||
assert(ha->dwFlags & MPQ_FLAG_ATTRIBUTES_NEW);
|
||||
assert(ha->dwReservedFiles > 0);
|
||||
|
||||
// Create the raw data that is to be written to (attributes)
|
||||
// Note: Blizzard MPQs have entries for (listfile) and (attributes),
|
||||
// but they are filled empty
|
||||
pbAttrFile = CreateAttributesFile(ha, &cbAttrFile);
|
||||
if(pbAttrFile != NULL)
|
||||
{
|
||||
// Determine the real flags for (attributes)
|
||||
if(ha->dwFileFlags2 == MPQ_FILE_DEFAULT_INTERNAL)
|
||||
ha->dwFileFlags2 = GetDefaultSpecialFileFlags(cbAttrFile, ha->pHeader->wFormatVersion);
|
||||
|
||||
// Create the attributes file in the MPQ
|
||||
dwErrCode = SFileAddFile_Init(ha, ATTRIBUTES_NAME,
|
||||
0,
|
||||
cbAttrFile,
|
||||
LANG_NEUTRAL,
|
||||
ha->dwFileFlags2 | MPQ_FILE_REPLACEEXISTING,
|
||||
&hf);
|
||||
|
||||
// Write the attributes file raw data to it
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Write the content of the attributes file to the MPQ
|
||||
dwErrCode = SFileAddFile_Write(hf, pbAttrFile, cbAttrFile, MPQ_COMPRESSION_ZLIB);
|
||||
SFileAddFile_Finish(hf);
|
||||
}
|
||||
|
||||
// Clear the number of reserved files
|
||||
ha->dwFlags &= ~(MPQ_FLAG_ATTRIBUTES_NEW | MPQ_FLAG_ATTRIBUTES_NONE);
|
||||
ha->dwReservedFiles--;
|
||||
|
||||
// Free the attributes buffer
|
||||
STORM_FREE(pbAttrFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the (attributes) file would be empty, its OK
|
||||
dwErrCode = (cbAttrFile == 0) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
DWORD WINAPI SFileGetAttributes(HANDLE hMpq)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
|
||||
// Verify the parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return SFILE_INVALID_ATTRIBUTES;
|
||||
}
|
||||
|
||||
return ha->dwAttrFlags;
|
||||
}
|
||||
|
||||
bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
|
||||
// Verify the parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not allowed when the archive is read-only
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the attributes
|
||||
InvalidateInternalFiles(ha);
|
||||
ha->dwAttrFlags = (dwFlags & MPQ_ATTRIBUTE_ALL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName)
|
||||
{
|
||||
hash_state md5_state;
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
TMPQFile * hf;
|
||||
BYTE Buffer[0x1000];
|
||||
HANDLE hFile = NULL;
|
||||
DWORD dwTotalBytes = 0;
|
||||
DWORD dwBytesRead;
|
||||
DWORD dwCrc32;
|
||||
|
||||
// Verify the parameters
|
||||
if(!IsValidMpqHandle(ha))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not allowed when the archive is read-only
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to open the file
|
||||
if(!SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, &hFile))
|
||||
return false;
|
||||
|
||||
// Get the file size
|
||||
hf = (TMPQFile *)hFile;
|
||||
dwTotalBytes = hf->pFileEntry->dwFileSize;
|
||||
|
||||
// Initialize the CRC32 and MD5 contexts
|
||||
md5_init(&md5_state);
|
||||
dwCrc32 = crc32(0, Z_NULL, 0);
|
||||
|
||||
// Go through entire file and calculate both CRC32 and MD5
|
||||
while(dwTotalBytes != 0)
|
||||
{
|
||||
// Read data from file
|
||||
SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
|
||||
if(dwBytesRead == 0)
|
||||
break;
|
||||
|
||||
// Update CRC32 and MD5
|
||||
dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);
|
||||
md5_process(&md5_state, Buffer, dwBytesRead);
|
||||
|
||||
// Decrement the total size
|
||||
dwTotalBytes -= dwBytesRead;
|
||||
}
|
||||
|
||||
// Update both CRC32 and MD5
|
||||
hf->pFileEntry->dwCrc32 = dwCrc32;
|
||||
md5_done(&md5_state, hf->pFileEntry->md5);
|
||||
|
||||
// Remember that we need to save the MPQ tables
|
||||
InvalidateInternalFiles(ha);
|
||||
SFileCloseFile(hFile);
|
||||
return true;
|
||||
}
|
654
StormLib/src/SFileCompactArchive.cpp
Normal file
654
StormLib/src/SFileCompactArchive.cpp
Normal file
@ -0,0 +1,654 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Archive compacting function */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
|
||||
/* 19.11.03 1.01 Dan Big endian handling */
|
||||
/* 21.04.13 1.02 Dea Compact callback now part of TMPQArchive */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Local functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
static DWORD CheckIfAllFilesKnown(TMPQArchive * ha)
|
||||
{
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
DWORD dwBlockIndex = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Verify the file table
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++)
|
||||
{
|
||||
// If there is an existing entry in the file table, check its name
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
|
||||
{
|
||||
// The name must be valid and must not be a pseudo-name
|
||||
if(pFileEntry->szFileName == NULL || IsPseudoFileName(pFileEntry->szFileName, NULL))
|
||||
{
|
||||
dwErrCode = ERROR_UNKNOWN_FILE_NAMES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD CheckIfAllKeysKnown(TMPQArchive * ha, const TCHAR * szListFile, LPDWORD pFileKeys)
|
||||
{
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
DWORD dwBlockIndex = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Add the listfile to the MPQ
|
||||
if(szListFile != NULL)
|
||||
{
|
||||
// Notify the user
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_CHECKING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
|
||||
dwErrCode = SFileAddListFile((HANDLE)ha, szListFile);
|
||||
}
|
||||
|
||||
// Verify the file table
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++)
|
||||
{
|
||||
// If the file exists and it's encrypted
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
|
||||
{
|
||||
// If we know the name, we decrypt the file key from the file name
|
||||
if(pFileEntry->szFileName != NULL && !IsPseudoFileName(pFileEntry->szFileName, NULL))
|
||||
{
|
||||
// Give the key to the caller
|
||||
pFileKeys[dwBlockIndex] = DecryptFileKey(pFileEntry->szFileName,
|
||||
pFileEntry->ByteOffset,
|
||||
pFileEntry->dwFileSize,
|
||||
pFileEntry->dwFlags);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't know the encryption key of this file,
|
||||
// thus we cannot compact the file
|
||||
dwErrCode = ERROR_UNKNOWN_FILE_NAMES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD CopyNonMpqData(
|
||||
TMPQArchive * ha,
|
||||
TFileStream * pSrcStream,
|
||||
TFileStream * pTrgStream,
|
||||
ULONGLONG & ByteOffset,
|
||||
ULONGLONG & ByteCount)
|
||||
{
|
||||
ULONGLONG DataSize = ByteCount;
|
||||
DWORD dwToRead;
|
||||
char DataBuffer[0x1000];
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Copy the data
|
||||
while(DataSize > 0)
|
||||
{
|
||||
// Get the proper size of data
|
||||
dwToRead = sizeof(DataBuffer);
|
||||
if(DataSize < dwToRead)
|
||||
dwToRead = (DWORD)DataSize;
|
||||
|
||||
// Read from the source stream
|
||||
if(!FileStream_Read(pSrcStream, &ByteOffset, DataBuffer, dwToRead))
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Write to the target stream
|
||||
if(!FileStream_Write(pTrgStream, NULL, DataBuffer, dwToRead))
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the progress
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
{
|
||||
ha->CompactBytesProcessed += dwToRead;
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_COPYING_NON_MPQ_DATA, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
}
|
||||
|
||||
// Decrement the number of data to be copied
|
||||
ByteOffset += dwToRead;
|
||||
DataSize -= dwToRead;
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
// Copies all file sectors into another archive.
|
||||
static DWORD CopyMpqFileSectors(
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hf,
|
||||
TFileStream * pNewStream,
|
||||
ULONGLONG MpqFilePos) // MPQ file position in the new archive
|
||||
{
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive
|
||||
DWORD dwBytesToCopy = pFileEntry->dwCmpSize;
|
||||
DWORD dwPatchSize = 0; // Size of patch header
|
||||
DWORD dwFileKey1 = 0; // File key used for decryption
|
||||
DWORD dwFileKey2 = 0; // File key used for encryption
|
||||
DWORD dwCmpSize = 0; // Compressed file size, including patch header
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Resolve decryption keys. Note that the file key given
|
||||
// in the TMPQFile structure also includes the key adjustment
|
||||
if(dwErrCode == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED))
|
||||
{
|
||||
dwFileKey2 = dwFileKey1 = hf->dwFileKey;
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
|
||||
{
|
||||
dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset;
|
||||
dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have to save patch header, do it
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->pPatchInfo != NULL)
|
||||
{
|
||||
BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3);
|
||||
if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
// Save the size of the patch info
|
||||
dwPatchSize = hf->pPatchInfo->dwLength;
|
||||
}
|
||||
|
||||
// If we have to save sector offset table, do it.
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->SectorOffsets != NULL)
|
||||
{
|
||||
DWORD * SectorOffsetsCopy = STORM_ALLOC(DWORD, hf->SectorOffsets[0] / sizeof(DWORD));
|
||||
DWORD dwSectorOffsLen = hf->SectorOffsets[0];
|
||||
|
||||
assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0);
|
||||
assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK);
|
||||
|
||||
if(SectorOffsetsCopy == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Encrypt the secondary sector offset table and write it to the target file
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen);
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwFileKey2 - 1);
|
||||
|
||||
BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen);
|
||||
if(!FileStream_Write(pNewStream, NULL, SectorOffsetsCopy, dwSectorOffsLen))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
dwBytesToCopy -= dwSectorOffsLen;
|
||||
dwCmpSize += dwSectorOffsLen;
|
||||
}
|
||||
|
||||
// Update compact progress
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
{
|
||||
ha->CompactBytesProcessed += dwSectorOffsLen;
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
}
|
||||
|
||||
STORM_FREE(SectorOffsetsCopy);
|
||||
}
|
||||
|
||||
// Now we have to copy all file sectors. We do it without
|
||||
// recompression, because recompression is not necessary in this case
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++)
|
||||
{
|
||||
DWORD dwRawDataInSector = hf->dwSectorSize;
|
||||
DWORD dwRawByteOffset = dwSector * hf->dwSectorSize;
|
||||
|
||||
// Fix the raw data length if the file is compressed
|
||||
if(hf->SectorOffsets != NULL)
|
||||
{
|
||||
dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector];
|
||||
dwRawByteOffset = hf->SectorOffsets[dwSector];
|
||||
}
|
||||
|
||||
// Last sector: If there is not enough bytes remaining in the file, cut the raw size
|
||||
if(dwRawDataInSector > dwBytesToCopy)
|
||||
dwRawDataInSector = dwBytesToCopy;
|
||||
|
||||
// Calculate the raw file offset of the file sector
|
||||
RawFilePos = CalculateRawSectorOffset(hf, dwRawByteOffset);
|
||||
|
||||
// Read the file sector
|
||||
if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// If necessary, re-encrypt the sector
|
||||
// Note: Recompression is not necessary here. Unlike encryption,
|
||||
// the compression does not depend on the position of the file in MPQ.
|
||||
if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2)
|
||||
{
|
||||
BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
|
||||
DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey1 + dwSector);
|
||||
EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey2 + dwSector);
|
||||
BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
|
||||
}
|
||||
|
||||
// Now write the sector back to the file
|
||||
if(!FileStream_Write(pNewStream, NULL, hf->pbFileSector, dwRawDataInSector))
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Update compact progress
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
{
|
||||
ha->CompactBytesProcessed += dwRawDataInSector;
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
}
|
||||
|
||||
// Adjust byte counts
|
||||
dwBytesToCopy -= dwRawDataInSector;
|
||||
dwCmpSize += dwRawDataInSector;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the sector CRCs, if any
|
||||
// Sector CRCs are always compressed (not imploded) and unencrypted
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->SectorOffsets != NULL && hf->SectorChksums != NULL)
|
||||
{
|
||||
DWORD dwCrcLength;
|
||||
|
||||
dwCrcLength = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
|
||||
if(dwCrcLength != 0)
|
||||
{
|
||||
if(!FileStream_Read(ha->pStream, NULL, hf->SectorChksums, dwCrcLength))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
// Update compact progress
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
{
|
||||
ha->CompactBytesProcessed += dwCrcLength;
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
}
|
||||
|
||||
// Size of the CRC block is also included in the compressed file size
|
||||
dwBytesToCopy -= dwCrcLength;
|
||||
dwCmpSize += dwCrcLength;
|
||||
}
|
||||
}
|
||||
|
||||
// There might be extra data beyond sector checksum table
|
||||
// Sometimes, these data are even part of sector offset table
|
||||
// Examples:
|
||||
// 2012 - WoW\15354\locale-enGB.MPQ:DBFilesClient\SpellLevels.dbc
|
||||
// 2012 - WoW\15354\locale-enGB.MPQ:Interface\AddOns\Blizzard_AuctionUI\Blizzard_AuctionUI.xml
|
||||
if(dwErrCode == ERROR_SUCCESS && dwBytesToCopy != 0)
|
||||
{
|
||||
LPBYTE pbExtraData;
|
||||
|
||||
// Allocate space for the extra data
|
||||
pbExtraData = STORM_ALLOC(BYTE, dwBytesToCopy);
|
||||
if(pbExtraData != NULL)
|
||||
{
|
||||
if(!FileStream_Read(ha->pStream, NULL, pbExtraData, dwBytesToCopy))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
if(!FileStream_Write(pNewStream, NULL, pbExtraData, dwBytesToCopy))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
// Include these extra data in the compressed size
|
||||
dwCmpSize += dwBytesToCopy;
|
||||
STORM_FREE(pbExtraData);
|
||||
}
|
||||
else
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Write the MD5's of the raw file data, if needed
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
|
||||
{
|
||||
dwErrCode = WriteMpqDataMD5(pNewStream,
|
||||
ha->MpqPos + MpqFilePos,
|
||||
pFileEntry->dwCmpSize,
|
||||
ha->pHeader->dwRawChunkSize);
|
||||
}
|
||||
|
||||
// Verify the number of bytes written
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// At this point, number of bytes written should be exactly
|
||||
// the same like the compressed file size. If it isn't,
|
||||
// there's something wrong (an unknown archive version, MPQ malformation, ...)
|
||||
//
|
||||
// Note: Diablo savegames have very weird layout, and the file "hero"
|
||||
// seems to have improper compressed size. Instead of real compressed size,
|
||||
// the "dwCmpSize" member of the block table entry contains
|
||||
// uncompressed size of file data + size of the sector table.
|
||||
// If we compact the archive, Diablo will refuse to load the game
|
||||
//
|
||||
// Note: Some patch files in WOW patches don't count the patch header
|
||||
// into compressed size
|
||||
//
|
||||
|
||||
if(!(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize))
|
||||
{
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream)
|
||||
{
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
TMPQFile * hf = NULL;
|
||||
ULONGLONG MpqFilePos;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Walk through all files and write them to the destination MPQ archive
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
// Copy all the file sectors
|
||||
// Only do that when the file has nonzero size
|
||||
if((pFileEntry->dwFlags & MPQ_FILE_EXISTS))
|
||||
{
|
||||
// Query the position where the destination file will be
|
||||
FileStream_GetPos(pNewStream, &MpqFilePos);
|
||||
MpqFilePos = MpqFilePos - ha->MpqPos;
|
||||
|
||||
// Perform file copy ONLY if the file has nonzero size
|
||||
if(pFileEntry->dwFileSize != 0)
|
||||
{
|
||||
// Allocate structure for the MPQ file
|
||||
hf = CreateFileHandle(ha, pFileEntry);
|
||||
if(hf == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Set the file decryption key
|
||||
hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable];
|
||||
|
||||
// If the file is a patch file, load the patch header
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
|
||||
{
|
||||
dwErrCode = AllocatePatchInfo(hf, true);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate buffers for file sector and sector offset table
|
||||
dwErrCode = AllocateSectorBuffer(hf);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
// Also allocate sector offset table and sector checksum table
|
||||
dwErrCode = AllocateSectorOffsets(hf, true);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
// Also load sector checksums, if any
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
|
||||
{
|
||||
dwErrCode = AllocateSectorChecksums(hf, false);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy all file sectors
|
||||
dwErrCode = CopyMpqFileSectors(ha, hf, pNewStream, MpqFilePos);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
// Free buffers. This also sets "hf" to NULL.
|
||||
FreeFileHandle(hf);
|
||||
}
|
||||
|
||||
// Note: DO NOT update the compressed size in the file entry, no matter how bad it is.
|
||||
pFileEntry->ByteOffset = MpqFilePos;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup and exit
|
||||
if(hf != NULL)
|
||||
FreeFileHandle(hf);
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Public functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Changing hash table size
|
||||
|
||||
DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
|
||||
return ha->dwMaxFileCount;
|
||||
}
|
||||
|
||||
bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
DWORD dwNewHashTableSize = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Test the valid parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
dwErrCode = ERROR_INVALID_HANDLE;
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
dwErrCode = ERROR_ACCESS_DENIED;
|
||||
if(dwMaxFileCount < ha->dwFileTableSize)
|
||||
dwErrCode = ERROR_DISK_FULL;
|
||||
|
||||
// ALL file names must be known in order to be able to rebuild hash table
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL)
|
||||
{
|
||||
dwErrCode = CheckIfAllFilesKnown(ha);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Calculate the hash table size for the new file limit
|
||||
dwNewHashTableSize = GetNearestPowerOfTwo(dwMaxFileCount);
|
||||
|
||||
// Rebuild both file tables
|
||||
dwErrCode = RebuildFileTable(ha, dwNewHashTableSize);
|
||||
}
|
||||
}
|
||||
|
||||
// We always have to rebuild the (attributes) file due to file table change
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Invalidate (listfile) and (attributes)
|
||||
InvalidateInternalFiles(ha);
|
||||
|
||||
// Rebuild the HET table, if we have any
|
||||
if(ha->pHetTable != NULL)
|
||||
dwErrCode = RebuildHetTable(ha);
|
||||
}
|
||||
|
||||
// Return the error
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Archive compacting
|
||||
|
||||
bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK pfnCompactCB, void * pvUserData)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *) hMpq;
|
||||
|
||||
if (!IsValidMpqHandle(hMpq))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
ha->pfnCompactCB = pfnCompactCB;
|
||||
ha->pvCompactUserData = pvUserData;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WINAPI SFileCompactArchive(HANDLE hMpq, const TCHAR * szListFile, bool /* bReserved */)
|
||||
{
|
||||
TFileStream * pTempStream = NULL;
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
ULONGLONG ByteOffset;
|
||||
ULONGLONG ByteCount;
|
||||
LPDWORD pFileKeys = NULL;
|
||||
TCHAR szTempFile[MAX_PATH+1] = _T("");
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Test the valid parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
dwErrCode = ERROR_INVALID_HANDLE;
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
dwErrCode = ERROR_ACCESS_DENIED;
|
||||
|
||||
// If the MPQ is changed at this moment, we have to flush the archive
|
||||
if(dwErrCode == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED))
|
||||
{
|
||||
SFileFlushArchive(hMpq);
|
||||
}
|
||||
|
||||
// Create the table with file keys
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL)
|
||||
memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize);
|
||||
else
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// First of all, we have to check of we are able to decrypt all files.
|
||||
// If not, sorry, but the archive cannot be compacted.
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Initialize the progress variables for compact callback
|
||||
FileStream_GetSize(ha->pStream, &(ha->CompactTotalBytes));
|
||||
ha->CompactBytesProcessed = 0;
|
||||
dwErrCode = CheckIfAllKeysKnown(ha, szListFile, pFileKeys);
|
||||
}
|
||||
|
||||
// Get the temporary file name and create it
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Create temporary file name. Prevent buffer overflow
|
||||
StringCopy(szTempFile, _countof(szTempFile), FileStream_GetFileName(ha->pStream));
|
||||
StringCat(szTempFile, _countof(szTempFile), _T(".tmp"));
|
||||
|
||||
// Create temporary file
|
||||
pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
|
||||
if(pTempStream == NULL)
|
||||
dwErrCode = GetLastError();
|
||||
}
|
||||
|
||||
// Write the data before MPQ user data (if any)
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->UserDataPos != 0)
|
||||
{
|
||||
// Inform the application about the progress
|
||||
if(ha->pfnCompactCB != NULL)
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_COPYING_NON_MPQ_DATA, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
|
||||
ByteOffset = 0;
|
||||
ByteCount = ha->UserDataPos;
|
||||
dwErrCode = CopyNonMpqData(ha, ha->pStream, pTempStream, ByteOffset, ByteCount);
|
||||
}
|
||||
|
||||
// Write the MPQ user data (if any)
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->MpqPos > ha->UserDataPos)
|
||||
{
|
||||
// At this point, we assume that the user data size is equal
|
||||
// to pUserData->dwHeaderOffs.
|
||||
// If this assumption doesn't work, then we have an unknown version of MPQ
|
||||
ByteOffset = ha->UserDataPos;
|
||||
ByteCount = ha->MpqPos - ha->UserDataPos;
|
||||
|
||||
assert(ha->pUserData != NULL);
|
||||
assert(ha->pUserData->dwHeaderOffs == ByteCount);
|
||||
dwErrCode = CopyNonMpqData(ha, ha->pStream, pTempStream, ByteOffset, ByteCount);
|
||||
}
|
||||
|
||||
// Write the MPQ header
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
TMPQHeader SaveMpqHeader;
|
||||
|
||||
// Write the MPQ header to the file
|
||||
memcpy(&SaveMpqHeader, ha->pHeader, ha->pHeader->dwHeaderSize);
|
||||
BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_1);
|
||||
BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_2);
|
||||
BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_3);
|
||||
BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_4);
|
||||
if(!FileStream_Write(pTempStream, NULL, &SaveMpqHeader, ha->pHeader->dwHeaderSize))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
// Update the progress
|
||||
ha->CompactBytesProcessed += ha->pHeader->dwHeaderSize;
|
||||
}
|
||||
|
||||
// Now copy all files
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
dwErrCode = CopyMpqFiles(ha, pFileKeys, pTempStream);
|
||||
|
||||
// If succeeded, switch the streams
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
ha->dwFlags |= MPQ_FLAG_CHANGED;
|
||||
if(FileStream_Replace(ha->pStream, pTempStream))
|
||||
pTempStream = NULL;
|
||||
else
|
||||
dwErrCode = ERROR_CAN_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
// Final user notification
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->pfnCompactCB != NULL)
|
||||
{
|
||||
ha->CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
|
||||
ha->CompactBytesProcessed += (ha->dwFileTableSize * sizeof(TMPQBlock));
|
||||
ha->pfnCompactCB(ha->pvCompactUserData, CCB_CLOSING_ARCHIVE, ha->CompactBytesProcessed, ha->CompactTotalBytes);
|
||||
}
|
||||
|
||||
// Cleanup and return
|
||||
if(pTempStream != NULL)
|
||||
FileStream_Close(pTempStream);
|
||||
if(pFileKeys != NULL)
|
||||
STORM_FREE(pFileKeys);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
276
StormLib/src/SFileCreateArchive.cpp
Normal file
276
StormLib/src/SFileCreateArchive.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileCreateArchive.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* MPQ Editing functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */
|
||||
/* 08.06.10 1.00 Lad Renamed to SFileCreateArchive.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local variables
|
||||
|
||||
static const DWORD MpqHeaderSizes[] =
|
||||
{
|
||||
MPQ_HEADER_SIZE_V1,
|
||||
MPQ_HEADER_SIZE_V2,
|
||||
MPQ_HEADER_SIZE_V3,
|
||||
MPQ_HEADER_SIZE_V4
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static USHORT GetSectorSizeShift(DWORD dwSectorSize)
|
||||
{
|
||||
USHORT wSectorSizeShift = 0;
|
||||
|
||||
while(dwSectorSize > 0x200)
|
||||
{
|
||||
dwSectorSize >>= 1;
|
||||
wSectorSizeShift++;
|
||||
}
|
||||
|
||||
return wSectorSizeShift;
|
||||
}
|
||||
|
||||
static DWORD WriteNakedMPQHeader(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
TMPQHeader Header;
|
||||
DWORD dwBytesToWrite = pHeader->dwHeaderSize;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Prepare the naked MPQ header
|
||||
memset(&Header, 0, sizeof(TMPQHeader));
|
||||
Header.dwID = pHeader->dwID;
|
||||
Header.dwHeaderSize = pHeader->dwHeaderSize;
|
||||
Header.dwArchiveSize = pHeader->dwHeaderSize;
|
||||
Header.wFormatVersion = pHeader->wFormatVersion;
|
||||
Header.wSectorSize = pHeader->wSectorSize;
|
||||
|
||||
// Write it to the file
|
||||
BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_1);
|
||||
BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_2);
|
||||
BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_3);
|
||||
BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_4);
|
||||
if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a new MPQ archive.
|
||||
|
||||
bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq)
|
||||
{
|
||||
SFILE_CREATE_MPQ CreateInfo;
|
||||
|
||||
// Fill the create structure
|
||||
memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ));
|
||||
CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ);
|
||||
CreateInfo.dwMpqVersion = (dwCreateFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT;
|
||||
CreateInfo.dwStreamFlags = STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE;
|
||||
CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
|
||||
CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
|
||||
CreateInfo.dwFileFlags3 = (dwCreateFlags & MPQ_CREATE_SIGNATURE) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
|
||||
CreateInfo.dwAttrFlags = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? (MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5) : 0;
|
||||
CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
|
||||
CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0;
|
||||
CreateInfo.dwMaxFileCount = dwMaxFileCount;
|
||||
|
||||
// Set the proper attribute parts
|
||||
if((CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) && (dwCreateFlags & MPQ_CREATE_ATTRIBUTES))
|
||||
CreateInfo.dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT;
|
||||
|
||||
// Backward compatibility: SFileCreateArchive always used to add (listfile)
|
||||
// We would break loads of applications if we change that
|
||||
CreateInfo.dwFileFlags1 = MPQ_FILE_DEFAULT_INTERNAL;
|
||||
|
||||
// Let the main function create the archive
|
||||
return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq);
|
||||
}
|
||||
|
||||
bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq)
|
||||
{
|
||||
TFileStream * pStream = NULL; // File stream
|
||||
TMPQArchive * ha = NULL; // MPQ archive handle
|
||||
TMPQHeader * pHeader;
|
||||
ULONGLONG MpqPos = 0; // Position of MPQ header in the file
|
||||
HANDLE hMpq = NULL;
|
||||
DWORD dwBlockTableSize = 0; // Initial block table size
|
||||
DWORD dwHashTableSize = 0;
|
||||
DWORD dwReservedFiles = 0; // Number of reserved file entries
|
||||
DWORD dwMpqFlags = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Check the parameters, if they are valid
|
||||
if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify if all variables in SFILE_CREATE_MPQ are correct
|
||||
if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) ||
|
||||
(pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) ||
|
||||
(pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) ||
|
||||
(pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) ||
|
||||
(pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) ||
|
||||
(pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// One time initialization of MPQ cryptography
|
||||
InitializeMpqCryptography();
|
||||
|
||||
// We verify if the file already exists and if it's a MPQ archive.
|
||||
// If yes, we won't allow to overwrite it.
|
||||
if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
|
||||
{
|
||||
SFileCloseArchive(hMpq);
|
||||
SetLastError(ERROR_ALREADY_EXISTS);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// At this point, we have to create the archive.
|
||||
// - If the file exists, convert it to MPQ archive.
|
||||
// - If the file doesn't exist, create new empty file
|
||||
//
|
||||
|
||||
pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
|
||||
if(pStream == NULL)
|
||||
{
|
||||
pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
|
||||
if(pStream == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Increment the maximum amount of files to have space for (listfile)
|
||||
if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags1)
|
||||
{
|
||||
dwMpqFlags |= MPQ_FLAG_LISTFILE_NEW;
|
||||
dwReservedFiles++;
|
||||
}
|
||||
|
||||
// Increment the maximum amount of files to have space for (attributes)
|
||||
if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags2 && pCreateInfo->dwAttrFlags)
|
||||
{
|
||||
dwMpqFlags |= MPQ_FLAG_ATTRIBUTES_NEW;
|
||||
dwReservedFiles++;
|
||||
}
|
||||
|
||||
// Increment the maximum amount of files to have space for (signature)
|
||||
if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags3)
|
||||
{
|
||||
dwMpqFlags |= MPQ_FLAG_SIGNATURE_NEW;
|
||||
dwReservedFiles++;
|
||||
}
|
||||
|
||||
// If file count is not zero, initialize the hash table size
|
||||
dwHashTableSize = GetNearestPowerOfTwo(pCreateInfo->dwMaxFileCount + dwReservedFiles);
|
||||
|
||||
// Retrieve the file size and round it up to 0x200 bytes
|
||||
FileStream_GetSize(pStream, &MpqPos);
|
||||
MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
|
||||
if(!FileStream_SetSize(pStream, MpqPos))
|
||||
dwErrCode = GetLastError();
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Debug code, used for testing StormLib
|
||||
// dwBlockTableSize = dwHashTableSize * 2;
|
||||
#endif
|
||||
|
||||
// Create the archive handle
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Fill the MPQ archive handle structure
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
memset(ha, 0, sizeof(TMPQArchive));
|
||||
ha->pfnHashString = HashStringSlash;
|
||||
ha->pStream = pStream;
|
||||
ha->dwSectorSize = pCreateInfo->dwSectorSize;
|
||||
ha->UserDataPos = MpqPos;
|
||||
ha->MpqPos = MpqPos;
|
||||
ha->pHeader = pHeader = (TMPQHeader *)ha->HeaderData;
|
||||
ha->dwMaxFileCount = dwHashTableSize;
|
||||
ha->dwFileTableSize = 0;
|
||||
ha->dwReservedFiles = dwReservedFiles;
|
||||
ha->dwFileFlags1 = pCreateInfo->dwFileFlags1;
|
||||
ha->dwFileFlags2 = pCreateInfo->dwFileFlags2;
|
||||
ha->dwFileFlags3 = pCreateInfo->dwFileFlags3 ? MPQ_FILE_EXISTS : 0;
|
||||
ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
|
||||
ha->dwFlags = dwMpqFlags | MPQ_FLAG_CHANGED;
|
||||
ha->useFreeSpaceOptimization = true;
|
||||
ha->lastFreeSpaceEntry = nullptr;
|
||||
pStream = NULL;
|
||||
|
||||
// Fill the MPQ header
|
||||
memset(pHeader, 0, sizeof(ha->HeaderData));
|
||||
pHeader->dwID = g_dwMpqSignature;
|
||||
pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
|
||||
pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
|
||||
pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion;
|
||||
pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize);
|
||||
pHeader->dwHashTablePos = pHeader->dwHeaderSize;
|
||||
pHeader->dwHashTableSize = dwHashTableSize;
|
||||
pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
|
||||
pHeader->dwBlockTableSize = dwBlockTableSize;
|
||||
|
||||
// For MPQs version 4 and higher, we set the size of raw data block
|
||||
// for calculating MD5
|
||||
if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
|
||||
pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;
|
||||
|
||||
// Write the naked MPQ header
|
||||
dwErrCode = WriteNakedMPQHeader(ha);
|
||||
}
|
||||
|
||||
// Create initial HET table, if the caller required an MPQ format 3.0 or newer
|
||||
if(dwErrCode == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3 && pCreateInfo->dwMaxFileCount != 0)
|
||||
{
|
||||
ha->pHetTable = CreateHetTable(ha->dwFileTableSize, 0, 0x40, NULL);
|
||||
if(ha->pHetTable == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Create initial hash table
|
||||
if(dwErrCode == ERROR_SUCCESS && dwHashTableSize != 0)
|
||||
{
|
||||
dwErrCode = CreateHashTable(ha, dwHashTableSize);
|
||||
}
|
||||
|
||||
// Create initial file table
|
||||
if(dwErrCode == ERROR_SUCCESS && ha->dwMaxFileCount != 0)
|
||||
{
|
||||
dwErrCode = CreateFileTable(ha, ha->dwMaxFileCount);
|
||||
}
|
||||
|
||||
// Cleanup : If an error, delete all buffers and return
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
FileStream_Close(pStream);
|
||||
FreeArchiveHandle(ha);
|
||||
SetLastError(dwErrCode);
|
||||
ha = NULL;
|
||||
}
|
||||
|
||||
// Return the values
|
||||
*phMpq = (HANDLE)ha;
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
64
StormLib/src/SFileExtractFile.cpp
Normal file
64
StormLib/src/SFileExtractFile.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Simple extracting utility */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope)
|
||||
{
|
||||
TFileStream * pLocalFile = NULL;
|
||||
HANDLE hMpqFile = NULL;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Open the MPQ file
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile))
|
||||
dwErrCode = GetLastError();
|
||||
}
|
||||
|
||||
// Create the local file
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
pLocalFile = FileStream_CreateFile(szExtracted, 0);
|
||||
if(pLocalFile == NULL)
|
||||
dwErrCode = GetLastError();
|
||||
}
|
||||
|
||||
// Copy the file's content
|
||||
while(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
char szBuffer[0x1000];
|
||||
DWORD dwTransferred = 0;
|
||||
|
||||
// dwTransferred is only set to nonzero if something has been read.
|
||||
// dwErrCode can be ERROR_SUCCESS or ERROR_HANDLE_EOF
|
||||
if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL))
|
||||
dwErrCode = GetLastError();
|
||||
if(dwErrCode == ERROR_HANDLE_EOF)
|
||||
dwErrCode = ERROR_SUCCESS;
|
||||
if(dwTransferred == 0)
|
||||
break;
|
||||
|
||||
// If something has been actually read, write it
|
||||
if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred))
|
||||
dwErrCode = GetLastError();
|
||||
}
|
||||
|
||||
// Close the files
|
||||
if(hMpqFile != NULL)
|
||||
SFileCloseFile(hMpqFile);
|
||||
if(pLocalFile != NULL)
|
||||
FileStream_Close(pLocalFile);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
483
StormLib/src/SFileFindFile.cpp
Normal file
483
StormLib/src/SFileFindFile.cpp
Normal file
@ -0,0 +1,483 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* A module for file searching within MPQs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Private structure used for file search (search handle)
|
||||
|
||||
// Used by searching in MPQ archives
|
||||
struct TMPQSearch
|
||||
{
|
||||
TMPQArchive * ha; // Handle to MPQ, where the search runs
|
||||
TFileEntry ** pSearchTable; // Table for files that have been already found
|
||||
DWORD dwSearchTableItems; // Number of items in the search table
|
||||
DWORD dwNextIndex; // Next file index to be checked
|
||||
DWORD dwFlagMask; // For checking flag mask
|
||||
char szSearchMask[1]; // Search mask (variable length)
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static TMPQSearch * IsValidSearchHandle(HANDLE hFind)
|
||||
{
|
||||
TMPQSearch * hs = (TMPQSearch *)hFind;
|
||||
|
||||
if(hs != NULL && IsValidMpqHandle(hs->ha))
|
||||
return hs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool SFileCheckWildCard(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] == '*')
|
||||
{
|
||||
while(szWildCardPtr[0] == '*')
|
||||
szWildCardPtr++;
|
||||
|
||||
if(szWildCardPtr[0] == 0)
|
||||
return true;
|
||||
|
||||
if(AsciiToUpperTable[szWildCardPtr[0]] == AsciiToUpperTable[szString[0]])
|
||||
{
|
||||
if(SFileCheckWildCard(szString, szWildCardPtr))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AsciiToUpperTable[szWildCardPtr[0]] != AsciiToUpperTable[szString[0]])
|
||||
return false;
|
||||
|
||||
szWildCard = szWildCardPtr + 1;
|
||||
}
|
||||
|
||||
if(szString[0] == 0)
|
||||
return false;
|
||||
szString++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (szString[0] == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD GetSearchTableItems(TMPQArchive * ha)
|
||||
{
|
||||
DWORD dwMergeItems = 0;
|
||||
|
||||
// Loop over all patches
|
||||
while(ha != NULL)
|
||||
{
|
||||
// Append the number of files
|
||||
dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwEntryCount
|
||||
: ha->pHeader->dwBlockTableSize;
|
||||
// Move to the patched archive
|
||||
ha = ha->haPatch;
|
||||
}
|
||||
|
||||
// Return the double size of number of items
|
||||
return (dwMergeItems | 1);
|
||||
}
|
||||
|
||||
static bool FileWasFoundBefore(
|
||||
TMPQArchive * ha,
|
||||
TMPQSearch * hs,
|
||||
TFileEntry * pFileEntry)
|
||||
{
|
||||
TFileEntry * pEntry;
|
||||
char * szRealFileName = pFileEntry->szFileName;
|
||||
DWORD dwStartIndex;
|
||||
DWORD dwNameHash;
|
||||
DWORD dwIndex;
|
||||
|
||||
if(hs->pSearchTable != NULL && szRealFileName != NULL)
|
||||
{
|
||||
// If we are in patch MPQ, we check if patch prefix matches
|
||||
// and then trim the patch prefix
|
||||
if(ha->pPatchPrefix != NULL)
|
||||
{
|
||||
// If the patch prefix doesn't fit, we pretend that the file
|
||||
// was there before and it will be skipped
|
||||
if(_strnicmp(szRealFileName, ha->pPatchPrefix->szPatchPrefix, ha->pPatchPrefix->nLength))
|
||||
return true;
|
||||
|
||||
szRealFileName += ha->pPatchPrefix->nLength;
|
||||
}
|
||||
|
||||
// Calculate the hash to the table
|
||||
dwNameHash = ha->pfnHashString(szRealFileName, MPQ_HASH_NAME_A);
|
||||
dwStartIndex = dwIndex = (dwNameHash % hs->dwSearchTableItems);
|
||||
|
||||
// The file might have been found before
|
||||
// only if this is not the first MPQ being searched
|
||||
if(ha->haBase != NULL)
|
||||
{
|
||||
// Enumerate all entries in the search table
|
||||
for(;;)
|
||||
{
|
||||
// Get the file entry at that position
|
||||
pEntry = hs->pSearchTable[dwIndex];
|
||||
if(pEntry == NULL)
|
||||
break;
|
||||
|
||||
if(pEntry->szFileName != NULL)
|
||||
{
|
||||
// Does the name match?
|
||||
if(!_stricmp(pEntry->szFileName, szRealFileName))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Move to the next entry
|
||||
dwIndex = (dwIndex + 1) % hs->dwSearchTableItems;
|
||||
if(dwIndex == dwStartIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Put the entry to the table for later use
|
||||
hs->pSearchTable[dwIndex] = pFileEntry;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry)
|
||||
{
|
||||
TFileEntry * pPatchEntry = pFileEntry;
|
||||
TFileEntry * pTempEntry;
|
||||
char szFileName[MAX_PATH+1];
|
||||
|
||||
// Can't find patch entry for a file that doesn't have name
|
||||
if(pFileEntry->szFileName != NULL && pFileEntry->szFileName[0] != 0)
|
||||
{
|
||||
// Go while there are patches
|
||||
while(ha->haPatch != NULL)
|
||||
{
|
||||
// Move to the patch archive
|
||||
ha = ha->haPatch;
|
||||
szFileName[0] = 0;
|
||||
|
||||
// Prepare the prefix for the file name
|
||||
if(ha->pPatchPrefix && ha->pPatchPrefix->nLength)
|
||||
StringCopy(szFileName, _countof(szFileName), ha->pPatchPrefix->szPatchPrefix);
|
||||
StringCat(szFileName, _countof(szFileName), pFileEntry->szFileName);
|
||||
|
||||
// Try to find the file there
|
||||
pTempEntry = GetFileEntryExact(ha, szFileName, 0, NULL);
|
||||
if(pTempEntry != NULL)
|
||||
pPatchEntry = pTempEntry;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the found patch entry
|
||||
return pPatchEntry;
|
||||
}
|
||||
|
||||
static bool DoMPQSearch_FileEntry(
|
||||
TMPQSearch * hs,
|
||||
SFILE_FIND_DATA * lpFindFileData,
|
||||
TMPQArchive * ha,
|
||||
TMPQHash * pHashEntry,
|
||||
TFileEntry * pFileEntry)
|
||||
{
|
||||
TFileEntry * pPatchEntry;
|
||||
HANDLE hFile = NULL;
|
||||
const char * szFileName;
|
||||
size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0;
|
||||
DWORD dwBlockIndex;
|
||||
char szNameBuff[MAX_PATH];
|
||||
|
||||
// Is it a file but not a patch file?
|
||||
if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
|
||||
{
|
||||
// Ignore fake files which are not compressed but have size higher than the archive
|
||||
if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
|
||||
return false;
|
||||
|
||||
// Now we have to check if this file was not enumerated before
|
||||
if(!FileWasFoundBefore(ha, hs, pFileEntry))
|
||||
{
|
||||
// if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy"))
|
||||
// DebugBreak();
|
||||
|
||||
// Find a patch to this file
|
||||
// Note: This either succeeds or returns pFileEntry
|
||||
pPatchEntry = FindPatchEntry(ha, pFileEntry);
|
||||
|
||||
// Prepare the block index
|
||||
dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
|
||||
if(dwBlockIndex == 569)
|
||||
szNameBuff[0] = 'F';
|
||||
|
||||
// Get the file name. If it's not known, we will create pseudo-name
|
||||
szFileName = pFileEntry->szFileName;
|
||||
if(szFileName == NULL)
|
||||
{
|
||||
// Open the file by its pseudo-name.
|
||||
StringCreatePseudoFileName(szNameBuff, _countof(szNameBuff), dwBlockIndex, "xxx");
|
||||
if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile))
|
||||
{
|
||||
SFileGetFileName(hFile, szNameBuff);
|
||||
szFileName = szNameBuff;
|
||||
SFileCloseFile(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
// If the file name is still NULL, we cannot include the file to search results
|
||||
if(szFileName != NULL)
|
||||
{
|
||||
// Check the file name against the wildcard
|
||||
if(SFileCheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
|
||||
{
|
||||
// Fill the found entry. hash entry and block index are taken from the base MPQ
|
||||
lpFindFileData->dwHashIndex = HASH_ENTRY_FREE;
|
||||
lpFindFileData->dwBlockIndex = dwBlockIndex;
|
||||
lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
|
||||
lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
|
||||
lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
|
||||
lpFindFileData->lcLocale = 0; // pPatchEntry->lcLocale;
|
||||
|
||||
// Fill the filetime
|
||||
lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
|
||||
lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);
|
||||
|
||||
// Fill-in the entries from hash table entry, if given
|
||||
if(pHashEntry != NULL)
|
||||
{
|
||||
lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable);
|
||||
lpFindFileData->lcLocale = pHashEntry->lcLocale;
|
||||
}
|
||||
|
||||
// Fill the file name and plain file name
|
||||
StringCopy(lpFindFileData->cFileName, _countof(lpFindFileData->cFileName), szFileName + nPrefixLength);
|
||||
lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Either not a valid item or was found before
|
||||
return false;
|
||||
}
|
||||
|
||||
static DWORD DoMPQSearch_HashTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha)
|
||||
{
|
||||
TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
|
||||
TMPQHash * pHash;
|
||||
|
||||
// Parse the file table
|
||||
for(pHash = ha->pHashTable + hs->dwNextIndex; pHash < pHashTableEnd; pHash++)
|
||||
{
|
||||
// Increment the next index for subsequent search
|
||||
hs->dwNextIndex++;
|
||||
|
||||
// Does this hash table entry point to a proper block table entry?
|
||||
if(IsValidHashEntry(ha, pHash))
|
||||
{
|
||||
// Check if this file entry should be included in the search result
|
||||
if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, pHash, ha->pFileTable + MPQ_BLOCK_INDEX(pHash)))
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// No more files
|
||||
return ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
static DWORD DoMPQSearch_FileTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha)
|
||||
{
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
|
||||
// Parse the file table
|
||||
for(pFileEntry = ha->pFileTable + hs->dwNextIndex; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
// Increment the next index for subsequent search
|
||||
hs->dwNextIndex++;
|
||||
|
||||
// Check if this file entry should be included in the search result
|
||||
if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, NULL, pFileEntry))
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// No more files
|
||||
return ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
// Performs one MPQ search
|
||||
static DWORD DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
TMPQArchive * ha = hs->ha;
|
||||
DWORD dwErrCode;
|
||||
|
||||
// Start searching with base MPQ
|
||||
while(ha != NULL)
|
||||
{
|
||||
// If the archive has hash table, we need to use hash table
|
||||
// in order to catch hash table index and file locale.
|
||||
// Note: If multiple hash table entries, point to the same block entry,
|
||||
// we need, to report them all
|
||||
dwErrCode = (ha->pHashTable != NULL) ? DoMPQSearch_HashTable(hs, lpFindFileData, ha)
|
||||
: DoMPQSearch_FileTable(hs, lpFindFileData, ha);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
return dwErrCode;
|
||||
|
||||
// If there is no more patches in the chain, stop it.
|
||||
// This also keeps hs->ha non-NULL, which is required
|
||||
// for freeing the handle later
|
||||
if(ha->haPatch == NULL)
|
||||
break;
|
||||
|
||||
// Move to the next patch in the patch chain
|
||||
hs->ha = ha = ha->haPatch;
|
||||
hs->dwNextIndex = 0;
|
||||
}
|
||||
|
||||
// No more files found, return error
|
||||
return ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
static void FreeMPQSearch(TMPQSearch *& hs)
|
||||
{
|
||||
if(hs != NULL)
|
||||
{
|
||||
if(hs->pSearchTable != NULL)
|
||||
STORM_FREE(hs->pSearchTable);
|
||||
STORM_FREE(hs);
|
||||
hs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const TCHAR * szListFile)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
TMPQSearch * hs = NULL;
|
||||
size_t nSize = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Check for the valid parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
dwErrCode = ERROR_INVALID_HANDLE;
|
||||
if(szMask == NULL || lpFindFileData == NULL)
|
||||
dwErrCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Include the listfile into the MPQ's internal listfile
|
||||
// Note that if the listfile name is NULL, do nothing because the
|
||||
// internal listfile is always included.
|
||||
if(dwErrCode == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0)
|
||||
dwErrCode = SFileAddListFile((HANDLE)ha, szListFile);
|
||||
|
||||
// Allocate the structure for MPQ search
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
nSize = sizeof(TMPQSearch) + strlen(szMask) + 1;
|
||||
if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Perform the first search
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
memset(hs, 0, sizeof(TMPQSearch));
|
||||
strcpy(hs->szSearchMask, szMask);
|
||||
hs->dwFlagMask = MPQ_FILE_EXISTS;
|
||||
hs->ha = ha;
|
||||
|
||||
// If the archive is patched archive, we have to create a merge table
|
||||
// to prevent files being repeated
|
||||
if(ha->haPatch != NULL)
|
||||
{
|
||||
hs->dwSearchTableItems = GetSearchTableItems(ha);
|
||||
hs->pSearchTable = STORM_ALLOC(TFileEntry *, hs->dwSearchTableItems);
|
||||
hs->dwFlagMask = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE;
|
||||
if(hs->pSearchTable != NULL)
|
||||
memset(hs->pSearchTable, 0, hs->dwSearchTableItems * sizeof(TFileEntry *));
|
||||
else
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform first item searching
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = DoMPQSearch(hs, lpFindFileData);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
FreeMPQSearch(hs);
|
||||
SetLastError(dwErrCode);
|
||||
}
|
||||
|
||||
// Return the result value
|
||||
return (HANDLE)hs;
|
||||
}
|
||||
|
||||
bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
TMPQSearch * hs = IsValidSearchHandle(hFind);
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Check the parameters
|
||||
if(hs == NULL)
|
||||
dwErrCode = ERROR_INVALID_HANDLE;
|
||||
if(lpFindFileData == NULL)
|
||||
dwErrCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
dwErrCode = DoMPQSearch(hs, lpFindFileData);
|
||||
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
bool WINAPI SFileFindClose(HANDLE hFind)
|
||||
{
|
||||
TMPQSearch * hs = IsValidSearchHandle(hFind);
|
||||
|
||||
// Check the parameters
|
||||
if(hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeMPQSearch(hs);
|
||||
return true;
|
||||
}
|
607
StormLib/src/SFileGetFileInfo.cpp
Normal file
607
StormLib/src/SFileGetFileInfo.cpp
Normal file
@ -0,0 +1,607 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileGetFileInfo.cpp Copyright (c) Ladislav Zezula 2013 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 30.11.13 1.00 Lad The first version of SFileGetFileInfo.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static DWORD GetMpqFileCount(TMPQArchive * ha)
|
||||
{
|
||||
TFileEntry * pFileTableEnd;
|
||||
TFileEntry * pFileEntry;
|
||||
DWORD dwFileCount = 0;
|
||||
|
||||
// Go through all open MPQs, including patches
|
||||
while(ha != NULL)
|
||||
{
|
||||
// Only count files that are not patch files
|
||||
pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
// If the file is patch file and this is not primary archive, skip it
|
||||
// BUGBUG: This errorneously counts non-patch files that are in both
|
||||
// base MPQ and in patches, and increases the number of files by cca 50%
|
||||
if((pFileEntry->dwFlags & (MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE)) == MPQ_FILE_EXISTS)
|
||||
dwFileCount++;
|
||||
}
|
||||
|
||||
// Move to the next patch archive
|
||||
ha = ha->haPatch;
|
||||
}
|
||||
|
||||
return dwFileCount;
|
||||
}
|
||||
|
||||
static bool GetInfo_ReturdwErrCode(DWORD dwErrCode)
|
||||
{
|
||||
SetLastError(dwErrCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbData, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
// Give the length needed to store the info
|
||||
if(pcbLengthNeeded != NULL)
|
||||
pcbLengthNeeded[0] = cbData;
|
||||
|
||||
// Check for sufficient buffer
|
||||
if(cbData > cbFileInfo)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
// If the buffer size is sufficient, check for valid user buffer
|
||||
if(pvFileInfo == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER);
|
||||
|
||||
// Buffers and sizes are OK, we are ready to proceed file copying
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
// Verify buffer pointer and buffer size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
|
||||
return false;
|
||||
|
||||
// Copy the data to the caller-supplied buffer
|
||||
memcpy(pvFileInfo, pvData, cbData);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
bool bResult;
|
||||
|
||||
// Verify buffer pointer and buffer size
|
||||
if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false)
|
||||
memcpy(pvFileInfo, pvData, cbData);
|
||||
|
||||
// Copy the data to the user buffer
|
||||
STORM_FREE(pvData);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static bool GetInfo_TablePointer(void * pvFileInfo, DWORD cbFileInfo, void * pvTablePointer, SFileInfoClass InfoClass, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
// Verify buffer pointer and buffer size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, sizeof(void *), pcbLengthNeeded))
|
||||
{
|
||||
SFileFreeFileInfo(pvTablePointer, InfoClass);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The user buffer receives pointer to the table.
|
||||
// When done, the caller needs to call SFileFreeFileInfo on it
|
||||
*(void **)pvFileInfo = pvTablePointer;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetInfo_ReadFromFile(void * pvFileInfo, DWORD cbFileInfo, TFileStream * pStream, ULONGLONG ByteOffset, DWORD cbData, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
// Verify buffer pointer and buffer size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
|
||||
return false;
|
||||
|
||||
return FileStream_Read(pStream, &ByteOffset, pvFileInfo, cbData);
|
||||
}
|
||||
|
||||
static bool GetInfo_FileEntry(void * pvFileInfo, DWORD cbFileInfo, TFileEntry * pFileEntry, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
LPBYTE pbFileInfo = (LPBYTE)pvFileInfo;
|
||||
DWORD cbSrcFileInfo = sizeof(TFileEntry);
|
||||
DWORD cbFileName = 1;
|
||||
|
||||
// The file name belongs to the file entry
|
||||
if(pFileEntry->szFileName)
|
||||
cbFileName = (DWORD)strlen(pFileEntry->szFileName) + 1;
|
||||
cbSrcFileInfo += cbFileName;
|
||||
|
||||
// Verify buffer pointer and buffer size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbSrcFileInfo, pcbLengthNeeded))
|
||||
return false;
|
||||
|
||||
// Copy the file entry
|
||||
memcpy(pbFileInfo, pFileEntry, sizeof(TFileEntry));
|
||||
pbFileInfo += sizeof(TFileEntry);
|
||||
pbFileInfo[0] = 0;
|
||||
|
||||
// Copy the file name
|
||||
if(pFileEntry->szFileName)
|
||||
memcpy(pbFileInfo, pFileEntry->szFileName, cbFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetInfo_PatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
TMPQFile * hfTemp;
|
||||
LPCTSTR szPatchName;
|
||||
LPTSTR szFileInfo = (LPTSTR)pvFileInfo;
|
||||
size_t cchCharsNeeded = 1;
|
||||
size_t nLength;
|
||||
|
||||
// Patch chain is only supported on MPQ files. Local files are not supported.
|
||||
if(hf->pStream != NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER);
|
||||
|
||||
// Calculate the necessary length of the multi-string
|
||||
for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
|
||||
cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1;
|
||||
|
||||
// Verify whether the caller gave us valid buffer with enough size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, (DWORD)(cchCharsNeeded * sizeof(TCHAR)), pcbLengthNeeded))
|
||||
return false;
|
||||
|
||||
// Copy each patch name
|
||||
for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
|
||||
{
|
||||
// Get the file name and its length
|
||||
szPatchName = FileStream_GetFileName(hfTemp->ha->pStream);
|
||||
nLength = _tcslen(szPatchName) + 1;
|
||||
|
||||
// Copy the file name
|
||||
memcpy(szFileInfo, szPatchName, nLength * sizeof(TCHAR));
|
||||
szFileInfo += nLength;
|
||||
}
|
||||
|
||||
// Make it multi-string
|
||||
szFileInfo[0] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Retrieves an information about an archive or about a file within the archive
|
||||
//
|
||||
// hMpqOrFile - Handle to an MPQ archive or to a file
|
||||
// InfoClass - Information to obtain
|
||||
// pvFileInfo - Pointer to buffer to store the information
|
||||
// cbFileInfo - Size of the buffer pointed by pvFileInfo
|
||||
// pcbLengthNeeded - Receives number of bytes necessary to store the information
|
||||
|
||||
bool WINAPI SFileGetFileInfo(
|
||||
HANDLE hMpqOrFile,
|
||||
SFileInfoClass InfoClass,
|
||||
void * pvFileInfo,
|
||||
DWORD cbFileInfo,
|
||||
LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
MPQ_SIGNATURE_INFO SignatureInfo;
|
||||
const TCHAR * szSrcFileInfo;
|
||||
TMPQArchive * ha = NULL;
|
||||
TFileEntry * pFileEntry = NULL;
|
||||
TMPQHeader * pHeader = NULL;
|
||||
ULONGLONG Int64Value = 0;
|
||||
TMPQFile * hf = NULL;
|
||||
void * pvSrcFileInfo = NULL;
|
||||
DWORD cbSrcFileInfo = 0;
|
||||
DWORD dwInt32Value = 0;
|
||||
|
||||
// Validate archive/file handle
|
||||
if((int)InfoClass <= (int)SFileMpqFlags)
|
||||
{
|
||||
if((ha = IsValidMpqHandle(hMpqOrFile)) == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE);
|
||||
pHeader = ha->pHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((hf = IsValidFileHandle(hMpqOrFile)) == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE);
|
||||
pFileEntry = hf->pFileEntry;
|
||||
}
|
||||
|
||||
// Return info-class-specific data
|
||||
switch(InfoClass)
|
||||
{
|
||||
case SFileMpqFileName:
|
||||
szSrcFileInfo = FileStream_GetFileName(ha->pStream);
|
||||
cbSrcFileInfo = (DWORD)((_tcslen(szSrcFileInfo) + 1) * sizeof(TCHAR));
|
||||
return GetInfo(pvFileInfo, cbFileInfo, szSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqStreamBitmap:
|
||||
return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqUserDataOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->UserDataPos, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqUserDataHeader:
|
||||
if(ha->pUserData == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER);
|
||||
return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos, sizeof(TMPQUserData), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqUserData:
|
||||
if(ha->pUserData == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER);
|
||||
return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos + sizeof(TMPQUserData), ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHeaderOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->MpqPos, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHeaderSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHeaderSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHeader:
|
||||
return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->MpqPos, pHeader->dwHeaderSize, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHetTableOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHetTableSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHetHeader:
|
||||
pvSrcFileInfo = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
|
||||
if(pvSrcFileInfo == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, sizeof(TMPQHetHeader), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHetTable:
|
||||
if((pvSrcFileInfo = LoadHetTable(ha)) == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBetTableOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBetTableSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBetHeader:
|
||||
|
||||
// Retrieve the table and its size
|
||||
pvSrcFileInfo = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
|
||||
if(pvSrcFileInfo == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD);
|
||||
|
||||
// It is allowed for the caller to only require BET header
|
||||
if(cbFileInfo == sizeof(TMPQBetHeader))
|
||||
cbSrcFileInfo = sizeof(TMPQBetHeader);
|
||||
return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBetTable:
|
||||
if((pvSrcFileInfo = LoadBetTable(ha)) == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHashTableOffset:
|
||||
Int64Value = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHashTableSize64:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HashTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHashTableSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHashTableSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHashTable:
|
||||
cbSrcFileInfo = pHeader->dwHashTableSize * sizeof(TMPQHash);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, ha->pHashTable, cbSrcFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBlockTableOffset:
|
||||
Int64Value = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBlockTableSize64:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBlockTableSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwBlockTableSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqBlockTable:
|
||||
if(MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) >= ha->FileSize)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
cbSrcFileInfo = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
|
||||
pvSrcFileInfo = LoadBlockTable(ha, true);
|
||||
return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHiBlockTableOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHiBlockTableSize64:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqHiBlockTable:
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
|
||||
case SFileMpqSignatures:
|
||||
if(!QueryMpqSignatureInfo(ha, &SignatureInfo))
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.SignatureTypes, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqStrongSignatureOffset:
|
||||
if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.EndMpqData, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqStrongSignatureSize:
|
||||
if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqStrongSignature:
|
||||
if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, SignatureInfo.Signature, MPQ_STRONG_SIGNATURE_SIZE + 4, pcbLengthNeeded);
|
||||
|
||||
case SFileMpqArchiveSize64:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->ArchiveSize64, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqArchiveSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwArchiveSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqMaxFileCount:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->dwMaxFileCount, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqFileTableSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFileTableSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqSectorSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->dwSectorSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqNumberOfFiles:
|
||||
dwInt32Value = GetMpqFileCount(ha);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqRawChunkSize:
|
||||
if(pHeader->dwRawChunkSize == 0)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwRawChunkSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqStreamFlags:
|
||||
FileStream_GetFlags(ha->pStream, &dwInt32Value);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileMpqFlags:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFlags, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoPatchChain:
|
||||
return GetInfo_PatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded);
|
||||
|
||||
case SFileInfoFileEntry:
|
||||
if(pFileEntry == NULL)
|
||||
return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND);
|
||||
return GetInfo_FileEntry(pvFileInfo, cbFileInfo, pFileEntry, pcbLengthNeeded);
|
||||
|
||||
case SFileInfoHashEntry:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, hf->pHashEntry, sizeof(TMPQHash), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoHashIndex:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash1:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash2:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash3:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoLocale:
|
||||
dwInt32Value = hf->pHashEntry->lcLocale;
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoFileIndex:
|
||||
dwInt32Value = (DWORD)(pFileEntry - hf->ha->pFileTable);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoByteOffset:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->ByteOffset, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoFileTime:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileTime, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoFileSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFileSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoCompressedSize:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwCmpSize, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoFlags:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFlags, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoEncryptionKey:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->dwFileKey, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoEncryptionKeyRaw:
|
||||
dwInt32Value = hf->dwFileKey;
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
|
||||
dwInt32Value = (dwInt32Value ^ pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoCRC32:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->pFileEntry->dwCrc32, sizeof(DWORD), pcbLengthNeeded);
|
||||
}
|
||||
|
||||
// Invalid info class
|
||||
return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
bool WINAPI SFileFreeFileInfo(void * pvFileInfo, SFileInfoClass InfoClass)
|
||||
{
|
||||
switch(InfoClass)
|
||||
{
|
||||
case SFileMpqHetTable:
|
||||
FreeHetTable((TMPQHetTable *)pvFileInfo);
|
||||
return true;
|
||||
|
||||
case SFileMpqBetTable:
|
||||
FreeBetTable((TMPQBetTable *)pvFileInfo);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tries to retrieve the file name
|
||||
|
||||
struct TFileHeader2Ext
|
||||
{
|
||||
DWORD dwOffset00Data; // Required data at offset 00 (32-bits)
|
||||
DWORD dwOffset00Mask; // Mask for data at offset 00 (32 bits). 0 = data are ignored
|
||||
DWORD dwOffset04Data; // Required data at offset 04 (32-bits)
|
||||
DWORD dwOffset04Mask; // Mask for data at offset 04 (32 bits). 0 = data are ignored
|
||||
const char * szExt; // Supplied extension, if the condition is true
|
||||
};
|
||||
|
||||
static TFileHeader2Ext data2ext[] =
|
||||
{
|
||||
{0x00005A4D, 0x0000FFFF, 0x00000000, 0x00000000, "exe"}, // EXE files
|
||||
{0x00000006, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, "dc6"}, // EXE files
|
||||
{0x1A51504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mpq"}, // MPQ archive header ID ('MPQ\x1A')
|
||||
{0x46464952, 0xFFFFFFFF, 0x00000000, 0x00000000, "wav"}, // WAVE header 'RIFF'
|
||||
{0x324B4D53, 0xFFFFFFFF, 0x00000000, 0x00000000, "smk"}, // Old "Smacker Video" files 'SMK2'
|
||||
{0x694B4942, 0xFFFFFFFF, 0x00000000, 0x00000000, "bik"}, // Bink video files (new)
|
||||
{0x0801050A, 0xFFFFFFFF, 0x00000000, 0x00000000, "pcx"}, // PCX images used in Diablo I
|
||||
{0x544E4F46, 0xFFFFFFFF, 0x00000000, 0x00000000, "fnt"}, // Font files used in Diablo II
|
||||
{0x6D74683C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<htm'
|
||||
{0x4D54483C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<HTM
|
||||
{0x216F6F57, 0xFFFFFFFF, 0x00000000, 0x00000000, "tbl"}, // Table files
|
||||
{0x31504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures
|
||||
{0x32504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures (v2)
|
||||
{0x584C444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mdx"}, // MDX files
|
||||
{0x45505954, 0xFFFFFFFF, 0x00000000, 0x00000000, "pud"}, // Warcraft II maps
|
||||
{0x38464947, 0xFFFFFFFF, 0x00000000, 0x00000000, "gif"}, // GIF images 'GIF8'
|
||||
{0x3032444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "m2"}, // WoW ??? .m2
|
||||
{0x43424457, 0xFFFFFFFF, 0x00000000, 0x00000000, "dbc"}, // ??? .dbc
|
||||
{0x47585053, 0xFFFFFFFF, 0x00000000, 0x00000000, "bls"}, // WoW pixel shaders
|
||||
{0xE0FFD8FF, 0xFFFFFFFF, 0x00000000, 0x00000000, "jpg"}, // JPEG image
|
||||
{0x503B4449, 0xFFFFFFFF, 0x3B4C5857, 0xFFFFFFFF, "slk"}, // SLK file (usually starts with "ID;PWXL;N;E")
|
||||
{0x61754C1B, 0xFFFFFFFF, 0x00000000, 0x00000000, "lua"}, // Compiled LUA files
|
||||
{0x20534444, 0xFFFFFFFF, 0x00000000, 0x00000000, "dds"}, // DDS textures
|
||||
{0x43614C66, 0xFFFFFFFF, 0x00000000, 0x00000000, "flac"}, // FLAC sound files
|
||||
{0x0000FBFF, 0x0000FFFF, 0x00000000, 0x00000000, "mp3"}, // MP3 sound files
|
||||
{0x0000F3FF, 0x0000FFFF, 0x00000000, 0x00000000, "mp3"}, // MP3 sound files
|
||||
{0x0000F2FF, 0x0000FFFF, 0x00000000, 0x00000000, "mp3"}, // MP3 sound files
|
||||
{0x00334449, 0x00FFFFFF, 0x00000000, 0x00000000, "mp3"}, // MP3 sound files
|
||||
{0x57334D48, 0xFFFFFFFF, 0x00000000, 0x00000000, "w3x"}, // Warcraft III map files, can also be w3m
|
||||
{0x6F643357, 0xFFFFFFFF, 0x00000000, 0x00000000, "doo"}, // Warcraft III doodad files
|
||||
{0x21453357, 0xFFFFFFFF, 0x00000000, 0x00000000, "w3e"}, // Warcraft III environment files
|
||||
{0x5733504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "wpm"}, // Warcraft III pathing map files
|
||||
{0x21475457, 0xFFFFFFFF, 0x00000000, 0x00000000, "wtg"}, // Warcraft III trigger files
|
||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000, "xxx"}, // Default extension
|
||||
{0, 0, 0, 0, NULL} // Terminator
|
||||
};
|
||||
|
||||
static DWORD CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * szFileName)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
|
||||
DWORD FirstBytes[2] = {0, 0}; // The first 4 bytes of the file
|
||||
DWORD dwBytesRead = 0;
|
||||
DWORD dwFilePos; // Saved file position
|
||||
char szPseudoName[20];
|
||||
|
||||
// Read the first 2 DWORDs bytes from the file
|
||||
dwFilePos = SFileSetFilePointer(hFile, 0, NULL, FILE_CURRENT);
|
||||
SFileReadFile(hFile, FirstBytes, sizeof(FirstBytes), &dwBytesRead, NULL);
|
||||
SFileSetFilePointer(hFile, dwFilePos, NULL, FILE_BEGIN);
|
||||
|
||||
// If we read at least 8 bytes
|
||||
if(dwBytesRead == sizeof(FirstBytes))
|
||||
{
|
||||
// Make sure that the array is properly BSWAP-ed
|
||||
BSWAP_ARRAY32_UNSIGNED(FirstBytes, sizeof(FirstBytes));
|
||||
|
||||
// Try to guess file extension from those 2 DWORDs
|
||||
for(size_t i = 0; data2ext[i].szExt != NULL; i++)
|
||||
{
|
||||
if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data &&
|
||||
(FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data)
|
||||
{
|
||||
// Format the pseudo-name
|
||||
StringCreatePseudoFileName(szPseudoName, _countof(szPseudoName), (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
|
||||
|
||||
// Save the pseudo-name in the file entry as well
|
||||
AllocateFileName(hf->ha, pFileEntry, szPseudoName);
|
||||
|
||||
// If the caller wants to copy the file name, do it
|
||||
if(szFileName != NULL)
|
||||
strcpy(szFileName, szPseudoName);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_CAN_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
|
||||
DWORD dwErrCode = ERROR_INVALID_HANDLE;
|
||||
|
||||
// Check valid parameters
|
||||
if(IsValidFileHandle(hFile))
|
||||
{
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
|
||||
// For MPQ files, retrieve the file name from the file entry
|
||||
if(hf->pStream == NULL)
|
||||
{
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// If the file name is not there yet, create a pseudo name
|
||||
if(pFileEntry->szFileName == NULL)
|
||||
dwErrCode = CreatePseudoFileName(hFile, pFileEntry, szFileName);
|
||||
|
||||
// Copy the file name to the output buffer, if any
|
||||
if(pFileEntry->szFileName && szFileName)
|
||||
{
|
||||
strcpy(szFileName, pFileEntry->szFileName);
|
||||
dwErrCode = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For local files, copy the file name from the stream
|
||||
else
|
||||
{
|
||||
if(szFileName != NULL)
|
||||
{
|
||||
const TCHAR * szStreamName = FileStream_GetFileName(hf->pStream);
|
||||
StringCopy(szFileName, MAX_PATH, szStreamName);
|
||||
}
|
||||
dwErrCode = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
687
StormLib/src/SFileListFile.cpp
Normal file
687
StormLib/src/SFileListFile.cpp
Normal file
@ -0,0 +1,687 @@
|
||||
/*****************************************************************************/
|
||||
/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description: */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 12.06.04 1.00 Lad The first version of SListFile.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
#include <assert.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Listfile entry structure
|
||||
|
||||
#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer
|
||||
#define MAX_LISTFILE_SIZE 0x8000000 // Maximum accepted listfile size is 128 MB
|
||||
|
||||
union TListFileHandle
|
||||
{
|
||||
TFileStream * pStream; // Opened local file
|
||||
HANDLE hFile; // Opened MPQ file
|
||||
};
|
||||
|
||||
struct TListFileCache
|
||||
{
|
||||
char * szWildCard; // Self-relative pointer to file mask
|
||||
LPBYTE pBegin; // The begin of the listfile cache
|
||||
LPBYTE pPos; // Current position in the cache
|
||||
LPBYTE pEnd; // The last character in the file cache
|
||||
DWORD dwFlags; // Flags from TMPQArchive
|
||||
|
||||
// char szWildCard[wildcard_length]; // Followed by the name mask (if any)
|
||||
// char szListFile[listfile_length]; // Followed by the listfile (if any)
|
||||
};
|
||||
|
||||
typedef bool (*LOAD_LISTFILE)(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions (cache)
|
||||
|
||||
// In SFileFindFile.cll
|
||||
bool SFileCheckWildCard(const char * szString, const char * szWildCard);
|
||||
|
||||
static char * CopyListLine(char * szListLine, const char * szFileName)
|
||||
{
|
||||
// Copy the string
|
||||
while (szFileName[0] != 0)
|
||||
{
|
||||
*szListLine++ = *szFileName++;
|
||||
}
|
||||
// Append the end-of-line
|
||||
*szListLine++ = 0x0D;
|
||||
*szListLine++ = 0x0A;
|
||||
return szListLine;
|
||||
}
|
||||
|
||||
static bool LoadListFile_Stream(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead)
|
||||
{
|
||||
ULONGLONG ByteOffset = 0;
|
||||
bool bResult;
|
||||
|
||||
bResult = FileStream_Read(pHandle->pStream, &ByteOffset, pvBuffer, cbBuffer);
|
||||
if(bResult)
|
||||
*pdwBytesRead = cbBuffer;
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static bool LoadListFile_MPQ(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead)
|
||||
{
|
||||
return SFileReadFile(pHandle->hFile, pvBuffer, cbBuffer, pdwBytesRead, NULL);
|
||||
}
|
||||
|
||||
static bool FreeListFileCache(TListFileCache * pCache)
|
||||
{
|
||||
// Valid parameter check
|
||||
if(pCache != NULL)
|
||||
STORM_FREE(pCache);
|
||||
return true;
|
||||
}
|
||||
|
||||
static TListFileCache * CreateListFileCache(
|
||||
LOAD_LISTFILE PfnLoadFile,
|
||||
TListFileHandle * pHandle,
|
||||
const char * szWildCard,
|
||||
DWORD dwFileSize,
|
||||
DWORD dwMaxSize,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
TListFileCache * pCache = NULL;
|
||||
size_t cchWildCardAligned = 0;
|
||||
size_t cchWildCard = 0;
|
||||
DWORD dwBytesRead = 0;
|
||||
|
||||
// Get the amount of bytes that need to be allocated
|
||||
if(dwFileSize == 0 || dwFileSize > dwMaxSize)
|
||||
return NULL;
|
||||
|
||||
// Append buffer for name mask, if any
|
||||
if(szWildCard != NULL)
|
||||
{
|
||||
cchWildCard = strlen(szWildCard) + 1;
|
||||
cchWildCardAligned = (cchWildCard + 3) & 0xFFFFFFFC;
|
||||
}
|
||||
|
||||
// Allocate cache for one file block
|
||||
pCache = (TListFileCache *)STORM_ALLOC(BYTE, sizeof(TListFileCache) + cchWildCardAligned + dwFileSize + 1);
|
||||
if(pCache != NULL)
|
||||
{
|
||||
// Clear the entire structure
|
||||
memset(pCache, 0, sizeof(TListFileCache) + cchWildCard);
|
||||
pCache->dwFlags = dwFlags;
|
||||
|
||||
// Shall we copy the mask?
|
||||
if(cchWildCard != 0)
|
||||
{
|
||||
pCache->szWildCard = (char *)(pCache + 1);
|
||||
memcpy(pCache->szWildCard, szWildCard, cchWildCard);
|
||||
}
|
||||
|
||||
// Fill-in the rest of the cache pointers
|
||||
pCache->pBegin = (LPBYTE)(pCache + 1) + cchWildCardAligned;
|
||||
|
||||
// Load the entire listfile to the cache
|
||||
PfnLoadFile(pHandle, pCache->pBegin, dwFileSize, &dwBytesRead);
|
||||
if(dwBytesRead != 0)
|
||||
{
|
||||
// Allocate pointers
|
||||
pCache->pPos = pCache->pBegin;
|
||||
pCache->pEnd = pCache->pBegin + dwBytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeListFileCache(pCache);
|
||||
pCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the cache
|
||||
return pCache;
|
||||
}
|
||||
|
||||
static TListFileCache * CreateListFileCache(
|
||||
HANDLE hMpq,
|
||||
const TCHAR * szListFile,
|
||||
const char * szWildCard,
|
||||
DWORD dwMaxSize,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
TListFileCache * pCache = NULL;
|
||||
TListFileHandle ListHandle = {NULL};
|
||||
|
||||
// Put default value to dwMaxSize
|
||||
if(dwMaxSize == 0)
|
||||
dwMaxSize = MAX_LISTFILE_SIZE;
|
||||
|
||||
// Internal listfile: hMPQ must be non NULL and szListFile must be NULL.
|
||||
// We load the MPQ::(listfile) file
|
||||
if(hMpq != NULL && szListFile == NULL)
|
||||
{
|
||||
DWORD dwFileSize = 0;
|
||||
|
||||
// Open the file from the MPQ
|
||||
if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &ListHandle.hFile))
|
||||
{
|
||||
// Get the file size and create the listfile cache
|
||||
dwFileSize = SFileGetFileSize(ListHandle.hFile, NULL);
|
||||
pCache = CreateListFileCache(LoadListFile_MPQ, &ListHandle, szWildCard, dwFileSize, dwMaxSize, dwFlags);
|
||||
|
||||
// Close the MPQ file
|
||||
SFileCloseFile(ListHandle.hFile);
|
||||
}
|
||||
|
||||
// Return the loaded cache
|
||||
return pCache;
|
||||
}
|
||||
|
||||
// External listfile: hMpq must be NULL and szListFile must be non-NULL.
|
||||
// We load the file using TFileStream
|
||||
if(hMpq == NULL && szListFile != NULL)
|
||||
{
|
||||
ULONGLONG FileSize = 0;
|
||||
|
||||
// Open the local file
|
||||
ListHandle.pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY);
|
||||
if(ListHandle.pStream != NULL)
|
||||
{
|
||||
// Verify the file size
|
||||
FileStream_GetSize(ListHandle.pStream, &FileSize);
|
||||
if(0 < FileSize && FileSize < dwMaxSize)
|
||||
{
|
||||
pCache = CreateListFileCache(LoadListFile_Stream, &ListHandle, szWildCard, (DWORD)FileSize, dwMaxSize, dwFlags);
|
||||
}
|
||||
|
||||
// Close the stream
|
||||
FileStream_Close(ListHandle.pStream);
|
||||
}
|
||||
|
||||
// Return the loaded cache
|
||||
return pCache;
|
||||
}
|
||||
|
||||
// This combination should never happen
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
/*
|
||||
TMPQNameCache * CreateNameCache(HANDLE hListFile, const char * szSearchMask)
|
||||
{
|
||||
TMPQNameCache * pNameCache;
|
||||
char * szCachePointer;
|
||||
size_t cbToAllocate;
|
||||
size_t nMaskLength = 1;
|
||||
DWORD dwBytesRead = 0;
|
||||
DWORD dwFileSize;
|
||||
|
||||
// Get the size of the listfile. Ignore zero or too long ones
|
||||
dwFileSize = SFileGetFileSize(hListFile, NULL);
|
||||
if(dwFileSize == 0 || dwFileSize > MAX_LISTFILE_SIZE)
|
||||
return NULL;
|
||||
|
||||
// Get the length of the search mask
|
||||
if(szSearchMask == NULL)
|
||||
szSearchMask = "*";
|
||||
nMaskLength = strlen(szSearchMask) + 1;
|
||||
|
||||
// Allocate the name cache
|
||||
cbToAllocate = sizeof(TMPQNameCache) + nMaskLength + dwFileSize + 1;
|
||||
pNameCache = (TMPQNameCache *)STORM_ALLOC(BYTE, cbToAllocate);
|
||||
if(pNameCache != NULL)
|
||||
{
|
||||
// Initialize the name cache
|
||||
memset(pNameCache, 0, sizeof(TMPQNameCache));
|
||||
pNameCache->TotalCacheSize = (DWORD)(nMaskLength + dwFileSize + 1);
|
||||
szCachePointer = (char *)(pNameCache + 1);
|
||||
|
||||
// Copy the search mask, if any
|
||||
memcpy(szCachePointer, szSearchMask, nMaskLength);
|
||||
pNameCache->FirstNameOffset = (DWORD)nMaskLength;
|
||||
pNameCache->FreeSpaceOffset = (DWORD)nMaskLength;
|
||||
|
||||
// Read the listfile itself
|
||||
SFileSetFilePointer(hListFile, 0, NULL, FILE_BEGIN);
|
||||
SFileReadFile(hListFile, szCachePointer + nMaskLength, dwFileSize, &dwBytesRead, NULL);
|
||||
|
||||
// If nothing has been read from the listfile, clear the cache
|
||||
if(dwBytesRead == 0)
|
||||
{
|
||||
STORM_FREE(pNameCache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Move the free space offset
|
||||
pNameCache->FreeSpaceOffset = pNameCache->FirstNameOffset + dwBytesRead + 1;
|
||||
szCachePointer[nMaskLength + dwBytesRead] = 0;
|
||||
}
|
||||
|
||||
return pNameCache;
|
||||
}
|
||||
|
||||
static void FreeNameCache(TMPQNameCache * pNameCache)
|
||||
{
|
||||
if(pNameCache != NULL)
|
||||
STORM_FREE(pNameCache);
|
||||
pNameCache = NULL;
|
||||
}
|
||||
*/
|
||||
#endif // _DEBUG
|
||||
|
||||
static char * ReadListFileLine(TListFileCache * pCache, size_t * PtrLength)
|
||||
{
|
||||
LPBYTE pbLineBegin;
|
||||
LPBYTE pbLineEnd;
|
||||
|
||||
// Skip newlines. Keep spaces and tabs, as they can be a legal part of the file name
|
||||
while(pCache->pPos < pCache->pEnd && (pCache->pPos[0] == 0x0A || pCache->pPos[0] == 0x0D))
|
||||
pCache->pPos++;
|
||||
|
||||
// Set the line begin and end
|
||||
if(pCache->pPos >= pCache->pEnd)
|
||||
return NULL;
|
||||
pbLineBegin = pbLineEnd = pCache->pPos;
|
||||
|
||||
// Find the end of the line
|
||||
while(pCache->pPos < pCache->pEnd && pCache->pPos[0] != 0x0A && pCache->pPos[0] != 0x0D)
|
||||
pCache->pPos++;
|
||||
|
||||
// Remember the end of the line
|
||||
pbLineEnd = pCache->pPos++;
|
||||
pbLineEnd[0] = 0;
|
||||
|
||||
// Give the line to the caller
|
||||
if(PtrLength != NULL)
|
||||
PtrLength[0] = (size_t)(pbLineEnd - pbLineBegin);
|
||||
return (char *)pbLineBegin;
|
||||
}
|
||||
|
||||
static int STORMLIB_CDECL CompareFileNodes(const void * p1, const void * p2)
|
||||
{
|
||||
char * szFileName1 = *(char **)p1;
|
||||
char * szFileName2 = *(char **)p2;
|
||||
|
||||
return _stricmp(szFileName1, szFileName2);
|
||||
}
|
||||
|
||||
static LPBYTE CreateListFile(TMPQArchive * ha, DWORD * pcbListFile)
|
||||
{
|
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
||||
TFileEntry * pFileEntry;
|
||||
char ** SortTable = NULL;
|
||||
char * szListFile = NULL;
|
||||
char * szListLine;
|
||||
size_t nFileNodes = 0;
|
||||
size_t cbListFile = 0;
|
||||
size_t nIndex0;
|
||||
size_t nIndex1;
|
||||
|
||||
// Allocate the table for sorting listfile
|
||||
SortTable = STORM_ALLOC(char*, ha->dwFileTableSize);
|
||||
if(SortTable == NULL)
|
||||
return NULL;
|
||||
|
||||
// Construct the sort table
|
||||
// Note: in MPQs with multiple locale versions of the same file,
|
||||
// this code causes adding multiple listfile entries.
|
||||
// They will get removed after the listfile sorting
|
||||
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
||||
{
|
||||
// Only take existing items
|
||||
if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
|
||||
{
|
||||
// Ignore pseudo-names and internal names
|
||||
if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName))
|
||||
{
|
||||
for (int i = 0; i < strlen(pFileEntry->szFileName); i++)
|
||||
{
|
||||
// OTRTODO
|
||||
//if (pFileEntry->szFileName[i] == '/')
|
||||
//pFileEntry->szFileName[i] = '\\';
|
||||
}
|
||||
|
||||
SortTable[nFileNodes++] = pFileEntry->szFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove duplicities
|
||||
if(nFileNodes > 0)
|
||||
{
|
||||
// Sort the table
|
||||
qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes);
|
||||
|
||||
// Count the 0-th item
|
||||
cbListFile += strlen(SortTable[0]) + 2;
|
||||
|
||||
// Walk through the items and only use the ones that are not duplicated
|
||||
for(nIndex0 = 0, nIndex1 = 1; nIndex1 < nFileNodes; nIndex1++)
|
||||
{
|
||||
// If the next file node is different, we will include it to the result listfile
|
||||
if(_stricmp(SortTable[nIndex1], SortTable[nIndex0]) != 0)
|
||||
{
|
||||
cbListFile += strlen(SortTable[nIndex1]) + 2;
|
||||
nIndex0 = nIndex1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now allocate buffer for the entire listfile
|
||||
szListFile = szListLine = STORM_ALLOC(char, cbListFile + 1);
|
||||
if(szListFile != NULL)
|
||||
{
|
||||
// Copy the 0-th item
|
||||
szListLine = CopyListLine(szListLine, SortTable[0]);
|
||||
|
||||
// Walk through the items and only use the ones that are not duplicated
|
||||
for(nIndex0 = 0, nIndex1 = 1; nIndex1 < nFileNodes; nIndex1++)
|
||||
{
|
||||
// If the next file node is different, we will include it to the result listfile
|
||||
if(_stricmp(SortTable[nIndex1], SortTable[nIndex0]) != 0)
|
||||
{
|
||||
// Copy the listfile line
|
||||
szListLine = CopyListLine(szListLine, SortTable[nIndex1]);
|
||||
nIndex0 = nIndex1;
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check - does the size match?
|
||||
assert((size_t)(szListLine - szListFile) == cbListFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szListFile = STORM_ALLOC(char, 1);
|
||||
cbListFile = 0;
|
||||
}
|
||||
|
||||
// Free the sort table
|
||||
STORM_FREE(SortTable);
|
||||
|
||||
// Give away the listfile
|
||||
if(pcbListFile != NULL)
|
||||
*pcbListFile = (DWORD)cbListFile;
|
||||
return (LPBYTE)szListFile;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions (listfile nodes)
|
||||
|
||||
// Adds a name into the list of all names. For each locale in the MPQ,
|
||||
// one entry will be created
|
||||
// If the file name is already there, does nothing.
|
||||
static DWORD SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName)
|
||||
{
|
||||
TFileEntry * pFileEntry;
|
||||
TMPQHash * pFirstHash;
|
||||
TMPQHash * pHash;
|
||||
|
||||
// If we have HET table, use that one
|
||||
if(ha->pHetTable != NULL)
|
||||
{
|
||||
pFileEntry = GetFileEntryLocale(ha, szFileName, 0);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// Allocate file name for the file entry
|
||||
AllocateFileName(ha, pFileEntry, szFileName);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If we have hash table, we use it
|
||||
if(ha->pHashTable != NULL)
|
||||
{
|
||||
// Go while we found something
|
||||
pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
|
||||
while(pHash != NULL)
|
||||
{
|
||||
// Allocate file name for the file entry
|
||||
AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName);
|
||||
|
||||
// Now find the next language version of the file
|
||||
pHash = GetNextHashEntry(ha, pFirstHash, pHash);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_CAN_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
// Saves the whole listfile to the MPQ
|
||||
DWORD SListFileSaveToMpq(TMPQArchive * ha)
|
||||
{
|
||||
TMPQFile * hf = NULL;
|
||||
LPBYTE pbListFile;
|
||||
DWORD cbListFile = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Only save the listfile if we should do so
|
||||
if(ha->dwFileFlags1 != 0)
|
||||
{
|
||||
// At this point, we expect to have at least one reserved entry in the file table
|
||||
assert(ha->dwFlags & MPQ_FLAG_LISTFILE_NEW);
|
||||
assert(ha->dwReservedFiles > 0);
|
||||
|
||||
// Create the raw data that is to be written to (listfile)
|
||||
// Note: Creating the raw data before the (listfile) has been created in the MPQ
|
||||
// causes that the name of the listfile will not be included in the listfile itself.
|
||||
// That is OK, because (listfile) in Blizzard MPQs does not contain it either.
|
||||
pbListFile = CreateListFile(ha, &cbListFile);
|
||||
if(pbListFile != NULL)
|
||||
{
|
||||
// Determine the real flags for (listfile)
|
||||
if(ha->dwFileFlags1 == MPQ_FILE_DEFAULT_INTERNAL)
|
||||
ha->dwFileFlags1 = GetDefaultSpecialFileFlags(cbListFile, ha->pHeader->wFormatVersion);
|
||||
|
||||
// Create the listfile in the MPQ
|
||||
dwErrCode = SFileAddFile_Init(ha, LISTFILE_NAME,
|
||||
0,
|
||||
cbListFile,
|
||||
LANG_NEUTRAL,
|
||||
ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING,
|
||||
&hf);
|
||||
|
||||
// Write the listfile raw data to it
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Write the content of the listfile to the MPQ
|
||||
dwErrCode = SFileAddFile_Write(hf, pbListFile, cbListFile, MPQ_COMPRESSION_ZLIB);
|
||||
SFileAddFile_Finish(hf);
|
||||
}
|
||||
|
||||
// Clear the listfile flags
|
||||
ha->dwFlags &= ~(MPQ_FLAG_LISTFILE_NEW | MPQ_FLAG_LISTFILE_NONE);
|
||||
ha->dwReservedFiles--;
|
||||
|
||||
// Free the listfile buffer
|
||||
STORM_FREE(pbListFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the (listfile) file would be empty, its OK
|
||||
dwErrCode = (cbListFile == 0) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD SFileAddArbitraryListFile(
|
||||
TMPQArchive * ha,
|
||||
HANDLE hMpq,
|
||||
const TCHAR * szListFile,
|
||||
DWORD dwMaxSize)
|
||||
{
|
||||
TListFileCache * pCache = NULL;
|
||||
|
||||
// Create the listfile cache for that file
|
||||
pCache = CreateListFileCache(hMpq, szListFile, NULL, dwMaxSize, ha->dwFlags);
|
||||
if(pCache != NULL)
|
||||
{
|
||||
char * szFileName;
|
||||
size_t nLength = 0;
|
||||
|
||||
// Get the next line
|
||||
while((szFileName = ReadListFileLine(pCache, &nLength)) != NULL)
|
||||
{
|
||||
// Add the line to the MPQ
|
||||
if(nLength != 0)
|
||||
SListFileCreateNodeForAllLocales(ha, szFileName);
|
||||
}
|
||||
|
||||
// Delete the cache
|
||||
FreeListFileCache(pCache);
|
||||
}
|
||||
|
||||
return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
static DWORD SFileAddInternalListFile(
|
||||
TMPQArchive * ha,
|
||||
HANDLE hMpq)
|
||||
{
|
||||
TMPQHash * pFirstHash;
|
||||
TMPQHash * pHash;
|
||||
LCID lcSaveLocale = g_lcFileLocale;
|
||||
DWORD dwMaxSize = MAX_LISTFILE_SIZE;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// If there is hash table, we need to support multiple listfiles
|
||||
// with different locales (BrooDat.mpq)
|
||||
if(ha->pHashTable != NULL)
|
||||
{
|
||||
// If the archive is a malformed map, ignore too large listfiles
|
||||
if(ha->dwFlags & MPQ_FLAG_MALFORMED)
|
||||
dwMaxSize = 0x40000;
|
||||
|
||||
pFirstHash = pHash = GetFirstHashEntry(ha, LISTFILE_NAME);
|
||||
while(dwErrCode == ERROR_SUCCESS && pHash != NULL)
|
||||
{
|
||||
// Set the prefered locale to that from list file
|
||||
SFileSetLocale(pHash->lcLocale);
|
||||
|
||||
// Add that listfile
|
||||
dwErrCode = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize);
|
||||
|
||||
// Move to the next hash
|
||||
pHash = GetNextHashEntry(ha, pFirstHash, pHash);
|
||||
}
|
||||
|
||||
// Restore the original locale
|
||||
SFileSetLocale(lcSaveLocale);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the single listfile
|
||||
dwErrCode = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize);
|
||||
}
|
||||
|
||||
// Return the result of the operation
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static bool DoListFileSearch(TListFileCache * pCache, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
// Check for the valid search handle
|
||||
if(pCache != NULL)
|
||||
{
|
||||
char * szFileName;
|
||||
size_t nLength = 0;
|
||||
|
||||
// Get the next line
|
||||
while((szFileName = ReadListFileLine(pCache, &nLength)) != NULL)
|
||||
{
|
||||
// Check search mask
|
||||
if(nLength != 0 && SFileCheckWildCard(szFileName, pCache->szWildCard))
|
||||
{
|
||||
if(nLength >= sizeof(lpFindFileData->cFileName))
|
||||
nLength = sizeof(lpFindFileData->cFileName) - 1;
|
||||
|
||||
memcpy(lpFindFileData->cFileName, szFileName, nLength);
|
||||
lpFindFileData->cFileName[nLength] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No more files
|
||||
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
|
||||
SetLastError(ERROR_NO_MORE_FILES);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File functions
|
||||
|
||||
// Adds a listfile into the MPQ archive.
|
||||
DWORD WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Add the listfile for each MPQ in the patch chain
|
||||
while(ha != NULL)
|
||||
{
|
||||
if(szListFile != NULL)
|
||||
dwErrCode = SFileAddArbitraryListFile(ha, NULL, szListFile, MAX_LISTFILE_SIZE);
|
||||
else
|
||||
dwErrCode = SFileAddInternalListFile(ha, hMpq);
|
||||
|
||||
// Also, add three special files to the listfile:
|
||||
// (listfile) itself, (attributes) and (signature)
|
||||
SListFileCreateNodeForAllLocales(ha, LISTFILE_NAME);
|
||||
SListFileCreateNodeForAllLocales(ha, SIGNATURE_NAME);
|
||||
SListFileCreateNodeForAllLocales(ha, ATTRIBUTES_NAME);
|
||||
|
||||
// Move to the next archive in the chain
|
||||
ha = ha->haPatch;
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enumerating files in listfile
|
||||
|
||||
HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const TCHAR * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
TListFileCache * pCache = NULL;
|
||||
|
||||
// Initialize the structure with zeros
|
||||
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
|
||||
|
||||
// Open the local/internal listfile
|
||||
pCache = CreateListFileCache(hMpq, szListFile, szMask, 0, 0);
|
||||
if(pCache != NULL)
|
||||
{
|
||||
if(!DoListFileSearch(pCache, lpFindFileData))
|
||||
{
|
||||
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
|
||||
SetLastError(ERROR_NO_MORE_FILES);
|
||||
FreeListFileCache(pCache);
|
||||
pCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the listfile cache as handle
|
||||
return (HANDLE)pCache;
|
||||
}
|
||||
|
||||
bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
return DoListFileSearch((TListFileCache *)hFind, lpFindFileData);
|
||||
}
|
||||
|
||||
bool WINAPI SListFileFindClose(HANDLE hFind)
|
||||
{
|
||||
TListFileCache * pCache = (TListFileCache *)hFind;
|
||||
|
||||
return FreeListFileCache(pCache);
|
||||
}
|
||||
|
658
StormLib/src/SFileOpenArchive.cpp
Normal file
658
StormLib/src/SFileOpenArchive.cpp
Normal file
@ -0,0 +1,658 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */
|
||||
/* */
|
||||
/* Author : Ladislav Zezula */
|
||||
/* E-mail : ladik@zezula.net */
|
||||
/* WWW : www.zezula.net */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Implementation of archive functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* xx.xx.xx 1.00 Lad Created */
|
||||
/* 19.11.03 1.01 Dan Big endian handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
#define HEADER_SEARCH_BUFFER_SIZE 0x1000
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer)
|
||||
{
|
||||
LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer;
|
||||
LPCTSTR szExtension;
|
||||
|
||||
// Don't do any checks if there is not at least 16 bytes
|
||||
if(cbHeaderBuffer > 0x10)
|
||||
{
|
||||
DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderInt32[0]);
|
||||
DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderInt32[1]);
|
||||
DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]);
|
||||
DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]);
|
||||
|
||||
// Test for AVI files (Warcraft III cinematics) - 'RIFF', 'AVI ' or 'LIST'
|
||||
if(DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C)
|
||||
return MapTypeAviFile;
|
||||
|
||||
// Check for Starcraft II maps
|
||||
if((szExtension = _tcsrchr(szFileName, _T('.'))) != NULL)
|
||||
{
|
||||
// The "NP_Protect" protector places fake Warcraft III header
|
||||
// into the Starcraft II maps, whilst SC2 maps have no other header but MPQ v4
|
||||
if(!_tcsicmp(szExtension, _T(".s2ma")) || !_tcsicmp(szExtension, _T(".SC2Map")) || !_tcsicmp(szExtension, _T(".SC2Mod")))
|
||||
{
|
||||
return MapTypeStarcraft2;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Warcraft III maps
|
||||
if(DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000)
|
||||
return MapTypeWarcraft3;
|
||||
}
|
||||
|
||||
// MIX files are DLL files that contain MPQ in overlay.
|
||||
// Only Warcraft III is able to load them, so we consider them Warcraft III maps
|
||||
if(cbHeaderBuffer > 0x200 && pbHeaderBuffer[0] == 'M' && pbHeaderBuffer[1] == 'Z')
|
||||
{
|
||||
// Check the value of IMAGE_DOS_HEADER::e_lfanew at offset 0x3C
|
||||
if(0 < HeaderInt32[0x0F] && HeaderInt32[0x0F] < 0x10000)
|
||||
return MapTypeWarcraft3;
|
||||
}
|
||||
|
||||
// No special map type recognized
|
||||
return MapTypeNotRecognized;
|
||||
}
|
||||
|
||||
static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData)
|
||||
{
|
||||
TMPQUserData * pUserData;
|
||||
|
||||
// BSWAP the source data and copy them to our buffer
|
||||
BSWAP_ARRAY32_UNSIGNED(pvUserData, sizeof(TMPQUserData));
|
||||
pUserData = (TMPQUserData *)pvUserData;
|
||||
|
||||
// Check the sizes
|
||||
if(pUserData->cbUserDataHeader <= pUserData->cbUserDataSize && pUserData->cbUserDataSize <= pUserData->dwHeaderOffs)
|
||||
{
|
||||
// Move to the position given by the userdata
|
||||
ByteOffset += pUserData->dwHeaderOffs;
|
||||
|
||||
// The MPQ header should be within range of the file size
|
||||
if((ByteOffset + MPQ_HEADER_SIZE_V1) < FileSize)
|
||||
{
|
||||
// Note: We should verify if there is the MPQ header.
|
||||
// However, the header could be at any position below that
|
||||
// that is multiplier of 0x200
|
||||
return (TMPQUserData *)pvUserData;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This function gets the right positions of the hash table and the block table.
|
||||
static DWORD VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
|
||||
{
|
||||
TMPQHeader * pHeader = ha->pHeader;
|
||||
ULONGLONG ByteOffset;
|
||||
//bool bMalformed = (ha->dwFlags & MPQ_FLAG_MALFORMED) ? true : false;
|
||||
|
||||
// Check the begin of HET table
|
||||
if(pHeader->HetTablePos64)
|
||||
{
|
||||
ByteOffset = ha->MpqPos + pHeader->HetTablePos64;
|
||||
if(ByteOffset > FileSize)
|
||||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
// Check the begin of BET table
|
||||
if(pHeader->BetTablePos64)
|
||||
{
|
||||
ByteOffset = ha->MpqPos + pHeader->BetTablePos64;
|
||||
if(ByteOffset > FileSize)
|
||||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
// Check the begin of hash table
|
||||
if(pHeader->wHashTablePosHi || pHeader->dwHashTablePos)
|
||||
{
|
||||
ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos));
|
||||
if(ByteOffset > FileSize)
|
||||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
// Check the begin of block table
|
||||
if(pHeader->wBlockTablePosHi || pHeader->dwBlockTablePos)
|
||||
{
|
||||
ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos));
|
||||
if(ByteOffset > FileSize)
|
||||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
// Check the begin of hi-block table
|
||||
//if(pHeader->HiBlockTablePos64 != 0)
|
||||
//{
|
||||
// ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64;
|
||||
// if(ByteOffset > FileSize)
|
||||
// return ERROR_BAD_FORMAT;
|
||||
//}
|
||||
|
||||
// All OK.
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for alternate markers. Call before opening an archive
|
||||
|
||||
#define SFILE_MARKERS_MIN_SIZE (sizeof(DWORD) + sizeof(DWORD) + sizeof(const char *) + sizeof(const char *))
|
||||
|
||||
bool WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers)
|
||||
{
|
||||
// Check structure minimum size
|
||||
if(pMarkers == NULL || pMarkers->dwSize < SFILE_MARKERS_MIN_SIZE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that the MPQ cryptography is initialized at this time
|
||||
InitializeMpqCryptography();
|
||||
|
||||
// Remember the marker for MPQ header
|
||||
if(pMarkers->dwSignature != 0)
|
||||
g_dwMpqSignature = pMarkers->dwSignature;
|
||||
|
||||
// Remember the encryption key for hash table
|
||||
if(pMarkers->szHashTableKey != NULL)
|
||||
g_dwHashTableKey = HashString(pMarkers->szHashTableKey, MPQ_HASH_FILE_KEY);
|
||||
|
||||
// Remember the encryption key for block table
|
||||
if(pMarkers->szBlockTableKey != NULL)
|
||||
g_dwBlockTableKey = HashString(pMarkers->szBlockTableKey, MPQ_HASH_FILE_KEY);
|
||||
|
||||
// Succeeded
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileGetLocale and SFileSetLocale
|
||||
// Set the locale for all newly opened files
|
||||
|
||||
LCID WINAPI SFileGetLocale()
|
||||
{
|
||||
return g_lcFileLocale;
|
||||
}
|
||||
|
||||
LCID WINAPI SFileSetLocale(LCID lcNewLocale)
|
||||
{
|
||||
g_lcFileLocale = lcNewLocale;
|
||||
return g_lcFileLocale;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileOpenArchive
|
||||
//
|
||||
// szFileName - MPQ archive file name to open
|
||||
// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives
|
||||
// dwFlags - See MPQ_OPEN_XXX in StormLib.h
|
||||
// phMpq - Pointer to store open archive handle
|
||||
|
||||
bool WINAPI SFileOpenArchive(
|
||||
const TCHAR * szMpqName,
|
||||
DWORD dwPriority,
|
||||
DWORD dwFlags,
|
||||
HANDLE * phMpq)
|
||||
{
|
||||
TMPQUserData * pUserData;
|
||||
TFileStream * pStream = NULL; // Open file stream
|
||||
TMPQArchive * ha = NULL; // Archive handle
|
||||
TFileEntry * pFileEntry;
|
||||
ULONGLONG FileSize = 0; // Size of the file
|
||||
LPBYTE pbHeaderBuffer = NULL; // Buffer for searching MPQ header
|
||||
DWORD dwStreamFlags = (dwFlags & STREAM_FLAGS_MASK);
|
||||
MTYPE MapType = MapTypeNotChecked;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Verify the parameters
|
||||
if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// One time initialization of MPQ cryptography
|
||||
InitializeMpqCryptography();
|
||||
dwPriority = dwPriority;
|
||||
|
||||
// If not forcing MPQ v 1.0, also use file bitmap
|
||||
dwStreamFlags |= (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) ? 0 : STREAM_FLAG_USE_BITMAP;
|
||||
|
||||
// Open the MPQ archive file
|
||||
pStream = FileStream_OpenFile(szMpqName, dwStreamFlags);
|
||||
if(pStream == NULL)
|
||||
return false;
|
||||
|
||||
// Check the file size. There must be at least 0x20 bytes
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
FileStream_GetSize(pStream, &FileSize);
|
||||
if(FileSize < MPQ_HEADER_SIZE_V1)
|
||||
dwErrCode = ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
// Allocate the MPQhandle
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Allocate buffer for searching MPQ header
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
pbHeaderBuffer = STORM_ALLOC(BYTE, HEADER_SEARCH_BUFFER_SIZE);
|
||||
if(pbHeaderBuffer == NULL)
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Find the position of MPQ header
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
ULONGLONG ByteOffset = 0;
|
||||
ULONGLONG EndOfSearch = FileSize;
|
||||
DWORD dwStrmFlags = 0;
|
||||
DWORD dwHeaderSize;
|
||||
DWORD dwHeaderID;
|
||||
bool bSearchComplete = false;
|
||||
|
||||
memset(ha, 0, sizeof(TMPQArchive));
|
||||
ha->pfnHashString = HashStringSlash;
|
||||
ha->pStream = pStream;
|
||||
pStream = NULL;
|
||||
|
||||
// Set the archive read only if the stream is read-only
|
||||
FileStream_GetFlags(ha->pStream, &dwStrmFlags);
|
||||
ha->dwFlags |= (dwStrmFlags & STREAM_FLAG_READ_ONLY) ? MPQ_FLAG_READ_ONLY : 0;
|
||||
|
||||
// Also remember if we shall check sector CRCs when reading file
|
||||
ha->dwFlags |= (dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC) ? MPQ_FLAG_CHECK_SECTOR_CRC : 0;
|
||||
|
||||
// Also remember if this MPQ is a patch
|
||||
ha->dwFlags |= (dwFlags & MPQ_OPEN_PATCH) ? MPQ_FLAG_PATCH : 0;
|
||||
|
||||
// Limit the header searching to about 130 MB of data
|
||||
if(EndOfSearch > 0x08000000)
|
||||
EndOfSearch = 0x08000000;
|
||||
|
||||
// Find the offset of MPQ header within the file
|
||||
while(bSearchComplete == false && ByteOffset < EndOfSearch)
|
||||
{
|
||||
// Always read at least 0x1000 bytes for performance.
|
||||
// This is what Storm.dll (2002) does.
|
||||
DWORD dwBytesAvailable = HEADER_SEARCH_BUFFER_SIZE;
|
||||
|
||||
// Cut the bytes available, if needed
|
||||
if((FileSize - ByteOffset) < HEADER_SEARCH_BUFFER_SIZE)
|
||||
dwBytesAvailable = (DWORD)(FileSize - ByteOffset);
|
||||
|
||||
// Read the eventual MPQ header
|
||||
if(!FileStream_Read(ha->pStream, &ByteOffset, pbHeaderBuffer, dwBytesAvailable))
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Check whether the file is AVI file or a Warcraft III/Starcraft II map
|
||||
if(MapType == MapTypeNotChecked)
|
||||
{
|
||||
// Do nothing if the file is an AVI file
|
||||
if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile)
|
||||
{
|
||||
dwErrCode = ERROR_AVI_FILE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search the header buffer
|
||||
for(DWORD dwInBufferOffset = 0; dwInBufferOffset < dwBytesAvailable; dwInBufferOffset += 0x200)
|
||||
{
|
||||
// Copy the data from the potential header buffer to the MPQ header
|
||||
memcpy(ha->HeaderData, pbHeaderBuffer + dwInBufferOffset, sizeof(ha->HeaderData));
|
||||
|
||||
// If there is the MPQ user data, process it
|
||||
// Note that Warcraft III does not check for user data, which is abused by many map protectors
|
||||
dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]);
|
||||
if(MapType != MapTypeWarcraft3 && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
|
||||
{
|
||||
if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA)
|
||||
{
|
||||
// Verify if this looks like a valid user data
|
||||
pUserData = IsValidMpqUserData(ByteOffset, FileSize, ha->HeaderData);
|
||||
if(pUserData != NULL)
|
||||
{
|
||||
// Fill the user data header
|
||||
ha->UserDataPos = ByteOffset;
|
||||
ha->pUserData = &ha->UserData;
|
||||
memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData));
|
||||
|
||||
// Continue searching from that position
|
||||
ByteOffset += ha->pUserData->dwHeaderOffs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There must be MPQ header signature. Note that STORM.dll from Warcraft III actually
|
||||
// tests the MPQ header size. It must be at least 0x20 bytes in order to load it
|
||||
// Abused by Spazzler Map protector. Note that the size check is not present
|
||||
// in Storm.dll v 1.00, so Diablo I code would load the MPQ anyway.
|
||||
dwHeaderSize = BSWAP_INT32_UNSIGNED(ha->HeaderData[1]);
|
||||
if(dwHeaderID == g_dwMpqSignature && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
|
||||
{
|
||||
// Now convert the header to version 4
|
||||
dwErrCode = ConvertMpqHeaderToFormat4(ha, ByteOffset, FileSize, dwFlags, MapType);
|
||||
if(dwErrCode != ERROR_FAKE_MPQ_HEADER)
|
||||
{
|
||||
bSearchComplete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for MPK archives (Longwu Online - MPQ fork)
|
||||
if(MapType == MapTypeNotRecognized && dwHeaderID == ID_MPK)
|
||||
{
|
||||
// Now convert the MPK header to MPQ Header version 4
|
||||
dwErrCode = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags);
|
||||
bSearchComplete = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If searching for the MPQ header is disabled, return an error
|
||||
if(dwFlags & MPQ_OPEN_NO_HEADER_SEARCH)
|
||||
{
|
||||
dwErrCode = ERROR_NOT_SUPPORTED;
|
||||
bSearchComplete = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Move the pointers
|
||||
ByteOffset += 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
// Did we identify one of the supported headers?
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Set the user data position to the MPQ header, if none
|
||||
if(ha->pUserData == NULL)
|
||||
ha->UserDataPos = ByteOffset;
|
||||
|
||||
// Set the position of the MPQ header
|
||||
ha->pHeader = (TMPQHeader *)ha->HeaderData;
|
||||
ha->MpqPos = ByteOffset;
|
||||
ha->FileSize = FileSize;
|
||||
|
||||
// Sector size must be nonzero.
|
||||
if(ByteOffset >= FileSize || ha->pHeader->wSectorSize == 0)
|
||||
dwErrCode = ERROR_BAD_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix table positions according to format
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Dump the header
|
||||
// DumpMpqHeader(ha->pHeader);
|
||||
|
||||
// W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data,
|
||||
// and ignores the MPQ format version as well. The trick is to
|
||||
// fake MPQ format 2, with an improper hi-word position of hash table and block table
|
||||
// We can overcome such protectors by forcing opening the archive as MPQ v 1.0
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
|
||||
{
|
||||
ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1;
|
||||
ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1;
|
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY;
|
||||
ha->pUserData = NULL;
|
||||
}
|
||||
|
||||
// Anti-overflow. If the hash table size in the header is
|
||||
// higher than 0x10000000, it would overflow in 32-bit version
|
||||
// Observed in the malformed Warcraft III maps
|
||||
// Example map: MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x
|
||||
ha->pHeader->dwBlockTableSize = (ha->pHeader->dwBlockTableSize & BLOCK_INDEX_MASK);
|
||||
ha->pHeader->dwHashTableSize = (ha->pHeader->dwHashTableSize & BLOCK_INDEX_MASK);
|
||||
|
||||
// Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode
|
||||
if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES))
|
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY;
|
||||
|
||||
// Check if the caller wants to force adding listfile
|
||||
if(dwFlags & MPQ_OPEN_FORCE_LISTFILE)
|
||||
ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE;
|
||||
|
||||
// Remember whether whis is a map for Warcraft III
|
||||
if(MapType == MapTypeWarcraft3)
|
||||
ha->dwFlags |= MPQ_FLAG_WAR3_MAP;
|
||||
|
||||
// Set the size of file sector
|
||||
ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize);
|
||||
|
||||
// Verify if any of the tables doesn't start beyond the end of the file
|
||||
dwErrCode = VerifyMpqTablePositions(ha, FileSize);
|
||||
}
|
||||
|
||||
// Read the hash table. Ignore the result, as hash table is no longer required
|
||||
// Read HET table. Ignore the result, as HET table is no longer required
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = LoadAnyHashTable(ha);
|
||||
}
|
||||
|
||||
// Now, build the file table. It will be built by combining
|
||||
// the block table, BET table, hi-block table, (attributes) and (listfile).
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = BuildFileTable(ha);
|
||||
}
|
||||
|
||||
// Load the internal listfile and include it to the file table
|
||||
if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0)
|
||||
{
|
||||
// Quick check for (listfile)
|
||||
pFileEntry = GetFileEntryLocale(ha, LISTFILE_NAME, LANG_NEUTRAL);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// Ignore result of the operation. (listfile) is optional.
|
||||
SFileAddListFile((HANDLE)ha, NULL);
|
||||
ha->dwFileFlags1 = pFileEntry->dwFlags;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the "(attributes)" file and merge it to the file table
|
||||
if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0 && (ha->dwFlags & MPQ_FLAG_BLOCK_TABLE_CUT) == 0)
|
||||
{
|
||||
// Quick check for (attributes)
|
||||
pFileEntry = GetFileEntryLocale(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// Ignore result of the operation. (attributes) is optional.
|
||||
SAttrLoadAttributes(ha);
|
||||
ha->dwFileFlags2 = pFileEntry->dwFlags;
|
||||
}
|
||||
}
|
||||
|
||||
// Remember whether the archive has weak signature. Only for MPQs format 1.0.
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Quick check for (signature)
|
||||
pFileEntry = GetFileEntryLocale(ha, SIGNATURE_NAME, LANG_NEUTRAL);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// Just remember that the archive is weak-signed
|
||||
assert((pFileEntry->dwFlags & MPQ_FILE_EXISTS) != 0);
|
||||
ha->dwFileFlags3 = pFileEntry->dwFlags;
|
||||
}
|
||||
|
||||
// Finally, set the MPQ_FLAG_READ_ONLY if the MPQ was found malformed
|
||||
ha->dwFlags |= (ha->dwFlags & MPQ_FLAG_MALFORMED) ? MPQ_FLAG_READ_ONLY : 0;
|
||||
}
|
||||
|
||||
// Cleanup and exit
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
FileStream_Close(pStream);
|
||||
FreeArchiveHandle(ha);
|
||||
SetLastError(dwErrCode);
|
||||
ha = NULL;
|
||||
}
|
||||
|
||||
// Free the header buffer
|
||||
if(pbHeaderBuffer != NULL)
|
||||
STORM_FREE(pbHeaderBuffer);
|
||||
if(phMpq != NULL)
|
||||
*phMpq = ha;
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool WINAPI SFileSetDownloadCallback(HANDLE, SFILE_DOWNLOAD_CALLBACK, void *);
|
||||
//
|
||||
// Sets a callback that is called when content is downloaded from the master MPQ
|
||||
//
|
||||
|
||||
bool WINAPI SFileSetDownloadCallback(HANDLE hMpq, SFILE_DOWNLOAD_CALLBACK DownloadCB, void * pvUserData)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
|
||||
// Do nothing if 'hMpq' is bad parameter
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
return FileStream_SetCallback(ha->pStream, DownloadCB, pvUserData);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool SFileFlushArchive(HANDLE hMpq)
|
||||
//
|
||||
// Saves all dirty data into MPQ archive.
|
||||
// Has similar effect like SFileCloseArchive, but the archive is not closed.
|
||||
// Use on clients who keep MPQ archive open even for write operations,
|
||||
// and terminating without calling SFileCloseArchive might corrupt the archive.
|
||||
//
|
||||
|
||||
bool WINAPI SFileFlushArchive(HANDLE hMpq)
|
||||
{
|
||||
TMPQArchive * ha;
|
||||
DWORD dwResultError = ERROR_SUCCESS;
|
||||
DWORD dwErrCode;
|
||||
|
||||
// Do nothing if 'hMpq' is bad parameter
|
||||
if((ha = IsValidMpqHandle(hMpq)) == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only if the MPQ was changed
|
||||
if(ha->dwFlags & MPQ_FLAG_CHANGED)
|
||||
{
|
||||
// Indicate that we are saving MPQ internal structures
|
||||
ha->dwFlags |= MPQ_FLAG_SAVING_TABLES;
|
||||
|
||||
// Defragment the file table. This will allow us to put the internal files to the end
|
||||
DefragmentFileTable(ha);
|
||||
|
||||
//
|
||||
// Create each internal file
|
||||
// Note that the (signature) file is usually before (listfile) in the file table
|
||||
//
|
||||
|
||||
if(ha->dwFlags & MPQ_FLAG_SIGNATURE_NEW)
|
||||
{
|
||||
dwErrCode = SSignFileCreate(ha);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
dwResultError = dwErrCode;
|
||||
}
|
||||
|
||||
if(ha->dwFlags & (MPQ_FLAG_LISTFILE_NEW | MPQ_FLAG_LISTFILE_FORCE))
|
||||
{
|
||||
dwErrCode = SListFileSaveToMpq(ha);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
dwResultError = dwErrCode;
|
||||
}
|
||||
|
||||
if(ha->dwFlags & MPQ_FLAG_ATTRIBUTES_NEW)
|
||||
{
|
||||
dwErrCode = SAttrFileSaveToMpq(ha);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
dwResultError = dwErrCode;
|
||||
}
|
||||
|
||||
// Save HET table, BET table, hash table, block table, hi-block table
|
||||
if(ha->dwFlags & MPQ_FLAG_CHANGED)
|
||||
{
|
||||
// Rebuild the HET table
|
||||
if(ha->pHetTable != NULL)
|
||||
RebuildHetTable(ha);
|
||||
|
||||
// Save all MPQ tables first
|
||||
dwErrCode = SaveMPQTables(ha);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
dwResultError = dwErrCode;
|
||||
|
||||
// If the archive has weak signature, we need to finish it
|
||||
if(ha->dwFileFlags3 != 0)
|
||||
{
|
||||
dwErrCode = SSignFileFinish(ha);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
dwResultError = dwErrCode;
|
||||
}
|
||||
}
|
||||
|
||||
// We are no longer saving internal MPQ structures
|
||||
ha->dwFlags &= ~MPQ_FLAG_SAVING_TABLES;
|
||||
}
|
||||
|
||||
// Return the error
|
||||
if(dwResultError != ERROR_SUCCESS)
|
||||
SetLastError(dwResultError);
|
||||
return (dwResultError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool SFileCloseArchive(HANDLE hMpq);
|
||||
//
|
||||
|
||||
bool WINAPI SFileCloseArchive(HANDLE hMpq)
|
||||
{
|
||||
TMPQArchive * ha = IsValidMpqHandle(hMpq);
|
||||
bool bResult = false;
|
||||
|
||||
// Only if the handle is valid
|
||||
if(ha == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Invalidate the add file callback so it won't be called
|
||||
// when saving (listfile) and (attributes)
|
||||
ha->pfnAddFileCB = NULL;
|
||||
ha->pvAddFileUserData = NULL;
|
||||
|
||||
// Flush all unsaved data to the storage
|
||||
bResult = SFileFlushArchive(hMpq);
|
||||
|
||||
// Free all memory used by MPQ archive
|
||||
FreeArchiveHandle(ha);
|
||||
return bResult;
|
||||
}
|
418
StormLib/src/SFileOpenFileEx.cpp
Normal file
418
StormLib/src/SFileOpenFileEx.cpp
Normal file
@ -0,0 +1,418 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description : */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Local functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex)
|
||||
{
|
||||
TMPQHash * pHashTableEnd;
|
||||
TMPQHash * pHash;
|
||||
DWORD dwFirstIndex = HASH_ENTRY_FREE;
|
||||
|
||||
// Should only be called if the archive has hash table
|
||||
assert(ha->pHashTable != NULL);
|
||||
|
||||
// Multiple hash table entries can point to the file table entry.
|
||||
// We need to search all of them
|
||||
pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
|
||||
for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++)
|
||||
{
|
||||
if(MPQ_BLOCK_INDEX(pHash) == dwFileIndex)
|
||||
{
|
||||
// Duplicate hash entry found
|
||||
if(dwFirstIndex != HASH_ENTRY_FREE)
|
||||
return HASH_ENTRY_FREE;
|
||||
dwFirstIndex = (DWORD)(pHash - ha->pHashTable);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the hash table entry index
|
||||
return dwFirstIndex;
|
||||
}
|
||||
|
||||
static const char * GetPatchFileName(TMPQArchive * ha, const char * szFileName, char * szBuffer)
|
||||
{
|
||||
TMPQNamePrefix * pPrefix;
|
||||
|
||||
// Are there patches in the current MPQ?
|
||||
if(ha->dwFlags & MPQ_FLAG_PATCH)
|
||||
{
|
||||
// The patch prefix must be already known here
|
||||
assert(ha->pPatchPrefix != NULL);
|
||||
pPrefix = ha->pPatchPrefix;
|
||||
|
||||
// The patch name for "OldWorld\\XXX\\YYY" is "Base\\XXX\YYY"
|
||||
// We need to remove the "OldWorld\\" prefix
|
||||
if(!_strnicmp(szFileName, "OldWorld\\", 9))
|
||||
szFileName += 9;
|
||||
|
||||
// Create the file name from the known patch entry
|
||||
memcpy(szBuffer, pPrefix->szPatchPrefix, pPrefix->nLength);
|
||||
strcpy(szBuffer + pPrefix->nLength, szFileName);
|
||||
szFileName = szBuffer;
|
||||
}
|
||||
|
||||
return szFileName;
|
||||
}
|
||||
|
||||
static bool OpenLocalFile(const char * szFileName, HANDLE * PtrFile)
|
||||
{
|
||||
TFileStream * pStream;
|
||||
TMPQFile * hf = NULL;
|
||||
TCHAR szFileNameT[MAX_PATH];
|
||||
|
||||
// Convert the file name to UNICODE (if needed)
|
||||
StringCopy(szFileNameT, _countof(szFileNameT), szFileName);
|
||||
|
||||
// Open the file and create the TMPQFile structure
|
||||
pStream = FileStream_OpenFile(szFileNameT, STREAM_FLAG_READ_ONLY);
|
||||
if(pStream != NULL)
|
||||
{
|
||||
// Allocate and initialize file handle
|
||||
hf = CreateFileHandle(NULL, NULL);
|
||||
if(hf != NULL)
|
||||
{
|
||||
hf->pStream = pStream;
|
||||
*PtrFile = hf;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileStream_Close(pStream);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
}
|
||||
*PtrFile = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile)
|
||||
{
|
||||
TMPQArchive * haBase = NULL;
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
TFileEntry * pFileEntry;
|
||||
TMPQFile * hfPatch; // Pointer to patch file
|
||||
TMPQFile * hfBase = NULL; // Pointer to base open file
|
||||
TMPQFile * hf = NULL;
|
||||
HANDLE hPatchFile;
|
||||
char szNameBuffer[MAX_PATH];
|
||||
|
||||
// First of all, find the latest archive where the file is in base version
|
||||
// (i.e. where the original, unpatched version of the file exists)
|
||||
while(ha != NULL)
|
||||
{
|
||||
// If the file is there, then we remember the archive
|
||||
pFileEntry = GetFileEntryExact(ha, GetPatchFileName(ha, szFileName, szNameBuffer), 0, NULL);
|
||||
if(pFileEntry != NULL && (pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
|
||||
haBase = ha;
|
||||
|
||||
// Move to the patch archive
|
||||
ha = ha->haPatch;
|
||||
}
|
||||
|
||||
// If we couldn't find the base file in any of the patches, it doesn't exist
|
||||
if((ha = haBase) != NULL)
|
||||
{
|
||||
// Now open the base file
|
||||
if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase))
|
||||
{
|
||||
// The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
|
||||
assert((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0);
|
||||
hf = hfBase;
|
||||
|
||||
// Now open all patches and attach them on top of the base file
|
||||
for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
|
||||
{
|
||||
// Prepare the file name with a correct prefix
|
||||
if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, &hPatchFile))
|
||||
{
|
||||
// Remember the new version
|
||||
hfPatch = (TMPQFile *)hPatchFile;
|
||||
|
||||
// We should not find patch file
|
||||
assert((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) != 0);
|
||||
|
||||
// Attach the patch to the base file
|
||||
hf->hfPatch = hfPatch;
|
||||
hf = hfPatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Give the updated base MPQ
|
||||
if(PtrFile != NULL)
|
||||
*PtrFile = (HANDLE)hfBase;
|
||||
return (hfBase != NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Public functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileEnumLocales enums all locale versions within MPQ.
|
||||
// Functions fills all available language identifiers on a file into the buffer
|
||||
// pointed by plcLocales. There must be enough entries to copy the localed,
|
||||
// otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
|
||||
|
||||
DWORD WINAPI SFileEnumLocales(
|
||||
HANDLE hMpq,
|
||||
const char * szFileName,
|
||||
LCID * PtrLocales,
|
||||
LPDWORD PtrMaxLocales,
|
||||
DWORD dwSearchScope)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
TMPQHash * pFirstHash;
|
||||
TMPQHash * pHash;
|
||||
DWORD dwFileIndex = 0;
|
||||
DWORD dwMaxLocales;
|
||||
DWORD dwLocales = 0;
|
||||
|
||||
// Test the parameters
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
if(szFileName == NULL || *szFileName == 0)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if(ha->pHashTable == NULL)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
if(PtrMaxLocales == NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if(IsPseudoFileName(szFileName, &dwFileIndex))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Keep compiler happy
|
||||
dwMaxLocales = PtrMaxLocales[0];
|
||||
dwSearchScope = dwSearchScope;
|
||||
|
||||
// Parse all files with that name
|
||||
pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
|
||||
while(pHash != NULL)
|
||||
{
|
||||
// Put the locales to the buffer
|
||||
if(PtrLocales != NULL && dwLocales < dwMaxLocales)
|
||||
*PtrLocales++ = pHash->lcLocale;
|
||||
dwLocales++;
|
||||
|
||||
// Get the next locale
|
||||
pHash = GetNextHashEntry(ha, pFirstHash, pHash);
|
||||
}
|
||||
|
||||
// Give the caller the number of locales and return
|
||||
PtrMaxLocales[0] = dwLocales;
|
||||
return (dwLocales <= dwMaxLocales) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileOpenFileEx
|
||||
//
|
||||
// hMpq - Handle of opened MPQ archive
|
||||
// szFileName - Name of file to open
|
||||
// dwSearchScope - Where to search
|
||||
// PtrFile - Pointer to store opened file handle
|
||||
|
||||
bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * PtrFile)
|
||||
{
|
||||
TMPQArchive * ha = IsValidMpqHandle(hMpq);
|
||||
TFileEntry * pFileEntry = NULL;
|
||||
TMPQFile * hf = NULL;
|
||||
DWORD dwHashIndex = HASH_ENTRY_FREE;
|
||||
DWORD dwFileIndex = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
bool bOpenByIndex = false;
|
||||
|
||||
// Don't accept NULL pointer to file handle
|
||||
if(szFileName == NULL || *szFileName == 0)
|
||||
dwErrCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// When opening a file from MPQ, the handle must be valid
|
||||
if(dwSearchScope != SFILE_OPEN_LOCAL_FILE && ha == NULL)
|
||||
dwErrCode = ERROR_INVALID_HANDLE;
|
||||
|
||||
// When not checking for existence, the pointer to file handle must be valid
|
||||
if(dwSearchScope != SFILE_OPEN_CHECK_EXISTS && PtrFile == NULL)
|
||||
dwErrCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Prepare the file opening
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
switch(dwSearchScope)
|
||||
{
|
||||
case SFILE_OPEN_FROM_MPQ:
|
||||
case SFILE_OPEN_BASE_FILE:
|
||||
case SFILE_OPEN_CHECK_EXISTS:
|
||||
|
||||
// If this MPQ has no patches, open the file from this MPQ directly
|
||||
if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE)
|
||||
{
|
||||
pFileEntry = GetFileEntryLocale2(ha, szFileName, g_lcFileLocale, &dwHashIndex);
|
||||
}
|
||||
|
||||
// If this MPQ is a patched archive, open the file as patched
|
||||
else
|
||||
{
|
||||
return OpenPatchedFile(hMpq, szFileName, PtrFile);
|
||||
}
|
||||
break;
|
||||
|
||||
case SFILE_OPEN_ANY_LOCALE:
|
||||
|
||||
// This open option is reserved for opening MPQ internal listfile.
|
||||
// No argument validation. Tries to open file with neutral locale first,
|
||||
// then any other available.
|
||||
pFileEntry = GetFileEntryLocale2(ha, szFileName, 0, &dwHashIndex);
|
||||
break;
|
||||
|
||||
case SFILE_OPEN_LOCAL_FILE:
|
||||
|
||||
// Open a local file
|
||||
return OpenLocalFile(szFileName, PtrFile);
|
||||
|
||||
default:
|
||||
|
||||
// Don't accept any other value
|
||||
dwErrCode = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the file really exists in the MPQ
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// If we didn't find the file, try to open it using pseudo file name ("File
|
||||
if (pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
|
||||
{
|
||||
// Check the pseudo-file name ("File00000001.ext")
|
||||
if ((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true)
|
||||
{
|
||||
// Get the file entry for the file
|
||||
if (dwFileIndex < ha->dwFileTableSize)
|
||||
{
|
||||
pFileEntry = ha->pFileTable + dwFileIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Still not found?
|
||||
if (pFileEntry == NULL)
|
||||
{
|
||||
dwErrCode = ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform some checks of invalid files
|
||||
if (pFileEntry != NULL)
|
||||
{
|
||||
// MPQ protectors use insanely amount of fake files, often with very high size.
|
||||
// We won't open any files whose compressed size is bigger than archive size
|
||||
// If the file is not compressed, its size cannot be bigger than archive size
|
||||
if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
|
||||
{
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
pFileEntry = NULL;
|
||||
}
|
||||
|
||||
// Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x)
|
||||
// if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
|
||||
// {
|
||||
// dwErrCode = ERROR_NOT_SUPPORTED;
|
||||
// pFileEntry = NULL;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Did the caller just wanted to know if the file exists?
|
||||
if(dwErrCode == ERROR_SUCCESS && dwSearchScope != SFILE_OPEN_CHECK_EXISTS)
|
||||
{
|
||||
// Allocate file handle
|
||||
hf = CreateFileHandle(ha, pFileEntry);
|
||||
if(hf != NULL)
|
||||
{
|
||||
// Get the hash index for the file
|
||||
if(ha->pHashTable != NULL && dwHashIndex == HASH_ENTRY_FREE)
|
||||
dwHashIndex = FindHashIndex(ha, dwFileIndex);
|
||||
if(dwHashIndex != HASH_ENTRY_FREE)
|
||||
hf->pHashEntry = ha->pHashTable + dwHashIndex;
|
||||
hf->dwHashIndex = dwHashIndex;
|
||||
|
||||
// If the MPQ has sector CRC enabled, enable if for the file
|
||||
if(ha->dwFlags & MPQ_FLAG_CHECK_SECTOR_CRC)
|
||||
hf->bCheckSectorCRCs = true;
|
||||
|
||||
// If we know the real file name, copy it to the file entry
|
||||
if(bOpenByIndex == false)
|
||||
{
|
||||
// If there is no file name yet, allocate it
|
||||
AllocateFileName(ha, pFileEntry, szFileName);
|
||||
|
||||
// If the file is encrypted, we should detect the file key
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
{
|
||||
hf->dwFileKey = DecryptFileKey(szFileName,
|
||||
pFileEntry->ByteOffset,
|
||||
pFileEntry->dwFileSize,
|
||||
pFileEntry->dwFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Give the file entry
|
||||
if(PtrFile != NULL)
|
||||
PtrFile[0] = hf;
|
||||
|
||||
// Return error code
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileHasFile
|
||||
//
|
||||
// hMpq - Handle of opened MPQ archive
|
||||
// szFileName - Name of file to look for
|
||||
|
||||
bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName)
|
||||
{
|
||||
return SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_CHECK_EXISTS, NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool WINAPI SFileCloseFile(HANDLE hFile);
|
||||
|
||||
bool WINAPI SFileCloseFile(HANDLE hFile)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
|
||||
if(!IsValidFileHandle(hFile))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Free the structure
|
||||
FreeFileHandle(hf);
|
||||
return true;
|
||||
}
|
1175
StormLib/src/SFilePatchArchives.cpp
Normal file
1175
StormLib/src/SFilePatchArchives.cpp
Normal file
File diff suppressed because it is too large
Load Diff
897
StormLib/src/SFileReadFile.cpp
Normal file
897
StormLib/src/SFileReadFile.cpp
Normal file
@ -0,0 +1,897 @@
|
||||
/*****************************************************************************/
|
||||
/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Description : */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */
|
||||
/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
// hf - MPQ File handle.
|
||||
// pbBuffer - Pointer to target buffer to store sectors.
|
||||
// dwByteOffset - Position of sector in the file (relative to file begin)
|
||||
// dwBytesToRead - Number of bytes to read. Must be multiplier of sector size.
|
||||
// pdwBytesRead - Stored number of bytes loaded
|
||||
static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
ULONGLONG RawFilePos;
|
||||
TMPQArchive * ha = hf->ha;
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
LPBYTE pbRawSector = NULL;
|
||||
LPBYTE pbOutSector = pbBuffer;
|
||||
LPBYTE pbInSector = pbBuffer;
|
||||
DWORD dwRawBytesToRead;
|
||||
DWORD dwRawSectorOffset = dwByteOffset;
|
||||
DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize;
|
||||
DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize;
|
||||
DWORD dwSectorsDone = 0;
|
||||
DWORD dwBytesRead = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Note that dwByteOffset must be aligned to size of one sector
|
||||
// Note that dwBytesToRead must be a multiplier of one sector size
|
||||
// This is local function, so we won't check if that's true.
|
||||
// Note that files stored in single units are processed by a separate function
|
||||
|
||||
// If there is not enough bytes remaining, cut dwBytesToRead
|
||||
if((dwByteOffset + dwBytesToRead) > hf->dwDataSize)
|
||||
dwBytesToRead = hf->dwDataSize - dwByteOffset;
|
||||
dwRawBytesToRead = dwBytesToRead;
|
||||
|
||||
// Perform all necessary work to do with compressed files
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
// If the sector positions are not loaded yet, do it
|
||||
if(hf->SectorOffsets == NULL)
|
||||
{
|
||||
dwErrCode = AllocateSectorOffsets(hf, true);
|
||||
if(dwErrCode != ERROR_SUCCESS || hf->SectorOffsets == NULL)
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
// If the sector checksums are not loaded yet, load them now.
|
||||
if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false)
|
||||
{
|
||||
//
|
||||
// Sector CRCs is plain crap feature. It is almost never present,
|
||||
// often it's empty, or the end offset of sector CRCs is zero.
|
||||
// We only try to load sector CRCs once, and regardless if it fails
|
||||
// or not, we won't try that again for the given file.
|
||||
//
|
||||
|
||||
AllocateSectorChecksums(hf, true);
|
||||
hf->bLoadedSectorCRCs = true;
|
||||
}
|
||||
|
||||
// TODO: If the raw data MD5s are not loaded yet, load them now
|
||||
// Only do it if the MPQ is of format 4.0
|
||||
// if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0)
|
||||
// {
|
||||
// dwErrCode = AllocateRawMD5s(hf, true);
|
||||
// if(dwErrCode != ERROR_SUCCESS)
|
||||
// return dwErrCode;
|
||||
// }
|
||||
|
||||
// Assign the temporary buffer as target for read operation
|
||||
dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];
|
||||
dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset;
|
||||
|
||||
// If the file is compressed, also allocate secondary buffer
|
||||
pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead);
|
||||
if(pbRawSector == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Calculate raw file offset where the sector(s) are stored.
|
||||
RawFilePos = CalculateRawSectorOffset(hf, dwRawSectorOffset);
|
||||
|
||||
// Set file pointer and read all required sectors
|
||||
if(FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead))
|
||||
{
|
||||
// Now we have to decrypt and decompress all file sectors that have been loaded
|
||||
for(DWORD i = 0; i < dwSectorsToRead; i++)
|
||||
{
|
||||
DWORD dwRawBytesInThisSector = ha->dwSectorSize;
|
||||
DWORD dwBytesInThisSector = ha->dwSectorSize;
|
||||
DWORD dwIndex = dwSectorIndex + i;
|
||||
|
||||
// If there is not enough bytes in the last sector,
|
||||
// cut the number of bytes in this sector
|
||||
if(dwRawBytesInThisSector > dwBytesToRead)
|
||||
dwRawBytesInThisSector = dwBytesToRead;
|
||||
if(dwBytesInThisSector > dwBytesToRead)
|
||||
dwBytesInThisSector = dwBytesToRead;
|
||||
|
||||
// If the file is compressed, we have to adjust the raw sector size
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex];
|
||||
|
||||
// If the file is encrypted, we have to decrypt the sector
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
{
|
||||
BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);
|
||||
|
||||
// If we don't know the key, try to detect it by file content
|
||||
if(hf->dwFileKey == 0)
|
||||
{
|
||||
hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector, hf->dwDataSize);
|
||||
if(hf->dwFileKey == 0)
|
||||
{
|
||||
dwErrCode = ERROR_UNKNOWN_FILE_KEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex);
|
||||
BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);
|
||||
}
|
||||
|
||||
// If the file has sector CRC check turned on, perform it
|
||||
if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL)
|
||||
{
|
||||
DWORD dwAdlerExpected = hf->SectorChksums[dwIndex];
|
||||
DWORD dwAdlerValue = 0;
|
||||
|
||||
// We can only check sector CRC when it's not zero
|
||||
// Neither can we check it if it's 0xFFFFFFFF.
|
||||
if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF)
|
||||
{
|
||||
dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector);
|
||||
if(dwAdlerValue != dwAdlerExpected)
|
||||
{
|
||||
dwErrCode = ERROR_CHECKSUM_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the sector is really compressed, decompress it.
|
||||
// WARNING : Some sectors may not be compressed, it can be determined only
|
||||
// by comparing uncompressed and compressed size !!!
|
||||
if(dwRawBytesInThisSector < dwBytesInThisSector)
|
||||
{
|
||||
int cbOutSector = dwBytesInThisSector;
|
||||
int cbInSector = dwRawBytesInThisSector;
|
||||
int nResult = 0;
|
||||
|
||||
// Is the file compressed by Blizzard's multiple compression ?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
|
||||
{
|
||||
// Remember the last used compression
|
||||
hf->dwCompression0 = pbInSector[0];
|
||||
|
||||
// Decompress the data
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
|
||||
nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
else
|
||||
nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
}
|
||||
|
||||
// Is the file compressed by PKWARE Data Compression Library ?
|
||||
else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
|
||||
{
|
||||
nResult = SCompExplode(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
}
|
||||
|
||||
// Did the decompression fail ?
|
||||
if(nResult == 0)
|
||||
{
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pbOutSector != pbInSector)
|
||||
memcpy(pbOutSector, pbInSector, dwBytesInThisSector);
|
||||
}
|
||||
|
||||
// Move pointers
|
||||
dwBytesToRead -= dwBytesInThisSector;
|
||||
dwByteOffset += dwBytesInThisSector;
|
||||
dwBytesRead += dwBytesInThisSector;
|
||||
pbOutSector += dwBytesInThisSector;
|
||||
pbInSector += dwRawBytesInThisSector;
|
||||
dwSectorsDone++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
}
|
||||
|
||||
// Free all used buffers
|
||||
if(pbRawSector != NULL)
|
||||
STORM_FREE(pbRawSector);
|
||||
|
||||
// Give the caller thenumber of bytes read
|
||||
*pdwBytesRead = dwBytesRead;
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
ULONGLONG RawFilePos = hf->RawFilePos;
|
||||
TMPQArchive * ha = hf->ha;
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
LPBYTE pbCompressed = NULL;
|
||||
LPBYTE pbRawData;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// If the file buffer is not allocated yet, do it.
|
||||
if(hf->pbFileSector == NULL)
|
||||
{
|
||||
dwErrCode = AllocateSectorBuffer(hf);
|
||||
if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL)
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
// If the file is a patch file, adjust raw data offset
|
||||
if(hf->pPatchInfo != NULL)
|
||||
RawFilePos += hf->pPatchInfo->dwLength;
|
||||
pbRawData = hf->pbFileSector;
|
||||
|
||||
// If the file sector is not loaded yet, do it
|
||||
if(hf->dwSectorOffs != 0)
|
||||
{
|
||||
// Is the file compressed?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
// Allocate space for compressed data
|
||||
pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize);
|
||||
if(pbCompressed == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
pbRawData = pbCompressed;
|
||||
}
|
||||
|
||||
// Load the raw (compressed, encrypted) data
|
||||
if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize))
|
||||
{
|
||||
STORM_FREE(pbCompressed);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
// If the file is encrypted, we have to decrypt the data first
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
{
|
||||
BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize);
|
||||
DecryptMpqBlock(pbRawData, pFileEntry->dwCmpSize, hf->dwFileKey);
|
||||
BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize);
|
||||
}
|
||||
|
||||
// If the file is compressed, we have to decompress it now
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
int cbOutBuffer = (int)hf->dwDataSize;
|
||||
int cbInBuffer = (int)pFileEntry->dwCmpSize;
|
||||
int nResult = 0;
|
||||
|
||||
//
|
||||
// If the file is an incremental patch, the size of compressed data
|
||||
// is determined as pFileEntry->dwCmpSize - sizeof(TPatchInfo)
|
||||
//
|
||||
// In "wow-update-12694.MPQ" from Wow-Cataclysm BETA:
|
||||
//
|
||||
// File CmprSize DcmpSize DataSize Compressed?
|
||||
// -------------------------------------- ---------- -------- -------- ---------------
|
||||
// esES\DBFilesClient\LightSkyBox.dbc 0xBE->0xA2 0xBC 0xBC Yes
|
||||
// deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No
|
||||
//
|
||||
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
|
||||
cbInBuffer = cbInBuffer - sizeof(TPatchInfo);
|
||||
|
||||
// Is the file compressed by Blizzard's multiple compression ?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
|
||||
{
|
||||
// Remember the last used compression
|
||||
hf->dwCompression0 = pbRawData[0];
|
||||
|
||||
// Decompress the file
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
|
||||
nResult = SCompDecompress2(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer);
|
||||
else
|
||||
nResult = SCompDecompress(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer);
|
||||
}
|
||||
|
||||
// Is the file compressed by PKWARE Data Compression Library ?
|
||||
// Note: Single unit files compressed with IMPLODE are not supported by Blizzard
|
||||
else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
|
||||
nResult = SCompExplode(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer);
|
||||
|
||||
dwErrCode = (nResult != 0) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hf->pbFileSector != NULL && pbRawData != hf->pbFileSector)
|
||||
memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize);
|
||||
}
|
||||
|
||||
// Free the decompression buffer.
|
||||
if(pbCompressed != NULL)
|
||||
STORM_FREE(pbCompressed);
|
||||
|
||||
// The file sector is now properly loaded
|
||||
hf->dwSectorOffs = 0;
|
||||
}
|
||||
|
||||
// At this moment, we have the file loaded into the file buffer.
|
||||
// Copy as much as the caller wants
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->dwSectorOffs == 0)
|
||||
{
|
||||
// File position is greater or equal to file size ?
|
||||
if(dwFilePos >= hf->dwDataSize)
|
||||
{
|
||||
*pdwBytesRead = 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If not enough bytes remaining in the file, cut them
|
||||
if((hf->dwDataSize - dwFilePos) < dwToRead)
|
||||
dwToRead = (hf->dwDataSize - dwFilePos);
|
||||
|
||||
// Copy the bytes
|
||||
memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead);
|
||||
|
||||
// Give the number of bytes read
|
||||
*pdwBytesRead = dwToRead;
|
||||
}
|
||||
|
||||
// An error, sorry
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
ULONGLONG RawFilePos = hf->RawFilePos + 0x0C; // For some reason, MPK files start at position (hf->RawFilePos + 0x0C)
|
||||
TMPQArchive * ha = hf->ha;
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
LPBYTE pbCompressed = NULL;
|
||||
LPBYTE pbRawData = hf->pbFileSector;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// We do not support patch files in MPK archives
|
||||
assert(hf->pPatchInfo == NULL);
|
||||
|
||||
// If the file buffer is not allocated yet, do it.
|
||||
if(hf->pbFileSector == NULL)
|
||||
{
|
||||
dwErrCode = AllocateSectorBuffer(hf);
|
||||
if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL)
|
||||
return dwErrCode;
|
||||
pbRawData = hf->pbFileSector;
|
||||
}
|
||||
|
||||
// If the file sector is not loaded yet, do it
|
||||
if(hf->dwSectorOffs != 0)
|
||||
{
|
||||
// Is the file compressed?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
// Allocate space for compressed data
|
||||
pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize);
|
||||
if(pbCompressed == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
pbRawData = pbCompressed;
|
||||
}
|
||||
|
||||
// Load the raw (compressed, encrypted) data
|
||||
if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize))
|
||||
{
|
||||
STORM_FREE(pbCompressed);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
// If the file is encrypted, we have to decrypt the data first
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
{
|
||||
DecryptMpkTable(pbRawData, pFileEntry->dwCmpSize);
|
||||
}
|
||||
|
||||
// If the file is compressed, we have to decompress it now
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
int cbOutBuffer = (int)hf->dwDataSize;
|
||||
|
||||
hf->dwCompression0 = pbRawData[0];
|
||||
if(!SCompDecompressMpk(hf->pbFileSector, &cbOutBuffer, pbRawData, (int)pFileEntry->dwCmpSize))
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pbRawData != hf->pbFileSector)
|
||||
memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize);
|
||||
}
|
||||
|
||||
// Free the decompression buffer.
|
||||
if(pbCompressed != NULL)
|
||||
STORM_FREE(pbCompressed);
|
||||
|
||||
// The file sector is now properly loaded
|
||||
hf->dwSectorOffs = 0;
|
||||
}
|
||||
|
||||
// At this moment, we have the file loaded into the file buffer.
|
||||
// Copy as much as the caller wants
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->dwSectorOffs == 0)
|
||||
{
|
||||
// File position is greater or equal to file size ?
|
||||
if(dwFilePos >= hf->dwDataSize)
|
||||
{
|
||||
*pdwBytesRead = 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If not enough bytes remaining in the file, cut them
|
||||
if((hf->dwDataSize - dwFilePos) < dwToRead)
|
||||
dwToRead = (hf->dwDataSize - dwFilePos);
|
||||
|
||||
// Copy the bytes
|
||||
memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead);
|
||||
|
||||
// Give the number of bytes read
|
||||
*pdwBytesRead = dwToRead;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// An error, sorry
|
||||
return ERROR_CAN_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
|
||||
static DWORD ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
TMPQArchive * ha = hf->ha;
|
||||
LPBYTE pbBuffer = (BYTE *)pvBuffer;
|
||||
DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts
|
||||
DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF
|
||||
DWORD dwFileSectorPos; // File offset of the loaded sector
|
||||
DWORD dwBytesRead; // Number of bytes read (temporary variable)
|
||||
DWORD dwErrCode;
|
||||
|
||||
// If the file position is at or beyond end of file, do nothing
|
||||
if(dwFilePos >= hf->dwDataSize)
|
||||
{
|
||||
*pdwBytesRead = 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If not enough bytes in the file remaining, cut them
|
||||
if(dwBytesToRead > (hf->dwDataSize - dwFilePos))
|
||||
dwBytesToRead = (hf->dwDataSize - dwFilePos);
|
||||
|
||||
// Compute sector position in the file
|
||||
dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block
|
||||
|
||||
// If the file sector buffer is not allocated yet, do it now
|
||||
if(hf->pbFileSector == NULL)
|
||||
{
|
||||
dwErrCode = AllocateSectorBuffer(hf);
|
||||
if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL)
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
// Load the first (incomplete) file sector
|
||||
if(dwFilePos & dwSectorSizeMask)
|
||||
{
|
||||
DWORD dwBytesInSector = ha->dwSectorSize;
|
||||
DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask;
|
||||
DWORD dwToCopy;
|
||||
|
||||
// Is the file sector already loaded ?
|
||||
if(hf->dwSectorOffs != dwFileSectorPos)
|
||||
{
|
||||
// Load one MPQ sector into archive buffer
|
||||
dwErrCode = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
return dwErrCode;
|
||||
|
||||
// Remember that the data loaded to the sector have new file offset
|
||||
hf->dwSectorOffs = dwFileSectorPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize)
|
||||
dwBytesInSector = hf->dwDataSize - dwFileSectorPos;
|
||||
}
|
||||
|
||||
// Copy the data from the offset in the loaded sector to the end of the sector
|
||||
dwToCopy = dwBytesInSector - dwBufferOffs;
|
||||
if(dwToCopy > dwBytesToRead)
|
||||
dwToCopy = dwBytesToRead;
|
||||
|
||||
// Copy data from sector buffer into target buffer
|
||||
memcpy(pbBuffer, hf->pbFileSector + dwBufferOffs, dwToCopy);
|
||||
|
||||
// Update pointers and byte counts
|
||||
dwTotalBytesRead += dwToCopy;
|
||||
dwFileSectorPos += dwBytesInSector;
|
||||
pbBuffer += dwToCopy;
|
||||
dwBytesToRead -= dwToCopy;
|
||||
}
|
||||
|
||||
// Load the whole ("middle") sectors only if there is at least one full sector to be read
|
||||
if(dwBytesToRead >= ha->dwSectorSize)
|
||||
{
|
||||
DWORD dwBlockBytes = dwBytesToRead & ~dwSectorSizeMask;
|
||||
|
||||
// Load all sectors to the output buffer
|
||||
dwErrCode = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
return dwErrCode;
|
||||
|
||||
// Update pointers
|
||||
dwTotalBytesRead += dwBytesRead;
|
||||
dwFileSectorPos += dwBytesRead;
|
||||
pbBuffer += dwBytesRead;
|
||||
dwBytesToRead -= dwBytesRead;
|
||||
}
|
||||
|
||||
// Read the terminating sector
|
||||
if(dwBytesToRead > 0)
|
||||
{
|
||||
DWORD dwToCopy = ha->dwSectorSize;
|
||||
|
||||
// Is the file sector already loaded ?
|
||||
if(hf->dwSectorOffs != dwFileSectorPos)
|
||||
{
|
||||
// Load one MPQ sector into archive buffer
|
||||
dwErrCode = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
return dwErrCode;
|
||||
|
||||
// Remember that the data loaded to the sector have new file offset
|
||||
hf->dwSectorOffs = dwFileSectorPos;
|
||||
}
|
||||
|
||||
// Check number of bytes read
|
||||
if(dwToCopy > dwBytesToRead)
|
||||
dwToCopy = dwBytesToRead;
|
||||
|
||||
// Copy the data from the cached last sector to the caller's buffer
|
||||
memcpy(pbBuffer, hf->pbFileSector, dwToCopy);
|
||||
|
||||
// Update pointers
|
||||
dwTotalBytesRead += dwToCopy;
|
||||
}
|
||||
|
||||
// Store total number of bytes read to the caller
|
||||
*pdwBytesRead = dwTotalBytesRead;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static DWORD ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
TMPQPatcher Patcher;
|
||||
DWORD dwBytesToRead = dwToRead;
|
||||
DWORD dwBytesRead = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Make sure that the patch file is loaded completely
|
||||
if(dwErrCode == ERROR_SUCCESS && hf->pbFileData == NULL)
|
||||
{
|
||||
// Initialize patching process and allocate data
|
||||
dwErrCode = Patch_InitPatcher(&Patcher, hf);
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
return dwErrCode;
|
||||
|
||||
// Set the current data size
|
||||
Patcher.cbFileData = hf->pFileEntry->dwFileSize;
|
||||
|
||||
// Initialize the patcher object with initial file data
|
||||
if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
|
||||
dwErrCode = ReadMpqFileSingleUnit(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead);
|
||||
else
|
||||
dwErrCode = ReadMpqFileSectorFile(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead);
|
||||
|
||||
// Perform the patching process
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
dwErrCode = Patch_Process(&Patcher, hf);
|
||||
|
||||
// Finalize the patcher structure
|
||||
Patch_Finalize(&Patcher);
|
||||
dwBytesRead = 0;
|
||||
}
|
||||
|
||||
// If there is something to read, do it
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if(dwFilePos < hf->cbFileData)
|
||||
{
|
||||
// Make sure we don't copy more than file size
|
||||
if((dwFilePos + dwToRead) > hf->cbFileData)
|
||||
dwToRead = hf->cbFileData - dwFilePos;
|
||||
|
||||
// Copy the appropriate amount of the file data to the caller's buffer
|
||||
memcpy(pvBuffer, hf->pbFileData + dwFilePos, dwToRead);
|
||||
dwBytesRead = dwToRead;
|
||||
}
|
||||
|
||||
// Set the proper error code
|
||||
dwErrCode = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF;
|
||||
}
|
||||
|
||||
// Give the result to the caller
|
||||
if(pdwBytesRead != NULL)
|
||||
*pdwBytesRead = dwBytesRead;
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
static DWORD ReadMpqFileLocalFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
|
||||
{
|
||||
ULONGLONG FilePosition1 = dwFilePos;
|
||||
ULONGLONG FilePosition2;
|
||||
DWORD dwBytesRead = 0;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
assert(hf->pStream != NULL);
|
||||
|
||||
// Because stream I/O functions are designed to read
|
||||
// "all or nothing", we compare file position before and after,
|
||||
// and if they differ, we assume that number of bytes read
|
||||
// is the difference between them
|
||||
|
||||
if(!FileStream_Read(hf->pStream, &FilePosition1, pvBuffer, dwToRead))
|
||||
{
|
||||
// If not all bytes have been read, then return the number of bytes read
|
||||
if((dwErrCode = GetLastError()) == ERROR_HANDLE_EOF)
|
||||
{
|
||||
FileStream_GetPos(hf->pStream, &FilePosition2);
|
||||
dwBytesRead = (DWORD)(FilePosition2 - FilePosition1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dwBytesRead = dwToRead;
|
||||
}
|
||||
|
||||
*pdwBytesRead = dwBytesRead;
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileReadFile
|
||||
|
||||
bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
DWORD dwBytesRead = 0; // Number of bytes read
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Always zero the result
|
||||
if(pdwRead != NULL)
|
||||
*pdwRead = 0;
|
||||
lpOverlapped = lpOverlapped;
|
||||
|
||||
// Check valid parameters
|
||||
if(!IsValidFileHandle(hFile))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pvBuffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we didn't load the patch info yet, do it now
|
||||
if(hf->pFileEntry != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) && hf->pPatchInfo == NULL)
|
||||
{
|
||||
dwErrCode = AllocatePatchInfo(hf, true);
|
||||
if(dwErrCode != ERROR_SUCCESS || hf->pPatchInfo == NULL)
|
||||
{
|
||||
SetLastError(dwErrCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the last used compression
|
||||
hf->dwCompression0 = 0;
|
||||
|
||||
// If the file is local file, read the data directly from the stream
|
||||
if(hf->pStream != NULL)
|
||||
{
|
||||
dwErrCode = ReadMpqFileLocalFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
|
||||
}
|
||||
|
||||
// If the file is a patch file, we have to read it special way
|
||||
else if(hf->hfPatch != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
|
||||
{
|
||||
dwErrCode = ReadMpqFilePatchFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
|
||||
}
|
||||
|
||||
// If the archive is a MPK archive, we need special way to read the file
|
||||
else if(hf->ha->dwSubType == MPQ_SUBTYPE_MPK)
|
||||
{
|
||||
dwErrCode = ReadMpkFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
|
||||
}
|
||||
|
||||
// If the file is single unit file, redirect it to read file
|
||||
else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
|
||||
{
|
||||
dwErrCode = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
|
||||
}
|
||||
|
||||
// Otherwise read it as sector based MPQ file
|
||||
else
|
||||
{
|
||||
dwErrCode = ReadMpqFileSectorFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
|
||||
}
|
||||
|
||||
// Increment the file position
|
||||
hf->dwFilePos += dwBytesRead;
|
||||
|
||||
// Give the caller the number of bytes read
|
||||
if(pdwRead != NULL)
|
||||
*pdwRead = dwBytesRead;
|
||||
|
||||
// If the read operation succeeded, but not full number of bytes was read,
|
||||
// set the last error to ERROR_HANDLE_EOF
|
||||
if(dwErrCode == ERROR_SUCCESS && (dwBytesRead < dwToRead))
|
||||
dwErrCode = ERROR_HANDLE_EOF;
|
||||
|
||||
// If something failed, set the last error value
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetLastError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileGetFileSize
|
||||
|
||||
DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh)
|
||||
{
|
||||
ULONGLONG FileSize;
|
||||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
|
||||
// Validate the file handle before we go on
|
||||
if(IsValidFileHandle(hFile))
|
||||
{
|
||||
// Make sure that the variable is initialized
|
||||
FileSize = 0;
|
||||
|
||||
// If the file is patched file, we have to get the size of the last version
|
||||
if(hf->hfPatch != NULL)
|
||||
{
|
||||
// Walk through the entire patch chain, take the last version
|
||||
while(hf != NULL)
|
||||
{
|
||||
// Get the size of the currently pointed version
|
||||
FileSize = hf->pFileEntry->dwFileSize;
|
||||
|
||||
// Move to the next patch file in the hierarchy
|
||||
hf = hf->hfPatch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is it a local file ?
|
||||
if(hf->pStream != NULL)
|
||||
{
|
||||
FileStream_GetSize(hf->pStream, &FileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSize = hf->dwDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
// If opened from archive, return file size
|
||||
if(pdwFileSizeHigh != NULL)
|
||||
*pdwFileSizeHigh = (DWORD)(FileSize >> 32);
|
||||
return (DWORD)FileSize;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return SFILE_INVALID_SIZE;
|
||||
}
|
||||
|
||||
DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
ULONGLONG OldPosition;
|
||||
ULONGLONG NewPosition;
|
||||
ULONGLONG FileSize;
|
||||
ULONGLONG DeltaPos;
|
||||
|
||||
// If the hFile is not a valid file handle, return an error.
|
||||
if(!IsValidFileHandle(hFile))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return SFILE_INVALID_POS;
|
||||
}
|
||||
|
||||
// Retrieve the file size for handling the limits
|
||||
if(hf->pStream != NULL)
|
||||
{
|
||||
FileStream_GetSize(hf->pStream, &FileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSize = SFileGetFileSize(hFile, NULL);
|
||||
}
|
||||
|
||||
// Handle the NULL and non-NULL values of plFilePosHigh
|
||||
// Non-NULL: The DeltaPos is combined from lFilePos and *lpFilePosHigh
|
||||
// NULL: The DeltaPos is sign-extended value of lFilePos
|
||||
DeltaPos = (plFilePosHigh != NULL) ? MAKE_OFFSET64(plFilePosHigh[0], lFilePos) : (ULONGLONG)(LONGLONG)lFilePos;
|
||||
|
||||
// Get the relative point where to move from
|
||||
switch(dwMoveMethod)
|
||||
{
|
||||
case FILE_BEGIN:
|
||||
|
||||
// Move relative to the file begin.
|
||||
OldPosition = 0;
|
||||
break;
|
||||
|
||||
case FILE_CURRENT:
|
||||
|
||||
// Retrieve the current file position
|
||||
if(hf->pStream != NULL)
|
||||
{
|
||||
FileStream_GetPos(hf->pStream, &OldPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
OldPosition = hf->dwFilePos;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILE_END:
|
||||
|
||||
// Move relative to the end of the file
|
||||
OldPosition = FileSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return SFILE_INVALID_POS;
|
||||
}
|
||||
|
||||
// Calculate the new position
|
||||
NewPosition = OldPosition + DeltaPos;
|
||||
|
||||
// If moving backward, don't allow the new position go negative
|
||||
if((LONGLONG)DeltaPos < 0)
|
||||
{
|
||||
if(NewPosition > FileSize) // Position is negative
|
||||
{
|
||||
SetLastError(ERROR_NEGATIVE_SEEK);
|
||||
return SFILE_INVALID_POS;
|
||||
}
|
||||
}
|
||||
|
||||
// If moving forward, don't allow the new position go past the end of the file
|
||||
else
|
||||
{
|
||||
if(NewPosition > FileSize)
|
||||
NewPosition = FileSize;
|
||||
}
|
||||
|
||||
// Now apply the file pointer to the file
|
||||
if(hf->pStream != NULL)
|
||||
{
|
||||
if(!FileStream_Read(hf->pStream, &NewPosition, NULL, 0))
|
||||
return SFILE_INVALID_POS;
|
||||
}
|
||||
|
||||
// Also, store the new file position to the TMPQFile struct
|
||||
hf->dwFilePos = (DWORD)NewPosition;
|
||||
|
||||
// Return the new file position
|
||||
if(plFilePosHigh != NULL)
|
||||
*plFilePosHigh = (LONG)(NewPosition >> 32);
|
||||
return (DWORD)NewPosition;
|
||||
}
|
1054
StormLib/src/SFileVerify.cpp
Normal file
1054
StormLib/src/SFileVerify.cpp
Normal file
File diff suppressed because it is too large
Load Diff
441
StormLib/src/StormCommon.h
Normal file
441
StormLib/src/StormCommon.h
Normal file
@ -0,0 +1,441 @@
|
||||
/*****************************************************************************/
|
||||
/* SCommon.h Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Common functions for encryption/decryption from Storm.dll. Included by */
|
||||
/* SFile*** functions, do not include and do not use this file directly */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 24.03.03 1.00 Lad The first version of SFileCommon.h */
|
||||
/* 12.06.04 1.00 Lad Renamed to SCommon.h */
|
||||
/* 06.09.10 1.00 Lad Renamed to StormCommon.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __STORMCOMMON_H__
|
||||
#define __STORMCOMMON_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compression support
|
||||
|
||||
// Include functions from Pkware Data Compression Library
|
||||
#include "pklib/pklib.h"
|
||||
|
||||
// Include functions from Huffmann compression
|
||||
#include "huffman/huff.h"
|
||||
|
||||
// Include functions from IMA ADPCM compression
|
||||
#include "adpcm/adpcm.h"
|
||||
|
||||
// Include functions from SPARSE compression
|
||||
#include "sparse/sparse.h"
|
||||
|
||||
// Include functions from LZMA compression
|
||||
#include "lzma/C/LzmaEnc.h"
|
||||
#include "lzma/C/LzmaDec.h"
|
||||
|
||||
// Include functions from zlib
|
||||
#ifndef __SYS_ZLIB
|
||||
#include "zlib/zlib.h"
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
// Include functions from bzlib
|
||||
#ifndef __SYS_BZLIB
|
||||
#include "bzip2/bzlib.h"
|
||||
#else
|
||||
#include <bzlib.h>
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cryptography support
|
||||
|
||||
// Headers from LibTomCrypt
|
||||
#include "libtomcrypt/src/headers/tomcrypt.h"
|
||||
|
||||
// For HashStringJenkins
|
||||
#include "jenkins/lookup.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StormLib private defines
|
||||
|
||||
#define ID_MPQ_FILE 0x46494c45 // Used internally for checking TMPQFile ('FILE')
|
||||
|
||||
// Prevent problems with CRT "min" and "max" functions,
|
||||
// as they are not defined on all platforms
|
||||
#define STORMLIB_MIN(a, b) ((a < b) ? a : b)
|
||||
#define STORMLIB_MAX(a, b) ((a > b) ? a : b)
|
||||
#define STORMLIB_UNUSED(p) ((void)(p))
|
||||
|
||||
// Checks for data pointers aligned to 4-byte boundary
|
||||
#define STORMLIB_DWORD_ALIGNED(ptr) (((size_t)(ptr) & 0x03) == 0)
|
||||
|
||||
// Macro for building 64-bit file offset from two 32-bit
|
||||
#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MTYPE definition - specifies what kind of MPQ is the map type
|
||||
|
||||
typedef enum _MTYPE
|
||||
{
|
||||
MapTypeNotChecked, // The map type was not checked yet
|
||||
MapTypeNotRecognized, // The file does not seems to be a map
|
||||
MapTypeAviFile, // The file is actually an AVI file (Warcraft III cinematics)
|
||||
MapTypeWarcraft3, // The file is a Warcraft III map
|
||||
MapTypeStarcraft2 // The file is a Starcraft II map
|
||||
} MTYPE, *PMTYPE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MPQ signature information
|
||||
|
||||
// Size of each signature type
|
||||
#define MPQ_WEAK_SIGNATURE_SIZE 64
|
||||
#define MPQ_STRONG_SIGNATURE_SIZE 256
|
||||
#define MPQ_STRONG_SIGNATURE_ID 0x5349474E // ID of the strong signature ("NGIS")
|
||||
#define MPQ_SIGNATURE_FILE_SIZE (MPQ_WEAK_SIGNATURE_SIZE + 8)
|
||||
|
||||
// MPQ signature info
|
||||
typedef struct _MPQ_SIGNATURE_INFO
|
||||
{
|
||||
ULONGLONG BeginMpqData; // File offset where the hashing starts
|
||||
ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file)
|
||||
ULONGLONG EndExclude; // End of the excluded area (used for (signature) file)
|
||||
ULONGLONG EndMpqData; // File offset where the hashing ends
|
||||
ULONGLONG EndOfFile; // Size of the entire file
|
||||
BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10];
|
||||
DWORD cbSignatureSize; // Length of the signature
|
||||
DWORD SignatureTypes; // See SIGNATURE_TYPE_XXX
|
||||
|
||||
} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
// - Memory freeing function doesn't have to test the pointer to NULL
|
||||
//
|
||||
|
||||
//#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
//
|
||||
//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type)))
|
||||
//#define STORM_REALLOC(type, ptr, nitems) (type *)HeapReAlloc(GetProcessHeap(), 0, ptr, ((nitems) * sizeof(type)))
|
||||
//#define STORM_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr)
|
||||
//
|
||||
//#else
|
||||
|
||||
#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type))
|
||||
#define STORM_REALLOC(type, ptr, nitems) (type *)realloc(ptr, ((nitems) * sizeof(type)))
|
||||
#define STORM_FREE(ptr) free(ptr)
|
||||
|
||||
//#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StormLib internal global variables
|
||||
|
||||
extern DWORD g_dwMpqSignature; // Marker for MPQ header
|
||||
extern DWORD g_dwHashTableKey; // Key for hash table
|
||||
extern DWORD g_dwBlockTableKey; // Key for block table
|
||||
extern LCID g_lcFileLocale; // Preferred file locale
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Conversion to uppercase/lowercase (and "/" to "\")
|
||||
|
||||
extern unsigned char AsciiToLowerTable[256];
|
||||
extern unsigned char AsciiToUpperTable[256];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Safe string functions
|
||||
|
||||
template <typename XCHAR, typename XINT>
|
||||
XCHAR * IntToString(XCHAR * szBuffer, size_t cchMaxChars, XINT nValue, size_t nDigitCount = 0)
|
||||
{
|
||||
XCHAR * szBufferEnd = szBuffer + cchMaxChars - 1;
|
||||
XCHAR szNumberRev[0x20];
|
||||
size_t nLength = 0;
|
||||
|
||||
// Always put the first digit
|
||||
szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0';
|
||||
nValue /= 10;
|
||||
|
||||
// Continue as long as we have non-zero
|
||||
while(nValue != 0)
|
||||
{
|
||||
szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0';
|
||||
nValue /= 10;
|
||||
}
|
||||
|
||||
// Fill zeros, if needed
|
||||
while(szBuffer < szBufferEnd && nLength < nDigitCount)
|
||||
{
|
||||
*szBuffer++ = '0';
|
||||
nDigitCount--;
|
||||
}
|
||||
|
||||
// Fill the buffer
|
||||
while(szBuffer < szBufferEnd && nLength > 0)
|
||||
{
|
||||
nLength--;
|
||||
*szBuffer++ = szNumberRev[nLength];
|
||||
}
|
||||
|
||||
// Terminate the number with zeros
|
||||
szBuffer[0] = 0;
|
||||
return szBuffer;
|
||||
}
|
||||
|
||||
char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource);
|
||||
void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource);
|
||||
void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension);
|
||||
|
||||
#ifdef _UNICODE
|
||||
void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource);
|
||||
void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource);
|
||||
void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource);
|
||||
void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource);
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Encryption and decryption functions
|
||||
|
||||
#define MPQ_HASH_TABLE_INDEX 0x000
|
||||
#define MPQ_HASH_NAME_A 0x100
|
||||
#define MPQ_HASH_NAME_B 0x200
|
||||
#define MPQ_HASH_FILE_KEY 0x300
|
||||
#define MPQ_HASH_KEY2_MIX 0x400
|
||||
|
||||
DWORD HashString(const char * szFileName, DWORD dwHashType);
|
||||
DWORD HashStringSlash(const char* szFileName, DWORD dwHashType);
|
||||
DWORD HashStringSlash2(const char * szFileName, DWORD dwHashType);
|
||||
DWORD HashStringLower(const char * szFileName, DWORD dwHashType);
|
||||
|
||||
void InitializeMpqCryptography();
|
||||
|
||||
DWORD GetNearestPowerOfTwo(DWORD dwFileCount);
|
||||
|
||||
bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex);
|
||||
ULONGLONG HashStringJenkins(const char * szFileName);
|
||||
|
||||
DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion);
|
||||
|
||||
void EncryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey);
|
||||
void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey);
|
||||
|
||||
DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwSectorOffsLen);
|
||||
DWORD DetectFileKeyByContent(void * pvEncryptedData, DWORD dwSectorSize, DWORD dwFileSize);
|
||||
DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags);
|
||||
|
||||
bool IsValidMD5(LPBYTE pbMd5);
|
||||
bool IsValidSignature(LPBYTE pbSignature);
|
||||
bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5);
|
||||
void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle validation functions
|
||||
|
||||
TMPQArchive * IsValidMpqHandle(HANDLE hMpq);
|
||||
TMPQFile * IsValidFileHandle(HANDLE hFile);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for MPQ file tables
|
||||
|
||||
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset);
|
||||
ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset);
|
||||
|
||||
DWORD ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, MTYPE MapType);
|
||||
|
||||
bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash);
|
||||
|
||||
TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale);
|
||||
TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName);
|
||||
TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash);
|
||||
TMPQHash * AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry, LCID lcLocale);
|
||||
|
||||
TMPQExtHeader * LoadExtTable(TMPQArchive * ha, ULONGLONG ByteOffset, size_t Size, DWORD dwSignature, DWORD dwKey);
|
||||
TMPQHetTable * LoadHetTable(TMPQArchive * ha);
|
||||
TMPQBetTable * LoadBetTable(TMPQArchive * ha);
|
||||
|
||||
TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool bDontFixEntries = false);
|
||||
TMPQBlock * TranslateBlockTable(TMPQArchive * ha, ULONGLONG * pcbTableSize, bool * pbNeedHiBlockTable);
|
||||
|
||||
ULONGLONG FindFreeMpqSpace(TMPQArchive * ha);
|
||||
|
||||
// Functions that load the HET and BET tables
|
||||
DWORD CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize);
|
||||
DWORD LoadAnyHashTable(TMPQArchive * ha);
|
||||
DWORD BuildFileTable(TMPQArchive * ha);
|
||||
DWORD DefragmentFileTable(TMPQArchive * ha);
|
||||
|
||||
DWORD CreateFileTable(TMPQArchive * ha, DWORD dwFileTableSize);
|
||||
DWORD RebuildHetTable(TMPQArchive * ha);
|
||||
DWORD RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize);
|
||||
DWORD SaveMPQTables(TMPQArchive * ha);
|
||||
|
||||
TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwHashBitSize, LPBYTE pbSrcData);
|
||||
void FreeHetTable(TMPQHetTable * pHetTable);
|
||||
|
||||
TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount);
|
||||
void FreeBetTable(TMPQBetTable * pBetTable);
|
||||
|
||||
// Functions for finding files in the file table
|
||||
TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex);
|
||||
TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
|
||||
TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex);
|
||||
|
||||
// Allocates file name in the file entry
|
||||
void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szFileName);
|
||||
|
||||
// Allocates new file entry in the MPQ tables. Reuses existing, if possible
|
||||
TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex);
|
||||
DWORD RenameFileEntry(TMPQArchive * ha, TMPQFile * hf, const char * szNewFileName);
|
||||
DWORD DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf);
|
||||
|
||||
// Invalidates entries for (listfile) and (attributes)
|
||||
void InvalidateInternalFiles(TMPQArchive * ha);
|
||||
|
||||
// Retrieves information about the strong signature
|
||||
bool QueryMpqSignatureInfo(TMPQArchive * ha, PMPQ_SIGNATURE_INFO pSignatureInfo);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for alternate file formats (SBaseSubTypes.cpp)
|
||||
|
||||
DWORD ConvertSqpHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags);
|
||||
TMPQHash * LoadSqpHashTable(TMPQArchive * ha);
|
||||
TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha);
|
||||
|
||||
DWORD ConvertMpkHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags);
|
||||
void DecryptMpkTable(void * pvMpkTable, size_t cbSize);
|
||||
TMPQHash * LoadMpkHashTable(TMPQArchive * ha);
|
||||
TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha);
|
||||
int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common functions - MPQ File
|
||||
|
||||
TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry);
|
||||
TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize);
|
||||
void * LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, LPBYTE pbTableHash, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey, bool * pbTableIsCut);
|
||||
DWORD AllocateSectorBuffer(TMPQFile * hf);
|
||||
DWORD AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile);
|
||||
DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile);
|
||||
DWORD AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile);
|
||||
DWORD WritePatchInfo(TMPQFile * hf);
|
||||
DWORD WriteSectorOffsets(TMPQFile * hf);
|
||||
DWORD WriteSectorChecksums(TMPQFile * hf);
|
||||
DWORD WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize);
|
||||
DWORD WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize);
|
||||
void FreeFileHandle(TMPQFile *& hf);
|
||||
void FreeArchiveHandle(TMPQArchive *& ha);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Patch functions
|
||||
|
||||
// Structure used for the patching process
|
||||
typedef struct _TMPQPatcher
|
||||
{
|
||||
BYTE this_md5[MD5_DIGEST_SIZE]; // MD5 of the current file state
|
||||
LPBYTE pbFileData1; // Primary working buffer
|
||||
LPBYTE pbFileData2; // Secondary working buffer
|
||||
DWORD cbMaxFileData; // Maximum allowed size of the patch data
|
||||
DWORD cbFileData; // Current size of the result data
|
||||
DWORD nCounter; // Counter of the patch process
|
||||
|
||||
} TMPQPatcher;
|
||||
|
||||
bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize);
|
||||
DWORD Patch_InitPatcher(TMPQPatcher * pPatcher, TMPQFile * hf);
|
||||
DWORD Patch_Process(TMPQPatcher * pPatcher, TMPQFile * hf);
|
||||
void Patch_Finalize(TMPQPatcher * pPatcher);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility functions
|
||||
|
||||
bool IsInternalMpqFileName(const char * szFileName);
|
||||
|
||||
template <typename XCHAR>
|
||||
const XCHAR * GetPlainFileName(const XCHAR * szFileName)
|
||||
{
|
||||
const XCHAR * szPlainName = szFileName;
|
||||
|
||||
while(*szFileName != 0)
|
||||
{
|
||||
if(*szFileName == '\\' || *szFileName == '/')
|
||||
szPlainName = szFileName + 1;
|
||||
szFileName++;
|
||||
}
|
||||
|
||||
return szPlainName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal support for MPQ modifications
|
||||
|
||||
DWORD SFileAddFile_Init(
|
||||
TMPQArchive * ha,
|
||||
const char * szArchivedName,
|
||||
ULONGLONG ft,
|
||||
DWORD dwFileSize,
|
||||
LCID lcLocale,
|
||||
DWORD dwFlags,
|
||||
TMPQFile ** phf
|
||||
);
|
||||
|
||||
DWORD SFileAddFile_Init(
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hfSrc,
|
||||
TMPQFile ** phf
|
||||
);
|
||||
|
||||
DWORD SFileAddFile_Write(
|
||||
TMPQFile * hf,
|
||||
const void * pvData,
|
||||
DWORD dwSize,
|
||||
DWORD dwCompression
|
||||
);
|
||||
|
||||
DWORD SFileAddFile_Finish(
|
||||
TMPQFile * hf
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attributes support
|
||||
|
||||
DWORD SAttrLoadAttributes(TMPQArchive * ha);
|
||||
DWORD SAttrFileSaveToMpq(TMPQArchive * ha);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Listfile functions
|
||||
|
||||
DWORD SListFileSaveToMpq(TMPQArchive * ha);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Weak signature support
|
||||
|
||||
DWORD SSignFileCreate(TMPQArchive * ha);
|
||||
DWORD SSignFileFinish(TMPQArchive * ha);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dump data support
|
||||
|
||||
#ifdef __STORMLIB_DUMP_DATA__
|
||||
|
||||
void DumpMpqHeader(TMPQHeader * pHeader);
|
||||
void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize);
|
||||
void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable);
|
||||
void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize);
|
||||
|
||||
#else
|
||||
|
||||
#define DumpMpqHeader(h) /* */
|
||||
#define DumpHashTable(t, s) /* */
|
||||
#define DumpHetAndBetTable(t, s) /* */
|
||||
#define DumpFileTable(t, s) /* */
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __STORMCOMMON_H__
|
||||
|
74
StormLib/src/StormLib.exp
Normal file
74
StormLib/src/StormLib.exp
Normal file
@ -0,0 +1,74 @@
|
||||
#
|
||||
# Export file for Mac OS X
|
||||
# Copyright (c) 2009 Sam Wilkins
|
||||
# swilkins1337@gmail.com
|
||||
#
|
||||
|
||||
_SFileSetLocale
|
||||
_SFileGetLocale
|
||||
|
||||
_SFileOpenArchive
|
||||
_SFileCreateArchive
|
||||
_SFileFlushArchive
|
||||
_SFileCloseArchive
|
||||
|
||||
_SFileAddListFile
|
||||
|
||||
_SFileSetCompactCallback
|
||||
_SFileCompactArchive
|
||||
|
||||
_SFileGetMaxFileCount
|
||||
_SFileSetMaxFileCount
|
||||
|
||||
_SFileGetAttributes
|
||||
_SFileSetAttributes
|
||||
_SFileUpdateFileAttributes
|
||||
|
||||
_SFileOpenPatchArchive
|
||||
_SFileIsPatchedArchive
|
||||
|
||||
_SFileOpenFileEx
|
||||
_SFileGetFileSize
|
||||
_SFileSetFilePointer
|
||||
_SFileReadFile
|
||||
_SFileCloseFile
|
||||
|
||||
_SFileHasFile
|
||||
_SFileGetFileName
|
||||
_SFileGetFileInfo
|
||||
|
||||
_SFileExtractFile
|
||||
|
||||
_SFileVerifyFile
|
||||
_SFileVerifyRawData
|
||||
_SFileVerifyArchive
|
||||
|
||||
_SFileFindFirstFile
|
||||
_SFileFindNextFile
|
||||
_SFileFindClose
|
||||
|
||||
_SListFileFindFirstFile
|
||||
_SListFileFindNextFile
|
||||
_SListFileFindClose
|
||||
|
||||
_SFileEnumLocales
|
||||
|
||||
_SFileCreateFile
|
||||
_SFileWriteFile
|
||||
_SFileFinishFile
|
||||
_SFileAddFileEx
|
||||
_SFileAddFile
|
||||
_SFileAddWave
|
||||
_SFileRemoveFile
|
||||
_SFileRenameFile
|
||||
_SFileSetFileLocale
|
||||
_SFileSetDataCompression
|
||||
_SFileSetAddFileCallback
|
||||
|
||||
_SCompImplode
|
||||
_SCompExplode
|
||||
_SCompCompress
|
||||
_SCompDecompress
|
||||
|
||||
_SetLastError
|
||||
_GetLastError
|
@ -117,11 +117,7 @@ extern "C" {
|
||||
#ifdef _DLL
|
||||
#pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
#pragma comment(lib, "StormLibDUS32.lib") // Debug Unicode CRT-LIB version
|
||||
#else
|
||||
#pragma comment(lib, "StormLibDUS64.lib") // Debug Unicode CRT-LIB version
|
||||
#endif
|
||||
#pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version
|
||||
#endif
|
||||
#endif
|
||||
#else // RELEASE VERSIONS
|
||||
@ -135,11 +131,7 @@ extern "C" {
|
||||
#ifdef _DLL
|
||||
#pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
#pragma comment(lib, "StormLibRUS32.lib") // Release Unicode CRT-LIB version
|
||||
#else
|
||||
#pragma comment(lib, "StormLibRUS64.lib") // Release Unicode CRT-LIB version
|
||||
#endif
|
||||
#pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
@ -857,6 +849,10 @@ typedef struct _TMPQArchive
|
||||
ULONGLONG CompactBytesProcessed; // Amount of bytes that have been processed during a particular compact call
|
||||
ULONGLONG CompactTotalBytes; // Total amount of bytes to be compacted
|
||||
void * pvCompactUserData; // User data thats passed to the callback
|
||||
|
||||
// OTR
|
||||
TFileEntry* lastFreeSpaceEntry;
|
||||
bool useFreeSpaceOptimization;
|
||||
} TMPQArchive;
|
||||
|
||||
// File handle structure
|
401
StormLib/src/adpcm/adpcm.cpp
Normal file
401
StormLib/src/adpcm/adpcm.cpp
Normal file
@ -0,0 +1,401 @@
|
||||
/*****************************************************************************/
|
||||
/* adpcm.cpp Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* This module contains implementation of adpcm decompression method used by */
|
||||
/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing */
|
||||
/* his sources. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
|
||||
/* 20.05.03 2.00 Lad Added compression */
|
||||
/* 19.11.03 2.01 Dan Big endian handling */
|
||||
/* 10.01.13 3.00 Lad Refactored, beautified, documented :-) */
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "adpcm.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tables necessary dor decompression
|
||||
|
||||
static int NextStepTable[] =
|
||||
{
|
||||
-1, 0, -1, 4, -1, 2, -1, 6,
|
||||
-1, 1, -1, 5, -1, 3, -1, 7,
|
||||
-1, 1, -1, 5, -1, 3, -1, 7,
|
||||
-1, 2, -1, 4, -1, 6, -1, 8
|
||||
};
|
||||
|
||||
static int StepSizeTable[] =
|
||||
{
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
16, 17, 19, 21, 23, 25, 28, 31,
|
||||
34, 37, 41, 45, 50, 55, 60, 66,
|
||||
73, 80, 88, 97, 107, 118, 130, 143,
|
||||
157, 173, 190, 209, 230, 253, 279, 307,
|
||||
337, 371, 408, 449, 494, 544, 598, 658,
|
||||
724, 796, 876, 963, 1060, 1166, 1282, 1411,
|
||||
1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
|
||||
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
|
||||
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
||||
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
|
||||
32767
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper class for writing output ADPCM data
|
||||
|
||||
class TADPCMStream
|
||||
{
|
||||
public:
|
||||
|
||||
TADPCMStream(void * pvBuffer, size_t cbBuffer)
|
||||
{
|
||||
pbBufferEnd = (unsigned char *)pvBuffer + cbBuffer;
|
||||
pbBuffer = (unsigned char *)pvBuffer;
|
||||
}
|
||||
|
||||
bool ReadByteSample(unsigned char & ByteSample)
|
||||
{
|
||||
// Check if there is enough space in the buffer
|
||||
if(pbBuffer >= pbBufferEnd)
|
||||
return false;
|
||||
|
||||
ByteSample = *pbBuffer++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteByteSample(unsigned char ByteSample)
|
||||
{
|
||||
// Check if there is enough space in the buffer
|
||||
if(pbBuffer >= pbBufferEnd)
|
||||
return false;
|
||||
|
||||
*pbBuffer++ = ByteSample;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadWordSample(short & OneSample)
|
||||
{
|
||||
// Check if we have enough space in the output buffer
|
||||
if((size_t)(pbBufferEnd - pbBuffer) < sizeof(short))
|
||||
return false;
|
||||
|
||||
// Write the sample
|
||||
OneSample = pbBuffer[0] + (((short)pbBuffer[1]) << 0x08);
|
||||
pbBuffer += sizeof(short);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteWordSample(short OneSample)
|
||||
{
|
||||
// Check if we have enough space in the output buffer
|
||||
if((size_t)(pbBufferEnd - pbBuffer) < sizeof(short))
|
||||
return false;
|
||||
|
||||
// Write the sample
|
||||
*pbBuffer++ = (unsigned char)(OneSample & 0xFF);
|
||||
*pbBuffer++ = (unsigned char)(OneSample >> 0x08);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LengthProcessed(void * pvOutBuffer)
|
||||
{
|
||||
return (int)((unsigned char *)pbBuffer - (unsigned char *)pvOutBuffer);
|
||||
}
|
||||
|
||||
unsigned char * pbBufferEnd;
|
||||
unsigned char * pbBuffer;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static inline short GetNextStepIndex(int StepIndex, unsigned int EncodedSample)
|
||||
{
|
||||
// Get the next step index
|
||||
StepIndex = StepIndex + NextStepTable[EncodedSample & 0x1F];
|
||||
|
||||
// Don't make the step index overflow
|
||||
if(StepIndex < 0)
|
||||
StepIndex = 0;
|
||||
else if(StepIndex > 88)
|
||||
StepIndex = 88;
|
||||
|
||||
return (short)StepIndex;
|
||||
}
|
||||
|
||||
static inline int UpdatePredictedSample(int PredictedSample, int EncodedSample, int Difference)
|
||||
{
|
||||
// Is the sign bit set?
|
||||
if(EncodedSample & 0x40)
|
||||
{
|
||||
PredictedSample -= Difference;
|
||||
if(PredictedSample <= -32768)
|
||||
PredictedSample = -32768;
|
||||
}
|
||||
else
|
||||
{
|
||||
PredictedSample += Difference;
|
||||
if(PredictedSample >= 32767)
|
||||
PredictedSample = 32767;
|
||||
}
|
||||
|
||||
return PredictedSample;
|
||||
}
|
||||
|
||||
static inline int DecodeSample(int PredictedSample, int EncodedSample, int StepSize, int Difference)
|
||||
{
|
||||
if(EncodedSample & 0x01)
|
||||
Difference += (StepSize >> 0);
|
||||
|
||||
if(EncodedSample & 0x02)
|
||||
Difference += (StepSize >> 1);
|
||||
|
||||
if(EncodedSample & 0x04)
|
||||
Difference += (StepSize >> 2);
|
||||
|
||||
if(EncodedSample & 0x08)
|
||||
Difference += (StepSize >> 3);
|
||||
|
||||
if(EncodedSample & 0x10)
|
||||
Difference += (StepSize >> 4);
|
||||
|
||||
if(EncodedSample & 0x20)
|
||||
Difference += (StepSize >> 5);
|
||||
|
||||
return UpdatePredictedSample(PredictedSample, EncodedSample, Difference);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Compression routine
|
||||
|
||||
int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount, int CompressionLevel)
|
||||
{
|
||||
TADPCMStream os(pvOutBuffer, cbOutBuffer); // The output stream
|
||||
TADPCMStream is(pvInBuffer, cbInBuffer); // The input stream
|
||||
unsigned char BitShift = (unsigned char)(CompressionLevel - 1);
|
||||
short PredictedSamples[MAX_ADPCM_CHANNEL_COUNT];// Predicted samples for each channel
|
||||
short StepIndexes[MAX_ADPCM_CHANNEL_COUNT]; // Step indexes for each channel
|
||||
short InputSample; // Input sample for the current channel
|
||||
int TotalStepSize;
|
||||
int ChannelIndex;
|
||||
int AbsDifference;
|
||||
int Difference;
|
||||
int MaxBitMask;
|
||||
int StepSize;
|
||||
|
||||
// _tprintf(_T("== CMPR Started ==============\n"));
|
||||
|
||||
// First byte in the output stream contains zero. The second one contains the compression level
|
||||
os.WriteByteSample(0);
|
||||
if(!os.WriteByteSample(BitShift))
|
||||
return 2;
|
||||
|
||||
// Set the initial step index for each channel
|
||||
PredictedSamples[0] = PredictedSamples[1] = 0;
|
||||
StepIndexes[0] = StepIndexes[1] = INITIAL_ADPCM_STEP_INDEX;
|
||||
|
||||
// Next, InitialSample value for each channel follows
|
||||
for(int i = 0; i < ChannelCount; i++)
|
||||
{
|
||||
// Get the initial sample from the input stream
|
||||
if(!is.ReadWordSample(InputSample))
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
|
||||
// Store the initial sample to our sample array
|
||||
PredictedSamples[i] = InputSample;
|
||||
|
||||
// Also store the loaded sample to the output stream
|
||||
if(!os.WriteWordSample(InputSample))
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
}
|
||||
|
||||
// Get the initial index
|
||||
ChannelIndex = ChannelCount - 1;
|
||||
|
||||
// Now keep reading the input data as long as there is something in the input buffer
|
||||
while(is.ReadWordSample(InputSample))
|
||||
{
|
||||
int EncodedSample = 0;
|
||||
|
||||
// If we have two channels, we need to flip the channel index
|
||||
ChannelIndex = (ChannelIndex + 1) % ChannelCount;
|
||||
|
||||
// Get the difference from the previous sample.
|
||||
// If the difference is negative, set the sign bit to the encoded sample
|
||||
AbsDifference = InputSample - PredictedSamples[ChannelIndex];
|
||||
if(AbsDifference < 0)
|
||||
{
|
||||
AbsDifference = -AbsDifference;
|
||||
EncodedSample |= 0x40;
|
||||
}
|
||||
|
||||
// If the difference is too low (higher that difference treshold),
|
||||
// write a step index modifier marker
|
||||
StepSize = StepSizeTable[StepIndexes[ChannelIndex]];
|
||||
if(AbsDifference < (StepSize >> CompressionLevel))
|
||||
{
|
||||
if(StepIndexes[ChannelIndex] != 0)
|
||||
StepIndexes[ChannelIndex]--;
|
||||
|
||||
os.WriteByteSample(0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the difference is too high, write marker that
|
||||
// indicates increase in step size
|
||||
while(AbsDifference > (StepSize << 1))
|
||||
{
|
||||
if(StepIndexes[ChannelIndex] >= 0x58)
|
||||
break;
|
||||
|
||||
// Modify the step index
|
||||
StepIndexes[ChannelIndex] += 8;
|
||||
if(StepIndexes[ChannelIndex] > 0x58)
|
||||
StepIndexes[ChannelIndex] = 0x58;
|
||||
|
||||
// Write the "modify step index" marker
|
||||
StepSize = StepSizeTable[StepIndexes[ChannelIndex]];
|
||||
os.WriteByteSample(0x81);
|
||||
}
|
||||
|
||||
// Get the limit bit value
|
||||
MaxBitMask = (1 << (BitShift - 1));
|
||||
MaxBitMask = (MaxBitMask > 0x20) ? 0x20 : MaxBitMask;
|
||||
Difference = StepSize >> BitShift;
|
||||
TotalStepSize = 0;
|
||||
|
||||
for(int BitVal = 0x01; BitVal <= MaxBitMask; BitVal <<= 1)
|
||||
{
|
||||
if((TotalStepSize + StepSize) <= AbsDifference)
|
||||
{
|
||||
TotalStepSize += StepSize;
|
||||
EncodedSample |= BitVal;
|
||||
}
|
||||
StepSize >>= 1;
|
||||
}
|
||||
|
||||
PredictedSamples[ChannelIndex] = (short)UpdatePredictedSample(PredictedSamples[ChannelIndex],
|
||||
EncodedSample,
|
||||
Difference + TotalStepSize);
|
||||
// Write the encoded sample to the output stream
|
||||
if(!os.WriteByteSample((unsigned char)EncodedSample))
|
||||
break;
|
||||
|
||||
// Calculates the step index to use for the next encode
|
||||
StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndexes[ChannelIndex], EncodedSample);
|
||||
}
|
||||
}
|
||||
|
||||
// _tprintf(_T("== CMPR Ended ================\n"));
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Decompression routine
|
||||
|
||||
int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount)
|
||||
{
|
||||
TADPCMStream os(pvOutBuffer, cbOutBuffer); // Output stream
|
||||
TADPCMStream is(pvInBuffer, cbInBuffer); // Input stream
|
||||
unsigned char EncodedSample;
|
||||
unsigned char BitShift;
|
||||
short PredictedSamples[MAX_ADPCM_CHANNEL_COUNT]; // Predicted sample for each channel
|
||||
short StepIndexes[MAX_ADPCM_CHANNEL_COUNT]; // Predicted step index for each channel
|
||||
int ChannelIndex; // Current channel index
|
||||
|
||||
// Initialize the StepIndex for each channel
|
||||
PredictedSamples[0] = PredictedSamples[1] = 0;
|
||||
StepIndexes[0] = StepIndexes[1] = INITIAL_ADPCM_STEP_INDEX;
|
||||
|
||||
// _tprintf(_T("== DCMP Started ==============\n"));
|
||||
|
||||
// The first byte is always zero, the second one contains bit shift (compression level - 1)
|
||||
is.ReadByteSample(BitShift);
|
||||
is.ReadByteSample(BitShift);
|
||||
// _tprintf(_T("DCMP: BitShift = %u\n"), (unsigned int)(unsigned char)BitShift);
|
||||
|
||||
// Next, InitialSample value for each channel follows
|
||||
for(int i = 0; i < ChannelCount; i++)
|
||||
{
|
||||
// Get the initial sample from the input stream
|
||||
short InitialSample;
|
||||
|
||||
// Attempt to read the initial sample
|
||||
if(!is.ReadWordSample(InitialSample))
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
|
||||
// _tprintf(_T("DCMP: Loaded InitialSample[%u]: %04X\n"), i, (unsigned int)(unsigned short)InitialSample);
|
||||
|
||||
// Store the initial sample to our sample array
|
||||
PredictedSamples[i] = InitialSample;
|
||||
|
||||
// Also store the loaded sample to the output stream
|
||||
if(!os.WriteWordSample(InitialSample))
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
}
|
||||
|
||||
// Get the initial index
|
||||
ChannelIndex = ChannelCount - 1;
|
||||
|
||||
// Keep reading as long as there is something in the input buffer
|
||||
while(is.ReadByteSample(EncodedSample))
|
||||
{
|
||||
// _tprintf(_T("DCMP: Loaded Encoded Sample: %02X\n"), (unsigned int)(unsigned char)EncodedSample);
|
||||
|
||||
// If we have two channels, we need to flip the channel index
|
||||
ChannelIndex = (ChannelIndex + 1) % ChannelCount;
|
||||
|
||||
if(EncodedSample == 0x80)
|
||||
{
|
||||
if(StepIndexes[ChannelIndex] != 0)
|
||||
StepIndexes[ChannelIndex]--;
|
||||
|
||||
// _tprintf(_T("DCMP: Writing Decoded Sample: %04lX\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]);
|
||||
if(!os.WriteWordSample(PredictedSamples[ChannelIndex]))
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
}
|
||||
else if(EncodedSample == 0x81)
|
||||
{
|
||||
// Modify the step index
|
||||
StepIndexes[ChannelIndex] += 8;
|
||||
if(StepIndexes[ChannelIndex] > 0x58)
|
||||
StepIndexes[ChannelIndex] = 0x58;
|
||||
|
||||
// _tprintf(_T("DCMP: New value of StepIndex: %04lX\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]);
|
||||
|
||||
// Next pass, keep going on the same channel
|
||||
ChannelIndex = (ChannelIndex + 1) % ChannelCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
int StepIndex = StepIndexes[ChannelIndex];
|
||||
int StepSize = StepSizeTable[StepIndex];
|
||||
|
||||
// Encode one sample
|
||||
PredictedSamples[ChannelIndex] = (short)DecodeSample(PredictedSamples[ChannelIndex],
|
||||
EncodedSample,
|
||||
StepSize,
|
||||
StepSize >> BitShift);
|
||||
|
||||
// _tprintf(_T("DCMP: Writing decoded sample: %04X\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]);
|
||||
|
||||
// Write the decoded sample to the output stream
|
||||
if(!os.WriteWordSample(PredictedSamples[ChannelIndex]))
|
||||
break;
|
||||
|
||||
// Calculates the step index to use for the next encode
|
||||
StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndex, EncodedSample);
|
||||
// _tprintf(_T("DCMP: New step index: %04X\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
// _tprintf(_T("DCMP: Total length written: %u\n"), (unsigned int)os.LengthProcessed(pvOutBuffer));
|
||||
// _tprintf(_T("== DCMP Ended ================\n"));
|
||||
|
||||
// Return total bytes written since beginning of the output buffer
|
||||
return os.LengthProcessed(pvOutBuffer);
|
||||
}
|
26
StormLib/src/adpcm/adpcm.h
Normal file
26
StormLib/src/adpcm/adpcm.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*****************************************************************************/
|
||||
/* adpcm.h Copyright (c) Ladislav Zezula 2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Header file for adpcm decompress functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 31.03.03 1.00 Lad The first version of adpcm.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __ADPCM_H__
|
||||
#define __ADPCM_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define MAX_ADPCM_CHANNEL_COUNT 2
|
||||
#define INITIAL_ADPCM_STEP_INDEX 0x2C
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
int CompressADPCM (void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int nCmpType, int ChannelCount);
|
||||
int DecompressADPCM(void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int ChannelCount);
|
||||
|
||||
#endif // __ADPCM_H__
|
1094
StormLib/src/bzip2/blocksort.c
Normal file
1094
StormLib/src/bzip2/blocksort.c
Normal file
File diff suppressed because it is too large
Load Diff
1573
StormLib/src/bzip2/bzlib.c
Normal file
1573
StormLib/src/bzip2/bzlib.c
Normal file
File diff suppressed because it is too large
Load Diff
282
StormLib/src/bzip2/bzlib.h
Normal file
282
StormLib/src/bzip2/bzlib.h
Normal file
@ -0,0 +1,282 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Public header file for the library. ---*/
|
||||
/*--- bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.5 of 10 December 2007
|
||||
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_H
|
||||
#define _BZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *(*bzalloc)(void *,int,int);
|
||||
void (*bzfree)(void *,void *);
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*-- High(er) level library functions --*/
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#define BZ_MAX_UNUSED 5000
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
int small,
|
||||
void* unused,
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int small,
|
||||
int verbosity
|
||||
);
|
||||
|
||||
|
||||
/*--
|
||||
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
|
||||
to support better zlib compatibility.
|
||||
This code is not _officially_ part of libbzip2 (yet);
|
||||
I haven't tested it, documented it, or considered the
|
||||
threading-safeness of it.
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
509
StormLib/src/bzip2/bzlib_private.h
Normal file
509
StormLib/src/bzip2/bzlib_private.h
Normal file
@ -0,0 +1,509 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Private header file for the library. ---*/
|
||||
/*--- bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.5 of 10 December 2007
|
||||
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_PRIVATE_H
|
||||
#define _BZLIB_PRIVATE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.5, 10-Dec-2007"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
typedef unsigned char UChar;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#define True ((Bool)1)
|
||||
#define False ((Bool)0)
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline__ /* */
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
|
||||
extern void BZ2_bz__AssertH__fail ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
|
||||
|
||||
#if BZ_DEBUG
|
||||
#define AssertD(cond,msg) \
|
||||
{ if (!(cond)) { \
|
||||
fprintf ( stderr, \
|
||||
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
|
||||
exit(1); \
|
||||
}}
|
||||
#else
|
||||
#define AssertD(cond,msg) /* */
|
||||
#endif
|
||||
|
||||
#define VPrintf0(zf) \
|
||||
fprintf(stderr,zf)
|
||||
#define VPrintf1(zf,za1) \
|
||||
fprintf(stderr,zf,za1)
|
||||
#define VPrintf2(zf,za1,za2) \
|
||||
fprintf(stderr,zf,za1,za2)
|
||||
#define VPrintf3(zf,za1,za2,za3) \
|
||||
fprintf(stderr,zf,za1,za2,za3)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4,za5)
|
||||
|
||||
#else
|
||||
|
||||
extern void bz_internal_error ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) bz_internal_error ( errcode ); }
|
||||
#define AssertD(cond,msg) do { } while (0)
|
||||
#define VPrintf0(zf) do { } while (0)
|
||||
#define VPrintf1(zf,za1) do { } while (0)
|
||||
#define VPrintf2(zf,za1,za2) do { } while (0)
|
||||
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
|
||||
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
|
||||
|
||||
|
||||
/*-- Header bytes. --*/
|
||||
|
||||
#define BZ_HDR_B 0x42 /* 'B' */
|
||||
#define BZ_HDR_Z 0x5a /* 'Z' */
|
||||
#define BZ_HDR_h 0x68 /* 'h' */
|
||||
#define BZ_HDR_0 0x30 /* '0' */
|
||||
|
||||
/*-- Constants for the back end. --*/
|
||||
|
||||
#define BZ_MAX_ALPHA_SIZE 258
|
||||
#define BZ_MAX_CODE_LEN 23
|
||||
|
||||
#define BZ_RUNA 0
|
||||
#define BZ_RUNB 1
|
||||
|
||||
#define BZ_N_GROUPS 6
|
||||
#define BZ_G_SIZE 50
|
||||
#define BZ_N_ITERS 4
|
||||
|
||||
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int32 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
Int32 rTPos \
|
||||
|
||||
#define BZ_RAND_INIT_MASK \
|
||||
s->rNToGo = 0; \
|
||||
s->rTPos = 0 \
|
||||
|
||||
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
s->rNToGo--;
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) \
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-- States and modes for compression. --*/
|
||||
|
||||
#define BZ_M_IDLE 1
|
||||
#define BZ_M_RUNNING 2
|
||||
#define BZ_M_FLUSHING 3
|
||||
#define BZ_M_FINISHING 4
|
||||
|
||||
#define BZ_S_OUTPUT 1
|
||||
#define BZ_S_INPUT 2
|
||||
|
||||
#define BZ_N_RADIX 2
|
||||
#define BZ_N_QSORT 12
|
||||
#define BZ_N_SHELL 18
|
||||
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
|
||||
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the compression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* mode this stream is in, and whether inputting */
|
||||
/* or outputting data */
|
||||
Int32 mode;
|
||||
Int32 state;
|
||||
|
||||
/* remembers avail_in when flush/finish requested */
|
||||
UInt32 avail_in_expect;
|
||||
|
||||
/* for doing the block sorting */
|
||||
UInt32* arr1;
|
||||
UInt32* arr2;
|
||||
UInt32* ftab;
|
||||
Int32 origPtr;
|
||||
|
||||
/* aliases for arr1 and arr2 */
|
||||
UInt32* ptr;
|
||||
UChar* block;
|
||||
UInt16* mtfv;
|
||||
UChar* zbits;
|
||||
|
||||
/* for deciding when to use the fallback sorting algorithm */
|
||||
Int32 workFactor;
|
||||
|
||||
/* run-length-encoding of the input */
|
||||
UInt32 state_in_ch;
|
||||
Int32 state_in_len;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* input and output limits and current posns */
|
||||
Int32 nblock;
|
||||
Int32 nblockMAX;
|
||||
Int32 numZ;
|
||||
Int32 state_out_pos;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
UChar unseqToSeq[256];
|
||||
|
||||
/* the buffer for bit stream creation */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* block and combined CRCs */
|
||||
UInt32 blockCRC;
|
||||
UInt32 combinedCRC;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 verbosity;
|
||||
Int32 blockNo;
|
||||
Int32 blockSize100k;
|
||||
|
||||
/* stuff for coding the MTF values */
|
||||
Int32 nMTF;
|
||||
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
/* second dimension: only 3 needed; 4 makes index calculations faster */
|
||||
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
|
||||
}
|
||||
EState;
|
||||
|
||||
|
||||
|
||||
/*-- externs for compression. --*/
|
||||
|
||||
extern void
|
||||
BZ2_blockSort ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_compressBlock ( EState*, Bool );
|
||||
|
||||
extern void
|
||||
BZ2_bsInitWrite ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
|
||||
extern void
|
||||
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
|
||||
|
||||
|
||||
/*-- states for decompression. --*/
|
||||
|
||||
#define BZ_X_IDLE 1
|
||||
#define BZ_X_OUTPUT 2
|
||||
|
||||
#define BZ_X_MAGIC_1 10
|
||||
#define BZ_X_MAGIC_2 11
|
||||
#define BZ_X_MAGIC_3 12
|
||||
#define BZ_X_MAGIC_4 13
|
||||
#define BZ_X_BLKHDR_1 14
|
||||
#define BZ_X_BLKHDR_2 15
|
||||
#define BZ_X_BLKHDR_3 16
|
||||
#define BZ_X_BLKHDR_4 17
|
||||
#define BZ_X_BLKHDR_5 18
|
||||
#define BZ_X_BLKHDR_6 19
|
||||
#define BZ_X_BCRC_1 20
|
||||
#define BZ_X_BCRC_2 21
|
||||
#define BZ_X_BCRC_3 22
|
||||
#define BZ_X_BCRC_4 23
|
||||
#define BZ_X_RANDBIT 24
|
||||
#define BZ_X_ORIGPTR_1 25
|
||||
#define BZ_X_ORIGPTR_2 26
|
||||
#define BZ_X_ORIGPTR_3 27
|
||||
#define BZ_X_MAPPING_1 28
|
||||
#define BZ_X_MAPPING_2 29
|
||||
#define BZ_X_SELECTOR_1 30
|
||||
#define BZ_X_SELECTOR_2 31
|
||||
#define BZ_X_SELECTOR_3 32
|
||||
#define BZ_X_CODING_1 33
|
||||
#define BZ_X_CODING_2 34
|
||||
#define BZ_X_CODING_3 35
|
||||
#define BZ_X_MTF_1 36
|
||||
#define BZ_X_MTF_2 37
|
||||
#define BZ_X_MTF_3 38
|
||||
#define BZ_X_MTF_4 39
|
||||
#define BZ_X_MTF_5 40
|
||||
#define BZ_X_MTF_6 41
|
||||
#define BZ_X_ENDHDR_2 42
|
||||
#define BZ_X_ENDHDR_3 43
|
||||
#define BZ_X_ENDHDR_4 44
|
||||
#define BZ_X_ENDHDR_5 45
|
||||
#define BZ_X_ENDHDR_6 46
|
||||
#define BZ_X_CCRC_1 47
|
||||
#define BZ_X_CCRC_2 48
|
||||
#define BZ_X_CCRC_3 49
|
||||
#define BZ_X_CCRC_4 50
|
||||
|
||||
|
||||
|
||||
/*-- Constants for the fast MTF decoder. --*/
|
||||
|
||||
#define MTFA_SIZE 4096
|
||||
#define MTFL_SIZE 16
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the decompression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* state indicator for this stream */
|
||||
Int32 state;
|
||||
|
||||
/* for doing the final run-length decoding */
|
||||
UChar state_out_ch;
|
||||
Int32 state_out_len;
|
||||
Bool blockRandomised;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* the buffer for bit stream reading */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 blockSize100k;
|
||||
Bool smallDecompress;
|
||||
Int32 currBlockNo;
|
||||
Int32 verbosity;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform */
|
||||
Int32 origPtr;
|
||||
UInt32 tPos;
|
||||
Int32 k0;
|
||||
Int32 unzftab[256];
|
||||
Int32 nblock_used;
|
||||
Int32 cftab[257];
|
||||
Int32 cftabCopy[257];
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (FAST) */
|
||||
UInt32 *tt;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (SMALL) */
|
||||
UInt16 *ll16;
|
||||
UChar *ll4;
|
||||
|
||||
/* stored and calculated CRCs */
|
||||
UInt32 storedBlockCRC;
|
||||
UInt32 storedCombinedCRC;
|
||||
UInt32 calculatedBlockCRC;
|
||||
UInt32 calculatedCombinedCRC;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
Bool inUse16[16];
|
||||
UChar seqToUnseq[256];
|
||||
|
||||
/* for decoding the MTF values */
|
||||
UChar mtfa [MTFA_SIZE];
|
||||
Int32 mtfbase[256 / MTFL_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
|
||||
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 minLens[BZ_N_GROUPS];
|
||||
|
||||
/* save area for scalars in the main decompress code */
|
||||
Int32 save_i;
|
||||
Int32 save_j;
|
||||
Int32 save_t;
|
||||
Int32 save_alphaSize;
|
||||
Int32 save_nGroups;
|
||||
Int32 save_nSelectors;
|
||||
Int32 save_EOB;
|
||||
Int32 save_groupNo;
|
||||
Int32 save_groupPos;
|
||||
Int32 save_nextSym;
|
||||
Int32 save_nblockMAX;
|
||||
Int32 save_nblock;
|
||||
Int32 save_es;
|
||||
Int32 save_N;
|
||||
Int32 save_curr;
|
||||
Int32 save_zt;
|
||||
Int32 save_zn;
|
||||
Int32 save_zvec;
|
||||
Int32 save_zj;
|
||||
Int32 save_gSel;
|
||||
Int32 save_gMinlen;
|
||||
Int32* save_gLimit;
|
||||
Int32* save_gBase;
|
||||
Int32* save_gPerm;
|
||||
|
||||
}
|
||||
DState;
|
||||
|
||||
|
||||
|
||||
/*-- Macros for decompression. --*/
|
||||
|
||||
#define BZ_GET_FAST(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
s->tPos = s->tt[s->tPos]; \
|
||||
cccc = (UChar)(s->tPos & 0xff); \
|
||||
s->tPos >>= 8;
|
||||
|
||||
#define BZ_GET_FAST_C(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
|
||||
c_tPos = c_tt[c_tPos]; \
|
||||
cccc = (UChar)(c_tPos & 0xff); \
|
||||
c_tPos >>= 8;
|
||||
|
||||
#define SET_LL4(i,n) \
|
||||
{ if (((i) & 0x1) == 0) \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
|
||||
}
|
||||
|
||||
#define GET_LL4(i) \
|
||||
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
|
||||
|
||||
#define SET_LL(i,n) \
|
||||
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
|
||||
SET_LL4(i, n >> 16); \
|
||||
}
|
||||
|
||||
#define GET_LL(i) \
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
|
||||
|
||||
#ifdef BZ_NO_STDIO
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user