I made some changes to it, you don't have to say "It's noob coded", because I AM pretty noob in C++.
-More checking.
-Able to create seperate directories for each file type. (-s)
-Able to see every file being extracted. (-v)
-WD1 files get _wd1 at the end of their name.
-You can disable VOQ decoding. (-n)
Code:
#include <stdio.h>
#include <direct.h>
#include <iostream>
#include <string>
#include <io.h>
#include <sys/stat.h>
using namespace std;
void decode(unsigned char *p, int h)
{
for(int a=0;a<h;a++)
{
p[a]^=(unsigned char)194;
p[a]=(p[a]<<4)|(p[a]>>4);
}
}
int direxists (string directory)
{
if (_access( directory.c_str(), 0) == 0 )
{
struct stat status;
stat(directory.c_str(), &status);
if (status.st_mode & S_IFDIR)
{
return 1; //directory exists
}
else
{
return 2; //directory is a file
}
}
else
{
return 0; //directory doesn't exist
}
}
int main(int argc, char* argv[])
{
int filegiven = 0;
int sep = 0;
int wd1 = 0;
int decvoq = 1;
int v = 0;
for (int i = 0; i < argc; i++)
{
if (strstr(argv[i], "-s"))
{
sep = 1;
}
if (strstr(argv[i], "-n"))
{
decvoq = 0;
}
if (strstr(argv[i], "-v"))
{
v = 1;
}
if (strstr(argv[i], ".wdf"))
{
filegiven = 1;
}
else if (strstr(argv[i], ".wd1"))
{
filegiven = 1;
wd1 = 1;
}
if (strstr(argv[i], "-help"))
{
cout << "Usage: wdfextract <WDFFile> [-v] [-s] [-help]" << "\n";
cout << " <WDFFile>" << "\t\t" << "Path to WDF/WD1 file" << "\n";
cout << " -v" << "\t\t\t" << "More verbose output" << "\n";
cout << " -s" << "\t\t\t" << "Make seperate folders for each filetype" << "\n";
cout << " -help" << "\t\t\t" << "Show this message" << "\n";
cout << " -n" << "\t\t\t" << "Disable VOQ decoding" << "\n";
return 0;
}
}
if (filegiven == 0 || argc <= 1)
{
cout << "No WDF/WD1 file specified!\n\n";
cout << "Usage: wdfextract <WDFFile> [-v] [-s] [-help]" << "\n";
cout << " <WDFFile>" << "\t\t" << "Path to WDF/WD1 file" << "\n";
cout << " -v" << "\t\t\t" << "More verbose output" << "\n";
cout << " -s" << "\t\t\t" << "Make seperate folders for each filetype" << "\n";
cout << " -help" << "\t\t\t" << "Show this message" << "\n";
cout << " -n" << "\t\t\t" << "Disable VOQ decoding" << "\n";
return 1;
}
char fname[256];
FILE *f1, *f2;
char *p;
int *fsizes, *startpos;
int a,b,n,h;
string dir = ".\\";
dir += argv[1];
dir.replace(dir.size() - 4,4,"");
if (wd1 == 1)
{
dir = dir + "_wd1";
}
const char* cdir = dir.c_str();
if (direxists(cdir))
{
_rmdir(cdir);
}
_mkdir(cdir);
_chdir(cdir);
string file = "..\\";
file += argv[1];
const char* cfile = file.c_str();
fopen_s(&f1, cfile, "rb");
fseek(f1, 4, SEEK_SET);
fread(&n, 1, 4, f1); //number of files
fsizes=new int[n];
startpos=new int[n];
fread(&a, 1, 4, f1); //offset of file table
fseek(f1, a, SEEK_SET);
h=0;
for(a=0;a<n;a++)
{
fread(&b, 1, 4, f1);
fread(&startpos[a], 1, 4, f1);
fread(&fsizes[a], 1, 4, f1);
fread(&b, 1, 4, f1);
h+=fsizes[a];
}
char *guess[12]={"DAT","dds", "wav", "lnd", "voq", "tga", "bmp", "sp", "jpg", "rt", "mp3", "LND"};
int aguess[12]={0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //only needed when sep == 1
cout << "\n";
for(a=0;a<n;a++)
{
if (sep == 1 && a != 0)
{
_chdir("..\\");
}
fseek(f1, startpos[a], SEEK_SET);
fread(&b, 1, 4, f1);
switch(b)
{
case 0x20534444: b=1; break; //DDS
case 0x46464952: b=2; break; //WAVE
case 0xd736a713: b=4; break; //VOQ
case 0x00020000: b=5; break; //TGA
case 0x65636152: b=9; break; //RT
case 0xe0ffd8ff: b=8; break; //JPG
default:
if((b&0xffff)==0x4d42)b=6; //BMP
else if((b&0xffff)==0x5053)b=7; //SP
else if((b&0xffff)==0x4449)b=10; //MP3
else if((b&0xffff)==0xfbff)b=10; //MP3
else if((b&0xff)==2)b=3; //LND
else if((b&0xff)==1)b=11; //sometimes its LND, sometimes its not...
else
{
b=0;
if (v == 1) printf("unknown type %d %c\n", (int)b, b);
}
};
if (sep == 1)
{
aguess[b] = aguess[b] + 1;
sprintf_s(fname, "F%d.%s", aguess[b], guess[b]);
}
else
{
sprintf_s(fname, "F%d.%s", a, guess[b]);
}
if (v == 1)
{
cout << "Extracting: " << fname << "\n";
}
if (direxists(guess[b]) && sep == 1)
{
_rmdir(guess[b]);
}
if (sep == 1)
{
_mkdir(guess[b]);
_chdir(guess[b]);
}
fopen_s(&f2, fname, "w+b");
p=new char[fsizes[a]];
fseek(f1, startpos[a], SEEK_SET);
fread(p, 1, fsizes[a], f1);
if (decvoq == 1)
{
if(b==4)decode((unsigned char*)p, fsizes[a]);
}
fwrite(p, 1, fsizes[a], f2);
delete[] p;
fclose(f2);
}
fclose(f1);
delete[] fsizes;
delete[] startpos;
printf("%d files (%d bytes) extracted!", n, h);
return 0;
}