blob: 8fe466e89ac0c88c5e156f63f59036ecccd2e4fb [file] [log] [blame]
James Kuszmaulcf324122023-01-14 14:07:17 -08001From 6e2f70b7bb7c59fe99b7469bf3e3a257876403dc Mon Sep 17 00:00:00 2001
2From: PJ Reiniger <pj.reiniger@gmail.com>
3Date: Sun, 22 May 2022 23:58:57 -0400
4Subject: [PATCH 1/3] Apply PR #35
5
6---
7 .gitignore | 9 +
8 Main/StackWalker/StackWalker.cpp | 642 ++++++++++--------------
9 Main/StackWalker/StackWalker.h | 40 +-
10 Main/StackWalker/StackWalker_VC2017.sln | 16 +-
11 Main/StackWalker/main.cpp | 2 +-
12 5 files changed, 306 insertions(+), 403 deletions(-)
13 create mode 100644 .gitignore
14
15diff --git a/.gitignore b/.gitignore
16new file mode 100644
17index 0000000..5d102c5
18--- /dev/null
19+++ b/.gitignore
20@@ -0,0 +1,9 @@
21+################################################################################
22+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
23+################################################################################
24+
25+*.suo
26+*.db
27+*.sqlite
28+/Main/StackWalker/_ReSharper.Caches/*
29+/.vs/*
30diff --git a/Main/StackWalker/StackWalker.cpp b/Main/StackWalker/StackWalker.cpp
31index 7008ac6..48c7c57 100644
32--- a/Main/StackWalker/StackWalker.cpp
33+++ b/Main/StackWalker/StackWalker.cpp
34@@ -1,4 +1,4 @@
35-/**********************************************************************
36+/**********************************************************************
37 *
38 * StackWalker.cpp
39 * https://github.com/JochenKalmbach/StackWalker
40@@ -87,162 +87,36 @@
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <tchar.h>
44-#include <windows.h>
45 #pragma comment(lib, "version.lib") // for "VerQueryValue"
46 #pragma warning(disable : 4826)
47
48+#ifdef UNICODE
49+ #define DBGHELP_TRANSLATE_TCHAR
50
51-// If VC7 and later, then use the shipped 'dbghelp.h'-file
52+#endif
53 #pragma pack(push, 8)
54-#if _MSC_VER >= 1300
55 #include <dbghelp.h>
56-#else
57-// inline the important dbghelp.h-declarations...
58-typedef enum
59-{
60- SymNone = 0,
61- SymCoff,
62- SymCv,
63- SymPdb,
64- SymExport,
65- SymDeferred,
66- SymSym,
67- SymDia,
68- SymVirtual,
69- NumSymTypes
70-} SYM_TYPE;
71-typedef struct _IMAGEHLP_LINE64
72-{
73- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
74- PVOID Key; // internal
75- DWORD LineNumber; // line number in file
76- PCHAR FileName; // full filename
77- DWORD64 Address; // first instruction of line
78-} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
79-typedef struct _IMAGEHLP_MODULE64
80-{
81- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
82- DWORD64 BaseOfImage; // base load address of module
83- DWORD ImageSize; // virtual size of the loaded module
84- DWORD TimeDateStamp; // date/time stamp from pe header
85- DWORD CheckSum; // checksum from the pe header
86- DWORD NumSyms; // number of symbols in the symbol table
87- SYM_TYPE SymType; // type of symbols loaded
88- CHAR ModuleName[32]; // module name
89- CHAR ImageName[256]; // image name
90- CHAR LoadedImageName[256]; // symbol file name
91-} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
92-typedef struct _IMAGEHLP_SYMBOL64
93-{
94- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
95- DWORD64 Address; // virtual address including dll base address
96- DWORD Size; // estimated size of symbol, can be zero
97- DWORD Flags; // info about the symbols, see the SYMF defines
98- DWORD MaxNameLength; // maximum size of symbol name in 'Name'
99- CHAR Name[1]; // symbol name (null terminated string)
100-} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
101-typedef enum
102-{
103- AddrMode1616,
104- AddrMode1632,
105- AddrModeReal,
106- AddrModeFlat
107-} ADDRESS_MODE;
108-typedef struct _tagADDRESS64
109-{
110- DWORD64 Offset;
111- WORD Segment;
112- ADDRESS_MODE Mode;
113-} ADDRESS64, *LPADDRESS64;
114-typedef struct _KDHELP64
115-{
116- DWORD64 Thread;
117- DWORD ThCallbackStack;
118- DWORD ThCallbackBStore;
119- DWORD NextCallback;
120- DWORD FramePointer;
121- DWORD64 KiCallUserMode;
122- DWORD64 KeUserCallbackDispatcher;
123- DWORD64 SystemRangeStart;
124- DWORD64 Reserved[8];
125-} KDHELP64, *PKDHELP64;
126-typedef struct _tagSTACKFRAME64
127-{
128- ADDRESS64 AddrPC; // program counter
129- ADDRESS64 AddrReturn; // return address
130- ADDRESS64 AddrFrame; // frame pointer
131- ADDRESS64 AddrStack; // stack pointer
132- ADDRESS64 AddrBStore; // backing store pointer
133- PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
134- DWORD64 Params[4]; // possible arguments to the function
135- BOOL Far; // WOW far call
136- BOOL Virtual; // is this a virtual frame?
137- DWORD64 Reserved[3];
138- KDHELP64 KdHelp;
139-} STACKFRAME64, *LPSTACKFRAME64;
140-typedef BOOL(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
141- DWORD64 qwBaseAddress,
142- PVOID lpBuffer,
143- DWORD nSize,
144- LPDWORD lpNumberOfBytesRead);
145-typedef PVOID(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE hProcess, DWORD64 AddrBase);
146-typedef DWORD64(__stdcall* PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address);
147-typedef DWORD64(__stdcall* PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
148- HANDLE hThread,
149- LPADDRESS64 lpaddr);
150-
151-// clang-format off
152-#define SYMOPT_CASE_INSENSITIVE 0x00000001
153-#define SYMOPT_UNDNAME 0x00000002
154-#define SYMOPT_DEFERRED_LOADS 0x00000004
155-#define SYMOPT_NO_CPP 0x00000008
156-#define SYMOPT_LOAD_LINES 0x00000010
157-#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
158-#define SYMOPT_LOAD_ANYTHING 0x00000040
159-#define SYMOPT_IGNORE_CVREC 0x00000080
160-#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
161-#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
162-#define SYMOPT_EXACT_SYMBOLS 0x00000400
163-#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
164-#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
165-#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
166-#define SYMOPT_PUBLICS_ONLY 0x00004000
167-#define SYMOPT_NO_PUBLICS 0x00008000
168-#define SYMOPT_AUTO_PUBLICS 0x00010000
169-#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
170-#define SYMOPT_SECURE 0x00040000
171-#define SYMOPT_DEBUG 0x80000000
172-#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
173-#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
174-// clang-format on
175-
176-#endif // _MSC_VER < 1300
177 #pragma pack(pop)
178
179-// Some missing defines (for VC5/6):
180-#ifndef INVALID_FILE_ATTRIBUTES
181-#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
182-#endif
183
184-// secure-CRT_functions are only available starting with VC8
185-#if _MSC_VER < 1400
186-#define strcpy_s(dst, len, src) strcpy(dst, src)
187-#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src)
188-#define strcat_s(dst, len, src) strcat(dst, src)
189-#define _snprintf_s _snprintf
190-#define _tcscat_s _tcscat
191-#endif
192-
193-static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
194+static void MyStrCpy(TCHAR* szDest, size_t nMaxDestSize, const TCHAR* szSrc)
195 {
196 if (nMaxDestSize <= 0)
197 return;
198- strncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE);
199+ _tcsncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE);
200 // INFO: _TRUNCATE will ensure that it is null-terminated;
201 // but with older compilers (<1400) it uses "strncpy" and this does not!)
202 szDest[nMaxDestSize - 1] = 0;
203 } // MyStrCpy
204
205+#ifdef _UNICODE
206+ typedef SYMBOL_INFOW tSymbolInfo;
207+ typedef IMAGEHLP_LINEW64 tImageHelperLine;
208+#else
209+ typedef SYMBOL_INFO tSymbolInfo;
210+ typedef IMAGEHLP_LINE64 tImageHelperLine;
211+#endif
212+
213 // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
214 #define USED_CONTEXT_FLAGS CONTEXT_FULL
215
216@@ -253,26 +127,26 @@ public:
217 {
218 m_parent = parent;
219 m_hDbhHelp = NULL;
220- pSC = NULL;
221+ symCleanup = NULL;
222 m_hProcess = hProcess;
223 m_szSymPath = NULL;
224- pSFTA = NULL;
225- pSGLFA = NULL;
226- pSGMB = NULL;
227- pSGMI = NULL;
228- pSGO = NULL;
229- pSGSFA = NULL;
230- pSI = NULL;
231- pSLM = NULL;
232- pSSO = NULL;
233- pSW = NULL;
234- pUDSN = NULL;
235- pSGSP = NULL;
236+ symFunctionTableAccess64 = NULL;
237+ symGetLineFromAddr64 = NULL;
238+ symGetModuleBase64 = NULL;
239+ symGetModuleInfo64 = NULL;
240+ symGetOptions = NULL;
241+ symFromAddr = NULL;
242+ symInitialize = NULL;
243+ symLoadModuleEx = NULL;
244+ symSetOptions = NULL;
245+ stackWalk64 = NULL;
246+ unDecorateSymbolName = NULL;
247+ symGetSearchPath = NULL;
248 }
249 ~StackWalkerInternal()
250 {
251- if (pSC != NULL)
252- pSC(m_hProcess); // SymCleanup
253+ if (symCleanup != NULL)
254+ symCleanup(m_hProcess); // SymCleanup
255 if (m_hDbhHelp != NULL)
256 FreeLibrary(m_hDbhHelp);
257 m_hDbhHelp = NULL;
258@@ -281,7 +155,7 @@ public:
259 free(m_szSymPath);
260 m_szSymPath = NULL;
261 }
262- BOOL Init(LPCSTR szSymPath)
263+ BOOL Init(LPCTSTR szSymPath)
264 {
265 if (m_parent == NULL)
266 return FALSE;
267@@ -354,54 +228,72 @@ public:
268 m_hDbhHelp = LoadLibrary(_T("dbghelp.dll"));
269 if (m_hDbhHelp == NULL)
270 return FALSE;
271- pSI = (tSI)GetProcAddress(m_hDbhHelp, "SymInitialize");
272- pSC = (tSC)GetProcAddress(m_hDbhHelp, "SymCleanup");
273-
274- pSW = (tSW)GetProcAddress(m_hDbhHelp, "StackWalk64");
275- pSGO = (tSGO)GetProcAddress(m_hDbhHelp, "SymGetOptions");
276- pSSO = (tSSO)GetProcAddress(m_hDbhHelp, "SymSetOptions");
277-
278- pSFTA = (tSFTA)GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64");
279- pSGLFA = (tSGLFA)GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64");
280- pSGMB = (tSGMB)GetProcAddress(m_hDbhHelp, "SymGetModuleBase64");
281- pSGMI = (tSGMI)GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64");
282- pSGSFA = (tSGSFA)GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64");
283- pUDSN = (tUDSN)GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName");
284- pSLM = (tSLM)GetProcAddress(m_hDbhHelp, "SymLoadModule64");
285- pSGSP = (tSGSP)GetProcAddress(m_hDbhHelp, "SymGetSearchPath");
286-
287- if (pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || pSGO == NULL ||
288- pSGSFA == NULL || pSI == NULL || pSSO == NULL || pSW == NULL || pUDSN == NULL ||
289- pSLM == NULL)
290+
291+#ifdef _UNICODE
292+ static const char strSymInitialize[] = "SymInitializeW";
293+ static const char strUnDecorateSymbolName[] = "UnDecorateSymbolNameW";
294+ static const char strSymGetSearchPath[] = "SymGetSearchPathW";
295+ static const char strSymLoadModuleEx[] = "SymLoadModuleExW";
296+ static const char strSymGetLineFromAddr64[] = "SymGetLineFromAddrW64";
297+ static const char strSymGetModuleInfo64[] = "SymGetModuleInfoW64";
298+ static const char strSymFromAddr[] = "SymFromAddrW";
299+#else
300+ static const char strSymInitialize[] = "SymInitialize";
301+ static const char strUnDecorateSymbolName[] = "UnDecorateSymbolName";
302+ static const char strSymGetSearchPath[] = "SymGetSearchPath";
303+ static const char strSymLoadModuleEx[] = "SymLoadModuleEx";
304+ static const char strSymGetLineFromAddr64[] = "SymGetLineFromAddr64";
305+ static const char strSymGetModuleInfo64[] = "SymGetModuleInfo64";
306+ static const char strSymFromAddr[] = "SymFromAddr";
307+#endif
308+ symInitialize = (tSI)GetProcAddress(m_hDbhHelp, strSymInitialize);
309+ symCleanup = (tSC)GetProcAddress(m_hDbhHelp, "SymCleanup");
310+
311+ stackWalk64 = (tSW)GetProcAddress(m_hDbhHelp, "StackWalk64");
312+ symGetOptions = (tSGO)GetProcAddress(m_hDbhHelp, "SymGetOptions");
313+ symSetOptions = (tSSO)GetProcAddress(m_hDbhHelp, "SymSetOptions");
314+
315+ symFunctionTableAccess64 = (tSFTA)GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64");
316+ symGetLineFromAddr64 = (tSGLFA)GetProcAddress(m_hDbhHelp, strSymGetLineFromAddr64);
317+ symGetModuleBase64 = (tSGMB)GetProcAddress(m_hDbhHelp, "SymGetModuleBase64");
318+ symGetModuleInfo64 = (tSGMI)GetProcAddress(m_hDbhHelp, strSymGetModuleInfo64);
319+ symFromAddr = (tSFA)GetProcAddress(m_hDbhHelp, strSymFromAddr);
320+ unDecorateSymbolName = (tUDSN)GetProcAddress(m_hDbhHelp, strUnDecorateSymbolName);
321+ symLoadModuleEx = (tSLM)GetProcAddress(m_hDbhHelp, strSymLoadModuleEx);
322+ symGetSearchPath = (tSGSP)GetProcAddress(m_hDbhHelp, strSymGetSearchPath);
323+
324+ if (symCleanup == NULL || symFunctionTableAccess64 == NULL || symGetModuleBase64 == NULL || symGetModuleInfo64 == NULL || symGetOptions == NULL ||
325+ symFromAddr == NULL || symInitialize == NULL || symSetOptions == NULL || stackWalk64 == NULL || unDecorateSymbolName == NULL ||
326+ symLoadModuleEx == NULL)
327 {
328 FreeLibrary(m_hDbhHelp);
329 m_hDbhHelp = NULL;
330- pSC = NULL;
331+ symCleanup = NULL;
332 return FALSE;
333 }
334
335 // SymInitialize
336 if (szSymPath != NULL)
337- m_szSymPath = _strdup(szSymPath);
338- if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE)
339- this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
340+ m_szSymPath = _tcsdup(szSymPath);
341+ if (this->symInitialize(m_hProcess, m_szSymPath, FALSE) == FALSE)
342+ this->m_parent->OnDbgHelpErr(_T("SymInitialize"), GetLastError(), 0);
343
344- DWORD symOptions = this->pSGO(); // SymGetOptions
345+ DWORD symOptions = this->symGetOptions(); // SymGetOptions
346 symOptions |= SYMOPT_LOAD_LINES;
347 symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
348 //symOptions |= SYMOPT_NO_PROMPTS;
349 // SymSetOptions
350- symOptions = this->pSSO(symOptions);
351+ symOptions = this->symSetOptions(symOptions);
352
353- char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
354- if (this->pSGSP != NULL)
355+ TCHAR buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
356+ if (this->symGetSearchPath != NULL)
357 {
358- if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
359- this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0);
360+ if (this->symGetSearchPath(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
361+ this->m_parent->OnDbgHelpErr(_T("SymGetSearchPath"), GetLastError(), 0);
362 }
363- char szUserName[1024] = {0};
364+ TCHAR szUserName[1024] = {0};
365 DWORD dwSize = 1024;
366- GetUserNameA(szUserName, &dwSize);
367+ GetUserName(szUserName, &dwSize);
368 this->m_parent->OnSymInit(buf, symOptions, szUserName);
369
370 return TRUE;
371@@ -411,7 +303,7 @@ public:
372
373 HMODULE m_hDbhHelp;
374 HANDLE m_hProcess;
375- LPSTR m_szSymPath;
376+ LPTSTR m_szSymPath;
377
378 #pragma pack(push, 8)
379 typedef struct IMAGEHLP_MODULE64_V3
380@@ -423,13 +315,13 @@ public:
381 DWORD CheckSum; // checksum from the pe header
382 DWORD NumSyms; // number of symbols in the symbol table
383 SYM_TYPE SymType; // type of symbols loaded
384- CHAR ModuleName[32]; // module name
385- CHAR ImageName[256]; // image name
386- CHAR LoadedImageName[256]; // symbol file name
387+ TCHAR ModuleName[32]; // module name
388+ TCHAR ImageName[256]; // image name
389+ TCHAR LoadedImageName[256]; // symbol file name
390 // new elements: 07-Jun-2002
391- CHAR LoadedPdbName[256]; // pdb file name
392+ TCHAR LoadedPdbName[256]; // pdb file name
393 DWORD CVSig; // Signature of the CV record in the debug directories
394- CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
395+ TCHAR CVData[MAX_PATH * 3]; // Contents of the CV record
396 DWORD PdbSig; // Signature of PDB
397 GUID PdbSig70; // Signature of PDB (VC 7 and up)
398 DWORD PdbAge; // DBI age of pdb
399@@ -460,56 +352,59 @@ public:
400
401 // SymCleanup()
402 typedef BOOL(__stdcall* tSC)(IN HANDLE hProcess);
403- tSC pSC;
404+ tSC symCleanup;
405
406 // SymFunctionTableAccess64()
407 typedef PVOID(__stdcall* tSFTA)(HANDLE hProcess, DWORD64 AddrBase);
408- tSFTA pSFTA;
409+ tSFTA symFunctionTableAccess64;
410
411 // SymGetLineFromAddr64()
412 typedef BOOL(__stdcall* tSGLFA)(IN HANDLE hProcess,
413 IN DWORD64 dwAddr,
414 OUT PDWORD pdwDisplacement,
415- OUT PIMAGEHLP_LINE64 Line);
416- tSGLFA pSGLFA;
417+ OUT tImageHelperLine* Line);
418+ tSGLFA symGetLineFromAddr64;
419
420 // SymGetModuleBase64()
421 typedef DWORD64(__stdcall* tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr);
422- tSGMB pSGMB;
423+ tSGMB symGetModuleBase64;
424
425 // SymGetModuleInfo64()
426 typedef BOOL(__stdcall* tSGMI)(IN HANDLE hProcess,
427 IN DWORD64 dwAddr,
428 OUT IMAGEHLP_MODULE64_V3* ModuleInfo);
429- tSGMI pSGMI;
430+ tSGMI symGetModuleInfo64;
431
432 // SymGetOptions()
433 typedef DWORD(__stdcall* tSGO)(VOID);
434- tSGO pSGO;
435+ tSGO symGetOptions;
436+
437
438 // SymGetSymFromAddr64()
439- typedef BOOL(__stdcall* tSGSFA)(IN HANDLE hProcess,
440- IN DWORD64 dwAddr,
441+ typedef BOOL(__stdcall* tSFA)(IN HANDLE hProcess,
442+ IN DWORD64 Address,
443 OUT PDWORD64 pdwDisplacement,
444- OUT PIMAGEHLP_SYMBOL64 Symbol);
445- tSGSFA pSGSFA;
446+ OUT tSymbolInfo* Symbol);
447+ tSFA symFromAddr;
448
449 // SymInitialize()
450- typedef BOOL(__stdcall* tSI)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
451- tSI pSI;
452+ typedef BOOL(__stdcall* tSI)(IN HANDLE hProcess, IN PTSTR UserSearchPath, IN BOOL fInvadeProcess);
453+ tSI symInitialize;
454
455 // SymLoadModule64()
456 typedef DWORD64(__stdcall* tSLM)(IN HANDLE hProcess,
457 IN HANDLE hFile,
458- IN PSTR ImageName,
459- IN PSTR ModuleName,
460+ IN PTSTR ImageName,
461+ IN PTSTR ModuleName,
462 IN DWORD64 BaseOfDll,
463- IN DWORD SizeOfDll);
464- tSLM pSLM;
465+ IN DWORD SizeOfDll,
466+ IN PMODLOAD_DATA Data,
467+ IN DWORD Flags);
468+ tSLM symLoadModuleEx;
469
470 // SymSetOptions()
471 typedef DWORD(__stdcall* tSSO)(IN DWORD SymOptions);
472- tSSO pSSO;
473+ tSSO symSetOptions;
474
475 // StackWalk64()
476 typedef BOOL(__stdcall* tSW)(DWORD MachineType,
477@@ -521,17 +416,17 @@ public:
478 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
479 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
480 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
481- tSW pSW;
482+ tSW stackWalk64;
483
484 // UnDecorateSymbolName()
485- typedef DWORD(__stdcall WINAPI* tUDSN)(PCSTR DecoratedName,
486- PSTR UnDecoratedName,
487+ typedef DWORD(__stdcall WINAPI* tUDSN)(PCTSTR DecoratedName,
488+ PTSTR UnDecoratedName,
489 DWORD UndecoratedLength,
490 DWORD Flags);
491- tUDSN pUDSN;
492+ tUDSN unDecorateSymbolName;
493
494- typedef BOOL(__stdcall WINAPI* tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength);
495- tSGSP pSGSP;
496+ typedef BOOL(__stdcall WINAPI* tSGSP)(HANDLE hProcess, PTSTR SearchPath, DWORD SearchPathLength);
497+ tSGSP symGetSearchPath;
498
499 private:
500 // **************************************** ToolHelp32 ************************
501@@ -548,8 +443,8 @@ private:
502 BYTE* modBaseAddr; // Base address of module in th32ProcessID's context
503 DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
504 HMODULE hModule; // The hModule of this module in th32ProcessID's context
505- char szModule[MAX_MODULE_NAME32 + 1];
506- char szExePath[MAX_PATH];
507+ TCHAR szModule[MAX_MODULE_NAME32 + 1];
508+ TCHAR szExePath[MAX_PATH];
509 } MODULEENTRY32;
510 typedef MODULEENTRY32* PMODULEENTRY32;
511 typedef MODULEENTRY32* LPMODULEENTRY32;
512@@ -567,25 +462,31 @@ private:
513 // try both dlls...
514 const TCHAR* dllname[] = {_T("kernel32.dll"), _T("tlhelp32.dll")};
515 HINSTANCE hToolhelp = NULL;
516- tCT32S pCT32S = NULL;
517- tM32F pM32F = NULL;
518- tM32N pM32N = NULL;
519+ tCT32S createToolhelp32Snapshot = NULL;
520+ tM32F module32First = NULL;
521+ tM32N module32Next = NULL;
522
523 HANDLE hSnap;
524- MODULEENTRY32 me;
525- me.dwSize = sizeof(me);
526+ MODULEENTRY32 moduleEntry32;
527+ moduleEntry32.dwSize = sizeof(moduleEntry32);
528 BOOL keepGoing;
529- size_t i;
530
531- for (i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
532+#ifdef _UNICODE
533+ static const char strModule32First[] = "Module32FirstW";
534+ static const char strModule32Next[] = "Module32NextW";
535+ #else
536+ static const char strModule32First[] = "Module32First";
537+ static const char strModule32Next[] = "Module32Next";
538+#endif
539+ for (size_t i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
540 {
541 hToolhelp = LoadLibrary(dllname[i]);
542 if (hToolhelp == NULL)
543 continue;
544- pCT32S = (tCT32S)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
545- pM32F = (tM32F)GetProcAddress(hToolhelp, "Module32First");
546- pM32N = (tM32N)GetProcAddress(hToolhelp, "Module32Next");
547- if ((pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL))
548+ createToolhelp32Snapshot = (tCT32S)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
549+ module32First = (tM32F)GetProcAddress(hToolhelp, strModule32First);
550+ module32Next = (tM32N)GetProcAddress(hToolhelp, strModule32Next);
551+ if ((createToolhelp32Snapshot != NULL) && (module32First != NULL) && (module32Next != NULL))
552 break; // found the functions!
553 FreeLibrary(hToolhelp);
554 hToolhelp = NULL;
555@@ -594,21 +495,21 @@ private:
556 if (hToolhelp == NULL)
557 return FALSE;
558
559- hSnap = pCT32S(TH32CS_SNAPMODULE, pid);
560+ hSnap = createToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
561 if (hSnap == (HANDLE)-1)
562 {
563 FreeLibrary(hToolhelp);
564 return FALSE;
565 }
566
567- keepGoing = !!pM32F(hSnap, &me);
568+ keepGoing = !!module32First(hSnap, &moduleEntry32);
569 int cnt = 0;
570 while (keepGoing)
571 {
572- this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64)me.modBaseAddr,
573- me.modBaseSize);
574+ this->LoadModule(hProcess, moduleEntry32.szExePath, moduleEntry32.szModule, (DWORD64)moduleEntry32.modBaseAddr,
575+ moduleEntry32.modBaseSize);
576 cnt++;
577- keepGoing = !!pM32N(hSnap, &me);
578+ keepGoing = !!module32Next(hSnap, &moduleEntry32);
579 }
580 CloseHandle(hSnap);
581 FreeLibrary(hToolhelp);
582@@ -631,39 +532,41 @@ private:
583 typedef BOOL(__stdcall * tEPM)(HANDLE hProcess, HMODULE * lphModule, DWORD cb,
584 LPDWORD lpcbNeeded);
585 // GetModuleFileNameEx()
586- typedef DWORD(__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename,
587+ typedef DWORD(__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename,
588 DWORD nSize);
589 // GetModuleBaseName()
590- typedef DWORD(__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename,
591+ typedef DWORD(__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename,
592 DWORD nSize);
593 // GetModuleInformation()
594 typedef BOOL(__stdcall * tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize);
595
596- HINSTANCE hPsapi;
597- tEPM pEPM;
598- tGMFNE pGMFNE;
599- tGMBN pGMBN;
600- tGMI pGMI;
601-
602- DWORD i;
603- //ModuleEntry e;
604+ //ModuleEntry e;
605 DWORD cbNeeded;
606 MODULEINFO mi;
607 HMODULE* hMods = 0;
608- char* tt = NULL;
609- char* tt2 = NULL;
610+ TCHAR* tt = NULL;
611+ TCHAR* tt2 = NULL;
612 const SIZE_T TTBUFLEN = 8096;
613 int cnt = 0;
614
615- hPsapi = LoadLibrary(_T("psapi.dll"));
616+ HINSTANCE hPsapi = LoadLibrary(_T("psapi.dll"));
617 if (hPsapi == NULL)
618 return FALSE;
619
620- pEPM = (tEPM)GetProcAddress(hPsapi, "EnumProcessModules");
621- pGMFNE = (tGMFNE)GetProcAddress(hPsapi, "GetModuleFileNameExA");
622- pGMBN = (tGMFNE)GetProcAddress(hPsapi, "GetModuleBaseNameA");
623- pGMI = (tGMI)GetProcAddress(hPsapi, "GetModuleInformation");
624- if ((pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL))
625+#ifdef _UNICODE
626+ static const char strGetModuleFileName[] = "GetModuleFileNameExW";
627+ static const char strGetModuleBaseName[] = "GetModuleBaseNameW";
628+#else
629+ static const char strGetModuleFileName[] = "GetModulefileNameExA";
630+ static const char strGetModuleBaseName[] = "GetModuleBaseNameA";
631+#endif
632+
633+ tEPM enumProcessModules = (tEPM)GetProcAddress(hPsapi, "EnumProcessModules");
634+ tGMFNE getModuleFileNameEx = (tGMFNE)GetProcAddress(hPsapi, strGetModuleFileName);
635+ tGMBN getModuleBaseName = (tGMFNE)GetProcAddress(hPsapi, strGetModuleBaseName);
636+ tGMI getModuleInformation = (tGMI)GetProcAddress(hPsapi, "GetModuleInformation");
637+ if ((enumProcessModules == NULL) || (getModuleFileNameEx == NULL) ||
638+ (getModuleBaseName == NULL) || (getModuleInformation == NULL))
639 {
640 // we couldn't find all functions
641 FreeLibrary(hPsapi);
642@@ -671,12 +574,12 @@ private:
643 }
644
645 hMods = (HMODULE*)malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE)));
646- tt = (char*)malloc(sizeof(char) * TTBUFLEN);
647- tt2 = (char*)malloc(sizeof(char) * TTBUFLEN);
648+ tt = (TCHAR*)malloc(sizeof(TCHAR) * TTBUFLEN);
649+ tt2 = (TCHAR*)malloc(sizeof(TCHAR) * TTBUFLEN);
650 if ((hMods == NULL) || (tt == NULL) || (tt2 == NULL))
651 goto cleanup;
652
653- if (!pEPM(hProcess, hMods, TTBUFLEN, &cbNeeded))
654+ if (!enumProcessModules(hProcess, hMods, TTBUFLEN, &cbNeeded))
655 {
656 //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle );
657 goto cleanup;
658@@ -688,20 +591,20 @@ private:
659 goto cleanup;
660 }
661
662- for (i = 0; i < cbNeeded / sizeof(hMods[0]); i++)
663+ for (DWORD i = 0; i < cbNeeded / sizeof(hMods[0]); i++)
664 {
665 // base address, size
666- pGMI(hProcess, hMods[i], &mi, sizeof(mi));
667+ getModuleInformation(hProcess, hMods[i], &mi, sizeof(mi));
668 // image file name
669 tt[0] = 0;
670- pGMFNE(hProcess, hMods[i], tt, TTBUFLEN);
671+ getModuleFileNameEx(hProcess, hMods[i], tt, TTBUFLEN);
672 // module name
673 tt2[0] = 0;
674- pGMBN(hProcess, hMods[i], tt2, TTBUFLEN);
675+ getModuleBaseName(hProcess, hMods[i], tt2, TTBUFLEN);
676
677 DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64)mi.lpBaseOfDll, mi.SizeOfImage);
678 if (dwRes != ERROR_SUCCESS)
679- this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0);
680+ this->m_parent->OnDbgHelpErr(_T("LoadModule"), dwRes, 0);
681 cnt++;
682 }
683
684@@ -718,16 +621,16 @@ private:
685 return cnt != 0;
686 } // GetModuleListPSAPI
687
688- DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size)
689+ DWORD LoadModule(HANDLE hProcess, LPCTSTR img, LPCTSTR mod, DWORD64 baseAddr, DWORD size)
690 {
691- CHAR* szImg = _strdup(img);
692- CHAR* szMod = _strdup(mod);
693+ TCHAR* szImg = _tcsdup(img);
694+ TCHAR* szMod = _tcsdup(mod);
695 DWORD result = ERROR_SUCCESS;
696 if ((szImg == NULL) || (szMod == NULL))
697 result = ERROR_NOT_ENOUGH_MEMORY;
698 else
699 {
700- if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0)
701+ if (symLoadModuleEx(hProcess, 0, szImg, szMod, baseAddr, size, 0, 0) == 0)
702 result = GetLastError();
703 }
704 ULONGLONG fileVersion = 0;
705@@ -738,13 +641,13 @@ private:
706 {
707 VS_FIXEDFILEINFO* fInfo = NULL;
708 DWORD dwHandle;
709- DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle);
710+ DWORD dwSize = GetFileVersionInfoSize(szImg, &dwHandle);
711 if (dwSize > 0)
712 {
713 LPVOID vData = malloc(dwSize);
714 if (vData != NULL)
715 {
716- if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
717+ if (GetFileVersionInfo(szImg, dwHandle, dwSize, vData) != 0)
718 {
719 UINT len;
720 TCHAR szSubBlock[] = _T("\\");
721@@ -763,41 +666,41 @@ private:
722
723 // Retrieve some additional-infos about the module
724 IMAGEHLP_MODULE64_V3 Module;
725- const char* szSymType = "-unknown-";
726+ const TCHAR* szSymType = _T("-unknown-");
727 if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE)
728 {
729 switch (Module.SymType)
730 {
731 case SymNone:
732- szSymType = "-nosymbols-";
733+ szSymType = _T("-nosymbols-");
734 break;
735 case SymCoff: // 1
736- szSymType = "COFF";
737+ szSymType = _T("COFF");
738 break;
739 case SymCv: // 2
740- szSymType = "CV";
741+ szSymType = _T("CV");
742 break;
743 case SymPdb: // 3
744- szSymType = "PDB";
745+ szSymType = _T("PDB");
746 break;
747 case SymExport: // 4
748- szSymType = "-exported-";
749+ szSymType = _T("-exported-");
750 break;
751 case SymDeferred: // 5
752- szSymType = "-deferred-";
753+ szSymType = _T("-deferred-");
754 break;
755 case SymSym: // 6
756- szSymType = "SYM";
757+ szSymType = _T("SYM");
758 break;
759 case 7: // SymDia:
760- szSymType = "DIA";
761+ szSymType = _T("DIA");
762 break;
763 case 8: //SymVirtual:
764- szSymType = "Virtual";
765+ szSymType = _T("Virtual");
766 break;
767 }
768 }
769- LPCSTR pdbName = Module.LoadedImageName;
770+ LPCTSTR pdbName = Module.LoadedImageName;
771 if (Module.LoadedPdbName[0] != 0)
772 pdbName = Module.LoadedPdbName;
773 this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, pdbName,
774@@ -823,7 +726,7 @@ public:
775 BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V3* pModuleInfo)
776 {
777 memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3));
778- if (this->pSGMI == NULL)
779+ if (this->symGetModuleInfo64 == NULL)
780 {
781 SetLastError(ERROR_DLL_INIT_FAILED);
782 return FALSE;
783@@ -841,7 +744,7 @@ public:
784 static bool s_useV3Version = true;
785 if (s_useV3Version)
786 {
787- if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
788+ if (this->symGetModuleInfo64(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
789 {
790 // only copy as much memory as is reserved...
791 memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V3));
792@@ -855,7 +758,7 @@ public:
793 // could not retrieve the bigger structure, try with the smaller one (as defined in VC7.1)...
794 pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
795 memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2));
796- if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
797+ if (this->symGetModuleInfo64(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
798 {
799 // only copy as much memory as is reserved...
800 memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2));
801@@ -880,7 +783,7 @@ StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess)
802 this->m_szSymPath = NULL;
803 this->m_MaxRecursionCount = 1000;
804 }
805-StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
806+StackWalker::StackWalker(int options, LPCTSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
807 {
808 this->m_options = options;
809 this->m_modulesLoaded = FALSE;
810@@ -889,7 +792,7 @@ StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDL
811 this->m_dwProcessId = dwProcessId;
812 if (szSymPath != NULL)
813 {
814- this->m_szSymPath = _strdup(szSymPath);
815+ this->m_szSymPath = _tcsdup(szSymPath);
816 this->m_options |= SymBuildPath;
817 }
818 else
819@@ -918,11 +821,11 @@ BOOL StackWalker::LoadModules()
820 return TRUE;
821
822 // Build the sym-path:
823- char* szSymPath = NULL;
824+ TCHAR* szSymPath = NULL;
825 if ((this->m_options & SymBuildPath) != 0)
826 {
827 const size_t nSymPathLen = 4096;
828- szSymPath = (char*)malloc(nSymPathLen);
829+ szSymPath = (TCHAR*)malloc(nSymPathLen * sizeof(TCHAR));
830 if (szSymPath == NULL)
831 {
832 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
833@@ -932,27 +835,27 @@ BOOL StackWalker::LoadModules()
834 // Now first add the (optional) provided sympath:
835 if (this->m_szSymPath != NULL)
836 {
837- strcat_s(szSymPath, nSymPathLen, this->m_szSymPath);
838- strcat_s(szSymPath, nSymPathLen, ";");
839+ _tcscat_s(szSymPath, nSymPathLen, this->m_szSymPath);
840+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
841 }
842
843- strcat_s(szSymPath, nSymPathLen, ".;");
844+ _tcscat_s(szSymPath, nSymPathLen, _T(".;"));
845
846 const size_t nTempLen = 1024;
847- char szTemp[nTempLen];
848+ TCHAR szTemp[nTempLen];
849 // Now add the current directory:
850- if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
851+ if (GetCurrentDirectory(nTempLen, szTemp) > 0)
852 {
853 szTemp[nTempLen - 1] = 0;
854- strcat_s(szSymPath, nSymPathLen, szTemp);
855- strcat_s(szSymPath, nSymPathLen, ";");
856+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
857+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
858 }
859
860 // Now add the path for the main-module:
861- if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0)
862+ if (GetModuleFileName(NULL, szTemp, nTempLen) > 0)
863 {
864 szTemp[nTempLen - 1] = 0;
865- for (char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p)
866+ for (TCHAR* p = (szTemp + _tcslen(szTemp) - 1); p >= szTemp; --p)
867 {
868 // locate the rightmost path separator
869 if ((*p == '\\') || (*p == '/') || (*p == ':'))
870@@ -961,48 +864,48 @@ BOOL StackWalker::LoadModules()
871 break;
872 }
873 } // for (search for path separator...)
874- if (strlen(szTemp) > 0)
875+ if (_tcslen(szTemp) > 0)
876 {
877- strcat_s(szSymPath, nSymPathLen, szTemp);
878- strcat_s(szSymPath, nSymPathLen, ";");
879+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
880+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
881 }
882 }
883- if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
884+ if (GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), szTemp, nTempLen) > 0)
885 {
886 szTemp[nTempLen - 1] = 0;
887- strcat_s(szSymPath, nSymPathLen, szTemp);
888- strcat_s(szSymPath, nSymPathLen, ";");
889+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
890+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
891 }
892- if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
893+ if (GetEnvironmentVariable(_T("_NT_ALTERNATE_SYMBOL_PATH"), szTemp, nTempLen) > 0)
894 {
895 szTemp[nTempLen - 1] = 0;
896- strcat_s(szSymPath, nSymPathLen, szTemp);
897- strcat_s(szSymPath, nSymPathLen, ";");
898+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
899+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
900 }
901- if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0)
902+ if (GetEnvironmentVariable(_T("SYSTEMROOT"), szTemp, nTempLen) > 0)
903 {
904 szTemp[nTempLen - 1] = 0;
905- strcat_s(szSymPath, nSymPathLen, szTemp);
906- strcat_s(szSymPath, nSymPathLen, ";");
907+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
908+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
909 // also add the "system32"-directory:
910- strcat_s(szTemp, nTempLen, "\\system32");
911- strcat_s(szSymPath, nSymPathLen, szTemp);
912- strcat_s(szSymPath, nSymPathLen, ";");
913+ _tcscat_s(szTemp, nTempLen, _T("\\system32"));
914+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
915+ _tcscat_s(szSymPath, nSymPathLen, _T(";"));
916 }
917
918 if ((this->m_options & SymUseSymSrv) != 0)
919 {
920- if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0)
921+ if (GetEnvironmentVariable(_T("SYSTEMDRIVE"), szTemp, nTempLen) > 0)
922 {
923 szTemp[nTempLen - 1] = 0;
924- strcat_s(szSymPath, nSymPathLen, "SRV*");
925- strcat_s(szSymPath, nSymPathLen, szTemp);
926- strcat_s(szSymPath, nSymPathLen, "\\websymbols");
927- strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;");
928+ _tcscat_s(szSymPath, nSymPathLen, _T("SRV*"));
929+ _tcscat_s(szSymPath, nSymPathLen, szTemp);
930+ _tcscat_s(szSymPath, nSymPathLen, _T("\\websymbols"));
931+ _tcscat_s(szSymPath, nSymPathLen, _T("*http://msdl.microsoft.com/download/symbols;"));
932 }
933 else
934- strcat_s(szSymPath, nSymPathLen,
935- "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;");
936+ _tcscat_s(szSymPath, nSymPathLen,
937+ _T("SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"));
938 }
939 } // if SymBuildPath
940
941@@ -1013,7 +916,7 @@ BOOL StackWalker::LoadModules()
942 szSymPath = NULL;
943 if (bRet == FALSE)
944 {
945- this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0);
946+ this->OnDbgHelpErr(_T("Error while initializing dbghelp.dll"), 0, 0);
947 SetLastError(ERROR_DLL_INIT_FAILED);
948 return FALSE;
949 }
950@@ -1038,9 +941,10 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
951 {
952 CONTEXT c;
953 CallstackEntry csEntry;
954- IMAGEHLP_SYMBOL64* pSym = NULL;
955+
956+ tSymbolInfo* pSym = NULL;
957 StackWalkerInternal::IMAGEHLP_MODULE64_V3 Module;
958- IMAGEHLP_LINE64 Line;
959+ tImageHelperLine Line;
960 int frameNum;
961 bool bLastEntryCalled = true;
962 int curRecursionCount = 0;
963@@ -1125,12 +1029,12 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
964 #error "Platform not supported!"
965 #endif
966
967- pSym = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
968+ pSym = (tSymbolInfo*)malloc(sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
969 if (!pSym)
970 goto cleanup; // not enough memory...
971- memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
972- pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
973- pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
974+ memset(pSym, 0, sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
975+ pSym->SizeOfStruct = sizeof(tSymbolInfo);
976+ pSym->MaxNameLen = STACKWALK_MAX_NAMELEN;
977
978 memset(&Line, 0, sizeof(Line));
979 Line.SizeOfStruct = sizeof(Line);
980@@ -1145,11 +1049,11 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
981 // assume that either you are done, or that the stack is so hosed that the next
982 // deeper frame could not be found.
983 // CONTEXT need not to be supplied if imageTyp is IMAGE_FILE_MACHINE_I386!
984- if (!this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem,
985- this->m_sw->pSFTA, this->m_sw->pSGMB, NULL))
986+ if (!this->m_sw->stackWalk64(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem,
987+ this->m_sw->symFunctionTableAccess64, this->m_sw->symGetModuleBase64, NULL))
988 {
989 // INFO: "StackWalk64" does not set "GetLastError"...
990- this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset);
991+ this->OnDbgHelpErr(_T("StackWalk64"), 0, s.AddrPC.Offset);
992 break;
993 }
994
995@@ -1167,7 +1071,7 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
996 {
997 if ((this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount))
998 {
999- this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset);
1000+ this->OnDbgHelpErr(_T("StackWalk64-Endless-Callstack!"), 0, s.AddrPC.Offset);
1001 break;
1002 }
1003 curRecursionCount++;
1004@@ -1178,23 +1082,23 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
1005 {
1006 // we seem to have a valid PC
1007 // show procedure info (SymGetSymFromAddr64())
1008- if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol),
1009+ if (this->m_sw->symFromAddr(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol),
1010 pSym) != FALSE)
1011 {
1012 MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name);
1013 // UnDecorateSymbolName()
1014- this->m_sw->pUDSN(pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
1015- this->m_sw->pUDSN(pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
1016+ DWORD res = this->m_sw->unDecorateSymbolName(pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
1017+ res = this->m_sw->unDecorateSymbolName(pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
1018 }
1019 else
1020 {
1021- this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset);
1022+ this->OnDbgHelpErr(_T("SymGetSymFromAddr64"), GetLastError(), s.AddrPC.Offset);
1023 }
1024
1025 // show line number info, NT5.0-method (SymGetLineFromAddr64())
1026- if (this->m_sw->pSGLFA != NULL)
1027+ if (this->m_sw->symGetLineFromAddr64 != NULL)
1028 { // yes, we have SymGetLineFromAddr64()
1029- if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine),
1030+ if (this->m_sw->symGetLineFromAddr64(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine),
1031 &Line) != FALSE)
1032 {
1033 csEntry.lineNumber = Line.LineNumber;
1034@@ -1202,7 +1106,7 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
1035 }
1036 else
1037 {
1038- this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset);
1039+ this->OnDbgHelpErr(_T("SymGetLineFromAddr64"), GetLastError(), s.AddrPC.Offset);
1040 }
1041 } // yes, we have SymGetLineFromAddr64()
1042
1043@@ -1252,7 +1156,7 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
1044 } // got module info OK
1045 else
1046 {
1047- this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset);
1048+ this->OnDbgHelpErr(_T("SymGetModuleInfo64"), GetLastError(), s.AddrPC.Offset);
1049 }
1050 } // we seem to have a valid PC
1051
1052@@ -1298,20 +1202,20 @@ BOOL StackWalker::ShowObject(LPVOID pObject)
1053 }
1054
1055 // SymGetSymFromAddr64() is required
1056- if (this->m_sw->pSGSFA == NULL)
1057+ if (this->m_sw->symFromAddr == NULL)
1058 return FALSE;
1059
1060 // Show object info (SymGetSymFromAddr64())
1061 DWORD64 dwAddress = DWORD64(pObject);
1062 DWORD64 dwDisplacement = 0;
1063- IMAGEHLP_SYMBOL64* pSym =
1064- (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
1065- memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
1066- pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
1067- pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
1068- if (this->m_sw->pSGSFA(this->m_hProcess, dwAddress, &dwDisplacement, pSym) == FALSE)
1069+ tSymbolInfo* pSym =
1070+ (tSymbolInfo*)malloc(sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
1071+ memset(pSym, 0, sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
1072+ pSym->SizeOfStruct = sizeof(tSymbolInfo);
1073+ pSym->MaxNameLen = STACKWALK_MAX_NAMELEN;
1074+ if (this->m_sw->symFromAddr(this->m_hProcess, dwAddress, &dwDisplacement, pSym) == FALSE)
1075 {
1076- this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), dwAddress);
1077+ this->OnDbgHelpErr(_T("SymGetSymFromAddr64"), GetLastError(), dwAddress);
1078 return FALSE;
1079 }
1080 // Object name output
1081@@ -1342,22 +1246,22 @@ BOOL __stdcall StackWalker::myReadProcMem(HANDLE hProcess,
1082 }
1083 }
1084
1085-void StackWalker::OnLoadModule(LPCSTR img,
1086- LPCSTR mod,
1087+void StackWalker::OnLoadModule(LPCTSTR img,
1088+ LPCTSTR mod,
1089 DWORD64 baseAddr,
1090 DWORD size,
1091 DWORD result,
1092- LPCSTR symType,
1093- LPCSTR pdbName,
1094+ LPCTSTR symType,
1095+ LPCTSTR pdbName,
1096 ULONGLONG fileVersion)
1097 {
1098- CHAR buffer[STACKWALK_MAX_NAMELEN];
1099+ TCHAR buffer[STACKWALK_MAX_NAMELEN];
1100 size_t maxLen = STACKWALK_MAX_NAMELEN;
1101 #if _MSC_VER >= 1400
1102 maxLen = _TRUNCATE;
1103 #endif
1104 if (fileVersion == 0)
1105- _snprintf_s(buffer, maxLen, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n",
1106+ _sntprintf_s(buffer, maxLen, _T("%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n"),
1107 img, mod, (LPVOID)baseAddr, size, result, symType, pdbName);
1108 else
1109 {
1110@@ -1365,9 +1269,9 @@ void StackWalker::OnLoadModule(LPCSTR img,
1111 DWORD v3 = (DWORD)((fileVersion >> 16) & 0xFFFF);
1112 DWORD v2 = (DWORD)((fileVersion >> 32) & 0xFFFF);
1113 DWORD v1 = (DWORD)((fileVersion >> 48) & 0xFFFF);
1114- _snprintf_s(
1115+ _sntprintf_s(
1116 buffer, maxLen,
1117- "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n",
1118+ _T("%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n"),
1119 img, mod, (LPVOID)baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
1120 }
1121 buffer[STACKWALK_MAX_NAMELEN - 1] = 0; // be sure it is NULL terminated
1122@@ -1376,7 +1280,7 @@ void StackWalker::OnLoadModule(LPCSTR img,
1123
1124 void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry)
1125 {
1126- CHAR buffer[STACKWALK_MAX_NAMELEN];
1127+ TCHAR buffer[STACKWALK_MAX_NAMELEN];
1128 size_t maxLen = STACKWALK_MAX_NAMELEN;
1129 #if _MSC_VER >= 1400
1130 maxLen = _TRUNCATE;
1131@@ -1384,48 +1288,48 @@ void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry& ent
1132 if ((eType != lastEntry) && (entry.offset != 0))
1133 {
1134 if (entry.name[0] == 0)
1135- MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)");
1136+ MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, _T("(function-name not available)"));
1137 if (entry.undName[0] != 0)
1138 MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName);
1139 if (entry.undFullName[0] != 0)
1140 MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName);
1141 if (entry.lineFileName[0] == 0)
1142 {
1143- MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)");
1144+ MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, _T("(filename not available)"));
1145 if (entry.moduleName[0] == 0)
1146- MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)");
1147- _snprintf_s(buffer, maxLen, "%p (%s): %s: %s\n", (LPVOID)entry.offset, entry.moduleName,
1148+ MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, _T("(module-name not available)"));
1149+ _sntprintf_s(buffer, maxLen, _T("%p (%s): %s: %s\n"), (LPVOID)entry.offset, entry.moduleName,
1150 entry.lineFileName, entry.name);
1151 }
1152 else
1153- _snprintf_s(buffer, maxLen, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber,
1154+ _sntprintf_s(buffer, maxLen, _T("%s (%d): %s\n"), entry.lineFileName, entry.lineNumber,
1155 entry.name);
1156 buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
1157 OnOutput(buffer);
1158 }
1159 }
1160
1161-void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr)
1162+void StackWalker::OnDbgHelpErr(LPCTSTR szFuncName, DWORD gle, DWORD64 addr)
1163 {
1164- CHAR buffer[STACKWALK_MAX_NAMELEN];
1165+ TCHAR buffer[STACKWALK_MAX_NAMELEN];
1166 size_t maxLen = STACKWALK_MAX_NAMELEN;
1167 #if _MSC_VER >= 1400
1168 maxLen = _TRUNCATE;
1169 #endif
1170- _snprintf_s(buffer, maxLen, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle,
1171+ _sntprintf_s(buffer, maxLen, _T("ERROR: %s, GetLastError: %d (Address: %p)\n"), szFuncName, gle,
1172 (LPVOID)addr);
1173 buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
1174 OnOutput(buffer);
1175 }
1176
1177-void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
1178+void StackWalker::OnSymInit(LPCTSTR szSearchPath, DWORD symOptions, LPCTSTR szUserName)
1179 {
1180- CHAR buffer[STACKWALK_MAX_NAMELEN];
1181+ TCHAR buffer[STACKWALK_MAX_NAMELEN];
1182 size_t maxLen = STACKWALK_MAX_NAMELEN;
1183 #if _MSC_VER >= 1400
1184 maxLen = _TRUNCATE;
1185 #endif
1186- _snprintf_s(buffer, maxLen, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n",
1187+ _sntprintf_s(buffer, maxLen, _T("SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n"),
1188 szSearchPath, symOptions, szUserName);
1189 buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
1190 OnOutput(buffer);
1191@@ -1442,16 +1346,16 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
1192 OnOutput(buffer);
1193 }
1194 #else
1195- OSVERSIONINFOEXA ver;
1196- ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA));
1197+ OSVERSIONINFOEX ver;
1198+ ZeroMemory(&ver, sizeof(OSVERSIONINFOEX));
1199 ver.dwOSVersionInfoSize = sizeof(ver);
1200 #if _MSC_VER >= 1900
1201 #pragma warning(push)
1202 #pragma warning(disable : 4996)
1203 #endif
1204- if (GetVersionExA((OSVERSIONINFOA*)&ver) != FALSE)
1205+ if (GetVersionEx((OSVERSIONINFO*)&ver) != FALSE)
1206 {
1207- _snprintf_s(buffer, maxLen, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", ver.dwMajorVersion,
1208+ _sntprintf_s(buffer, maxLen, _T("OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n"), ver.dwMajorVersion,
1209 ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion, ver.wSuiteMask,
1210 ver.wProductType);
1211 buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
1212@@ -1463,7 +1367,7 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
1213 #endif
1214 }
1215
1216-void StackWalker::OnOutput(LPCSTR buffer)
1217+void StackWalker::OnOutput(LPCTSTR buffer)
1218 {
1219- OutputDebugStringA(buffer);
1220+ OutputDebugString(buffer);
1221 }
1222diff --git a/Main/StackWalker/StackWalker.h b/Main/StackWalker/StackWalker.h
1223index 0a004d9..03efcec 100644
1224--- a/Main/StackWalker/StackWalker.h
1225+++ b/Main/StackWalker/StackWalker.h
1226@@ -47,16 +47,6 @@
1227 #pragma warning(disable : 4091)
1228 #endif
1229
1230-// special defines for VC5/6 (if no actual PSDK is installed):
1231-#if _MSC_VER < 1300
1232-typedef unsigned __int64 DWORD64, *PDWORD64;
1233-#if defined(_WIN64)
1234-typedef unsigned __int64 SIZE_T, *PSIZE_T;
1235-#else
1236-typedef unsigned long SIZE_T, *PSIZE_T;
1237-#endif
1238-#endif // _MSC_VER < 1300
1239-
1240 class StackWalkerInternal; // forward
1241 class StackWalker
1242 {
1243@@ -96,7 +86,7 @@ public:
1244 } StackWalkOptions;
1245
1246 StackWalker(int options = OptionsAll, // 'int' is by design, to combine the enum-flags
1247- LPCSTR szSymPath = NULL,
1248+ LPCTSTR szSymPath = NULL,
1249 DWORD dwProcessId = GetCurrentProcessId(),
1250 HANDLE hProcess = GetCurrentProcess());
1251 StackWalker(DWORD dwProcessId, HANDLE hProcess);
1252@@ -137,18 +127,18 @@ protected:
1253 typedef struct CallstackEntry
1254 {
1255 DWORD64 offset; // if 0, we have no valid entry
1256- CHAR name[STACKWALK_MAX_NAMELEN];
1257- CHAR undName[STACKWALK_MAX_NAMELEN];
1258- CHAR undFullName[STACKWALK_MAX_NAMELEN];
1259+ TCHAR name[STACKWALK_MAX_NAMELEN];
1260+ TCHAR undName[STACKWALK_MAX_NAMELEN];
1261+ TCHAR undFullName[STACKWALK_MAX_NAMELEN];
1262 DWORD64 offsetFromSmybol;
1263 DWORD offsetFromLine;
1264 DWORD lineNumber;
1265- CHAR lineFileName[STACKWALK_MAX_NAMELEN];
1266+ TCHAR lineFileName[STACKWALK_MAX_NAMELEN];
1267 DWORD symType;
1268 LPCSTR symTypeString;
1269- CHAR moduleName[STACKWALK_MAX_NAMELEN];
1270+ TCHAR moduleName[STACKWALK_MAX_NAMELEN];
1271 DWORD64 baseOfImage;
1272- CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
1273+ TCHAR loadedImageName[STACKWALK_MAX_NAMELEN];
1274 } CallstackEntry;
1275
1276 typedef enum CallstackEntryType
1277@@ -158,24 +148,24 @@ protected:
1278 lastEntry
1279 } CallstackEntryType;
1280
1281- virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
1282- virtual void OnLoadModule(LPCSTR img,
1283- LPCSTR mod,
1284+ virtual void OnSymInit(LPCTSTR szSearchPath, DWORD symOptions, LPCTSTR szUserName);
1285+ virtual void OnLoadModule(LPCTSTR img,
1286+ LPCTSTR mod,
1287 DWORD64 baseAddr,
1288 DWORD size,
1289 DWORD result,
1290- LPCSTR symType,
1291- LPCSTR pdbName,
1292+ LPCTSTR symType,
1293+ LPCTSTR pdbName,
1294 ULONGLONG fileVersion);
1295 virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry);
1296- virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
1297- virtual void OnOutput(LPCSTR szText);
1298+ virtual void OnDbgHelpErr(LPCTSTR szFuncName, DWORD gle, DWORD64 addr);
1299+ virtual void OnOutput(LPCTSTR szText);
1300
1301 StackWalkerInternal* m_sw;
1302 HANDLE m_hProcess;
1303 DWORD m_dwProcessId;
1304 BOOL m_modulesLoaded;
1305- LPSTR m_szSymPath;
1306+ LPTSTR m_szSymPath;
1307
1308 int m_options;
1309 int m_MaxRecursionCount;
1310diff --git a/Main/StackWalker/StackWalker_VC2017.sln b/Main/StackWalker/StackWalker_VC2017.sln
1311index 790d550..2209e23 100644
1312--- a/Main/StackWalker/StackWalker_VC2017.sln
1313+++ b/Main/StackWalker/StackWalker_VC2017.sln
1314@@ -16,18 +16,18 @@ Global
1315 Release_VC2017-UNICODE|x64 = Release_VC2017-UNICODE|x64
1316 EndGlobalSection
1317 GlobalSection(ProjectConfigurationPlatforms) = postSolution
1318- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.ActiveCfg = Debug_VC2017-UNICODE|Win32
1319- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.Build.0 = Debug_VC2017-UNICODE|Win32
1320- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.ActiveCfg = Debug_VC2017-UNICODE|x64
1321- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.Build.0 = Debug_VC2017-UNICODE|x64
1322+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.ActiveCfg = Debug_VC2017|Win32
1323+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.Build.0 = Debug_VC2017|Win32
1324+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.ActiveCfg = Debug_VC2017|x64
1325+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.Build.0 = Debug_VC2017|x64
1326 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|Win32.ActiveCfg = Debug_VC2017-UNICODE|Win32
1327 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|Win32.Build.0 = Debug_VC2017-UNICODE|Win32
1328 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|x64.ActiveCfg = Debug_VC2017-UNICODE|x64
1329 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|x64.Build.0 = Debug_VC2017-UNICODE|x64
1330- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.ActiveCfg = Release_VC2017-UNICODE|Win32
1331- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.Build.0 = Release_VC2017-UNICODE|Win32
1332- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.ActiveCfg = Release_VC2017-UNICODE|x64
1333- {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.Build.0 = Release_VC2017-UNICODE|x64
1334+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.ActiveCfg = Release_VC2017|Win32
1335+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.Build.0 = Release_VC2017|Win32
1336+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.ActiveCfg = Release_VC2017|x64
1337+ {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.Build.0 = Release_VC2017|x64
1338 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|Win32.ActiveCfg = Release_VC2017-UNICODE|Win32
1339 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|Win32.Build.0 = Release_VC2017-UNICODE|Win32
1340 {89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|x64.ActiveCfg = Release_VC2017-UNICODE|x64
1341diff --git a/Main/StackWalker/main.cpp b/Main/StackWalker/main.cpp
1342index 220c97b..496021e 100644
1343--- a/Main/StackWalker/main.cpp
1344+++ b/Main/StackWalker/main.cpp
1345@@ -33,7 +33,7 @@ void (*pGlobalFuncPtr)() = 0;
1346 class StackWalkerToConsole : public StackWalker
1347 {
1348 protected:
1349- virtual void OnOutput(LPCSTR szText) { printf("%s", szText); }
1350+ virtual void OnOutput(LPCTSTR szText) { _tprintf(_T("%s"), szText); }
1351 };
1352
1353 void Func5()