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
25 template<class _Traits, class _Ax>
26 static 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
56 template<class _Traits, class _Ax>
57 static 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
81 template<class _Traits, class _Ax>
82 static _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
105 template<class _Traits, class _Ax>
106 static _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
125 template<class _Ty, class _Ax>
126 static _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
145 template<class _Ty, class _Ax>
146 static _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
161 template<class _Traits, class _Ax>
162 static _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
191 template<class _Traits, class _Ax>
192 static _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
215 template<class _Traits, class _Ax>
216 static 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
234 template<class _Traits, class _Ax>
235 static 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
255 static _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
328 static _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
415 template<class _Traits, class _Ax>
416 static 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
481 template<class _Traits, class _Ax>
482 static 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
530 template<class _Ty, class _Ax>
531 static 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
557 template<class _Ty, class _Ax>
558 static 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
582 template<class _Traits, class _Ax>
583 static 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
596 template<class _Traits, class _Ax>
597 static 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
626 template<class _Traits, class _Ax>
627 static _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
669 template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
670 static _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
706 template<class _Traits, class _Ax>
707 static _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
724 template<class _Traits, class _Ax>
725 static _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
742 static 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
754 static 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
766 static 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
779 static 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
788 template<class _Traits, class _Ax>
789 static _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
806 template<class _Traits, class _Ax>
807 static _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
820 template<class _Traits, class _Ax>
821 static _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
859 template<class _Traits, class _Ax>
860 static _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
898 static _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
921 template<class _Ty>
922 static _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
945 template<class _Traits, class _Ax>
946 static _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
974 template<class _Traits, class _Ax>
975 static _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
1002 namespace winstd
1003{
1006
1010 template<HANDLE INVALID>
1011 class win_handle : public handle<HANDLE, INVALID>
1012 {
1013 WINSTD_HANDLE_IMPL(win_handle, HANDLE, INVALID)
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 {
1035 CloseHandle(m_h);
1036 }
1037 };
1038
1044 class library : public handle<HMODULE, NULL>
1045 {
1046 WINSTD_HANDLE_IMPL(library, HMODULE, NULL)
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 {
1068 FreeLibrary(m_h);
1069 }
1070 };
1071
1077 typedef win_handle<NULL> process;
1078
1084 typedef win_handle<NULL> thread;
1085
1091 typedef win_handle<INVALID_HANDLE_VALUE> process_snapshot;
1092
1098 typedef win_handle<NULL> mutex;
1099
1103 class mutex_locker
1104 {
1105 WINSTD_NONCOPYABLE(mutex_locker)
1106 WINSTD_NONMOVABLE(mutex_locker)
1107
1108 public:
1117 mutex_locker(_In_ HANDLE hMutex, _In_ DWORD dwMilliseconds = INFINITE) : m_h(hMutex)
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
1135 virtual ~mutex_locker()
1136 {
1137 ReleaseMutex(m_h);
1138 }
1139
1140 protected:
1141 HANDLE m_h;
1142 };
1143
1150 typedef win_handle<INVALID_HANDLE_VALUE> file;
1151
1157 typedef win_handle<NULL> file_mapping;
1158
1162 struct UnmapViewOfFile_delete
1163 {
1167 void operator()(void* _Ptr) const
1168 {
1169 if (!UnmapViewOfFile(_Ptr))
1170 throw win_runtime_error("UnmapViewOfFile failed");
1171 }
1172 };
1173
1180 typedef win_handle<NULL> event;
1181
1185 class critical_section
1186 {
1187 WINSTD_NONCOPYABLE(critical_section)
1188 WINSTD_NONMOVABLE(critical_section)
1189
1190 public:
1196 critical_section() noexcept
1197 {
1198 InitializeCriticalSection(&m_data);
1199 }
1200
1206 virtual ~critical_section()
1207 {
1208 DeleteCriticalSection(&m_data);
1209 }
1210
1216 operator LPCRITICAL_SECTION() noexcept
1217 {
1218 return &m_data;
1219 }
1220
1221 protected:
1222 CRITICAL_SECTION m_data;
1223 };
1224
1230 class find_file : public handle<HANDLE, INVALID_HANDLE_VALUE>
1231 {
1232 WINSTD_HANDLE_IMPL(find_file, HANDLE, INVALID_HANDLE_VALUE)
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 {
1265 WINSTD_HANDLE_IMPL(heap, HANDLE, NULL)
1266
1267 public:
1273 virtual ~heap()
1274 {
1275 if (m_h != invalid)
1276 free_internal();
1277 }
1278
1286 bool enumerate() noexcept
1287 {
1288 assert(m_h != invalid);
1289
1290 bool found = false;
1291
1292 // Lock the heap for exclusive access.
1293 HeapLock(m_h);
1294
1295 PROCESS_HEAP_ENTRY e;
1296 e.lpData = NULL;
1297 while (HeapWalk(m_h, &e) != FALSE) {
1298 if ((e.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
1299 OutputDebugStr(
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();
1315 if (dwResult != ERROR_NO_MORE_ITEMS)
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();
1333 HeapDestroy(m_h);
1334 }
1335 };
1336
1340 template <class _Ty>
1341 class heap_allocator
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
1351 typedef SIZE_T size_type;
1352 typedef ptrdiff_t difference_type;
1353
1357 template <class _Other>
1358 struct rebind
1359 {
1360 typedef heap_allocator<_Other> other;
1361 };
1362
1363 public:
1369 heap_allocator(_In_ HANDLE heap) : m_heap(heap)
1370 {}
1371
1377 template <class _Other>
1378 heap_allocator(_In_ const heap_allocator<_Other> &other) : m_heap(other.m_heap)
1379 {}
1380
1388 pointer allocate(_In_ size_type count)
1389 {
1390 assert(m_heap);
1391 return (pointer)HeapAlloc(m_heap, 0, count * sizeof(_Ty));
1392 }
1393
1400 void deallocate(_In_ pointer ptr, _In_ size_type size)
1401 {
1402 UNREFERENCED_PARAMETER(size);
1403 assert(m_heap);
1404 HeapFree(m_heap, 0, ptr);
1405 }
1406
1413 void construct(_Inout_ pointer ptr, _In_ const _Ty& val)
1414 {
1415 ::new ((void*)ptr) _Ty(val);
1416 }
1417
1424 void construct(_Inout_ pointer ptr, _Inout_ _Ty&& val)
1425 {
1426 ::new ((void*)ptr) _Ty(std::forward<_Ty>(val));
1427 }
1428
1434 void destroy(_Inout_ pointer ptr)
1435 {
1436 ptr->_Ty::~_Ty();
1437 }
1438
1442 size_type max_size() const
1443 {
1444 return (SIZE_T)-1;
1445 }
1446
1447 public:
1448 HANDLE m_heap;
1449 };
1450
1454 class actctx_activator
1455 {
1456 WINSTD_NONCOPYABLE(actctx_activator)
1457 WINSTD_NONMOVABLE(actctx_activator)
1458
1459 public:
1467 actctx_activator(_In_ HANDLE hActCtx) noexcept
1468 {
1469 if (!ActivateActCtx(hActCtx, &m_cookie))
1470 m_cookie = 0;
1471 }
1472
1478 virtual ~actctx_activator()
1479 {
1480 if (m_cookie)
1481 DeactivateActCtx(0, m_cookie);
1482 }
1483
1484 protected:
1485 ULONG_PTR m_cookie;
1486 };
1487
1491 class impersonator
1492 {
1493 public:
1497 impersonator() noexcept : m_cookie(FALSE) {}
1498
1504 virtual ~impersonator()
1505 {
1506 if (m_cookie)
1507 RevertToSelf();
1508 }
1509
1513 operator bool () const { return m_cookie; }
1514
1515 protected:
1516 BOOL m_cookie;
1517 };
1518
1522 class user_impersonator : public impersonator
1523 {
1524 WINSTD_NONCOPYABLE(user_impersonator)
1525 WINSTD_NONMOVABLE(user_impersonator)
1526
1527 public:
1535 user_impersonator(_In_opt_ HANDLE hToken) noexcept
1536 {
1537 m_cookie = hToken && ImpersonateLoggedOnUser(hToken);
1538 }
1539 };
1540
1544 class system_impersonator : public impersonator
1545 {
1546 WINSTD_NONCOPYABLE(system_impersonator)
1547 WINSTD_NONMOVABLE(system_impersonator)
1548
1549 public:
1553 system_impersonator() noexcept
1554 {
1555 TOKEN_PRIVILEGES privileges = { 1, {{{ 0, 0 }, SE_PRIVILEGE_ENABLED }} };
1556 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid) ||
1557 !ImpersonateSelf(SecurityImpersonation))
1558 return;
1559
1560 {
1561 HANDLE h;
1562 if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &h))
1563 goto revert;
1564 win_handle<INVALID_HANDLE_VALUE> thread_token(h);
1565 if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL))
1566 goto revert;
1567 process_snapshot process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1568 if (!process_snapshot)
1569 goto revert;
1570 PROCESSENTRY32 entry = { sizeof(PROCESSENTRY32) };
1571 if (!Process32First(process_snapshot, &entry))
1572 goto revert;
1573 while (_tcsicmp(entry.szExeFile, TEXT("winlogon.exe")) != 0)
1574 if (!Process32Next(process_snapshot, &entry))
1575 goto revert;
1576 process winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID);
1577 if (!winlogon_process)
1578 goto revert;
1579 if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &h))
1580 goto revert;
1581 win_handle<INVALID_HANDLE_VALUE> winlogon_token(h);
1582 if (!DuplicateToken(winlogon_token, SecurityImpersonation, &h))
1583 goto revert;
1584 win_handle<INVALID_HANDLE_VALUE> duplicated_token(h);
1585 if (!SetThreadToken(NULL, duplicated_token))
1586 goto revert;
1587 }
1588
1589 m_cookie = TRUE;
1590 return;
1591
1592 revert:
1593 DWORD dwResult = GetLastError();
1594 RevertToSelf();
1595 SetLastError(dwResult);
1596 }
1597 };
1598
1602 class clipboard_opener
1603 {
1604 public:
1610 clipboard_opener(_In_opt_ HWND hWndNewOwner = NULL)
1611 {
1612 if (!OpenClipboard(hWndNewOwner))
1613 throw win_runtime_error("OpenClipboard failed");
1614 }
1615
1621 virtual ~clipboard_opener()
1622 {
1623 CloseClipboard();
1624 }
1625 };
1626
1630 class console_ctrl_handler
1631 {
1632 WINSTD_NONCOPYABLE(console_ctrl_handler)
1633 WINSTD_NONMOVABLE(console_ctrl_handler)
1634
1635 public:
1643 console_ctrl_handler(_In_opt_ PHANDLER_ROUTINE HandlerRoutine) noexcept : m_handler(HandlerRoutine)
1644 {
1645 m_cookie = SetConsoleCtrlHandler(m_handler, TRUE);
1646 }
1647
1653 virtual ~console_ctrl_handler()
1654 {
1655 if (m_cookie)
1656 SetConsoleCtrlHandler(m_handler, FALSE);
1657 }
1658
1659 protected:
1660 BOOL m_cookie;
1661 PHANDLER_ROUTINE m_handler;
1662 };
1663
1667 class vmemory : public handle<LPVOID, NULL>
1668 {
1669 WINSTD_NONCOPYABLE(vmemory)
1670
1671 public:
1675 vmemory() noexcept : m_proc(NULL)
1676 {}
1677
1684 vmemory(_In_ handle_type h, _In_ HANDLE proc) noexcept :
1685 m_proc(proc),
1686 handle<LPVOID, NULL>(h)
1687 {}
1688
1694 vmemory(_Inout_ vmemory &&h) noexcept :
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)
1707 VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
1708 }
1709
1715 vmemory& operator=(_Inout_ vmemory &&other) noexcept
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
1732 void attach(_In_ HANDLE proc, _In_opt_ handle_type h) noexcept
1733 {
1734 m_proc = proc;
1735 if (m_h != invalid)
1736 free_internal();
1737 m_h = h;
1738 }
1739
1749 bool alloc(
1750 _In_ HANDLE hProcess,
1751 _In_opt_ LPVOID lpAddress,
1752 _In_ SIZE_T dwSize,
1753 _In_ DWORD flAllocationType,
1754 _In_ DWORD flProtect) noexcept
1755 {
1756 handle_type h = VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect);
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 {
1772 VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
1773 }
1774
1775 protected:
1776 HANDLE m_proc;
1777 };
1778
1785 class reg_key : public handle<HKEY, NULL>
1786 {
1787 WINSTD_HANDLE_IMPL(reg_key, HKEY, NULL)
1788
1789 public:
1795 virtual ~reg_key()
1796 {
1797 if (m_h != invalid)
1798 free_internal();
1799 }
1800
1810 bool delete_subkey(_In_z_ LPCTSTR szSubkey)
1811 {
1812 LSTATUS s;
1813
1814 s = RegDeleteKey(m_h, szSubkey);
1815 if (s == ERROR_SUCCESS || s == ERROR_FILE_NOT_FOUND)
1816 return true;
1817
1818 {
1819 reg_key k;
1820 handle_type h;
1821 s = RegOpenKeyEx(m_h, szSubkey, 0, KEY_ENUMERATE_SUB_KEYS, &h);
1822 if (s == ERROR_SUCCESS)
1823 k.attach(h);
1824 else {
1825 SetLastError(s);
1826 return false;
1827 }
1828 for (;;) {
1829 TCHAR szName[MAX_PATH];
1830 DWORD dwSize = _countof(szName);
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
1843 s = RegDeleteKey(m_h, szSubkey);
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 {
1860 RegCloseKey(m_h);
1861 }
1862 };
1863
1867 class security_id : public handle<PSID, NULL>
1868 {
1869 WINSTD_HANDLE_IMPL(security_id, PSID, NULL)
1870
1871 public:
1877 virtual ~security_id()
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 {
1900 WINSTD_NONCOPYABLE(process_information)
1901 WINSTD_NONMOVABLE(process_information)
1902
1903 public:
1907 process_information() noexcept
1908 {
1909 hProcess = INVALID_HANDLE_VALUE;
1910 hThread = INVALID_HANDLE_VALUE;
1911 dwProcessId = 0;
1912 dwThreadId = 0;
1913 }
1914
1918 ~process_information()
1919 {
1920 #pragma warning(push)
1921 #pragma warning(disable: 6001) // Using uninitialized memory '*this'. << ???
1922
1923 if (hProcess != INVALID_HANDLE_VALUE)
1924 CloseHandle(hProcess);
1925
1926 if (hThread != INVALID_HANDLE_VALUE)
1927 CloseHandle(hThread);
1928
1929 #pragma warning(pop)
1930 }
1931 };
1932
1938 class event_log : public handle<HANDLE, NULL>
1939 {
1940 WINSTD_HANDLE_IMPL(event_log, HANDLE, NULL)
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 {
1962 DeregisterEventSource(m_h);
1963 }
1964 };
1965
1969 class sc_handle : public handle<SC_HANDLE, NULL>
1970 {
1971 WINSTD_HANDLE_IMPL(sc_handle, SC_HANDLE, NULL)
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 {
1993 CloseServiceHandle(m_h);
1994 }
1995 };
1996
1998}
1999
2002
2003#pragma warning(push)
2004#pragma warning(disable: 4505) // Don't warn on unused code
2005
2007 static 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
2030 static 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
2049 static 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
2068 static 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
2087 static 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
2102 static 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
2117 static 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
2128 static 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
2142 static 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
2156 template<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
winstd::actctx_activator
Activates given activation context in constructor and deactivates it in destructor.
Definition Win.h:1455
winstd::actctx_activator::actctx_activator
actctx_activator(HANDLE hActCtx) noexcept
Construct the activator and activates the given activation context.
Definition Win.h:1467
winstd::actctx_activator::~actctx_activator
virtual ~actctx_activator()
Deactivates activation context and destructs the activator.
Definition Win.h:1478
winstd::actctx_activator::m_cookie
ULONG_PTR m_cookie
Cookie for context deactivation.
Definition Win.h:1485
winstd::clipboard_opener
Clipboard management.
Definition Win.h:1603
winstd::clipboard_opener::~clipboard_opener
virtual ~clipboard_opener()
Closes the clipboard.
Definition Win.h:1621
winstd::clipboard_opener::clipboard_opener
clipboard_opener(HWND hWndNewOwner=NULL)
Opens the clipboard for examination and prevents other applications from modifying the clipboard cont...
Definition Win.h:1610
winstd::console_ctrl_handler
Console control handler stack management.
Definition Win.h:1631
winstd::console_ctrl_handler::console_ctrl_handler
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
winstd::console_ctrl_handler::~console_ctrl_handler
virtual ~console_ctrl_handler()
Pops console control handler from the console control handler stack.
Definition Win.h:1653
winstd::console_ctrl_handler::m_handler
PHANDLER_ROUTINE m_handler
Pointer to console control handler.
Definition Win.h:1661
winstd::console_ctrl_handler::m_cookie
BOOL m_cookie
Did pushing the console control handler succeed?
Definition Win.h:1660
winstd::critical_section
Critical section wrapper.
Definition Win.h:1186
winstd::critical_section::critical_section
critical_section() noexcept
Construct the object and initializes a critical section object.
Definition Win.h:1196
winstd::critical_section::m_data
CRITICAL_SECTION m_data
Critical section struct.
Definition Win.h:1222
winstd::critical_section::~critical_section
virtual ~critical_section()
Releases all resources used by an unowned critical section object.
Definition Win.h:1206
winstd::event_log
Event log handle wrapper.
Definition Win.h:1939
winstd::event_log::free_internal
void free_internal() noexcept override
Closes an event log handle.
Definition Win.h:1960
winstd::event_log::~event_log
virtual ~event_log()
Closes an event log handle.
Definition Win.h:1948
winstd::find_file
Find-file handle wrapper.
Definition Win.h:1231
winstd::find_file::~find_file
virtual ~find_file()
Closes a file search handle.
Definition Win.h:1240
winstd::find_file::free_internal
void free_internal() noexcept override
Closes a file search handle.
Definition Win.h:1252
winstd::handle
Base abstract template class to support generic object handle keeping.
Definition Common.h:1024
winstd::handle< HANDLE, INVALID >::m_h
handle_type m_h
Object handle.
Definition Common.h:1276
winstd::heap_allocator
HeapAlloc allocator.
Definition Win.h:1342
winstd::heap_allocator::size_type
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
winstd::heap_allocator::value_type
_Ty value_type
A type that is managed by the allocator.
Definition Win.h:1344
winstd::heap_allocator::heap_allocator
heap_allocator(const heap_allocator< _Other > &other)
Constructs allocator from another type.
Definition Win.h:1378
winstd::heap_allocator::m_heap
HANDLE m_heap
Heap handle.
Definition Win.h:1448
winstd::heap_allocator::allocate
pointer allocate(size_type count)
Allocates a new memory block.
Definition Win.h:1388
winstd::heap_allocator::difference_type
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
winstd::heap_allocator::heap_allocator
heap_allocator(HANDLE heap)
Constructs allocator.
Definition Win.h:1369
winstd::heap_allocator::reference
_Ty & reference
A type that provides a reference to the type of object managed by the allocator.
Definition Win.h:1347
winstd::heap_allocator::construct
void construct(pointer ptr, _Ty &&val)
Calls moving constructor for the element.
Definition Win.h:1424
winstd::heap_allocator::deallocate
void deallocate(pointer ptr, size_type size)
Frees memory block.
Definition Win.h:1400
winstd::heap_allocator::max_size
size_type max_size() const
Returns maximum memory block size.
Definition Win.h:1442
winstd::heap_allocator::construct
void construct(pointer ptr, const _Ty &val)
Calls copying constructor for the element.
Definition Win.h:1413
winstd::heap_allocator::const_reference
const _Ty & const_reference
A type that provides a constant reference to type of object managed by the allocator.
Definition Win.h:1349
winstd::heap_allocator::const_pointer
const _Ty * const_pointer
A type that provides a constant pointer to the type of object managed by the allocator.
Definition Win.h:1348
winstd::heap_allocator::pointer
_Ty * pointer
A type that provides a pointer to the type of object managed by the allocator.
Definition Win.h:1346
winstd::heap_allocator::destroy
void destroy(pointer ptr)
Calls destructor for the element.
Definition Win.h:1434
winstd::heap
Heap handle wrapper.
Definition Win.h:1264
winstd::heap::enumerate
bool enumerate() noexcept
Enumerates allocated heap blocks using OutputDebugString()
Definition Win.h:1286
winstd::heap::free_internal
void free_internal() noexcept override
Destroys the heap.
Definition Win.h:1330
winstd::heap::~heap
virtual ~heap()
Destroys the heap.
Definition Win.h:1273
winstd::impersonator
Base class for thread impersonation of another security context.
Definition Win.h:1492
winstd::impersonator::~impersonator
virtual ~impersonator()
Reverts to current user and destructs the impersonator.
Definition Win.h:1504
winstd::impersonator::impersonator
impersonator() noexcept
Construct the impersonator.
Definition Win.h:1497
winstd::impersonator::m_cookie
BOOL m_cookie
Did impersonation succeed?
Definition Win.h:1516
winstd::library
Module handle wrapper.
Definition Win.h:1045
winstd::library::free_internal
void free_internal() noexcept override
Frees the module.
Definition Win.h:1066
winstd::library::~library
virtual ~library()
Frees the module.
Definition Win.h:1054
winstd::mutex_locker
Locks given mutex in constructor and releases it in destructor.
Definition Win.h:1104
winstd::mutex_locker::~mutex_locker
virtual ~mutex_locker()
Releases ownership of the mutex object.
Definition Win.h:1135
winstd::mutex_locker::mutex_locker
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
winstd::process_information
PROCESS_INFORMATION struct wrapper.
Definition Win.h:1899
winstd::process_information::~process_information
~process_information()
Closes process and thread handles.
Definition Win.h:1918
winstd::process_information::process_information
process_information() noexcept
Constructs blank PROCESS_INFORMATION.
Definition Win.h:1907
winstd::ref_unique_ptr
Helper class for returning pointers to std::unique_ptr.
Definition Common.h:863
winstd::reg_key
Registry key wrapper class.
Definition Win.h:1786
winstd::reg_key::free_internal
void free_internal() noexcept override
Closes a handle to the registry key.
Definition Win.h:1858
winstd::reg_key::delete_subkey
bool delete_subkey(LPCTSTR szSubkey)
Deletes the specified registry subkey.
Definition Win.h:1810
winstd::reg_key::~reg_key
virtual ~reg_key()
Closes a handle to the registry key.
Definition Win.h:1795
winstd::sc_handle
SC_HANDLE wrapper class.
Definition Win.h:1970
winstd::sc_handle::free_internal
void free_internal() noexcept override
Closes an open object handle.
Definition Win.h:1991
winstd::sc_handle::~sc_handle
virtual ~sc_handle()
Closes an open object handle.
Definition Win.h:1979
winstd::security_id
SID wrapper class.
Definition Win.h:1868
winstd::security_id::free_internal
void free_internal() noexcept override
Closes a handle to the SID.
Definition Win.h:1889
winstd::security_id::~security_id
virtual ~security_id()
Closes a handle to the SID.
Definition Win.h:1877
winstd::system_impersonator
Lets the calling thread impersonate the security context of the SYSTEM user.
Definition Win.h:1545
winstd::system_impersonator::system_impersonator
system_impersonator() noexcept
Construct the impersonator and impersonates the SYSTEM user.
Definition Win.h:1553
winstd::user_impersonator
Lets the calling thread impersonate the security context of a logged-on user.
Definition Win.h:1523
winstd::user_impersonator::user_impersonator
user_impersonator(HANDLE hToken) noexcept
Construct the impersonator and impersonates the given user.
Definition Win.h:1535
winstd::vmemory
Memory in virtual address space of a process handle wrapper.
Definition Win.h:1668
winstd::vmemory::operator=
vmemory & operator=(vmemory &&other) noexcept
Move assignment.
Definition Win.h:1715
winstd::vmemory::alloc
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
winstd::vmemory::free_internal
void free_internal() noexcept override
Frees the memory.
Definition Win.h:1770
winstd::vmemory::attach
void attach(HANDLE proc, handle_type h) noexcept
Sets a new memory handle for the class.
Definition Win.h:1732
winstd::vmemory::~vmemory
virtual ~vmemory()
Frees the memory.
Definition Win.h:1704
winstd::vmemory::vmemory
vmemory(handle_type h, HANDLE proc) noexcept
Initializes a new class instance with an already available object handle.
Definition Win.h:1684
winstd::vmemory::vmemory
vmemory() noexcept
Initializes a new class instance with the memory handle set to INVAL.
Definition Win.h:1675
winstd::vmemory::vmemory
vmemory(vmemory &&h) noexcept
Move constructor.
Definition Win.h:1694
winstd::vmemory::m_proc
HANDLE m_proc
Handle of memory's process.
Definition Win.h:1776
winstd::win_handle
Windows HANDLE wrapper class.
Definition Win.h:1012
winstd::win_handle::free_internal
void free_internal() noexcept override
Closes an open object handle.
Definition Win.h:1033
winstd::win_handle::~win_handle
virtual ~win_handle()
Closes an open object handle.
Definition Win.h:1021
winstd::win_runtime_error
Windows runtime error.
Definition Common.h:1524
WINSTD_NONCOPYABLE
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition Common.h:67
WINSTD_STACK_BUFFER_BYTES
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition Common.h:94
WINSTD_NONMOVABLE
#define WINSTD_NONMOVABLE(C)
Declares a class as non-movable.
Definition Common.h:75
sprintf
static int sprintf(std::basic_string< _Elem, _Traits, _Ax > &str, const _Elem *format,...)
Formats string using printf().
Definition Common.h:333
vsprintf
static int vsprintf(std::basic_string< char, _Traits, _Ax > &str, const char *format, va_list arg)
Formats string using printf().
Definition Common.h:256
WINSTD_HANDLE_IMPL
#define WINSTD_HANDLE_IMPL(C, T, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition Common.h:164
winstd::handle< HANDLE, INVALID >::invalid
static const HANDLE invalid
Invalid handle value.
Definition Common.h:1034
NormalizeString
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
ExpandEnvironmentStringsW
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
StringToGuidA
static BOOL StringToGuidA(LPCSTR lpszGuid, LPGUID lpGuid, LPCSTR *lpszGuidEnd=NULL) noexcept
Parses string with GUID and stores it to GUID.
Definition Win.h:255
GetWindowTextA
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
RegCreateKeyExW
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
LoadStringA
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
winstd::file
win_handle< INVALID_HANDLE_VALUE > file
File handle wrapper.
Definition Win.h:1150
GetFileVersionInfoA
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
RegCreateKeyExA
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
RegOpenKeyExA
static LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2049
RegOpenKeyExW
static LSTATUS RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2068
GuidToStringA
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
StringToGuidW
static BOOL StringToGuidW(LPCWSTR lpszGuid, LPGUID lpGuid, LPCWSTR *lpszGuidEnd=NULL) noexcept
Parses string with GUID and stores it to GUID.
Definition Win.h:328
RegLoadMUIStringW
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
OpenProcessToken
static BOOL OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, winstd::win_handle< NULL > &TokenHandle)
Opens the access token associated with a process.
Definition Win.h:2087
SetEntriesInAclW
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
LookupAccountSidA
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
GetModuleFileNameW
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
LookupAccountSidW
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
AllocateAndInitializeSid
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
winstd::process_snapshot
win_handle< INVALID_HANDLE_VALUE > process_snapshot
Process snapshot handle wrapper.
Definition Win.h:1091
GetModuleFileNameA
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
GetDateFormatW
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
CreateWellKnownSid
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
LoadStringW
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
GetTokenInformation
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
DuplicateTokenEx
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
SetEntriesInAclA
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
RegQueryValueExW
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
GetFileVersionInfoW
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
winstd::event
win_handle< NULL > event
Event handle wrapper.
Definition Win.h:1180
RegLoadMUIStringA
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
OutputDebugStr
static VOID OutputDebugStr(LPCSTR lpOutputString,...) noexcept
Formats and sends a string to the debugger for display.
Definition Win.h:766
QueryFullProcessImageNameA
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
winstd::mutex
win_handle< NULL > mutex
Mutex handle wrapper.
Definition Win.h:1098
ExpandEnvironmentStringsA
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
winstd::file_mapping
win_handle< NULL > file_mapping
File mapping.
Definition Win.h:1157
QueryFullProcessImageNameW
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
winstd::process
win_handle< NULL > process
Process handle wrapper.
Definition Win.h:1077
RegQueryValueExA
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
GetThreadPreferredUILanguages
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
RegQueryStringValue
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
GetWindowTextW
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
GetDateFormatA
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
GuidToStringW
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
OutputDebugStrV
static VOID OutputDebugStrV(LPCSTR lpOutputString, va_list arg) noexcept
Formats and sends a string to the debugger for display.
Definition Win.h:742
winstd::thread
win_handle< NULL > thread
Thread handle wrapper.
Definition Win.h:1084
winstd::UnmapViewOfFile_delete
Deleter for unique_ptr using UnmapViewOfFile.
Definition Win.h:1163
winstd::UnmapViewOfFile_delete::operator()
void operator()(void *_Ptr) const
Delete a pointer.
Definition Win.h:1167
winstd::heap_allocator::rebind
A structure that enables an allocator for objects of one type to allocate storage for objects of anot...
Definition Win.h:1359
winstd::heap_allocator::rebind::other
heap_allocator< _Other > other
Other allocator type.
Definition Win.h:1360