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;
+}