//检查文件尾部的CRC校验码 bool checkCRCFlag(const char* szFileName) { //计算文件crc unsigned int nCRC; if(!crcFile32(szFileName, nCRC, true)) return false; //打开文件 HANDLE hFile = ::CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN, 0); if(hFile == INVALID_HANDLE_VALUE) { setLastError(AXP_ERR_FILE_ACCESS, "File=%s, WinErr=%d", szFileName, ::GetLastError()); return false; } //Get File Size unsigned int nFileSize = ::GetFileSize(hFile, 0); //size must >= 4 if(nFileSize < 4) { CloseHandle(hFile); return false; } //move to end if(INVALID_SET_FILE_POINTER == ::SetFilePointer(hFile, -4, 0, FILE_END)) { setLastError(AXP_ERR_FILE_POINT, "File=%s, WinErr=%d", szFileName, ::GetLastError()); CloseHandle(hFile); return false; } unsigned int nCRCRead; //Read Head DWORD dwReadBytes; if(!ReadFile(hFile, &nCRCRead, sizeof(nCRCRead), &dwReadBytes, 0) || dwReadBytes != sizeof(nCRCRead)) { setLastError(AXP_ERR_FILE_READ, "WinErr=%d", ::GetLastError()); CloseHandle(hFile); return false; } CloseHandle(hFile); hFile=0; return nCRCRead == nCRC; }
//在文件尾部附上crc校验码 bool attachCRCFlag(const char* szFileName) { assert(szFileName); if(!szFileName || szFileName[0] == 0) { setLastError(AXP_ERR_PARAM); return 0; } //计算文件校验码 unsigned int nCRC; if(!crcFile32(szFileName, nCRC)) return false; //打开该文件 HANDLE hFile = ::CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN, 0); if(hFile == INVALID_HANDLE_VALUE) { setLastError(AXP_ERR_FILE_ACCESS, "File=%s, WinErr=%d", szFileName, ::GetLastError()); return false; } //move to end if(INVALID_SET_FILE_POINTER == ::SetFilePointer(hFile, 0, 0, FILE_END)) { setLastError(AXP_ERR_FILE_POINT, "File=%s, WinErr=%d", szFileName, ::GetLastError()); CloseHandle(hFile); return false; } //write crc DWORD dwBytesWrite; if(!WriteFile(hFile, &nCRC, sizeof(nCRC), &dwBytesWrite, 0) || dwBytesWrite != sizeof(nCRC)) { setLastError(AXP_ERR_FILE_WRITE, "winErr: %d", GetLastError()); CloseHandle(hFile); return false; } CloseHandle(hFile); hFile=0; return true; }
//检测一个文件的crc校验码 bool Updater::crcFile(const char* szFilename, unsigned int &dwCrc32, bool bIgnoreTail) { return crcFile32(szFilename, dwCrc32, bIgnoreTail); }
//将加入的文件保存成pak文件, bool PakMaker::savePakFile(const char* szPakFileName, AXP_PAKMAKER_SAVECALLBACK callbackFunc) { assert(szPakFileName); if(!szPakFileName || szPakFileName[0]==0) { setLastError(AXP_ERR_PARAM); return false; } //Pak文件 PackFile pakFile; if(!pakFile.createNewPakFile(szPakFileName)) return false; //最终文件数 int nActFileCount = 0; //最终文件crc unsigned int nTotalCRC = 0xFFFFFFFF; //加入文件 FileNodeBuf::iterator it; for(it=m_AllFiles.begin(); it!=m_AllFiles.end(); it++) { FileNode& file = it->second; char szTempFileName[1024] = {0}; if(callbackFunc) { //调用Callback if(!callbackFunc(file.strFileInDisk.c_str(), file.strFileInPak.c_str(), szTempFileName, 1024)) { //从列表中删除 file.bExcute = true; continue; } } else { strncpy(szTempFileName, file.strFileInDisk.c_str(), 1024); } file.strFileInDisk = szTempFileName; if(!crcFile32(szTempFileName, file.nCRC)) return false; file.nFileSize = getDiskFileSize(szTempFileName); if(!pakFile.insertContents(szTempFileName, 0, file.strFileInPak.c_str(), AC_DISKFILE, false)) { return false; } nActFileCount++; nTotalCRC ^= file.nCRC; } //生成(list)文件 std::string strListFile; if(!_genrateListFile(strListFile, nActFileCount, nTotalCRC)) return false; //加入(list)文件 if(!pakFile.insertContents(strListFile.c_str(), 0, PackFile::LIST_FILENAME, AC_DISKFILE, false)) { return false; } //删除临时的temp文件 ::DeleteFile(strListFile.c_str()); pakFile.closePakFile(); return true; }