blob: 55b11f2752269f16b2377bcb28961813f8f9fb58 (
plain) (
blame)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
//============================================================
//
// winutil.cpp - Win32 OSD core utility functions
//
//============================================================
#include "winutil.h"
// lib/util
#include "timeconv.h"
// osd
#include "strconv.h"
// standard windows headers
#include <windows.h>
#include <direct.h>
//============================================================
// win_attributes_to_entry_type
//============================================================
osd::directory::entry::entry_type win_attributes_to_entry_type(DWORD attributes)
{
if (attributes == 0xFFFFFFFF)
return osd::directory::entry::entry_type::NONE;
else if (attributes & FILE_ATTRIBUTE_DIRECTORY)
return osd::directory::entry::entry_type::DIR;
else
return osd::directory::entry::entry_type::FILE;
}
//============================================================
// win_time_point_from_filetime
//============================================================
std::chrono::system_clock::time_point win_time_point_from_filetime(LPFILETIME file_time)
{
auto converted_file_time = util::ntfs_duration_from_filetime(file_time->dwHighDateTime, file_time->dwLowDateTime);
return util::system_clock_time_point_from_ntfs_duration(converted_file_time);
}
//============================================================
// win_is_gui_application
//============================================================
BOOL win_is_gui_application()
{
static BOOL is_gui_frontend;
static BOOL is_first_time = TRUE;
HMODULE module;
BYTE *image_ptr;
IMAGE_DOS_HEADER *dos_header;
IMAGE_NT_HEADERS *nt_headers;
IMAGE_OPTIONAL_HEADER *opt_header;
// is this the first time we've been ran?
if (is_first_time)
{
is_first_time = FALSE;
// get the current module
module = GetModuleHandleUni();
if (!module)
return FALSE;
image_ptr = (BYTE*) module;
// access the DOS header
dos_header = (IMAGE_DOS_HEADER *) image_ptr;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
// access the NT headers
nt_headers = (IMAGE_NT_HEADERS *) ((BYTE*)(dos_header) + (DWORD)(dos_header->e_lfanew));
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
// access the optional header
opt_header = &nt_headers->OptionalHeader;
switch (opt_header->Subsystem)
{
case IMAGE_SUBSYSTEM_WINDOWS_GUI:
is_gui_frontend = TRUE;
break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI:
is_gui_frontend = FALSE;
break;
}
}
return is_gui_frontend;
}
//============================================================
// osd_subst_env
//============================================================
std::string osd_subst_env(std::string_view src)
{
std::wstring const w_src = osd::text::to_wstring(src);
std::vector<wchar_t> buffer(w_src.size() + 2);
DWORD length(ExpandEnvironmentStringsW(w_src.c_str(), &buffer[0], buffer.size()));
while (length && (buffer.size() < length))
{
buffer.clear();
buffer.resize(length + 1);
length = ExpandEnvironmentStringsW(w_src.c_str(), &buffer[0], buffer.size());
}
std::string dst;
if (length)
osd::text::from_wstring(dst, &buffer[0]);
return dst;
}
//-------------------------------------------------
// Universal way to get module handle
//-------------------------------------------------
HMODULE WINAPI GetModuleHandleUni()
{
HMODULE result = nullptr;
BOOL const succeeded = GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
LPCWSTR(uintptr_t(&GetModuleHandleUni)),
&result);
return succeeded ? result : nullptr;
}
//============================================================
// win_error_to_error_condition
//============================================================
std::error_condition win_error_to_error_condition(DWORD error) noexcept
{
// TODO: work out if there's a better way to do this
switch (error)
{
case ERROR_SUCCESS:
return std::error_condition();
case ERROR_INVALID_HANDLE:
return std::errc::bad_file_descriptor;
case ERROR_OUTOFMEMORY:
return std::errc::not_enough_memory;
case ERROR_NOT_SUPPORTED:
return std::errc::not_supported;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
return std::errc::no_such_file_or_directory;
case ERROR_FILENAME_EXCED_RANGE:
return std::errc::filename_too_long;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return std::errc::permission_denied;
case ERROR_ALREADY_EXISTS:
return std::errc::file_exists;
case ERROR_TOO_MANY_OPEN_FILES:
return std::errc::too_many_files_open;
case ERROR_WRITE_FAULT:
case ERROR_READ_FAULT:
return std::errc::io_error;
case ERROR_HANDLE_DISK_FULL:
case ERROR_DISK_FULL:
return std::errc::no_space_on_device;
case ERROR_PATH_BUSY:
case ERROR_BUSY:
return std::errc::device_or_resource_busy;
case ERROR_FILE_TOO_LARGE:
return std::errc::file_too_large;
case ERROR_INVALID_ACCESS:
case ERROR_NEGATIVE_SEEK:
case ERROR_BAD_ARGUMENTS:
return std::errc::invalid_argument;
default:
return std::error_condition(error, std::system_category());
}
}
|