// incorporate.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "assert.h"
#include "stdio.h"
#include<windows.h>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
#include "jtzCompress.h"
#include "jtcCompress.h"
static bool checkContext(const char * fileName, const char * szCheck);
static bool checkIfDataHasStr(const char * fileName, const char * szCheck, Byte * pData, UInt32 nFileLen);
//单字节、双字节互转
static char * wstrTostr(const wchar_t * lpcwszStr){
DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);
char *psText = NULL;
psText = new char[dwNum*sizeof(char)];
if(!psText)
{
delete(psText);
psText = NULL;
return psText;
}
WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);
return psText;
}
static wchar_t * strToWstr(const char * lpcwszStr){
DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, NULL, 0);
wchar_t *psText = NULL;
psText = new wchar_t[dwNum];;
if(!psText)
{
delete(psText);
psText = NULL;
return psText;
}
MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, psText, dwNum);
return psText;
}
ostream & green(ostream & s)
{
HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hstdhadle, FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}
ostream & white(ostream & s)
{
HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hstdhadle, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
return s;
}
class CFile{
private:
fstream m_fout;
public:
CFile(){
m_fout.open("out.txt", ios::out | ios::binary);
}
//检查要测试文件的路径
void checkFolder(const char* lpPath, const char * szCheck, bool bNeedCheckAllFile){
assert(lpPath);
char szFind[1024];
char szFile[1024];
WIN32_FIND_DATA FindFileData;
strcpy_s(szFind,lpPath);
strcat_s(szFind,"*.*");
wchar_t * wszFind = strToWstr(szFind);
HANDLE hFind=FindFirstFile(wszFind,&FindFileData);
delete wszFind;
if (INVALID_HANDLE_VALUE == hFind)
return;
bool bHasFileFinded = false;//如果有文件已经找到匹配了,不用全部文件遍历
while(true)
{
if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
if (FindFileData.cFileName[0]!='.')
{
strcpy_s(szFile,lpPath);
char * pFileName = wstrTostr(FindFileData.cFileName);
strcat_s(szFile,pFileName);
strcat_s(szFile,"\\");
delete pFileName;
checkFolder(szFile, szCheck, bNeedCheckAllFile);
}
}
else if(bHasFileFinded == false || bNeedCheckAllFile == true)
{
char * pFileName = wstrTostr(FindFileData.cFileName);
char pFilePath[1024] = {0};
strcpy_s(pFilePath,lpPath);
strcat_s(pFilePath,pFileName);
bHasFileFinded = checkContext(pFilePath, szCheck);
delete pFileName;
}
if (!FindNextFile(hFind,&FindFileData))
break;
}
FindClose(hFind);
}
bool checkContext(const char * fileName, const char * szCheck)
{
fstream fin;
bool bRet = false;
if(ifFileTypeEqual(fileName, "jtz"))
{
Byte* fileContext = NULL;
UInt32 nFileLen = 0;
wchar_t * pFileName = strToWstr(fileName);
fin.open(pFileName, ios::in | ios::binary);//防止有中文名
fin.seekg(0, ios::end);
nFileLen = fin.tellg();
fileContext = new Byte[nFileLen];
fin.seekg(0, ios::beg);
fin.read((char*)fileContext, nFileLen);
fin.close();
Byte* unzipMem = NULL;
UInt32 unzipSize = 0;
Unzip(&unzipMem, &unzipSize, fileContext, nFileLen);
delete fileContext;
//检测
bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
delete unzipMem;
delete pFileName;
return bRet;
}
if(ifFileTypeEqual(fileName, "jtc"))
{
Byte* unzipMem = NULL;
UInt32 unzipSize = 0;
CJtcCompress * jtcInstance = new CJtcCompress(fileName);
unzipMem = jtcInstance->Decode(unzipSize);
delete jtcInstance;
wchar_t * pFileName = strToWstr(fileName);
//检测
bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
delete unzipMem;
delete pFileName;
return bRet;
}
//其他文件格式,直接用strstr即可
if(ifFileTypeEqual(fileName, "ini")
|| ifFileTypeEqual(fileName, "cfg")
|| ifFileTypeEqual(fileName, "txt")
|| ifFileTypeEqual(fileName, "mod"))
{
Byte* unzipMem = NULL;
UInt32 unzipSize = 0;
wchar_t * pFileName = strToWstr(fileName);
fin.open(pFileName, ios::in | ios::binary);//防止有中文名
assert(fin);
fin.seekg(0, ios::end);
unzipSize = fin.tellg();
unzipMem = new Byte[unzipSize];
fin.seekg(0, ios::beg);
fin.read((char*)unzipMem, unzipSize);
fin.close();
//检测
bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
delete unzipMem;
delete pFileName;
return bRet;
}
if(ifFileTypeEqual(fileName, "bar"))
{
char copyLocalCmd[512];
char delLocalCmd[512];
char brewrcCmd[512];
const wchar_t * wszBarName = L"demo.bar";
const wchar_t * wszBrxName = L"demo.brx";
const char * szBarName = "demo.bar";
wchar_t * pFileName = strToWstr(fileName);
copyFileToOtherPath(pFileName, wszBarName);
sprintf_s(brewrcCmd, 512, "brewrc.exe -d %s > 1.txt", szBarName);
system(brewrcCmd);//执行Brew反解析工具
DeleteFile(wszBarName);
Byte* unzipMem = NULL;
UInt32 unzipSize = 0;
fin.open(wszBrxName, ios::in | ios::binary);//防止有中文名
fin.seekg(0, ios::end);
unzipSize = fin.tellg();
unzipMem = new Byte[unzipSize];
fin.seekg(0, ios::beg);
fin.read((char*)unzipMem, unzipSize);
fin.close();
//检测
bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
delete unzipMem;
delete pFileName;
return bRet;
}
return bRet;
}
//判定文件后缀是否匹配
bool ifFileTypeEqual(const char * fullName, const char * szCompare){
assert(fullName && szCompare);
bool bRet = false;
string * str = new string(fullName);
int nLen = str->find_last_of('.');
if (nLen <= 0)
bRet = false;
else
{
const char * sz = fullName + nLen + 1;
if(strcmp(sz, szCompare) == 0)
bRet = true;
}
delete str;
return bRet;
}
//判定文件后缀是否匹配
const char * getBrxName(const char * fullName){
assert(fullName);
char * szRet = NULL;
string * str = new string(fullName);
int nLen = str->find_last_of('.');
if (nLen > 0)
{
szRet = strdup(fullName);
nLen++;
szRet[nLen] = 'b';
nLen++;
szRet[nLen] = 'r';
nLen++;
szRet[nLen] = 'x';
}
delete str;
return szRet;
}
void copyFileToOtherPath(const wchar_t * wszSrc, const wchar_t * wszDes)
{
assert(wszDes && wszSrc);
fstream fin, fout;
fin.open(wszSrc, ios::in | ios::binary);
if(fin.is_open())
{
Byte * buf = NULL;
UInt32 nFileLen = 0;
fin.seekg(0, ios::end);
nFileLen = fin.tellg();
buf = new Byte[nFileLen];
fin.seekg(0, ios::beg);
fin.read((char *)buf, nFileLen);
fin.close();
fout.open(wszDes, ios::out | ios::binary);
if (fout.is_open())
{
fout.write((char *)buf, nFileLen);
fout.close();
}
}
}
bool checkIfDataHasStr(const char * fileName, const char * szCheck, Byte * pData, UInt32 nFileLen)
{
assert(pData && fileName && szCheck);
bool bRet = false;
UInt32 nCheckLen = strlen(szCheck);
UInt32 nCheckOffest = 0;
UInt32 nOffest = 0;
while (nOffest < nFileLen){
while(nOffest < nFileLen && pData[nOffest++] == szCheck[nCheckOffest++])
{
if(nCheckOffest == nCheckLen)
{
const char * c_file = "文件:";
const char * c_have = " 有 ";
const char * c_changeline = "\r\n";
m_fout.write(c_file, strlen(c_file));
m_fout.write(fileName, strlen(fileName));
m_fout.write(c_have, strlen(c_have));
m_fout.write(szCheck, strlen(szCheck));
m_fout.write(c_changeline, strlen(c_changeline));
return true;
}
}
nCheckOffest = 0;
}
cout << white << "检测文件:" << green << fileName << white << endl;
return bRet;
}
~CFile(){
if(m_fout)
m_fout.close();
}
};
int main(int argc, char* argv[]/* f */)
{
//说明
if(argc >= 2 && strcmp(argv[1], "/?") == 0)
{
cout << "参数1:要检查的目录,以‘/’结束,如“Res/”" << endl;
cout << "参数2:要检查的字符串" << endl;
cout << "参数3(Y/N):是否检测到一个文件存在要查字符串,就不再查这个目录下的其他文件" << endl;
cout << "目前会查的文件有:bar、jtz、jtc、mod、cfg、ini、txt" << endl;
return 0;
}
CFile * pFile = new CFile();
if(argc > 3)
{
if (toupper(*argv[3]) == 'Y')
pFile->checkFolder(argv[1], argv[2], true);
else
pFile->checkFolder(argv[1], argv[2], false);
}
else
pFile->checkFolder("res\\", "base_url", false);
delete pFile;
getchar();
return 0;
}