我有一些只有资源的dll,我想把它们转换成十六进制格式的*.cpp文件。然后从*.cpp文件中获取资源。但是,我不知道怎么做。
这里是*.cpp格式(示例格式)?
unsigned long g_XXXResourceMap[172] =
{
0x7725,0xa,0x0,0xd21,0x7726, 0xa,0xd21,0xf99,0x7727, 0xa,0x1cba,0xe15,0x7728, 0xa,0x2acf,0xd7f,
0x7729,0xa,0x384e,0xcf2,0x772a, 0xa,0x4540,0xc75,0x772b, 0xa,0x51b5,0x128a,0x772c, 0xa,0x643f,0xda1,
0x772d,0xa,0x71e0,0xf51,0x7744, 0xa,0x8131,0xda5,0x7745, 0xa,0x8ed6,0xcc2,0x7746, 0xa,0x9b98,0xe18,
};
unsigned char g_XXXResourceArray[55001] =
{
0x78,0x9c,0x1,0x16,0xd,0xe9,0xf2,0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,
0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x18,
0x8,0x6,0x0,0x0,0x0,0xe0,0x77,0x3d,0xf8,0x0,0x0,0x0,0x9,0x70,0x48,0x59,
0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,
};
看看这个,我花了几个小时来实现它。注意:代码使用c++ 11、STL和Lambda。我用Visual Studio 2010编译它。代码如下:
#include "stdafx.h"
#include "function.h"
/*
0: type
1: name
2: Lang
*/
typedef std::tuple<VARIANT, VARIANT, DWORD> resInfoTuple;
// Declare callback functions.
BOOL EnumTypesFunc(
HANDLE hModule,
LPTSTR lpType,
LONG lParam);
BOOL EnumNamesFunc(
HANDLE hModule,
LPCTSTR lpType,
LPTSTR lpName,
LONG lParam);
BOOL EnumLangsFunc(
HANDLE hModule,
LPCTSTR lpType,
LPCTSTR lpName,
WORD wLang,
LONG lParam);
void rawData2Hex(
CCodec_ModuleMgr*,
HMODULE hRes,
std::wofstream& wofs,
const wchar_t* wsInxAryName,
const wchar_t* wsDataAryName,
std::vector<resInfoTuple>& vecResInfo
);
namespace omg
{
int res2C(
const wchar_t* szFileName,
const wchar_t* wsInxAryName,
const wchar_t* wsDataAryName,
const wchar_t* outFileName
)
{
// Load the .EXE whose resources you want to list.
auto hRes = LoadLibrary(szFileName);
if (hRes == NULL)
{
// Add code to fail as securely as possible.
return -1;
}
std::wofstream wofs;
std::vector<resInfoTuple>vecResInfo;
CCodec_ModuleMgr * pCodecModuleMgr = nullptr;
CPDF_Document* pDoc = nullptr;
CPDF_Parser* pParser = nullptr;
//initialization
pCodecModuleMgr = CCodec_ModuleMgr::Create();
CFX_GEModule::Create();
CFX_GEModule::Get()->SetCodecModule(pCodecModuleMgr);
CPDF_ModuleMgr::Create();
CPDF_ModuleMgr* pModule = CPDF_ModuleMgr::Get();
if (pModule)
{
pModule->SetCodecModule(pCodecModuleMgr);
pModule->InitPageModule();
pModule->InitRenderModule();
}
auto bRes = EnumResourceTypes(hRes, // module handle
(ENUMRESTYPEPROC)EnumTypesFunc, // callback function
(LONG_PTR)&vecResInfo); // extra parameter
if(!bRes) return -1;
wofs.open(outFileName, std::ios_base::ate/* | std::ios_base::binary*/);
rawData2Hex(pCodecModuleMgr, hRes, wofs, wsInxAryName, wsDataAryName, vecResInfo);
// Unload the executable file whose resources were
// enumerated and close the file created to contain
// the resource information.
FreeLibrary(hRes);
wofs.close();
pCodecModuleMgr->Destroy();
CFX_GEModule::Destroy();
CPDF_ModuleMgr::Destroy();
return 0;
}//--end res2C
}//--end namespace::omg
// FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
// PURPOSE: Resource type callback
BOOL EnumTypesFunc(
HANDLE hModule, // module handle
LPTSTR lpType, // address of resource type
LONG lParam) // extra parameter, could be
// used for error checking
{
// Find the names of all resources of type lpType.
EnumResourceNames((HMODULE)hModule,
lpType,
(ENUMRESNAMEPROC)EnumNamesFunc,
lParam);
return TRUE;
}
// FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)
//
// PURPOSE: Resource name callback
BOOL EnumNamesFunc(
HANDLE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPTSTR lpName, // address of resource name
LONG lParam) // extra parameter, could be
// used for error checking
{
// Find the languages of all resources of type
// lpType and name lpName.
EnumResourceLanguages((HMODULE)hModule,
lpType,
lpName,
(ENUMRESLANGPROC)EnumLangsFunc,
lParam);
return TRUE;
}
// FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)
//
// PURPOSE: Resource language callback
BOOL EnumLangsFunc(
HANDLE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPCTSTR lpName, // address of resource name
WORD wLang, // resource language
LONG lParam) // extra parameter, could be
// used for error checking
{
std::vector<resInfoTuple>& vecResInfo = *(std::vector<resInfoTuple>*)lParam;
HANDLE hResInfo;
size_t cbString = 0;
hResInfo = FindResourceEx((HMODULE)hModule, lpType, lpName, wLang);
VARIANT varType = {0};
VARIANT varName = {0};
if ((ULONG)lpType & 0xFFFF0000)
{
varType.vt = VT_BSTR;
varType.bstrVal = _bstr_t(lpType);
}
else
{
varType.vt = VT_UI2;
varType.uiVal = (USHORT)lpType;
}
if ((ULONG)lpName & 0xFFFF0000)
{
varName.vt = VT_BSTR;
varName.bstrVal = _bstr_t(lpName);
}
else
{
varName.vt = VT_UI2;
varName.uiVal = (USHORT)lpName;
}
vecResInfo.push_back(std::make_tuple(varType, varName, wLang));
return TRUE;
}
void rawData2Hex(
CCodec_ModuleMgr* pCodecModuleMgr,
HMODULE hRes,
std::wofstream& wofs,
const wchar_t* wsInxAryName,
const wchar_t* wsDataAryName,
std::vector<resInfoTuple>& vecResInfo)
{
using namespace std;
unsigned __int64 offset = 0;
size_t lineFeedFlag = 1;
wstringstream wss;
wss << endl;
std::vector<FX_BYTE> vecBytes;
wss << L"unsigned long " << wsInxAryName << L"["
//<< vecResInfo.size() * 4
<< "] = " << endl << "{" << endl;
auto inxAry2Hex =
[pCodecModuleMgr, &wss, &vecBytes, &hRes, &lineFeedFlag, &offset]
(resInfoTuple& param, const wchar_t* format) mutable -> void
{
auto varType = std::get<0>(param);
auto varName = std::get<1>(param);
auto wLang = std::get<2>(param);
bool bRawData = (VT_BSTR == varType.vt);
HRSRC hResInfo = nullptr;
hResInfo = FindResourceEx((HMODULE)hRes,
bRawData ? (LPCTSTR)varType.bstrVal : (LPCTSTR)varType.uiVal,
(VT_BSTR == varName.vt) ? (LPCTSTR)varName.bstrVal : (LPCTSTR)varName.uiVal, wLang);
CString strOut;
auto srcSize = SizeofResource(hRes, hResInfo);
auto hData = LoadResource((HMODULE)hRes, hResInfo);
auto pSrcData = (unsigned char*)LockResource(hData);
FX_LPBYTE pDestBuf = nullptr;
FX_DWORD destSize = 0;
if(2 != varType.uiVal)
FlateEncode(pSrcData, srcSize, pDestBuf, destSize);
else
{
auto pBasicModule = pCodecModuleMgr->GetBasicModule();
ASSERT(nullptr != pBasicModule);
pBasicModule->RunLengthEncode(pSrcData, srcSize, pDestBuf, destSize);
}
vecBytes.insert(vecBytes.end(), pDestBuf, pDestBuf + destSize);
UnlockResource(pSrcData);
FreeResource(hData);
/*name / id, type, offset, size*/
strOut.Format(format, varName.uiVal, bRawData ? 10 : varType.uiVal, offset, destSize);
if(1 == lineFeedFlag)
wss << 't';
wss << strOut.GetBuffer();
if(0 == lineFeedFlag % 2)
{
lineFeedFlag = 1;
wss << std::endl;
}else
++lineFeedFlag;
offset += destSize;
};
if(vecResInfo.size() > 0)
{
auto& param = *vecResInfo.begin();
inxAry2Hex(param, _T("0x%08x, 0x%08x, 0x%08llx, 0x%08x"));
}
for(auto iter = vecResInfo.begin() + 1; iter != vecResInfo.end(); ++iter)
{
auto& param = *iter;
inxAry2Hex(param, _T(", 0x%08x, 0x%08x, 0x%08llx, 0x%08x"));
}//--end for each(auto& param in vecResInfo)
wss << endl << L"};" << endl << endl;
lineFeedFlag = 1;
wss << L"unsigned char " << wsDataAryName << L"["
//<< vecBytes.size()
<< "] = " << endl << "{" << endl;
if(vecBytes.size() > 0)
{
FX_BYTE param = *vecBytes.begin();
CString strOut;
strOut.Format(_T("0x%02x"), param);
wss << 't' << strOut.GetBuffer();
++lineFeedFlag;
}
for_each(vecBytes.begin() + 1, vecBytes.end(),
[lineFeedFlag, &wss](FX_BYTE param) mutable
{
CString strOut;
strOut.Format(_T(", 0x%02x"), param);
if(1 == lineFeedFlag)
wss << 't';
wss << strOut.GetBuffer();
if(0 == lineFeedFlag % 21)
{
lineFeedFlag = 1;
wss << std::endl;
}else
++lineFeedFlag;
}
);//--end for_each
wss << endl << L"};";
wofs << L"extern const size_t " << wsInxAryName << L"Cnt = "
<< vecResInfo.size() * 4 << L";" << endl;
wofs << L"extern const size_t " << wsDataAryName << L"Cnt = "
<< vecBytes.size() << L";" << endl;
wofs << wss.str();
}