Показать сообщение отдельно
Непрочитано 26.12.2013, 21:17   #17
Аватар для MadHacker
Пользователь

По умолчанию Re: [Мануал] Распаковка пака игры

По просьбам трудящихся, исходник представленного на скрине шела.
Код кривоват. Английский скорее всего тоже. Не стоит бездумно копировать код в свои утилиты
В таком варианте гдето память течёт при копировании большого количества файлов.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <windows.h>
 
using namespace std;
 
const char* libname = "xlpack.dll";
const char* pck_name = "game_pak";
const char* masterfs = "/master";
const char* realfs = "/fs";
 
typedef void* File;
typedef void* findstruct;
 
typedef void __cdecl (*loghandler)(const char *val, ...);
 
void __cdecl (*SetFileLogHandler)(char const* filename, loghandler lh);
void __cdecl (*CreateFileSystem)(void);
void __cdecl (*DestroyFileLogHandler)(void *);
void __cdecl (*DestroyFileSystem)(void);
void __cdecl (*CreatePak)(const char* filename, bool xz);
 
File * __cdecl(*lib_FOpen)(const char* filename, const char* filemode);
void __cdecl(*lib_FClose)(File *f);
int __cdecl(*lib_FEof)(File *f);
int __cdecl(*lib_GetC)(File *f);
 
void * __cdecl(*mount)(char const* filepath, char const* filename, bool writeble);
int __cdecl(*umount)(const char * mountpath);
int __cdecl(*copydir)(const char * from, const char * to);
int __cdecl(*copyfile)(const char * from, const char * to);
int __cdecl(*findfirst)(char const * param, findstruct st);
int __cdecl(*findnext)(int serchHandle, findstruct st);
int __cdecl(*findclose)(int serchHandle);
bool __cdecl(*IsDirectory)(findstruct st);
bool __cdecl(*IsFileExist)(const char* filename);
const char * __cdecl(*GetFileName)(findstruct st);
 
HINSTANCE xlpack;
 
string globalpath;
 
enum ConsoleColor
{
        Black         = 0,
        Blue          = 1,
        Green         = 2,
        Cyan          = 3,
        Red           = 4,
        Magenta       = 5,
        Brown         = 6,
        LightGray     = 7,
        DarkGray      = 8,
        LightBlue     = 9,
        LightGreen    = 10,
        LightCyan     = 11,
        LightRed      = 12,
        LightMagenta  = 13,
        Yellow        = 14,
        White         = 15
};
 
void SetColor(ConsoleColor text, ConsoleColor background)
{
    HANDLE hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsoleHandle, (WORD)((background << 4) | text));
}
 
void __cdecl log(const char *val, ...){
   SetColor(LightCyan, Black);
   cout << val;
        SetColor(LightGray, Black);
}
 
 
bool fillMethod(string basepath){
    string fulllibname = basepath + libname;
    cout << "load " << fulllibname << "..." << endl;
    xlpack = LoadLibrary(fulllibname.c_str());
    if (xlpack){
        cout << "lib loaded" << endl;
        CreateFileSystem = (void (__cdecl *)(void)) GetProcAddress(xlpack, "?CreateFileSystem@@YA_NXZ");
        if (NULL == CreateFileSystem) return false;
        SetFileLogHandler = (void (__cdecl *)(char const* a, loghandler b)) GetProcAddress(xlpack, "?SetFileLogHandler@@YAPAXPBDP6AX0ZZ@Z");
        if (NULL == SetFileLogHandler) return false;
 
        DestroyFileLogHandler = (void (__cdecl *)(void *)) GetProcAddress(xlpack, "?DestroyFileLogHandler@@YAXPAX@Z");
        if (NULL == DestroyFileLogHandler) return false;
        DestroyFileSystem = (void (__cdecl *)(void)) GetProcAddress(xlpack, "?DestroyFileSystem@@YAXXZ");
        if (NULL == DestroyFileSystem) return false;
 
        CreatePak = (void (__cdecl *)(const char* filename, bool readonly)) GetProcAddress(xlpack, "?CreatePak@@YA_NPBD_N@Z");
        if (NULL == CreatePak) return false;
        mount = (void * (__cdecl *)(char const* filename, char const* filepath, bool mode)) GetProcAddress(xlpack, "?Mount@@YAPAXPBD0_N@Z");
        if (NULL == mount) return false;
        umount = (int (__cdecl *)(const char * mp)) GetProcAddress(xlpack, "?Unmount@@YA_NPBD@Z");
        if (NULL == umount) return false;
 
        copydir = (int (__cdecl *)(const char * filename, const char * filepath)) GetProcAddress(xlpack, "?CopyDir@@YA_NPBD0@Z");
        if (NULL == copydir) return false;
        copyfile = (int (__cdecl *)(const char * filename, const char * filepath)) GetProcAddress(xlpack, "?Copy@@YA_NPBD0@Z");
        if (NULL == copyfile) return false;
 
        lib_FOpen = (File * (__cdecl*)(const char* filename, const char* filemode)) GetProcAddress(xlpack, "?FOpen@@YAPAUFile@@PBD0@Z");
        if (NULL == lib_FOpen) return false;
        lib_FClose = (void (__cdecl *)(File * f)) GetProcAddress(xlpack, "?FClose@@YAXAAPAUFile@@@Z");
        if (NULL == lib_FClose) return false;
        lib_FEof = (int (__cdecl *)(File * f)) GetProcAddress(xlpack, "?FEof@@YAHPAUFile@@@Z");
        if (NULL == lib_FEof) return false;
        lib_GetC = (int (__cdecl *)(File * f)) GetProcAddress(xlpack, "?Getc@@YAHPAUFile@@@Z");
        if (NULL == lib_GetC) return false;
 
        findfirst = (int (__cdecl *)(char const * param, findstruct st)) GetProcAddress(xlpack, "?FindFirst@@YAHPBDPAUafs_finddata@@@Z");
        if (NULL == findfirst) return false;
        findnext = (int (__cdecl *)(int serchHandle, findstruct st)) GetProcAddress(xlpack, "?FindNext@@YAHHPAUafs_finddata@@@Z");
        if (NULL == findnext) return false;
        findclose = (int (__cdecl *)(int serchHandle)) GetProcAddress(xlpack, "?FindClose@@YAHH@Z");
        if (NULL == findclose) return false;
 
        IsDirectory = (bool (__cdecl *)(findstruct st)) GetProcAddress(xlpack, "?IsDirectory@@YA_NPBUafs_finddata@@@Z");
        if (NULL == IsDirectory) return false;
        IsFileExist = (bool (__cdecl *)(const char * filename)) GetProcAddress(xlpack, "?IsFileExist@@YA_NPBD@Z");
        if (NULL == IsFileExist) return false;
        GetFileName = (const char * (__cdecl *)(findstruct st)) GetProcAddress(xlpack, "?GetFileName@@YAPBDPBUafs_finddata@@@Z");
        if (NULL == GetFileName) return false;
 
        CreateFileSystem();
        string logfile = basepath + libname + ".log";
        SetFileLogHandler(logfile.c_str(), &log);
 
        return true;
    }
    return false;
}
 
void freelib()
{
    DestroyFileLogHandler(NULL);
    DestroyFileSystem();
    cout << "unload lib ..." << endl;
    FreeLibrary(xlpack);
    cout << "end" << endl;
}
 
findstruct makefs(){
    char *buf = new char[100];
    for (int i = 0; i < 100; ++i) buf[i] = 0;
    return buf;
}
 
void freefs(findstruct fs){
    delete[] fs;
}
 
void createPCK(string base){
 
    string full_pck_name = base + pck_name;
    cout << "Create pck" << endl;
    CreatePak(full_pck_name.c_str(), true);
 
    cout << "mount fs" << endl;
    void * ret = mount("/master", full_pck_name.c_str(), true);
    ret = mount("/origin", base.c_str(), true);
 
    cout << "copy to fs" << endl;
    int iret = copydir( "/origin/pck_tool", "/master/pcktoo");
    if (iret) cout << "copy ok" << endl;
 
    cout << "umount" << endl;
    int umret = umount("/master");
    if (umret) cout << "umount ok" << endl;
 
}
 
bool mountBase(string base){
    string full_pck_name = base + pck_name;
 
    cout << "mount " << base << " to " << realfs << endl;
    void * ret = mount(realfs, base.c_str(), true);
    if (NULL == ret) return false;
 
    cout << "readonly mount " << full_pck_name << " to " << masterfs << endl;
    ret = mount(masterfs, full_pck_name.c_str(), false);
    if (NULL == ret){
        SetColor(LightRed, Black);
        cout << "Bad pck file " << full_pck_name << endl;
        SetColor(LightGray, Black);
        return false;
    }
 
    return true;
}
void umountBase(){
    umount(masterfs);
    umount(realfs);
}
 
vector<string> &split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}
 
vector<string> split(const string &s, char delim) {
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}
 
string extractFilePath(const string base){
    if (base.compare("/") == 0) return base;
    unsigned found = base.find_last_of("/\\");
    return base.substr(0, found + 1);
}
string extractFileDir(const string base){
    if (base.compare("/") == 0) return base;
    unsigned found = base.find_last_of("/\\");
    return base.substr(0, found);
}
 
 
string absolutePath(const string path){
    if (path.size() == 0) return globalpath;
    if (path.at(0) == '/' || path.at(0) == '\\') return path;
    if (path.size() == 1 && path.at(0) == '.') return globalpath;
    string base, relative;
    base = extractFileDir(globalpath);
    relative = path;
    while (relative.substr(0,2).compare("..") == 0){
        base = extractFileDir(base);
        if (relative.size() < 3) relative = "";
        else relative = relative.substr(3, relative.size() - 3);
    }
    return base + "/" + relative;
}
 
void cd(string path){
    globalpath = absolutePath(path);
    if (globalpath.at(globalpath.size() - 1) != '/' && globalpath.at(globalpath.size() - 1) != '\\') globalpath += '/';
}
 
void ls(string path){
    if (path.compare("/") == 0)
    {
        SetColor(LightBlue, Black);
        cout << masterfs << " " << realfs << endl;
        SetColor(LightGray, Black);
        return;
    }
    path = absolutePath(path);// + "*";
    cout << path << endl;
    if (path.at(path.size() - 1) == '/') path += "*";
    findstruct fs = makefs();
    int findhandle = findfirst(path.c_str(), fs);
    if (findhandle != -1){
        int find;
        do{
           if (IsDirectory(fs)) SetColor(LightBlue, Black);
            else SetColor(White, Black);
            cout << GetFileName(fs) << " ";
           find = findnext(findhandle, fs);
        }while(find != -1);
        findclose(findhandle);
    } else cout << "empty";
    cout << endl;
    SetColor(LightGray, Black);
    freefs(fs);
}
 
void checkPath(string absolutePath, bool &exist, bool &dir){
 
 
    exist = IsFileExist(absolutePath.c_str());
    if (exist){
        dir = false;
        return;
    }
    findstruct fs = makefs();
    int findhandle = findfirst(absolutePath.c_str(), fs);
    exist = (findhandle != -1);
    dir = exist; // не сработает для пустых каталогов.
    findclose(findhandle);
    freefs(fs);
}
 
void cp(string src, string dest){
    src = absolutePath(src);
    dest = absolutePath(dest);
 
    SetColor(White, Black);
    bool isExist = false, isDir = false;
    checkPath(src, isExist, isDir);
 
    if (!isExist){
        cout << "bad source path: " << src << endl;
        SetColor(LightGray, Black);
        return;
    }
    if (isDir){
        cout << "copy catalog " << src << " to " << dest << endl;
        copydir(src.c_str(), dest.c_str());
    }else{
        cout << "copy file " << src << " to " << dest << endl;
        copyfile(src.c_str(), dest.c_str());
    }
 
    SetColor(LightGray, Black);
}
 
void cat(string path){
    path = absolutePath(path);
    bool isExist, isDir;
    checkPath(path, isExist, isDir);
 
    SetColor(White, Black);
    if (!isExist){
        cout << "bad path" << endl;
        SetColor(LightGray, Black);
        return;
    }
    if (isDir){
        cout << "directory" << endl;
        SetColor(LightGray, Black);
        return;
    }
 
    File *f = lib_FOpen(path.c_str(), "r");
    while (!lib_FEof(f)){
        cout << (char) lib_GetC(f);
    }
    cout <<endl;
    SetColor(LightGray, Black);
}
 
void help(){
    cout << "Arhe age game arhive shell" << endl;
    SetColor(White, Black);
    cout << "\thelp\t";
    SetColor(LightGray, Black);
    cout << "show this message" << endl;
    SetColor(White, Black);
    cout << "\tls <path>\t";
    SetColor(LightGray, Black);
    cout << "show file list" << endl;
    SetColor(White, Black);
    cout << "\tcd path\t";
    SetColor(LightGray, Black);
    cout << "change catalog" << endl;
    SetColor(White, Black);
    cout << "\tcp src dest\t";
    SetColor(LightGray, Black);
    cout << "copy file or catalog. Destination only /fs/" << endl;
    SetColor(White, Black);
    cout << "\tq\t";
    SetColor(LightGray, Black);
    cout << "exit" << endl;
}
 
void parsecmd(const string &cmd){
    std::vector<std::string> x;
    split(cmd, ' ', x);
    if (x.size() >= 1){
        if (x.at(0).compare("help") == 0) help();
        if (x.at(0).compare("ls") == 0){
           if (x.size() >= 2) ls(x.at(1));
            else ls(globalpath);
        }
        if (x.at(0).compare("cd") == 0 && (x.size() >= 2)) cd(x.at(1));
        if (x.at(0).compare("cp") == 0 ){
            if (x.size() == 3) cp(x.at(1), x.at(2));
            else {
                SetColor(White, Black);
                cout << "usage: cp source destination \ndestination only in " << realfs << endl;
                SetColor(LightGray, Black);
            }
        }
        if (x.at(0).compare("cat") == 0 && (x.size() >= 2)) cat(x.at(1));
 
    }
 
}
 
int main(int argc, char** argv)
{
    globalpath = string(masterfs) + "/";
    string workdir = extractFilePath(string(argv[0]));
 
 
    if (fillMethod(workdir)){
        //createPCK(workdir);
        if (mountBase(workdir)){
            help();
            string cmd;
            for (;;){
                cout << globalpath << " :> ";
                getline(cin, cmd);
                if (cmd.compare("q") == 0) break;
                parsecmd(cmd);
            }
            umountBase();
        }
 
        freelib();
    }
 
    return 0;
}
 
Code: C++
MadHacker вне форума Ответить с цитированием
Сказали спасибо: