WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
Win.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2024 Amebis
4 Copyright © 2016 GÉANT
5*/
6
8
9#pragma once
10
11#include "Common.h"
12#include <AclAPI.h>
13#include <tlhelp32.h>
14#include <winsvc.h>
15#include <string>
16#include <vector>
17
18#pragma warning(push)
19#pragma warning(disable: 4505) // Don't warn on unused code
20
23
25template<class _Traits, class _Ax>
26static DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
27{
28 assert(0); // TODO: Test this code.
29
30 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
31
32 // Try with stack buffer first.
33 DWORD dwResult = ::GetModuleFileNameA(hModule, szStackBuffer, _countof(szStackBuffer));
34 if (dwResult < _countof(szStackBuffer)) {
35 // Copy from stack.
36 sValue.assign(szStackBuffer, dwResult);
37 return dwResult;
38 } else {
39 for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(char);; dwCapacity *= 2) {
40 // Allocate on heap and retry.
41 sValue.resize(dwCapacity - 1);
42 dwResult = ::GetModuleFileNameA(hModule, &sValue[0], dwCapacity);
43 if (dwResult < dwCapacity) {
44 sValue.resize(dwResult);
45 return dwResult;
46 }
47 }
48 }
49}
50
56template<class _Traits, class _Ax>
57static DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
58{
59 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
60
61 // Try with stack buffer first.
62 DWORD dwResult = ::GetModuleFileNameW(hModule, szStackBuffer, _countof(szStackBuffer));
63 if (dwResult < _countof(szStackBuffer)) {
64 // Copy from stack.
65 sValue.assign(szStackBuffer, dwResult);
66 return dwResult;
67 } else {
68 for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t);; dwCapacity *= 2) {
69 // Allocate on heap and retry.
70 sValue.resize(dwCapacity - 1);
71 dwResult = ::GetModuleFileNameW(hModule, &sValue[0], dwCapacity);
72 if (dwResult < dwCapacity) {
73 sValue.resize(dwResult);
74 return dwResult;
75 }
76 }
77 }
78}
79
81template<class _Traits, class _Ax>
82static _Success_(return != 0) int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
83{
84 assert(0); // TODO: Test this code.
85
86 int iResult;
87
88 // Query the final string length first.
89 iResult = ::GetWindowTextLengthA(hWnd);
90 if (iResult > 0) {
91 // Allocate buffer on heap and read the string data into it.
92 sValue.resize(iResult++);
93 return ::GetWindowTextA(hWnd, &sValue[0], iResult);
94 }
95
96 sValue.clear();
97 return 0;
98}
99
105template<class _Traits, class _Ax>
106static _Success_(return != 0) int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
107{
108 assert(0); // TODO: Test this code.
109
110 int iResult;
111
112 // Query the final string length first.
113 iResult = ::GetWindowTextLengthW(hWnd);
114 if (iResult > 0) {
115 // Allocate buffer on heap and read the string data into it.
116 sValue.resize(iResult++);
117 return ::GetWindowTextW(hWnd, &sValue[0], iResult);
118 }
119
120 sValue.clear();
121 return 0;
122}
123
125template<class _Ty, class _Ax>
126static _Success_(return != 0) BOOL GetFileVersionInfoA(_In_z_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) noexcept
127{
128 assert(0); // TODO: Test this code.
129
130 // Get version info size.
131 DWORD dwVerInfoSize = ::GetFileVersionInfoSizeA(lptstrFilename, &dwHandle);
132 if (dwVerInfoSize != 0) {
133 // Read version info.
134 aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
135 return ::GetFileVersionInfoA(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
136 } else
137 return FALSE;
138}
139
145template<class _Ty, class _Ax>
146static _Success_(return != 0) BOOL GetFileVersionInfoW(_In_z_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) noexcept
147{
148 assert(0); // TODO: Test this code.
149
150 // Get version info size.
151 DWORD dwVerInfoSize = ::GetFileVersionInfoSizeW(lptstrFilename, &dwHandle);
152 if (dwVerInfoSize != 0) {
153 // Read version info.
154 aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
155 return ::GetFileVersionInfoW(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
156 } else
157 return FALSE;
158}
159
161template<class _Traits, class _Ax>
162static _Success_(return != 0) DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSrc, _Out_ std::basic_string<char, _Traits, _Ax> &sValue)
163{
164 assert(0); // TODO: Test this code.
165
166 for (SIZE_T sSizeOut = SIZETAdd(strlen(lpSrc), 0x100);;) {
167 if (sSizeOut > DWORD_MAX)
168 throw std::invalid_argument("String too big");
169 DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
170 sValue.resize((size_t)dwSizeIn + 1); // Note: ANSI version requires one extra char.
171 sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, &sValue[0], dwSizeIn);
172 if (sSizeOut == 0) {
173 // Error or zero-length input.
174 break;
175 } else if (sSizeOut <= dwSizeIn) {
176 // The buffer was sufficient.
177 sValue.resize(sSizeOut - 1);
178 return static_cast<DWORD>(sSizeOut);
179 }
180 }
181
182 sValue.clear();
183 return 0;
184}
185
191template<class _Traits, class _Ax>
192static _Success_(return != 0) DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpSrc, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
193{
194 for (SIZE_T sSizeOut = SIZETAdd(wcslen(lpSrc), 0x100);;) {
195 if (sSizeOut > DWORD_MAX)
196 throw std::invalid_argument("String too big");
197 DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
198 sValue.resize(dwSizeIn);
199 sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, &sValue[0], dwSizeIn);
200 if (sSizeOut == 0) {
201 // Error or zero-length input.
202 break;
203 } else if (sSizeOut <= dwSizeIn) {
204 // The buffer was sufficient.
205 sValue.resize(sSizeOut - 1);
206 return static_cast<DWORD>(sSizeOut);
207 }
208 }
209
210 sValue.clear();
211 return 0;
212}
213
215template<class _Traits, class _Ax>
216static VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<char, _Traits, _Ax> &str) noexcept
217{
218 assert(0); // TODO: Test this code.
219
220 sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
221 lpGuid->Data1,
222 lpGuid->Data2,
223 lpGuid->Data3,
224 lpGuid->Data4[0], lpGuid->Data4[1],
225 lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]);
226}
227
234template<class _Traits, class _Ax>
235static VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &str) noexcept
236{
237 assert(0); // TODO: Test this code.
238
239 sprintf(str, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
240 lpGuid->Data1,
241 lpGuid->Data2,
242 lpGuid->Data3,
243 lpGuid->Data4[0], lpGuid->Data4[1],
244 lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]);
245}
246
248#ifdef _UNICODE
249#define GuidToString GuidToStringW
250#else
251#define GuidToString GuidToStringA
252#endif
253
255static _Success_(return) BOOL StringToGuidA(_In_z_ LPCSTR lpszGuid, _Out_ LPGUID lpGuid, _Out_opt_ LPCSTR *lpszGuidEnd = NULL) noexcept
256{
257 GUID g;
258 LPSTR lpszEnd;
259 unsigned long ulTmp;
260 unsigned long long ullTmp;
261
262 if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE;
263 lpszGuid++;
264
265 g.Data1 = strtoul(lpszGuid, &lpszEnd, 16);
266 if (errno == ERANGE) return FALSE;
267 lpszGuid = lpszEnd;
268
269 if (*lpszGuid != '-') return FALSE;
270 lpszGuid++;
271
272 ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
273 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
274 g.Data2 = static_cast<unsigned short>(ulTmp);
275 lpszGuid = lpszEnd;
276
277 if (*lpszGuid != '-') return FALSE;
278 lpszGuid++;
279
280 ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
281 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
282 g.Data3 = static_cast<unsigned short>(ulTmp);
283 lpszGuid = lpszEnd;
284
285 if (*lpszGuid != '-') return FALSE;
286 lpszGuid++;
287
288 ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
289 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
290 g.Data4[0] = static_cast<unsigned char>((ulTmp >> 8) & 0xff);
291 g.Data4[1] = static_cast<unsigned char>( ulTmp & 0xff);
292 lpszGuid = lpszEnd;
293
294 if (*lpszGuid != '-') return FALSE;
295 lpszGuid++;
296
297 ullTmp = _strtoui64(lpszGuid, &lpszEnd, 16);
298 if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE;
299 g.Data4[2] = static_cast<unsigned char>((ullTmp >> 40) & 0xff);
300 g.Data4[3] = static_cast<unsigned char>((ullTmp >> 32) & 0xff);
301 g.Data4[4] = static_cast<unsigned char>((ullTmp >> 24) & 0xff);
302 g.Data4[5] = static_cast<unsigned char>((ullTmp >> 16) & 0xff);
303 g.Data4[6] = static_cast<unsigned char>((ullTmp >> 8) & 0xff);
304 g.Data4[7] = static_cast<unsigned char>( ullTmp & 0xff);
305 lpszGuid = lpszEnd;
306
307 if (*lpszGuid != '}') return FALSE;
308 lpszGuid++;
309
310 if (lpszGuidEnd)
311 *lpszGuidEnd = lpszGuid;
312
313 *lpGuid = g;
314 return TRUE;
315}
316
328static _Success_(return) BOOL StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ LPGUID lpGuid, _Out_opt_ LPCWSTR *lpszGuidEnd = NULL) noexcept
329{
330 GUID g;
331 LPWSTR lpszEnd;
332 unsigned long ulTmp;
333 unsigned long long ullTmp;
334
335 if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE;
336 lpszGuid++;
337
338 g.Data1 = wcstoul(lpszGuid, &lpszEnd, 16);
339 if (errno == ERANGE) return FALSE;
340 lpszGuid = lpszEnd;
341
342 if (*lpszGuid != '-') return FALSE;
343 lpszGuid++;
344
345 ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
346 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
347 g.Data2 = static_cast<unsigned short>(ulTmp);
348 lpszGuid = lpszEnd;
349
350 if (*lpszGuid != '-') return FALSE;
351 lpszGuid++;
352
353 ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
354 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
355 g.Data3 = static_cast<unsigned short>(ulTmp);
356 lpszGuid = lpszEnd;
357
358 if (*lpszGuid != '-') return FALSE;
359 lpszGuid++;
360
361 ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
362 if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
363 g.Data4[0] = static_cast<unsigned char>((ulTmp >> 8) & 0xff);
364 g.Data4[1] = static_cast<unsigned char>( ulTmp & 0xff);
365 lpszGuid = lpszEnd;
366
367 if (*lpszGuid != '-') return FALSE;
368 lpszGuid++;
369
370 ullTmp = _wcstoui64(lpszGuid, &lpszEnd, 16);
371 if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE;
372 g.Data4[2] = static_cast<unsigned char>((ullTmp >> 40) & 0xff);
373 g.Data4[3] = static_cast<unsigned char>((ullTmp >> 32) & 0xff);
374 g.Data4[4] = static_cast<unsigned char>((ullTmp >> 24) & 0xff);
375 g.Data4[5] = static_cast<unsigned char>((ullTmp >> 16) & 0xff);
376 g.Data4[6] = static_cast<unsigned char>((ullTmp >> 8) & 0xff);
377 g.Data4[7] = static_cast<unsigned char>( ullTmp & 0xff);
378 lpszGuid = lpszEnd;
379
380 if (*lpszGuid != '}') return FALSE;
381 lpszGuid++;
382
383 if (lpszGuidEnd)
384 *lpszGuidEnd = lpszGuid;
385
386 *lpGuid = g;
387 return TRUE;
388}
389
391#ifdef _UNICODE
392#define StringToGuid StringToGuidW
393#else
394#define StringToGuid StringToGuidA
395#endif
396
415template<class _Traits, class _Ax>
416static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
417{
418 LSTATUS lResult;
419 BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
420 DWORD dwSize = sizeof(aStackBuffer), dwType;
421
422 // Try with stack buffer first.
423 lResult = ::RegQueryValueExA(hReg, pszName, NULL, &dwType, aStackBuffer, &dwSize);
424 if (lResult == ERROR_SUCCESS) {
425 if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
426 // The value is REG_SZ or REG_MULTI_SZ.
427 dwSize /= sizeof(CHAR);
428 sValue.assign(reinterpret_cast<LPCSTR>(aStackBuffer), dwSize && reinterpret_cast<LPCSTR>(aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
429 } else if (dwType == REG_EXPAND_SZ) {
430 // The value is REG_EXPAND_SZ. Expand it from stack buffer.
431 if (::ExpandEnvironmentStringsA(reinterpret_cast<LPCSTR>(aStackBuffer), sValue) == 0)
432 lResult = ::GetLastError();
433 } else {
434 // The value is not a string type.
435 lResult = ERROR_INVALID_DATA;
436 }
437 } else if (lResult == ERROR_MORE_DATA) {
438 if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
439 // The value is REG_SZ or REG_MULTI_SZ. Read it now.
440 sValue.resize(dwSize / sizeof(CHAR));
441 if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
442 dwSize /= sizeof(CHAR);
443 sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
444 }
445 } else if (dwType == REG_EXPAND_SZ) {
446 // The value is REG_EXPAND_SZ. Read it and expand environment variables.
447 std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR) + 1]);
448 if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
449 dwSize /= sizeof(CHAR);
450 szBuffer[dwSize] = 0;
451 if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0)
452 lResult = ::GetLastError();
453 }
454 } else {
455 // The value is not a string type.
456 lResult = ERROR_INVALID_DATA;
457 }
458 }
459
460 return lResult;
461}
462
481template<class _Traits, class _Ax>
482static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
483{
484 LSTATUS lResult;
485 BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
486 DWORD dwSize = sizeof(aStackBuffer), dwType;
487
488 // Try with stack buffer first.
489 lResult = ::RegQueryValueExW(hReg, pszName, NULL, &dwType, aStackBuffer, &dwSize);
490 if (lResult == ERROR_SUCCESS) {
491 if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
492 // The value is REG_SZ or REG_MULTI_SZ.
493 dwSize /= sizeof(WCHAR);
494 sValue.assign(reinterpret_cast<LPCWSTR>(aStackBuffer), dwSize && reinterpret_cast<LPCWSTR>(aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
495 } else if (dwType == REG_EXPAND_SZ) {
496 // The value is REG_EXPAND_SZ. Expand it from stack buffer.
497 if (::ExpandEnvironmentStringsW(reinterpret_cast<LPCWSTR>(aStackBuffer), sValue) == 0)
498 lResult = ::GetLastError();
499 } else {
500 // The value is not a string type.
501 lResult = ERROR_INVALID_DATA;
502 }
503 } else if (lResult == ERROR_MORE_DATA) {
504 if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
505 // The value is REG_SZ or REG_MULTI_SZ. Read it now.
506 sValue.resize(dwSize / sizeof(WCHAR));
507 if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
508 dwSize /= sizeof(WCHAR);
509 sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
510 }
511 } else if (dwType == REG_EXPAND_SZ) {
512 // The value is REG_EXPAND_SZ. Read it and expand environment variables.
513 std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR) + 1]);
514 if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
515 dwSize /= sizeof(WCHAR);
516 szBuffer[dwSize] = 0;
517 if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
518 lResult = ::GetLastError();
519 }
520 } else {
521 // The value is not a string type.
522 lResult = ERROR_INVALID_DATA;
523 }
524 }
525
526 return lResult;
527}
528
530template<class _Ty, class _Ax>
531static LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_z_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData) noexcept
532{
533 LSTATUS lResult;
534 BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
535 DWORD dwSize = sizeof(aStackBuffer);
536
537 // Try with stack buffer first.
538 lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aStackBuffer, &dwSize);
539 if (lResult == ERROR_SUCCESS) {
540 // Copy from stack buffer.
541 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
542 memcpy(aData.data(), aStackBuffer, dwSize);
543 } else if (lResult == ERROR_MORE_DATA) {
544 // Allocate buffer on heap and retry.
545 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
546 lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, NULL, reinterpret_cast<LPBYTE>(aData.data()), &dwSize);
547 }
548
549 return lResult;
550}
551
557template<class _Ty, class _Ax>
558static LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData) noexcept
559{
560 LSTATUS lResult;
561 BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
562 DWORD dwSize = sizeof(aStackBuffer);
563
564 // Try with stack buffer first.
565 lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aStackBuffer, &dwSize);
566 if (lResult == ERROR_SUCCESS) {
567 // Copy from stack buffer.
568 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
569 memcpy(aData.data(), aStackBuffer, dwSize);
570 } else if (lResult == ERROR_MORE_DATA) {
571 // Allocate buffer on heap and retry.
572 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
573 lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, NULL, reinterpret_cast<LPBYTE>(aData.data()), &dwSize);
574 }
575
576 return lResult;
577}
578
579#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
580
582template<class _Traits, class _Ax>
583static LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_z_ LPCSTR pszValue, _Out_ std::basic_string<char, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCSTR pszDirectory) noexcept
584{
585 // According to "Remarks" section in MSDN documentation of RegLoadMUIString(),
586 // this function is defined but not implemented as ANSI variation.
587 assert(0);
588 return ERROR_CALL_NOT_IMPLEMENTED;
589}
590
596template<class _Traits, class _Ax>
597static LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR pszValue, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCWSTR pszDirectory) noexcept
598{
599 LSTATUS lResult;
600 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
601 DWORD dwSize;
602
603 Flags &= ~REG_MUI_STRING_TRUNCATE;
604
605 // Try with stack buffer first.
606 lResult = RegLoadMUIStringW(hKey, pszValue, szStackBuffer, sizeof(szStackBuffer), &dwSize, Flags, pszDirectory);
607 if (lResult == ERROR_SUCCESS) {
608 // Copy from stack buffer.
609 sOut.assign(szStackBuffer, wcsnlen(szStackBuffer, dwSize/sizeof(wchar_t)));
610 } else if (lResult == ERROR_MORE_DATA) {
611 // Allocate buffer on heap and retry.
612 sOut.resize((dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t) - 1);
613 sOut.resize((lResult = RegLoadMUIStringW(hKey, pszValue, &sOut[0], dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? wcsnlen(&sOut[0], dwSize/sizeof(wchar_t)) : 0);
614 }
615
616 return lResult;
617}
618
619#endif
620
626template<class _Traits, class _Ax>
627static _Success_(return > 0) int NormalizeString(_In_ NORM_FORM NormForm, _In_ LPCWSTR lpSrcString, _In_ int cwSrcLength, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sDstString) noexcept
628{
629 WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
630
631 // Try to convert to stack buffer first.
632 int cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, szStackBuffer, _countof(szStackBuffer));
633 if (cch > 0) {
634 // Copy from stack.
635 sDstString.assign(szStackBuffer, cwSrcLength != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1);
636 } else {
637 switch (::GetLastError()) {
638 case ERROR_INSUFFICIENT_BUFFER:
639 for (int i = 10; i--;) {
640 // Allocate buffer. Then convert again.
641 cch = -cch;
642 sDstString.resize((size_t)cch - 1);
643 cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, &sDstString[0], cch);
644 if (cch > 0) {
645 sDstString.resize(cwSrcLength != -1 ? wcsnlen(&sDstString[0], cch) : (size_t)cch - 1);
646 break;
647 }
648 if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
649 sDstString.clear();
650 break;
651 }
652 }
653 break;
654
655 case ERROR_SUCCESS:
656 sDstString.clear();
657 break;
658 }
659 }
660
661 return cch;
662}
663
669template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
670static _Success_(return > 0) int NormalizeString(_In_ NORM_FORM NormForm, _In_ const std::basic_string<wchar_t, _Traits1, _Ax1> &sSrcString, _Out_ std::basic_string<wchar_t, _Traits2, _Ax2> &sDstString) noexcept
671{
672 WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
673
674 // Try to convert to stack buffer first.
675 int cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), szStackBuffer, _countof(szStackBuffer));
676 if (cch > 0) {
677 // Copy from stack.
678 sDstString.assign(szStackBuffer, cch);
679 } else {
680 switch (::GetLastError()) {
681 case ERROR_INSUFFICIENT_BUFFER:
682 for (int i = 10; i--;) {
683 // Allocate buffer. Then convert again.
684 cch = -cch;
685 sDstString.resize(cch);
686 cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), &sDstString[0], cch);
687 if (cch > 0)
688 break;
689 if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
690 sDstString.clear();
691 break;
692 }
693 }
694 break;
695
696 case ERROR_SUCCESS:
697 sDstString.clear();
698 break;
699 }
700 }
701
702 return cch;
703}
704
706template<class _Traits, class _Ax>
707static _Success_(return != 0) int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string<char, _Traits, _Ax> &sBuffer) noexcept
708{
709 // Get read-only pointer to string resource.
710 LPCSTR pszStr;
711 int i = LoadStringA(hInstance, uID, reinterpret_cast<LPSTR>(&pszStr), 0);
712 if (i) {
713 sBuffer.assign(pszStr, i);
714 return i;
715 } else
716 return 0;
717}
718
724template<class _Traits, class _Ax>
725static _Success_(return != 0) int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sBuffer) noexcept
726{
727 // Get read-only pointer to string resource.
728 LPCWSTR pszStr;
729 int i = LoadStringW(hInstance, uID, reinterpret_cast<LPWSTR>(&pszStr), 0);
730 if (i) {
731 sBuffer.assign(pszStr, i);
732 return i;
733 } else
734 return 0;
735}
736
742static VOID OutputDebugStrV(_In_z_ LPCSTR lpOutputString, _In_ va_list arg) noexcept
743{
744 std::string str;
745 try { vsprintf(str, lpOutputString, arg); } catch (...) { return; }
746 OutputDebugStringA(str.c_str());
747}
748
754static VOID OutputDebugStrV(_In_z_ LPCWSTR lpOutputString, _In_ va_list arg) noexcept
755{
756 std::wstring str;
757 try { vsprintf(str, lpOutputString, arg); } catch (...) { return; }
758 OutputDebugStringW(str.c_str());
759}
760
766static VOID OutputDebugStr(_In_z_ LPCSTR lpOutputString, ...) noexcept
767{
768 va_list arg;
769 va_start(arg, lpOutputString);
770 OutputDebugStrV(lpOutputString, arg);
771 va_end(arg);
772}
773
779static VOID OutputDebugStr(_In_z_ LPCWSTR lpOutputString, ...) noexcept
780{
781 va_list arg;
782 va_start(arg, lpOutputString);
783 OutputDebugStrV(lpOutputString, arg);
784 va_end(arg);
785}
786
788template<class _Traits, class _Ax>
789static _Success_(return != 0) int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCSTR lpFormat, _Out_ std::basic_string<char, _Traits, _Ax> &sDate) noexcept
790{
791 int iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
792 if (iResult) {
793 // Allocate buffer on heap and retry.
794 sDate.resize(iResult - 1);
795 return GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
796 }
797
798 return iResult;
799}
800
806template<class _Traits, class _Ax>
807static _Success_(return != 0) int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCWSTR lpFormat, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sDate) noexcept
808{
809 int iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
810 if (iResult) {
811 // Allocate buffer on heap and retry.
812 sDate.resize(iResult - 1);
813 return GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
814 }
815
816 return iResult;
817}
818
820template<class _Traits, class _Ax>
821static _Success_(return != 0) BOOL LookupAccountSidA(_In_opt_z_ LPCSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<char, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<char, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) noexcept
822{
823 assert(0); // TODO: Test this code.
824
825 DWORD dwNameLen = 0, dwRefDomainLen = 0;
826
827 if (LookupAccountSidA(lpSystemName, lpSid,
828 NULL, &dwNameLen ,
829 NULL, &dwRefDomainLen,
830 peUse))
831 {
832 // Name and domain is blank.
833 if (sName ) sName ->clear();
834 if (sReferencedDomainName) sReferencedDomainName->clear();
835 return TRUE;
836 } else if (GetLastError() == ERROR_MORE_DATA) {
837 // Allocate on heap and retry.
838 std::unique_ptr<char[]> bufName (new char[dwNameLen ]);
839 std::unique_ptr<char[]> bufRefDomain(new char[dwRefDomainLen]);
840 if (LookupAccountSidA(lpSystemName, lpSid,
841 bufName .get(), &dwNameLen ,
842 bufRefDomain.get(), &dwRefDomainLen,
843 peUse))
844 {
845 if (sName ) sName ->assign(bufName .get(), dwNameLen - 1);
846 if (sReferencedDomainName) sReferencedDomainName->assign(bufRefDomain.get(), dwRefDomainLen - 1);
847 return TRUE;
848 }
849 }
850
851 return FALSE;
852}
853
859template<class _Traits, class _Ax>
860static _Success_(return != 0) BOOL LookupAccountSidW(_In_opt_z_ LPCWSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<wchar_t, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<wchar_t, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) noexcept
861{
862 assert(0); // TODO: Test this code.
863
864 DWORD dwNameLen = 0, dwRefDomainLen = 0;
865
866 if (LookupAccountSidW(lpSystemName, lpSid,
867 NULL, &dwNameLen ,
868 NULL, &dwRefDomainLen,
869 peUse))
870 {
871 // Name and domain is blank.
872 if (sName ) sName ->clear();
873 if (sReferencedDomainName) sReferencedDomainName->clear();
874 return TRUE;
875 } else if (GetLastError() == ERROR_MORE_DATA) {
876 // Allocate on heap and retry.
877 std::unique_ptr<wchar_t[]> bufName (new wchar_t[dwNameLen ]);
878 std::unique_ptr<wchar_t[]> bufRefDomain(new wchar_t[dwRefDomainLen]);
879 if (LookupAccountSidW(lpSystemName, lpSid,
880 bufName .get(), &dwNameLen ,
881 bufRefDomain.get(), &dwRefDomainLen,
882 peUse))
883 {
884 if (sName ) sName ->assign(bufName .get(), dwNameLen - 1);
885 if (sReferencedDomainName) sReferencedDomainName->assign(bufRefDomain.get(), dwRefDomainLen - 1);
886 return TRUE;
887 }
888 }
889
890 return FALSE;
891}
892
898static _Success_(return != FALSE) BOOL CreateWellKnownSid(_In_ WELL_KNOWN_SID_TYPE WellKnownSidType, _In_opt_ PSID DomainSid, _Inout_ std::unique_ptr<SID> &Sid)
899{
900 BYTE szStackBuffer[WINSTD_STACK_BUFFER_BYTES];
901 DWORD dwSize = sizeof(szStackBuffer);
902
903 if (CreateWellKnownSid(WellKnownSidType, DomainSid, szStackBuffer, &dwSize)) {
904 // The stack buffer was big enough to retrieve complete data. Alloc and copy.
905 Sid.reset((SID*)new BYTE[dwSize]);
906 memcpy(Sid.get(), szStackBuffer, dwSize);
907 return TRUE;
908 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
909 // The stack buffer was too small to retrieve complete data. Alloc and retry.
910 Sid.reset((SID*)new BYTE[dwSize]);
911 return CreateWellKnownSid(WellKnownSidType, DomainSid, Sid.get(), &dwSize);
912 } else
913 return FALSE;
914}
915
921template<class _Ty>
922static _Success_(return != 0) BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_ std::unique_ptr<_Ty> &TokenInformation) noexcept
923{
924 BYTE szStackBuffer[WINSTD_STACK_BUFFER_BYTES];
925 DWORD dwSize;
926
927 if (GetTokenInformation(TokenHandle, TokenInformationClass, szStackBuffer, sizeof(szStackBuffer), &dwSize)) {
928 // The stack buffer was big enough to retrieve complete data. Alloc and copy.
929 TokenInformation.reset((_Ty*)(new BYTE[dwSize]));
930 memcpy(TokenInformation.get(), szStackBuffer, dwSize);
931 return TRUE;
932 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
933 // The stack buffer was too small to retrieve complete data. Alloc and retry.
934 TokenInformation.reset((_Ty*)(new BYTE[dwSize]));
935 return GetTokenInformation(TokenHandle, TokenInformationClass, TokenInformation.get(), dwSize, &dwSize);
936 } else
937 return FALSE;
938}
939
945template<class _Traits, class _Ax>
946static _Success_(return != 0) BOOL QueryFullProcessImageNameA(_In_ HANDLE hProcess, _In_ DWORD dwFlags, _Inout_ std::basic_string<char, _Traits, _Ax>& sExeName)
947{
948 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES / sizeof(char)];
949 DWORD dwSize = _countof(szStackBuffer);
950
951 // Try with stack buffer first.
952 if (::QueryFullProcessImageNameA(hProcess, dwFlags, szStackBuffer, &dwSize)) {
953 // Copy from stack.
954 sExeName.assign(szStackBuffer, dwSize);
955 return TRUE;
956 }
957 for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(char); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
958 // Allocate on heap and retry.
959 sExeName.resize(dwCapacity - 1);
960 dwSize = dwCapacity;
961 if (::QueryFullProcessImageNameA(hProcess, dwFlags, &sExeName[0], &dwSize)) {
962 sExeName.resize(dwSize);
963 return TRUE;
964 }
965 }
966 return FALSE;
967}
968
974template<class _Traits, class _Ax>
975static _Success_(return != 0) BOOL QueryFullProcessImageNameW(_In_ HANDLE hProcess, _In_ DWORD dwFlags, _Inout_ std::basic_string<wchar_t, _Traits, _Ax>& sExeName)
976{
977 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES / sizeof(wchar_t)];
978 DWORD dwSize = _countof(szStackBuffer);
979
980 // Try with stack buffer first.
981 if (::QueryFullProcessImageNameW(hProcess, dwFlags, szStackBuffer, &dwSize)) {
982 // Copy from stack.
983 sExeName.assign(szStackBuffer, dwSize);
984 return TRUE;
985 }
986 for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(wchar_t); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
987 // Allocate on heap and retry.
988 sExeName.resize(dwCapacity - 1);
989 dwSize = dwCapacity;
990 if (::QueryFullProcessImageNameW(hProcess, dwFlags, &sExeName[0], &dwSize)) {
991 sExeName.resize(dwSize);
992 return TRUE;
993 }
994 }
995 return FALSE;
996}
997
999
1000#pragma warning(pop)
1001
1002namespace winstd
1003{
1006
1010 template<HANDLE INVALID>
1011 class win_handle : public handle<HANDLE, INVALID>
1012 {
1014
1015 public:
1021 virtual ~win_handle()
1022 {
1023 if (m_h != invalid)
1024 free_internal();
1025 }
1026
1027 protected:
1033 void free_internal() noexcept override
1034 {
1036 }
1037 };
1038
1044 class library : public handle<HMODULE, NULL>
1045 {
1047
1048 public:
1054 virtual ~library()
1055 {
1056 if (m_h != invalid)
1057 free_internal();
1058 }
1059
1060 protected:
1066 void free_internal() noexcept override
1067 {
1069 }
1070 };
1071
1078
1085
1092
1099
1104 {
1107
1108 public:
1118 {
1119 switch (WaitForSingleObject(m_h, dwMilliseconds)) {
1120 case WAIT_OBJECT_0:
1121 case WAIT_ABANDONED:
1122 return;
1123 case WAIT_TIMEOUT:
1124 throw std::runtime_error("timeout");
1125 case WAIT_FAILED:
1126 throw win_runtime_error("WaitForSingleObject failed");
1127 }
1128 }
1129
1136 {
1137 ReleaseMutex(m_h);
1138 }
1139
1140 protected:
1141 HANDLE m_h;
1142 };
1143
1151
1158
1163 {
1167 void operator()(void* _Ptr) const
1168 {
1169 if (!UnmapViewOfFile(_Ptr))
1170 throw win_runtime_error("UnmapViewOfFile failed");
1171 }
1172 };
1173
1181
1186 {
1189
1190 public:
1200
1207 {
1209 }
1210
1217 {
1218 return &m_data;
1219 }
1220
1221 protected:
1223 };
1224
1230 class find_file : public handle<HANDLE, INVALID_HANDLE_VALUE>
1231 {
1233
1234 public:
1240 virtual ~find_file()
1241 {
1242 if (m_h != invalid)
1243 free_internal();
1244 }
1245
1246 protected:
1252 void free_internal() noexcept override
1253 {
1254 FindClose(m_h);
1255 }
1256 };
1257
1263 class heap : public handle<HANDLE, NULL>
1264 {
1266
1267 public:
1273 virtual ~heap()
1274 {
1275 if (m_h != invalid)
1276 free_internal();
1277 }
1278
1287 {
1288 assert(m_h != invalid);
1289
1290 bool found = false;
1291
1292 // Lock the heap for exclusive access.
1293 HeapLock(m_h);
1294
1296 e.lpData = NULL;
1297 while (HeapWalk(m_h, &e) != FALSE) {
1298 if ((e.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
1300 _T("Allocated block%s%s\n")
1301 _T(" Data portion begins at: %#p\n Size: %d bytes\n")
1302 _T(" Overhead: %d bytes\n Region index: %d\n"),
1303 (e.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0 ? tstring_printf(_T(", movable with HANDLE %#p"), e.Block.hMem).c_str() : _T(""),
1304 (e.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0 ? _T(", DDESHARE") : _T(""),
1305 e.lpData,
1306 e.cbData,
1307 e.cbOverhead,
1308 e.iRegionIndex);
1309
1310 found = true;
1311 }
1312 }
1313
1314 const DWORD dwResult = GetLastError();
1316 OutputDebugStr(_T("HeapWalk failed (error %u).\n"), dwResult);
1317
1318 // Unlock the heap.
1319 HeapUnlock(m_h);
1320
1321 return found;
1322 }
1323
1324 protected:
1330 void free_internal() noexcept override
1331 {
1332 enumerate();
1334 }
1335 };
1336
1340 template <class _Ty>
1342 {
1343 public:
1344 typedef typename _Ty value_type;
1345
1346 typedef _Ty *pointer;
1347 typedef _Ty& reference;
1348 typedef const _Ty *const_pointer;
1349 typedef const _Ty& const_reference;
1350
1353
1357 template <class _Other>
1358 struct rebind
1359 {
1361 };
1362
1363 public:
1371
1377 template <class _Other>
1380
1389 {
1390 assert(m_heap);
1391 return (pointer)HeapAlloc(m_heap, 0, count * sizeof(_Ty));
1392 }
1393
1401 {
1403 assert(m_heap);
1404 HeapFree(m_heap, 0, ptr);
1405 }
1406
1414 {
1415 ::new ((void*)ptr) _Ty(val);
1416 }
1417
1425 {
1426 ::new ((void*)ptr) _Ty(std::forward<_Ty>(val));
1427 }
1428
1435 {
1436 ptr->_Ty::~_Ty();
1437 }
1438
1443 {
1444 return (SIZE_T)-1;
1445 }
1446
1447 public:
1449 };
1450
1455 {
1458
1459 public:
1468 {
1470 m_cookie = 0;
1471 }
1472
1479 {
1480 if (m_cookie)
1482 }
1483
1484 protected:
1486 };
1487
1492 {
1493 public:
1498
1505 {
1506 if (m_cookie)
1507 RevertToSelf();
1508 }
1509
1513 operator bool () const { return m_cookie; }
1514
1515 protected:
1517 };
1518
1540
1545 {
1548
1549 public:
1554 {
1555 TOKEN_PRIVILEGES privileges = { 1, {{{ 0, 0 }, SE_PRIVILEGE_ENABLED }} };
1556 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid) ||
1558 return;
1559
1560 {
1561 HANDLE h;
1563 goto revert;
1566 goto revert;
1568 if (!process_snapshot)
1569 goto revert;
1570 PROCESSENTRY32 entry = { sizeof(PROCESSENTRY32) };
1572 goto revert;
1573 while (_tcsicmp(entry.szExeFile, TEXT("winlogon.exe")) != 0)
1575 goto revert;
1577 if (!winlogon_process)
1578 goto revert;
1580 goto revert;
1583 goto revert;
1586 goto revert;
1587 }
1588
1589 m_cookie = TRUE;
1590 return;
1591
1592 revert:
1594 RevertToSelf();
1596 }
1597 };
1598
1603 {
1604 public:
1611 {
1613 throw win_runtime_error("OpenClipboard failed");
1614 }
1615
1622 {
1624 }
1625 };
1626
1663
1667 class vmemory : public handle<LPVOID, NULL>
1668 {
1670
1671 public:
1677
1688
1695 m_proc(std::move(h.m_proc)),
1696 handle<LPVOID, NULL>(std::move(h))
1697 {}
1698
1704 virtual ~vmemory()
1705 {
1706 if (m_h != invalid)
1708 }
1709
1716 {
1717 if (this != std::addressof(other)) {
1718 (handle<handle_type, NULL>&&)*this = std::move(other);
1719 m_proc = std::move(other.m_proc);
1720 }
1721 return *this;
1722 }
1723
1733 {
1734 m_proc = proc;
1735 if (m_h != invalid)
1736 free_internal();
1737 m_h = h;
1738 }
1739
1749 bool alloc(
1754 _In_ DWORD flProtect) noexcept
1755 {
1757 if (h != invalid) {
1758 attach(hProcess, h);
1759 return true;
1760 } else
1761 return false;
1762 }
1763
1764 protected:
1770 void free_internal() noexcept override
1771 {
1773 }
1774
1775 protected:
1777 };
1778
1785 class reg_key : public handle<HKEY, NULL>
1786 {
1788
1789 public:
1795 virtual ~reg_key()
1796 {
1797 if (m_h != invalid)
1798 free_internal();
1799 }
1800
1811 {
1812 LSTATUS s;
1813
1816 return true;
1817
1818 {
1819 reg_key k;
1820 handle_type h;
1822 if (s == ERROR_SUCCESS)
1823 k.attach(h);
1824 else {
1825 SetLastError(s);
1826 return false;
1827 }
1828 for (;;) {
1831 s = RegEnumKeyEx(k, 0, szName, &dwSize, NULL, NULL, NULL, NULL);
1832 if (s == ERROR_SUCCESS)
1833 k.delete_subkey(szName);
1834 else if (s == ERROR_NO_MORE_ITEMS)
1835 break;
1836 else {
1837 SetLastError(s);
1838 return false;
1839 }
1840 }
1841 }
1842
1844 if (s == ERROR_SUCCESS)
1845 return true;
1846 else {
1847 SetLastError(s);
1848 return false;
1849 }
1850 }
1851
1852 protected:
1858 void free_internal() noexcept override
1859 {
1861 }
1862 };
1863
1867 class security_id : public handle<PSID, NULL>
1868 {
1870
1871 public:
1878 {
1879 if (m_h != invalid)
1880 free_internal();
1881 }
1882
1883 protected:
1889 void free_internal() noexcept override
1890 {
1891 FreeSid(m_h);
1892 }
1893 };
1894
1898 class process_information : public PROCESS_INFORMATION
1899 {
1902
1903 public:
1914
1919 {
1920 #pragma warning(push)
1921 #pragma warning(disable: 6001) // Using uninitialized memory '*this'. << ???
1922
1925
1928
1929 #pragma warning(pop)
1930 }
1931 };
1932
1938 class event_log : public handle<HANDLE, NULL>
1939 {
1941
1942 public:
1948 virtual ~event_log()
1949 {
1950 if (m_h != invalid)
1951 free_internal();
1952 }
1953
1954 protected:
1960 void free_internal() noexcept override
1961 {
1963 }
1964 };
1965
1969 class sc_handle : public handle<SC_HANDLE, NULL>
1970 {
1972
1973 public:
1979 virtual ~sc_handle()
1980 {
1981 if (m_h != invalid)
1982 free_internal();
1983 }
1984
1985 protected:
1991 void free_internal() noexcept override
1992 {
1994 }
1995 };
1996
1998}
1999
2002
2003#pragma warning(push)
2004#pragma warning(disable: 4505) // Don't warn on unused code
2005
2007static LSTATUS RegCreateKeyExA(
2008 _In_ HKEY hKey,
2009 _In_ LPCSTR lpSubKey,
2010 _Reserved_ DWORD Reserved,
2011 _In_opt_ LPSTR lpClass,
2012 _In_ DWORD dwOptions,
2013 _In_ REGSAM samDesired,
2014 _In_opt_ CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
2015 _Inout_ winstd::reg_key &result,
2016 _Out_opt_ LPDWORD lpdwDisposition)
2017{
2018 HKEY h;
2019 LSTATUS s = RegCreateKeyExA(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
2020 if (s == ERROR_SUCCESS)
2021 result.attach(h);
2022 return s;
2023}
2024
2030static LSTATUS RegCreateKeyExW(
2031 _In_ HKEY hKey,
2032 _In_ LPCWSTR lpSubKey,
2033 _Reserved_ DWORD Reserved,
2034 _In_opt_ LPWSTR lpClass,
2035 _In_ DWORD dwOptions,
2036 _In_ REGSAM samDesired,
2037 _In_opt_ CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
2038 _Inout_ winstd::reg_key &result,
2039 _Out_opt_ LPDWORD lpdwDisposition)
2040{
2041 HKEY h;
2042 LSTATUS s = RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
2043 if (s == ERROR_SUCCESS)
2044 result.attach(h);
2045 return s;
2046}
2047
2049static LSTATUS RegOpenKeyExA(
2050 _In_ HKEY hKey,
2051 _In_opt_ LPCSTR lpSubKey,
2052 _In_opt_ DWORD ulOptions,
2053 _In_ REGSAM samDesired,
2054 _Inout_ winstd::reg_key &result)
2055{
2056 HKEY h;
2057 LSTATUS s = RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, &h);
2058 if (s == ERROR_SUCCESS)
2059 result.attach(h);
2060 return s;
2061}
2062
2068static LSTATUS RegOpenKeyExW(
2069 _In_ HKEY hKey,
2070 _In_opt_ LPCWSTR lpSubKey,
2071 _In_opt_ DWORD ulOptions,
2072 _In_ REGSAM samDesired,
2073 _Inout_ winstd::reg_key &result)
2074{
2075 HKEY h;
2076 LSTATUS s = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, &h);
2077 if (s == ERROR_SUCCESS)
2078 result.attach(h);
2079 return s;
2080}
2081
2087static BOOL OpenProcessToken(_In_ HANDLE ProcessHandle, _In_ DWORD DesiredAccess, _Inout_ winstd::win_handle<NULL> &TokenHandle)
2088{
2089 HANDLE h;
2090 if (OpenProcessToken(ProcessHandle, DesiredAccess, &h)) {
2091 TokenHandle.attach(h);
2092 return TRUE;
2093 }
2094 return FALSE;
2095}
2096
2102static BOOL DuplicateTokenEx(_In_ HANDLE hExistingToken, _In_ DWORD dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpTokenAttributes, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ TOKEN_TYPE TokenType, _Inout_ winstd::win_handle<NULL> &NewToken)
2103{
2104 HANDLE h;
2105 if (DuplicateTokenEx(hExistingToken, dwDesiredAccess, lpTokenAttributes, ImpersonationLevel, TokenType, &h)) {
2106 NewToken.attach(h);
2107 return TRUE;
2108 }
2109 return FALSE;
2110}
2111
2117static BOOL AllocateAndInitializeSid(_In_ PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, _In_ BYTE nSubAuthorityCount, _In_ DWORD nSubAuthority0, _In_ DWORD nSubAuthority1, _In_ DWORD nSubAuthority2, _In_ DWORD nSubAuthority3, _In_ DWORD nSubAuthority4, _In_ DWORD nSubAuthority5, _In_ DWORD nSubAuthority6, _In_ DWORD nSubAuthority7, _Inout_ winstd::security_id& Sid)
2118{
2119 PSID h;
2120 if (AllocateAndInitializeSid(pIdentifierAuthority, nSubAuthorityCount, nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3, nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, &h)) {
2121 Sid.attach(h);
2122 return TRUE;
2123 }
2124 return FALSE;
2125}
2126
2128static DWORD SetEntriesInAclA(_In_ ULONG cCountOfExplicitEntries, _In_reads_opt_(cCountOfExplicitEntries) PEXPLICIT_ACCESS_A pListOfExplicitEntries, _In_opt_ PACL OldAcl, _Inout_ std::unique_ptr<ACL, winstd::LocalFree_delete<ACL>>& Acl)
2129{
2130 PACL h;
2131 DWORD dwResult = SetEntriesInAclA(cCountOfExplicitEntries, pListOfExplicitEntries, OldAcl, &h);
2132 if (dwResult == ERROR_SUCCESS)
2133 Acl.reset(h);
2134 return ERROR_SUCCESS;
2135}
2136
2142static DWORD SetEntriesInAclW(_In_ ULONG cCountOfExplicitEntries, _In_reads_opt_(cCountOfExplicitEntries) PEXPLICIT_ACCESS_W pListOfExplicitEntries, _In_opt_ PACL OldAcl, _Inout_ std::unique_ptr<ACL, winstd::LocalFree_delete<ACL>>& Acl)
2143{
2144 PACL h;
2145 DWORD dwResult = SetEntriesInAclW(cCountOfExplicitEntries, pListOfExplicitEntries, OldAcl, &h);
2146 if (dwResult == ERROR_SUCCESS)
2147 Acl.reset(h);
2148 return ERROR_SUCCESS;
2149}
2150
2156template<class _Traits, class _Ax>
2157_Success_(return != 0) BOOL GetThreadPreferredUILanguages(_In_ DWORD dwFlags, _Out_ PULONG pulNumLanguages, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
2158{
2159 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
2160 ULONG ulSize = _countof(szStackBuffer);
2161
2162 // Try with stack buffer first.
2163 if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, szStackBuffer, &ulSize)) {
2164 // Copy from stack.
2165 sValue.assign(szStackBuffer, ulSize - 1);
2166 return TRUE;
2167 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
2168 // Query required size.
2169 ulSize = 0;
2170 GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, NULL, &ulSize);
2171 // Allocate on heap and retry.
2172 sValue.resize(ulSize - 1);
2173 if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, &sValue[0], &ulSize))
2174 return TRUE;
2175 }
2176 return FALSE;
2177}
2178
2179#pragma warning(pop)
2180
Activates given activation context in constructor and deactivates it in destructor.
Definition Win.h:1455
actctx_activator(HANDLE hActCtx) noexcept
Construct the activator and activates the given activation context.
Definition Win.h:1467
virtual ~actctx_activator()
Deactivates activation context and destructs the activator.
Definition Win.h:1478
ULONG_PTR m_cookie
Cookie for context deactivation.
Definition Win.h:1485
Clipboard management.
Definition Win.h:1603
virtual ~clipboard_opener()
Closes the clipboard.
Definition Win.h:1621
clipboard_opener(HWND hWndNewOwner=NULL)
Opens the clipboard for examination and prevents other applications from modifying the clipboard cont...
Definition Win.h:1610
Console control handler stack management.
Definition Win.h:1631
console_ctrl_handler(PHANDLER_ROUTINE HandlerRoutine) noexcept
Construct the console control handler object and pushes the given handler to the console control hand...
Definition Win.h:1643
virtual ~console_ctrl_handler()
Pops console control handler from the console control handler stack.
Definition Win.h:1653
PHANDLER_ROUTINE m_handler
Pointer to console control handler.
Definition Win.h:1661
BOOL m_cookie
Did pushing the console control handler succeed?
Definition Win.h:1660
Critical section wrapper.
Definition Win.h:1186
critical_section() noexcept
Construct the object and initializes a critical section object.
Definition Win.h:1196
CRITICAL_SECTION m_data
Critical section struct.
Definition Win.h:1222
virtual ~critical_section()
Releases all resources used by an unowned critical section object.
Definition Win.h:1206
Event log handle wrapper.
Definition Win.h:1939
void free_internal() noexcept override
Closes an event log handle.
Definition Win.h:1960
virtual ~event_log()
Closes an event log handle.
Definition Win.h:1948
Find-file handle wrapper.
Definition Win.h:1231
virtual ~find_file()
Closes a file search handle.
Definition Win.h:1240
void free_internal() noexcept override
Closes a file search handle.
Definition Win.h:1252
Base abstract template class to support generic object handle keeping.
Definition Common.h:1024
handle_type m_h
Object handle.
Definition Common.h:1276
HeapAlloc allocator.
Definition Win.h:1342
SIZE_T size_type
An unsigned integral type that can represent the length of any sequence that an object of template cl...
Definition Win.h:1351
_Ty value_type
A type that is managed by the allocator.
Definition Win.h:1344
heap_allocator(const heap_allocator< _Other > &other)
Constructs allocator from another type.
Definition Win.h:1378
HANDLE m_heap
Heap handle.
Definition Win.h:1448
pointer allocate(size_type count)
Allocates a new memory block.
Definition Win.h:1388
ptrdiff_t difference_type
A signed integral type that can represent the difference between values of pointers to the type of ob...
Definition Win.h:1352
heap_allocator(HANDLE heap)
Constructs allocator.
Definition Win.h:1369
_Ty & reference
A type that provides a reference to the type of object managed by the allocator.
Definition Win.h:1347
void construct(pointer ptr, _Ty &&val)
Calls moving constructor for the element.
Definition Win.h:1424
void deallocate(pointer ptr, size_type size)
Frees memory block.
Definition Win.h:1400
size_type max_size() const
Returns maximum memory block size.
Definition Win.h:1442
void construct(pointer ptr, const _Ty &val)
Calls copying constructor for the element.
Definition Win.h:1413
const _Ty & const_reference
A type that provides a constant reference to type of object managed by the allocator.
Definition Win.h:1349
const _Ty * const_pointer
A type that provides a constant pointer to the type of object managed by the allocator.
Definition Win.h:1348
_Ty * pointer
A type that provides a pointer to the type of object managed by the allocator.
Definition Win.h:1346
void destroy(pointer ptr)
Calls destructor for the element.
Definition Win.h:1434
Heap handle wrapper.
Definition Win.h:1264
bool enumerate() noexcept
Enumerates allocated heap blocks using OutputDebugString()
Definition Win.h:1286
void free_internal() noexcept override
Destroys the heap.
Definition Win.h:1330
virtual ~heap()
Destroys the heap.
Definition Win.h:1273
Base class for thread impersonation of another security context.
Definition Win.h:1492
virtual ~impersonator()
Reverts to current user and destructs the impersonator.
Definition Win.h:1504
impersonator() noexcept
Construct the impersonator.
Definition Win.h:1497
BOOL m_cookie
Did impersonation succeed?
Definition Win.h:1516
Module handle wrapper.
Definition Win.h:1045
void free_internal() noexcept override
Frees the module.
Definition Win.h:1066
virtual ~library()
Frees the module.
Definition Win.h:1054
Locks given mutex in constructor and releases it in destructor.
Definition Win.h:1104
virtual ~mutex_locker()
Releases ownership of the mutex object.
Definition Win.h:1135
mutex_locker(HANDLE hMutex, DWORD dwMilliseconds=INFINITE)
Waits until the specified mutex is in the signaled state or the time-out interval elapses.
Definition Win.h:1117
PROCESS_INFORMATION struct wrapper.
Definition Win.h:1899
~process_information()
Closes process and thread handles.
Definition Win.h:1918
process_information() noexcept
Constructs blank PROCESS_INFORMATION.
Definition Win.h:1907
Helper class for returning pointers to std::unique_ptr.
Definition Common.h:863
Registry key wrapper class.
Definition Win.h:1786
void free_internal() noexcept override
Closes a handle to the registry key.
Definition Win.h:1858
bool delete_subkey(LPCTSTR szSubkey)
Deletes the specified registry subkey.
Definition Win.h:1810
virtual ~reg_key()
Closes a handle to the registry key.
Definition Win.h:1795
SC_HANDLE wrapper class.
Definition Win.h:1970
void free_internal() noexcept override
Closes an open object handle.
Definition Win.h:1991
virtual ~sc_handle()
Closes an open object handle.
Definition Win.h:1979
SID wrapper class.
Definition Win.h:1868
void free_internal() noexcept override
Closes a handle to the SID.
Definition Win.h:1889
virtual ~security_id()
Closes a handle to the SID.
Definition Win.h:1877
Lets the calling thread impersonate the security context of the SYSTEM user.
Definition Win.h:1545
system_impersonator() noexcept
Construct the impersonator and impersonates the SYSTEM user.
Definition Win.h:1553
Lets the calling thread impersonate the security context of a logged-on user.
Definition Win.h:1523
user_impersonator(HANDLE hToken) noexcept
Construct the impersonator and impersonates the given user.
Definition Win.h:1535
Memory in virtual address space of a process handle wrapper.
Definition Win.h:1668
vmemory & operator=(vmemory &&other) noexcept
Move assignment.
Definition Win.h:1715
bool alloc(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) noexcept
Reserves, commits, or changes the state of a region of memory within the virtual address space of a s...
Definition Win.h:1749
void free_internal() noexcept override
Frees the memory.
Definition Win.h:1770
void attach(HANDLE proc, handle_type h) noexcept
Sets a new memory handle for the class.
Definition Win.h:1732
virtual ~vmemory()
Frees the memory.
Definition Win.h:1704
vmemory(handle_type h, HANDLE proc) noexcept
Initializes a new class instance with an already available object handle.
Definition Win.h:1684
vmemory() noexcept
Initializes a new class instance with the memory handle set to INVAL.
Definition Win.h:1675
vmemory(vmemory &&h) noexcept
Move constructor.
Definition Win.h:1694
HANDLE m_proc
Handle of memory's process.
Definition Win.h:1776
Windows HANDLE wrapper class.
Definition Win.h:1012
void free_internal() noexcept override
Closes an open object handle.
Definition Win.h:1033
virtual ~win_handle()
Closes an open object handle.
Definition Win.h:1021
Windows runtime error.
Definition Common.h:1524
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition Common.h:67
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition Common.h:94
#define WINSTD_NONMOVABLE(C)
Declares a class as non-movable.
Definition Common.h:75
static int sprintf(std::basic_string< _Elem, _Traits, _Ax > &str, const _Elem *format,...)
Formats string using printf().
Definition Common.h:333
static int vsprintf(std::basic_string< char, _Traits, _Ax > &str, const char *format, va_list arg)
Formats string using printf().
Definition Common.h:256
#define WINSTD_HANDLE_IMPL(C, T, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition Common.h:164
static const HANDLE invalid
Invalid handle value.
Definition Common.h:1034
static int NormalizeString(NORM_FORM NormForm, LPCWSTR lpSrcString, int cwSrcLength, std::basic_string< wchar_t, _Traits, _Ax > &sDstString) noexcept
Normalizes characters of a text string according to Unicode 4.0 TR#15.
Definition Win.h:627
static DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Expands environment-variable strings, replaces them with the values defined for the current user,...
Definition Win.h:192
static BOOL StringToGuidA(LPCSTR lpszGuid, LPGUID lpGuid, LPCSTR *lpszGuidEnd=NULL) noexcept
Parses string with GUID and stores it to GUID.
Definition Win.h:255
static int GetWindowTextA(HWND hWnd, std::basic_string< char, _Traits, _Ax > &sValue) noexcept
Copies the text of the specified window's title bar (if it has one) into a std::wstring string.
Definition Win.h:82
static LSTATUS RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, winstd::reg_key &result, LPDWORD lpdwDisposition)
Creates the specified registry key. If the key already exists, the function opens it.
Definition Win.h:2030
static int WINAPI LoadStringA(HINSTANCE hInstance, UINT uID, std::basic_string< char, _Traits, _Ax > &sBuffer) noexcept
Loads a string resource from the executable file associated with a specified module.
Definition Win.h:707
win_handle< INVALID_HANDLE_VALUE > file
File handle wrapper.
Definition Win.h:1150
static BOOL GetFileVersionInfoA(LPCSTR lptstrFilename, __reserved DWORD dwHandle, std::vector< _Ty, _Ax > &aValue) noexcept
Retrieves version information for the specified file and stores it in a std::vector buffer.
Definition Win.h:126
static LSTATUS RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, winstd::reg_key &result, LPDWORD lpdwDisposition)
Creates the specified registry key. If the key already exists, the function opens it.
Definition Win.h:2007
static LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2049
static LSTATUS RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2068
static VOID GuidToStringA(LPCGUID lpGuid, std::basic_string< char, _Traits, _Ax > &str) noexcept
Formats GUID and stores it in a std::wstring string.
Definition Win.h:216
static BOOL StringToGuidW(LPCWSTR lpszGuid, LPGUID lpGuid, LPCWSTR *lpszGuidEnd=NULL) noexcept
Parses string with GUID and stores it to GUID.
Definition Win.h:328
static LSTATUS RegLoadMUIStringW(HKEY hKey, LPCWSTR pszValue, std::basic_string< wchar_t, _Traits, _Ax > &sOut, DWORD Flags, LPCWSTR pszDirectory) noexcept
Loads the specified string from the specified key and subkey, and stores it in a std::wstring string.
Definition Win.h:597
static BOOL OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, winstd::win_handle< NULL > &TokenHandle)
Opens the access token associated with a process.
Definition Win.h:2087
static DWORD SetEntriesInAclW(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS_W pListOfExplicitEntries, PACL OldAcl, std::unique_ptr< ACL, winstd::LocalFree_delete< ACL > > &Acl)
Creates a new access control list (ACL) by merging new access control or audit control information in...
Definition Win.h:2142
static BOOL LookupAccountSidA(LPCSTR lpSystemName, PSID lpSid, std::basic_string< char, _Traits, _Ax > *sName, std::basic_string< char, _Traits, _Ax > *sReferencedDomainName, PSID_NAME_USE peUse) noexcept
Retrieves the name of the account for this SID and the name of the first domain on which this SID is ...
Definition Win.h:821
static DWORD GetModuleFileNameW(HMODULE hModule, std::basic_string< wchar_t, _Traits, _Ax > &sValue) noexcept
Retrieves the fully qualified path for the file that contains the specified module and stores it in a...
Definition Win.h:57
static BOOL LookupAccountSidW(LPCWSTR lpSystemName, PSID lpSid, std::basic_string< wchar_t, _Traits, _Ax > *sName, std::basic_string< wchar_t, _Traits, _Ax > *sReferencedDomainName, PSID_NAME_USE peUse) noexcept
Retrieves the name of the account for this SID and the name of the first domain on which this SID is ...
Definition Win.h:860
static BOOL AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, winstd::security_id &Sid)
Allocates and initializes a security identifier (SID) with up to eight subauthorities.
Definition Win.h:2117
win_handle< INVALID_HANDLE_VALUE > process_snapshot
Process snapshot handle wrapper.
Definition Win.h:1091
static DWORD GetModuleFileNameA(HMODULE hModule, std::basic_string< char, _Traits, _Ax > &sValue) noexcept
Retrieves the fully qualified path for the file that contains the specified module and stores it in a...
Definition Win.h:26
static int GetDateFormatW(LCID Locale, DWORD dwFlags, const SYSTEMTIME *lpDate, LPCWSTR lpFormat, std::basic_string< wchar_t, _Traits, _Ax > &sDate) noexcept
Formats a date as a date string for a locale specified by the locale identifier. The function formats...
Definition Win.h:807
static BOOL CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, PSID DomainSid, std::unique_ptr< SID > &Sid)
Creates a SID for predefined aliases.
Definition Win.h:898
static int WINAPI LoadStringW(HINSTANCE hInstance, UINT uID, std::basic_string< wchar_t, _Traits, _Ax > &sBuffer) noexcept
Loads a string resource from the executable file associated with a specified module.
Definition Win.h:725
static BOOL GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, std::unique_ptr< _Ty > &TokenInformation) noexcept
Retrieves a specified type of information about an access token. The calling process must have approp...
Definition Win.h:922
static BOOL DuplicateTokenEx(HANDLE hExistingToken, DWORD dwDesiredAccess, LPSECURITY_ATTRIBUTES lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, winstd::win_handle< NULL > &NewToken)
Creates a new access token that duplicates an existing token. This function can create either a prima...
Definition Win.h:2102
static DWORD SetEntriesInAclA(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS_A pListOfExplicitEntries, PACL OldAcl, std::unique_ptr< ACL, winstd::LocalFree_delete< ACL > > &Acl)
Creates a new access control list (ACL) by merging new access control or audit control information in...
Definition Win.h:2128
static LSTATUS RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, __reserved LPDWORD lpReserved, LPDWORD lpType, std::vector< _Ty, _Ax > &aData) noexcept
Retrieves the type and data for the specified value name associated with an open registry key and sto...
Definition Win.h:558
static BOOL GetFileVersionInfoW(LPCWSTR lptstrFilename, __reserved DWORD dwHandle, std::vector< _Ty, _Ax > &aValue) noexcept
Retrieves version information for the specified file and stores it in a std::vector buffer.
Definition Win.h:146
win_handle< NULL > event
Event handle wrapper.
Definition Win.h:1180
static LSTATUS RegLoadMUIStringA(HKEY hKey, LPCSTR pszValue, std::basic_string< char, _Traits, _Ax > &sOut, DWORD Flags, LPCSTR pszDirectory) noexcept
Loads the specified string from the specified key and subkey, and stores it in a std::wstring string.
Definition Win.h:583
static VOID OutputDebugStr(LPCSTR lpOutputString,...) noexcept
Formats and sends a string to the debugger for display.
Definition Win.h:766
static BOOL QueryFullProcessImageNameA(HANDLE hProcess, DWORD dwFlags, std::basic_string< char, _Traits, _Ax > &sExeName)
Retrieves the full name of the executable image for the specified process.
Definition Win.h:946
win_handle< NULL > mutex
Mutex handle wrapper.
Definition Win.h:1098
static DWORD ExpandEnvironmentStringsA(LPCSTR lpSrc, std::basic_string< char, _Traits, _Ax > &sValue)
Expands environment-variable strings, replaces them with the values defined for the current user,...
Definition Win.h:162
win_handle< NULL > file_mapping
File mapping.
Definition Win.h:1157
static BOOL QueryFullProcessImageNameW(HANDLE hProcess, DWORD dwFlags, std::basic_string< wchar_t, _Traits, _Ax > &sExeName)
Retrieves the full name of the executable image for the specified process.
Definition Win.h:975
win_handle< NULL > process
Process handle wrapper.
Definition Win.h:1077
static LSTATUS RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, __reserved LPDWORD lpReserved, LPDWORD lpType, std::vector< _Ty, _Ax > &aData) noexcept
Retrieves the type and data for the specified value name associated with an open registry key and sto...
Definition Win.h:531
BOOL GetThreadPreferredUILanguages(DWORD dwFlags, PULONG pulNumLanguages, std::basic_string< wchar_t, _Traits, _Ax > &sValue)
Retrieves the thread preferred UI languages for the current thread.
Definition Win.h:2157
static LSTATUS RegQueryStringValue(HKEY hReg, LPCSTR pszName, std::basic_string< char, _Traits, _Ax > &sValue) noexcept
Queries for a string value in the registry and stores it in a std::string string.
Definition Win.h:416
static int GetWindowTextW(HWND hWnd, std::basic_string< wchar_t, _Traits, _Ax > &sValue) noexcept
Copies the text of the specified window's title bar (if it has one) into a std::wstring string.
Definition Win.h:106
static int GetDateFormatA(LCID Locale, DWORD dwFlags, const SYSTEMTIME *lpDate, LPCSTR lpFormat, std::basic_string< char, _Traits, _Ax > &sDate) noexcept
Formats a date as a date string for a locale specified by the locale identifier. The function formats...
Definition Win.h:789
static VOID GuidToStringW(LPCGUID lpGuid, std::basic_string< wchar_t, _Traits, _Ax > &str) noexcept
Formats GUID and stores it in a std::wstring string.
Definition Win.h:235
static VOID OutputDebugStrV(LPCSTR lpOutputString, va_list arg) noexcept
Formats and sends a string to the debugger for display.
Definition Win.h:742
win_handle< NULL > thread
Thread handle wrapper.
Definition Win.h:1084
Deleter for unique_ptr using UnmapViewOfFile.
Definition Win.h:1163
void operator()(void *_Ptr) const
Delete a pointer.
Definition Win.h:1167
A structure that enables an allocator for objects of one type to allocate storage for objects of anot...
Definition Win.h:1359
heap_allocator< _Other > other
Other allocator type.
Definition Win.h:1360