Win.h
/*
SPDX-License-Identifier: MIT
Copyright © 1991-2022 Amebis
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.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.
std::unique_ptr<char[]> szBuffer(new char[dwCapacity]);
dwResult = ::GetModuleFileNameA(hModule, szBuffer.get(), dwCapacity);
if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), 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.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwCapacity]);
dwResult = ::GetModuleFileNameW(hModule, szBuffer.get(), dwCapacity);
if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), 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) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(char)) {
// Read string data to stack.
char szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
iResult = ::GetWindowTextA(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
std::unique_ptr<char[]> szBuffer(new char[++iResult]);
iResult = ::GetWindowTextA(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
return 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) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)) {
// Read string data to stack.
wchar_t szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
iResult = ::GetWindowTextW(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++iResult]);
iResult = ::GetWindowTextW(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
return 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) noexcept
{
assert(0); // TODO: Test this code.
for (DWORD dwSizeOut = (DWORD)strlen(lpSrc) + 0x100;;) {
DWORD dwSizeIn = dwSizeOut;
std::unique_ptr<char[]> szBuffer(new char[(size_t)dwSizeIn + 2]); // Note: ANSI version requires one extra char.
dwSizeOut = ::ExpandEnvironmentStringsA(lpSrc, szBuffer.get(), dwSizeIn);
if (dwSizeOut == 0) {
// Error or zero-length input.
break;
} else if (dwSizeOut <= dwSizeIn) {
// The buffer was sufficient.
sValue.assign(szBuffer.get(), dwSizeOut - 1);
return dwSizeOut;
}
}
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) noexcept
{
for (DWORD dwSizeOut = (DWORD)wcslen(lpSrc) + 0x100;;) {
DWORD dwSizeIn = dwSizeOut;
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[(size_t)dwSizeIn + 1]);
dwSizeOut = ::ExpandEnvironmentStringsW(lpSrc, szBuffer.get(), dwSizeIn);
if (dwSizeOut == 0) {
// Error or zero-length input.
break;
} else if (dwSizeOut <= dwSizeIn) {
// The buffer was sufficient.
sValue.assign(szBuffer.get(), dwSizeOut - 1);
return dwSizeOut;
}
}
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.
std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR)]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(CHAR);
sValue.assign(szBuffer.get(), dwSize && szBuffer[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)]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
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.
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(WCHAR);
sValue.assign(szBuffer.get(), dwSize && szBuffer[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)]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
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, 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, 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.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[(dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t)]);
sOut.assign(szBuffer.get(), (lResult = RegLoadMUIStringW(hKey, pszValue, szBuffer.get(), dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? wcsnlen(szBuffer.get(), dwSize/sizeof(wchar_t)) : 0);
}
return lResult;
}
#endif
template<class _Traits, class _Ax>
static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::basic_string<char, _Traits, _Ax> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack. Be careful not to include zero terminator.
sMultiByteStr.assign(szStackBuffer, cchWideChar != -1 ? strnlen(szStackBuffer, cch) : (size_t)cch - 1);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1);
}
return cch;
}
template<class _Ax>
static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::vector<char, _Ax> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack.
sMultiByteStr.assign(szStackBuffer, szStackBuffer + cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, sMultiByteStr.data(), cch, lpDefaultChar, lpUsedDefaultChar);
}
return cch;
}
template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string<wchar_t, _Traits1, _Ax1> sWideCharStr, _Out_ std::basic_string<char, _Traits2, _Ax2> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack.
sMultiByteStr.assign(szStackBuffer, cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cch);
}
return cch;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::basic_string<char, _Traits, _Ax> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack. Be careful not to include zero terminator.
sMultiByteStr.assign(szStackBuffer, cchWideChar != -1 ? strnlen(szStackBuffer, cch) : (size_t)cch - 1);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1);
SecureZeroMemory(szBuffer.get(), sizeof(CHAR)*cch);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
template<class _Ax>
static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::vector<char, _Ax> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack.
sMultiByteStr.assign(szStackBuffer, szStackBuffer + cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, sMultiByteStr.data(), cch, lpDefaultChar, lpUsedDefaultChar);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _Out_ std::basic_string<wchar_t, _Traits1, _Ax1> sWideCharStr, _Out_ std::basic_string<char, _Traits2, _Ax2> &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) noexcept
{
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
// Try to convert to stack buffer first.
int cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar);
if (cch) {
// Copy from stack.
sMultiByteStr.assign(szStackBuffer, cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cch);
SecureZeroMemory(szBuffer.get(), sizeof(CHAR)*cch);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, cbMultiByte != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch);
sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1);
}
return cch;
}
template<class _Ax>
static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::vector<wchar_t, _Ax> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, szStackBuffer + cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, sWideCharStr.data(), cch);
}
return cch;
}
template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string<char, _Traits1, _Ax1> &sMultiByteStr, _Out_ std::basic_string<wchar_t, _Traits2, _Ax2> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch);
sWideCharStr.assign(szBuffer.get(), cch);
}
return cch;
}
template<class _Traits, class _Ax>
static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, cbMultiByte != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch);
sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1);
SecureZeroMemory(szBuffer.get(), sizeof(WCHAR)*cch);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
template<class _Ax>
static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::vector<wchar_t, _Ax> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, szStackBuffer + cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, sWideCharStr.data(), cch);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
template<class _Traits1, class _Ax1, class _Traits2, class _Ax2>
static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string<char, _Traits1, _Ax1> &sMultiByteStr, _Out_ std::basic_string<wchar_t, _Traits2, _Ax2> &sWideCharStr) noexcept
{
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
// Try to convert to stack buffer first.
int cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szStackBuffer, _countof(szStackBuffer));
if (cch) {
// Copy from stack.
sWideCharStr.assign(szStackBuffer, cch);
} else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch);
sWideCharStr.assign(szBuffer.get(), cch);
SecureZeroMemory(szBuffer.get(), sizeof(WCHAR)*cch);
}
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
return cch;
}
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;
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, szBuffer.get(), cch);
if (cch > 0) {
sDstString.assign(szBuffer.get(), cwSrcLength != -1 ? wcsnlen(szStackBuffer, 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;
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), szBuffer.get(), cch);
if (cch > 0) {
sDstString.assign(szBuffer.get(), cch);
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.
std::unique_ptr<char[]> szBuffer(new char[iResult]);
iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult);
sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0);
return 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.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[iResult]);
iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult);
sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0);
return 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;
}
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/sizeof(BYTE)];
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 / sizeof(BYTE)]));
if (!TokenInformation) {
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
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 / sizeof(BYTE)]));
if (!TokenInformation) {
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
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.
std::unique_ptr<char[]> szBuffer(new char[dwCapacity]);
dwSize = dwCapacity;
if (::QueryFullProcessImageNameA(hProcess, dwFlags, szBuffer.get(), &dwSize)) {
sExeName.assign(szBuffer.get(), 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.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwCapacity]);
dwSize = dwCapacity;
if (::QueryFullProcessImageNameW(hProcess, dwFlags, szBuffer.get(), &dwSize)) {
sExeName.assign(szBuffer.get(), 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, 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, NULL)
public:
virtual ~library()
{
if (m_h != invalid)
free_internal();
}
bool load(_In_z_ LPCTSTR lpFileName, __reserved handle_type hFile, _In_ DWORD dwFlags) noexcept
{
handle_type h = LoadLibraryEx(lpFileName, hFile, dwFlags);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
protected:
void free_internal() noexcept override
{
FreeLibrary(m_h);
}
};
class process : public win_handle<NULL>
{
public:
bool open(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId) noexcept
{
handle_type h = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
};
class file : public win_handle<INVALID_HANDLE_VALUE>
{
public:
bool create(_In_z_ LPCTSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_opt_ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL, _In_opt_ HANDLE hTemplateFile = NULL) noexcept
{
handle_type h = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
};
class event : public win_handle<NULL>
{
public:
bool create(_In_ BOOL bManualReset, _In_ BOOL bInitialState, _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes = NULL, _In_opt_z_ LPCTSTR lpName = NULL) noexcept
{
handle_type h = CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
bool open(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_z_ LPCTSTR lpName) noexcept
{
handle_type h = OpenEvent(dwDesiredAccess, bInheritHandle, lpName);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
};
class critical_section
{
WINSTD_NONCOPYABLE(critical_section)
WINSTD_NONMOVABLE(critical_section)
public:
critical_section()
{
__try {
InitializeCriticalSection(&m_data);
} __except(EXCEPTION_EXECUTE_HANDLER) {
throw std::runtime_error("InitializeCriticalSection failed");
}
}
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, INVALID_HANDLE_VALUE)
public:
virtual ~find_file()
{
if (m_h != invalid)
free_internal();
}
bool find(_In_ LPCTSTR lpFileName, _Out_ LPWIN32_FIND_DATA lpFindFileData) noexcept
{
handle_type h = FindFirstFile(lpFileName, lpFindFileData);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
protected:
void free_internal() noexcept override
{
FindClose(m_h);
}
};
class heap : public handle<HANDLE, NULL>
{
WINSTD_HANDLE_IMPL(heap, NULL)
public:
virtual ~heap()
{
if (m_h != invalid)
free_internal();
}
bool create(_In_ DWORD flOptions, _In_ SIZE_T dwInitialSize, _In_ SIZE_T dwMaximumSize) noexcept
{
handle_type h = HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
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 user_impersonator
{
WINSTD_NONCOPYABLE(user_impersonator)
WINSTD_NONMOVABLE(user_impersonator)
public:
user_impersonator(_In_opt_ HANDLE hToken) noexcept
{
m_cookie = hToken && ImpersonateLoggedOnUser(hToken);
}
virtual ~user_impersonator()
{
if (m_cookie)
RevertToSelf();
}
protected:
BOOL m_cookie;
};
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, NULL)
public:
virtual ~reg_key()
{
if (m_h != invalid)
free_internal();
}
bool create(
_In_ HKEY hKey,
_In_z_ LPCTSTR lpSubKey,
_In_opt_ LPTSTR lpClass,
_In_ DWORD dwOptions,
_In_ REGSAM samDesired,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL,
_Out_opt_ LPDWORD lpdwDisposition = NULL) noexcept
{
handle_type h;
const LSTATUS s = RegCreateKeyEx(hKey, lpSubKey, 0, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
if (s == ERROR_SUCCESS) {
attach(h);
return true;
} else {
SetLastError(s);
return false;
}
}
bool open(
_In_ HKEY hKey,
_In_opt_z_ LPCTSTR lpSubKey,
_In_ DWORD ulOptions,
_In_ REGSAM samDesired) noexcept
{
handle_type h;
const LONG s = RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &h);
if (s == ERROR_SUCCESS) {
attach(h);
return true;
} else {
SetLastError(s);
return false;
}
}
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;
if (!k.open(m_h, szSubkey, 0, KEY_ENUMERATE_SUB_KEYS))
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, 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, NULL)
public:
virtual ~event_log()
{
if (m_h != invalid)
free_internal();
}
bool open(_In_z_ LPCTSTR lpUNCServerName, _In_z_ LPCTSTR lpSourceName) noexcept
{
handle_type h = RegisterEventSource(lpUNCServerName, lpSourceName);
if (h != invalid) {
attach(h);
return true;
} else
return false;
}
protected:
void free_internal() noexcept override
{
DeregisterEventSource(m_h);
}
};
}
winstd::actctx_activator
Activates given activation context in constructor and deactivates it in destructor.
Definition: Win.h:1834
winstd::actctx_activator::actctx_activator
actctx_activator(HANDLE hActCtx) noexcept
Construct the activator and activates the given activation context.
Definition: Win.h:1846
winstd::actctx_activator::~actctx_activator
virtual ~actctx_activator()
Deactivates activation context and destructs the activator.
Definition: Win.h:1857
winstd::actctx_activator::m_cookie
ULONG_PTR m_cookie
Cookie for context deactivation.
Definition: Win.h:1864
winstd::basic_string_printf
Base template class to support string formatting using printf() style templates.
Definition: Common.h:1115
winstd::console_ctrl_handler
Console control handler stack management.
Definition: Win.h:1907
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:1919
winstd::console_ctrl_handler::~console_ctrl_handler
virtual ~console_ctrl_handler()
Pops console control handler from the console control handler stack.
Definition: Win.h:1929
winstd::console_ctrl_handler::m_handler
PHANDLER_ROUTINE m_handler
Pointer to console control handler.
Definition: Win.h:1937
winstd::console_ctrl_handler::m_cookie
BOOL m_cookie
Did pushing the console control handler succeed?
Definition: Win.h:1936
winstd::critical_section
Critical section wrapper.
Definition: Win.h:1525
winstd::critical_section::m_data
CRITICAL_SECTION m_data
Critical section struct.
Definition: Win.h:1565
winstd::critical_section::~critical_section
virtual ~critical_section()
Releases all resources used by an unowned critical section object.
Definition: Win.h:1549
winstd::critical_section::critical_section
critical_section()
Construct the object and initializes a critical section object.
Definition: Win.h:1535
winstd::event_log
Event log handle wrapper.
Definition: Win.h:2262
winstd::event_log::free_internal
void free_internal() noexcept override
Closes an event log handle.
Definition: Win.h:2302
winstd::event_log::~event_log
virtual ~event_log()
Closes an event log handle.
Definition: Win.h:2271
winstd::event_log::open
bool open(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName) noexcept
Retrieves a registered handle to the specified event log.
Definition: Win.h:2286
winstd::event
Event handle wrapper.
Definition: Win.h:1480
winstd::event::open
bool open(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName) noexcept
Opens an existing named event object.
Definition: Win.h:1510
winstd::event::create
bool create(BOOL bManualReset, BOOL bInitialState, LPSECURITY_ATTRIBUTES lpEventAttributes=NULL, LPCTSTR lpName=NULL) noexcept
Creates or opens a named or unnamed event object.
Definition: Win.h:1491
winstd::file
File handle wrapper.
Definition: Win.h:1454
winstd::file::create
bool create(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, LPSECURITY_ATTRIBUTES lpSecurityAttributes=NULL, HANDLE hTemplateFile=NULL) noexcept
Opens file handle.
Definition: Win.h:1465
winstd::find_file
Find-file handle wrapper.
Definition: Win.h:1572
winstd::find_file::~find_file
virtual ~find_file()
Closes a file search handle.
Definition: Win.h:1581
winstd::find_file::free_internal
void free_internal() noexcept override
Closes a file search handle.
Definition: Win.h:1612
winstd::find_file::find
bool find(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) noexcept
Searches a directory for a file or subdirectory with a name that matches a specific name (or partial ...
Definition: Win.h:1596
winstd::handle
Base abstract template class to support generic object handle keeping.
Definition: Common.h:604
winstd::handle< HMODULE, NULL >::handle_type
HMODULE handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:609
winstd::handle< HANDLE, INVALID >::m_h
handle_type m_h
Object handle.
Definition: Common.h:855
winstd::handle< HMODULE, NULL >::attach
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:818
winstd::heap_allocator
HeapAlloc allocator.
Definition: Win.h:1719
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:1728
winstd::heap_allocator::value_type
_Ty value_type
A type that is managed by the allocator.
Definition: Win.h:1721
winstd::heap_allocator::heap_allocator
heap_allocator(const heap_allocator< _Other > &other)
Constructs allocator from another type.
Definition: Win.h:1756
winstd::heap_allocator::m_heap
HANDLE m_heap
Heap handle.
Definition: Win.h:1827
winstd::heap_allocator::allocate
pointer allocate(size_type count)
Allocates a new memory block.
Definition: Win.h:1767
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:1729
winstd::heap_allocator::heap_allocator
heap_allocator(HANDLE heap)
Constructs allocator.
Definition: Win.h:1746
winstd::heap_allocator::reference
_Ty & reference
A type that provides a reference to the type of object managed by the allocator.
Definition: Win.h:1724
winstd::heap_allocator::construct
void construct(pointer ptr, _Ty &&val)
Calls moving constructor for the element.
Definition: Win.h:1803
winstd::heap_allocator::deallocate
void deallocate(pointer ptr, size_type size)
Frees memory block.
Definition: Win.h:1779
winstd::heap_allocator::max_size
size_type max_size() const
Returns maximum memory block size.
Definition: Win.h:1821
winstd::heap_allocator::construct
void construct(pointer ptr, const _Ty &val)
Calls copying constructor for the element.
Definition: Win.h:1792
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:1726
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:1725
winstd::heap_allocator::pointer
_Ty * pointer
A type that provides a pointer to the type of object managed by the allocator.
Definition: Win.h:1723
winstd::heap_allocator::destroy
void destroy(pointer ptr)
Calls destructor for the element.
Definition: Win.h:1813
winstd::heap
Heap handle wrapper.
Definition: Win.h:1622
winstd::heap::enumerate
bool enumerate() noexcept
Enumerates allocated heap blocks using OutputDebugString()
Definition: Win.h:1663
winstd::heap::create
bool create(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) noexcept
Creates the heap.
Definition: Win.h:1646
winstd::heap::free_internal
void free_internal() noexcept override
Destroys the heap.
Definition: Win.h:1707
winstd::heap::~heap
virtual ~heap()
Destroys the heap.
Definition: Win.h:1631
winstd::library
Module handle wrapper.
Definition: Win.h:1378
winstd::library::free_internal
void free_internal() noexcept override
Frees the module.
Definition: Win.h:1418
winstd::library::~library
virtual ~library()
Frees the module.
Definition: Win.h:1387
winstd::library::load
bool load(LPCTSTR lpFileName, __reserved handle_type hFile, DWORD dwFlags) noexcept
Loads the specified module into the address space of the calling process.
Definition: Win.h:1402
winstd::process_information
PROCESS_INFORMATION struct wrapper.
Definition: Win.h:2224
winstd::process_information::~process_information
~process_information()
Closes process and thread handles.
Definition: Win.h:2243
winstd::process_information::process_information
process_information() noexcept
Constructs blank PROCESS_INFORMATION.
Definition: Win.h:2232
winstd::process
Process handle wrapper.
Definition: Win.h:1428
winstd::process::open
bool open(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) noexcept
Opens process handle.
Definition: Win.h:1439
winstd::reg_key
Registry wrapper class.
Definition: Win.h:2062
winstd::reg_key::free_internal
void free_internal() noexcept override
Closes a handle to the registry key.
Definition: Win.h:2183
winstd::reg_key::delete_subkey
bool delete_subkey(LPCTSTR szSubkey)
Deletes the specified registry subkey.
Definition: Win.h:2141
winstd::reg_key::open
bool open(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired) noexcept
Opens the specified registry key.
Definition: Win.h:2115
winstd::reg_key::create
bool create(HKEY hKey, LPCTSTR lpSubKey, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes=NULL, LPDWORD lpdwDisposition=NULL) noexcept
Creates the specified registry key. If the key already exists, the function opens it.
Definition: Win.h:2086
winstd::reg_key::~reg_key
virtual ~reg_key()
Closes a handle to the registry key.
Definition: Win.h:2071
winstd::security_id
SID wrapper class.
Definition: Win.h:2193
winstd::security_id::free_internal
void free_internal() noexcept override
Closes a handle to the SID.
Definition: Win.h:2214
winstd::security_id::~security_id
virtual ~security_id()
Closes a handle to the SID.
Definition: Win.h:2202
winstd::user_impersonator
Lets the calling thread impersonate the security context of a logged-on user.
Definition: Win.h:1871
winstd::user_impersonator::m_cookie
BOOL m_cookie
Did impersonation succeed?
Definition: Win.h:1900
winstd::user_impersonator::user_impersonator
user_impersonator(HANDLE hToken) noexcept
Construct the impersonator and impersonates the given user.
Definition: Win.h:1883
winstd::user_impersonator::~user_impersonator
virtual ~user_impersonator()
Reverts to current user and destructs the impersonator.
Definition: Win.h:1893
winstd::vmemory
Memory in virtual address space of a process handle wrapper.
Definition: Win.h:1944
winstd::vmemory::operator=
vmemory & operator=(vmemory &&other) noexcept
Move assignment.
Definition: Win.h:1994
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:2028
winstd::vmemory::free_internal
void free_internal() noexcept override
Frees the memory.
Definition: Win.h:2049
winstd::vmemory::attach
void attach(HANDLE proc, handle_type h) noexcept
Sets a new memory handle for the class.
Definition: Win.h:2011
winstd::vmemory::~vmemory
virtual ~vmemory()
Frees the memory.
Definition: Win.h:1983
winstd::vmemory::vmemory
vmemory(handle_type h, HANDLE proc) noexcept
Initializes a new class instance with an already available object handle.
Definition: Win.h:1961
winstd::vmemory::vmemory
vmemory() noexcept
Initializes a new class instance with the memory handle set to INVAL.
Definition: Win.h:1951
winstd::vmemory::vmemory
vmemory(vmemory &&h) noexcept
Move constructor.
Definition: Win.h:1972
winstd::vmemory::m_proc
HANDLE m_proc
Handle of memory's process.
Definition: Win.h:2055
winstd::win_handle
Windows HANDLE wrapper class.
Definition: Win.h:1347
winstd::win_handle::free_internal
void free_internal() noexcept override
Closes an open object handle.
Definition: Win.h:1368
winstd::win_handle::~win_handle
virtual ~win_handle()
Closes an open object handle.
Definition: Win.h:1356
WINSTD_NONCOPYABLE
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:53
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:80
WINSTD_NONMOVABLE
#define WINSTD_NONMOVABLE(C)
Declares a class as non-movable.
Definition: Common.h:61
WINSTD_HANDLE_IMPL
#define WINSTD_HANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:162
winstd::handle< HANDLE, INVALID >::invalid
static const HANDLE invalid
Invalid handle value.
Definition: Common.h:614
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:1736
winstd::heap_allocator::rebind::other
heap_allocator< _Other > other
Other allocator type.
Definition: Win.h:1737