-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.cpp
123 lines (101 loc) · 2.55 KB
/
log.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
#include "log.h"
#ifdef WALNUT_ENABLE_LOGGING
#include <comdef.h>
#include <shlobj.h>
#include <iostream>
/* Helper class for RAII */
class SystemErrorCodeString {
public:
SystemErrorCodeString(DWORD code) {
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)string, 0, NULL);
}
~SystemErrorCodeString() {
if (string) {
LocalFree(string);
string = NULL;
}
}
SystemErrorCodeString(const SystemErrorCodeString&) = delete;
void operator=(const SystemErrorCodeString&) = delete;
bool IsValid() {
return string && wcslen((wchar_t*)string);
}
LPCWSTR Get() {
return (LPCWSTR) string;
}
private:
LPVOID string {NULL};
};
/**/
std::wofstream Log::stream {};
void Log::initialize() {
PWSTR temp_dir_path = NULL;
std::wstring path;
if (stream.is_open())
return;
try {
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &temp_dir_path);
path = temp_dir_path;
path += L"\\Walnut";
CreateDirectory(path.c_str(), NULL);
path += L"\\Log.txt";
std::ios_base::iostate exception_mask;
exception_mask = stream.exceptions();
exception_mask |= std::ios::failbit;
stream.exceptions(exception_mask);
stream.open(path, std::ios::app);
}
catch (std::ios_base::failure& e) {
OutputDebugStringA(e.what());
}
catch (...) {
}
if (temp_dir_path) {
CoTaskMemFree((LPVOID)temp_dir_path);
temp_dir_path = NULL;
}
}
void Log::finalize() {
stream.close();
}
void Log::print(const std::wstring& str) {
if (!stream) return;
stream << str << L"\n";
}
void Log::print_error_hr(const std::wstring& str, HRESULT hr) {
if (!stream) return;
stream << str;
if (FAILED(hr)) {
_com_error err(hr);
stream << L"\n" << L"HRESULT: " << hr;
auto error_description = err.ErrorMessage();
if (error_description && wcslen(error_description)) {
stream << L"\n" << "Error string: " << error_description;
}
}
stream << L"\n";
}
void Log::print_error_code(const std::wstring& str, DWORD code) {
if (!stream) return;
stream << str;
if (code > 0) {
SystemErrorCodeString error_string(code);
stream << L"\n" << L"Error code: " << code;
if (error_string.IsValid()) {
stream << L"\n" << "Error string: " << error_string.Get();
}
}
stream << L"\n";
}
#else
void Log::initialize() {}
void Log::finalize() {}
void Log::print(const std::wstring& str) {}
void Log::print_error_hr(const std::wstring& str, HRESULT hr) {}
void Log::print_error_code(const std::wstring& str, DWORD code) {}
#endif // WALNUT_ENABLE_LOGGING