diff --git a/tools/fetchdlls/fetchdlls.sln b/tools/fetchdlls/fetchdlls.sln new file mode 100644 index 00000000..e2f7107b --- /dev/null +++ b/tools/fetchdlls/fetchdlls.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fetchdlls", "fetchdlls.vcproj", "{3C1C562B-1080-445F-A632-EA9EC9793389}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3C1C562B-1080-445F-A632-EA9EC9793389}.Debug|Win32.ActiveCfg = Debug|Win32 + {3C1C562B-1080-445F-A632-EA9EC9793389}.Debug|Win32.Build.0 = Debug|Win32 + {3C1C562B-1080-445F-A632-EA9EC9793389}.Release|Win32.ActiveCfg = Release|Win32 + {3C1C562B-1080-445F-A632-EA9EC9793389}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/fetchdlls/fetchdlls.vcproj b/tools/fetchdlls/fetchdlls.vcproj new file mode 100644 index 00000000..d230be74 --- /dev/null +++ b/tools/fetchdlls/fetchdlls.vcproj @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/fetchdlls/main.cpp b/tools/fetchdlls/main.cpp new file mode 100644 index 00000000..5c52e6bf --- /dev/null +++ b/tools/fetchdlls/main.cpp @@ -0,0 +1,192 @@ +#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; +}