#include "StdAfx.h" #include "ResourceHelper.h" #include "PatchLog.h" CResourceHelper::CResourceHelper(void) : m_uiResID(0), m_uiResSize(0), m_uiResPosOffset(0), m_bInner(true) { } CResourceHelper::~CResourceHelper(void) { } CResourceHelper::CResourceHelper(unsigned int uiResID, bool bInner) : m_uiResID(0), m_uiResSize(0), m_uiResPosOffset(0), m_bInner(true) { m_uiResID = uiResID; m_bInner = bInner; } unsigned int CResourceHelper::GetResourceID() const { return m_uiResID; } unsigned int CResourceHelper::GetResourceSize() const { return m_uiResSize; } unsigned int CResourceHelper::GetResourcePosOffset() const { return m_uiResPosOffset; } bool CResourceHelper::DoUpdateResouce(string strExeFileName,string strResFileName) { if (_access_s(strExeFileName.c_str(), 4) != 0) { PATCH_MEG_REPROT("UpdateFileResouce failed, can not read file",strExeFileName); return false; } if (_access_s(strResFileName.c_str(), 4) != 0) { PATCH_MEG_REPROT("UpdateFileResouce failed, can not read file",strResFileName); return false; } if (m_bInner) { return _UpdateInnerResource(strExeFileName, strResFileName); } else { return _WriteResouce(strExeFileName, strResFileName); } } bool CResourceHelper::_WriteResouce(string strExeFileName,string strResFileName) { // 映射exe文件 [1/4/2010 hemeng] HANDLE hdResFile = CreateFile(strResFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hdResFile == INVALID_HANDLE_VALUE) { //PATCH_MEG_REPROT("Fail to open file",strResFileName); string strMsg = "Fail to open file:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } m_uiResSize = GetFileSize(hdResFile,NULL); if ( _UpdateResourceInfo(strExeFileName) == false) { CloseHandle(hdResFile); return false; } HANDLE hResFileMapping = CreateFileMapping(hdResFile, NULL, PAGE_READONLY, 0, 0, NULL); if ( NULL == hResFileMapping ) { CloseHandle(hdResFile); //PATCH_MEG_REPROT("Fail to creat file mapping", strResFileName); string strMsg = "Fail to creat file mapping:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } CloseHandle(hdResFile); PVOID pvResFile = MapViewOfFile(hResFileMapping, FILE_MAP_READ, 0,0,0); if ( NULL == pvResFile ) { CloseHandle(hResFileMapping); //PATCH_MEG_REPROT("Fail to map file", strResFileName); string strMsg = "Fail to map file:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } HANDLE hdExeFile = CreateFile(strExeFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hdExeFile) { //PATCH_MEG_REPROT("Fail to open file", strExeFileName); string strMsg = "Fail to open file:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return false; } // 设置偏移量 [1/5/2010 hemeng] DWORD dwTmp = SetFilePointer(hdExeFile, m_uiResPosOffset,0,FILE_BEGIN); if (INVALID_SET_FILE_POINTER == dwTmp) { //PATCH_MEG_REPROT("Fail to set file pointer", strExeFileName); string strMsg = "Fail to set file pointer:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); CloseHandle(hdExeFile); return false; } dwTmp = 0; if(WriteFile(hdExeFile, pvResFile, m_uiResSize, &dwTmp, NULL) == false) { //PATCH_MEG_REPROT("Fail to write resource to file", strExeFileName); string strMsg = "Fail to write resource to file:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); CloseHandle(hdExeFile); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return false; } FlushFileBuffers(hdExeFile); CloseHandle(hdExeFile); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return true; } bool CResourceHelper::_UpdateResourceInfo(string strExeFileName) { HANDLE hdExeFile = CreateFile(strExeFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hdExeFile == INVALID_HANDLE_VALUE) { //PATCH_MEG_REPROT("Fail to open file",strExeFileName); string strMsg = "Fail to open file:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } m_uiResPosOffset = GetFileSize(hdExeFile, NULL) + sizeof(CResourceHelper);/*SetFilePointer(hdExeFile, 0, NULL, FILE_END);*/ CloseHandle(hdExeFile); hdExeFile = NULL; HANDLE hUpdateRes; // update resource handle BOOL result; // Open the file to which you want to add the dialog box resource. hUpdateRes = BeginUpdateResource(strExeFileName.c_str(), FALSE); if (hUpdateRes == NULL) { string strMsg = "Fail to update resource:" + CPatchHelper::MyIntToString(m_uiResID) + "-"; //PATCH_MEG_REPROT(strMsg, strExeFileName); strMsg += strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } // Add the dialog box resource to the update list. result = UpdateResource(hUpdateRes, // update resource handle RT_RCDATA, // change dialog box resource MAKEINTRESOURCE(m_uiResID), // dialog box name 这里用PatchReleaser中的IDR_RCDATA1的ID MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), // neutral language this, // ptr to resource info sizeof(CResourceHelper)); // size of resource info. if (result == FALSE) { string strMsg = "Fail during updating resource:" + CPatchHelper::MyIntToString(m_uiResID) + "-" + strExeFileName; //PATCH_MEG_REPROT(strMsg, strExeFileName); CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } // Write changes to FOOT.EXE and then close it. if (!EndUpdateResource(hUpdateRes, FALSE)) { string strMsg = "Fail during end update resource:" + CPatchHelper::MyIntToString(m_uiResID) + "-" + strExeFileName; //PATCH_MEG_REPROT(strMsg, strExeFileName); CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } return true; } bool CResourceHelper::_UpdateInnerResource(string strExeFileName, string strResFileName) { if (strExeFileName.empty() || strResFileName.empty()) { return false; } if (_access_s(strExeFileName.c_str(), 4) != 0) { //PATCH_MEG_REPROT("UpdateFileResouce failed, can not read file",strExeFileName); string strMsg = "UpdateFileResouce failed, can not read file:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } if (_access_s(strResFileName.c_str(), 4) != 0) { //PATCH_MEG_REPROT("UpdateFileResouce failed, can not read file",strResFileName); string strMsg = "UpdateFileResouce failed, can not read file:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } // 映射exe文件 [1/4/2010 hemeng] HANDLE hdResFile = CreateFile(strResFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hdResFile == INVALID_HANDLE_VALUE) { //PATCH_MEG_REPROT("Fail to open file",strResFileName); string strMsg = "Fail to open file:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } m_uiResSize = GetFileSize(hdResFile,NULL); HANDLE hResFileMapping = CreateFileMapping(hdResFile, NULL, PAGE_READONLY, 0, 0, NULL); if ( NULL == hResFileMapping ) { CloseHandle(hdResFile); //PATCH_MEG_REPROT("Fail to creat file mapping", strResFileName); string strMsg = "Fail to creat file mapping:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } CloseHandle(hdResFile); PVOID pvResFile = MapViewOfFile(hResFileMapping, FILE_MAP_READ, 0,0,0); if ( NULL == pvResFile ) { CloseHandle(hResFileMapping); //PATCH_MEG_REPROT("Fail to map file", strResFileName); string strMsg = "Fail to map file:" + strResFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); return false; } HANDLE hUpdateRes; // update resource handle BOOL result; // Open the file to which you want to add the dialog box resource. hUpdateRes = BeginUpdateResource(strExeFileName.c_str(), FALSE); if (hUpdateRes == NULL) { //PATCH_MEG_REPROT("Fail during begin update resource.",strExeFileName); string strMsg = "Fail during begin update resource:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return false; } // Add the dialog box resource to the update list. result = UpdateResource(hUpdateRes, // update resource handle RT_RCDATA, // change dialog box resource MAKEINTRESOURCE(m_uiResID), // dialog box name 这里用PatchReleaser中的IDR_RCDATA1的ID MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), // neutral language pvResFile, // ptr to resource info m_uiResSize); // size of resource info. if (result == FALSE) { //PATCH_MEG_REPROT("Fail during updating resource.",strExeFileName); string strMsg = "Fail during updating resource:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return false; } // Write changes to FOOT.EXE and then close it. if (!EndUpdateResource(hUpdateRes, FALSE)) { //PATCH_MEG_REPROT("Fail during end update resource.",strExeFileName); string strMsg = "Fail during end update resource:" + strExeFileName; CPatchLog::GetInstance()->AddLog(PLT_ERROR, strMsg); UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return false; } UnmapViewOfFile(pvResFile); CloseHandle(hResFileMapping); return true; }