Skip to content

Commit

Permalink
add Windows compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Talv committed Jul 22, 2019
1 parent 49021fa commit dbfde6e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 42 deletions.
11 changes: 9 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ Did you forgot to execute the following commands?
git submodule update")
endif()


if(WIN32)
set(CASC_BUILD_STATIC_LIB ON CACHE BOOL "Force Static library building to link test app")
set(CASC_BUILD_SHARED_LIB OFF CACHE BOOL "Compile dynamically linked library")
endif()
add_subdirectory(CascLib)

include_directories("${STORMEXTRACT_SOURCE_DIR}/src/"
Expand All @@ -29,7 +32,11 @@ include_directories("${STORMEXTRACT_SOURCE_DIR}/src/"
)

add_executable(stormex src/storm-extract.cpp)
target_link_libraries(stormex casc)
if(WIN32)
target_link_libraries(stormex casc_static)
else()
target_link_libraries(stormex casc)
endif()

# Set the RPATH
if (APPLE)
Expand Down
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# stormex

Command-line application to list and extract files from the [CASC](https://wowdev.wiki/CASC) (Content
Addressable Storage Container) archives used in Blizzard games.
Addressable Storage Container) used in Blizzard games.

Tested on:

Expand All @@ -10,16 +10,28 @@ Tested on:

## Building

Requires [cmake](http://www.cmake.org/) to build.
### Linux

```sh
git submodule init
git submodule update
git submodule update --init
cd build && cmake ..
make
```

The executable will be put in `build/bin/stormex`
> Executable will be put in `build/bin/stormex`
### Windows

* Requires `Visual Studio 15 2017 Build Tools`

```sh
git submodule update --init
cd build
cmake -G "Visual Studio 15 2017 Win64" ..
MSBuild STORMEXTRACT.sln /p:Configuration=Release
```

> Executable will be put in `build\bin\Release\stormex.exe`
## Usage

Expand Down
71 changes: 36 additions & 35 deletions src/storm-extract.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
#define __CASCLIB_SELF__
#include "../CascLib/src/CascLib.h"
#include "../include/SimpleOpt.h"

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unistd.h>
#include <dirent.h>

#if (defined(_WIN32) || defined(_WIN64))
#include <direct.h>
#define mkdir(name, chmod) _mkdir(name)
#endif

#if defined(WIN32) || defined(_WIN32)
#define PATH_SEP_STR "\\"
#define PATH_SEP_CHAR '\\'
#else
#define PATH_SEP_STR "/"
#define PATH_SEP_CHAR '/'
#endif

#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
Expand All @@ -17,7 +31,7 @@ using namespace std;


// All the global variables
string version = "1.3.0";
string version = "1.4.0";

struct tSearchResult {
string strFileName;
Expand Down Expand Up @@ -211,40 +225,27 @@ vector<string> searchArchive() {
}

size_t extractFile(string strFullPath) {
char buffer[0x100000]; // 1MB buffer
string strDestName = strDestination;

{
strDestName += strFullPath;

size_t offset = strDestName.find("\\");
while (offset != string::npos)
{
strDestName = strDestName.substr(0, offset) + "/" + strDestName.substr(offset + 1);
offset = strDestName.find("\\");
}
char buffer[0x1000];
string strDestName = strDestination + strFullPath;
size_t pos;

offset = strDestName.find_last_of("/");
if (offset != string::npos)
{
string dest = strDestName.substr(0, offset + 1);

size_t start = dest.find("/", 0);
while (start != string::npos)
{
string dirname = dest.substr(0, start);
// normalize slashes in the path
std::replace(strDestName.begin(), strDestName.end(), '\\', '/');

DIR* d = opendir(dirname.c_str());
if (!d)
mkdir(dirname.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
else
closedir(d);
// ensure directory path to the file exists
pos = -1;
while ((pos = strDestName.find('/', pos + 1)) != string::npos)
{
string dirname = strDestName.substr(0, pos);

start = dest.find("/", start + 1);
}
}
DIR* d = opendir(dirname.c_str());
if (!d)
mkdir(dirname.c_str(), 0755);
else
closedir(d);
}

// extract data
HANDLE hFile;
size_t fileSize = 0;
if (CascOpenFile(hStorage, strFullPath.c_str(), CASC_LOCALE_ALL, 0, &hFile))
Expand All @@ -254,7 +255,7 @@ size_t extractFile(string strFullPath) {
if (dest)
{
do {
if (CascReadFile(hFile, &buffer, 0x100000, &read)) {
if (CascReadFile(hFile, &buffer, sizeof(buffer), &read)) {
fileSize += fwrite(&buffer, read, 1, dest);
}
} while (read > 0);
Expand All @@ -264,7 +265,7 @@ size_t extractFile(string strFullPath) {
else
{
cerr << "NOFILE: (" << errno << ") Failed to extract '" << strFullPath << "' to " << strDestName << endl;
return 0;
return 0;
}
CascCloseFile(hFile);
}
Expand Down Expand Up @@ -380,8 +381,8 @@ int main(int argc, char** argv) {
int progress;
echo("Extracting files:\n");

if (strDestination.at(strDestination.size() - 1) != '/')
strDestination += "/";
if (strDestination.at(strDestination.size() - 1) != PATH_SEP_CHAR)
strDestination += PATH_SEP_STR;

vector<string>::iterator iter, iterEnd;
for (iter = results.begin(), iterEnd = results.end(); iter != iterEnd; ++iter)
Expand Down

0 comments on commit dbfde6e

Please sign in to comment.