From 010919ff24c553f7ea95d1ab5d3260381565892d Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 17 May 2016 10:23:48 +0200 Subject: [PATCH] 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 --- include/WinStd/Common.h | 2 + include/WinStd/Crypt.h | 20 ++++--- include/WinStd/MSI.h | 61 ++++++++++--------- include/WinStd/Sec.h | 14 +++-- include/WinStd/Shell.h | 10 ++-- include/WinStd/WLAN.h | 5 +- include/WinStd/Win.h | 126 +++++++++++++++++++++++----------------- 7 files changed, 140 insertions(+), 98 deletions(-) diff --git a/include/WinStd/Common.h b/include/WinStd/Common.h index fd7ef9f8..62161f3c 100644 --- a/include/WinStd/Common.h +++ b/include/WinStd/Common.h @@ -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 diff --git a/include/WinStd/Crypt.h b/include/WinStd/Crypt.h index d177462c..caf5e361 100644 --- a/include/WinStd/Crypt.h +++ b/include/WinStd/Crypt.h @@ -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 +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(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 +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(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 &aData, _In_ DWORD dwFlags) +template +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 &aData) +template +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; } diff --git a/include/WinStd/MSI.h b/include/WinStd/MSI.h index 1a1acf12..c86d0bbc 100644 --- a/include/WinStd/MSI.h +++ b/include/WinStd/MSI.h @@ -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 +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(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 +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(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 +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(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 +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(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 +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(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 +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(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 &binData) +template +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 +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(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 +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(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; diff --git a/include/WinStd/Sec.h b/include/WinStd/Sec.h index 77a8aec4..43333a87 100644 --- a/include/WinStd/Sec.h +++ b/include/WinStd/Sec.h @@ -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 +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(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 +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(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; diff --git a/include/WinStd/Shell.h b/include/WinStd/Shell.h index 0787e950..6eb1ef1a 100644 --- a/include/WinStd/Shell.h +++ b/include/WinStd/Shell.h @@ -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 +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 +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; diff --git a/include/WinStd/WLAN.h b/include/WinStd/WLAN.h index 4c8a8414..678d4180 100644 --- a/include/WinStd/WLAN.h +++ b/include/WinStd/WLAN.h @@ -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 +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(new WCHAR[dwSize += 1024]); + auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize += 1024]); // Try! DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, dwSize, szBuffer.get(), pReserved); diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index 4ce50f28..ddef7d69 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -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 +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(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 +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(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 +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(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 +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(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 &aValue) +template +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 &aValue) +template +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 +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(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 +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(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 +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 +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 +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(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(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 +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(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(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 &aData) +template +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 &aData) +template +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 +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(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 +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(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); }