#include #include #include void mdmp_string(void *mdmp, RVA addr, char *buffer, size_t maxlength) { int len; MINIDUMP_STRING *str; str = (MINIDUMP_STRING *)((char *)mdmp + addr); len = WideCharToMultiByte(CP_UTF8, 0, str->Buffer, str->Length / sizeof(WCHAR), buffer, maxlength, NULL, NULL); buffer[len] = '\0'; } int find_revision(const char *version, MINIDUMP_MODULE *module, const char *name) { FILE *fp; char msg[255]; size_t i, len; char path[255]; char buffer[3000]; int last_revision; len = _snprintf(path, sizeof(path), "%s", name); for (i = 0; i < len; i++) { if (path[i] == '\\') { path[i] = '/'; } } DeleteFile("_svnlog.txt"); _snprintf(buffer, sizeof(buffer), "svn log svn://svn.alliedmods.net/svnroot/Packages/sourcemod/sourcemod-%d.%d/windows/base/addons/sourcemod/%s > _svnlog.txt", (module->VersionInfo.dwFileVersionMS >> 16), (module->VersionInfo.dwFileVersionMS & 0xFFFF), path); system(buffer); if ((fp = fopen("_svnlog.txt", "rt")) == NULL) { return -1; } _snprintf(msg, sizeof(msg), "sourcemod-%s", version); while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (buffer[0] == 'r') { last_revision = atoi(&buffer[1]); } else if (strstr(buffer, msg) != NULL) { fclose(fp); _snprintf(buffer, sizeof(buffer), "svn export -q -r %d svn://svn.alliedmods.net/svnroot/Packages/sourcemod/sourcemod-%d.%d/windows/base/addons/sourcemod/%s", last_revision, (module->VersionInfo.dwFileVersionMS >> 16), (module->VersionInfo.dwFileVersionMS & 0xFFFF), path); system(buffer); return last_revision; } } fclose(fp); return -1; } int main(int argc, char **argv) { int rev; ULONG32 m; LPVOID mdmp; HANDLE hFile; const char *name; ULONG stream_size; char name_buf[255]; HANDLE hFileMapping; MINIDUMP_MODULE *module; MINIDUMP_DIRECTORY *dir; MINIDUMP_MODULE_LIST *modules; if (argc < 3) { fprintf(stderr, "Usage: \n"); exit(-1); } if ((hFile = CreateFile(argv[2], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { fprintf(stderr, "Could not open file (error %d)\n", GetLastError()); exit(-1); } hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hFileMapping == NULL) { fprintf(stderr, "Could not open file mapping (error %d)\n", GetLastError()); CloseHandle(hFile); exit(-1); } mdmp = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if (mdmp == NULL) { fprintf(stderr, "Could not create map view (error %d)\n", GetLastError()); CloseHandle(hFileMapping); CloseHandle(hFile); exit(-1); } if (!MiniDumpReadDumpStream(mdmp, ModuleListStream, &dir, (void **)&modules, &stream_size)) { fprintf(stderr, "Could not read the module list stream.\n"); UnmapViewOfFile(mdmp); CloseHandle(hFileMapping); CloseHandle(hFile); } for (m = 0; m < modules->NumberOfModules; m++) { module = &modules->Modules[m]; mdmp_string(mdmp, module->ModuleNameRva, name_buf, sizeof(name_buf)); if ((name = strstr(name_buf, "sourcemod\\")) != NULL) { name += 10; fprintf(stdout, "looking for: %s (%d.%d.%d.%d of build %s)... ", name, (module->VersionInfo.dwFileVersionMS >> 16), (module->VersionInfo.dwFileVersionMS & 0xFFFF), (module->VersionInfo.dwFileVersionLS >> 16), (module->VersionInfo.dwFileVersionLS & 0xFFFF), argv[1] ); fflush(stdout); if ((rev = find_revision(argv[1], module, name)) == -1) { fprintf(stdout, "not found :(\n"); continue; } fprintf(stdout, "downloaded! (pkgrev %d)\n", rev); } } UnmapViewOfFile(mdmp); CloseHandle(hFileMapping); CloseHandle(hFile); return 0; }