#include "StdAfx.h" #include "PatchHelper.h" #include #include "PatchDef.h" CPatchHelper::CPatchHelper(void) { } CPatchHelper::~CPatchHelper(void) { } string CPatchHelper::GetCurrWorkDir() { char pTemp[MAX_PATH]; GetModuleFileName(NULL,pTemp,MAX_PATH); if (NULL == pTemp) { return ""; } string strConfigFilePath = string(pTemp); strConfigFilePath = strConfigFilePath.substr(0,strConfigFilePath.find_last_of("\\")); strConfigFilePath += "\\"; return strConfigFilePath; } bool CPatchHelper::StringToBYTE(string str, BYTE* pBuffer, UINT nBufferSize) { if (str.empty()) { return false; } if (NULL == pBuffer) { return false; } if (nBufferSize <= str.size()) { return false; } for (unsigned int uiIndex = 0; uiIndex < str.size(); uiIndex++) { pBuffer[uiIndex] = (BYTE)str[uiIndex]; } return true; } bool CPatchHelper::DeleteVectorElem(vector& vec,string strInfo) { vector::iterator it = vec.begin(); bool bSuccess = false; for (vector::size_type i = 0;it != vec.end(); it++, i++) { if (vec[i] == strInfo) { bSuccess = true; break; } } if (bSuccess) { vec.erase(it); } return bSuccess; } DWORD CPatchHelper::MyStringToDWORD(string str) { DWORD num; stringstream sstr; sstr << str; sstr >> num; sstr.clear(); return num; } string CPatchHelper::MyIntToString(int num) { string str = ""; stringstream sstr; sstr << num; sstr >> str; sstr.clear(); return str; } int CPatchHelper::CompareVersion(string strSrcVer,string strDesVer) { // version 0.XXXX.X [8/13/2009 hemeng] string strSrcBranch = strSrcVer.substr(0,strSrcVer.find(".")); string strDesBranch = strDesVer.substr(0,strDesVer.find(".")); DWORD iSrcBranch = MyStringToDWORD(strSrcBranch); DWORD iDesBranch = MyStringToDWORD(strDesBranch); if (iSrcBranch > iDesBranch) { return 1; } else if (iSrcBranch < iDesBranch) { return -1; } // [8/13/2009 hemeng] string strHigh = strSrcVer.substr(strSrcVer.find(".") + 1,strSrcVer.find_last_of(".")); string strLow = strSrcVer.substr(strSrcVer.find_last_of(".") + 1); if (strHigh.empty() || strLow.empty()) { return -2; } DWORD iSrcHigh = MyStringToDWORD(strHigh); DWORD iSrcLow = MyStringToDWORD(strLow); strHigh = strDesVer.substr(strDesVer.find(".") + 1,strDesVer.find_last_of(".")); strLow = strDesVer.substr(strDesVer.find_last_of(".") + 1); if (strHigh.empty() || strLow.empty()) { return -2; } DWORD iDesHigh = MyStringToDWORD(strHigh); DWORD iDesLow = MyStringToDWORD(strLow); // 比较 [8/13/2009 hemeng] if (iSrcHigh > iDesHigh) { return 1; } else if (iSrcHigh < iDesHigh) { return -1; } else if (iSrcHigh == iDesHigh) { if (iSrcLow > iDesLow) { return 1; } else if (iSrcLow < iDesLow) { return -1; } else if (iSrcLow == iDesLow) { return 0; } } return -2; } string CPatchHelper::LoadVersionFromPatchClient(string strPatchClientFileName) { if (strPatchClientFileName.empty()) { return ""; } StringLower(strPatchClientFileName); if (_access_s(strPatchClientFileName.c_str(),0) != 0) { //PATCH_MEG_REPROT("Fail to find current version file",strPatchClientFileName.c_str()); return ""; } TiXmlDocument* pXmlDoc = new TiXmlDocument(); pXmlDoc->LoadFile(strPatchClientFileName.c_str()); TiXmlElement* pElmtRoot = pXmlDoc->RootElement(); TiXmlElement* pElmt = pElmtRoot->FirstChildElement(); if (NULL == pElmt) { return ""; } string strResult; const char* pszName = pElmt->Value(); if (strcmp(pszName, "ClientVersion") == 0) { strResult = pElmt->Attribute("Version"); } delete pXmlDoc; pXmlDoc = NULL; return strResult; } string CPatchHelper::GetVersion(string strFilePath,SPatchVersionRule sRule,string strPatchClientPath) { if (strFilePath.empty()) { return ""; } HANDLE hdFile = CreateFile(strFilePath.c_str(), GENERIC_READ , 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hdFile == INVALID_HANDLE_VALUE) { return ""; } HANDLE hdFileMap = CreateFileMapping(hdFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hdFileMap == NULL) { CloseHandle(hdFile); return ""; } CloseHandle(hdFile); PVOID pvSrcFile = MapViewOfFile(hdFileMap, FILE_MAP_READ, 0, 0, 0); if (NULL == pvSrcFile) { CloseHandle(hdFileMap); return ""; } string strVersion = (string)(char*)pvSrcFile; UnmapViewOfFile(pvSrcFile); CloseHandle(hdFileMap); string strBranch = strVersion.substr(strVersion.find(CLIENT_VERSION_LOG)); strBranch = strBranch.substr(0,strBranch.find(CLIENT_VERSION_SUB_SGIN)); StringLower(strBranch); // 首先找到MUX [8/24/2009 hemeng] strVersion = strVersion.substr(strVersion.find(CLIENT_VERSION_LOG) + string(CLIENT_VERSION_LOG).length()); // 从MUX后查找_ [8/24/2009 hemeng] strVersion = strVersion.substr(strVersion.find(CLIENT_VERSION_SUB_SGIN) + string(CLIENT_VERSION_SUB_SGIN).length()); strVersion = strVersion.substr(0,CLIENT_VERSIN_LENGTH); string strBranchNum = ""; map::iterator it = sRule.mapBranch.find(strBranch); if (it == sRule.mapBranch.end()) { return ""; } int iResult = 0; string strResult = ""; string strNewDate = strVersion.substr(0,strVersion.find(".")); int iTotalDays = _SubDate(strNewDate,sRule.strCmpDate); if (iTotalDays < 0) { return ""; } // 如果当前时间是新的版本比较基准时间,则版本号从旧的patchclient中直接读取 [11/18/2009 hemeng] else if (iTotalDays == 0) { strResult = LoadVersionFromPatchClient(strPatchClientPath); } else { // Build times [9/17/2009 hemeng] strVersion = strVersion.substr(strVersion.find_last_of(".") + 1); int iBuildTimes = (int)MyStringToDWORD(strVersion); iResult = iTotalDays << 2; iResult += iBuildTimes; strResult = sRule.strVerPre + "." + MyIntToString(iResult); } return strResult; } bool CPatchHelper::LoadVersionRule(TiXmlElement* pElmt, SPatchVersionRule& sRule) { if (NULL == pElmt) { return false; } TiXmlElement* pChildElmt = pElmt->FirstChildElement(); if (NULL == pChildElmt) { return false; } while(pChildElmt != NULL) { const char* pszName = pChildElmt->Value(); if (strcmp(pszName,"CompareData") == 0) { sRule.strCmpDate = pChildElmt->Attribute("StandarData"); } else if (strcmp(pszName,"Rule") == 0) { // 处理版本号 [9/2/2009 hemeng] string strBranch = pChildElmt->Attribute("Branch"); StringLower(strBranch); string strNum = pChildElmt->Attribute("Num"); StringLower(strNum); if (strBranch == "" || strNum == "") { return false; } map::iterator it = sRule.mapBranch.find(strBranch); if (it == sRule.mapBranch.end()) { sRule.mapBranch.insert(pair(strBranch,strNum)); } else { it->second = strNum; } } else if (strcmp(pszName,"VersionPre") == 0) { sRule.strVerPre = pChildElmt->Attribute("VerPrefix"); } pChildElmt = pChildElmt->NextSiblingElement(); } return true; } int CPatchHelper::_SubDate(string strSrcDate,string strDesDate) { if (strSrcDate.empty() || strDesDate.empty()) { return -1; } int iSrcYear = (int)MyStringToDWORD(strSrcDate.substr(0,4)); int iDesYear = (int)MyStringToDWORD(strDesDate.substr(0,4)); int iSrcMonth = (int)MyStringToDWORD(strSrcDate.substr(4,2)); int iDesMonth = (int)MyStringToDWORD(strDesDate.substr(4,2)); int iSrcDate = (int)MyStringToDWORD(strSrcDate.substr(6,2)); int iDesDate = (int)MyStringToDWORD(strDesDate.substr(6,2)); COleDateTime tStartDate; COleDateTime tEndDate; tStartDate.SetDate(iSrcYear,iSrcMonth,iSrcDate); tEndDate.SetDate(iDesYear,iDesMonth,iDesDate); COleDateTimeSpan tTotalDay = tStartDate - tEndDate; int iResult = (int)tTotalDay.GetTotalDays(); return iResult; } void CPatchHelper::StringLower(string& str ) { if (str.empty()) { return; } for ( UINT uiIndex = 0; uiIndex < str.size(); uiIndex++ ) { str[uiIndex] = tolower( str[uiIndex] ); } } bool CPatchHelper::IsRoot(string szPath ) { if (szPath.empty()) { return false; } string Root; Root = szPath.at(0); Root += ":\\"; if ( Root== szPath ) { return true; } else { return false; } } bool CPatchHelper::VerifyFile(string strFileName) { if (strFileName.empty()) { return false; } if (_access_s(strFileName.c_str(),0) != 0) { return false; } DWORD dwAttr = GetFileAttributes(strFileName.c_str()); if (dwAttr == FILE_ATTRIBUTE_READONLY) { dwAttr = SetFileAttributes(strFileName.c_str(),FILE_ATTRIBUTE_NORMAL); if (dwAttr == 0) { return false; } } return true; } char* CPatchHelper::GetFileVersion(string strFileName) { string strCurWorkDir = GetCurrWorkDir(); if (strCurWorkDir.empty()) { return NULL; } string strTmpFilePath = strCurWorkDir + strFileName.substr(strFileName.find_last_of("\\") + 1); // 由于远程路径不支持,所以拷贝至工作目录在比较 [12/16/2009 hemeng] bool bSuccess = (bool)CopyFile(strFileName.c_str(),strTmpFilePath.c_str(),FALSE); if (!bSuccess) { return NULL; } // 如果未找到版本号信息则认为不相同 [12/15/2009 hemeng] DWORD dwFileVersionSize = GetFileVersionInfoSize(strTmpFilePath.c_str(),0); if (dwFileVersionSize == 0) { DeleteFile(strTmpFilePath.c_str()); return NULL; } BYTE* pSrcVersionData = new BYTE[dwFileVersionSize]; memset(pSrcVersionData , 0x0, dwFileVersionSize); if (!GetFileVersionInfo(strTmpFilePath.c_str(),0,dwFileVersionSize,(void*)pSrcVersionData)) { delete [] pSrcVersionData; pSrcVersionData = NULL; DeleteFile(strTmpFilePath.c_str()); return NULL; } // 删除临时拷贝文件 [12/16/2009 hemeng] DeleteFile(strTmpFilePath.c_str()); // 解析版本号 [1/11/2010 hemeng] LPVOID lpBuf = NULL; UINT dwVersionLen = 0; if (!VerQueryValue(pSrcVersionData, "\\", &lpBuf, &dwVersionLen)) { delete [] pSrcVersionData; pSrcVersionData = NULL; DeleteFile(strTmpFilePath.c_str()); return NULL; } VS_FIXEDFILEINFO* pVerInfo = reinterpret_cast(lpBuf); USHORT usVer1, usVer2, usVer3, usVer4; usVer2 = HIWORD(pVerInfo->dwProductVersionMS); usVer1 = LOWORD(pVerInfo->dwProductVersionMS); usVer3 = HIWORD(pVerInfo->dwProductVersionLS); usVer4 = LOWORD(pVerInfo->dwProductVersionLS); char* szBuf = new char[MAX_PATH]; sprintf_s(szBuf,MAX_PATH, "%d.%d.%d.%d", usVer2, usVer1, usVer3, usVer4); return szBuf; }