# WinStd: include/WinStd/Win.h Source File

Loading...
Searching...
No Matches
Win.h
/*
SPDX-License-Identifier: MIT
Copyright © 1991-2024 Amebis
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <AclAPI.h>
#include <tlhelp32.h>
#include <winsvc.h>
#include <string>
#include <vector>
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
template<class _Traits, class _Ax>
static DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
{
assert(0); // TODO: Test this code.
char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
// Try with stack buffer first.
DWORD dwResult = ::GetModuleFileNameA(hModule, szStackBuffer, _countof(szStackBuffer));
if (dwResult < _countof(szStackBuffer)) {
// Copy from stack.
sValue.assign(szStackBuffer, dwResult);
return dwResult;
} else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(char);; dwCapacity *= 2) {
// Allocate on heap and retry.
sValue.resize(dwCapacity - 1);
dwResult = ::GetModuleFileNameA(hModule, &sValue[0], dwCapacity);
if (dwResult < dwCapacity) {
sValue.resize(dwResult);
return dwResult;
}
}
}
}
template<class _Traits, class _Ax>
static DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
{
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
// Try with stack buffer first.
DWORD dwResult = ::GetModuleFileNameW(hModule, szStackBuffer, _countof(szStackBuffer));
if (dwResult < _countof(szStackBuffer)) {
// Copy from stack.
sValue.assign(szStackBuffer, dwResult);
return dwResult;
} else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t);; dwCapacity *= 2) {
// Allocate on heap and retry.
sValue.resize(dwCapacity - 1);
dwResult = ::GetModuleFileNameW(hModule, &sValue[0], dwCapacity);
if (dwResult < dwCapacity) {
sValue.resize(dwResult);
return dwResult;
}
}
}
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
{
assert(0); // TODO: Test this code.
int iResult;
// Query the final string length first.
iResult = ::GetWindowTextLengthA(hWnd);
if (iResult > 0) {
// Allocate buffer on heap and read the string data into it.
sValue.resize(iResult++);
return ::GetWindowTextA(hWnd, &sValue[0], iResult);
}
sValue.clear();
return 0;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
{
assert(0); // TODO: Test this code.
int iResult;
// Query the final string length first.
iResult = ::GetWindowTextLengthW(hWnd);
if (iResult > 0) {
// Allocate buffer on heap and read the string data into it.
sValue.resize(iResult++);
return ::GetWindowTextW(hWnd, &sValue[0], iResult);
}
sValue.clear();
return 0;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL GetFileVersionInfoA(_In_z_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) noexcept
{
assert(0); // TODO: Test this code.
// Get version info size.
DWORD dwVerInfoSize = ::GetFileVersionInfoSizeA(lptstrFilename, &dwHandle);
if (dwVerInfoSize != 0) {
// Read version info.
aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return ::GetFileVersionInfoA(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
} else
return FALSE;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL GetFileVersionInfoW(_In_z_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) noexcept
{
assert(0); // TODO: Test this code.
// Get version info size.
DWORD dwVerInfoSize = ::GetFileVersionInfoSizeW(lptstrFilename, &dwHandle);
if (dwVerInfoSize != 0) {
// Read version info.
aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return ::GetFileVersionInfoW(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
} else
return FALSE;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSrc, _Out_ std::basic_string<char, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
for (SIZE_T sSizeOut = SIZETAdd(strlen(lpSrc), 0x100);;) {
if (sSizeOut > DWORD_MAX)
throw std::invalid_argument("String too big");
DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
sValue.resize((size_t)dwSizeIn + 1); // Note: ANSI version requires one extra char.
sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, &sValue[0], dwSizeIn);
if (sSizeOut == 0) {
// Error or zero-length input.
break;
} else if (sSizeOut <= dwSizeIn) {
// The buffer was sufficient.
sValue.resize(sSizeOut - 1);
return static_cast<DWORD>(sSizeOut);
}
}
sValue.clear();
return 0;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpSrc, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
for (SIZE_T sSizeOut = SIZETAdd(wcslen(lpSrc), 0x100);;) {
if (sSizeOut > DWORD_MAX)
throw std::invalid_argument("String too big");
DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
sValue.resize(dwSizeIn);
sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, &sValue[0], dwSizeIn);
if (sSizeOut == 0) {
// Error or zero-length input.
break;
} else if (sSizeOut <= dwSizeIn) {
// The buffer was sufficient.
sValue.resize(sSizeOut - 1);
return static_cast<DWORD>(sSizeOut);
}
}
sValue.clear();
return 0;
}
template<class _Traits, class _Ax>
static VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<char, _Traits, _Ax> &str) noexcept
{
assert(0); // TODO: Test this code.
sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
lpGuid->Data1,
lpGuid->Data2,
lpGuid->Data3,
lpGuid->Data4[0], lpGuid->Data4[1],
lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]);
}
template<class _Traits, class _Ax>
static VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &str) noexcept
{
assert(0); // TODO: Test this code.
sprintf(str, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
lpGuid->Data1,
lpGuid->Data2,
lpGuid->Data3,
lpGuid->Data4[0], lpGuid->Data4[1],
lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]);
}
#ifdef _UNICODE
#define GuidToString GuidToStringW
#else
#define GuidToString GuidToStringA
#endif
static _Success_(return) BOOL StringToGuidA(_In_z_ LPCSTR lpszGuid, _Out_ LPGUID lpGuid, _Out_opt_ LPCSTR *lpszGuidEnd = NULL) noexcept
{
GUID g;
LPSTR lpszEnd;
unsigned long ulTmp;
unsigned long long ullTmp;
if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE;
lpszGuid++;
g.Data1 = strtoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE) return FALSE;
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data2 = static_cast<unsigned short>(ulTmp);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data3 = static_cast<unsigned short>(ulTmp);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = strtoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data4[0] = static_cast<unsigned char>((ulTmp >> 8) & 0xff);
g.Data4[1] = static_cast<unsigned char>( ulTmp & 0xff);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ullTmp = _strtoui64(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE;
g.Data4[2] = static_cast<unsigned char>((ullTmp >> 40) & 0xff);
g.Data4[3] = static_cast<unsigned char>((ullTmp >> 32) & 0xff);
g.Data4[4] = static_cast<unsigned char>((ullTmp >> 24) & 0xff);
g.Data4[5] = static_cast<unsigned char>((ullTmp >> 16) & 0xff);
g.Data4[6] = static_cast<unsigned char>((ullTmp >> 8) & 0xff);
g.Data4[7] = static_cast<unsigned char>( ullTmp & 0xff);
lpszGuid = lpszEnd;
if (*lpszGuid != '}') return FALSE;
lpszGuid++;
if (lpszGuidEnd)
*lpszGuidEnd = lpszGuid;
*lpGuid = g;
return TRUE;
}
static _Success_(return) BOOL StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ LPGUID lpGuid, _Out_opt_ LPCWSTR *lpszGuidEnd = NULL) noexcept
{
GUID g;
LPWSTR lpszEnd;
unsigned long ulTmp;
unsigned long long ullTmp;
if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE;
lpszGuid++;
g.Data1 = wcstoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE) return FALSE;
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data2 = static_cast<unsigned short>(ulTmp);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data3 = static_cast<unsigned short>(ulTmp);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ulTmp = wcstoul(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE;
g.Data4[0] = static_cast<unsigned char>((ulTmp >> 8) & 0xff);
g.Data4[1] = static_cast<unsigned char>( ulTmp & 0xff);
lpszGuid = lpszEnd;
if (*lpszGuid != '-') return FALSE;
lpszGuid++;
ullTmp = _wcstoui64(lpszGuid, &lpszEnd, 16);
if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE;
g.Data4[2] = static_cast<unsigned char>((ullTmp >> 40) & 0xff);
g.Data4[3] = static_cast<unsigned char>((ullTmp >> 32) & 0xff);
g.Data4[4] = static_cast<unsigned char>((ullTmp >> 24) & 0xff);
g.Data4[5] = static_cast<unsigned char>((ullTmp >> 16) & 0xff);
g.Data4[6] = static_cast<unsigned char>((ullTmp >> 8) & 0xff);
g.Data4[7] = static_cast<unsigned char>( ullTmp & 0xff);
lpszGuid = lpszEnd;
if (*lpszGuid != '}') return FALSE;
lpszGuid++;
if (lpszGuidEnd)
*lpszGuidEnd = lpszGuid;
*lpGuid = g;
return TRUE;
}
#ifdef _UNICODE
#define StringToGuid StringToGuidW
#else
#define StringToGuid StringToGuidA
#endif
template<class _Traits, class _Ax>
static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<char, _Traits, _Ax> &sValue) noexcept
{
LSTATUS lResult;
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = sizeof(aStackBuffer), dwType;
// Try with stack buffer first.
lResult = ::RegQueryValueExA(hReg, pszName, NULL, &dwType, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ.
dwSize /= sizeof(CHAR);
sValue.assign(reinterpret_cast<LPCSTR>(aStackBuffer), dwSize && reinterpret_cast<LPCSTR>(aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
if (::ExpandEnvironmentStringsA(reinterpret_cast<LPCSTR>(aStackBuffer), sValue) == 0)
lResult = ::GetLastError();
} else {
// The value is not a string type.
lResult = ERROR_INVALID_DATA;
}
} else if (lResult == ERROR_MORE_DATA) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
sValue.resize(dwSize / sizeof(CHAR));
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(CHAR);
sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
}
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR) + 1]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(CHAR);
szBuffer[dwSize] = 0;
if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError();
}
} else {
// The value is not a string type.
lResult = ERROR_INVALID_DATA;
}
}
return lResult;
}
template<class _Traits, class _Ax>
static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue) noexcept
{
LSTATUS lResult;
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = sizeof(aStackBuffer), dwType;
// Try with stack buffer first.
lResult = ::RegQueryValueExW(hReg, pszName, NULL, &dwType, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ.
dwSize /= sizeof(WCHAR);
sValue.assign(reinterpret_cast<LPCWSTR>(aStackBuffer), dwSize && reinterpret_cast<LPCWSTR>(aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
if (::ExpandEnvironmentStringsW(reinterpret_cast<LPCWSTR>(aStackBuffer), sValue) == 0)
lResult = ::GetLastError();
} else {
// The value is not a string type.
lResult = ERROR_INVALID_DATA;
}
} else if (lResult == ERROR_MORE_DATA) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
sValue.resize(dwSize / sizeof(WCHAR));
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(WCHAR);
sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
}
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR) + 1]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(WCHAR);
szBuffer[dwSize] = 0;
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError();
}
} else {
// The value is not a string type.
lResult = ERROR_INVALID_DATA;
}
}
return lResult;
}
template<class _Ty, class _Ax>
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
{
LSTATUS lResult;
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = sizeof(aStackBuffer);
// Try with stack buffer first.
lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
// Copy from stack buffer.
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
memcpy(aData.data(), aStackBuffer, dwSize);
} else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, NULL, reinterpret_cast<LPBYTE>(aData.data()), &dwSize);
}
return lResult;
}
template<class _Ty, class _Ax>
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
{
LSTATUS lResult;
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = sizeof(aStackBuffer);
// Try with stack buffer first.
lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
// Copy from stack buffer.
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
memcpy(aData.data(), aStackBuffer, dwSize);
} else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, NULL, reinterpret_cast<LPBYTE>(aData.data()), &dwSize);
}
return lResult;
}
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
template<class _Traits, class _Ax>
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
{
// According to "Remarks" section in MSDN documentation of RegLoadMUIString(),
// this function is defined but not implemented as ANSI variation.
assert(0);
return ERROR_CALL_NOT_IMPLEMENTED;
}
template<class _Traits, class _Ax>
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
{
LSTATUS lResult;
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
DWORD dwSize;
Flags &= ~REG_MUI_STRING_TRUNCATE;
// Try with stack buffer first.
lResult = RegLoadMUIStringW(hKey, pszValue, szStackBuffer, sizeof(szStackBuffer), &dwSize, Flags, pszDirectory);
if (lResult == ERROR_SUCCESS) {
// Copy from stack buffer.
sOut.assign(szStackBuffer, wcsnlen(szStackBuffer, dwSize/sizeof(wchar_t)));
} else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
sOut.resize((dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t) - 1);
sOut.resize((lResult = RegLoadMUIStringW(hKey, pszValue, &sOut[0], dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? wcsnlen(&sOut[0], dwSize/sizeof(wchar_t)) : 0);
}
return lResult;
}
#endif
template<class _Traits, class _Ax>
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
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, szStackBuffer, _countof(szStackBuffer));
if (cch > 0) {
// Copy from stack.
sDstString.assign(szStackBuffer, cwSrcLength != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1);
} else {
switch (::GetLastError()) {
case ERROR_INSUFFICIENT_BUFFER:
for (int i = 10; i--;) {
// Allocate buffer. Then convert again.
cch = -cch;
sDstString.resize((size_t)cch - 1);
cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, &sDstString[0], cch);
if (cch > 0) {
sDstString.resize(cwSrcLength != -1 ? wcsnlen(&sDstString[0], cch) : (size_t)cch - 1);
break;
}
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
sDstString.clear();
break;
}
}
break;
case ERROR_SUCCESS:
sDstString.clear();
break;
}
}
return cch;
}
template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
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
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), szStackBuffer, _countof(szStackBuffer));
if (cch > 0) {
// Copy from stack.
sDstString.assign(szStackBuffer, cch);
} else {
switch (::GetLastError()) {
case ERROR_INSUFFICIENT_BUFFER:
for (int i = 10; i--;) {
// Allocate buffer. Then convert again.
cch = -cch;
sDstString.resize(cch);
cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), &sDstString[0], cch);
if (cch > 0)
break;
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
sDstString.clear();
break;
}
}
break;
case ERROR_SUCCESS:
sDstString.clear();
break;
}
}
return cch;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string<char, _Traits, _Ax> &sBuffer) noexcept
{
// Get read-only pointer to string resource.
LPCSTR pszStr;
int i = LoadStringA(hInstance, uID, reinterpret_cast<LPSTR>(&pszStr), 0);
if (i) {
sBuffer.assign(pszStr, i);
return i;
} else
return 0;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sBuffer) noexcept
{
// Get read-only pointer to string resource.
LPCWSTR pszStr;
int i = LoadStringW(hInstance, uID, reinterpret_cast<LPWSTR>(&pszStr), 0);
if (i) {
sBuffer.assign(pszStr, i);
return i;
} else
return 0;
}
static VOID OutputDebugStrV(_In_z_ LPCSTR lpOutputString, _In_ va_list arg) noexcept
{
std::string str;
try { vsprintf(str, lpOutputString, arg); } catch (...) { return; }
OutputDebugStringA(str.c_str());
}
static VOID OutputDebugStrV(_In_z_ LPCWSTR lpOutputString, _In_ va_list arg) noexcept
{
std::wstring str;
try { vsprintf(str, lpOutputString, arg); } catch (...) { return; }
OutputDebugStringW(str.c_str());
}
static VOID OutputDebugStr(_In_z_ LPCSTR lpOutputString, ...) noexcept
{
va_list arg;
va_start(arg, lpOutputString);
OutputDebugStrV(lpOutputString, arg);
va_end(arg);
}
static VOID OutputDebugStr(_In_z_ LPCWSTR lpOutputString, ...) noexcept
{
va_list arg;
va_start(arg, lpOutputString);
OutputDebugStrV(lpOutputString, arg);
va_end(arg);
}
template<class _Traits, class _Ax>
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
{
int iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
if (iResult) {
// Allocate buffer on heap and retry.
sDate.resize(iResult - 1);
return GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
}
return iResult;
}
template<class _Traits, class _Ax>
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
{
int iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
if (iResult) {
// Allocate buffer on heap and retry.
sDate.resize(iResult - 1);
return GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
}
return iResult;
}
template<class _Traits, class _Ax>
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
{
assert(0); // TODO: Test this code.
DWORD dwNameLen = 0, dwRefDomainLen = 0;
if (LookupAccountSidA(lpSystemName, lpSid,
NULL, &dwNameLen ,
NULL, &dwRefDomainLen,
peUse))
{
// Name and domain is blank.
if (sName ) sName ->clear();
if (sReferencedDomainName) sReferencedDomainName->clear();
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
// Allocate on heap and retry.
std::unique_ptr<char[]> bufName (new char[dwNameLen ]);
std::unique_ptr<char[]> bufRefDomain(new char[dwRefDomainLen]);
if (LookupAccountSidA(lpSystemName, lpSid,
bufName .get(), &dwNameLen ,
bufRefDomain.get(), &dwRefDomainLen,
peUse))
{
if (sName ) sName ->assign(bufName .get(), dwNameLen - 1);
if (sReferencedDomainName) sReferencedDomainName->assign(bufRefDomain.get(), dwRefDomainLen - 1);
return TRUE;
}
}
return FALSE;
}
template<class _Traits, class _Ax>
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
{
assert(0); // TODO: Test this code.
DWORD dwNameLen = 0, dwRefDomainLen = 0;
if (LookupAccountSidW(lpSystemName, lpSid,
NULL, &dwNameLen ,
NULL, &dwRefDomainLen,
peUse))
{
// Name and domain is blank.
if (sName ) sName ->clear();
if (sReferencedDomainName) sReferencedDomainName->clear();
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
// Allocate on heap and retry.
std::unique_ptr<wchar_t[]> bufName (new wchar_t[dwNameLen ]);
std::unique_ptr<wchar_t[]> bufRefDomain(new wchar_t[dwRefDomainLen]);
if (LookupAccountSidW(lpSystemName, lpSid,
bufName .get(), &dwNameLen ,
bufRefDomain.get(), &dwRefDomainLen,
peUse))
{
if (sName ) sName ->assign(bufName .get(), dwNameLen - 1);
if (sReferencedDomainName) sReferencedDomainName->assign(bufRefDomain.get(), dwRefDomainLen - 1);
return TRUE;
}
}
return FALSE;
}
static _Success_(return != FALSE) BOOL CreateWellKnownSid(_In_ WELL_KNOWN_SID_TYPE WellKnownSidType, _In_opt_ PSID DomainSid, _Inout_ std::unique_ptr<SID> &Sid)
{
BYTE szStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = sizeof(szStackBuffer);
if (CreateWellKnownSid(WellKnownSidType, DomainSid, szStackBuffer, &dwSize)) {
// The stack buffer was big enough to retrieve complete data. Alloc and copy.
Sid.reset((SID*)new BYTE[dwSize]);
memcpy(Sid.get(), szStackBuffer, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// The stack buffer was too small to retrieve complete data. Alloc and retry.
Sid.reset((SID*)new BYTE[dwSize]);
return CreateWellKnownSid(WellKnownSidType, DomainSid, Sid.get(), &dwSize);
} else
return FALSE;
}
template<class _Ty>
static _Success_(return != 0) BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_ std::unique_ptr<_Ty> &TokenInformation) noexcept
{
BYTE szStackBuffer[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize;
if (GetTokenInformation(TokenHandle, TokenInformationClass, szStackBuffer, sizeof(szStackBuffer), &dwSize)) {
// The stack buffer was big enough to retrieve complete data. Alloc and copy.
TokenInformation.reset((_Ty*)(new BYTE[dwSize]));
memcpy(TokenInformation.get(), szStackBuffer, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// The stack buffer was too small to retrieve complete data. Alloc and retry.
TokenInformation.reset((_Ty*)(new BYTE[dwSize]));
return GetTokenInformation(TokenHandle, TokenInformationClass, TokenInformation.get(), dwSize, &dwSize);
} else
return FALSE;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) BOOL QueryFullProcessImageNameA(_In_ HANDLE hProcess, _In_ DWORD dwFlags, _Inout_ std::basic_string<char, _Traits, _Ax>& sExeName)
{
char szStackBuffer[WINSTD_STACK_BUFFER_BYTES / sizeof(char)];
DWORD dwSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::QueryFullProcessImageNameA(hProcess, dwFlags, szStackBuffer, &dwSize)) {
// Copy from stack.
sExeName.assign(szStackBuffer, dwSize);
return TRUE;
}
for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(char); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
// Allocate on heap and retry.
sExeName.resize(dwCapacity - 1);
dwSize = dwCapacity;
if (::QueryFullProcessImageNameA(hProcess, dwFlags, &sExeName[0], &dwSize)) {
sExeName.resize(dwSize);
return TRUE;
}
}
return FALSE;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) BOOL QueryFullProcessImageNameW(_In_ HANDLE hProcess, _In_ DWORD dwFlags, _Inout_ std::basic_string<wchar_t, _Traits, _Ax>& sExeName)
{
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES / sizeof(wchar_t)];
DWORD dwSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::QueryFullProcessImageNameW(hProcess, dwFlags, szStackBuffer, &dwSize)) {
// Copy from stack.
sExeName.assign(szStackBuffer, dwSize);
return TRUE;
}
for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(wchar_t); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
// Allocate on heap and retry.
sExeName.resize(dwCapacity - 1);
dwSize = dwCapacity;
if (::QueryFullProcessImageNameW(hProcess, dwFlags, &sExeName[0], &dwSize)) {
sExeName.resize(dwSize);
return TRUE;
}
}
return FALSE;
}
#pragma warning(pop)
namespace winstd
{
template<HANDLE INVALID>
class win_handle : public handle<HANDLE, INVALID>
{
WINSTD_HANDLE_IMPL(win_handle, HANDLE, INVALID)
public:
virtual ~win_handle()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
CloseHandle(m_h);
}
};
class library : public handle<HMODULE, NULL>
{
WINSTD_HANDLE_IMPL(library, HMODULE, NULL)
public:
virtual ~library()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
FreeLibrary(m_h);
}
};
typedef win_handle<NULL> process;
typedef win_handle<NULL> thread;
typedef win_handle<INVALID_HANDLE_VALUE> process_snapshot;
typedef win_handle<NULL> mutex;
class mutex_locker
{
WINSTD_NONCOPYABLE(mutex_locker)
WINSTD_NONMOVABLE(mutex_locker)
public:
mutex_locker(_In_ HANDLE hMutex, _In_ DWORD dwMilliseconds = INFINITE) : m_h(hMutex)
{
switch (WaitForSingleObject(m_h, dwMilliseconds)) {
case WAIT_OBJECT_0:
case WAIT_ABANDONED:
return;
case WAIT_TIMEOUT:
throw std::runtime_error("timeout");
case WAIT_FAILED:
throw win_runtime_error("WaitForSingleObject failed");
}
}
virtual ~mutex_locker()
{
ReleaseMutex(m_h);
}
protected:
HANDLE m_h;
};
typedef win_handle<INVALID_HANDLE_VALUE> file;
typedef win_handle<NULL> file_mapping;
struct UnmapViewOfFile_delete
{
void operator()(void* _Ptr) const
{
if (!UnmapViewOfFile(_Ptr))
throw win_runtime_error("UnmapViewOfFile failed");
}
};
typedef win_handle<NULL> event;
class critical_section
{
WINSTD_NONCOPYABLE(critical_section)
WINSTD_NONMOVABLE(critical_section)
public:
critical_section() noexcept
{
InitializeCriticalSection(&m_data);
}
virtual ~critical_section()
{
DeleteCriticalSection(&m_data);
}
operator LPCRITICAL_SECTION() noexcept
{
return &m_data;
}
protected:
CRITICAL_SECTION m_data;
};
class find_file : public handle<HANDLE, INVALID_HANDLE_VALUE>
{
WINSTD_HANDLE_IMPL(find_file, HANDLE, INVALID_HANDLE_VALUE)
public:
virtual ~find_file()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
FindClose(m_h);
}
};
class heap : public handle<HANDLE, NULL>
{
WINSTD_HANDLE_IMPL(heap, HANDLE, NULL)
public:
virtual ~heap()
{
if (m_h != invalid)
free_internal();
}
bool enumerate() noexcept
{
assert(m_h != invalid);
bool found = false;
// Lock the heap for exclusive access.
HeapLock(m_h);
PROCESS_HEAP_ENTRY e;
e.lpData = NULL;
while (HeapWalk(m_h, &e) != FALSE) {
if ((e.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
OutputDebugStr(
_T("Allocated block%s%s\n")
_T(" Data portion begins at: %#p\n Size: %d bytes\n")
_T(" Overhead: %d bytes\n Region index: %d\n"),
(e.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0 ? tstring_printf(_T(", movable with HANDLE %#p"), e.Block.hMem).c_str() : _T(""),
(e.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0 ? _T(", DDESHARE") : _T(""),
e.lpData,
e.cbData,
e.cbOverhead,
e.iRegionIndex);
found = true;
}
}
const DWORD dwResult = GetLastError();
if (dwResult != ERROR_NO_MORE_ITEMS)
OutputDebugStr(_T("HeapWalk failed (error %u).\n"), dwResult);
// Unlock the heap.
HeapUnlock(m_h);
return found;
}
protected:
void free_internal() noexcept override
{
enumerate();
HeapDestroy(m_h);
}
};
template <class _Ty>
class heap_allocator
{
public:
typedef typename _Ty value_type;
typedef _Ty *pointer;
typedef _Ty& reference;
typedef const _Ty *const_pointer;
typedef const _Ty& const_reference;
typedef SIZE_T size_type;
typedef ptrdiff_t difference_type;
template <class _Other>
struct rebind
{
typedef heap_allocator<_Other> other;
};
public:
heap_allocator(_In_ HANDLE heap) : m_heap(heap)
{}
template <class _Other>
heap_allocator(_In_ const heap_allocator<_Other> &other) : m_heap(other.m_heap)
{}
pointer allocate(_In_ size_type count)
{
assert(m_heap);
return (pointer)HeapAlloc(m_heap, 0, count * sizeof(_Ty));
}
void deallocate(_In_ pointer ptr, _In_ size_type size)
{
UNREFERENCED_PARAMETER(size);
assert(m_heap);
HeapFree(m_heap, 0, ptr);
}
void construct(_Inout_ pointer ptr, _In_ const _Ty& val)
{
::new ((void*)ptr) _Ty(val);
}
void construct(_Inout_ pointer ptr, _Inout_ _Ty&& val)
{
::new ((void*)ptr) _Ty(std::forward<_Ty>(val));
}
void destroy(_Inout_ pointer ptr)
{
ptr->_Ty::~_Ty();
}
size_type max_size() const
{
return (SIZE_T)-1;
}
public:
HANDLE m_heap;
};
class actctx_activator
{
WINSTD_NONCOPYABLE(actctx_activator)
WINSTD_NONMOVABLE(actctx_activator)
public:
actctx_activator(_In_ HANDLE hActCtx) noexcept
{
if (!ActivateActCtx(hActCtx, &m_cookie))
m_cookie = 0;
}
virtual ~actctx_activator()
{
if (m_cookie)
DeactivateActCtx(0, m_cookie);
}
protected:
ULONG_PTR m_cookie;
};
class impersonator
{
public:
impersonator() noexcept : m_cookie(FALSE) {}
virtual ~impersonator()
{
if (m_cookie)
RevertToSelf();
}
operator bool () const { return m_cookie; }
protected:
BOOL m_cookie;
};
class user_impersonator : public impersonator
{
WINSTD_NONCOPYABLE(user_impersonator)
WINSTD_NONMOVABLE(user_impersonator)
public:
user_impersonator(_In_opt_ HANDLE hToken) noexcept
{
m_cookie = hToken && ImpersonateLoggedOnUser(hToken);
}
};
class system_impersonator : public impersonator
{
WINSTD_NONCOPYABLE(system_impersonator)
WINSTD_NONMOVABLE(system_impersonator)
public:
system_impersonator() noexcept
{
TOKEN_PRIVILEGES privileges = { 1, {{{ 0, 0 }, SE_PRIVILEGE_ENABLED }} };
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid) ||
!ImpersonateSelf(SecurityImpersonation))
return;
{
HANDLE h;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &h))
goto revert;
win_handle<INVALID_HANDLE_VALUE> thread_token(h);
if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL))
goto revert;
process_snapshot process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!process_snapshot)
goto revert;
PROCESSENTRY32 entry = { sizeof(PROCESSENTRY32) };
if (!Process32First(process_snapshot, &entry))
goto revert;
while (_tcsicmp(entry.szExeFile, TEXT("winlogon.exe")) != 0)
if (!Process32Next(process_snapshot, &entry))
goto revert;
process winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID);
if (!winlogon_process)
goto revert;
if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &h))
goto revert;
win_handle<INVALID_HANDLE_VALUE> winlogon_token(h);
if (!DuplicateToken(winlogon_token, SecurityImpersonation, &h))
goto revert;
win_handle<INVALID_HANDLE_VALUE> duplicated_token(h);
if (!SetThreadToken(NULL, duplicated_token))
goto revert;
}
m_cookie = TRUE;
return;
revert:
last_error_saver last_error_save;
RevertToSelf();
}
};
class clipboard_opener
{
public:
clipboard_opener(_In_opt_ HWND hWndNewOwner = NULL)
{
if (!OpenClipboard(hWndNewOwner))
throw win_runtime_error("OpenClipboard failed");
}
virtual ~clipboard_opener()
{
CloseClipboard();
}
};
class console_ctrl_handler
{
WINSTD_NONCOPYABLE(console_ctrl_handler)
WINSTD_NONMOVABLE(console_ctrl_handler)
public:
console_ctrl_handler(_In_opt_ PHANDLER_ROUTINE HandlerRoutine) noexcept : m_handler(HandlerRoutine)
{
m_cookie = SetConsoleCtrlHandler(m_handler, TRUE);
}
virtual ~console_ctrl_handler()
{
if (m_cookie)
SetConsoleCtrlHandler(m_handler, FALSE);
}
protected:
BOOL m_cookie;
PHANDLER_ROUTINE m_handler;
};
class vmemory : public handle<LPVOID, NULL>
{
WINSTD_NONCOPYABLE(vmemory)
public:
vmemory() noexcept : m_proc(NULL)
{}
vmemory(_In_ handle_type h, _In_ HANDLE proc) noexcept :
m_proc(proc),
handle<LPVOID, NULL>(h)
{}
vmemory(_Inout_ vmemory &&h) noexcept :
m_proc(std::move(h.m_proc)),
handle<LPVOID, NULL>(std::move(h))
{}
virtual ~vmemory()
{
if (m_h != invalid)
VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
}
vmemory& operator=(_Inout_ vmemory &&other) noexcept
{
if (this != std::addressof(other)) {
(handle<handle_type, NULL>&&)*this = std::move(other);
m_proc = std::move(other.m_proc);
}
return *this;
}
void attach(_In_ HANDLE proc, _In_opt_ handle_type h) noexcept
{
m_proc = proc;
if (m_h != invalid)
free_internal();
m_h = h;
}
bool alloc(
_In_ HANDLE hProcess,
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect) noexcept
{
handle_type h = VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect);
if (h != invalid) {
attach(hProcess, h);
return true;
} else
return false;
}
protected:
void free_internal() noexcept override
{
VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
}
protected:
HANDLE m_proc;
};
class reg_key : public handle<HKEY, NULL>
{
WINSTD_HANDLE_IMPL(reg_key, HKEY, NULL)
public:
virtual ~reg_key()
{
if (m_h != invalid)
free_internal();
}
bool delete_subkey(_In_z_ LPCTSTR szSubkey)
{
LSTATUS s;
s = RegDeleteKey(m_h, szSubkey);
if (s == ERROR_SUCCESS || s == ERROR_FILE_NOT_FOUND)
return true;
{
reg_key k;
handle_type h;
s = RegOpenKeyEx(m_h, szSubkey, 0, KEY_ENUMERATE_SUB_KEYS, &h);
if (s == ERROR_SUCCESS)
k.attach(h);
else {
SetLastError(s);
return false;
}
for (;;) {
TCHAR szName[MAX_PATH];
DWORD dwSize = _countof(szName);
s = RegEnumKeyEx(k, 0, szName, &dwSize, NULL, NULL, NULL, NULL);
if (s == ERROR_SUCCESS)
k.delete_subkey(szName);
else if (s == ERROR_NO_MORE_ITEMS)
break;
else {
SetLastError(s);
return false;
}
}
}
s = RegDeleteKey(m_h, szSubkey);
if (s == ERROR_SUCCESS)
return true;
else {
SetLastError(s);
return false;
}
}
protected:
void free_internal() noexcept override
{
RegCloseKey(m_h);
}
};
class security_id : public handle<PSID, NULL>
{
WINSTD_HANDLE_IMPL(security_id, PSID, NULL)
public:
virtual ~security_id()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
FreeSid(m_h);
}
};
class process_information : public PROCESS_INFORMATION
{
WINSTD_NONCOPYABLE(process_information)
WINSTD_NONMOVABLE(process_information)
public:
process_information() noexcept
{
hProcess = INVALID_HANDLE_VALUE;
hThread = INVALID_HANDLE_VALUE;
dwProcessId = 0;
dwThreadId = 0;
}
~process_information()
{
#pragma warning(push)
#pragma warning(disable: 6001) // Using uninitialized memory '*this'. << ???
if (hProcess != INVALID_HANDLE_VALUE)
CloseHandle(hProcess);
if (hThread != INVALID_HANDLE_VALUE)
CloseHandle(hThread);
#pragma warning(pop)
}
};
class event_log : public handle<HANDLE, NULL>
{
WINSTD_HANDLE_IMPL(event_log, HANDLE, NULL)
public:
virtual ~event_log()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
DeregisterEventSource(m_h);
}
};
class sc_handle : public handle<SC_HANDLE, NULL>
{
WINSTD_HANDLE_IMPL(sc_handle, SC_HANDLE, NULL)
public:
virtual ~sc_handle()
{
if (m_h != invalid)
free_internal();
}
protected:
void free_internal() noexcept override
{
CloseServiceHandle(m_h);
}
};
}
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
static LSTATUS RegCreateKeyExA(
_In_ HKEY hKey,
_In_ LPCSTR lpSubKey,
_Reserved_ DWORD Reserved,
_In_opt_ LPSTR lpClass,
_In_ DWORD dwOptions,
_In_ REGSAM samDesired,
_In_opt_ CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_Inout_ winstd::reg_key &result,
_Out_opt_ LPDWORD lpdwDisposition)
{
HKEY h;
LSTATUS s = RegCreateKeyExA(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
if (s == ERROR_SUCCESS)
result.attach(h);
return s;
}
static LSTATUS RegCreateKeyExW(
_In_ HKEY hKey,
_In_ LPCWSTR lpSubKey,
_Reserved_ DWORD Reserved,
_In_opt_ LPWSTR lpClass,
_In_ DWORD dwOptions,
_In_ REGSAM samDesired,
_In_opt_ CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_Inout_ winstd::reg_key &result,
_Out_opt_ LPDWORD lpdwDisposition)
{
HKEY h;
LSTATUS s = RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
if (s == ERROR_SUCCESS)
result.attach(h);
return s;
}
static LSTATUS RegOpenKeyExA(
_In_ HKEY hKey,
_In_opt_ LPCSTR lpSubKey,
_In_opt_ DWORD ulOptions,
_In_ REGSAM samDesired,
_Inout_ winstd::reg_key &result)
{
HKEY h;
LSTATUS s = RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, &h);
if (s == ERROR_SUCCESS)
result.attach(h);
return s;
}
static LSTATUS RegOpenKeyExW(
_In_ HKEY hKey,
_In_opt_ LPCWSTR lpSubKey,
_In_opt_ DWORD ulOptions,
_In_ REGSAM samDesired,
_Inout_ winstd::reg_key &result)
{
HKEY h;
LSTATUS s = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, &h);
if (s == ERROR_SUCCESS)
result.attach(h);
return s;
}
static BOOL OpenProcessToken(_In_ HANDLE ProcessHandle, _In_ DWORD DesiredAccess, _Inout_ winstd::win_handle<NULL> &TokenHandle)
{
HANDLE h;
if (OpenProcessToken(ProcessHandle, DesiredAccess, &h)) {
TokenHandle.attach(h);
return TRUE;
}
return FALSE;
}
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)
{
HANDLE h;
if (DuplicateTokenEx(hExistingToken, dwDesiredAccess, lpTokenAttributes, ImpersonationLevel, TokenType, &h)) {
NewToken.attach(h);
return TRUE;
}
return FALSE;
}
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)
{
PSID h;
if (AllocateAndInitializeSid(pIdentifierAuthority, nSubAuthorityCount, nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3, nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, &h)) {
Sid.attach(h);
return TRUE;
}
return FALSE;
}
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)
{
PACL h;
DWORD dwResult = SetEntriesInAclA(cCountOfExplicitEntries, pListOfExplicitEntries, OldAcl, &h);
if (dwResult == ERROR_SUCCESS)
Acl.reset(h);
return ERROR_SUCCESS;
}
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)
{
PACL h;
DWORD dwResult = SetEntriesInAclW(cCountOfExplicitEntries, pListOfExplicitEntries, OldAcl, &h);
if (dwResult == ERROR_SUCCESS)
Acl.reset(h);
return ERROR_SUCCESS;
}
template<class _Traits, class _Ax>
_Success_(return != 0) BOOL GetThreadPreferredUILanguages(_In_ DWORD dwFlags, _Out_ PULONG pulNumLanguages, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, szStackBuffer, &ulSize)) {
// Copy from stack.
sValue.assign(szStackBuffer, ulSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query required size.
ulSize = 0;
GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, NULL, &ulSize);
// Allocate on heap and retry.
sValue.resize(ulSize - 1);
if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, &sValue[0], &ulSize))
return TRUE;
}
return FALSE;
}
#pragma warning(pop)
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::basic_string_printf
Base template class to support string formatting using printf() style templates.
Definition Common.h:1485
winstd::clipboard_opener
Clipboard management.
Definition Win.h:1602
winstd::clipboard_opener::~clipboard_opener
virtual ~clipboard_opener()
Closes the clipboard.
Definition Win.h:1620
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:1609
winstd::console_ctrl_handler
Console control handler stack management.
Definition Win.h:1630
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:1642
winstd::console_ctrl_handler::~console_ctrl_handler
virtual ~console_ctrl_handler()
Pops console control handler from the console control handler stack.
Definition Win.h:1652
winstd::console_ctrl_handler::m_handler
PHANDLER_ROUTINE m_handler
Pointer to console control handler.
Definition Win.h:1660
winstd::console_ctrl_handler::m_cookie
BOOL m_cookie
Did pushing the console control handler succeed?
Definition Win.h:1659
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:1938
winstd::event_log::free_internal
void free_internal() noexcept override
Closes an event log handle.
Definition Win.h:1959
winstd::event_log::~event_log
virtual ~event_log()
Closes an event log handle.
Definition Win.h:1947
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:874
winstd::handle< HANDLE, INVALID >::m_h
handle_type m_h
Definition Common.h:1126
winstd::handle::attach
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition Common.h:1089
winstd::handle< LPVOID, NULL >::handle_type
LPVOID handle_type
Definition Common.h:879
winstd::heap_allocator
HeapAlloc allocator.
Definition Win.h:1342
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::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::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::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::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::heap_allocator
heap_allocator(HANDLE heap)
Constructs allocator.
Definition Win.h:1369
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::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::destroy
void destroy(pointer ptr)
Calls destructor for the element.
Definition Win.h:1434
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
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::last_error_saver
Saves GetLastError and restores SetLastError when going out of scope.
Definition Common.h:1374
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:1898
winstd::process_information::~process_information
~process_information()
Closes process and thread handles.
Definition Win.h:1917
winstd::process_information::process_information
process_information() noexcept
Constructs blank PROCESS_INFORMATION.
Definition Win.h:1906
winstd::reg_key
Registry key wrapper class.
Definition Win.h:1785
winstd::reg_key::free_internal
void free_internal() noexcept override
Closes a handle to the registry key.
Definition Win.h:1857
winstd::reg_key::delete_subkey
bool delete_subkey(LPCTSTR szSubkey)
Deletes the specified registry subkey.
Definition Win.h:1809
winstd::reg_key::~reg_key
virtual ~reg_key()
Closes a handle to the registry key.
Definition Win.h:1794
winstd::sc_handle
SC_HANDLE wrapper class.
Definition Win.h:1969
winstd::sc_handle::free_internal
void free_internal() noexcept override
Closes an open object handle.
Definition Win.h:1990
winstd::sc_handle::~sc_handle
virtual ~sc_handle()
Closes an open object handle.
Definition Win.h:1978
winstd::security_id
SID wrapper class.
Definition Win.h:1867
winstd::security_id::free_internal
void free_internal() noexcept override
Closes a handle to the SID.
Definition Win.h:1888
winstd::security_id::~security_id
virtual ~security_id()
Closes a handle to the SID.
Definition Win.h:1876
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:1667
winstd::vmemory::operator=
vmemory & operator=(vmemory &&other) noexcept
Move assignment.
Definition Win.h:1714
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:1748
winstd::vmemory::free_internal
void free_internal() noexcept override
Frees the memory.
Definition Win.h:1769
winstd::vmemory::attach
void attach(HANDLE proc, handle_type h) noexcept
Sets a new memory handle for the class.
Definition Win.h:1731
winstd::vmemory::~vmemory
virtual ~vmemory()
Frees the memory.
Definition Win.h:1703
winstd::vmemory::vmemory
vmemory(handle_type h, HANDLE proc) noexcept
Initializes a new class instance with an already available object handle.
Definition Win.h:1683
winstd::vmemory::vmemory
vmemory() noexcept
Initializes a new class instance with the memory handle set to INVAL.
Definition Win.h:1674
winstd::vmemory::vmemory
vmemory(vmemory &&h) noexcept
Move constructor.
Definition Win.h:1693
winstd::vmemory::m_proc
HANDLE m_proc
Handle of memory's process.
Definition Win.h:1775
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:1403
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
Definition Common.h:884
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:2029
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:2006
RegOpenKeyExA
static LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2048
RegOpenKeyExW
static LSTATUS RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, winstd::reg_key &result)
Opens the specified registry key.
Definition Win.h:2067
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:2086
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:2141
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:2116
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:2101
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:2127
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:2156
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::LocalFree_delete
Deleter for unique_ptr using LocalFree.
Definition Common.h:739
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