-
Notifications
You must be signed in to change notification settings - Fork 2
/
windhawk-symbol-helper.cpp
127 lines (99 loc) · 3.54 KB
/
windhawk-symbol-helper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "stdafx.h"
#include "MainDlg.h"
#include "symbols_from_binary.h"
CAppModule _Module;
namespace {
struct CommandLineOptions {
SymbolsFromBinaryOptions symbolsFromBinaryOptions;
std::wstring outputFile;
};
std::optional<CommandLineOptions> OptionsFromCommandLine() {
if (__argc != 8) {
return std::nullopt;
}
const auto is_true = [](const WCHAR* value) {
return _wcsicmp(value, L"true") == 0 || _wcsicmp(value, L"1") == 0;
};
return CommandLineOptions{
.symbolsFromBinaryOptions =
{
.engineDir = __wargv[1],
.symbolsDir = __wargv[2],
.symbolServer = __wargv[3],
.targetExecutable = __wargv[4],
.undecorated = is_true(__wargv[5]),
.decorated = is_true(__wargv[6]),
},
.outputFile = __wargv[7],
};
}
// https://stackoverflow.com/a/69410299
std::string WideStringToString(PCWSTR wide_string) {
int wide_string_len = static_cast<int>(wcslen(wide_string));
int size_needed = WideCharToMultiByte(
CP_UTF8, 0, wide_string, wide_string_len, nullptr, 0, nullptr, nullptr);
if (size_needed <= 0) {
throw std::runtime_error("WideCharToMultiByte() failed: " +
std::to_string(size_needed));
}
std::string result(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, wide_string, wide_string_len, result.data(),
size_needed, nullptr, nullptr);
return result;
}
bool WriteContentsToFile(PCWSTR path, const void* data, DWORD size) {
HANDLE hFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, nullptr,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
DWORD dwBytesWritten;
bool written = WriteFile(hFile, data, size, &dwBytesWritten, nullptr);
CloseHandle(hFile);
return written;
}
} // namespace
int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpstrCmdLine*/,
int nCmdShow) {
if (auto options = OptionsFromCommandLine()) {
try {
auto result =
SymbolsFromBinary(std::move(options->symbolsFromBinaryOptions),
nullptr, nullptr, nullptr);
auto resultUtf8 = WideStringToString(result);
DWORD resultUtf8Size = static_cast<DWORD>(resultUtf8.size());
if (resultUtf8Size < resultUtf8.size()) {
throw std::runtime_error("Size too large");
}
if (!WriteContentsToFile(options->outputFile.c_str(),
resultUtf8.data(), resultUtf8Size)) {
throw std::runtime_error("WriteFile() failed");
}
return 0;
} catch (const std::exception&) {
return 1;
}
}
HRESULT hRes = ::CoInitialize(nullptr);
ATLASSERT(SUCCEEDED(hRes));
AtlInitCommonControls(
ICC_BAR_CLASSES); // add flags to support other controls
hRes = _Module.Init(nullptr, hInstance);
ATLASSERT(SUCCEEDED(hRes));
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
CMainDlg dlgMain;
int nRet = 0;
if (dlgMain.Create(nullptr)) {
dlgMain.ShowWindow(nCmdShow);
nRet = theLoop.Run();
} else {
ATLTRACE(L"Main dialog creation failed!\n");
}
_Module.RemoveMessageLoop();
_Module.Term();
::CoUninitialize();
return nRet;
}