BOOL CChatPipe::CheckRevision(LPCTSTR lpszFileName1, LPCTSTR lpszFileName2, LPCTSTR lpszFileName3, LPCTSTR lpszValueString, DWORD * lpdwVersion, DWORD * lpdwChecksum, LPSTR lpExeInfoString, LPCTSTR lpszMpqFileName) { HANDLE hFile, hFileMapping; char * s, lpszFileName[256], cOperations[16]; int nHashFile, nVariable1[16], nVariable2[16], nVariable3[16], nVariable, i, k, nHashOperations; DWORD dwTotalSize, dwSize, j, dwBytesRead, dwVariables[4], dwMpqKey, * lpdwBuffer; LPSTR lpszFileNames[3]; FILETIME ft; SYSTEMTIME st; LPBYTE lpbBuffer; VS_FIXEDFILEINFO * ffi; s = strchr((char *) lpszMpqFileName, '.'); if (s == NULL) return FALSE; nHashFile = (int) (*(s - 1) - '0'); if (nHashFile > 7 || nHashFile < 0) return FALSE; dwMpqKey = dwMpqChecksumKeys[nHashFile]; lpszFileNames[0] = (LPSTR) lpszFileName1; lpszFileNames[1] = (LPSTR) lpszFileName2; lpszFileNames[2] = (LPSTR) lpszFileName3; s = (char *) lpszValueString; while (*s != '\0') { if (isalpha(*s)) nVariable = (int) (toupper(*s) - 'A'); else { nHashOperations = (int) (*s - '0'); s = strchr(s, ' '); if (s == NULL) return FALSE; s++; break; } if (*(++s) == '=') s++; dwVariables[nVariable] = atol(s); s = strchr(s, ' '); if (s == NULL) return FALSE; s++; } for (i = 0; i < nHashOperations; i++) { if (!isalpha(*s)) return FALSE; nVariable1[i] = (int) (toupper(*s) - 'A'); if (*(++s) == '=') s++; if (toupper(*s) == 'S') nVariable2[i] = 3; else nVariable2[i] = (int) (toupper(*s) - 'A'); cOperations[i] = *(++s); s++; if (toupper(*s) == 'S') nVariable3[i] = 3; else nVariable3[i] = (int) (toupper(*s) - 'A'); s = strchr(s, ' '); if (s == NULL) break; s++; } dwVariables[0] ^= dwMpqKey; for (i = 0; i < 3; i++) { if (lpszFileNames[i][0] == '\0') continue; hFile = CreateFile(lpszFileNames[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == (HANDLE) INVALID_HANDLE_VALUE) return FALSE; hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hFileMapping == NULL) { CloseHandle(hFile); return FALSE; } lpdwBuffer = (LPDWORD) MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if (lpdwBuffer == NULL) { CloseHandle(hFileMapping); CloseHandle(hFile); return FALSE; } if (i == 0) { GetFileTime(hFile, &ft, NULL, NULL); FileTimeToSystemTime(&ft, &st); dwTotalSize = GetFileSize(hFile, NULL); } dwSize = (GetFileSize(hFile, NULL) / 1024lu) * 1024lu; for (j = 0; j < (dwSize / 4lu); j++) { dwVariables[3] = lpdwBuffer[j]; for (k = 0; k < nHashOperations; k++) { switch (cOperations[k]) { case '+': dwVariables[nVariable1[k]] = dwVariables[nVariable2[k]] + dwVariables[nVariable3[k]]; break; case '-': dwVariables[nVariable1[k]] = dwVariables[nVariable2[k]] - dwVariables[nVariable3[k]]; break; case '^': dwVariables[nVariable1[k]] = dwVariables[nVariable2[k]] ^ dwVariables[nVariable3[k]]; break; default: return FALSE; } } } UnmapViewOfFile(lpdwBuffer); CloseHandle(hFileMapping); CloseHandle(hFile); } strcpy(lpszFileName, lpszFileName1); dwSize = GetFileVersionInfoSize(lpszFileName, &dwBytesRead); lpbBuffer = (LPBYTE) VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpbBuffer == NULL) return FALSE; if (GetFileVersionInfo(lpszFileName, NULL, dwSize, lpbBuffer) == FALSE) return FALSE; if (VerQueryValue(lpbBuffer, "\\", (LPVOID *) &ffi, (PUINT) &dwSize) == FALSE) return FALSE; *lpdwVersion = ((HIWORD(ffi->dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi->dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi->dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi->dwProductVersionLS) & 0xFF); VirtualFree(lpbBuffer, 0lu, MEM_RELEASE); s = (char *) &lpszFileName[strlen(lpszFileName)-1]; while (*s != '\\' && s > (char *) lpszFileName) s--; s++; sprintf(lpExeInfoString, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", s, st.wMonth, st.wDay, st.wYear % 100, st.wHour, st.wMinute, st.wSecond, dwTotalSize); *lpdwChecksum = dwVariables[2]; return TRUE; }