Function returning std::string and std::wstring rewriten to templates to use std::basic_string, allowing finer selection of the string type to use: nonstandard traits & allocator

This commit is contained in:
Simon Rozman 2016-05-17 10:23:48 +02:00
parent 1ce8a004be
commit 010919ff24
7 changed files with 140 additions and 98 deletions

View File

@ -224,6 +224,7 @@ namespace winstd
}
};
///
/// Deleter for unique_ptr to array of unknown size using LocalFree
///
@ -254,6 +255,7 @@ namespace winstd
}
};
///
/// \defgroup WinStdSysHandles System Handles
/// Simplifies work with object handles of various type

View File

@ -39,7 +39,8 @@
///
/// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
///
inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::string &sNameString)
template<class _Elem, class _Traits, class _Ax>
inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString)
{
assert(0); // TODO: Test this code.
@ -47,7 +48,7 @@ inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize);
return dwSize;
@ -59,7 +60,8 @@ inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
///
/// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
///
inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::wstring &sNameString)
template<class _Elem, class _Traits, class _Ax>
inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString)
{
assert(0); // TODO: Test this code.
@ -67,7 +69,7 @@ inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize);
return dwSize;
@ -79,14 +81,15 @@ inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
///
/// \sa [CryptGetHashParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379947.aspx)
///
inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<unsigned char> &aData, _In_ DWORD dwFlags)
template<class _Ty, class _Ax>
inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
{
assert(0); // TODO: Test this code.
DWORD dwHashSize;
if (CryptGetHashParam(hHash, dwParam, NULL, &dwHashSize, dwFlags)) {
aData.resize(dwHashSize);
aData.resize((dwHashSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptGetHashParam(hHash, dwParam, aData.data(), &dwHashSize, dwFlags))
return TRUE;
}
@ -101,14 +104,15 @@ inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_
///
/// \sa [CryptExportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379931.aspx)
///
inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<unsigned char> &aData)
template<class _Ty, class _Ax>
inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData)
{
assert(0); // TODO: Test this code.
DWORD dwKeyBLOBSize;
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) {
aData.resize(dwKeyBLOBSize);
aData.resize((dwKeyBLOBSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.data(), &dwKeyBLOBSize))
return TRUE;
}

View File

@ -39,11 +39,12 @@
///
/// \sa [MsiGetProperty function](https://msdn.microsoft.com/en-us/library/aa370134.aspx)
///
inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -55,7 +56,7 @@ inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ s
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiGetPropertyA(hInstall, szName, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -71,11 +72,12 @@ inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ s
///
/// \sa [MsiGetProperty function](https://msdn.microsoft.com/en-us/library/aa370134.aspx)
///
inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -87,7 +89,7 @@ inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiGetPropertyW(hInstall, szName, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -103,11 +105,12 @@ inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_
///
/// \sa [MsiRecordGetString function](https://msdn.microsoft.com/en-us/library/aa370368.aspx)
///
inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -119,7 +122,7 @@ inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiRecordGetStringA(hRecord, iField, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -135,11 +138,12 @@ inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
///
/// \sa [MsiRecordGetString function](https://msdn.microsoft.com/en-us/library/aa370368.aspx)
///
inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -151,7 +155,7 @@ inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiRecordGetStringW(hRecord, iField, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -167,11 +171,12 @@ inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
///
/// \sa [MsiFormatRecord function](https://msdn.microsoft.com/en-us/library/aa370109.aspx)
///
inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -183,7 +188,7 @@ inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::string
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiFormatRecordA(hInstall, hRecord, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -199,11 +204,12 @@ inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::string
///
/// \sa [MsiFormatRecord function](https://msdn.microsoft.com/en-us/library/aa370109.aspx)
///
inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -215,7 +221,7 @@ inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::wstring
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiFormatRecordW(hInstall, hRecord, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -231,7 +237,8 @@ inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::wstring
///
/// \sa [MsiRecordReadStream function](https://msdn.microsoft.com/en-us/library/aa370370.aspx)
///
inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::vector<unsigned char> &binData)
template<class _Ty, class _Ax>
inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::vector<_Ty, _Ax> &binData)
{
assert(0); // TODO: Test this code.
@ -241,7 +248,7 @@ inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
// Query the actual data length first.
uiResult = ::MsiRecordReadStream(hRecord, iField, NULL, &dwSize);
if (uiResult == NO_ERROR) {
binData.resize(dwSize);
binData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return ::MsiRecordReadStream(hRecord, iField, (char*)binData.data(), &dwSize);
} else {
// Return error code.
@ -255,11 +262,12 @@ inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
///
/// \sa [MsiGetTargetPath function](https://msdn.microsoft.com/en-us/library/aa370303.aspx)
///
inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -271,7 +279,7 @@ inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Ou
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiGetTargetPathA(hInstall, szFolder, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;
@ -287,11 +295,12 @@ inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Ou
///
/// \sa [MsiGetTargetPath function](https://msdn.microsoft.com/en-us/library/aa370303.aspx)
///
inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(szStackBuffer);
UINT uiResult;
@ -303,7 +312,7 @@ inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _O
return NO_ERROR;
} else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[++dwSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++dwSize]);
uiResult = ::MsiGetTargetPathW(hInstall, szFolder, szBuffer.get(), &dwSize);
sValue.assign(szBuffer.get(), uiResult == NO_ERROR ? dwSize : 0);
return uiResult;

View File

@ -36,11 +36,12 @@
///
/// \sa [GetUserNameEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx)
///
BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::string &sName)
template<class _Elem, class _Traits, class _Ax>
BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
@ -51,7 +52,7 @@ BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::string &
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[ulSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[ulSize]);
if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;
@ -69,11 +70,12 @@ BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::string &
///
/// \sa [GetUserNameEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx)
///
BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::wstring &sName)
template<class _Elem, class _Traits, class _Ax>
BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
@ -84,7 +86,7 @@ BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::wstring
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[ulSize]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[ulSize]);
if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;

View File

@ -34,12 +34,13 @@
///
/// \sa [PathCanonicalize function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773569.aspx)
///
inline BOOL PathCanonicalizeA(__out std::string &sValue, __in LPCSTR pszPath)
template<class _Elem, class _Traits, class _Ax>
inline BOOL PathCanonicalizeA(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCSTR pszPath)
{
assert(0); // TODO: Test this code.
// Allocate buffer on heap and read into it.
CHAR szBuffer[MAX_PATH + 1];
_Elem szBuffer[MAX_PATH + 1];
BOOL bResult = ::PathCanonicalizeA(szBuffer, pszPath);
sValue.assign(szBuffer, bResult ? MAX_PATH : 0);
return bResult;
@ -51,11 +52,12 @@ inline BOOL PathCanonicalizeA(__out std::string &sValue, __in LPCSTR pszPath)
///
/// \sa [PathCanonicalize function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773569.aspx)
///
inline BOOL PathCanonicalizeW(__out std::wstring &sValue, __in LPCWSTR pszPath)
template<class _Elem, class _Traits, class _Ax>
inline BOOL PathCanonicalizeW(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCWSTR pszPath)
{
assert(0); // TODO: Test this code.
WCHAR szBuffer[MAX_PATH + 1];
_Elem szBuffer[MAX_PATH + 1];
BOOL bResult = ::PathCanonicalizeW(szBuffer, pszPath);
sValue.assign(szBuffer, bResult ? MAX_PATH : 0);
return bResult;

View File

@ -44,7 +44,8 @@ extern DWORD (WINAPI *pfnWlanReasonCodeToString)(__in DWORD dwReasonCode, __in D
/// Since Wlanapi.dll is not always present, the \c pfnWlanReasonCodeToString pointer to \c WlanReasonCodeToString
/// function must be loaded dynamically.
///
inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Out_ std::wstring &sValue, __reserved PVOID pReserved)
template<class _Elem, class _Traits, class _Ax>
inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue, __reserved PVOID pReserved)
{
assert(0); // TODO: Test this code.
@ -55,7 +56,7 @@ inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Out_ std::wstring
for (;;) {
// Increment size and allocate buffer.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize += 1024]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize += 1024]);
// Try!
DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, dwSize, szBuffer.get(), pReserved);

View File

@ -39,11 +39,12 @@
///
/// \sa [GetModuleFileName function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197.aspx)
///
inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
CHAR szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
// Try with stack buffer first.
DWORD dwResult = ::GetModuleFileNameA(hModule, szBuffer, _countof(szBuffer));
@ -52,9 +53,9 @@ inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::string &sVa
sValue.assign(szBuffer, dwResult);
return dwResult;
} else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR);; dwCapacity *= 2) {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; dwCapacity *= 2) {
// Allocate on heap and retry.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwCapacity]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwCapacity]);
dwResult = ::GetModuleFileNameA(hModule, szBuffer.get(), dwCapacity);
if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), dwResult);
@ -70,11 +71,12 @@ inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::string &sVa
///
/// \sa [GetModuleFileName function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197.aspx)
///
inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
WCHAR szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
// Try with stack buffer first.
DWORD dwResult = ::GetModuleFileNameW(hModule, szBuffer, _countof(szBuffer));
@ -83,9 +85,9 @@ inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::wstring &sV
sValue.assign(szBuffer, dwResult);
return dwResult;
} else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR);; dwCapacity *= 2) {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; dwCapacity *= 2) {
// Allocate on heap and retry.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwCapacity]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwCapacity]);
dwResult = ::GetModuleFileNameW(hModule, szBuffer.get(), dwCapacity);
if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), dwResult);
@ -101,7 +103,8 @@ inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::wstring &sV
///
/// \sa [GetWindowText function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633520.aspx)
///
inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
@ -110,14 +113,14 @@ inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::string &sValue)
// Query the final string length first.
iResult = ::GetWindowTextLengthA(hWnd);
if (iResult > 0) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)) {
// Read string data to stack.
CHAR szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
iResult = ::GetWindowTextA(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[++iResult]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++iResult]);
iResult = ::GetWindowTextA(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
@ -134,7 +137,8 @@ inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::string &sValue)
///
/// \sa [GetWindowText function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633520.aspx)
///
inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
@ -143,14 +147,14 @@ inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::wstring &sValue)
// Query the final string length first.
iResult = ::GetWindowTextLengthW(hWnd);
if (iResult > 0) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)) {
// Read string data to stack.
WCHAR szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
iResult = ::GetWindowTextW(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[++iResult]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[++iResult]);
iResult = ::GetWindowTextW(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
@ -167,7 +171,8 @@ inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::wstring &sValue)
///
/// \sa [GetFileVersionInfo function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003.aspx)
///
inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<unsigned char> &aValue)
template<class _Ty, class _Ax>
inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue)
{
assert(0); // TODO: Test this code.
@ -175,7 +180,7 @@ inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwH
DWORD dwVerInfoSize = ::GetFileVersionInfoSizeA(lptstrFilename, &dwHandle);
if (dwVerInfoSize != 0) {
// Read version info.
aValue.resize(dwVerInfoSize);
aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return ::GetFileVersionInfoA(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
} else
return FALSE;
@ -187,7 +192,8 @@ inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwH
///
/// \sa [GetFileVersionInfo function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003.aspx)
///
inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<unsigned char> &aValue)
template<class _Ty, class _Ax>
inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue)
{
assert(0); // TODO: Test this code.
@ -195,7 +201,7 @@ inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dw
DWORD dwVerInfoSize = ::GetFileVersionInfoSizeW(lptstrFilename, &dwHandle);
if (dwVerInfoSize != 0) {
// Read version info.
aValue.resize(dwVerInfoSize);
aValue.resize((dwVerInfoSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return ::GetFileVersionInfoW(lptstrFilename, dwHandle, dwVerInfoSize, aValue.data());
} else
return FALSE;
@ -207,13 +213,14 @@ inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dw
///
/// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx)
///
inline DWORD ExpandEnvironmentStringsW(_In_ LPCSTR lpSrc, std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline DWORD ExpandEnvironmentStringsW(_In_ LPCSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
for (DWORD dwSizeOut = (DWORD)strlen(lpSrc) + 0x100;;) {
DWORD dwSizeIn = dwSizeOut;
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSizeIn + 2]); // Note: ANSI version requires one extra char.
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSizeIn + 2]); // Note: ANSI version requires one extra char.
dwSizeOut = ::ExpandEnvironmentStringsA(lpSrc, szBuffer.get(), dwSizeIn);
if (dwSizeOut == 0) {
// Error.
@ -235,13 +242,14 @@ inline DWORD ExpandEnvironmentStringsW(_In_ LPCSTR lpSrc, std::string &sValue)
///
/// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx)
///
inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
for (DWORD dwSizeOut = (DWORD)wcslen(lpSrc) + 0x100;;) {
DWORD dwSizeIn = dwSizeOut;
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSizeIn + 1]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSizeIn + 1]);
dwSizeOut = ::ExpandEnvironmentStringsW(lpSrc, szBuffer.get(), dwSizeIn);
if (dwSizeOut == 0) {
// Error.
@ -264,7 +272,8 @@ inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::wstring &sValue)
/// \param[in ] lpGuid Pointer to GUID
/// \param[out] str String to store the result to
///
inline VOID GuidToString(_In_ LPCGUID lpGuid, _Out_ std::string &str)
template<class _Elem, class _Traits, class _Ax>
inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str)
{
assert(0); // TODO: Test this code.
@ -283,7 +292,8 @@ inline VOID GuidToString(_In_ LPCGUID lpGuid, _Out_ std::string &str)
/// \param[in ] lpGuid Pointer to GUID
/// \param[out] str String to store the result to
///
inline VOID GuidToString(_In_ LPCGUID lpGuid, _Out_ std::wstring &str)
template<class _Elem, class _Traits, class _Ax>
inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str)
{
assert(0); // TODO: Test this code.
@ -295,6 +305,12 @@ inline VOID GuidToString(_In_ LPCGUID lpGuid, _Out_ std::wstring &str)
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
///
/// Queries for a string value in the registry and stores it in a std::string string.
@ -314,7 +330,8 @@ inline VOID GuidToString(_In_ LPCGUID lpGuid, _Out_ std::wstring &str)
/// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx)
/// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx)
///
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::string &sValue)
template<class _Elem, class _Traits, class _Ax>
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
@ -327,10 +344,10 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
if (lResult == ERROR_SUCCESS) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ.
sValue.assign((CHAR*)aStackBuffer, dwSize / sizeof(CHAR));
sValue.assign((_Elem*)aStackBuffer, dwSize / sizeof(_Elem));
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
if (::ExpandEnvironmentStringsW((const CHAR*)aStackBuffer, sValue) == 0)
if (::ExpandEnvironmentStringsW((const _Elem*)aStackBuffer, sValue) == 0)
lResult = ::GetLastError();
} else {
// The value is not a string type.
@ -339,14 +356,14 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
} 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.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize / sizeof(CHAR)]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS)
sValue.assign(szBuffer.get(), dwSize / sizeof(CHAR));
sValue.assign(szBuffer.get(), dwSize / sizeof(_Elem));
else
sValue.clear();
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize / sizeof(CHAR)]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError();
@ -380,7 +397,8 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
/// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx)
/// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx)
///
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::wstring &sValue)
template<class _Elem, class _Traits, class _Ax>
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
{
assert(0); // TODO: Test this code.
@ -393,10 +411,10 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
if (lResult == ERROR_SUCCESS) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ.
sValue.assign((WCHAR*)aStackBuffer, dwSize / sizeof(WCHAR));
sValue.assign((_Elem*)aStackBuffer, dwSize / sizeof(_Elem));
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
if (::ExpandEnvironmentStringsW((const WCHAR*)aStackBuffer, sValue) == 0)
if (::ExpandEnvironmentStringsW((const _Elem*)aStackBuffer, sValue) == 0)
lResult = ::GetLastError();
} else {
// The value is not a string type.
@ -405,14 +423,14 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
} 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.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize / sizeof(WCHAR)]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS)
sValue.assign(szBuffer.get(), dwSize / sizeof(WCHAR));
sValue.assign(szBuffer.get(), dwSize / sizeof(_Elem));
else
sValue.clear();
} else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize / sizeof(WCHAR)]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError();
@ -433,7 +451,8 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
///
/// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx)
///
inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<unsigned char> &aData)
template<class _Ty, class _Ax>
inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData)
{
assert(0); // TODO: Test this code.
@ -444,12 +463,12 @@ inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __r
// Try with stack buffer first.
lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, NULL, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
// Allocate buffer on heap, copy from stack buffer.
aData.resize(dwSize);
// 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);
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if ((lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize)) != ERROR_SUCCESS)
aData.clear();
}
@ -463,7 +482,8 @@ inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __r
///
/// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx)
///
inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<unsigned char> &aData)
template<class _Ty, class _Ax>
inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData)
{
assert(0); // TODO: Test this code.
@ -474,12 +494,12 @@ inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __
// Try with stack buffer first.
lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, NULL, aStackBuffer, &dwSize);
if (lResult == ERROR_SUCCESS) {
// Allocate buffer on heap, copy from stack buffer.
aData.resize(dwSize);
// 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);
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if ((lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize)) != ERROR_SUCCESS)
aData.clear();
}
@ -495,12 +515,13 @@ inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __
///
/// \sa [RegLoadMUIString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724890.aspx)
///
inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_ std::string &sOut, _In_ DWORD Flags, _In_opt_ LPCSTR pszDirectory)
template<class _Elem, class _Traits, class _Ax>
inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCSTR pszDirectory)
{
assert(0); // TODO: Test this code.
LSTATUS lResult;
CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize;
Flags &= ~REG_MUI_STRING_TRUNCATE;
@ -512,7 +533,7 @@ inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_
sOut.assign(szStackBuffer, dwSize);
} else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize + 1]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize + 1]);
sOut.assign(szBuffer.get(), (lResult = RegLoadMUIStringA(hKey, pszValue, szBuffer.get(), dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? dwSize : 0);
}
@ -525,12 +546,13 @@ inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_
///
/// \sa [RegLoadMUIString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724890.aspx)
///
inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out_ std::wstring &sOut, _In_ DWORD Flags, _In_opt_ LPCWSTR pszDirectory)
template<class _Elem, class _Traits, class _Ax>
inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCWSTR pszDirectory)
{
assert(0); // TODO: Test this code.
LSTATUS lResult;
WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)];
_Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize;
Flags &= ~REG_MUI_STRING_TRUNCATE;
@ -542,7 +564,7 @@ inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out
sOut.assign(szStackBuffer, dwSize);
} else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize + 1]);
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize + 1]);
sOut.assign(szBuffer.get(), (lResult = RegLoadMUIStringW(hKey, pszValue, szBuffer.get(), dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? dwSize : 0);
}