summaryrefslogtreecommitdiff
path: root/plugins/CrashDumper/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-17 06:57:55 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-17 06:57:55 +0000
commit1ca120b165c2f2d9f521a04bfc31c7956d2ce422 (patch)
treef56c88f1ffdb865612a3d1e05f047c17deed68ab /plugins/CrashDumper/src
parenteb146b049b43c6fb09e6f8c7716c1bbc88bf2159 (diff)
ContactsPlus, CountryFlags, CrashDumper: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1000 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/CrashDumper/src')
-rw-r--r--plugins/CrashDumper/src/bkstring.cpp188
-rw-r--r--plugins/CrashDumper/src/bkstring.h278
-rw-r--r--plugins/CrashDumper/src/crshdmp.cpp434
-rw-r--r--plugins/CrashDumper/src/crshdmp_icons.cpp88
-rw-r--r--plugins/CrashDumper/src/dumper.cpp745
-rw-r--r--plugins/CrashDumper/src/exhndlr.cpp207
-rw-r--r--plugins/CrashDumper/src/resource.h34
-rw-r--r--plugins/CrashDumper/src/sdkstuff.h124
-rw-r--r--plugins/CrashDumper/src/ui.cpp327
-rw-r--r--plugins/CrashDumper/src/upload.cpp292
-rw-r--r--plugins/CrashDumper/src/utils.cpp836
-rw-r--r--plugins/CrashDumper/src/utils.h177
-rw-r--r--plugins/CrashDumper/src/vc6/dbghelp.h4532
-rw-r--r--plugins/CrashDumper/src/vc6/dbghelp.libbin0 -> 48054 bytes
-rw-r--r--plugins/CrashDumper/src/version.h3
15 files changed, 8265 insertions, 0 deletions
diff --git a/plugins/CrashDumper/src/bkstring.cpp b/plugins/CrashDumper/src/bkstring.cpp
new file mode 100644
index 0000000000..418cb0bd83
--- /dev/null
+++ b/plugins/CrashDumper/src/bkstring.cpp
@@ -0,0 +1,188 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "bkstring.h"
+
+bkstring::~bkstring() { if (sizeAlloced) free(buf); }
+
+
+void bkstring::reserve(size_type len)
+{
+ if (len >= sizeAlloced || sizeAlloced == 0)
+ {
+ if (sizeAlloced == 0) buf = NULL;
+ buf = (value_type*)realloc(buf, (len+1) * sizeof(value_type));
+ if (sizeAlloced == 0) buf[0] = 0;
+ sizeAlloced = len+1;
+ }
+}
+
+void bkstring::appendfmt(const value_type *fmt, ...)
+{
+ areserve(_tcslen(fmt)*2);
+
+ va_list vararg;
+ va_start(vararg, fmt);
+ for (;;)
+ {
+ int len = _vsntprintf(buf + lenBuf, sizeAlloced - lenBuf - 1, fmt, vararg);
+ if (len < 0)
+ reserve(sizeAlloced + 256);
+ else
+ {
+ lenBuf += len;
+ buf[lenBuf] = 0;
+ break;
+ }
+ }
+ va_end(vararg);
+}
+
+bkstring& bkstring::append(const value_type* _Ptr)
+{
+ size_type len = _tcslen(_Ptr);
+ areserve(len);
+ memcpy(buf+lenBuf, _Ptr, (len+1)*sizeof(value_type));
+ lenBuf += len;
+ return *this;
+}
+
+bkstring& bkstring::append(const value_type* _Ptr, size_type _Count)
+{
+ size_type len = min(_tcslen(_Ptr), _Count);
+ areserve(len);
+ memcpy(buf+lenBuf, _Ptr, len*sizeof(value_type));
+ lenBuf += len;
+ buf[lenBuf] = 0;
+ return *this;
+}
+
+bkstring& bkstring::append(const bkstring& _Str, size_type _Off, size_type _Count)
+{
+ size_type len = min(_Count, _Str.size() - _Off);
+ areserve(len);
+ memcpy(buf+lenBuf, _Str.c_str()+_Off, len*sizeof(value_type));
+ lenBuf += len;
+ buf[lenBuf] = 0;
+ return *this;
+}
+
+bkstring& bkstring::append(const bkstring& _Str)
+{
+ size_type len = _Str.size();
+ areserve(len);
+ memcpy(buf+lenBuf, _Str.c_str(), len*sizeof(value_type));
+ lenBuf += len;
+ buf[lenBuf] = 0;
+ return *this;
+}
+
+bkstring& bkstring::append(size_type _Count, value_type _Ch)
+{
+ areserve(_Count);
+ for(size_type i=0; i<_Count; ++i) buf[lenBuf+i] = _Ch;
+ lenBuf += _Count;
+ buf[lenBuf] = 0;
+ return *this;
+}
+
+
+bkstring& bkstring::assign(const value_type* _Ptr, size_type _Count)
+{
+ reserve(_Count);
+ memcpy(buf, _Ptr, _Count*sizeof(value_type));
+ buf[_Count] = 0;
+ lenBuf = _Count;
+ return *this;
+}
+
+bkstring& bkstring::assign(const bkstring& _Str, size_type _Off, size_type _Count)
+{
+ size_type len = min(_Count, _Str.size() - _Off);
+ reserve(len);
+ memcpy(buf, _Str.c_str() + _Off, len*sizeof(value_type));
+ lenBuf = len;
+ buf[len] = 0;
+ return *this;
+}
+
+bkstring& bkstring::assign(size_type _Count, value_type _Ch)
+{
+ reserve(_Count);
+ for(size_type i=0; i<_Count; ++i) buf[i] = _Ch;
+ buf[_Count] = 0;
+ lenBuf = _Count;
+ return *this;
+}
+
+bkstring::size_type bkstring::find(value_type _Ch, size_type _Off) const
+{
+ for (size_type i=_Off; i<=lenBuf; ++i)
+ if (buf[i] == _Ch) return i;
+ return (size_type)npos;
+}
+
+bkstring::size_type bkstring::find(const value_type* _Ptr, size_type _Off) const
+{
+ if (_Off > lenBuf) return (size_type)npos;
+
+ value_type* pstr = _tcsstr(buf+_Off, _Ptr);
+ return pstr ? pstr - buf : npos;
+}
+
+bkstring::size_type bkstring::find_last_of(value_type _Ch, size_type _Off) const
+{
+ for (size_type i=(_Off == npos ? lenBuf : _Off); i--;)
+ if (buf[i] == _Ch) return i;
+ return (size_type)npos;
+}
+
+bkstring& bkstring::insert(size_type _P0, const value_type* _Ptr, size_type _Count)
+{
+ size_type len = _tcslen(_Ptr);
+ if (_Count < len) len = _Count;
+ areserve(len);
+ value_type *p = buf + _P0;
+ memmove(p+len, p, (lenBuf-_P0+1)*sizeof(value_type));
+ memcpy(p, _Ptr, _Count*sizeof(value_type));
+ lenBuf += len;
+ return *this;
+}
+
+bkstring& bkstring::insert(size_type _P0, size_type _Count, value_type _Ch)
+{
+ areserve(_Count);
+ value_type *p = buf + _P0;
+ memmove(p+_Count, p, (lenBuf-_P0+1)*sizeof(value_type));
+ for(size_type i=0; i<_Count; ++i) p[i] = _Ch;
+ lenBuf += _Count;
+ return *this;
+}
+
+bkstring& bkstring::erase(size_type _Pos, size_type _Count)
+{
+ if (_Pos < lenBuf)
+ {
+ const size_type len = min(lenBuf - _Pos, _Count);
+ value_type *p = buf + _Pos;
+ lenBuf -= len;
+ memmove(p, p+len, (lenBuf - _Pos)*sizeof(value_type));
+ buf[lenBuf] = 0;
+ }
+ return *this;
+}
diff --git a/plugins/CrashDumper/src/bkstring.h b/plugins/CrashDumper/src/bkstring.h
new file mode 100644
index 0000000000..88cb3bdfc4
--- /dev/null
+++ b/plugins/CrashDumper/src/bkstring.h
@@ -0,0 +1,278 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#ifndef _BKSTRING_H_
+#define _BKSTRING_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <tchar.h>
+
+#ifndef min
+#define min(A, B) ((A) < (B) ? (A) : (B))
+#endif
+
+class bkstring
+{
+public:
+ typedef size_t size_type;
+ typedef TCHAR value_type;
+ typedef value_type* iterator;
+ typedef const value_type* const_iterator;
+
+#if defined(_MSC_VER) && _MSC_VER > 1200
+ static const size_type npos = size_type(-1);
+#else
+ enum { npos = -1 };
+#endif
+
+private:
+ value_type* buf;
+ size_type sizeAlloced;
+ size_type lenBuf;
+
+ void areserve(size_type len) { reserve(lenBuf + len); }
+
+public:
+
+ explicit bkstring() : buf((TCHAR*)_T("")), sizeAlloced(0), lenBuf(0)
+ {}
+
+ bkstring(const value_type* _Ptr, size_type _Count) : sizeAlloced(0), lenBuf(0)
+ { assign(_Ptr, _Count); }
+
+ bkstring(const value_type* _Ptr) : sizeAlloced(0), lenBuf(0)
+ { assign(_Ptr); }
+
+ bkstring(size_type _Count, value_type _Ch) : sizeAlloced(0), lenBuf(0)
+ { assign(_Count, _Ch); }
+
+ bkstring(const bkstring& _Str) : sizeAlloced(0), lenBuf(0)
+ { assign(_Str); }
+
+ bkstring(const bkstring& _Str, size_type _Off, size_type _Count) : sizeAlloced(0), lenBuf(0)
+ { assign(_Str, _Off, _Count); }
+
+ ~bkstring();
+
+ size_type size(void) const { return lenBuf; }
+ const value_type* c_str(void) const { return buf; }
+
+ void clear(void) { if (lenBuf) { lenBuf = 0; buf[0] = 0; } }
+ void insert(const value_type *txt);
+ void reserve(size_type len);
+
+ bkstring& assign(const value_type* _Ptr)
+ { return assign(_Ptr, _tcslen(_Ptr)); }
+
+ bkstring& assign(const bkstring& _Str)
+ { return assign(_Str, 0, (size_type)npos); }
+
+ bkstring& assign(const value_type* _Ptr, size_type _Count);
+ bkstring& assign(const bkstring& _Str, size_type off, size_type _Count);
+ bkstring& assign(size_type _Count, value_type _Ch);
+
+ bkstring& append(const value_type* _Ptr);
+ bkstring& append(const value_type* _Ptr, size_type _Count);
+ bkstring& append(const bkstring& _Str, size_type _Off, size_type _Count);
+ bkstring& append(const bkstring& _Str);
+ bkstring& append(size_type _Count, value_type _Ch);
+
+ int compare(const bkstring& _Str) const
+ { return _tcscmp(buf, _Str.c_str()); }
+
+ int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str) const
+ { return _tcsncmp(&buf[_Pos1], _Str.c_str(), _Num1); }
+
+ int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const
+ { return _tcsncmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); }
+
+ int compare(const value_type* _Ptr) const
+ { return _tcscmp(buf, _Ptr); }
+
+ int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const
+ { return _tcsncmp(&buf[_Pos1], _Ptr, _Num1); }
+
+ int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const
+ { return _tcsncmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); }
+
+ int comparei(const bkstring& _Str) const
+ { return _tcsicmp(buf, _Str.c_str()); }
+
+ int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str) const
+ { return _tcsnicmp(&buf[_Pos1], _Str.c_str(), _Num1); }
+
+ int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const
+ { return _tcsnicmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); }
+
+ int comparei(const value_type* _Ptr) const
+ { return _tcsicmp(buf, _Ptr); }
+
+ int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const
+ { return _tcsnicmp(&buf[_Pos1], _Ptr, _Num1); }
+
+ int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const
+ { return _tcsnicmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); }
+
+ bool empty(void) const { return lenBuf == 0; };
+ bkstring& erase(size_type _Pos = 0, size_type _Count = npos);
+
+ size_type find(value_type _Ch, size_type _Off = 0) const;
+ size_type find(const value_type* _Ptr, size_type _Off = 0) const;
+ size_type find(bkstring& _Str, size_type _Off = 0) const
+ { return find(_Str.c_str(), _Off); }
+
+ size_type find_last_of(value_type _Ch, size_type _Off = npos) const;
+
+ bkstring& insert(size_type _P0, const value_type* _Ptr)
+ { return insert(_P0, _Ptr, _tcslen(_Ptr)); }
+
+ bkstring& insert(size_type _P0, const bkstring& _Str)
+ { return insert(_P0, _Str.c_str(), _Str.size()); };
+
+ bkstring& insert(size_type _P0, const value_type* _Ptr, size_type _Count);
+ bkstring& insert(size_type _P0, size_type _Count, value_type _Ch);
+
+ bkstring substr(size_type _Off = 0, size_type _Count = npos) const
+ { return bkstring(*this, _Off, _Count); }
+
+ bkstring& operator = (const bkstring& _Str)
+ { return assign(_Str); }
+
+ bkstring& operator =(const value_type* _Ptr)
+ { return assign(_Ptr); }
+
+ bkstring& operator = (const value_type _Ch)
+ { return assign(1, _Ch); }
+
+ bkstring& operator +=(const bkstring& _Str)
+ { return append(_Str); }
+
+ bkstring& operator += (const value_type* _Ptr)
+ { return append(_Ptr); }
+
+ bkstring& operator += (const value_type _Ch)
+ { return append(1, _Ch); }
+
+ value_type& operator[] (int ind) const
+ { return buf[ind]; }
+
+ friend bkstring operator+ (const bkstring& _Str1, const bkstring& _Str2)
+ { bkstring s(_Str1); return s.append(_Str2); }
+
+ friend bkstring operator+ (const bkstring& _Str1, const value_type* _Ptr2)
+ { bkstring s(_Str1); return s.append(_Ptr2); }
+
+ friend bkstring operator+(const value_type* _Ptr1, const bkstring& _Str2)
+ { bkstring s(_Ptr1); return s.append(_Str2); }
+
+ friend bkstring operator+ (const bkstring& _Str1, const value_type _Ch)
+ { bkstring s(_Str1); return s.append(1, _Ch); }
+
+ friend bool operator==(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) == 0; }
+
+ friend bool operator==(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) == 0; }
+
+ friend bool operator==(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) == 0; }
+
+ friend bool operator!=(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) != 0; }
+
+ friend bool operator!=(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) != 0; }
+
+ friend bool operator!=(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) != 0; }
+
+ friend bool operator<(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) < 0; }
+
+ friend bool operator<(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) < 0; }
+
+ friend bool operator<(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) > 0; }
+
+ friend bool operator>(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) > 0; }
+
+ friend bool operator>(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) > 0; }
+
+ friend bool operator>(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) < 0; }
+
+ friend bool operator<=(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) <= 0; }
+
+ friend bool operator<=(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) <= 0; }
+
+ friend bool operator<=(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) >= 0; }
+
+ friend bool operator>=(const bkstring& _Str1, const bkstring& _Str2)
+ { return _Str1.compare(_Str2) >= 0; }
+
+ friend bool operator>=(const bkstring& _Str1, const value_type* _Ptr2)
+ { return _Str1.compare(_Ptr2) >= 0; }
+
+ friend bool operator>=(const value_type* _Ptr1, const bkstring& _Str2)
+ { return _Str2.compare(_Ptr1) <= 0; }
+
+ friend bool operator==(const value_type _Ch1, const bkstring& _Str2)
+ { return (_Str2.size() == 1) && (_Str2[0] == _Ch1); }
+
+ friend bool operator==(const bkstring& _Str1, const value_type _Ch2)
+ { return (_Str1.size() == 1) && (_Str1[0] == _Ch2); }
+
+ friend bool operator!=(const value_type _Ch1, const bkstring& _Str2)
+ { return (_Str2.size() != 1) || (_Str2[0] != _Ch1); }
+
+ friend bool operator!=(const bkstring& _Str1, const value_type _Ch2)
+ { return (_Str1.size() != 1) || (_Str1[0] != _Ch2); }
+
+ iterator begin(void)
+ { return buf; }
+
+ const_iterator begin(void) const
+ { return buf; }
+
+ iterator end(void)
+ { return buf + lenBuf; }
+
+ const_iterator end(void) const
+ { return buf + lenBuf; }
+
+ // Custom extentions
+
+ void appendfmt(const value_type *fmt, ...);
+
+ size_type sizebytes(void) const { return lenBuf * sizeof(value_type); }
+};
+
+//const bkstring::size_type bkstring::npos = -1;
+
+#endif
diff --git a/plugins/CrashDumper/src/crshdmp.cpp b/plugins/CrashDumper/src/crshdmp.cpp
new file mode 100644
index 0000000000..72ffac7f44
--- /dev/null
+++ b/plugins/CrashDumper/src/crshdmp.cpp
@@ -0,0 +1,434 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <m_options.h>
+#include "m_folders.h"
+#include "m_toptoolbar.h"
+#include "version.h"
+
+int hLangpack;
+
+HINSTANCE hInst;
+DWORD mirandaVersion;
+LCID packlcid;
+HANDLE hCrashLogFolder, hVerInfoFolder;
+HMODULE hRichModule;
+
+TCHAR* vertxt;
+TCHAR* profname;
+TCHAR* profpath;
+
+TCHAR CrashLogFolder[MAX_PATH];
+TCHAR VersionInfoFolder[MAX_PATH];
+
+bool servicemode;
+bool clsdates;
+bool dtsubfldr;
+
+static const PLUGININFOEX pluginInfoEx =
+{
+ sizeof(PLUGININFOEX),
+ "Crash Dumper",
+ __VERSION_DWORD,
+ "Crash Dumper for Miranda IM.",
+ "borkra",
+ "borkra@miranda-im.org",
+ "Copyright© 2008 - 2012 Boris Krasnovskiy All Rights Reserved",
+ "http://code.google.com/p/mirandaimplugins/downloads/list",
+ UNICODE_AWARE,
+ // {F62C1D7A-FFA4-4065-A251-4C9DD9101CC8}
+ { 0xf62c1d7a, 0xffa4, 0x4065, { 0xa2, 0x51, 0x4c, 0x9d, 0xd9, 0x10, 0x1c, 0xc8 } }
+};
+
+const PLUGININFOEX* GetPluginInfoEx(void) { return &pluginInfoEx; }
+
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion)
+{
+ ::mirandaVersion = mirVersion;
+ return (PLUGININFOEX*)&pluginInfoEx;
+}
+
+#define MIID_CRASHDUMP { 0x36a31a50, 0xcb55, 0x46d0, { 0xab, 0x9c, 0x1e, 0xac, 0xfb, 0x24, 0x0, 0x2a } }
+
+// MirandaInterfaces - returns the protocol interface to the core
+extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SERVICEMODE, MIID_CRASHDUMP, MIID_LAST };
+
+HANDLE hHooks[5];
+HANDLE hServices[6];
+
+
+INT_PTR StoreVersionInfoToFile(WPARAM, LPARAM lParam)
+{
+ CreateDirectoryTree(VersionInfoFolder);
+
+ TCHAR path[MAX_PATH];
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder);
+
+ HANDLE hDumpFile = CreateFile(path, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hDumpFile != INVALID_HANDLE_VALUE)
+ {
+ bkstring buffer;
+
+ buffer.reserve(0x1800);
+ PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR);
+
+ char* bufu = mir_utf8encodeT(buffer.c_str());
+ WriteUtfFile(hDumpFile, bufu);
+ mir_free(bufu);
+
+ CloseHandle(hDumpFile);
+
+ ShowMessage(3, TranslateT("VersionInfo stored into file %s"), path);
+ }
+ else
+ ShowMessage(2, TranslateT("VersionInfo file %s is inaccessible"), path);
+
+ return 0;
+}
+
+INT_PTR StoreVersionInfoToClipboard(WPARAM, LPARAM lParam)
+{
+ bkstring buffer;
+ buffer.reserve(0x1800);
+
+ WriteBBFile(buffer, true);
+ PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR | VI_FLAG_FORMAT);
+ WriteBBFile(buffer, false);
+
+ StoreStringToClip(buffer);
+
+ return 0;
+}
+
+INT_PTR UploadVersionInfo(WPARAM, LPARAM lParam)
+{
+ bkstring buffer;
+ buffer.reserve(0x1800);
+ PrintVersionInfo(buffer);
+
+ VerTrnsfr *trn = (VerTrnsfr*)mir_alloc(sizeof(VerTrnsfr));
+ trn->buf = mir_utf8encodeT(buffer.c_str());
+ trn->autot = lParam == 0xa1;
+
+ mir_forkthread(VersionInfoUploadThread, trn);
+
+ return 0;
+}
+
+
+INT_PTR ViewVersionInfo(WPARAM wParam, LPARAM)
+{
+ // unsigned *p = (unsigned*)0x15;
+ // *p = 324;
+
+ if (hRichModule == NULL && GetModuleHandle(TEXT("Riched20.dll")) == NULL)
+ hRichModule = LoadLibrary(TEXT("Riched20.dll"));
+
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_VIEWVERSION), NULL,
+ DlgProcView, wParam ? (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL) : VI_FLAG_PRNVAR);
+
+ return 0;
+}
+
+INT_PTR OpenUrl(WPARAM wParam, LPARAM)
+{
+ switch (wParam)
+ {
+ case 0:
+ ShellExecute(NULL, TEXT("explore"), CrashLogFolder, NULL, NULL, SW_SHOW);
+ break;
+
+ case 1:
+ OpenAuthUrl("http://%s.miranda-vi.org");
+ break;
+ }
+ return 0;
+}
+
+INT_PTR ServiceModeLaunch(WPARAM, LPARAM)
+{
+ servicemode = true;
+ return 0;
+}
+
+
+static int FoldersPathChanged(WPARAM, LPARAM)
+{
+ FOLDERSGETDATA fgd = {0};
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = MAX_PATH;
+ fgd.szPathT = CrashLogFolder;
+ CallService(MS_FOLDERS_GET_PATH, (WPARAM) hCrashLogFolder, (LPARAM) &fgd);
+
+ fgd.szPathT = VersionInfoFolder;
+ CallService(MS_FOLDERS_GET_PATH, (WPARAM) hVerInfoFolder, (LPARAM) &fgd);
+ return 0;
+}
+
+int OptionsInit(WPARAM wParam, LPARAM)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof(odp);
+ odp.position = -790000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.pszTitle = (char*)PluginName;
+ odp.pszGroup = LPGEN("Services");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcOptions;
+ Options_AddPage(wParam, &odp);
+
+ return 0;
+}
+
+static int ToolbarModulesLoaded(WPARAM, LPARAM)
+{
+ TTBButton tbb = {0};
+ tbb.cbSize = sizeof(TTBButton);
+
+ tbb.pszService = MS_CRASHDUMPER_STORETOCLIP;
+ tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To Clipboard");
+ tbb.hIconHandleUp = GetIconHandle("storeToClip");
+ tbb.dwFlags = TTBBF_VISIBLE;
+ TopToolbar_AddButton(&tbb);
+
+ tbb.pszService = MS_CRASHDUMPER_STORETOFILE;
+ tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To File");
+ tbb.hIconHandleUp = GetIconHandle("storeToFile");
+ tbb.dwFlags = 0;
+ TopToolbar_AddButton(&tbb);
+
+ tbb.pszService = MS_CRASHDUMPER_VIEWINFO;
+ tbb.name = tbb.pszTooltipUp = LPGEN("Show Version Information");
+ tbb.hIconHandleUp = GetIconHandle("showInfo");
+ TopToolbar_AddButton(&tbb);
+
+ tbb.pszService = MS_CRASHDUMPER_UPLOAD;
+ tbb.name = tbb.pszTooltipUp = LPGEN("Upload Version Information");
+ tbb.hIconHandleUp = GetIconHandle("uploadInfo");
+ TopToolbar_AddButton(&tbb);
+ return 0;
+}
+
+static int ModulesLoaded(WPARAM, LPARAM)
+{
+ char temp[MAX_PATH];
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)SIZEOF(temp), (LPARAM)temp);
+ crs_a2t(vertxt, temp);
+
+ profname = Utils_ReplaceVarsT(_T("%miranda_profilename%.dat"));
+ if (ServiceExists(MS_FOLDERS_REGISTER_PATH))
+ {
+ profpath = _T("%miranda_userdata%");
+ }
+ else
+ {
+ profpath = Utils_ReplaceVarsT(_T("%miranda_userdata%"));
+ }
+
+ crs_sntprintf(CrashLogFolder, MAX_PATH, TEXT("%s\\CrashLog"), profpath);
+ crs_sntprintf(VersionInfoFolder, MAX_PATH, TEXT("%s"), profpath);
+
+ SetExceptionHandler();
+
+ hCrashLogFolder = FoldersRegisterCustomPathT(PluginName, "Crash Reports", CrashLogFolder);
+ hVerInfoFolder = FoldersRegisterCustomPathT(PluginName, "Version Information", VersionInfoFolder);
+
+ FoldersPathChanged(0, 0);
+
+
+
+ hHooks[2] = HookEvent(ME_FOLDERS_PATH_CHANGED, FoldersPathChanged);
+ if (hHooks[3] == NULL) hHooks[3] = HookEvent(ME_TTB_MODULELOADED, ToolbarModulesLoaded);
+
+ UploadInit();
+
+ CLISTMENUITEM mi = { 0 };
+
+ mi.cbSize = sizeof(mi);
+
+ mi.popupPosition = 2000089999;
+ mi.position = 2000089999;
+ mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR;
+ mi.icolibItem = GetIconHandle("versionInfo");
+ mi.ptszName = LPGENT("Version Information");
+ mi.pszPopupName = (char *)-1;
+ HANDLE hMenuRoot = Menu_AddMainMenuItem(&mi);
+
+ mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR;
+ mi.pszPopupName = (char *)hMenuRoot;
+ mi.popupPosition = 0;
+
+ mi.position = 2000089995;
+ mi.ptszName = LPGENT("Copy to clipboard");
+ mi.icolibItem = GetIconHandle("storeToClip");
+ mi.pszService = MS_CRASHDUMPER_STORETOCLIP;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.position = 2000089996;
+ mi.ptszName = LPGENT("Store to file");
+ mi.icolibItem = GetIconHandle("storeToFile");
+ mi.pszService = MS_CRASHDUMPER_STORETOFILE;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.position = 2000089997;
+ mi.ptszName = LPGENT("Show");
+ mi.icolibItem = GetIconHandle("showInfo");
+ mi.pszService = MS_CRASHDUMPER_VIEWINFO;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.popupPosition = 1;
+ mi.position = 2000089998;
+ mi.ptszName = LPGENT("Show with DLLs");
+ mi.icolibItem = GetIconHandle("showInfo");
+ mi.pszService = MS_CRASHDUMPER_VIEWINFO;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.popupPosition = 0;
+ mi.position = 2000089999;
+ mi.ptszName = LPGENT("Upload");
+ mi.icolibItem = GetIconHandle("uploadInfo");
+ mi.pszService = MS_CRASHDUMPER_UPLOAD;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.position = 2000099990;
+ mi.ptszName = LPGENT("Open crash report directory");
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_FILE);
+ mi.pszService = MS_CRASHDUMPER_URL;
+ Menu_AddMainMenuItem(&mi);
+
+ mi.popupPosition = 1;
+ mi.position = 2000099991;
+ mi.ptszName = LPGENT("Open miranda-vi.org");
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_URL);
+ mi.pszService = MS_CRASHDUMPER_URL;
+ Menu_AddMainMenuItem(&mi);
+
+ HOTKEYDESC hk = {0};
+ hk.cbSize = sizeof(hk);
+ hk.pszSection = PluginName;
+
+ hk.pszDescription = LPGEN("Copy Version Info to clipboard");
+ hk.pszName = "CopyVerInfo";
+ hk.pszService = MS_CRASHDUMPER_STORETOCLIP;
+ Hotkey_Register(&hk);
+
+ hk.pszDescription = LPGEN("Show Version Info");
+ hk.pszName = "ShowVerInfo";
+ hk.pszService = MS_CRASHDUMPER_VIEWINFO;
+ Hotkey_Register(&hk);
+
+ if (servicemode) ViewVersionInfo(0, 0);
+ else
+ {
+ if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0) && !ProcessVIHash(false))
+ UploadVersionInfo(0, 0xa1);
+ }
+
+ CheckForOtherCrashReportingPlugins();
+ return 0;
+}
+
+static int PreShutdown(WPARAM, LPARAM)
+{
+ unsigned i;
+
+ DestroyAllWindows();
+ UploadClose();
+
+ for (i=0; i<SIZEOF(hHooks); ++i)
+ UnhookEvent(hHooks[i]);
+
+ for (i=0; i<SIZEOF(hServices); ++i)
+ DestroyServiceFunction(hServices[i]);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+
+
+ clsdates = DBGetContactSettingByte(NULL, PluginName, "ClassicDates", 1) != 0;
+
+ dtsubfldr = DBGetContactSettingByte(NULL, PluginName, "SubFolders", 1) != 0;
+ mir_getLP(&pluginInfoEx);
+
+ hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ hHooks[1] = HookEvent(ME_OPT_INITIALISE, OptionsInit);
+ hHooks[3] = HookEvent(ME_TTB_MODULELOADED, ToolbarModulesLoaded);
+ hHooks[4] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+
+ packlcid = (LCID)CallService(MS_LANGPACK_GETLOCALE, 0, 0);
+
+ InitIcons();
+
+ InitExceptionHandler();
+
+ hServices[0] = CreateServiceFunction(MS_CRASHDUMPER_STORETOFILE, StoreVersionInfoToFile);
+ hServices[1] = CreateServiceFunction(MS_CRASHDUMPER_STORETOCLIP, StoreVersionInfoToClipboard);
+ hServices[2] = CreateServiceFunction(MS_CRASHDUMPER_VIEWINFO, ViewVersionInfo);
+ hServices[3] = CreateServiceFunction(MS_CRASHDUMPER_UPLOAD, UploadVersionInfo);
+ hServices[4] = CreateServiceFunction(MS_CRASHDUMPER_URL, OpenUrl);
+ hServices[5] = CreateServiceFunction(MS_SERVICEMODE_LAUNCH, ServiceModeLaunch);
+
+ // unsigned *p = (unsigned*)0x15;
+ // *p = 324;
+
+ return 0;
+}
+
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ DestroyAllWindows();
+ FreeLibrary(hRichModule);
+
+ DestroyExceptionHandler();
+
+ if (!_tcsstr(profpath, _T("%miranda")))
+ {
+ mir_free(profpath);
+ }
+ mir_free(profname);
+ mir_free(vertxt);
+
+ return 0;
+}
+
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ hInst = hinstDLL;
+ break;
+
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/plugins/CrashDumper/src/crshdmp_icons.cpp b/plugins/CrashDumper/src/crshdmp_icons.cpp
new file mode 100644
index 0000000000..1f7106303f
--- /dev/null
+++ b/plugins/CrashDumper/src/crshdmp_icons.cpp
@@ -0,0 +1,88 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <m_icolib.h>
+
+struct _tag_iconList
+{
+ const char* szDescr;
+ const char* szName;
+ int defIconID;
+}
+static const iconList[] =
+{
+ { "Version Information", "versionInfo", IDI_VI },
+ { "Copy To Clipboard", "storeToClip", IDI_VITOCLIP },
+ { "Store to file", "storeToFile", IDI_VITOFILE },
+ { "Show", "showInfo", IDI_VISHOW },
+ { "Upload", "uploadInfo", IDI_VIUPLOAD },
+};
+
+static HANDLE hIconLibItem[SIZEOF(iconList)];
+
+void InitIcons(void)
+{
+ char szFile[MAX_PATH];
+ char szSettingName[100];
+ SKINICONDESC sid = {0};
+
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.pszDefaultFile = szFile;
+ sid.pszName = szSettingName;
+ sid.pszSection = (char*)PluginName;
+
+ GetModuleFileNameA(hInst, szFile, MAX_PATH);
+
+ for (unsigned i = 0; i < SIZEOF(iconList); i++)
+ {
+ mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, iconList[i].szName);
+
+ sid.pszDescription = (char*)iconList[i].szDescr;
+ sid.iDefaultIndex = -iconList[i].defIconID;
+ hIconLibItem[i] = Skin_AddIcon(&sid);
+ }
+}
+
+HICON LoadIconEx(const char* name, bool big)
+{
+ char szSettingName[100];
+ mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name);
+ return (HICON)CallService(MS_SKIN2_GETICON, big, (LPARAM)szSettingName);
+}
+
+HANDLE GetIconHandle(const char* name)
+{
+ unsigned i;
+ for (i=0; i < SIZEOF(iconList); i++)
+ if (strcmp(iconList[i].szName, name) == 0)
+ return hIconLibItem[i];
+ return NULL;
+}
+
+void ReleaseIconEx(const char* name)
+{
+ char szSettingName[100];
+ mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name);
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)szSettingName);
+}
+
+void ReleaseIconEx(HICON hIcon)
+{
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+}
diff --git a/plugins/CrashDumper/src/dumper.cpp b/plugins/CrashDumper/src/dumper.cpp
new file mode 100644
index 0000000000..bae091a023
--- /dev/null
+++ b/plugins/CrashDumper/src/dumper.cpp
@@ -0,0 +1,745 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+
+extern TCHAR* vertxt;
+extern TCHAR* profname;
+extern TCHAR* profpath;
+
+
+void CreateMiniDump(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr)
+{
+ MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
+ exceptionInfo.ThreadId = GetCurrentThreadId();
+ exceptionInfo.ExceptionPointers = exc_ptr;
+ exceptionInfo.ClientPointers = false;
+
+ MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
+ hDumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL);
+}
+
+
+void WriteBBFile(bkstring& buffer, bool hdr)
+{
+ static const TCHAR header[] = TEXT("[quote][size=1]");
+ static const TCHAR footer[] = TEXT("[/size][/quote]");
+
+ buffer.append(hdr ? header : footer);
+}
+
+
+void WriteUtfFile(HANDLE hDumpFile, char* bufu)
+{
+ DWORD bytes;
+
+ static const unsigned char bytemark[] = { 0xEF, 0xBB, 0xBF };
+ WriteFile(hDumpFile, bytemark, 3, &bytes, NULL);
+ WriteFile(hDumpFile, bufu, (DWORD)strlen(bufu), &bytes, NULL);
+}
+
+
+BOOL CALLBACK LoadedModules64(LPCSTR, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext)
+{
+ bkstring& buffer = *(bkstring*)UserContext;
+
+ const HMODULE hModule = (HMODULE)ModuleBase;
+
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(hModule, path, MAX_PATH);
+
+ buffer.appendfmt(TEXT("%s %p - %p"), path, (LPVOID)ModuleBase, (LPVOID)(ModuleBase + ModuleSize));
+
+ GetVersionInfo(hModule, buffer);
+
+ TCHAR timebuf[30] = TEXT("");
+ GetLastWriteTime(path, timebuf, 30);
+
+ buffer.appendfmt(TEXT(" [%s]\r\n"), timebuf);
+
+ return TRUE;
+}
+
+typedef struct _FindData
+{
+ DWORD64 Offset; IMAGEHLP_MODULE64* pModule;
+} FindData;
+
+
+BOOL CALLBACK LoadedModulesFind64(LPCSTR ModuleName, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext)
+{
+ FindData* data = (FindData*)UserContext;
+
+ if ((DWORD)(data->Offset - ModuleBase) < ModuleSize)
+ {
+ const size_t len = SIZEOF(data->pModule->ModuleName);
+ strncpy(data->pModule->ModuleName, ModuleName, len);
+ data->pModule->ModuleName[len-1] = 0;
+
+ data->pModule->BaseOfImage = ModuleBase;
+
+ const HMODULE hModule = (HMODULE)ModuleBase;
+ GetModuleFileNameA(hModule, data->pModule->LoadedImageName, SIZEOF(data->pModule->LoadedImageName));
+
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+void GetLinkedModulesInfo(TCHAR *moduleName, bkstring &buffer)
+{
+ HANDLE hDllFile = CreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hDllFile == INVALID_HANDLE_VALUE) return;
+
+ HANDLE hDllMapping = CreateFileMapping(hDllFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hDllMapping == INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hDllFile);
+ return;
+ }
+
+ LPVOID dllAddr = MapViewOfFile(hDllMapping, FILE_MAP_READ, 0, 0, 0);
+
+
+ static const TCHAR format[] = TEXT(" Plugin statically linked to missing module: %S\r\n");
+
+
+ __try
+ {
+ PIMAGE_NT_HEADERS nthdrs = ImageNtHeader(dllAddr);
+
+ ULONG tableSize;
+ PIMAGE_IMPORT_DESCRIPTOR importData = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(dllAddr, FALSE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT, &tableSize);
+ if (importData)
+ {
+ while (importData->Name)
+ {
+ char* moduleName = (char*)ImageRvaToVa(nthdrs, dllAddr, importData->Name, NULL);
+ if (!SearchPathA(NULL, moduleName, NULL, NULL, 0, NULL))
+ {
+ buffer.appendfmt(format, moduleName);
+ }
+ importData++; //go to next record
+ }
+ }
+
+ bool found = false;
+ PIMAGE_EXPORT_DIRECTORY exportData = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(dllAddr, FALSE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT, &tableSize);
+ if (exportData)
+ {
+ ULONG* funcAddr = (ULONG*)ImageRvaToVa(nthdrs, dllAddr, exportData->AddressOfNames, NULL);
+ for(unsigned i=0; i<exportData->NumberOfNames && !found; ++i)
+ {
+ char* funcName = (char*)ImageRvaToVa(nthdrs, dllAddr, funcAddr[i], NULL);
+ found = strcmp(funcName, "MirandaPluginInfoEx") == 0 || strcmp(funcName, "MirandaPluginInfo") == 0;
+ if (strcmp(funcName, "DatabasePluginInfo") == 0)
+ {
+ buffer.append(TEXT(" This dll is a Miranda database plugin, another database is active right now\r\n"));
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ buffer.append(TEXT(" This dll is not a Miranda plugin and should be removed from plugins directory\r\n"));
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER) {}
+
+ UnmapViewOfFile(dllAddr);
+ CloseHandle(hDllMapping);
+ CloseHandle(hDllFile);
+}
+
+
+struct ListItem
+{
+ ListItem() : str(), next(NULL) {}
+
+ bkstring str;
+ ListItem *next;
+};
+
+static void GetPluginsString(bkstring& buffer, unsigned& flags)
+{
+ buffer.appendfmt(TEXT("Service Mode: %s\r\n"), servicemode ? TEXT("Yes") : TEXT("No"));
+
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(NULL, path, MAX_PATH);
+
+ LPTSTR fname = _tcsrchr(path, TEXT('\\'));
+ if (fname == NULL) fname = path;
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\*.dll"));
+
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind = FindFirstFile(path, &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) return;
+
+ size_t count = 0, ucount = 0;
+
+ bkstring ubuffer;
+ ListItem* dlllist = NULL;
+
+
+ static const TCHAR format[] = TEXT("%c %s v.%s%d.%d.%d.%d%s [%s] - %S %s\r\n");
+
+
+ do
+ {
+ bool loaded = false;
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\%s"), FindFileData.cFileName);
+ HMODULE hModule = GetModuleHandle(path);
+ if (hModule == NULL && servicemode)
+ {
+ hModule = LoadLibrary(path);
+ loaded = true;
+ }
+ if (hModule == NULL)
+ {
+ if ((flags & VI_FLAG_PRNVAR) && IsPluginEnabled(FindFileData.cFileName))
+ {
+ TCHAR timebuf[30] = TEXT("");
+ GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30);
+
+ ubuffer.appendfmt(format, TEXT(' '), FindFileData.cFileName,
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ 0, 0, 0, 0,
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""),
+ timebuf, "<unknown>", TEXT(""));
+
+ GetLinkedModulesInfo(path, ubuffer);
+ ubuffer.append(TEXT("\r\n"));
+
+ ++ucount;
+ }
+ continue;
+ }
+
+ PLUGININFOEX* pi = GetMirInfo(hModule);
+ if (pi != NULL)
+ {
+ TCHAR timebuf[30] = TEXT("");
+ GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30);
+
+ bool ep = (size_t)pi->cbSize > sizeof(PLUGININFOEX);
+ const TCHAR *unica = (ep && ((PLUGININFOEX*)pi)->flags & 1) ? TEXT("|Unicode aware|") : TEXT("");
+
+ ListItem* lst = new ListItem;
+ DWORD ver = pi->version;
+ lst->str.appendfmt(format, ep ? TEXT('\xa4') : TEXT(' '), FindFileData.cFileName,
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ HIBYTE(HIWORD(ver)), LOBYTE(HIWORD(ver)), HIBYTE(LOWORD(ver)), LOBYTE(LOWORD(ver)),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""),
+ timebuf, pi->shortName ? pi->shortName : "", unica);
+
+ ListItem* lsttmp = dlllist;
+ ListItem* lsttmppv = NULL;
+ while (lsttmp != NULL)
+ {
+ size_t sz = min(lsttmp->str.size(), lst->str.size()) - 2;
+ if (lsttmp->str.comparei(2, sz, lst->str, 2, sz) > 0) break;
+ lsttmppv = lsttmp;
+ lsttmp = lsttmp->next;
+ }
+ lst->next = lsttmp;
+ if (lsttmppv == NULL)
+ dlllist = lst;
+ else
+ lsttmppv->next = lst;
+
+ if (_tcsicmp(FindFileData.cFileName, TEXT("weather.dll")) == 0)
+ flags |= VI_FLAG_WEATHER;
+
+ ++count;
+ }
+ if (loaded) FreeLibrary(hModule);
+ }
+ while (FindNextFile(hFind, &FindFileData));
+ FindClose(hFind);
+
+ buffer.appendfmt(TEXT("\r\n%sActive Plugins (%u):%s\r\n"),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), count, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""));
+
+ ListItem* lsttmp = dlllist;
+ while (lsttmp != NULL)
+ {
+ buffer.append(lsttmp->str);
+ ListItem* lsttmp1 = lsttmp->next;
+ delete lsttmp;
+ lsttmp = lsttmp1;
+ }
+
+ if (ucount)
+ {
+ buffer.appendfmt(TEXT("\r\n%sUnloadable Plugins (%u):%s\r\n"),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), ucount, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""));
+ buffer.append(ubuffer);
+ }
+}
+
+
+struct ProtoCount
+{
+ char countse;
+ char countsd;
+ bool nloaded;
+};
+
+static void GetProtocolStrings(bkstring& buffer)
+{
+ PROTOACCOUNT **accList;
+ int accCount, protoCount;
+ int i, j;
+
+ PROTOCOLDESCRIPTOR **protoList;
+ if (ProtoEnumAccounts(&accCount, &accList) == CALLSERVICE_NOTFOUND || (accCount > 0 && accList[0]->cbSize == 0))
+ {
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protoList);
+ for (i = 0; i < protoCount; i++)
+ {
+ if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue;
+
+ TCHAR* nm;
+ crsi_a2t(nm, protoList[i]->szName);
+ buffer.appendfmt(TEXT(" 1 - %s\r\n"), nm);
+ }
+ }
+ else
+ {
+ CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&protoList);
+
+ int protoCountMy = 0;
+ char** protoListMy = (char**)alloca((protoCount + accCount) * sizeof(char*));
+
+ for (i = 0; i < protoCount; i++)
+ {
+ if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue;
+ protoListMy[protoCountMy++] = protoList[i]->szName;
+ }
+
+ for (j = 0; j < accCount; j++)
+ {
+ for (i = 0; i < protoCountMy; i++)
+ {
+ if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0)
+ break;
+ }
+ if (i == protoCountMy)
+ protoListMy[protoCountMy++] = accList[j]->szProtoName;
+ }
+
+ ProtoCount *protos = (ProtoCount*)alloca(sizeof(ProtoCount) * protoCountMy);
+ memset(protos, 0, sizeof(ProtoCount) * protoCountMy);
+
+ for (j = 0; j < accCount; j++)
+ {
+ for (i = 0; i < protoCountMy; i++)
+ {
+ if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0)
+ {
+ protos[i].nloaded = accList[j]->bDynDisabled != 0;
+ if (IsAccountEnabled(accList[j]))
+ ++protos[i].countse;
+ else
+ ++protos[i].countsd;
+ break;
+ }
+ }
+ }
+ for (i = 0; i < protoCountMy; i++)
+ {
+ TCHAR* nm;
+ crsi_a2t(nm, protoListMy[i]);
+ buffer.appendfmt(TEXT("%-24s %d - Enabled %d - Disabled %sLoaded\r\n"), nm, protos[i].countse,
+ protos[i].countsd, protos[i].nloaded ? _T("Not ") : _T(""));
+ }
+ }
+}
+
+
+static void GetWeatherStrings(bkstring& buffer, unsigned flags)
+{
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(NULL, path, MAX_PATH);
+
+ LPTSTR fname = _tcsrchr(path, TEXT('\\'));
+ if (fname == NULL) fname = path;
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\*.ini"));
+
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind = FindFirstFile(path, &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) return;
+
+ do
+ {
+ if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\%s"), FindFileData.cFileName);
+ HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hDumpFile != INVALID_HANDLE_VALUE)
+ {
+ char buf[8192];
+
+ DWORD bytes = 0;
+ ReadFile(hDumpFile, buf, 8190, &bytes, NULL);
+ buf[bytes] = 0;
+
+ char* ver = strstr(buf, "Version=");
+ if (ver != NULL)
+ {
+ char *endid = strchr(ver, '\r');
+ if (endid != NULL) *endid = 0;
+ else
+ {
+ endid = strchr(ver, '\n');
+ if (endid != NULL) *endid = 0;
+ }
+ ver += 8;
+ }
+
+ char *id = strstr(buf, "Name=");
+ if (id != NULL)
+ {
+ char *endid = strchr(id, '\r');
+ if (endid != NULL) *endid = 0;
+ else
+ {
+ endid = strchr(id, '\n');
+ if (endid != NULL) *endid = 0;
+ }
+ id += 5;
+ }
+
+ TCHAR timebuf[30] = TEXT("");
+ GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30);
+
+
+ static const TCHAR format[] = TEXT(" %s v.%s%S%s [%s] - %S\r\n");
+
+ buffer.appendfmt(format, FindFileData.cFileName,
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ ver,
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""),
+ timebuf, id);
+ CloseHandle(hDumpFile);
+ }
+ }
+ while (FindNextFile(hFind, &FindFileData));
+ FindClose(hFind);
+}
+
+
+static void GetIconStrings(bkstring& buffer)
+{
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(NULL, path, MAX_PATH);
+
+ LPTSTR fname = _tcsrchr(path, TEXT('\\'));
+ if (fname == NULL) fname = path;
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\Icons\\*.*"));
+
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind = FindFirstFile(path, &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) return;
+
+ do
+ {
+ if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+
+ TCHAR timebuf[30] = TEXT("");
+ GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30);
+
+ buffer.appendfmt(TEXT(" %s [%s]\r\n"), FindFileData.cFileName, timebuf);
+ }
+ while (FindNextFile(hFind, &FindFileData));
+ FindClose(hFind);
+}
+
+
+void PrintVersionInfo(bkstring& buffer, unsigned flags)
+{
+ GetProcessorString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ GetFreeMemoryString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ GetOSDisplayString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ GetInternetExplorerVersion(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ GetAdminString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ GetLanguageString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ TCHAR *profpathfull = Utils_ReplaceVarsT(profpath);
+ if (flags & VI_FLAG_PRNVAR)
+ {
+ GetFreeDiskString(profpathfull, buffer);
+ buffer.append(TEXT("\r\n"));
+ }
+
+ buffer.appendfmt(TEXT("\r\nMiranda IM Version: %s"), vertxt);
+ GetWow64String(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ TCHAR path[MAX_PATH], mirtime[30];
+ GetModuleFileName(NULL, path, MAX_PATH);
+ GetLastWriteTime(path, mirtime, 30);
+ buffer.appendfmt(TEXT("Build time: %s\r\n"), mirtime);
+
+ TCHAR profpn[MAX_PATH];
+ crs_sntprintf(profpn, SIZEOF(profpn), TEXT("%s\\%s"), profpathfull, profname);
+
+ buffer.appendfmt(TEXT("Profile: %s\r\n"), profpn);
+
+ if (flags & VI_FLAG_PRNVAR)
+ {
+ WIN32_FIND_DATA FindFileData;
+
+ HANDLE hFind = FindFirstFile(profpn, &FindFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ FindClose(hFind);
+
+ unsigned __int64 fsize = (unsigned __int64)FindFileData.nFileSizeHigh << 32 | FindFileData.nFileSizeLow;
+ buffer.appendfmt(TEXT("Profile size: %I64u Bytes\r\n"), fsize),
+
+ GetLastWriteTime(&FindFileData.ftCreationTime, mirtime, 30);
+ buffer.appendfmt(TEXT("Profile creation date: %s\r\n"), mirtime);
+ }
+ }
+ mir_free(profpathfull);
+
+ GetLanguagePackString(buffer);
+ buffer.append(TEXT("\r\n"));
+
+ buffer.appendfmt(TEXT("Nightly: %s\r\n"), _tcsstr(vertxt, TEXT("alpha")) ? TEXT("Yes") : TEXT("No"));
+ buffer.appendfmt(TEXT("Unicode: %s\r\n"), _tcsstr(vertxt, TEXT("Unicode")) ? TEXT("Yes") : TEXT("No"));
+
+ GetPluginsString(buffer, flags);
+
+ if (flags & VI_FLAG_WEATHER)
+ {
+ buffer.appendfmt(TEXT("\r\n%sWeather ini files:%s\r\n-------------------------------------------------------------------------------\r\n"),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""));
+ GetWeatherStrings(buffer, flags);
+ }
+
+ if (flags & VI_FLAG_PRNVAR && !servicemode)
+ {
+ buffer.appendfmt(TEXT("\r\n%sProtocols and Accounts:%s\r\n-------------------------------------------------------------------------------\r\n"),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""));
+ GetProtocolStrings(buffer);
+ }
+
+ if (flags & VI_FLAG_PRNVAR)
+ {
+ buffer.appendfmt(TEXT("\r\n%sIcon Packs:%s\r\n-------------------------------------------------------------------------------\r\n"),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""),
+ (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""));
+ GetIconStrings(buffer);
+ }
+
+ if (flags & VI_FLAG_PRNDLL)
+ {
+ __try
+ {
+ buffer.append(TEXT("\r\nLoaded Modules:\r\n-------------------------------------------------------------------------------\r\n"));
+ EnumerateLoadedModules64(GetCurrentProcess(), LoadedModules64, &buffer);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER) {}
+ }
+
+ if (flags & (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL)) UnloadDbgHlp();
+}
+
+
+void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg)
+{
+ if (exc_ptr->ContextRecord == NULL || (exc_ptr->ContextRecord->ContextFlags & CONTEXT_CONTROL) == 0)
+ return;
+
+ CONTEXT context = *exc_ptr->ContextRecord;
+
+ STACKFRAME64 frame = {0};
+
+#if defined(_AMD64_)
+#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_AMD64
+ frame.AddrPC.Offset = context.Rip;
+ frame.AddrFrame.Offset = context.Rbp;
+ frame.AddrStack.Offset = context.Rsp;
+#elif defined(_IA64_)
+#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_IA64
+ frame.AddrPC.Offset = context.StIIP;
+ frame.AddrFrame.Offset = context.AddrBStore;
+ frame.AddrStack.Offset = context.SP;
+#else
+#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386
+ frame.AddrPC.Offset = context.Eip;
+ frame.AddrFrame.Offset = context.Ebp;
+ frame.AddrStack.Offset = context.Esp;
+#endif
+
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Mode = AddrModeFlat;
+
+ const PLUGININFOEX *pluginInfoEx = GetPluginInfoEx();
+
+ bkstring buffer;
+ buffer.reserve(0x5000);
+
+ TCHAR curtime[30];
+ GetISO8061Time(NULL, curtime, 30);
+
+ buffer.appendfmt(TEXT("Miranda Crash Report from %s. Crash Dumper v.%d.%d.%d.%d\r\n"),
+ curtime,
+ HIBYTE(HIWORD(pluginInfoEx->version)), LOBYTE(HIWORD(pluginInfoEx->version)),
+ HIBYTE(LOWORD(pluginInfoEx->version)), LOBYTE(LOWORD(pluginInfoEx->version)));
+
+ size_t crashpos = buffer.size();
+
+ ReadableExceptionInfo(exc_ptr->ExceptionRecord, buffer);
+ buffer.append(TEXT("\r\n"));
+
+ const HANDLE hProcess = GetCurrentProcess();
+
+ if (&SymSetOptions)
+ SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
+ SymInitialize(hProcess, NULL, TRUE);
+
+ buffer.append(TEXT("\r\nStack Trace:\r\n---------------------------------------------------------------\r\n"));
+
+ for (int i=81; --i;)
+ {
+ /*
+ char symbuf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0};
+ PSYMBOL_INFO pSym = (PSYMBOL_INFO)symbuf;
+ pSym->SizeOfStruct = sizeof(SYMBOL_INFO);
+ pSym->MaxNameLen = MAX_SYM_NAME;
+ */
+
+ char symbuf[sizeof(IMAGEHLP_SYMBOL64) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0};
+ PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)symbuf;
+ pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ pSym->MaxNameLength = MAX_SYM_NAME;
+
+ IMAGEHLP_LINE64 Line = {0};
+ Line.SizeOfStruct = sizeof(Line);
+
+ IMAGEHLP_MODULE64 Module = {0};
+ Module.SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
+
+ char undName[MAX_SYM_NAME] = "";
+ char undFullName[MAX_SYM_NAME] = "";
+
+ DWORD64 offsetFromSmybol = 0;
+ DWORD offsetFromLine = 0;
+
+ if (!StackWalk64(IMAGE_FILE_MACHINE, hProcess, GetCurrentThread(), &frame, &context,
+ NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break;
+
+ if (frame.AddrPC.Offset == frame.AddrReturn.Offset) break;
+
+ if (frame.AddrPC.Offset != 0)
+ {
+ if (SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym))
+ // if (SymFromAddr(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym))
+ {
+ UnDecorateSymbolName(pSym->Name, undName, MAX_SYM_NAME, UNDNAME_NAME_ONLY);
+ UnDecorateSymbolName(pSym->Name, undFullName, MAX_SYM_NAME, UNDNAME_COMPLETE);
+ }
+
+ SymGetLineFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromLine, &Line);
+ SymGetModuleInfo64(hProcess, frame.AddrPC.Offset, &Module);
+ if (Module.ModuleName[0] == 0)
+ {
+ FindData data;
+ data.Offset = frame.AddrPC.Offset;
+ data.pModule = &Module;
+ EnumerateLoadedModules64(hProcess, LoadedModulesFind64, &data);
+ }
+ }
+
+ const char* name;
+ if (undFullName[0] != 0)
+ name = undFullName;
+ else if (undName[0] != 0)
+ name = undName;
+ else if (pSym->Name[0] != 0)
+ name = pSym->Name;
+ else
+ name = "(function-name not available)";
+
+ const char *lineFileName = Line.FileName ? Line.FileName : "(filename not available)";
+ const char *moduleName = Module.ModuleName[0] ? Module.ModuleName : "(module-name not available)";
+
+ if (crashpos != 0)
+ {
+ HMODULE hModule = (HMODULE)Module.BaseOfImage;
+ PLUGININFOEX *pi = GetMirInfo(hModule);
+ if (pi != NULL)
+ {
+
+ static const TCHAR formatc[] = TEXT("\r\nLikely cause of the crash plugin: %S\r\n\r\n");
+
+ if (pi->shortName)
+ {
+ bkstring crashcause;
+ crashcause.appendfmt(formatc, pi->shortName);
+ buffer.insert(crashpos, crashcause);
+ }
+ crashpos = 0;
+ }
+ }
+
+
+ static const TCHAR formatd[] = TEXT("%p (%S %p): %S (%d): %S\r\n");
+
+ buffer.appendfmt(formatd,
+ (LPVOID)frame.AddrPC.Offset, moduleName, (LPVOID)Module.BaseOfImage,
+ lineFileName, Line.LineNumber, name);
+ }
+ SymCleanup(hProcess);
+ buffer.append(TEXT("\r\n"));
+
+ PrintVersionInfo(buffer, VI_FLAG_PRNDLL);
+
+
+ int len = WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, NULL, 0, NULL, NULL);
+ char* dst = (char*)(len > 8192 ? malloc(len) : alloca(len));
+ WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, dst, len, NULL, NULL);
+
+ WriteUtfFile(hDumpFile, dst);
+
+ if (len > 8192) free(dst);
+
+
+ if (msg && MessageBox(NULL, msg, TEXT("Miranda Crash Dumper"), MB_YESNO | MB_ICONERROR | MB_TASKMODAL | MB_DEFBUTTON2 | MB_TOPMOST) == IDYES)
+ StoreStringToClip(buffer);
+}
diff --git a/plugins/CrashDumper/src/exhndlr.cpp b/plugins/CrashDumper/src/exhndlr.cpp
new file mode 100644
index 0000000000..93406efaa8
--- /dev/null
+++ b/plugins/CrashDumper/src/exhndlr.cpp
@@ -0,0 +1,207 @@
+#include "utils.h"
+#include "crtdbg.h"
+
+static PVOID exchndlr, exchndlrv;
+static pfnExceptionFilter threadfltr;
+static PEXCEPTION_POINTERS lastptr;
+
+static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll"));
+
+tAddVectoredExceptionHandler pAddVectoredExceptionHandler = (tAddVectoredExceptionHandler)GetProcAddress(hKernel, "AddVectoredExceptionHandler");
+tRemoveVectoredExceptionHandler pRemoveVectoredExceptionHandler = (tRemoveVectoredExceptionHandler)GetProcAddress(hKernel, "RemoveVectoredExceptionHandler");
+tRtlCaptureContext pRtlCaptureContext = (tRtlCaptureContext)GetProcAddress(hKernel, "RtlCaptureContext");
+
+void SetExceptionHandler(void)
+{
+ // if (pAddVectoredExceptionHandler && !exchndlrv)
+ // exchndlrv = pAddVectoredExceptionHandler(0, myfilterv);
+ /*exchndlr = */ SetUnhandledExceptionFilter(myfilter);
+}
+
+void RemoveExceptionHandler(void)
+{
+ if (pRemoveVectoredExceptionHandler && exchndlrv)
+ pRemoveVectoredExceptionHandler(exchndlrv);
+ SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr);
+ exchndlr = NULL;
+ exchndlrv = NULL;
+}
+
+void UnloadDbgHlp(void)
+{
+#ifdef _MSC_VER
+#if _MSC_VER > 1200
+ __FUnloadDelayLoadedDLL2("dbghelp.dll");
+#else
+ __FUnloadDelayLoadedDLL("dbghelp.dll");
+#endif
+#endif
+}
+
+int myDebugFilter(unsigned int code, PEXCEPTION_POINTERS ep)
+{
+ if (code == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ||
+ code == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND))
+ {
+ PDelayLoadInfo dlld = (PDelayLoadInfo)ep->ExceptionRecord->ExceptionInformation[0];
+
+ char str[256];
+ int off = mir_snprintf(str, SIZEOF(str), "dbghelp.dll v.5.0 or later required to provide a crash report\n");
+ off += mir_snprintf(str+off, SIZEOF(str)-off, "Missing Module: %s ", dlld->szDll);
+
+ if (dlld->dlp.fImportByName)
+ mir_snprintf(str+off, SIZEOF(str)-off, "Function: %s ", dlld->dlp.szProcName);
+ else
+ mir_snprintf(str+off, SIZEOF(str)-off, "Ordinal: %x ", dlld->dlp.dwOrdinal);
+
+ MessageBoxA(NULL, str, "Miranda Crash Dumper", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST);
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+
+void myfilterWorker(PEXCEPTION_POINTERS exc_ptr, bool notify)
+{
+ TCHAR path[MAX_PATH];
+ SYSTEMTIME st;
+ HANDLE hDumpFile = NULL;
+
+ GetLocalTime(&st);
+ CreateDirectoryTree(CrashLogFolder);
+
+ __try
+ {
+ if (dtsubfldr)
+ {
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay);
+ CreateDirectory(path, NULL);
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder,
+ st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+ }
+ else
+ {
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder,
+ st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+ }
+ hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hDumpFile != INVALID_HANDLE_VALUE)
+ CreateMiniDump(hDumpFile, exc_ptr);
+ else if (GetLastError() != ERROR_ALREADY_EXISTS)
+ MessageBox(NULL, TranslateT("Crash Report write location is inaccesible"),
+ TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST);
+
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER) {}
+
+ bool empty = GetFileSize(hDumpFile, NULL) == 0;
+ CloseHandle(hDumpFile);
+ if (empty) DeleteFile(path);
+
+ __try
+ {
+ if (dtsubfldr)
+ {
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay);
+ CreateDirectory(path, NULL);
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder,
+ st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+ }
+ else
+ {
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder,
+ st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+ }
+ hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ crs_sntprintf(path, MAX_PATH, TranslateT("Miranda crashed. Crash report stored in the folder:\n %s\n\n Would you like store it in the clipboard as well?"), CrashLogFolder);
+
+ if (hDumpFile != INVALID_HANDLE_VALUE)
+ CreateCrashReport(hDumpFile, exc_ptr, notify ? path : NULL);
+ }
+ __except(myDebugFilter(GetExceptionCode(), GetExceptionInformation())) {}
+
+ bool empty1 = GetFileSize(hDumpFile, NULL) == 0;
+ CloseHandle(hDumpFile);
+ if (empty1) DeleteFile(path);
+
+ UnloadDbgHlp();
+}
+
+LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr)
+{
+ if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER;
+ lastptr = exc_ptr;
+
+ myfilterWorker(exc_ptr, true);
+
+ return exchndlr ? ((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr)(exc_ptr) : EXCEPTION_CONTINUE_SEARCH;
+}
+
+LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr)
+{
+ if (0xC0000000L <= exc_ptr->ExceptionRecord->ExceptionCode && 0xC0000500L >= exc_ptr->ExceptionRecord->ExceptionCode)
+ {
+ if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER;
+ lastptr = exc_ptr;
+
+ myfilterWorker(exc_ptr, true);
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info)
+{
+ if (info != lastptr)
+ {
+ lastptr = info;
+ myfilterWorker(info, true);
+ }
+ return threadfltr(code, info);
+}
+
+#if _MSC_VER >= 1400
+void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, UINT_PTR)
+{
+ EXCEPTION_RECORD ExceptionRecord = {0};
+ CONTEXT ContextRecord = {0};
+ EXCEPTION_POINTERS info = { &ExceptionRecord, &ContextRecord };
+
+ if (pRtlCaptureContext)
+ pRtlCaptureContext(&ContextRecord);
+ else
+ {
+ ContextRecord.ContextFlags = CONTEXT_ALL;
+ GetThreadContext(GetCurrentThread(), &ContextRecord);
+ }
+
+#if defined(_AMD64_)
+ ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Rip;
+#elif defined(_IA64_)
+ ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.BrRp;
+#else
+ ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip;
+#endif
+
+ ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER;
+ ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+
+ myfilterWorker(&info, true);
+}
+#endif
+
+void InitExceptionHandler(void)
+{
+#if _MSC_VER >= 1400
+ _set_invalid_parameter_handler(InvalidParameterHandler);
+#endif
+ threadfltr = Miranda_SetExceptFilter(MirandaThreadFilter);
+ SetExceptionHandler();
+}
+
+void DestroyExceptionHandler(void)
+{
+ Miranda_SetExceptFilter(threadfltr);
+ RemoveExceptionHandler();
+}
+
diff --git a/plugins/CrashDumper/src/resource.h b/plugins/CrashDumper/src/resource.h
new file mode 100644
index 0000000000..83d8a491e4
--- /dev/null
+++ b/plugins/CrashDumper/src/resource.h
@@ -0,0 +1,34 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by crshdmp.rc
+//
+#define IDD_VIEWVERSION 101
+#define IDR_CONTEXT 102
+#define IDI_VI 104
+#define IDI_VISHOW 105
+#define IDI_VITOCLIP 106
+#define IDI_VITOFILE 107
+#define IDI_VIUPLOAD 108
+#define IDD_OPTIONS 109
+#define IDC_VIEWVERSIONINFO 1001
+#define IDC_FILEVER 1003
+#define IDC_CLIPVER 1004
+#define IDC_USERNAME 1006
+#define IDC_PASSWORD 1007
+#define IDC_UPLOADCHN 1008
+#define IDC_CLASSICDATES 1009
+#define IDC_DATESUBFOLDER 1010
+#define IDM_COPY 40002
+#define IDM_COPYALL 40003
+#define IDM_SELECTALL 40004
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 110
+#define _APS_NEXT_COMMAND_VALUE 40005
+#define _APS_NEXT_CONTROL_VALUE 1011
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/CrashDumper/src/sdkstuff.h b/plugins/CrashDumper/src/sdkstuff.h
new file mode 100644
index 0000000000..536a00bc40
--- /dev/null
+++ b/plugins/CrashDumper/src/sdkstuff.h
@@ -0,0 +1,124 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <windows.h>
+
+
+//#define DBGHELP_TRANSLATE_TCHAR
+
+
+#ifndef __in_bcount_opt
+#define __in_bcount_opt(x)
+#endif
+
+#ifndef __out_bcount_opt
+#define __out_bcount_opt(x)
+#endif
+
+#include "dbghelp.h"
+
+
+#ifndef PRODUCT_ULTIMATE
+
+#define PRODUCT_UNDEFINED 0x00000000
+
+#define PRODUCT_ULTIMATE 0x00000001
+#define PRODUCT_HOME_BASIC 0x00000002
+#define PRODUCT_HOME_PREMIUM 0x00000003
+#define PRODUCT_ENTERPRISE 0x00000004
+#define PRODUCT_HOME_BASIC_N 0x00000005
+#define PRODUCT_BUSINESS 0x00000006
+#define PRODUCT_STANDARD_SERVER 0x00000007
+#define PRODUCT_DATACENTER_SERVER 0x00000008
+#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
+#define PRODUCT_ENTERPRISE_SERVER 0x0000000A
+#define PRODUCT_STARTER 0x0000000B
+#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
+#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
+#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
+#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
+#define PRODUCT_BUSINESS_N 0x00000010
+#define PRODUCT_WEB_SERVER 0x00000011
+#define PRODUCT_CLUSTER_SERVER 0x00000012
+#define PRODUCT_HOME_SERVER 0x00000013
+#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
+#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
+#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
+#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
+#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
+#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
+
+#define PRODUCT_UNLICENSED 0xABCDABCD
+
+#define SM_TABLETPC 86
+#define SM_MEDIACENTER 87
+#define SM_STARTER 88
+#define SM_SERVERR2 89
+
+#endif
+
+#ifndef VER_SUITE_STORAGE_SERVER
+#define VER_SUITE_STORAGE_SERVER 0x00002000
+#define VER_SUITE_COMPUTE_SERVER 0x00004000
+#endif
+
+#ifndef PF_NX_ENABLED
+#define PF_NX_ENABLED 12
+#endif
+
+typedef struct _IMAGEHLP_MODULE64_V2 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ CHAR ModuleName[32]; // module name
+ CHAR ImageName[256]; // image name
+ CHAR LoadedImageName[256]; // symbol file name
+} IMAGEHLP_MODULE64_V2;
+
+typedef struct _IMAGEHLP_MODULEW64_V2 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ WCHAR ModuleName[32]; // module name
+ WCHAR ImageName[256]; // image name
+ WCHAR LoadedImageName[256]; // symbol file name
+} IMAGEHLP_MODULEW64_V2;
+
+#ifdef DBGHELP_TRANSLATE_TCHAR
+#define IMAGEHLP_MODULE64_V2 IMAGEHLP_MODULEW64_V2
+#endif
+
+typedef void (WINAPI *tGetNativeSystemInfo)(LPSYSTEM_INFO);
+typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
+typedef BOOL (WINAPI *tGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer);
+typedef BOOL (WINAPI *tGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
+typedef LANGID (WINAPI *tGetUserDefaultUILanguage)(void);
+typedef LANGID (WINAPI *tGetSystemDefaultUILanguage)(void);
+typedef BOOL (WINAPI *tIsWow64Process)(HANDLE, PBOOL);
+typedef PVOID (WINAPI *tAddVectoredExceptionHandler)(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler);
+typedef ULONG (WINAPI *tRemoveVectoredExceptionHandler)(PVOID Handler);
+typedef BOOL (WINAPI *tIsProcessorFeaturePresent)(DWORD ProcessorFeature);
+typedef VOID (WINAPI *tRtlCaptureContext)(PCONTEXT ContextRecord);
diff --git a/plugins/CrashDumper/src/ui.cpp b/plugins/CrashDumper/src/ui.cpp
new file mode 100644
index 0000000000..00cf9c26cd
--- /dev/null
+++ b/plugins/CrashDumper/src/ui.cpp
@@ -0,0 +1,327 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <commctrl.h>
+#include <richedit.h>
+#include <m_popup.h>
+
+HWND hViewWnd;
+extern HINSTANCE hInst;
+
+
+HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndCtrl, int nHorizontalOffset, int nVerticalOffset,
+ int nWidthOffset, int nHeightOffset)
+{
+ POINT pt;
+ RECT rcinit;
+
+ // get current bounding rectangle
+ GetWindowRect(hwndCtrl, &rcinit);
+
+ // get current top left point
+ pt.x = rcinit.left;
+ pt.y = rcinit.top;
+ ScreenToClient(hwndDlg, &pt);
+
+ return DeferWindowPos(hDwp, hwndCtrl, NULL,
+ pt.x + nHorizontalOffset,
+ pt.y + nVerticalOffset,
+ rcinit.right - rcinit.left + nWidthOffset,
+ rcinit.bottom - rcinit.top + nHeightOffset,
+ SWP_NOZORDER);
+}
+
+BOOL MyResizeGetOffset(HWND hwndCtrl, int nWidth, int nHeight, int* nDx, int* nDy)
+{
+ RECT rcinit;
+
+ // get current bounding rectangle
+ GetWindowRect(hwndCtrl, &rcinit);
+
+ // calculate offsets
+ *nDx = nWidth - (rcinit.right - rcinit.left);
+ *nDy = nHeight - (rcinit.bottom - rcinit.top);
+
+ return rcinit.bottom != rcinit.top && nHeight > 0;
+}
+
+INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ if (hViewWnd == NULL)
+ {
+ hViewWnd = hwndDlg;
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx("versionInfo", true));
+ SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconEx("versionInfo"));
+
+ CHARFORMAT2 chf;
+ chf.cbSize = sizeof(chf);
+ SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&chf);
+ _tcscpy(chf.szFaceName, TEXT("Courier New"));
+ SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&chf);
+
+ bkstring buffer;
+ buffer.reserve(0x1800);
+ PrintVersionInfo(buffer, (unsigned int)lParam);
+ SetDlgItemText(hwndDlg, IDC_VIEWVERSIONINFO, buffer.c_str());
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+
+ Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, PluginName, "ViewInfo_");
+ ShowWindow(hwndDlg, SW_SHOW);
+ }
+ else
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_SIZE:
+ {
+ int dx, dy, bsz;
+ HDWP hDwp;
+ RECT rc;
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_FILEVER), &rc);
+ bsz = rc.bottom - rc.top;
+
+ if (MyResizeGetOffset(GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO),
+ LOWORD(lParam)-20, HIWORD(lParam)-30-bsz, &dx, &dy))
+ {
+ hDwp = BeginDeferWindowPos(4);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_FILEVER), 0, dy, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_CLIPVER), dx/2, dy, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDCANCEL), dx, dy, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO), 0, 0, dx, dy);
+ EndDeferWindowPos(hDwp);
+ }
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
+
+ // The minimum width in points
+ mmi->ptMinTrackSize.x = 350;
+ // The minimum height in points
+ mmi->ptMinTrackSize.y = 300;
+ }
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_CLIPVER:
+ CallService(MS_CRASHDUMPER_STORETOCLIP, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
+ break;
+
+ case IDC_FILEVER:
+ CallService(MS_CRASHDUMPER_STORETOFILE, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
+ break;
+
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ {
+ HWND hView = GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO);
+ RECT rc;
+ GetWindowRect(hView, &rc);
+
+ POINT pt;
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ if (PtInRect(&rc, pt))
+ {
+ static const CHARRANGE all = { 0, -1 };
+
+ HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ HMENU hSubMenu = GetSubMenu(hMenu, 0);
+ TranslateMenu(hSubMenu);
+
+ CHARRANGE sel;
+ SendMessage(hView, EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin == sel.cpMax)
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL))
+ {
+ case IDM_COPY:
+ SendMessage(hView, WM_COPY, 0, 0);
+ break;
+
+ case IDM_COPYALL:
+ SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all);
+ SendMessage(hView, WM_COPY, 0, 0);
+ SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&sel);
+ break;
+
+ case IDM_SELECTALL:
+ SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all);
+ break;
+ }
+ DestroyMenu(hMenu);
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ hViewWnd = NULL;
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0));
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0));
+ Utils_SaveWindowPosition(hwndDlg, NULL, PluginName, "ViewInfo_");
+ if (servicemode) PostQuitMessage(0);
+ break;
+ }
+ return FALSE;
+}
+
+
+void DestroyAllWindows(void)
+{
+ if (hViewWnd != NULL) DestroyWindow(hViewWnd);
+ hViewWnd = NULL;
+}
+
+
+INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+
+ DBVARIANT dbv;
+ if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0)
+ {
+ SetDlgItemTextA(hwndDlg, IDC_USERNAME, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0)
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal);
+ SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ CheckDlgButton(hwndDlg, IDC_UPLOADCHN, DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0));
+ CheckDlgButton(hwndDlg, IDC_CLASSICDATES, clsdates);
+ CheckDlgButton(hwndDlg, IDC_DATESUBFOLDER, dtsubfldr);
+ }
+ break;
+
+ case WM_COMMAND:
+ if ((HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus())
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY)
+ {
+ char szSetting[100];
+ GetDlgItemTextA(hwndDlg, IDC_USERNAME, szSetting, SIZEOF(szSetting));
+ DBWriteContactSettingString(NULL, PluginName, "Username", szSetting);
+
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, szSetting, SIZEOF(szSetting));
+ CallService(MS_DB_CRYPT_ENCODESTRING, SIZEOF(szSetting), (LPARAM)szSetting);
+ DBWriteContactSettingString(NULL, PluginName, "Password", szSetting);
+
+ DBWriteContactSettingByte(NULL, PluginName, "UploadChanged",
+ (BYTE)IsDlgButtonChecked(hwndDlg, IDC_UPLOADCHN));
+
+ clsdates = IsDlgButtonChecked(hwndDlg, IDC_CLASSICDATES) == BST_CHECKED;
+ if (clsdates)
+ DBWriteContactSettingByte(NULL, PluginName, "ClassicDates", 1);
+ else
+ DBDeleteContactSetting(NULL, PluginName, "ClassicDates");
+ dtsubfldr = IsDlgButtonChecked(hwndDlg, IDC_DATESUBFOLDER) == BST_CHECKED;
+ if (dtsubfldr)
+ DBWriteContactSettingByte(NULL, PluginName, "SubFolders", 1);
+ else
+ DBDeleteContactSetting(NULL, PluginName, "SubFolders");
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+LRESULT CALLBACK DlgProcPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_CONTEXTMENU:
+ PUDeletePopUp(hWnd);
+ break;
+
+ case WM_COMMAND:
+ switch ((int)PUGetPluginData(hWnd))
+ {
+ case 0:
+ OpenAuthUrl("http://www.miranda-vi.org/");
+ break;
+
+ case 1:
+ OpenAuthUrl("http://%s.miranda-vi.org/global");
+ break;
+
+ case 3:
+ TCHAR path[MAX_PATH];
+ crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder);
+ ShellExecute(NULL, TEXT("open"), path, NULL, NULL, SW_SHOW);
+ break;
+
+ }
+ PUDeletePopUp(hWnd);
+ break;
+
+ case UM_FREEPLUGINDATA:
+ ReleaseIconEx("versionInfo");
+ break;
+ }
+
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+void ShowMessage(int type, const TCHAR* format, ...)
+{
+ POPUPDATAT pi = {0};
+
+ va_list va;
+ va_start(va, format);
+ int len = _vsntprintf(pi.lptzText, SIZEOF(pi.lptzText)-1, format, va);
+ pi.lptzText[len] = 0;
+ va_end(va);
+
+ if (ServiceExists(MS_POPUP_ADDPOPUPT))
+ {
+ _tcscpy(pi.lptzContactName, TEXT(PluginName));
+ pi.lchIcon = LoadIconEx("versionInfo");
+ pi.PluginWindowProc = DlgProcPopup;
+ pi.PluginData = (void*)type;
+
+ PUAddPopUpT(&pi);
+ }
+ else
+ MessageBox(NULL, pi.lptzText, TEXT(PluginName), MB_OK | MB_ICONINFORMATION);
+}
diff --git a/plugins/CrashDumper/src/upload.cpp b/plugins/CrashDumper/src/upload.cpp
new file mode 100644
index 0000000000..498b5cb2f6
--- /dev/null
+++ b/plugins/CrashDumper/src/upload.cpp
@@ -0,0 +1,292 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <m_netlib.h>
+
+HANDLE hNetlibUser;
+
+static void arrayToHex(BYTE* data, size_t datasz, char* res)
+{
+ char* resptr = res;
+ for (unsigned i=0; i<datasz ; i++)
+ {
+ const BYTE ch = data[i];
+
+ const char ch0 = (char)(ch >> 4);
+ *resptr++ = (char)((ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0));
+
+ const char ch1 = (char)(ch & 0xF);
+ *resptr++ = (char)((ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1));
+ }
+ *resptr = '\0';
+}
+
+void GetLoginStr(char* user, size_t szuser, char* pass)
+{
+ DBVARIANT dbv;
+
+ if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0)
+ {
+ mir_snprintf(user, szuser, "%s", dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ user[0] = 0;
+
+ if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0)
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal);
+
+ mir_md5_byte_t hash[16];
+ mir_md5_state_t context;
+
+ mir_md5_init(&context);
+ mir_md5_append(&context, (BYTE*)dbv.pszVal, (int)strlen(dbv.pszVal));
+ mir_md5_finish(&context, hash);
+
+ arrayToHex(hash, sizeof(hash), pass);
+
+ DBFreeVariant(&dbv);
+ }
+ else
+ pass[0] = 0;
+}
+
+void OpenAuthUrl(const char* url)
+{
+ char user[64], pass[40];
+ GetLoginStr(user, sizeof(user), pass);
+
+ if (user[0] && pass[0])
+ {
+ char str[256];
+
+ mir_snprintf(str, sizeof(str), url, user);
+ char* eurl = (char*)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM)str);
+
+ mir_snprintf(str, sizeof(str), "http://www.miranda-vi.org/cdlogin?name=%s&pass=%s&redir=%s", user, pass, eurl);
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM)str);
+ HeapFree(GetProcessHeap(), 0, eurl);
+ }
+ else
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://www.miranda-vi.org/");
+}
+
+void CreateAuthString(char* auth)
+{
+ char user[64], pass[40];
+ GetLoginStr(user, sizeof(user), pass);
+
+ char str[110];
+ int len = mir_snprintf(str, sizeof(str), "%s:%s", user, pass);
+
+ strcpy(auth, "Basic ");
+ NETLIBBASE64 nlb = { auth+6, 250, (PBYTE)str, len };
+ CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb));
+}
+
+
+bool InternetDownloadFile(const char *szUrl, VerTrnsfr* szReq)
+{
+ int result = 0xBADBAD;
+ char* szRedirUrl = NULL;
+ NETLIBHTTPREQUEST nlhr = {0};
+
+ // initialize the netlib request
+ nlhr.cbSize = sizeof(nlhr);
+ nlhr.requestType = REQUEST_POST;
+ nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP;
+ nlhr.szUrl = (char*)szUrl;
+
+ nlhr.headersCount = 6;
+ nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount);
+ nlhr.headers[0].szName = "Connection";
+ nlhr.headers[0].szValue = "close";
+ nlhr.headers[1].szName = "Cache-Control";
+ nlhr.headers[1].szValue = "no-cache";
+ nlhr.headers[2].szName = "Pragma";
+ nlhr.headers[2].szValue = "no-cache";
+ nlhr.headers[3].szName = "Content-Type";
+ nlhr.headers[3].szValue = "text/plain; charset=utf-8";
+ nlhr.headers[4].szName = "AutoUpload";
+ nlhr.headers[4].szValue = (char*)(szReq->autot ? "1" : "0");
+ nlhr.headers[5].szName = "Authorization";
+
+ char auth[256];
+ CreateAuthString(auth);
+ nlhr.headers[5].szValue = auth;
+
+ nlhr.pData = szReq->buf;
+ nlhr.dataLength = (int)strlen(szReq->buf);
+
+ while (result == 0xBADBAD)
+ {
+ // download the page
+ NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION,
+ (WPARAM)hNetlibUser,(LPARAM)&nlhr);
+
+ if (nlhrReply)
+ {
+ int i;
+
+ // if the recieved code is 200 OK
+ switch(nlhrReply->resultCode)
+ {
+ case 200:
+ if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0))
+ ProcessVIHash(true);
+
+ for (i=nlhrReply->headersCount; i--; )
+ {
+ if (_stricmp(nlhrReply->headers[i].szName, "OldPlugins") == 0)
+ {
+ i = atoi(nlhrReply->headers[i].szValue);
+ break;
+ }
+ }
+
+ ShowMessage(1, TranslateT("VersionInfo upload successful,\n %d old plugins"), i);
+ result = 0;
+ break;
+
+ case 401:
+ ShowMessage(0, TranslateT("Cannot upload VersionInfo. Incorrect username or password"));
+ result = 1;
+ break;
+
+ case 510:
+ ShowMessage(0, TranslateT("Cannot upload VersionInfo. User is banned"));
+ result = 1;
+ break;
+
+ case 511:
+ ShowMessage(0, TranslateT("Cannot upload VersionInfo. Daily upload limit exceeded"));
+ result = 1;
+ break;
+
+ case 301:
+ case 302:
+ case 307:
+ // get the url for the new location and save it to szInfo
+ // look for the reply header "Location"
+ for (i=0; i<nlhrReply->headersCount; i++)
+ {
+ if (!strcmp(nlhrReply->headers[i].szName, "Location"))
+ {
+ size_t rlen = 0;
+ if (nlhrReply->headers[i].szValue[0] == '/')
+ {
+ const char* szPath;
+ const char* szPref = strstr(szUrl, "://");
+ szPref = szPref ? szPref + 3 : szUrl;
+ szPath = strchr(szPref, '/');
+ rlen = szPath != NULL ? szPath - szUrl : strlen(szUrl);
+ }
+
+ szRedirUrl = (char*)mir_realloc(szRedirUrl,
+ rlen + strlen(nlhrReply->headers[i].szValue)*3 + 1);
+
+ strncpy(szRedirUrl, szUrl, rlen);
+ strcpy(szRedirUrl+rlen, nlhrReply->headers[i].szValue);
+
+ nlhr.szUrl = szRedirUrl;
+ break;
+ }
+ }
+ break;
+
+ default:
+ result = 1;
+ ShowMessage(0, TranslateT("Cannot upload VersionInfo. Unknown error"));
+ }
+ }
+ else
+ {
+ result = 1;
+ ShowMessage(0, TranslateT("Cannot upload VersionInfo. Host unreachable."));
+ }
+
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply);
+ }
+
+ mir_free(szRedirUrl);
+ mir_free(nlhr.headers);
+
+ return result == 0;
+}
+
+void __cdecl VersionInfoUploadThread(void* arg)
+{
+ VerTrnsfr* trn = (VerTrnsfr*)arg;
+ InternetDownloadFile("http://www.miranda-vi.org/uploadpost", trn);
+ mir_free(trn->buf);
+ mir_free(trn);
+}
+
+
+void UploadInit(void)
+{
+ NETLIBUSER nlu = {0};
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_TCHAR;
+ nlu.szSettingsModule = (char*)PluginName;
+ nlu.ptszDescriptiveName = TranslateT("Crash Dumper HTTP connections");
+ hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+}
+
+void UploadClose(void)
+{
+ Netlib_CloseHandle(hNetlibUser);
+}
+
+bool ProcessVIHash(bool store)
+{
+ bkstring buffer;
+ buffer.reserve(0x1800);
+ PrintVersionInfo(buffer, 0);
+
+ mir_md5_byte_t hash[16];
+ mir_md5_state_t context;
+
+ mir_md5_init(&context);
+ mir_md5_append(&context, (PBYTE)buffer.c_str(), (int)buffer.sizebytes());
+ mir_md5_finish(&context, hash);
+
+ char hashstr[40];
+ arrayToHex(hash, sizeof(hash), hashstr);
+
+ bool result;
+ if (store)
+ {
+ DBWriteContactSettingString(NULL, PluginName, "VIHash", hashstr);
+ result = true;
+ }
+ else
+ {
+ DBVARIANT dbv;
+ if (DBGetContactSettingString(NULL, PluginName, "VIHash", &dbv) == 0)
+ {
+ result = strcmp(hashstr, dbv.pszVal) == 0;
+ DBFreeVariant(&dbv);
+ }
+ else
+ result = false;
+ }
+ return result;
+}
diff --git a/plugins/CrashDumper/src/utils.cpp b/plugins/CrashDumper/src/utils.cpp
new file mode 100644
index 0000000000..d4dced7d70
--- /dev/null
+++ b/plugins/CrashDumper/src/utils.cpp
@@ -0,0 +1,836 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <lm.h>
+
+static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll"));
+
+tGetNativeSystemInfo pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo");
+tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo");
+tGlobalMemoryStatusEx pGlobalMemoryStatusEx = (tGlobalMemoryStatusEx) GetProcAddress(hKernel, "GlobalMemoryStatusEx");
+tGetUserDefaultUILanguage pGetUserDefaultUILanguage = (tGetUserDefaultUILanguage) GetProcAddress(hKernel, "GetUserDefaultUILanguage");
+tGetSystemDefaultUILanguage pGetSystemDefaultUILanguage = (tGetSystemDefaultUILanguage) GetProcAddress(hKernel, "GetSystemDefaultUILanguage");
+tIsWow64Process pIsWow64Process = (tIsWow64Process) GetProcAddress(hKernel, "IsWow64Process");
+tIsProcessorFeaturePresent pIsProcessorFeaturePresent = (tIsProcessorFeaturePresent) GetProcAddress(hKernel, "IsProcessorFeaturePresent");
+
+
+tGetDiskFreeSpaceEx pGetDiskFreeSpaceEx = (tGetDiskFreeSpaceEx) GetProcAddress(hKernel, "GetDiskFreeSpaceExW");
+
+
+
+void CheckForOtherCrashReportingPlugins(void)
+{
+ HMODULE hModule = GetModuleHandle(TEXT("attache.dll"));
+ if (hModule == NULL)
+ hModule = GetModuleHandle(TEXT("crashrpt.dll"));
+ if (hModule == NULL)
+ hModule = GetModuleHandle(TEXT("crashdmp.dll"));
+
+ if (hModule == NULL) return;
+
+ MessageBox(NULL, TranslateT("More then one crash reporting plugin installed. This will result in inability of creating crash reports"),
+ TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST);
+}
+
+void GetOSDisplayString(bkstring& buffer)
+{
+ OSVERSIONINFOEX osvi = {0};
+ SYSTEM_INFO si = {0};
+ BOOL bOsVersionInfoEx;
+ DWORD dwType = 0;
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi);
+ if (!bOsVersionInfoEx)
+ {
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (!GetVersionEx((OSVERSIONINFO*)&osvi))
+ return;
+ }
+
+ // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+ pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo");
+ if (NULL != pGetNativeSystemInfo) pGetNativeSystemInfo(&si);
+ else GetSystemInfo(&si);
+
+ if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4)
+ {
+ buffer.append(TEXT("Operating System: Microsoft "));
+
+ // Test for the specific product.
+ if (osvi.dwMajorVersion == 6)
+ {
+ switch (osvi.dwMinorVersion)
+ {
+ case 0:
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ buffer.append(TEXT("Windows Vista "));
+ else
+ buffer.append(TEXT("Windows Server 2008 "));
+ break;
+
+ case 1:
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ buffer.append(TEXT("Windows 7 "));
+ else
+ buffer.append(TEXT("Windows Server 2008 R2 "));
+ break;
+
+ default:
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ buffer.append(TEXT("Windows 8 "));
+ else
+ buffer.append(TEXT("Windows Server 2012 "));
+ break;
+ }
+
+ pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo");
+ if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType);
+
+ switch(dwType)
+ {
+ case PRODUCT_ULTIMATE:
+ buffer.append(TEXT("Ultimate Edition"));
+ break;
+ case PRODUCT_HOME_PREMIUM:
+ buffer.append(TEXT("Home Premium Edition"));
+ break;
+ case PRODUCT_HOME_BASIC:
+ buffer.append(TEXT("Home Basic Edition"));
+ break;
+ case PRODUCT_ENTERPRISE:
+ buffer.append(TEXT("Enterprise Edition"));
+ break;
+ case PRODUCT_BUSINESS:
+ buffer.append(TEXT("Business Edition"));
+ break;
+ case PRODUCT_STARTER:
+ buffer.append(TEXT("Starter Edition"));
+ break;
+ case PRODUCT_CLUSTER_SERVER:
+ buffer.append(TEXT("Cluster Server Edition"));
+ break;
+ case PRODUCT_DATACENTER_SERVER:
+ buffer.append(TEXT("Datacenter Edition"));
+ break;
+ case PRODUCT_DATACENTER_SERVER_CORE:
+ buffer.append(TEXT("Datacenter Edition (core installation)"));
+ break;
+ case PRODUCT_ENTERPRISE_SERVER:
+ buffer.append(TEXT("Enterprise Edition"));
+ break;
+ case PRODUCT_ENTERPRISE_SERVER_CORE:
+ buffer.append(TEXT("Enterprise Edition (core installation)"));
+ break;
+ case PRODUCT_ENTERPRISE_SERVER_IA64:
+ buffer.append(TEXT("Enterprise Edition for Itanium-based Systems"));
+ break;
+ case PRODUCT_SMALLBUSINESS_SERVER:
+ buffer.append(TEXT("Small Business Server"));
+ break;
+ case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
+ buffer.append(TEXT("Small Business Server Premium Edition"));
+ break;
+ case PRODUCT_STANDARD_SERVER:
+ buffer.append(TEXT("Standard Edition"));
+ break;
+ case PRODUCT_STANDARD_SERVER_CORE:
+ buffer.append(TEXT("Standard Edition (core installation)"));
+ break;
+ case PRODUCT_WEB_SERVER:
+ buffer.append(TEXT("Web Server Edition"));
+ break;
+ }
+
+ if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ buffer.append(TEXT(", 64-bit"));
+ else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL)
+ buffer.append(TEXT(", 32-bit"));
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+ {
+ if (GetSystemMetrics(SM_SERVERR2))
+ buffer.append(TEXT("Windows Server 2003 R2, "));
+ else if (osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER)
+ buffer.append(TEXT("Windows Storage Server 2003"));
+ else if (osvi.wProductType == VER_NT_WORKSTATION &&
+ si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ buffer.append(TEXT("Windows XP Professional x64 Edition"));
+ else buffer.append(TEXT("Windows Server 2003, "));
+
+ // Test for the server type.
+ if (osvi.wProductType != VER_NT_WORKSTATION)
+ {
+ if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)
+ {
+ if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ buffer.append(TEXT("Datacenter Edition for Itanium-based Systems"));
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ buffer.append(TEXT("Enterprise Edition for Itanium-based Systems"));
+ }
+
+ else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ {
+ if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ buffer.append(TEXT("Datacenter x64 Edition"));
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ buffer.append(TEXT("Enterprise x64 Edition"));
+ else buffer.append(TEXT("Standard x64 Edition"));
+ }
+
+ else
+ {
+ if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
+ buffer.append(TEXT("Compute Cluster Edition"));
+ else if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ buffer.append(TEXT("Datacenter Edition"));
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ buffer.append(TEXT("Enterprise Edition"));
+ else if (osvi.wSuiteMask & VER_SUITE_BLADE)
+ buffer.append(TEXT("Web Edition"));
+ else buffer.append(TEXT("Standard Edition"));
+ }
+ }
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ buffer.append(TEXT("Windows XP "));
+ if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
+ buffer.append(TEXT("Home Edition"));
+ else
+ buffer.append(TEXT("Professional"));
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+ {
+ buffer.append(TEXT("Windows 2000 "));
+
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ buffer.append(TEXT("Professional"));
+ }
+ else
+ {
+ if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ buffer.append(TEXT("Datacenter Server"));
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ buffer.append(TEXT("Advanced Server"));
+ else buffer.append(TEXT("Server"));
+ }
+ }
+ if (_tcslen(osvi.szCSDVersion) > 0)
+ {
+ buffer.append(TEXT(" "));
+ buffer.append(osvi.szCSDVersion);
+ }
+
+ buffer.appendfmt(TEXT(" (build %d)"), osvi.dwBuildNumber);
+ }
+ else
+ {
+ if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
+ {
+ buffer.append(TEXT("Microsoft Windows NT "));
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ buffer.append(TEXT("Workstation 4.0 "));
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ buffer.append(TEXT("Server 4.0, Enterprise Edition "));
+ else
+ buffer.append(TEXT("Server 4.0 "));
+ }
+
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && osvi.dwMajorVersion == 4)
+ {
+ if (osvi.dwMinorVersion == 0)
+ {
+ buffer.append(TEXT("Microsoft Windows 95 "));
+ if (osvi.szCSDVersion[1]==TEXT('C') || osvi.szCSDVersion[1]==TEXT('B'))
+ buffer.append(TEXT("OSR2 "));
+ }
+
+ if (osvi.dwMinorVersion == 10)
+ {
+ buffer.append(TEXT("Microsoft Windows 98 "));
+ if (osvi.szCSDVersion[1]==TEXT('A') || osvi.szCSDVersion[1]==TEXT('B'))
+ buffer.append(TEXT("SE "));
+ }
+
+ if (osvi.dwMinorVersion == 90)
+ {
+ buffer.append(TEXT("Microsoft Windows Millennium Edition"));
+ }
+ buffer.appendfmt(TEXT("(build %d)"), LOWORD(osvi.dwBuildNumber));
+ }
+ else if (osvi.dwPlatformId == VER_PLATFORM_WIN32s)
+ {
+ buffer.append(TEXT("Microsoft Win32s"));
+ }
+ }
+}
+
+int GetTZOffset(void)
+{
+ TIME_ZONE_INFORMATION tzInfo = {0};
+ DWORD type = GetTimeZoneInformation(&tzInfo);
+
+ int offset = 0;
+ switch (type)
+ {
+ case TIME_ZONE_ID_DAYLIGHT:
+ offset = -(tzInfo.Bias + tzInfo.DaylightBias);
+ break;
+
+ case TIME_ZONE_ID_STANDARD:
+ offset = -(tzInfo.Bias + tzInfo.StandardBias);
+ break;
+
+ case TIME_ZONE_ID_UNKNOWN:
+ offset = -tzInfo.Bias;
+ break;
+ }
+ return offset;
+}
+
+void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize)
+{
+ SYSTEMTIME loctime;
+ if (stLocal == NULL)
+ {
+ stLocal = &loctime;
+ GetLocalTime(stLocal);
+ }
+
+ if (clsdates)
+ {
+ GetDateFormat(LOCALE_INVARIANT, 0, stLocal, TEXT("d MMM yyyy"), lpszString, dwSize);
+ int dlen = (int)_tcslen(lpszString);
+ GetTimeFormat(LOCALE_INVARIANT, 0, stLocal, TEXT(" H:mm:ss"), lpszString+dlen, dwSize-dlen);
+ }
+ else
+ {
+ int offset = GetTZOffset();
+
+ // Build a string showing the date and time.
+ crs_sntprintf(lpszString, dwSize, TEXT("%d-%02d-%02d %02d:%02d:%02d%+03d%02d"),
+ stLocal->wYear, stLocal->wMonth, stLocal->wDay,
+ stLocal->wHour, stLocal->wMinute, stLocal->wSecond,
+ offset / 60, offset % 60);
+ }
+}
+
+void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize)
+{
+ FILETIME ftLocal;
+ SYSTEMTIME stLocal;
+
+ // Convert the last-write time to local time.
+ FileTimeToLocalFileTime(ftime, &ftLocal);
+ FileTimeToSystemTime(&ftLocal, &stLocal);
+
+ GetISO8061Time(&stLocal, lpszString, dwSize);
+}
+
+void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize)
+{
+ WIN32_FIND_DATA FindFileData;
+
+ HANDLE hFind = FindFirstFile(fileName, &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) return;
+ FindClose(hFind);
+
+ GetLastWriteTime(&FindFileData.ftLastWriteTime, lpszString, dwSize);
+}
+
+typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_Info) (DWORD mirandaVersion);
+
+PLUGININFOEX* GetMirInfo(HMODULE hModule)
+{
+ Miranda_Plugin_Info bpi = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfoEx");
+ if (bpi == NULL)
+ return NULL;
+
+ return bpi(mirandaVersion);
+}
+
+
+void GetInternetExplorerVersion(bkstring& buffer)
+{
+ HKEY hKey;
+ DWORD size;
+
+ TCHAR ieVersion[1024] = {0};
+ TCHAR ieBuild[512] = {0};
+ TCHAR iVer[64] = {0};
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Internet Explorer"), 0,
+ KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ size = sizeof(ieBuild)/sizeof(ieBuild[0]);
+ if (RegQueryValueEx(hKey, TEXT("Build"), NULL, NULL, (LPBYTE) ieBuild, &size) != ERROR_SUCCESS)
+ ieBuild[0] = 0;
+
+ size = sizeof(ieVersion)/sizeof(ieVersion[0]);
+ if (RegQueryValueEx(hKey, TEXT("Version"), NULL, NULL, (LPBYTE) ieVersion, &size) != ERROR_SUCCESS)
+ ieVersion[0] = 0;
+
+ size = sizeof(iVer)/sizeof(iVer[0]);
+ if (RegQueryValueEx(hKey, TEXT("IVer"), NULL, NULL, (LPBYTE) iVer, &size) != ERROR_SUCCESS)
+ iVer[0] = 0;
+
+ RegCloseKey(hKey);
+ }
+
+ buffer.append(TEXT("Internet Explorer: "));
+ if (ieVersion[0] == 0)
+ {
+ if (iVer[0] == 0)
+ buffer.append(TEXT("<not installed>"));
+ else if (_tcscmp(iVer, TEXT("100")) == 0)
+ buffer.append(TEXT("1.0"));
+ else if (_tcscmp(iVer, TEXT("101")) == 0)
+ buffer.append(TEXT("NT"));
+ else if (_tcscmp(iVer, TEXT("102")) == 0)
+ buffer.append(TEXT("2.0"));
+ else if (_tcscmp(iVer, TEXT("103")) == 0)
+ buffer.append(TEXT("3.0"));
+ }
+ else
+ {
+ buffer.append(ieVersion);
+ }
+ if (ieBuild[0] != 0)
+ {
+ buffer.appendfmt(TEXT(" (build %s)"), ieBuild);
+ }
+}
+
+
+void TrimMultiSpaces(TCHAR* str)
+{
+ TCHAR *src = str, *dest = str;
+ bool trimst = false;
+
+ for (;;)
+ {
+ if (*src == TEXT(' '))
+ {
+ if (!trimst)
+ {
+ trimst = true;
+ *dest++ = *src;
+ }
+ }
+ else
+ {
+ trimst = false;
+ *dest++ = *src;
+ }
+ if (*src++ == 0) break;
+ }
+}
+
+void GetProcessorString(bkstring& buffer)
+{
+ HKEY hKey;
+ DWORD size;
+
+ TCHAR cpuIdent[512] = {0};
+ TCHAR cpuName[512] = {0};
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Hardware\\Description\\System\\CentralProcessor\\0"), 0,
+ KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ size = sizeof(cpuName)/sizeof(cpuName[0]);
+ if (RegQueryValueEx(hKey, TEXT("ProcessorNameString"), NULL, NULL, (LPBYTE) cpuName, &size) != ERROR_SUCCESS)
+ _tcscpy(cpuName, TEXT("Unknown"));
+
+ size = sizeof(cpuIdent)/sizeof(cpuIdent[0]);
+ if (RegQueryValueEx(hKey, TEXT("Identifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS)
+ if (RegQueryValueEx(hKey, TEXT("VendorIdentifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS)
+ _tcscpy(cpuIdent, TEXT("Unknown"));
+
+ RegCloseKey(hKey);
+ }
+ TrimMultiSpaces(cpuName);
+ buffer.appendfmt(TEXT("CPU: %s [%s]"), cpuName, cpuIdent);
+
+ if (pIsProcessorFeaturePresent && pIsProcessorFeaturePresent(PF_NX_ENABLED))
+ buffer.append(TEXT(" [DEP Enabled]"));
+
+ SYSTEM_INFO si = {0};
+ GetSystemInfo(&si);
+
+ if (si.dwNumberOfProcessors > 1)
+ buffer.appendfmt(TEXT(" [%u CPUs]"), si.dwNumberOfProcessors);
+}
+
+void GetFreeMemoryString(bkstring& buffer)
+{
+ unsigned ram;
+ if (pGlobalMemoryStatusEx)
+ {
+ MEMORYSTATUSEX ms = {0};
+ ms.dwLength = sizeof(ms);
+ pGlobalMemoryStatusEx(&ms);
+ ram = (unsigned int) ((ms.ullTotalPhys / (1024 * 1024)) + 1);
+ }
+ else
+ {
+ MEMORYSTATUS ms = {0};
+ ZeroMemory(&ms, sizeof(ms));
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatus(&ms);
+ ram = (unsigned int)(ms.dwTotalPhys/(1024*1024))+1;
+ }
+ buffer.appendfmt(TEXT("Installed RAM: %u MBytes"), ram);
+}
+
+void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer)
+{
+ ULARGE_INTEGER tnb, tfb, fs = {0};
+ if (pGetDiskFreeSpaceEx)
+ pGetDiskFreeSpaceEx(dirname, &fs, &tnb, &tfb);
+ else
+ {
+ DWORD SectorsPerCluster, BytesPerSector;
+ DWORD NumberOfFreeClusters, TotalNumberOfClusters;
+
+ GetDiskFreeSpace(dirname, &SectorsPerCluster, &BytesPerSector,
+ &NumberOfFreeClusters, &TotalNumberOfClusters);
+
+ fs.QuadPart = BytesPerSector * SectorsPerCluster;
+ fs.QuadPart *= NumberOfFreeClusters;
+ }
+ fs.QuadPart /= (1024*1024);
+
+ buffer.appendfmt(TEXT("Free disk space on Miranda partition: %u MBytes"), fs.LowPart);
+}
+
+void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer)
+{
+ buffer.append(TEXT("Exception: "));
+
+ switch (excrec->ExceptionCode)
+ {
+ case EXCEPTION_BREAKPOINT:
+ buffer.append(TEXT("User Defined Breakpoint"));
+ break;
+
+ case EXCEPTION_ACCESS_VIOLATION:
+ buffer.append(TEXT("Access Violation"));
+ break;
+
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ buffer.append(TEXT("Array Bounds Exceeded"));
+ break;
+
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ buffer.append(TEXT("Datatype Misalignment"));
+ break;
+
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ buffer.append(TEXT("Floating Point denormlized operand"));
+ break;
+
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ buffer.append(TEXT("Floating Point divide by 0"));
+ break;
+
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ buffer.append(TEXT("Floating Point inexact result"));
+ break;
+
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ buffer.append(TEXT("Floating Point invalid operation"));
+ break;
+
+ case EXCEPTION_FLT_OVERFLOW:
+ buffer.append(TEXT("Floating Point overflow"));
+ break;
+
+ case EXCEPTION_FLT_STACK_CHECK:
+ buffer.append(TEXT("Floating Point stack overflow/underflow"));
+ break;
+
+ case EXCEPTION_FLT_UNDERFLOW:
+ buffer.append(TEXT("Floating Point underflow"));
+ break;
+
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ buffer.append(TEXT("Invalid instruction executed"));
+ break;
+
+ case EXCEPTION_IN_PAGE_ERROR:
+ buffer.append(TEXT("Access to the not present page"));
+ break;
+
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ buffer.append(TEXT("Integer divide by zero"));
+ break;
+
+ case EXCEPTION_INT_OVERFLOW:
+ buffer.append(TEXT("Integer overflow"));
+ break;
+
+ case EXCEPTION_PRIV_INSTRUCTION:
+ buffer.append(TEXT("Priveleged instruction executed"));
+ break;
+
+ case EXCEPTION_STACK_OVERFLOW:
+ buffer.append(TEXT("Stack overflow"));
+ break;
+
+ case 0xe06d7363:
+ buffer.append(TEXT("Unhandled C++ software exception"));
+ break;
+
+ default:
+ buffer.appendfmt(TEXT("%x"), excrec->ExceptionCode);
+ break;
+ }
+
+ buffer.appendfmt(TEXT(" at address %p."), excrec->ExceptionAddress);
+
+ if (excrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
+ excrec->ExceptionCode == EXCEPTION_IN_PAGE_ERROR)
+ {
+ switch(excrec->ExceptionInformation[0])
+ {
+ case 0:
+ buffer.appendfmt(TEXT(" Reading from address %p."), (LPVOID)excrec->ExceptionInformation[1]);
+ break;
+
+ case 1:
+ buffer.appendfmt(TEXT(" Writing to address %p."), (LPVOID)excrec->ExceptionInformation[1]);
+ break;
+
+ case 8:
+ buffer.appendfmt(TEXT(" DEP at address %p."), (LPVOID)excrec->ExceptionInformation[1]);
+ break;
+ }
+ }
+}
+
+void GetAdminString(bkstring& buffer)
+{
+ BOOL b;
+ __try
+ {
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ PSID AdministratorsGroup;
+
+ b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
+ if (b)
+ {
+ if (!CheckTokenMembership(NULL, AdministratorsGroup, &b))
+ b = FALSE;
+ FreeSid(AdministratorsGroup);
+ }
+ else
+ b = GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ b = TRUE;
+ }
+
+ buffer.appendfmt(TEXT("Administrator privileges: %s"), b ? TEXT("Yes") : TEXT ("No"));
+}
+
+void GetLanguageString(bkstring& buffer)
+{
+ TCHAR name1[256], name2[256], name3[256], name4[256];
+
+ GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, name1, 256);
+ GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, name2, 256);
+
+ if (pGetUserDefaultUILanguage && pGetSystemDefaultUILanguage)
+ {
+ GetLocaleInfo(MAKELCID(pGetUserDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name3, 256);
+ GetLocaleInfo(MAKELCID(pGetSystemDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name4, 256);
+ }
+ else
+ {
+ _tcscpy(name3, name1);
+ _tcscpy(name4, name2);
+ }
+
+ buffer.appendfmt(TEXT("OS Languages: (UI | Locale (User/System)) : %s/%s | %s/%s"), name3, name4, name1, name2);
+}
+
+void GetLanguagePackString(bkstring& buffer)
+{
+ buffer.append(TEXT("Language pack: "));
+ if (packlcid == LOCALE_USER_DEFAULT)
+ buffer.append(TEXT("No language pack installed"));
+ else
+ {
+ TCHAR path[MAX_PATH] = TEXT("Locale id invalid");
+ GetLocaleInfo(packlcid, LOCALE_SENGLANGUAGE, path, MAX_PATH);
+ buffer.append(path);
+
+ GetLocaleInfo(packlcid, LOCALE_SISO3166CTRYNAME, path, MAX_PATH);
+ buffer.appendfmt(TEXT(" (%s) [%04x]"), path, packlcid);
+
+ GetModuleFileName(NULL, path, MAX_PATH);
+
+ LPTSTR fname = _tcsrchr(path, TEXT('\\'));
+ if (fname == NULL) fname = path;
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\langpack_*.txt"));
+
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind = FindFirstFile(path, &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) return;
+ FindClose(hFind);
+
+ crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\%s"), FindFileData.cFileName);
+ HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hDumpFile != INVALID_HANDLE_VALUE)
+ {
+ char buf[8192];
+
+ DWORD bytes = 0;
+ ReadFile(hDumpFile, buf, 8190, &bytes, NULL);
+ buf[bytes] = 0;
+
+ char *id = strstr(buf, "FLID:");
+ if (id != NULL)
+ {
+ char *endid = strchr(id, '\r');
+ if (endid != NULL) *endid = 0;
+
+ endid = strchr(id, '\n');
+ if (endid != NULL) *endid = 0;
+
+ TCHAR mirtime[30];
+ GetLastWriteTime(path, mirtime, 30);
+
+ TCHAR* tid;
+ crsi_a2t(tid, id+5);
+ buffer.appendfmt(TEXT(", %s, modified: %s"), tid, mirtime);
+ }
+ CloseHandle(hDumpFile);
+ }
+ }
+}
+
+void GetWow64String(bkstring& buffer)
+{
+ BOOL wow64 = 0;
+ if (pIsWow64Process)
+ {
+ if (!pIsWow64Process(GetCurrentProcess(), &wow64))
+ {
+ wow64 = 0;
+ }
+ }
+ if (wow64) buffer.append(TEXT(" [running inside WOW64]"));
+}
+
+
+bool CreateDirectoryTree(LPTSTR szDir)
+{
+ DWORD dwAttr = GetFileAttributes(szDir);
+ if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
+ return true;
+
+ TCHAR* pszSlash = _tcsrchr(szDir, TEXT('\\'));
+ if (pszSlash == NULL)
+ return false;
+
+ *pszSlash = 0;
+ bool res = CreateDirectoryTree(szDir);
+ *pszSlash = TEXT('\\');
+
+ if (res) res = CreateDirectory(szDir, NULL) != 0;
+
+ return res;
+}
+
+int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+
+ int len = _vsntprintf(buffer, count-1, fmt, va);
+ buffer[len] = 0;
+
+ va_end(va);
+ return len;
+}
+
+void GetVersionInfo(HMODULE hLib, bkstring& buffer)
+{
+ HRSRC hVersion = FindResource(hLib, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+ if (hVersion != NULL)
+ {
+ HGLOBAL hGlobal = LoadResource(hLib, hVersion);
+ if (hGlobal != NULL)
+ {
+ LPVOID versionInfo = LockResource(hGlobal);
+ if (versionInfo != NULL)
+ {
+ int vl = *(unsigned short*)versionInfo;
+ unsigned *res = (unsigned*)versionInfo;
+ while (*res != 0xfeef04bd && ((char*)res - (char*)versionInfo) < vl) ++res;
+
+ if (((char*)res - (char*)versionInfo) < vl)
+ {
+ VS_FIXEDFILEINFO *vsInfo = (VS_FIXEDFILEINFO*)res;
+ buffer.appendfmt(TEXT(" v.%u.%u.%u.%u"),
+ HIWORD(vsInfo->dwFileVersionMS), LOWORD(vsInfo->dwFileVersionMS),
+ HIWORD(vsInfo->dwFileVersionLS), LOWORD(vsInfo->dwFileVersionLS));
+ }
+ }
+ FreeResource(hGlobal);
+ }
+ }
+}
+
+void StoreStringToClip(bkstring& buffer)
+{
+ HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, buffer.sizebytes() + sizeof(TCHAR));
+ LPSTR buf = (LPSTR)GlobalLock(hData);
+
+ memcpy(buf, buffer.c_str(), buffer.sizebytes() + sizeof(TCHAR));
+
+ GlobalUnlock(hData);
+
+ OpenClipboard(NULL);
+ EmptyClipboard();
+
+
+ SetClipboardData(CF_UNICODETEXT, hData);
+
+}
+
+bool IsPluginEnabled(TCHAR* filename)
+{
+ char* fname;
+ crsi_t2a(fname, filename);
+ char* ext = strstr(_strlwr(fname), ".dll");
+ bool res = ext && ext[4] == '\0' && DBGetContactSettingByte(NULL, "PluginDisable", fname, 0) == 0;
+ return res;
+}
diff --git a/plugins/CrashDumper/src/utils.h b/plugins/CrashDumper/src/utils.h
new file mode 100644
index 0000000000..9089f57571
--- /dev/null
+++ b/plugins/CrashDumper/src/utils.h
@@ -0,0 +1,177 @@
+/*
+Miranda Crash Dumper Plugin
+Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+#define MIRANDA_VER 0x0A00
+
+#include <m_stdhdr.h>
+#include "sdkstuff.h"
+
+#ifdef _MSC_VER
+#include <delayimp.h>
+#endif
+
+#include <stdio.h>
+
+#include "resource.h"
+
+#include <newpluginapi.h>
+
+#ifdef _MSC_VER
+
+#pragma warning( push )
+#pragma warning( disable : 4201 4100 )
+#include <m_database.h>
+#pragma warning( pop )
+
+#else
+
+#include <m_database.h>
+
+#endif
+
+#ifdef __GNUC__
+#endif
+
+#include <m_system.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_clist.h>
+#include <m_skin.h>
+#include <m_hotkeys.h>
+#include <m_protocols.h>
+#include <m_help.h>
+
+#include "bkstring.h"
+
+#define MS_PROTO_ENUMPROTOS "Proto/EnumProtos"
+
+int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...);
+
+#define crsi_u2a(dst, src) \
+{ \
+ int cbLen = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL); \
+ dst = (char*)alloca(cbLen+1); \
+ WideCharToMultiByte(CP_ACP, 0, src, -1, dst, cbLen, NULL, NULL); \
+}
+
+#define crsi_a2u(dst, src, alloc) \
+{ \
+ int cbLen = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); \
+ dst = (wchar_t*)alloc(sizeof(wchar_t) * (cbLen+1)); \
+ MultiByteToWideChar(CP_ACP, 0, src, -1, dst, cbLen); \
+}
+
+
+
+#define crsi_t2a(d,s) crsi_u2a(d,s)
+#define crsi_a2t(d,s) crsi_a2u(d,s,alloca)
+#define crs_a2t(d,s) crsi_a2u(d,s,mir_alloc)
+
+
+
+#define SIZEOF(X) (sizeof(X)/sizeof(X[0]))
+
+#define MS_CRASHDUMPER_STORETOFILE "CrashDmp/StoreVerInfoToFile"
+#define MS_CRASHDUMPER_STORETOCLIP "CrashDmp/StoreVerInfoToClip"
+#define MS_CRASHDUMPER_GETINFO "Versioninfo/GetInfo"
+#define MS_CRASHDUMPER_VIEWINFO "CrashDmp/ViewInfo"
+#define MS_CRASHDUMPER_UPLOAD "CrashDmp/UploadInfo"
+#define MS_CRASHDUMPER_URL "CrashDmp/StartUrl"
+
+#define PluginName "Crash Dumper"
+
+#define VI_FLAG_FORMAT 1
+#define VI_FLAG_PRNVAR 2
+#define VI_FLAG_PRNDLL 4
+#define VI_FLAG_WEATHER 8
+
+struct VerTrnsfr
+{
+ char* buf;
+ bool autot;
+};
+
+extern HMODULE hInst;
+extern DWORD mirandaVersion;
+extern LCID packlcid;
+extern bool servicemode;
+extern bool clsdates;
+extern bool dtsubfldr;
+
+extern TCHAR CrashLogFolder[MAX_PATH];
+extern TCHAR VersionInfoFolder[MAX_PATH];
+
+void WriteBBFile(bkstring& buffer, bool hdr);
+void WriteUtfFile(HANDLE hDumpFile, char* bufu);
+void UnloadDbgHlp(void);
+
+LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr);
+LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr);
+DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info);
+
+void GetOSDisplayString(bkstring& buffer);
+void GetInternetExplorerVersion(bkstring& buffer);
+void GetProcessorString(bkstring& buffer);
+void GetFreeMemoryString(bkstring& buffer);
+void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer);
+void GetAdminString(bkstring& buffer);
+void GetLanguageString(bkstring& buffer);
+void GetLanguagePackString(bkstring& buffer);
+void GetWow64String(bkstring& buffer);
+void GetVersionInfo(HMODULE hLib, bkstring& buffer);
+
+void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize);
+
+void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer);
+
+void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize);
+void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize);
+bool CreateDirectoryTree(LPTSTR szDir);
+void StoreStringToClip(bkstring& buffer);
+void ShowMessage(int type, const TCHAR* format, ...);
+bool IsPluginEnabled(TCHAR* filename);
+
+PLUGININFOEX* GetMirInfo(HMODULE hModule);
+const PLUGININFOEX* GetPluginInfoEx(void);
+
+void CreateMiniDump (HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr);
+void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg);
+void PrintVersionInfo(bkstring& buffer, unsigned flags = VI_FLAG_PRNVAR);
+bool ProcessVIHash(bool store);
+
+void InitExceptionHandler(void);
+void DestroyExceptionHandler(void);
+void SetExceptionHandler(void);
+void RemoveExceptionHandler(void);
+void CheckForOtherCrashReportingPlugins(void);
+
+INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+void DestroyAllWindows(void);
+
+void UploadInit(void);
+void UploadClose(void);
+void OpenAuthUrl(const char* url);
+void __cdecl VersionInfoUploadThread(void* arg);
+
+void InitIcons(void);
+HICON LoadIconEx(const char* name, bool big = false);
+HANDLE GetIconHandle(const char* name);
+void ReleaseIconEx(const char* name);
+void ReleaseIconEx(HICON hIcon);
diff --git a/plugins/CrashDumper/src/vc6/dbghelp.h b/plugins/CrashDumper/src/vc6/dbghelp.h
new file mode 100644
index 0000000000..d8a713060b
--- /dev/null
+++ b/plugins/CrashDumper/src/vc6/dbghelp.h
@@ -0,0 +1,4532 @@
+/*++ BUILD Version: 0000 Increment this if a change has global effects
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ dbghelp.h
+
+Abstract:
+
+ This module defines the prototypes and constants required for the image
+ help routines.
+
+ Contains debugging support routines that are redistributable.
+
+Revision History:
+
+--*/
+
+#ifndef _DBGHELP_
+#define _DBGHELP_
+
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
+
+// As a general principal always call the 64 bit version
+// of every API, if a choice exists. The 64 bit version
+// works great on 32 bit platforms, and is forward
+// compatible to 64 bit platforms.
+
+#ifdef _WIN64
+#ifndef _IMAGEHLP64
+#define _IMAGEHLP64
+#endif
+#endif
+
+// For those without specstrings.h
+// Since there are different versions of this header, I need to
+// individually test each item and define it if it is not around.
+
+#ifndef __in
+ #define __in
+#endif
+#ifndef __out
+ #define __out
+#endif
+#ifndef __inout
+ #define __inout
+#endif
+#ifndef __in_opt
+ #define __in_opt
+#endif
+#ifndef __out_opt
+ #define __out_opt
+#endif
+#ifndef __inout_opt
+ #define __inout_opt
+#endif
+#ifndef __in_ecount
+ #define __in_ecount(x)
+#endif
+#ifndef __out_ecount
+ #define __out_ecount(x)
+#endif
+#ifndef __inout_ecount
+ #define __inout_ecount(x)
+#endif
+#ifndef __in_bcount
+ #define __in_bcount(x)
+#endif
+#ifndef __out_bcount
+ #define __out_bcount(x)
+#endif
+#ifndef __inout_bcount
+ #define __inout_bcount(x)
+#endif
+#ifndef __out_xcount
+ #define __out_xcount(x)
+#endif
+#ifndef __deref_opt_out
+ #define __deref_opt_out
+#endif
+#ifndef __deref_out
+ #define __deref_out
+#endif
+#ifndef __out_ecount_opt
+ #define __out_ecount_opt(x)
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _IMAGEHLP_SOURCE_
+ #define IMAGEAPI __stdcall
+ #define DBHLP_DEPRECIATED
+#else
+ #define IMAGEAPI DECLSPEC_IMPORT __stdcall
+ #if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+ #define DBHLP_DEPRECIATED __declspec(deprecated)
+ #else
+ #define DBHLP_DEPRECIATED
+ #endif
+#endif
+
+#define DBHLPAPI IMAGEAPI
+
+#define IMAGE_SEPARATION (64*1024)
+
+// Observant readers may notice that 2 new fields,
+// 'fReadOnly' and 'Version' have been added to
+// the LOADED_IMAGE structure after 'fDOSImage'.
+// This does not change the size of the structure
+// from previous headers. That is because while
+// 'fDOSImage' is a byte, it is padded by the
+// compiler to 4 bytes. So the 2 new fields are
+// slipped into the extra space.
+
+typedef struct _LOADED_IMAGE {
+ PSTR ModuleName;
+ HANDLE hFile;
+ PUCHAR MappedAddress;
+#ifdef _IMAGEHLP64
+ PIMAGE_NT_HEADERS64 FileHeader;
+#else
+ PIMAGE_NT_HEADERS32 FileHeader;
+#endif
+ PIMAGE_SECTION_HEADER LastRvaSection;
+ ULONG NumberOfSections;
+ PIMAGE_SECTION_HEADER Sections;
+ ULONG Characteristics;
+ BOOLEAN fSystemImage;
+ BOOLEAN fDOSImage;
+ BOOLEAN fReadOnly;
+ UCHAR Version;
+ LIST_ENTRY Links;
+ ULONG SizeOfImage;
+} LOADED_IMAGE, *PLOADED_IMAGE;
+
+#define MAX_SYM_NAME 2000
+
+
+// Error codes set by dbghelp functions. Call GetLastError
+// to see them.
+// Dbghelp also sets error codes found in winerror.h
+
+#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available.
+#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file
+#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file
+
+typedef BOOL
+(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(
+ __in HANDLE FileHandle,
+ __in PCSTR FileName,
+ __in PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+SymFindDebugInfoFile(
+ __in HANDLE hProcess,
+ __in PCSTR FileName,
+ __out_ecount(MAX_PATH + 1) PSTR DebugFilePath,
+ __in_opt PFIND_DEBUG_FILE_CALLBACK Callback,
+ __in_opt PVOID CallerData
+ );
+
+typedef BOOL
+(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)(
+ __in HANDLE FileHandle,
+ __in PCWSTR FileName,
+ __in PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+SymFindDebugInfoFileW(
+ __in HANDLE hProcess,
+ __in PCWSTR FileName,
+ __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath,
+ __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback,
+ __in_opt PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFile (
+ __in PCSTR FileName,
+ __in PCSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PSTR DebugFilePath
+ );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFileEx (
+ __in PCSTR FileName,
+ __in PCSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PSTR DebugFilePath,
+ __in_opt PFIND_DEBUG_FILE_CALLBACK Callback,
+ __in_opt PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+FindDebugInfoFileExW (
+ __in PCWSTR FileName,
+ __in PCWSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath,
+ __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback,
+ __in_opt PVOID CallerData
+ );
+
+typedef BOOL
+(CALLBACK *PFINDFILEINPATHCALLBACK)(
+ PCSTR filename,
+ PVOID context
+ );
+
+BOOL
+IMAGEAPI
+SymFindFileInPath(
+ __in HANDLE hprocess,
+ __in_opt PCSTR SearchPath,
+ __in PCSTR FileName,
+ __in_opt PVOID id,
+ __in DWORD two,
+ __in DWORD three,
+ __in DWORD flags,
+ __out_ecount(MAX_PATH + 1) PSTR FoundFile,
+ __in_opt PFINDFILEINPATHCALLBACK callback,
+ __in_opt PVOID context
+ );
+
+typedef BOOL
+(CALLBACK *PFINDFILEINPATHCALLBACKW)(
+ __in PCWSTR filename,
+ __in PVOID context
+ );
+
+BOOL
+IMAGEAPI
+SymFindFileInPathW(
+ __in HANDLE hprocess,
+ __in_opt PCWSTR SearchPath,
+ __in PCWSTR FileName,
+ __in_opt PVOID id,
+ __in DWORD two,
+ __in DWORD three,
+ __in DWORD flags,
+ __out_ecount(MAX_PATH + 1) PWSTR FoundFile,
+ __in_opt PFINDFILEINPATHCALLBACKW callback,
+ __in_opt PVOID context
+ );
+
+typedef BOOL
+(CALLBACK *PFIND_EXE_FILE_CALLBACK)(
+ __in HANDLE FileHandle,
+ __in PCSTR FileName,
+ __in_opt PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+SymFindExecutableImage(
+ __in HANDLE hProcess,
+ __in PCSTR FileName,
+ __out_ecount(MAX_PATH + 1) PSTR ImageFilePath,
+ __in PFIND_EXE_FILE_CALLBACK Callback,
+ __in PVOID CallerData
+ );
+
+typedef BOOL
+(CALLBACK *PFIND_EXE_FILE_CALLBACKW)(
+ __in HANDLE FileHandle,
+ __in PCWSTR FileName,
+ __in_opt PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+SymFindExecutableImageW(
+ __in HANDLE hProcess,
+ __in PCWSTR FileName,
+ __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath,
+ __in PFIND_EXE_FILE_CALLBACKW Callback,
+ __in PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+FindExecutableImage(
+ __in PCSTR FileName,
+ __in PCSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PSTR ImageFilePath
+ );
+
+HANDLE
+IMAGEAPI
+FindExecutableImageEx(
+ __in PCSTR FileName,
+ __in PCSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PSTR ImageFilePath,
+ __in_opt PFIND_EXE_FILE_CALLBACK Callback,
+ __in_opt PVOID CallerData
+ );
+
+HANDLE
+IMAGEAPI
+FindExecutableImageExW(
+ __in PCWSTR FileName,
+ __in PCWSTR SymbolPath,
+ __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath,
+ __in_opt PFIND_EXE_FILE_CALLBACKW Callback,
+ __in PVOID CallerData
+ );
+
+PIMAGE_NT_HEADERS
+IMAGEAPI
+ImageNtHeader (
+ __in PVOID Base
+ );
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToDataEx (
+ __in PVOID Base,
+ __in BOOLEAN MappedAsImage,
+ __in USHORT DirectoryEntry,
+ __out PULONG Size,
+ __out_opt PIMAGE_SECTION_HEADER *FoundHeader
+ );
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToData (
+ __in PVOID Base,
+ __in BOOLEAN MappedAsImage,
+ __in USHORT DirectoryEntry,
+ __out PULONG Size
+ );
+
+PIMAGE_SECTION_HEADER
+IMAGEAPI
+ImageRvaToSection(
+ __in PIMAGE_NT_HEADERS NtHeaders,
+ __in PVOID Base,
+ __in ULONG Rva
+ );
+
+PVOID
+IMAGEAPI
+ImageRvaToVa(
+ __in PIMAGE_NT_HEADERS NtHeaders,
+ __in PVOID Base,
+ __in ULONG Rva,
+ __in_opt OUT PIMAGE_SECTION_HEADER *LastRvaSection
+ );
+
+#ifndef _WIN64
+// This api won't be ported to Win64 - Fix your code.
+
+typedef struct _IMAGE_DEBUG_INFORMATION {
+ LIST_ENTRY List;
+ DWORD ReservedSize;
+ PVOID ReservedMappedBase;
+ USHORT ReservedMachine;
+ USHORT ReservedCharacteristics;
+ DWORD ReservedCheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+
+ DWORD ReservedNumberOfSections;
+ PIMAGE_SECTION_HEADER ReservedSections;
+
+ DWORD ReservedExportedNamesSize;
+ PSTR ReservedExportedNames;
+
+ DWORD ReservedNumberOfFunctionTableEntries;
+ PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
+ DWORD ReservedLowestFunctionStartingAddress;
+ DWORD ReservedHighestFunctionEndingAddress;
+
+ DWORD ReservedNumberOfFpoTableEntries;
+ PFPO_DATA ReservedFpoTableEntries;
+
+ DWORD SizeOfCoffSymbols;
+ PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
+
+ DWORD ReservedSizeOfCodeViewSymbols;
+ PVOID ReservedCodeViewSymbols;
+
+ PSTR ImageFilePath;
+ PSTR ImageFileName;
+ PSTR ReservedDebugFilePath;
+
+ DWORD ReservedTimeDateStamp;
+
+ BOOL ReservedRomImage;
+ PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
+ DWORD ReservedNumberOfDebugDirectories;
+
+ DWORD ReservedOriginalFunctionTableBaseAddress;
+
+ DWORD Reserved[ 2 ];
+
+} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;
+
+
+PIMAGE_DEBUG_INFORMATION
+IMAGEAPI
+MapDebugInformation(
+ __in_opt HANDLE FileHandle,
+ __in PCSTR FileName,
+ __in_opt PCSTR SymbolPath,
+ __in ULONG ImageBase
+ );
+
+BOOL
+IMAGEAPI
+UnmapDebugInformation(
+ __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo
+ );
+
+#endif
+
+BOOL
+IMAGEAPI
+SearchTreeForFile(
+ __in PCSTR RootPath,
+ __in PCSTR InputPathName,
+ __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer
+ );
+
+BOOL
+IMAGEAPI
+SearchTreeForFileW(
+ __in PCWSTR RootPath,
+ __in PCWSTR InputPathName,
+ __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer
+ );
+
+typedef BOOL
+(CALLBACK *PENUMDIRTREE_CALLBACK)(
+ __in PCSTR FilePath,
+ __in_opt PVOID CallerData
+ );
+
+BOOL
+IMAGEAPI
+EnumDirTree(
+ __in_opt HANDLE hProcess,
+ __in PCSTR RootPath,
+ __in PCSTR InputPathName,
+ __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer,
+ __in_opt PENUMDIRTREE_CALLBACK cb,
+ __in_opt PVOID data
+ );
+
+typedef BOOL
+(CALLBACK *PENUMDIRTREE_CALLBACKW)(
+ __in PCWSTR FilePath,
+ __in_opt PVOID CallerData
+ );
+
+BOOL
+IMAGEAPI
+EnumDirTreeW(
+ __in_opt HANDLE hProcess,
+ __in PCWSTR RootPath,
+ __in PCWSTR InputPathName,
+ __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer,
+ __in_opt PENUMDIRTREE_CALLBACKW cb,
+ __in_opt PVOID data
+ );
+
+BOOL
+IMAGEAPI
+MakeSureDirectoryPathExists(
+ __in PCSTR DirPath
+ );
+
+//
+// UnDecorateSymbolName Flags
+//
+
+#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
+#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords
+#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords
+#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration
+#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model
+#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier
+#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration
+#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration
+#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type
+#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members
+#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions
+#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members
+#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns
+#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names
+#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
+ // return just [scope::]name. Does expand template params
+#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function
+#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc)
+
+DWORD
+IMAGEAPI
+WINAPI
+UnDecorateSymbolName(
+ __in PCSTR name,
+ __out_ecount(maxStringLength) PSTR outputString,
+ __in DWORD maxStringLength,
+ __in DWORD flags
+ );
+
+DWORD
+IMAGEAPI
+WINAPI
+UnDecorateSymbolNameW(
+ __in PCWSTR name,
+ __out_ecount(maxStringLength) PWSTR outputString,
+ __in DWORD maxStringLength,
+ __in DWORD flags
+ );
+
+//
+// these values are used for synthesized file types
+// that can be passed in as image headers instead of
+// the standard ones from ntimage.h
+//
+
+#define DBHHEADER_DEBUGDIRS 0x1
+#define DBHHEADER_CVMISC 0x2
+
+typedef struct _MODLOAD_DATA {
+ DWORD ssize; // size of this struct
+ DWORD ssig; // signature identifying the passed data
+ PVOID data; // pointer to passed data
+ DWORD size; // size of passed data
+ DWORD flags; // options
+} MODLOAD_DATA, *PMODLOAD_DATA;
+
+typedef struct _MODLOAD_CVMISC {
+ DWORD oCV; // ofset to the codeview record
+ size_t cCV; // size of the codeview record
+ DWORD oMisc; // offset to the misc record
+ size_t cMisc; // size of the misc record
+ DWORD dtImage; // datetime stamp of the image
+ DWORD cImage; // size of the image
+} MODLOAD_CVMISC, *PMODLOAD_CVMISC;
+
+//
+// StackWalking API
+//
+
+typedef enum {
+ AddrMode1616,
+ AddrMode1632,
+ AddrModeReal,
+ AddrModeFlat
+} ADDRESS_MODE;
+
+typedef struct _tagADDRESS64 {
+ DWORD64 Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+} ADDRESS64, *LPADDRESS64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define ADDRESS ADDRESS64
+#define LPADDRESS LPADDRESS64
+#else
+typedef struct _tagADDRESS {
+ DWORD Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+} ADDRESS, *LPADDRESS;
+
+__inline
+void
+Address32To64(
+ __in LPADDRESS a32,
+ __out LPADDRESS64 a64
+ )
+{
+ a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset;
+ a64->Segment = a32->Segment;
+ a64->Mode = a32->Mode;
+}
+
+__inline
+void
+Address64To32(
+ __in LPADDRESS64 a64,
+ __out LPADDRESS a32
+ )
+{
+ a32->Offset = (ULONG)a64->Offset;
+ a32->Segment = a64->Segment;
+ a32->Mode = a64->Mode;
+}
+#endif
+
+//
+// This structure is included in the STACKFRAME structure,
+// and is used to trace through usermode callbacks in a thread's
+// kernel stack. The values must be copied by the kernel debugger
+// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets.
+//
+
+//
+// New KDHELP structure for 64 bit system support.
+// This structure is preferred in new code.
+//
+typedef struct _KDHELP64 {
+
+ //
+ // address of kernel thread object, as provided in the
+ // WAIT_STATE_CHANGE packet.
+ //
+ DWORD64 Thread;
+
+ //
+ // offset in thread object to pointer to the current callback frame
+ // in kernel stack.
+ //
+ DWORD ThCallbackStack;
+
+ //
+ // offset in thread object to pointer to the current callback backing
+ // store frame in kernel stack.
+ //
+ DWORD ThCallbackBStore;
+
+ //
+ // offsets to values in frame:
+ //
+ // address of next callback frame
+ DWORD NextCallback;
+
+ // address of saved frame pointer (if applicable)
+ DWORD FramePointer;
+
+
+ //
+ // Address of the kernel function that calls out to user mode
+ //
+ DWORD64 KiCallUserMode;
+
+ //
+ // Address of the user mode dispatcher function
+ //
+ DWORD64 KeUserCallbackDispatcher;
+
+ //
+ // Lowest kernel mode address
+ //
+ DWORD64 SystemRangeStart;
+
+ //
+ // Address of the user mode exception dispatcher function.
+ // Added in API version 10.
+ //
+ DWORD64 KiUserExceptionDispatcher;
+
+ //
+ // Stack bounds, added in API version 11.
+ //
+ DWORD64 StackBase;
+ DWORD64 StackLimit;
+
+ DWORD64 Reserved[5];
+
+} KDHELP64, *PKDHELP64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define KDHELP KDHELP64
+#define PKDHELP PKDHELP64
+#else
+typedef struct _KDHELP {
+
+ //
+ // address of kernel thread object, as provided in the
+ // WAIT_STATE_CHANGE packet.
+ //
+ DWORD Thread;
+
+ //
+ // offset in thread object to pointer to the current callback frame
+ // in kernel stack.
+ //
+ DWORD ThCallbackStack;
+
+ //
+ // offsets to values in frame:
+ //
+ // address of next callback frame
+ DWORD NextCallback;
+
+ // address of saved frame pointer (if applicable)
+ DWORD FramePointer;
+
+ //
+ // Address of the kernel function that calls out to user mode
+ //
+ DWORD KiCallUserMode;
+
+ //
+ // Address of the user mode dispatcher function
+ //
+ DWORD KeUserCallbackDispatcher;
+
+ //
+ // Lowest kernel mode address
+ //
+ DWORD SystemRangeStart;
+
+ //
+ // offset in thread object to pointer to the current callback backing
+ // store frame in kernel stack.
+ //
+ DWORD ThCallbackBStore;
+
+ //
+ // Address of the user mode exception dispatcher function.
+ // Added in API version 10.
+ //
+ DWORD KiUserExceptionDispatcher;
+
+ //
+ // Stack bounds, added in API version 11.
+ //
+ DWORD StackBase;
+ DWORD StackLimit;
+
+ DWORD Reserved[5];
+
+} KDHELP, *PKDHELP;
+
+__inline
+void
+KdHelp32To64(
+ __in PKDHELP p32,
+ __out PKDHELP64 p64
+ )
+{
+ p64->Thread = p32->Thread;
+ p64->ThCallbackStack = p32->ThCallbackStack;
+ p64->NextCallback = p32->NextCallback;
+ p64->FramePointer = p32->FramePointer;
+ p64->KiCallUserMode = p32->KiCallUserMode;
+ p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
+ p64->SystemRangeStart = p32->SystemRangeStart;
+ p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher;
+ p64->StackBase = p32->StackBase;
+ p64->StackLimit = p32->StackLimit;
+}
+#endif
+
+typedef struct _tagSTACKFRAME64 {
+ ADDRESS64 AddrPC; // program counter
+ ADDRESS64 AddrReturn; // return address
+ ADDRESS64 AddrFrame; // frame pointer
+ ADDRESS64 AddrStack; // stack pointer
+ ADDRESS64 AddrBStore; // backing store pointer
+ PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
+ DWORD64 Params[4]; // possible arguments to the function
+ BOOL Far; // WOW far call
+ BOOL Virtual; // is this a virtual frame?
+ DWORD64 Reserved[3];
+ KDHELP64 KdHelp;
+} STACKFRAME64, *LPSTACKFRAME64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define STACKFRAME STACKFRAME64
+#define LPSTACKFRAME LPSTACKFRAME64
+#else
+typedef struct _tagSTACKFRAME {
+ ADDRESS AddrPC; // program counter
+ ADDRESS AddrReturn; // return address
+ ADDRESS AddrFrame; // frame pointer
+ ADDRESS AddrStack; // stack pointer
+ PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
+ DWORD Params[4]; // possible arguments to the function
+ BOOL Far; // WOW far call
+ BOOL Virtual; // is this a virtual frame?
+ DWORD Reserved[3];
+ KDHELP KdHelp;
+ ADDRESS AddrBStore; // backing store pointer
+} STACKFRAME, *LPSTACKFRAME;
+#endif
+
+
+typedef
+BOOL
+(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
+ __in HANDLE hProcess,
+ __in DWORD64 qwBaseAddress,
+ __out_bcount(nSize) PVOID lpBuffer,
+ __in DWORD nSize,
+ __out LPDWORD lpNumberOfBytesRead
+ );
+
+typedef
+PVOID
+(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
+ __in HANDLE ahProcess,
+ __in DWORD64 AddrBase
+ );
+
+typedef
+DWORD64
+(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
+ __in HANDLE hProcess,
+ __in DWORD64 Address
+ );
+
+typedef
+DWORD64
+(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
+ __in HANDLE hProcess,
+ __in HANDLE hThread,
+ __in LPADDRESS64 lpaddr
+ );
+
+BOOL
+IMAGEAPI
+StackWalk64(
+ __in DWORD MachineType,
+ __in HANDLE hProcess,
+ __in HANDLE hThread,
+ __inout LPSTACKFRAME64 StackFrame,
+ __inout PVOID ContextRecord,
+ __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
+#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
+#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
+#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
+
+#define StackWalk StackWalk64
+
+#else
+
+typedef
+BOOL
+(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)(
+ __in HANDLE hProcess,
+ __in DWORD lpBaseAddress,
+ __out_bcount(nSize) PVOID lpBuffer,
+ __in DWORD nSize,
+ __out PDWORD lpNumberOfBytesRead
+ );
+
+typedef
+PVOID
+(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)(
+ __in HANDLE hProcess,
+ __in DWORD AddrBase
+ );
+
+typedef
+DWORD
+(__stdcall *PGET_MODULE_BASE_ROUTINE)(
+ __in HANDLE hProcess,
+ __in DWORD Address
+ );
+
+typedef
+DWORD
+(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)(
+ __in HANDLE hProcess,
+ __in HANDLE hThread,
+ __out LPADDRESS lpaddr
+ );
+
+BOOL
+IMAGEAPI
+StackWalk(
+ DWORD MachineType,
+ __in HANDLE hProcess,
+ __in HANDLE hThread,
+ __inout LPSTACKFRAME StackFrame,
+ __inout PVOID ContextRecord,
+ __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
+ __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
+ __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
+ __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
+ );
+
+#endif
+
+
+#define API_VERSION_NUMBER 11
+
+typedef struct API_VERSION {
+ USHORT MajorVersion;
+ USHORT MinorVersion;
+ USHORT Revision;
+ USHORT Reserved;
+} API_VERSION, *LPAPI_VERSION;
+
+LPAPI_VERSION
+IMAGEAPI
+ImagehlpApiVersion(
+ VOID
+ );
+
+LPAPI_VERSION
+IMAGEAPI
+ImagehlpApiVersionEx(
+ __in LPAPI_VERSION AppVersion
+ );
+
+DWORD
+IMAGEAPI
+GetTimestampForLoadedLibrary(
+ __in HMODULE Module
+ );
+
+//
+// typedefs for function pointers
+//
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(
+ __in PCSTR ModuleName,
+ __in DWORD64 BaseOfDll,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)(
+ __in PCWSTR ModuleName,
+ __in DWORD64 BaseOfDll,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(
+ __in PCSTR ModuleName,
+ __in DWORD64 ModuleBase,
+ __in ULONG ModuleSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)(
+ __in PCWSTR ModuleName,
+ __in DWORD64 ModuleBase,
+ __in ULONG ModuleSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(
+ __in PCSTR SymbolName,
+ __in DWORD64 SymbolAddress,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(
+ __in PCWSTR SymbolName,
+ __in DWORD64 SymbolAddress,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(
+ __in HANDLE hProcess,
+ __in ULONG ActionCode,
+ __in_opt ULONG64 CallbackData,
+ __in_opt ULONG64 UserContext
+ );
+
+typedef
+PVOID
+(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(
+ __in HANDLE hProcess,
+ __in DWORD AddrBase,
+ __in_opt PVOID UserContext
+ );
+
+typedef
+PVOID
+(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(
+ __in HANDLE hProcess,
+ __in ULONG64 AddrBase,
+ __in ULONG64 UserContext
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
+#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
+#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
+#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
+
+#else
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMMODULES_CALLBACK)(
+ __in PCSTR ModuleName,
+ __in ULONG BaseOfDll,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(
+ __in PCSTR SymbolName,
+ __in ULONG SymbolAddress,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(
+ __in PCWSTR SymbolName,
+ __in ULONG SymbolAddress,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PENUMLOADED_MODULES_CALLBACK)(
+ __in PCSTR ModuleName,
+ __in ULONG ModuleBase,
+ __in ULONG ModuleSize,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(
+ __in HANDLE hProcess,
+ __in ULONG ActionCode,
+ __in_opt PVOID CallbackData,
+ __in_opt PVOID UserContext
+ );
+
+#endif
+
+
+// values found in SYMBOL_INFO.Tag
+//
+// This was taken from cvconst.h and should
+// not override any values found there.
+//
+// #define _NO_CVCONST_H_ if you don't
+// have access to that file...
+
+#ifdef _NO_CVCONST_H
+
+// DIA enums
+
+enum SymTagEnum
+{
+ SymTagNull,
+ SymTagExe,
+ SymTagCompiland,
+ SymTagCompilandDetails,
+ SymTagCompilandEnv,
+ SymTagFunction,
+ SymTagBlock,
+ SymTagData,
+ SymTagAnnotation,
+ SymTagLabel,
+ SymTagPublicSymbol,
+ SymTagUDT,
+ SymTagEnum,
+ SymTagFunctionType,
+ SymTagPointerType,
+ SymTagArrayType,
+ SymTagBaseType,
+ SymTagTypedef,
+ SymTagBaseClass,
+ SymTagFriend,
+ SymTagFunctionArgType,
+ SymTagFuncDebugStart,
+ SymTagFuncDebugEnd,
+ SymTagUsingNamespace,
+ SymTagVTableShape,
+ SymTagVTable,
+ SymTagCustom,
+ SymTagThunk,
+ SymTagCustomType,
+ SymTagManagedType,
+ SymTagDimension,
+ SymTagMax
+};
+
+#endif
+
+//
+// flags found in SYMBOL_INFO.Flags
+//
+
+#define SYMFLAG_VALUEPRESENT 0x00000001
+#define SYMFLAG_REGISTER 0x00000008
+#define SYMFLAG_REGREL 0x00000010
+#define SYMFLAG_FRAMEREL 0x00000020
+#define SYMFLAG_PARAMETER 0x00000040
+#define SYMFLAG_LOCAL 0x00000080
+#define SYMFLAG_CONSTANT 0x00000100
+#define SYMFLAG_EXPORT 0x00000200
+#define SYMFLAG_FORWARDER 0x00000400
+#define SYMFLAG_FUNCTION 0x00000800
+#define SYMFLAG_VIRTUAL 0x00001000
+#define SYMFLAG_THUNK 0x00002000
+#define SYMFLAG_TLSREL 0x00004000
+#define SYMFLAG_SLOT 0x00008000
+#define SYMFLAG_ILREL 0x00010000
+#define SYMFLAG_METADATA 0x00020000
+#define SYMFLAG_CLR_TOKEN 0x00040000
+
+// this resets SymNext/Prev to the beginning
+// of the module passed in the address field
+
+#define SYMFLAG_RESET 0x80000000
+
+//
+// symbol type enumeration
+//
+typedef enum {
+ SymNone = 0,
+ SymCoff,
+ SymCv,
+ SymPdb,
+ SymExport,
+ SymDeferred,
+ SymSym, // .sym file
+ SymDia,
+ SymVirtual,
+ NumSymTypes
+} SYM_TYPE;
+
+//
+// symbol data structure
+//
+
+typedef struct _IMAGEHLP_SYMBOL64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
+ DWORD64 Address; // virtual address including dll base address
+ DWORD Size; // estimated size of symbol, can be zero
+ DWORD Flags; // info about the symbols, see the SYMF defines
+ DWORD MaxNameLength; // maximum size of symbol name in 'Name'
+ CHAR Name[1]; // symbol name (null terminated string)
+} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+
+typedef struct _IMAGEHLP_SYMBOL64_PACKAGE {
+ IMAGEHLP_SYMBOL64 sym;
+ CHAR name[MAX_SYM_NAME + 1];
+} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE;
+
+typedef struct _IMAGEHLP_SYMBOLW64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64)
+ DWORD64 Address; // virtual address including dll base address
+ DWORD Size; // estimated size of symbol, can be zero
+ DWORD Flags; // info about the symbols, see the SYMF defines
+ DWORD MaxNameLength; // maximum size of symbol name in 'Name'
+ WCHAR Name[1]; // symbol name (null terminated string)
+} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64;
+
+typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE {
+ IMAGEHLP_SYMBOLW64 sym;
+ WCHAR name[MAX_SYM_NAME + 1];
+} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+
+ #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
+ #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
+ #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE
+ #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE
+ #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64
+ #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64
+ #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE
+ #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE
+
+#else
+
+ typedef struct _IMAGEHLP_SYMBOL {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL)
+ DWORD Address; // virtual address including dll base address
+ DWORD Size; // estimated size of symbol, can be zero
+ DWORD Flags; // info about the symbols, see the SYMF defines
+ DWORD MaxNameLength; // maximum size of symbol name in 'Name'
+ CHAR Name[1]; // symbol name (null terminated string)
+ } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;
+
+ typedef struct _IMAGEHLP_SYMBOL_PACKAGE {
+ IMAGEHLP_SYMBOL sym;
+ CHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE;
+
+ typedef struct _IMAGEHLP_SYMBOLW {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW)
+ DWORD Address; // virtual address including dll base address
+ DWORD Size; // estimated size of symbol, can be zero
+ DWORD Flags; // info about the symbols, see the SYMF defines
+ DWORD MaxNameLength; // maximum size of symbol name in 'Name'
+ WCHAR Name[1]; // symbol name (null terminated string)
+ } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW;
+
+ typedef struct _IMAGEHLP_SYMBOLW_PACKAGE {
+ IMAGEHLP_SYMBOLW sym;
+ WCHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE;
+
+#endif
+
+//
+// module data structure
+//
+
+typedef struct _IMAGEHLP_MODULE64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ CHAR ModuleName[32]; // module name
+ CHAR ImageName[256]; // image name
+ CHAR LoadedImageName[256]; // symbol file name
+ // new elements: 07-Jun-2002
+ CHAR LoadedPdbName[256]; // pdb file name
+ DWORD CVSig; // Signature of the CV record in the debug directories
+ CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
+ DWORD PdbSig; // Signature of PDB
+ GUID PdbSig70; // Signature of PDB (VC 7 and up)
+ DWORD PdbAge; // DBI age of pdb
+ BOOL PdbUnmatched; // loaded an unmatched pdb
+ BOOL DbgUnmatched; // loaded an unmatched dbg
+ BOOL LineNumbers; // we have line number information
+ BOOL GlobalSymbols; // we have internal symbol information
+ BOOL TypeInfo; // we have type information
+ // new elements: 17-Dec-2003
+ BOOL SourceIndexed; // pdb supports source server
+ BOOL Publics; // contains public symbols
+} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
+
+typedef struct _IMAGEHLP_MODULEW64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ WCHAR ModuleName[32]; // module name
+ WCHAR ImageName[256]; // image name
+ // new elements: 07-Jun-2002
+ WCHAR LoadedImageName[256]; // symbol file name
+ WCHAR LoadedPdbName[256]; // pdb file name
+ DWORD CVSig; // Signature of the CV record in the debug directories
+ WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record
+ DWORD PdbSig; // Signature of PDB
+ GUID PdbSig70; // Signature of PDB (VC 7 and up)
+ DWORD PdbAge; // DBI age of pdb
+ BOOL PdbUnmatched; // loaded an unmatched pdb
+ BOOL DbgUnmatched; // loaded an unmatched dbg
+ BOOL LineNumbers; // we have line number information
+ BOOL GlobalSymbols; // we have internal symbol information
+ BOOL TypeInfo; // we have type information
+ // new elements: 17-Dec-2003
+ BOOL SourceIndexed; // pdb supports source server
+ BOOL Publics; // contains public symbols
+} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
+#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
+#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
+#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
+#else
+typedef struct _IMAGEHLP_MODULE {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE)
+ DWORD BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ CHAR ModuleName[32]; // module name
+ CHAR ImageName[256]; // image name
+ CHAR LoadedImageName[256]; // symbol file name
+} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE;
+
+typedef struct _IMAGEHLP_MODULEW {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE)
+ DWORD BaseOfImage; // base load address of module
+ DWORD ImageSize; // virtual size of the loaded module
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ DWORD CheckSum; // checksum from the pe header
+ DWORD NumSyms; // number of symbols in the symbol table
+ SYM_TYPE SymType; // type of symbols loaded
+ WCHAR ModuleName[32]; // module name
+ WCHAR ImageName[256]; // image name
+ WCHAR LoadedImageName[256]; // symbol file name
+} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW;
+#endif
+
+//
+// source file line data structure
+//
+
+typedef struct _IMAGEHLP_LINE64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
+ PVOID Key; // internal
+ DWORD LineNumber; // line number in file
+ PCHAR FileName; // full filename
+ DWORD64 Address; // first instruction of line
+} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+
+typedef struct _IMAGEHLP_LINEW64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
+ PVOID Key; // internal
+ DWORD LineNumber; // line number in file
+ PWSTR FileName; // full filename
+ DWORD64 Address; // first instruction of line
+} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_LINE IMAGEHLP_LINE64
+#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
+#else
+typedef struct _IMAGEHLP_LINE {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE)
+ PVOID Key; // internal
+ DWORD LineNumber; // line number in file
+ PCHAR FileName; // full filename
+ DWORD Address; // first instruction of line
+} IMAGEHLP_LINE, *PIMAGEHLP_LINE;
+
+typedef struct _IMAGEHLP_LINEW {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
+ PVOID Key; // internal
+ DWORD LineNumber; // line number in file
+ PCHAR FileName; // full filename
+ DWORD64 Address; // first instruction of line
+} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW;
+#endif
+
+//
+// source file structure
+//
+
+typedef struct _SOURCEFILE {
+ DWORD64 ModBase; // base address of loaded module
+ PCHAR FileName; // full filename of source
+} SOURCEFILE, *PSOURCEFILE;
+
+typedef struct _SOURCEFILEW {
+ DWORD64 ModBase; // base address of loaded module
+ PWSTR FileName; // full filename of source
+} SOURCEFILEW, *PSOURCEFILEW;
+
+//
+// data structures used for registered symbol callbacks
+//
+
+#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001
+#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002
+#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003
+#define CBA_SYMBOLS_UNLOADED 0x00000004
+#define CBA_DUPLICATE_SYMBOL 0x00000005
+#define CBA_READ_MEMORY 0x00000006
+#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007
+#define CBA_SET_OPTIONS 0x00000008
+#define CBA_EVENT 0x00000010
+#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020
+#define CBA_DEBUG_INFO 0x10000000
+#define CBA_SRCSRV_INFO 0x20000000
+#define CBA_SRCSRV_EVENT 0x40000000
+
+typedef struct _IMAGEHLP_CBA_READ_MEMORY {
+ DWORD64 addr; // address to read from
+ PVOID buf; // buffer to read to
+ DWORD bytes; // amount of bytes to read
+ DWORD *bytesread; // pointer to store amount of bytes read
+} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY;
+
+enum {
+ sevInfo = 0,
+ sevProblem,
+ sevAttn,
+ sevFatal,
+ sevMax // unused
+};
+
+#define EVENT_SRCSPEW_START 100
+#define EVENT_SRCSPEW 100
+#define EVENT_SRCSPEW_END 199
+
+typedef struct _IMAGEHLP_CBA_EVENT {
+ DWORD severity; // values from sevInfo to sevFatal
+ DWORD code; // numerical code IDs the error
+ PCHAR desc; // may contain a text description of the error
+ PVOID object; // value dependant upon the error code
+} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT;
+
+typedef struct _IMAGEHLP_CBA_EVENTW {
+ DWORD severity; // values from sevInfo to sevFatal
+ DWORD code; // numerical code IDs the error
+ PCWSTR desc; // may contain a text description of the error
+ PVOID object; // value dependant upon the error code
+} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW;
+
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD CheckSum; // checksum from the pe header
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ CHAR FileName[MAX_PATH]; // symbols file or image name
+ BOOLEAN Reparse; // load failure reparse
+ HANDLE hFile; // file handle, if passed
+ DWORD Flags; //
+} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
+
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64)
+ DWORD64 BaseOfImage; // base load address of module
+ DWORD CheckSum; // checksum from the pe header
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ WCHAR FileName[MAX_PATH + 1]; // symbols file or image name
+ BOOLEAN Reparse; // load failure reparse
+ HANDLE hFile; // file handle, if passed
+ DWORD Flags; //
+} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64;
+
+#define DSLFLAG_MISMATCHED_PDB 0x1
+#define DSLFLAG_MISMATCHED_DBG 0x2
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#else
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD)
+ DWORD BaseOfImage; // base load address of module
+ DWORD CheckSum; // checksum from the pe header
+ DWORD TimeDateStamp; // date/time stamp from pe header
+ CHAR FileName[MAX_PATH]; // symbols file or image name
+ BOOLEAN Reparse; // load failure reparse
+ HANDLE hFile; // file handle, if passed
+} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
+#endif
+
+typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
+ DWORD NumberOfDups; // number of duplicates in the Symbol array
+ PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols
+ DWORD SelectedSymbol; // symbol selected (-1 to start)
+} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64;
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
+#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
+#else
+typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
+ DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL)
+ DWORD NumberOfDups; // number of duplicates in the Symbol array
+ PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols
+ DWORD SelectedSymbol; // symbol selected (-1 to start)
+} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;
+#endif
+
+// If dbghelp ever needs to display graphical UI, it will use this as the parent window.
+
+BOOL
+IMAGEAPI
+SymSetParentWindow(
+ __in HWND hwnd
+ );
+
+PCHAR
+IMAGEAPI
+SymSetHomeDirectory(
+ __in_opt HANDLE hProcess,
+ __in_opt PCSTR dir
+ );
+
+PWSTR
+IMAGEAPI
+SymSetHomeDirectoryW(
+ __in_opt HANDLE hProcess,
+ __in_opt PCWSTR dir
+ );
+
+PCHAR
+IMAGEAPI
+SymGetHomeDirectory(
+ __in DWORD type,
+ __out_ecount(size) PSTR dir,
+ __in size_t size
+ );
+
+PWSTR
+IMAGEAPI
+SymGetHomeDirectoryW(
+ __in DWORD type,
+ __out_ecount(size) PWSTR dir,
+ __in size_t size
+ );
+
+enum {
+ hdBase = 0, // root directory for dbghelp
+ hdSym, // where symbols are stored
+ hdSrc, // where source is stored
+ hdMax // end marker
+};
+
+typedef struct _OMAP {
+ ULONG rva;
+ ULONG rvaTo;
+} OMAP, *POMAP;
+
+BOOL
+IMAGEAPI
+SymGetOmaps(
+ __in HANDLE hProcess,
+ __in DWORD64 BaseOfDll,
+ __out POMAP *OmapTo,
+ __out PDWORD64 cOmapTo,
+ __out POMAP *OmapFrom,
+ __out PDWORD64 cOmapFrom
+ );
+
+//
+// options that are set/returned by SymSetOptions() & SymGetOptions()
+// these are used as a mask
+//
+#define SYMOPT_CASE_INSENSITIVE 0x00000001
+#define SYMOPT_UNDNAME 0x00000002
+#define SYMOPT_DEFERRED_LOADS 0x00000004
+#define SYMOPT_NO_CPP 0x00000008
+#define SYMOPT_LOAD_LINES 0x00000010
+#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
+#define SYMOPT_LOAD_ANYTHING 0x00000040
+#define SYMOPT_IGNORE_CVREC 0x00000080
+#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
+#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
+#define SYMOPT_EXACT_SYMBOLS 0x00000400
+#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
+#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
+#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
+#define SYMOPT_PUBLICS_ONLY 0x00004000
+#define SYMOPT_NO_PUBLICS 0x00008000
+#define SYMOPT_AUTO_PUBLICS 0x00010000
+#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
+#define SYMOPT_SECURE 0x00040000
+#define SYMOPT_NO_PROMPTS 0x00080000
+#define SYMOPT_OVERWRITE 0x00100000
+#define SYMOPT_IGNORE_IMAGEDIR 0x00200000
+#define SYMOPT_FLAT_DIRECTORY 0x00400000
+#define SYMOPT_FAVOR_COMPRESSED 0x00800000
+#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000
+#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000
+
+#define SYMOPT_DEBUG 0x80000000
+
+DWORD
+IMAGEAPI
+SymSetOptions(
+ __in DWORD SymOptions
+ );
+
+DWORD
+IMAGEAPI
+SymGetOptions(
+ VOID
+ );
+
+BOOL
+IMAGEAPI
+SymCleanup(
+ __in HANDLE hProcess
+ );
+
+BOOL
+IMAGEAPI
+SymMatchString(
+ __in PCSTR string,
+ __in PCSTR expression,
+ __in BOOL fCase
+ );
+
+BOOL
+IMAGEAPI
+SymMatchStringA(
+ __in PCSTR string,
+ __in PCSTR expression,
+ __in BOOL fCase
+ );
+
+BOOL
+IMAGEAPI
+SymMatchStringW(
+ __in PCWSTR string,
+ __in PCWSTR expression,
+ __in BOOL fCase
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)(
+ __in PSOURCEFILE pSourceFile,
+ __in_opt PVOID UserContext
+ );
+
+// for backwards compatibility - don't use this
+#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK
+
+BOOL
+IMAGEAPI
+SymEnumSourceFiles(
+ __in HANDLE hProcess,
+ __in ULONG64 ModBase,
+ __in_opt PCSTR Mask,
+ __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)(
+ __in PSOURCEFILEW pSourceFile,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSourceFilesW(
+ __in HANDLE hProcess,
+ __in ULONG64 ModBase,
+ __in_opt PCWSTR Mask,
+ __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumerateModules64(
+ __in HANDLE hProcess,
+ __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumerateModulesW64(
+ __in HANDLE hProcess,
+ __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymEnumerateModules SymEnumerateModules64
+#else
+BOOL
+IMAGEAPI
+SymEnumerateModules(
+ __in HANDLE hProcess,
+ __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
+ __in_opt PVOID UserContext
+ );
+#endif
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesEx(
+ __in HANDLE hProcess,
+ __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesExW(
+ __in HANDLE hProcess,
+ __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModules64(
+ __in HANDLE hProcess,
+ __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+EnumerateLoadedModulesW64(
+ __in HANDLE hProcess,
+ __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
+ __in_opt PVOID UserContext
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define EnumerateLoadedModules EnumerateLoadedModules64
+#else
+BOOL
+IMAGEAPI
+EnumerateLoadedModules(
+ __in HANDLE hProcess,
+ __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
+ __in_opt PVOID UserContext
+ );
+#endif
+
+PVOID
+IMAGEAPI
+SymFunctionTableAccess64(
+ __in HANDLE hProcess,
+ __in DWORD64 AddrBase
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymFunctionTableAccess SymFunctionTableAccess64
+#else
+PVOID
+IMAGEAPI
+SymFunctionTableAccess(
+ __in HANDLE hProcess,
+ __in DWORD AddrBase
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetUnwindInfo(
+ __in HANDLE hProcess,
+ __in DWORD64 Address,
+ __out_bcount_opt(*Size) PVOID Buffer,
+ __inout PULONG Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetModuleInfo64(
+ __in HANDLE hProcess,
+ __in DWORD64 qwAddr,
+ __out PIMAGEHLP_MODULE64 ModuleInfo
+ );
+
+BOOL
+IMAGEAPI
+SymGetModuleInfoW64(
+ __in HANDLE hProcess,
+ __in DWORD64 qwAddr,
+ __out PIMAGEHLP_MODULEW64 ModuleInfo
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetModuleInfo SymGetModuleInfo64
+#define SymGetModuleInfoW SymGetModuleInfoW64
+#else
+BOOL
+IMAGEAPI
+SymGetModuleInfo(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr,
+ __out PIMAGEHLP_MODULE ModuleInfo
+ );
+
+BOOL
+IMAGEAPI
+SymGetModuleInfoW(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr,
+ __out PIMAGEHLP_MODULEW ModuleInfo
+ );
+#endif
+
+DWORD64
+IMAGEAPI
+SymGetModuleBase64(
+ __in HANDLE hProcess,
+ __in DWORD64 qwAddr
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetModuleBase SymGetModuleBase64
+#else
+DWORD
+IMAGEAPI
+SymGetModuleBase(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr
+ );
+#endif
+
+typedef struct _SRCCODEINFO {
+ DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO)
+ PVOID Key; // not used
+ DWORD64 ModBase; // base address of module this applies to
+ CHAR Obj[MAX_PATH + 1]; // the object file within the module
+ CHAR FileName[MAX_PATH + 1]; // full filename
+ DWORD LineNumber; // line number in file
+ DWORD64 Address; // first instruction of line
+} SRCCODEINFO, *PSRCCODEINFO;
+
+typedef struct _SRCCODEINFOW {
+ DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO)
+ PVOID Key; // not used
+ DWORD64 ModBase; // base address of module this applies to
+ WCHAR Obj[MAX_PATH + 1]; // the object file within the module
+ WCHAR FileName[MAX_PATH + 1]; // full filename
+ DWORD LineNumber; // line number in file
+ DWORD64 Address; // first instruction of line
+} SRCCODEINFOW, *PSRCCODEINFOW;
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMLINES_CALLBACK)(
+ __in PSRCCODEINFO LineInfo,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumLines(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCSTR Obj,
+ __in_opt PCSTR File,
+ __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMLINES_CALLBACKW)(
+ __in PSRCCODEINFOW LineInfo,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumLinesW(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCWSTR Obj,
+ __in_opt PCWSTR File,
+ __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddr64(
+ __in HANDLE hProcess,
+ __in DWORD64 qwAddr,
+ __out PDWORD pdwDisplacement,
+ __out PIMAGEHLP_LINE64 Line64
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddrW64(
+ __in HANDLE hProcess,
+ __in DWORD64 dwAddr,
+ __out PDWORD pdwDisplacement,
+ __out PIMAGEHLP_LINEW64 Line
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSourceLines(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCSTR Obj,
+ __in_opt PCSTR File,
+ __in_opt DWORD Line,
+ __in DWORD Flags,
+ __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSourceLinesW(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCWSTR Obj,
+ __in_opt PCWSTR File,
+ __in_opt DWORD Line,
+ __in DWORD Flags,
+ __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback,
+ __in_opt PVOID UserContext
+ );
+
+// flags for SymEnumSourceLines
+
+#define ESLFLAG_FULLPATH 0x1
+#define ESLFLAG_NEAREST 0x2
+#define ESLFLAG_PREV 0x4
+#define ESLFLAG_NEXT 0x8
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineFromAddr SymGetLineFromAddr64
+#define SymGetLineFromAddrW SymGetLineFromAddrW64
+#else
+BOOL
+IMAGEAPI
+SymGetLineFromAddr(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr,
+ __out PDWORD pdwDisplacement,
+ __out PIMAGEHLP_LINE Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineFromAddrW(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr,
+ __out PDWORD pdwDisplacement,
+ __out PIMAGEHLP_LINEW Line
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLineFromName64(
+ __in HANDLE hProcess,
+ __in_opt PCSTR ModuleName,
+ __in_opt PCSTR FileName,
+ __in DWORD dwLineNumber,
+ __out PLONG plDisplacement,
+ __inout PIMAGEHLP_LINE64 Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineFromNameW64(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR ModuleName,
+ __in_opt PCWSTR FileName,
+ __in DWORD dwLineNumber,
+ __out PLONG plDisplacement,
+ __inout PIMAGEHLP_LINEW64 Line
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineFromName SymGetLineFromName64
+#else
+BOOL
+IMAGEAPI
+SymGetLineFromName(
+ __in HANDLE hProcess,
+ __in_opt PCSTR ModuleName,
+ __in_opt PCSTR FileName,
+ __in DWORD dwLineNumber,
+ __out PLONG plDisplacement,
+ __inout PIMAGEHLP_LINE Line
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLineNext64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINE64 Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineNextW64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINEW64 Line
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLineNext SymGetLineNext64
+#else
+BOOL
+IMAGEAPI
+SymGetLineNext(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINE Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLineNextW(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINEW Line
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetLinePrev64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINE64 Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLinePrevW64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINEW64 Line
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetLinePrev SymGetLinePrev64
+#else
+BOOL
+IMAGEAPI
+SymGetLinePrev(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINE Line
+ );
+
+BOOL
+IMAGEAPI
+SymGetLinePrevW(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_LINEW Line
+ );
+#endif
+
+ULONG
+IMAGEAPI
+SymGetFileLineOffsets64(
+ __in HANDLE hProcess,
+ __in_opt PCSTR ModuleName,
+ __in PCSTR FileName,
+ __out_ecount(BufferLines) PDWORD64 Buffer,
+ __in ULONG BufferLines
+ );
+
+BOOL
+IMAGEAPI
+SymMatchFileName(
+ __in PCSTR FileName,
+ __in PCSTR Match,
+ __deref_opt_out PSTR *FileNameStop,
+ __deref_opt_out PSTR *MatchStop
+ );
+
+BOOL
+IMAGEAPI
+SymMatchFileNameW(
+ __in PCWSTR FileName,
+ __in PCWSTR Match,
+ __deref_opt_out PWSTR *FileNameStop,
+ __deref_opt_out PWSTR *MatchStop
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFile(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCSTR Params,
+ __in PCSTR FileSpec,
+ __out_ecount(Size) PSTR FilePath,
+ __in DWORD Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileW(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCWSTR Params,
+ __in PCWSTR FileSpec,
+ __out_ecount(Size) PWSTR FilePath,
+ __in DWORD Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileToken(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in PCSTR FileSpec,
+ __deref_out PVOID *Token,
+ __out DWORD *Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileTokenW(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in PCWSTR FileSpec,
+ __deref_out PVOID *Token,
+ __out DWORD *Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileFromToken(
+ __in HANDLE hProcess,
+ __in PVOID Token,
+ __in_opt PCSTR Params,
+ __out_ecount(Size) PSTR FilePath,
+ __in DWORD Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceFileFromTokenW(
+ __in HANDLE hProcess,
+ __in PVOID Token,
+ __in_opt PCWSTR Params,
+ __out_ecount(Size) PWSTR FilePath,
+ __in DWORD Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceVarFromToken(
+ __in HANDLE hProcess,
+ __in PVOID Token,
+ __in_opt PCSTR Params,
+ __in PCSTR VarName,
+ __out_ecount(Size) PSTR Value,
+ __in DWORD Size
+ );
+
+BOOL
+IMAGEAPI
+SymGetSourceVarFromTokenW(
+ __in HANDLE hProcess,
+ __in PVOID Token,
+ __in_opt PCWSTR Params,
+ __in PCWSTR VarName,
+ __out_ecount(Size) PWSTR Value,
+ __in DWORD Size
+ );
+
+typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size);
+
+BOOL
+IMAGEAPI
+SymEnumSourceFileTokens(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in PENUMSOURCEFILETOKENSCALLBACK Callback
+ );
+
+BOOL
+IMAGEAPI
+SymInitialize(
+ __in HANDLE hProcess,
+ __in_opt PCSTR UserSearchPath,
+ __in BOOL fInvadeProcess
+ );
+
+BOOL
+IMAGEAPI
+SymInitializeW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR UserSearchPath,
+ __in BOOL fInvadeProcess
+ );
+
+BOOL
+IMAGEAPI
+SymGetSearchPath(
+ __in HANDLE hProcess,
+ __out_ecount(SearchPathLength) PSTR SearchPath,
+ __in DWORD SearchPathLength
+ );
+
+BOOL
+IMAGEAPI
+SymGetSearchPathW(
+ __in HANDLE hProcess,
+ __out_ecount(SearchPathLength) PWSTR SearchPath,
+ __in DWORD SearchPathLength
+ );
+
+BOOL
+IMAGEAPI
+SymSetSearchPath(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SearchPath
+ );
+
+BOOL
+IMAGEAPI
+SymSetSearchPathW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SearchPath
+ );
+
+#define SLMFLAG_VIRTUAL 0x1
+#define SLMFLAG_ALT_INDEX 0x2
+#define SLMFLAG_NO_SYMBOLS 0x4
+
+DWORD64
+IMAGEAPI
+SymLoadModuleEx(
+ __in HANDLE hProcess,
+ __in_opt HANDLE hFile,
+ __in_opt PCSTR ImageName,
+ __in_opt PCSTR ModuleName,
+ __in DWORD64 BaseOfDll,
+ __in DWORD DllSize,
+ __in_opt PMODLOAD_DATA Data,
+ __in_opt DWORD Flags
+ );
+
+DWORD64
+IMAGEAPI
+SymLoadModuleExW(
+ __in HANDLE hProcess,
+ __in_opt HANDLE hFile,
+ __in_opt PCWSTR ImageName,
+ __in_opt PCWSTR ModuleName,
+ __in DWORD64 BaseOfDll,
+ __in DWORD DllSize,
+ __in_opt PMODLOAD_DATA Data,
+ __in_opt DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymUnloadModule64(
+ __in HANDLE hProcess,
+ __in DWORD64 BaseOfDll
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymUnloadModule SymUnloadModule64
+#else
+BOOL
+IMAGEAPI
+SymUnloadModule(
+ __in HANDLE hProcess,
+ __in DWORD BaseOfDll
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymUnDName64(
+ __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate
+ __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in
+ __in DWORD UnDecNameLength // Size of the buffer
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymUnDName SymUnDName64
+#else
+BOOL
+IMAGEAPI
+SymUnDName(
+ __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate
+ __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in
+ __in DWORD UnDecNameLength // Size of the buffer
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymRegisterCallback64(
+ __in HANDLE hProcess,
+ __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
+ __in ULONG64 UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymRegisterCallbackW64(
+ __in HANDLE hProcess,
+ __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
+ __in ULONG64 UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymRegisterFunctionEntryCallback64(
+ __in HANDLE hProcess,
+ __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,
+ __in ULONG64 UserContext
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymRegisterCallback SymRegisterCallback64
+#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
+#else
+BOOL
+IMAGEAPI
+SymRegisterCallback(
+ __in HANDLE hProcess,
+ __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymRegisterFunctionEntryCallback(
+ __in HANDLE hProcess,
+ __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,
+ __in_opt PVOID UserContext
+ );
+#endif
+
+
+typedef struct _IMAGEHLP_SYMBOL_SRC {
+ DWORD sizeofstruct;
+ DWORD type;
+ char file[MAX_PATH];
+} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC;
+
+typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP
+ USHORT dataLength;
+ USHORT leaf;
+ BYTE data[1];
+} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO;
+
+typedef struct _SYMBOL_INFO {
+ ULONG SizeOfStruct;
+ ULONG TypeIndex; // Type Index of symbol
+ ULONG64 Reserved[2];
+ ULONG Index;
+ ULONG Size;
+ ULONG64 ModBase; // Base Address of module comtaining this symbol
+ ULONG Flags;
+ ULONG64 Value; // Value of symbol, ValuePresent should be 1
+ ULONG64 Address; // Address of symbol including base address of module
+ ULONG Register; // register holding value or pointer to value
+ ULONG Scope; // scope of the symbol
+ ULONG Tag; // pdb classification
+ ULONG NameLen; // Actual length of name
+ ULONG MaxNameLen;
+ CHAR Name[1]; // Name of symbol
+} SYMBOL_INFO, *PSYMBOL_INFO;
+
+typedef struct _SYMBOL_INFO_PACKAGE {
+ SYMBOL_INFO si;
+ CHAR name[MAX_SYM_NAME + 1];
+} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE;
+
+typedef struct _SYMBOL_INFOW {
+ ULONG SizeOfStruct;
+ ULONG TypeIndex; // Type Index of symbol
+ ULONG64 Reserved[2];
+ ULONG Index;
+ ULONG Size;
+ ULONG64 ModBase; // Base Address of module comtaining this symbol
+ ULONG Flags;
+ ULONG64 Value; // Value of symbol, ValuePresent should be 1
+ ULONG64 Address; // Address of symbol including base address of module
+ ULONG Register; // register holding value or pointer to value
+ ULONG Scope; // scope of the symbol
+ ULONG Tag; // pdb classification
+ ULONG NameLen; // Actual length of name
+ ULONG MaxNameLen;
+ WCHAR Name[1]; // Name of symbol
+} SYMBOL_INFOW, *PSYMBOL_INFOW;
+
+typedef struct _SYMBOL_INFO_PACKAGEW {
+ SYMBOL_INFOW si;
+ WCHAR name[MAX_SYM_NAME + 1];
+} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW;
+
+typedef struct _IMAGEHLP_STACK_FRAME
+{
+ ULONG64 InstructionOffset;
+ ULONG64 ReturnOffset;
+ ULONG64 FrameOffset;
+ ULONG64 StackOffset;
+ ULONG64 BackingStoreOffset;
+ ULONG64 FuncTableEntry;
+ ULONG64 Params[4];
+ ULONG64 Reserved[5];
+ BOOL Virtual;
+ ULONG Reserved2;
+} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
+
+typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT;
+
+
+BOOL
+IMAGEAPI
+SymSetContext(
+ __in HANDLE hProcess,
+ __in PIMAGEHLP_STACK_FRAME StackFrame,
+ __in_opt PIMAGEHLP_CONTEXT Context
+ );
+
+BOOL
+IMAGEAPI
+SymSetScopeFromAddr(
+ __in HANDLE hProcess,
+ __in ULONG64 Address
+ );
+
+BOOL
+IMAGEAPI
+SymSetScopeFromIndex(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in DWORD Index
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)(
+ __in HANDLE hProcess,
+ __in PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumProcesses(
+ __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback,
+ __in PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymFromAddr(
+ __in HANDLE hProcess,
+ __in DWORD64 Address,
+ __out_opt PDWORD64 Displacement,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromAddrW(
+ __in HANDLE hProcess,
+ __in DWORD64 Address,
+ __out_opt PDWORD64 Displacement,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromToken(
+ __in HANDLE hProcess,
+ __in DWORD64 Base,
+ __in DWORD Token,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromTokenW(
+ __in HANDLE hProcess,
+ __in DWORD64 Base,
+ __in DWORD Token,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymNext(
+ __in HANDLE hProcess,
+ __inout PSYMBOL_INFO si
+ );
+
+BOOL
+IMAGEAPI
+SymNextW(
+ __in HANDLE hProcess,
+ __inout PSYMBOL_INFOW siw
+ );
+
+BOOL
+IMAGEAPI
+SymPrev(
+ __in HANDLE hProcess,
+ __inout PSYMBOL_INFO si
+ );
+
+BOOL
+IMAGEAPI
+SymPrevW(
+ __in HANDLE hProcess,
+ __inout PSYMBOL_INFOW siw
+ );
+
+// While SymFromName will provide a symbol from a name,
+// SymEnumSymbols can provide the same matching information
+// for ALL symbols with a matching name, even regular
+// expressions. That way you can search across modules
+// and differentiate between identically named symbols.
+
+BOOL
+IMAGEAPI
+SymFromName(
+ __in HANDLE hProcess,
+ __in PCSTR Name,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromNameW(
+ __in HANDLE hProcess,
+ __in PCWSTR Name,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(
+ __in PSYMBOL_INFO pSymInfo,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSymbols(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCSTR Mask,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+typedef BOOL
+(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)(
+ __in PSYMBOL_INFOW pSymInfo,
+ __in ULONG SymbolSize,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCWSTR Mask,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsForAddr(
+ __in HANDLE hProcess,
+ __in DWORD64 Address,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumSymbolsForAddrW(
+ __in HANDLE hProcess,
+ __in DWORD64 Address,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs
+#define SYMSEARCH_RECURSE 0X02 // recurse scopes
+#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols
+#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols
+
+BOOL
+IMAGEAPI
+SymSearch(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt DWORD Index,
+ __in_opt DWORD SymTag,
+ __in_opt PCSTR Mask,
+ __in_opt DWORD64 Address,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext,
+ __in DWORD Options
+ );
+
+BOOL
+IMAGEAPI
+SymSearchW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt DWORD Index,
+ __in_opt DWORD SymTag,
+ __in_opt PCWSTR Mask,
+ __in_opt DWORD64 Address,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext,
+ __in DWORD Options
+ );
+
+BOOL
+IMAGEAPI
+SymGetScope(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in DWORD Index,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetScopeW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in DWORD Index,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromIndex(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in DWORD Index,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymFromIndexW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in DWORD Index,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
+ TI_GET_SYMTAG,
+ TI_GET_SYMNAME,
+ TI_GET_LENGTH,
+ TI_GET_TYPE,
+ TI_GET_TYPEID,
+ TI_GET_BASETYPE,
+ TI_GET_ARRAYINDEXTYPEID,
+ TI_FINDCHILDREN,
+ TI_GET_DATAKIND,
+ TI_GET_ADDRESSOFFSET,
+ TI_GET_OFFSET,
+ TI_GET_VALUE,
+ TI_GET_COUNT,
+ TI_GET_CHILDRENCOUNT,
+ TI_GET_BITPOSITION,
+ TI_GET_VIRTUALBASECLASS,
+ TI_GET_VIRTUALTABLESHAPEID,
+ TI_GET_VIRTUALBASEPOINTEROFFSET,
+ TI_GET_CLASSPARENTID,
+ TI_GET_NESTED,
+ TI_GET_SYMINDEX,
+ TI_GET_LEXICALPARENT,
+ TI_GET_ADDRESS,
+ TI_GET_THISADJUST,
+ TI_GET_UDTKIND,
+ TI_IS_EQUIV_TO,
+ TI_GET_CALLING_CONVENTION,
+ TI_IS_CLOSE_EQUIV_TO,
+ TI_GTIEX_REQS_VALID,
+ TI_GET_VIRTUALBASEOFFSET,
+ TI_GET_VIRTUALBASEDISPINDEX,
+ TI_GET_IS_REFERENCE,
+ TI_GET_INDIRECTVIRTUALBASECLASS,
+ IMAGEHLP_SYMBOL_TYPE_INFO_MAX,
+} IMAGEHLP_SYMBOL_TYPE_INFO;
+
+typedef struct _TI_FINDCHILDREN_PARAMS {
+ ULONG Count;
+ ULONG Start;
+ ULONG ChildId[1];
+} TI_FINDCHILDREN_PARAMS;
+
+BOOL
+IMAGEAPI
+SymGetTypeInfo(
+ __in HANDLE hProcess,
+ __in DWORD64 ModBase,
+ __in ULONG TypeId,
+ __in IMAGEHLP_SYMBOL_TYPE_INFO GetType,
+ __out PVOID pInfo
+ );
+
+#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001
+#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002
+
+typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS {
+ IN ULONG SizeOfStruct;
+ IN ULONG Flags;
+ IN ULONG NumIds;
+ IN PULONG TypeIds;
+ IN ULONG64 TagFilter;
+ IN ULONG NumReqs;
+ IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds;
+ IN PULONG_PTR ReqOffsets;
+ IN PULONG ReqSizes;
+ IN ULONG_PTR ReqStride;
+ IN ULONG_PTR BufferSize;
+ OUT PVOID Buffer;
+ OUT ULONG EntriesMatched;
+ OUT ULONG EntriesFilled;
+ OUT ULONG64 TagsFound;
+ OUT ULONG64 AllReqsValid;
+ IN ULONG NumReqsValid;
+ OUT PULONG64 ReqsValid OPTIONAL;
+} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS;
+
+BOOL
+IMAGEAPI
+SymGetTypeInfoEx(
+ __in HANDLE hProcess,
+ __in DWORD64 ModBase,
+ __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params
+ );
+
+BOOL
+IMAGEAPI
+SymEnumTypes(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumTypesW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumTypesByName(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCSTR mask,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymEnumTypesByNameW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCWSTR mask,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+BOOL
+IMAGEAPI
+SymGetTypeFromName(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PCSTR Name,
+ __inout PSYMBOL_INFO Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetTypeFromNameW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PCWSTR Name,
+ __inout PSYMBOL_INFOW Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymAddSymbol(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PCSTR Name,
+ __in DWORD64 Address,
+ __in DWORD Size,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymAddSymbolW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PCWSTR Name,
+ __in DWORD64 Address,
+ __in DWORD Size,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymDeleteSymbol(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCSTR Name,
+ __in DWORD64 Address,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymDeleteSymbolW(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in_opt PCWSTR Name,
+ __in DWORD64 Address,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymRefreshModuleList(
+ __in HANDLE hProcess
+ );
+
+BOOL
+IMAGEAPI
+SymAddSourceStream(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCSTR StreamFile,
+ __in_bcount_opt(Size) PBYTE Buffer,
+ __in size_t Size
+ );
+
+typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
+
+BOOL
+IMAGEAPI
+SymAddSourceStreamA(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCSTR StreamFile,
+ __in_bcount_opt(Size) PBYTE Buffer,
+ __in size_t Size
+ );
+
+typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t);
+
+BOOL
+IMAGEAPI
+SymAddSourceStreamW(
+ __in HANDLE hProcess,
+ __in ULONG64 Base,
+ __in_opt PCWSTR FileSpec,
+ __in_bcount_opt(Size) PBYTE Buffer,
+ __in size_t Size
+ );
+
+BOOL
+IMAGEAPI
+SymSrvIsStoreW(
+ __in_opt HANDLE hProcess,
+ __in PCWSTR path
+ );
+
+BOOL
+IMAGEAPI
+SymSrvIsStore(
+ __in_opt HANDLE hProcess,
+ __in PCSTR path
+ );
+
+PCSTR
+IMAGEAPI
+SymSrvDeltaName(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SymPath,
+ __in PCSTR Type,
+ __in PCSTR File1,
+ __in PCSTR File2
+ );
+
+PCWSTR
+IMAGEAPI
+SymSrvDeltaNameW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SymPath,
+ __in PCWSTR Type,
+ __in PCWSTR File1,
+ __in PCWSTR File2
+ );
+
+PCSTR
+IMAGEAPI
+SymSrvGetSupplement(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SymPath,
+ __in PCSTR Node,
+ __in PCSTR File
+ );
+
+PCWSTR
+IMAGEAPI
+SymSrvGetSupplementW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SymPath,
+ __in PCWSTR Node,
+ __in PCWSTR File
+ );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexes(
+ __in PCSTR File,
+ __out GUID *Id,
+ __out PDWORD Val1,
+ __out_opt PDWORD Val2,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexesW(
+ __in PCWSTR File,
+ __out GUID *Id,
+ __out PDWORD Val1,
+ __out_opt PDWORD Val2,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexStringW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SrvPath,
+ __in PCWSTR File,
+ __out_ecount(Size) PWSTR Index,
+ __in size_t Size,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexString(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SrvPath,
+ __in PCSTR File,
+ __out_ecount(Size) PSTR Index,
+ __in size_t Size,
+ __in DWORD Flags
+ );
+
+typedef struct {
+ DWORD sizeofstruct;
+ char file[MAX_PATH +1];
+ BOOL stripped;
+ DWORD timestamp;
+ DWORD size;
+ char dbgfile[MAX_PATH +1];
+ char pdbfile[MAX_PATH + 1];
+ GUID guid;
+ DWORD sig;
+ DWORD age;
+} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO;
+
+typedef struct {
+ DWORD sizeofstruct;
+ WCHAR file[MAX_PATH +1];
+ BOOL stripped;
+ DWORD timestamp;
+ DWORD size;
+ WCHAR dbgfile[MAX_PATH +1];
+ WCHAR pdbfile[MAX_PATH + 1];
+ GUID guid;
+ DWORD sig;
+ DWORD age;
+} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW;
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexInfo(
+ __in PCSTR File,
+ __out PSYMSRV_INDEX_INFO Info,
+ __in DWORD Flags
+ );
+
+BOOL
+IMAGEAPI
+SymSrvGetFileIndexInfoW(
+ __in PCWSTR File,
+ __out PSYMSRV_INDEX_INFOW Info,
+ __in DWORD Flags
+ );
+
+PCSTR
+IMAGEAPI
+SymSrvStoreSupplement(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SrvPath,
+ __in PCSTR Node,
+ __in PCSTR File,
+ __in DWORD Flags
+ );
+
+PCWSTR
+IMAGEAPI
+SymSrvStoreSupplementW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SymPath,
+ __in PCWSTR Node,
+ __in PCWSTR File,
+ __in DWORD Flags
+ );
+
+PCSTR
+IMAGEAPI
+SymSrvStoreFile(
+ __in HANDLE hProcess,
+ __in_opt PCSTR SrvPath,
+ __in PCSTR File,
+ __in DWORD Flags
+ );
+
+PCWSTR
+IMAGEAPI
+SymSrvStoreFileW(
+ __in HANDLE hProcess,
+ __in_opt PCWSTR SrvPath,
+ __in PCWSTR File,
+ __in DWORD Flags
+ );
+
+// used by SymGetSymbolFile's "Type" parameter
+
+enum {
+ sfImage = 0,
+ sfDbg,
+ sfPdb,
+ sfMpd,
+ sfMax
+};
+
+BOOL
+IMAGEAPI
+SymGetSymbolFile(
+ __in_opt HANDLE hProcess,
+ __in_opt PCSTR SymPath,
+ __in PCSTR ImageFile,
+ __in DWORD Type,
+ __out_ecount(cSymbolFile) PSTR SymbolFile,
+ __in size_t cSymbolFile,
+ __out_ecount(cDbgFile) PSTR DbgFile,
+ __in size_t cDbgFile
+ );
+
+BOOL
+IMAGEAPI
+SymGetSymbolFileW(
+ __in_opt HANDLE hProcess,
+ __in_opt PCWSTR SymPath,
+ __in PCWSTR ImageFile,
+ __in DWORD Type,
+ __out_ecount(cSymbolFile) PWSTR SymbolFile,
+ __in size_t cSymbolFile,
+ __out_ecount(cDbgFile) PWSTR DbgFile,
+ __in size_t cDbgFile
+ );
+
+//
+// Full user-mode dump creation.
+//
+
+typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(
+ __in DWORD DataType,
+ __in PVOID* Data,
+ __out LPDWORD DataLength,
+ __in_opt PVOID UserData
+ );
+
+BOOL
+WINAPI
+DbgHelpCreateUserDump(
+ __in_opt LPCSTR FileName,
+ __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
+ __in_opt PVOID UserData
+ );
+
+BOOL
+WINAPI
+DbgHelpCreateUserDumpW(
+ __in_opt LPCWSTR FileName,
+ __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
+ __in_opt PVOID UserData
+ );
+
+// -----------------------------------------------------------------
+// The following 4 legacy APIs are fully supported, but newer
+// ones are recommended. SymFromName and SymFromAddr provide
+// much more detailed info on the returned symbol.
+
+BOOL
+IMAGEAPI
+SymGetSymFromAddr64(
+ __in HANDLE hProcess,
+ __in DWORD64 qwAddr,
+ __out_opt PDWORD64 pdwDisplacement,
+ __inout PIMAGEHLP_SYMBOL64 Symbol
+ );
+
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymFromAddr SymGetSymFromAddr64
+#else
+BOOL
+IMAGEAPI
+SymGetSymFromAddr(
+ __in HANDLE hProcess,
+ __in DWORD dwAddr,
+ __out_opt PDWORD pdwDisplacement,
+ __inout PIMAGEHLP_SYMBOL Symbol
+ );
+#endif
+
+// While following two APIs will provide a symbol from a name,
+// SymEnumSymbols can provide the same matching information
+// for ALL symbols with a matching name, even regular
+// expressions. That way you can search across modules
+// and differentiate between identically named symbols.
+
+BOOL
+IMAGEAPI
+SymGetSymFromName64(
+ __in HANDLE hProcess,
+ __in PCSTR Name,
+ __inout PIMAGEHLP_SYMBOL64 Symbol
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymFromName SymGetSymFromName64
+#else
+BOOL
+IMAGEAPI
+SymGetSymFromName(
+ __in HANDLE hProcess,
+ __in PCSTR Name,
+ __inout PIMAGEHLP_SYMBOL Symbol
+ );
+#endif
+
+
+// Symbol server exports
+
+typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID);
+typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID);
+typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64);
+typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64);
+typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
+typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)();
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION);
+typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD);
+typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR);
+typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR);
+typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)();
+typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
+
+#define SYMSRV_VERSION 2
+
+#define SSRVOPT_CALLBACK 0x00000001
+#define SSRVOPT_DWORD 0x00000002
+#define SSRVOPT_DWORDPTR 0x00000004
+#define SSRVOPT_GUIDPTR 0x00000008
+#define SSRVOPT_OLDGUIDPTR 0x00000010
+#define SSRVOPT_UNATTENDED 0x00000020
+#define SSRVOPT_NOCOPY 0x00000040
+#define SSRVOPT_GETPATH 0x00000040
+#define SSRVOPT_PARENTWIN 0x00000080
+#define SSRVOPT_PARAMTYPE 0x00000100
+#define SSRVOPT_SECURE 0x00000200
+#define SSRVOPT_TRACE 0x00000400
+#define SSRVOPT_SETCONTEXT 0x00000800
+#define SSRVOPT_PROXY 0x00001000
+#define SSRVOPT_DOWNSTREAM_STORE 0x00002000
+#define SSRVOPT_OVERWRITE 0x00004000
+#define SSRVOPT_RESETTOU 0x00008000
+#define SSRVOPT_CALLBACKW 0x00010000
+#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000
+#define SSRVOPT_PROXYW 0x00040000
+#define SSRVOPT_MESSAGE 0x00080000
+#define SSRVOPT_SERVICE 0x00100000 // deprecated
+#define SSRVOPT_FAVOR_COMPRESSED 0x00200000
+#define SSRVOPT_STRING 0x00400000
+#define SSRVOPT_WINHTTP 0x00800000
+#define SSRVOPT_WININET 0x01000000
+
+#define SSRVOPT_MAX 0x0100000
+
+#define SSRVOPT_RESET ((ULONG_PTR)-1)
+
+
+#define NUM_SSRVOPTS 30
+
+#define SSRVACTION_TRACE 1
+#define SSRVACTION_QUERYCANCEL 2
+#define SSRVACTION_EVENT 3
+#define SSRVACTION_EVENTW 4
+#define SSRVACTION_SIZE 5
+
+#define SYMSTOREOPT_COMPRESS 0x01
+#define SYMSTOREOPT_OVERWRITE 0x02
+#define SYMSTOREOPT_RETURNINDEX 0x04
+#define SYMSTOREOPT_POINTER 0x08
+#define SYMSTOREOPT_ALT_INDEX 0x10
+#define SYMSTOREOPT_UNICODE 0x20
+#define SYMSTOREOPT_PASS_IF_EXISTS 0x40
+
+#ifdef DBGHELP_TRANSLATE_TCHAR
+ #define SymInitialize SymInitializeW
+ #define SymAddSymbol SymAddSymbolW
+ #define SymDeleteSymbol SymDeleteSymbolW
+ #define SearchTreeForFile SearchTreeForFileW
+ #define UnDecorateSymbolName UnDecorateSymbolNameW
+ #define SymGetLineFromName64 SymGetLineFromNameW64
+ #define SymGetLineFromAddr64 SymGetLineFromAddrW64
+ #define SymGetLineNext64 SymGetLineNextW64
+ #define SymGetLinePrev64 SymGetLinePrevW64
+ #define SymFromName SymFromNameW
+ #define SymFindExecutableImage SymFindExecutableImageW
+ #define FindExecutableImageEx FindExecutableImageExW
+ #define SymSearch SymSearchW
+ #define SymEnumLines SymEnumLinesW
+ #define SymEnumSourceLines SymEnumSourceLinesW
+ #define SymGetTypeFromName SymGetTypeFromNameW
+ #define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW
+ #define SymFromAddr SymFromAddrW
+ #define SymMatchString SymMatchStringW
+ #define SymEnumSourceFiles SymEnumSourceFilesW
+ #define SymEnumSymbols SymEnumSymbolsW
+ #define SymLoadModuleEx SymLoadModuleExW
+ #define SymSetSearchPath SymSetSearchPathW
+ #define SymGetSearchPath SymGetSearchPathW
+ #define EnumDirTree EnumDirTreeW
+ #define SymFromToken SymFromTokenW
+ #define SymFromIndex SymFromIndexW
+ #define SymGetScope SymGetScopeW
+ #define SymNext SymNextW
+ #define SymPrev SymPrevW
+ #define SymEnumTypes SymEnumTypesW
+ #define SymEnumTypesByName SymEnumTypesByNameW
+ #define SymRegisterCallback64 SymRegisterCallbackW64
+ #define SymFindDebugInfoFile SymFindDebugInfoFileW
+ #define FindDebugInfoFileEx FindDebugInfoFileExW
+ #define SymFindFileInPath SymFindFileInPathW
+ #define SymEnumerateModules64 SymEnumerateModulesW64
+ #define SymSetHomeDirectory SymSetHomeDirectoryW
+ #define SymGetHomeDirectory SymGetHomeDirectoryW
+ #define SymGetSourceFile SymGetSourceFileW
+ #define SymGetSourceFileToken SymGetSourceFileTokenW
+ #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW
+ #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW
+ #define SymGetSourceFileToken SymGetSourceFileTokenW
+ #define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64
+ #define SymFindFileInPath SymFindFileInPathW
+ #define SymMatchFileName SymMatchFileNameW
+ #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW
+ #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW
+ #define SymGetModuleInfo64 SymGetModuleInfoW64
+ #define SymSrvIsStore SymSrvIsStoreW
+ #define SymSrvDeltaName SymSrvDeltaNameW
+ #define SymSrvGetSupplement SymSrvGetSupplementW
+ #define SymSrvStoreSupplement SymSrvStoreSupplementW
+ #define SymSrvGetFileIndexes SymSrvGetFileIndexes
+ #define SymSrvGetFileIndexString SymSrvGetFileIndexStringW
+ #define SymSrvStoreFile SymSrvStoreFileW
+ #define SymGetSymbolFile SymGetSymbolFileW
+ #define EnumerateLoadedModules64 EnumerateLoadedModulesW64
+ #define EnumerateLoadedModulesEx EnumerateLoadedModulesExW
+ #define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW
+
+ #define IMAGEHLP_LINE64 IMAGEHLP_LINEW64
+ #define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64
+ #define SYMBOL_INFO SYMBOL_INFOW
+ #define PSYMBOL_INFO PSYMBOL_INFOW
+ #define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW
+ #define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW
+ #define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW
+ #define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW
+ #define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW
+ #define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW
+ #define SRCCODEINFO SRCCODEINFOW
+ #define PSRCCODEINFO PSRCCODEINFOW
+ #define SOURCEFILE SOURCEFILEW
+ #define PSOURCEFILE PSOURCEFILEW
+ #define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW
+ #define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW
+ #define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW
+ #define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW
+ #define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW
+ #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64
+ #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64
+ #define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW
+ #define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW
+ #define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64
+ #define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64
+ #define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW
+ #define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW
+
+ #define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW
+ #define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW
+#endif
+
+// -----------------------------------------------------------------
+// The following APIs exist only for backwards compatibility
+// with a pre-release version documented in an MSDN release.
+
+// You should use SymFindFileInPath if you want to maintain
+// future compatibility.
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+FindFileInPath(
+ __in HANDLE hprocess,
+ __in PCSTR SearchPath,
+ __in PCSTR FileName,
+ __in PVOID id,
+ __in DWORD two,
+ __in DWORD three,
+ __in DWORD flags,
+ __out_ecount(MAX_PATH + 1) PSTR FilePath
+ );
+
+// You should use SymFindFileInPath if you want to maintain
+// future compatibility.
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+FindFileInSearchPath(
+ __in HANDLE hprocess,
+ __in PCSTR SearchPath,
+ __in PCSTR FileName,
+ __in DWORD one,
+ __in DWORD two,
+ __in DWORD three,
+ __out_ecount(MAX_PATH + 1) PSTR FilePath
+ );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumSym(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbols64(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbolsW64(
+ __in HANDLE hProcess,
+ __in ULONG64 BaseOfDll,
+ __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymEnumerateSymbols SymEnumerateSymbols64
+#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
+#else
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbols(
+ __in HANDLE hProcess,
+ __in ULONG BaseOfDll,
+ __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+
+DBHLP_DEPRECIATED
+BOOL
+IMAGEAPI
+SymEnumerateSymbolsW(
+ __in HANDLE hProcess,
+ __in ULONG BaseOfDll,
+ __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,
+ __in_opt PVOID UserContext
+ );
+#endif
+
+// use SymLoadModuleEx
+
+DWORD64
+IMAGEAPI
+SymLoadModule64(
+ __in HANDLE hProcess,
+ __in_opt HANDLE hFile,
+ __in_opt PCSTR ImageName,
+ __in_opt PCSTR ModuleName,
+ __in DWORD64 BaseOfDll,
+ __in DWORD SizeOfDll
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymLoadModule SymLoadModule64
+#else
+DWORD
+IMAGEAPI
+SymLoadModule(
+ __in HANDLE hProcess,
+ __in_opt HANDLE hFile,
+ __in_opt PCSTR ImageName,
+ __in_opt PCSTR ModuleName,
+ __in DWORD BaseOfDll,
+ __in DWORD SizeOfDll
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetSymNext64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOL64 Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetSymNextW64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOLW64 Symbol
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymNext SymGetSymNext64
+#define SymGetSymNextW SymGetSymNextW64
+#else
+BOOL
+IMAGEAPI
+SymGetSymNext(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOL Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetSymNextW(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOLW Symbol
+ );
+#endif
+
+BOOL
+IMAGEAPI
+SymGetSymPrev64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOL64 Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetSymPrevW64(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOLW64 Symbol
+ );
+
+#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
+#define SymGetSymPrev SymGetSymPrev64
+#define SymGetSymPrevW SymGetSymPrevW64
+#else
+BOOL
+IMAGEAPI
+SymGetSymPrev(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOL Symbol
+ );
+
+BOOL
+IMAGEAPI
+SymGetSymPrevW(
+ __in HANDLE hProcess,
+ __inout PIMAGEHLP_SYMBOLW Symbol
+ );
+#endif
+
+
+// These values should not be used.
+// They have been replaced by SYMFLAG_ values.
+
+#define SYMF_OMAP_GENERATED 0x00000001
+#define SYMF_OMAP_MODIFIED 0x00000002
+#define SYMF_REGISTER 0x00000008
+#define SYMF_REGREL 0x00000010
+#define SYMF_FRAMEREL 0x00000020
+#define SYMF_PARAMETER 0x00000040
+#define SYMF_LOCAL 0x00000080
+#define SYMF_CONSTANT 0x00000100
+#define SYMF_EXPORT 0x00000200
+#define SYMF_FORWARDER 0x00000400
+#define SYMF_FUNCTION 0x00000800
+#define SYMF_VIRTUAL 0x00001000
+#define SYMF_THUNK 0x00002000
+#define SYMF_TLSREL 0x00004000
+
+// These values should also not be used.
+// They have been replaced by SYMFLAG_ values.
+
+#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1
+#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008
+#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010
+#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020
+#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040
+#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080
+#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100
+#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800
+#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000
+#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000
+#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000
+
+
+#include <pshpack4.h>
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+#pragma warning(disable:4200) /* Zero length array */
+#pragma warning(disable:4201) /* Nameless struct/union */
+#endif
+#endif
+
+#define MINIDUMP_SIGNATURE ('PMDM')
+#define MINIDUMP_VERSION (42899)
+typedef DWORD RVA;
+typedef ULONG64 RVA64;
+
+typedef struct _MINIDUMP_LOCATION_DESCRIPTOR {
+ ULONG32 DataSize;
+ RVA Rva;
+} MINIDUMP_LOCATION_DESCRIPTOR;
+
+typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 {
+ ULONG64 DataSize;
+ RVA64 Rva;
+} MINIDUMP_LOCATION_DESCRIPTOR64;
+
+
+typedef struct _MINIDUMP_MEMORY_DESCRIPTOR {
+ ULONG64 StartOfMemoryRange;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR;
+
+// DESCRIPTOR64 is used for full-memory minidumps where
+// all of the raw memory is laid out sequentially at the
+// end of the dump. There is no need for individual RVAs
+// as the RVA is the base RVA plus the sum of the preceeding
+// data blocks.
+typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 {
+ ULONG64 StartOfMemoryRange;
+ ULONG64 DataSize;
+} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64;
+
+
+typedef struct _MINIDUMP_HEADER {
+ ULONG32 Signature;
+ ULONG32 Version;
+ ULONG32 NumberOfStreams;
+ RVA StreamDirectoryRva;
+ ULONG32 CheckSum;
+ union {
+ ULONG32 Reserved;
+ ULONG32 TimeDateStamp;
+ };
+ ULONG64 Flags;
+} MINIDUMP_HEADER, *PMINIDUMP_HEADER;
+
+//
+// The MINIDUMP_HEADER field StreamDirectoryRva points to
+// an array of MINIDUMP_DIRECTORY structures.
+//
+
+typedef struct _MINIDUMP_DIRECTORY {
+ ULONG32 StreamType;
+ MINIDUMP_LOCATION_DESCRIPTOR Location;
+} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY;
+
+
+typedef struct _MINIDUMP_STRING {
+ ULONG32 Length; // Length in bytes of the string
+ WCHAR Buffer [0]; // Variable size buffer
+} MINIDUMP_STRING, *PMINIDUMP_STRING;
+
+
+
+//
+// The MINIDUMP_DIRECTORY field StreamType may be one of the following types.
+// Types will be added in the future, so if a program reading the minidump
+// header encounters a stream type it does not understand it should ignore
+// the data altogether. Any tag above LastReservedStream will not be used by
+// the system and is reserved for program-specific information.
+//
+
+typedef enum _MINIDUMP_STREAM_TYPE {
+
+ UnusedStream = 0,
+ ReservedStream0 = 1,
+ ReservedStream1 = 2,
+ ThreadListStream = 3,
+ ModuleListStream = 4,
+ MemoryListStream = 5,
+ ExceptionStream = 6,
+ SystemInfoStream = 7,
+ ThreadExListStream = 8,
+ Memory64ListStream = 9,
+ CommentStreamA = 10,
+ CommentStreamW = 11,
+ HandleDataStream = 12,
+ FunctionTableStream = 13,
+ UnloadedModuleListStream = 14,
+ MiscInfoStream = 15,
+ MemoryInfoListStream = 16,
+ ThreadInfoListStream = 17,
+ HandleOperationListStream = 18,
+
+ ceStreamNull = 0x8000,
+ ceStreamSystemInfo = 0x8001,
+ ceStreamException = 0x8002,
+ ceStreamModuleList = 0x8003,
+ ceStreamProcessList = 0x8004,
+ ceStreamThreadList = 0x8005,
+ ceStreamThreadContextList = 0x8006,
+ ceStreamThreadCallStackList = 0x8007,
+ ceStreamMemoryVirtualList = 0x8008,
+ ceStreamMemoryPhysicalList = 0x8009,
+ ceStreamBucketParameters = 0x800A,
+
+ LastReservedStream = 0xffff
+
+} MINIDUMP_STREAM_TYPE;
+
+
+//
+// The minidump system information contains processor and
+// Operating System specific information.
+//
+
+//
+// CPU information is obtained from one of two places.
+//
+// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID
+// instruction. You must use the X86 portion of the union for X86
+// computers.
+//
+// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling
+// IsProcessorFeatureSupported().
+//
+
+typedef union _CPU_INFORMATION {
+
+ //
+ // X86 platforms use CPUID function to obtain processor information.
+ //
+
+ struct {
+
+ //
+ // CPUID Subfunction 0, register EAX (VendorId [0]),
+ // EBX (VendorId [1]) and ECX (VendorId [2]).
+ //
+
+ ULONG32 VendorId [ 3 ];
+
+ //
+ // CPUID Subfunction 1, register EAX
+ //
+
+ ULONG32 VersionInformation;
+
+ //
+ // CPUID Subfunction 1, register EDX
+ //
+
+ ULONG32 FeatureInformation;
+
+
+ //
+ // CPUID, Subfunction 80000001, register EBX. This will only
+ // be obtained if the vendor id is "AuthenticAMD".
+ //
+
+ ULONG32 AMDExtendedCpuFeatures;
+
+ } X86CpuInfo;
+
+ //
+ // Non-x86 platforms use processor feature flags.
+ //
+
+ struct {
+
+ ULONG64 ProcessorFeatures [ 2 ];
+
+ } OtherCpuInfo;
+
+} CPU_INFORMATION, *PCPU_INFORMATION;
+
+typedef struct _MINIDUMP_SYSTEM_INFO {
+
+ //
+ // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all
+ // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ).
+ //
+
+ USHORT ProcessorArchitecture;
+ USHORT ProcessorLevel;
+ USHORT ProcessorRevision;
+
+ union {
+ USHORT Reserved0;
+ struct {
+ UCHAR NumberOfProcessors;
+ UCHAR ProductType;
+ };
+ };
+
+ //
+ // MajorVersion, MinorVersion, BuildNumber, PlatformId and
+ // CSDVersion are all taken from the OSVERSIONINFO structure
+ // returned by GetVersionEx( ).
+ //
+
+ ULONG32 MajorVersion;
+ ULONG32 MinorVersion;
+ ULONG32 BuildNumber;
+ ULONG32 PlatformId;
+
+ //
+ // RVA to a CSDVersion string in the string table.
+ //
+
+ RVA CSDVersionRva;
+
+ union {
+ ULONG32 Reserved1;
+ struct {
+ USHORT SuiteMask;
+ USHORT Reserved2;
+ };
+ };
+
+ CPU_INFORMATION Cpu;
+
+} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO;
+
+
+//
+// The minidump thread contains standard thread
+// information plus an RVA to the memory for this
+// thread and an RVA to the CONTEXT structure for
+// this thread.
+//
+
+
+//
+// ThreadId must be 4 bytes on all architectures.
+//
+
+C_ASSERT (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4);
+
+typedef struct _MINIDUMP_THREAD {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+} MINIDUMP_THREAD, *PMINIDUMP_THREAD;
+
+//
+// The thread list is a container of threads.
+//
+
+typedef struct _MINIDUMP_THREAD_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD Threads [0];
+} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST;
+
+
+typedef struct _MINIDUMP_THREAD_EX {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
+} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX;
+
+//
+// The thread list is a container of threads.
+//
+
+typedef struct _MINIDUMP_THREAD_EX_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD_EX Threads [0];
+} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST;
+
+
+//
+// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64.
+//
+
+typedef struct _MINIDUMP_EXCEPTION {
+ ULONG32 ExceptionCode;
+ ULONG32 ExceptionFlags;
+ ULONG64 ExceptionRecord;
+ ULONG64 ExceptionAddress;
+ ULONG32 NumberParameters;
+ ULONG32 __unusedAlignment;
+ ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ];
+} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION;
+
+
+//
+// The exception information stream contains the id of the thread that caused
+// the exception (ThreadId), the exception record for the exception
+// (ExceptionRecord) and an RVA to the thread context where the exception
+// occured.
+//
+
+typedef struct MINIDUMP_EXCEPTION_STREAM {
+ ULONG32 ThreadId;
+ ULONG32 __alignment;
+ MINIDUMP_EXCEPTION ExceptionRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM;
+
+
+//
+// The MINIDUMP_MODULE contains information about a
+// a specific module. It includes the CheckSum and
+// the TimeDateStamp for the module so the module
+// can be reloaded during the analysis phase.
+//
+
+typedef struct _MINIDUMP_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+ VS_FIXEDFILEINFO VersionInfo;
+ MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
+ ULONG64 Reserved0; // Reserved for future use.
+ ULONG64 Reserved1; // Reserved for future use.
+} MINIDUMP_MODULE, *PMINIDUMP_MODULE;
+
+
+//
+// The minidump module list is a container for modules.
+//
+
+typedef struct _MINIDUMP_MODULE_LIST {
+ ULONG32 NumberOfModules;
+ MINIDUMP_MODULE Modules [ 0 ];
+} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST;
+
+
+//
+// Memory Ranges
+//
+
+typedef struct _MINIDUMP_MEMORY_LIST {
+ ULONG32 NumberOfMemoryRanges;
+ MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0];
+} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST;
+
+typedef struct _MINIDUMP_MEMORY64_LIST {
+ ULONG64 NumberOfMemoryRanges;
+ RVA64 BaseRva;
+ MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0];
+} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST;
+
+
+//
+// Support for user supplied exception information.
+//
+
+typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
+ DWORD ThreadId;
+ PEXCEPTION_POINTERS ExceptionPointers;
+ BOOL ClientPointers;
+} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
+
+typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 {
+ DWORD ThreadId;
+ ULONG64 ExceptionRecord;
+ ULONG64 ContextRecord;
+ BOOL ClientPointers;
+} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64;
+
+
+//
+// Support for capturing system handle state at the time of the dump.
+//
+
+// Per-handle object information varies according to
+// the OS, the OS version, the processor type and
+// so on. The minidump gives a minidump identifier
+// to each possible data format for identification
+// purposes but does not control nor describe the actual data.
+typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE {
+ MiniHandleObjectInformationNone,
+ MiniThreadInformation1,
+ MiniMutantInformation1,
+ MiniMutantInformation2,
+ MiniProcessInformation1,
+ MiniProcessInformation2,
+ MiniHandleObjectInformationTypeMax
+} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE;
+
+typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION {
+ RVA NextInfoRva;
+ ULONG32 InfoType;
+ ULONG32 SizeOfInfo;
+ // Raw information follows.
+} MINIDUMP_HANDLE_OBJECT_INFORMATION;
+
+typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
+ ULONG64 Handle;
+ RVA TypeNameRva;
+ RVA ObjectNameRva;
+ ULONG32 Attributes;
+ ULONG32 GrantedAccess;
+ ULONG32 HandleCount;
+ ULONG32 PointerCount;
+} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR;
+
+typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 {
+ ULONG64 Handle;
+ RVA TypeNameRva;
+ RVA ObjectNameRva;
+ ULONG32 Attributes;
+ ULONG32 GrantedAccess;
+ ULONG32 HandleCount;
+ ULONG32 PointerCount;
+ RVA ObjectInfoRva;
+ ULONG32 Reserved0;
+} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2;
+
+// The latest MINIDUMP_HANDLE_DESCRIPTOR definition.
+typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N;
+typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N;
+
+typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 Reserved;
+} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM;
+
+// Some operating systems can track the last operations
+// performed on a handle. For example, Application Verifier
+// can enable this for some versions of Windows. The
+// handle operation list collects handle operations
+// known for the dump target.
+// Each entry is an AVRF_HANDLE_OPERATION.
+typedef struct _MINIDUMP_HANDLE_OPERATION_LIST {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfEntry;
+ ULONG32 NumberOfEntries;
+ ULONG32 Reserved;
+} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST;
+
+
+//
+// Support for capturing dynamic function table state at the time of the dump.
+//
+
+typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
+ ULONG64 MinimumAddress;
+ ULONG64 MaximumAddress;
+ ULONG64 BaseAddress;
+ ULONG32 EntryCount;
+ ULONG32 SizeOfAlignPad;
+} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR;
+
+typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 SizeOfNativeDescriptor;
+ ULONG32 SizeOfFunctionEntry;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 SizeOfAlignPad;
+} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM;
+
+
+//
+// The MINIDUMP_UNLOADED_MODULE contains information about a
+// a specific module that was previously loaded but no
+// longer is. This can help with diagnosing problems where
+// callers attempt to call code that is no longer loaded.
+//
+
+typedef struct _MINIDUMP_UNLOADED_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE;
+
+
+//
+// The minidump unloaded module list is a container for unloaded modules.
+//
+
+typedef struct _MINIDUMP_UNLOADED_MODULE_LIST {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfEntry;
+ ULONG32 NumberOfEntries;
+} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST;
+
+
+//
+// The miscellaneous information stream contains a variety
+// of small pieces of information. A member is valid if
+// it's within the available size and its corresponding
+// bit is set.
+//
+
+#define MINIDUMP_MISC1_PROCESS_ID 0x00000001
+#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002
+#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004
+
+typedef struct _MINIDUMP_MISC_INFO {
+ ULONG32 SizeOfInfo;
+ ULONG32 Flags1;
+ ULONG32 ProcessId;
+ ULONG32 ProcessCreateTime;
+ ULONG32 ProcessUserTime;
+ ULONG32 ProcessKernelTime;
+} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO;
+
+typedef struct _MINIDUMP_MISC_INFO_2 {
+ ULONG32 SizeOfInfo;
+ ULONG32 Flags1;
+ ULONG32 ProcessId;
+ ULONG32 ProcessCreateTime;
+ ULONG32 ProcessUserTime;
+ ULONG32 ProcessKernelTime;
+ ULONG32 ProcessorMaxMhz;
+ ULONG32 ProcessorCurrentMhz;
+ ULONG32 ProcessorMhzLimit;
+ ULONG32 ProcessorMaxIdleState;
+ ULONG32 ProcessorCurrentIdleState;
+} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2;
+
+// The latest MINIDUMP_MISC_INFO definition.
+typedef MINIDUMP_MISC_INFO_2 MINIDUMP_MISC_INFO_N;
+typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N;
+
+
+//
+// The memory information stream contains memory region
+// description information. This stream corresponds to
+// what VirtualQuery would return for the process the
+// dump was created for.
+//
+
+typedef struct _MINIDUMP_MEMORY_INFO {
+ ULONG64 BaseAddress;
+ ULONG64 AllocationBase;
+ ULONG32 AllocationProtect;
+ ULONG32 __alignment1;
+ ULONG64 RegionSize;
+ ULONG32 State;
+ ULONG32 Protect;
+ ULONG32 Type;
+ ULONG32 __alignment2;
+} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO;
+
+typedef struct _MINIDUMP_MEMORY_INFO_LIST {
+ ULONG SizeOfHeader;
+ ULONG SizeOfEntry;
+ ULONG64 NumberOfEntries;
+} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST;
+
+
+//
+// The memory information stream contains memory region
+// description information. This stream corresponds to
+// what VirtualQuery would return for the process the
+// dump was created for.
+//
+
+// Thread dump writer status flags.
+#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001
+#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002
+#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004
+#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008
+#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010
+#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020
+
+typedef struct _MINIDUMP_THREAD_INFO {
+ ULONG32 ThreadId;
+ ULONG32 DumpFlags;
+ ULONG32 DumpError;
+ ULONG32 ExitStatus;
+ ULONG64 CreateTime;
+ ULONG64 ExitTime;
+ ULONG64 KernelTime;
+ ULONG64 UserTime;
+ ULONG64 StartAddress;
+ ULONG64 Affinity;
+} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO;
+
+typedef struct _MINIDUMP_THREAD_INFO_LIST {
+ ULONG SizeOfHeader;
+ ULONG SizeOfEntry;
+ ULONG NumberOfEntries;
+} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST;
+
+
+//
+// Support for arbitrary user-defined information.
+//
+
+typedef struct _MINIDUMP_USER_RECORD {
+ ULONG32 Type;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD;
+
+
+typedef struct _MINIDUMP_USER_STREAM {
+ ULONG32 Type;
+ ULONG BufferSize;
+ PVOID Buffer;
+
+} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM;
+
+
+typedef struct _MINIDUMP_USER_STREAM_INFORMATION {
+ ULONG UserStreamCount;
+ PMINIDUMP_USER_STREAM UserStreamArray;
+} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION;
+
+//
+// Callback support.
+//
+
+typedef enum _MINIDUMP_CALLBACK_TYPE {
+ ModuleCallback,
+ ThreadCallback,
+ ThreadExCallback,
+ IncludeThreadCallback,
+ IncludeModuleCallback,
+ MemoryCallback,
+ CancelCallback,
+ WriteKernelMinidumpCallback,
+ KernelMinidumpStatusCallback,
+ RemoveMemoryCallback,
+ IncludeVmRegionCallback,
+ IoStartCallback,
+ IoWriteAllCallback,
+ IoFinishCallback,
+ ReadMemoryFailureCallback,
+ SecondaryFlagsCallback,
+} MINIDUMP_CALLBACK_TYPE;
+
+
+typedef struct _MINIDUMP_THREAD_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK;
+
+
+typedef struct _MINIDUMP_THREAD_EX_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+ ULONG64 BackingStoreBase;
+ ULONG64 BackingStoreEnd;
+} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK;
+
+
+typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK {
+ ULONG ThreadId;
+} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK;
+
+
+typedef enum _THREAD_WRITE_FLAGS {
+ ThreadWriteThread = 0x0001,
+ ThreadWriteStack = 0x0002,
+ ThreadWriteContext = 0x0004,
+ ThreadWriteBackingStore = 0x0008,
+ ThreadWriteInstructionWindow = 0x0010,
+ ThreadWriteThreadData = 0x0020,
+ ThreadWriteThreadInfo = 0x0040,
+} THREAD_WRITE_FLAGS;
+
+typedef struct _MINIDUMP_MODULE_CALLBACK {
+ PWCHAR FullPath;
+ ULONG64 BaseOfImage;
+ ULONG SizeOfImage;
+ ULONG CheckSum;
+ ULONG TimeDateStamp;
+ VS_FIXEDFILEINFO VersionInfo;
+ PVOID CvRecord;
+ ULONG SizeOfCvRecord;
+ PVOID MiscRecord;
+ ULONG SizeOfMiscRecord;
+} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK;
+
+
+typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK {
+ ULONG64 BaseOfImage;
+} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK;
+
+
+typedef enum _MODULE_WRITE_FLAGS {
+ ModuleWriteModule = 0x0001,
+ ModuleWriteDataSeg = 0x0002,
+ ModuleWriteMiscRecord = 0x0004,
+ ModuleWriteCvRecord = 0x0008,
+ ModuleReferencedByMemory = 0x0010,
+ ModuleWriteTlsData = 0x0020,
+ ModuleWriteCodeSegs = 0x0040,
+} MODULE_WRITE_FLAGS;
+
+
+typedef struct _MINIDUMP_IO_CALLBACK {
+ HANDLE Handle;
+ ULONG64 Offset;
+ PVOID Buffer;
+ ULONG BufferBytes;
+} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK;
+
+
+typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK
+{
+ ULONG64 Offset;
+ ULONG Bytes;
+ HRESULT FailureStatus;
+} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK,
+ *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK;
+
+
+typedef struct _MINIDUMP_CALLBACK_INPUT {
+ ULONG ProcessId;
+ HANDLE ProcessHandle;
+ ULONG CallbackType;
+ union {
+ HRESULT Status;
+ MINIDUMP_THREAD_CALLBACK Thread;
+ MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
+ MINIDUMP_MODULE_CALLBACK Module;
+ MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
+ MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
+ MINIDUMP_IO_CALLBACK Io;
+ MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure;
+ ULONG SecondaryFlags;
+ };
+} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT;
+
+typedef struct _MINIDUMP_CALLBACK_OUTPUT {
+ union {
+ ULONG ModuleWriteFlags;
+ ULONG ThreadWriteFlags;
+ ULONG SecondaryFlags;
+ struct {
+ ULONG64 MemoryBase;
+ ULONG MemorySize;
+ };
+ struct {
+ BOOL CheckCancel;
+ BOOL Cancel;
+ };
+ HANDLE Handle;
+ struct {
+ MINIDUMP_MEMORY_INFO VmRegion;
+ BOOL Continue;
+ };
+ HRESULT Status;
+ };
+} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT;
+
+
+//
+// A normal minidump contains just the information
+// necessary to capture stack traces for all of the
+// existing threads in a process.
+//
+// A minidump with data segments includes all of the data
+// sections from loaded modules in order to capture
+// global variable contents. This can make the dump much
+// larger if many modules have global data.
+//
+// A minidump with full memory includes all of the accessible
+// memory in the process and can be very large. A minidump
+// with full memory always has the raw memory data at the end
+// of the dump so that the initial structures in the dump can
+// be mapped directly without having to include the raw
+// memory information.
+//
+// Stack and backing store memory can be filtered to remove
+// data unnecessary for stack walking. This can improve
+// compression of stacks and also deletes data that may
+// be private and should not be stored in a dump.
+// Memory can also be scanned to see what modules are
+// referenced by stack and backing store memory to allow
+// omission of other modules to reduce dump size.
+// In either of these modes the ModuleReferencedByMemory flag
+// is set for all modules referenced before the base
+// module callbacks occur.
+//
+// On some operating systems a list of modules that were
+// recently unloaded is kept in addition to the currently
+// loaded module list. This information can be saved in
+// the dump if desired.
+//
+// Stack and backing store memory can be scanned for referenced
+// pages in order to pick up data referenced by locals or other
+// stack memory. This can increase the size of a dump significantly.
+//
+// Module paths may contain undesired information such as user names
+// or other important directory names so they can be stripped. This
+// option reduces the ability to locate the proper image later
+// and should only be used in certain situations.
+//
+// Complete operating system per-process and per-thread information can
+// be gathered and stored in the dump.
+//
+// The virtual address space can be scanned for various types
+// of memory to be included in the dump.
+//
+// Code which is concerned with potentially private information
+// getting into the minidump can set a flag that automatically
+// modifies all existing and future flags to avoid placing
+// unnecessary data in the dump. Basic data, such as stack
+// information, will still be included but optional data, such
+// as indirect memory, will not.
+//
+// When doing a full memory dump it's possible to store all
+// of the enumerated memory region descriptive information
+// in a memory information stream.
+//
+// Additional thread information beyond the basic thread
+// structure can be collected if desired.
+//
+// A minidump with code segments includes all of the code
+// and code-related sections from loaded modules in order
+// to capture executable content.
+//
+// MiniDumpWithoutAuxiliaryState turns off any secondary,
+// auxiliary-supported memory gathering.
+//
+// MiniDumpWithFullAuxiliaryState asks any present auxiliary
+// data providers to include all of their state in the dump.
+// The exact set of what is provided depends on the auxiliary.
+// This can be quite large.
+//
+
+typedef enum _MINIDUMP_TYPE {
+ MiniDumpNormal = 0x00000000,
+ MiniDumpWithDataSegs = 0x00000001,
+ MiniDumpWithFullMemory = 0x00000002,
+ MiniDumpWithHandleData = 0x00000004,
+ MiniDumpFilterMemory = 0x00000008,
+ MiniDumpScanMemory = 0x00000010,
+ MiniDumpWithUnloadedModules = 0x00000020,
+ MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
+ MiniDumpFilterModulePaths = 0x00000080,
+ MiniDumpWithProcessThreadData = 0x00000100,
+ MiniDumpWithPrivateReadWriteMemory = 0x00000200,
+ MiniDumpWithoutOptionalData = 0x00000400,
+ MiniDumpWithFullMemoryInfo = 0x00000800,
+ MiniDumpWithThreadInfo = 0x00001000,
+ MiniDumpWithCodeSegs = 0x00002000,
+ MiniDumpWithoutAuxiliaryState = 0x00004000,
+ MiniDumpWithFullAuxiliaryState = 0x00008000,
+
+ MiniDumpValidTypeFlags = 0x0000ffff,
+} MINIDUMP_TYPE;
+
+//
+// In addition to the primary flags provided to
+// MiniDumpWriteDump there are additional, less
+// frequently used options queried via the secondary
+// flags callback.
+//
+// MiniSecondaryWithoutPowerInfo suppresses the minidump
+// query that retrieves processor power information for
+// MINIDUMP_MISC_INFO.
+//
+
+typedef enum _MINIDUMP_SECONDARY_FLAGS {
+ MiniSecondaryWithoutPowerInfo = 0x00000001,
+
+ MiniSecondaryValidFlags = 0x00000001,
+} MINIDUMP_SECONDARY_FLAGS;
+
+
+//
+// The minidump callback should modify the FieldsToWrite parameter to reflect
+// what portions of the specified thread or module should be written to the
+// file.
+//
+
+typedef
+BOOL
+(WINAPI * MINIDUMP_CALLBACK_ROUTINE) (
+ IN PVOID CallbackParam,
+ IN CONST PMINIDUMP_CALLBACK_INPUT CallbackInput,
+ IN OUT PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
+ );
+
+typedef struct _MINIDUMP_CALLBACK_INFORMATION {
+ MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
+ PVOID CallbackParam;
+} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION;
+
+
+
+//++
+//
+// PVOID
+// RVA_TO_ADDR(
+// PVOID Mapping,
+// ULONG Rva
+// )
+//
+// Routine Description:
+//
+// Map an RVA that is contained within a mapped file to it's associated
+// flat address.
+//
+// Arguments:
+//
+// Mapping - Base address of mapped file containing the RVA.
+//
+// Rva - An Rva to fixup.
+//
+// Return Values:
+//
+// A pointer to the desired data.
+//
+//--
+
+#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva)))
+
+BOOL
+WINAPI
+MiniDumpWriteDump(
+ IN HANDLE hProcess,
+ IN DWORD ProcessId,
+ IN HANDLE hFile,
+ IN MINIDUMP_TYPE DumpType,
+ IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
+ IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
+ IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
+ );
+
+BOOL
+WINAPI
+MiniDumpReadDumpStream(
+ IN PVOID BaseOfDump,
+ IN ULONG StreamNumber,
+ OUT PMINIDUMP_DIRECTORY * Dir, OPTIONAL
+ OUT PVOID * StreamPointer, OPTIONAL
+ OUT ULONG * StreamSize OPTIONAL
+ );
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#else
+#pragma warning(default:4200) /* Zero length array */
+#pragma warning(default:4201) /* Nameless struct/union */
+#endif
+#endif
+#endif
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _DBGHELP_
diff --git a/plugins/CrashDumper/src/vc6/dbghelp.lib b/plugins/CrashDumper/src/vc6/dbghelp.lib
new file mode 100644
index 0000000000..5d50c3f74d
--- /dev/null
+++ b/plugins/CrashDumper/src/vc6/dbghelp.lib
Binary files differ
diff --git a/plugins/CrashDumper/src/version.h b/plugins/CrashDumper/src/version.h
new file mode 100644
index 0000000000..776e30e404
--- /dev/null
+++ b/plugins/CrashDumper/src/version.h
@@ -0,0 +1,3 @@
+#define __FILEVERSION_STRING 0,0,4,21
+#define __VERSION_STRING "0.0.4.21"
+#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 0, 4, 21)