diff --git a/include/WinStd/Common.h b/include/WinStd/Common.h index b8408051..e5575538 100644 --- a/include/WinStd/Common.h +++ b/include/WinStd/Common.h @@ -243,23 +243,6 @@ inline SIZE_T SIZETAdd(SIZE_T a, SIZE_T b) /// \addtogroup WinStdStrFormat /// @{ -/// -/// Formats string using `printf()`. -/// -/// \param[out] str Buffer to receive string -/// \param[in ] capacity Size of `str` in characters -/// \param[in ] format String template using `printf()` style -/// \param[in ] arg Arguments to `format` -/// -/// \returns Number of characters in result. -/// -#if _MSC_VER <= 1600 -static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ va_list arg) -{ - return _vsnprintf(str, capacity, format, arg); -} -#endif - /// /// Formats string using `printf()`. /// @@ -290,22 +273,27 @@ static int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; // Try with stack buffer first. - int count = vsnprintf(buf, _countof(buf) - 1, format, arg); - if (count >= 0) { + int count = vsnprintf(buf, _countof(buf), format, arg); + if (0 <= count && count < _countof(buf)) { // Copy from stack. - str.assign(buf, count); - } else { - for (size_t capacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; capacity *= 2) { - // Allocate on heap and retry. - auto buf_dyn = std::make_unique<_Elem[]>(capacity); - count = vsnprintf(buf_dyn.get(), capacity - 1, format, arg); - if (count >= 0) { - str.assign(buf_dyn.get(), count); - break; - } + str.append(buf, count); + return count; + } + if (count < 0) { + switch (errno) { + case 0: + count = vsnprintf(NULL, 0, format, arg); + assert(count >= 0); + break; + case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments"); + case EILSEQ: throw std::runtime_error("encoding error"); + default: throw std::runtime_error("failed to format string"); } } - + size_t offset = str.size(); + str.resize(offset + count); + if (vsnprintf(&str[offset], count + 1, format, arg) != count) + throw std::runtime_error("failed to format string"); return count; } @@ -346,9 +334,9 @@ static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ D 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 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); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.resize(cchWideChar != -1 ? strnlen(&sMultiByteStr[0], cch) : (size_t)cch - 1); } return cch; @@ -399,9 +387,8 @@ static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ D 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 szBuffer(new CHAR[cch]); - cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); - sMultiByteStr.assign(szBuffer.get(), cch); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar); } return cch; @@ -428,10 +415,9 @@ static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage, 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 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); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.resize(cchWideChar != -1 ? strnlen(&sMultiByteStr[0], cch) : (size_t)cch - 1); } SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); @@ -490,10 +476,8 @@ static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage, 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 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); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar); } SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); @@ -520,9 +504,9 @@ static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ D 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 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); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, &sWideCharStr[0], cch); + sWideCharStr.resize(cbMultiByte != -1 ? wcsnlen(&sWideCharStr[0], cch) : (size_t)cch - 1); } return cch; @@ -573,9 +557,8 @@ static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ D 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 szBuffer(new WCHAR[cch]); - cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch); - sWideCharStr.assign(szBuffer.get(), cch); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), &sWideCharStr[0], cch); } return cch; @@ -602,10 +585,9 @@ static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage, 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 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); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, &sWideCharStr[0], cch); + sWideCharStr.resize(cbMultiByte != -1 ? wcsnlen(&sWideCharStr[0], cch) : (size_t)cch - 1); } SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); @@ -664,10 +646,8 @@ static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage, 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 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); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), &sWideCharStr[0], cch); } SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); diff --git a/include/WinStd/Cred.h b/include/WinStd/Cred.h index ab6b4355..4f778408 100644 --- a/include/WinStd/Cred.h +++ b/include/WinStd/Cred.h @@ -29,11 +29,9 @@ static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR ps return TRUE; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Allocate on heap and retry. - std::unique_ptr buf(new char[dwSize]); - if (CredProtectA(fAsSelf, const_cast(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) { - sProtectedCredentials.assign(buf.get(), dwSize - 1); + sProtectedCredentials.resize(dwSize - 1); + if (CredProtectA(fAsSelf, const_cast(pszCredentials), cchCredentials, &sProtectedCredentials[0], &dwSize, ProtectionType)) return TRUE; - } } return FALSE; @@ -57,11 +55,9 @@ static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR p return TRUE; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Allocate on heap and retry. - std::unique_ptr buf(new wchar_t[dwSize]); - if (CredProtectW(fAsSelf, const_cast(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) { - sProtectedCredentials.assign(buf.get(), dwSize - 1); + sProtectedCredentials.resize(dwSize - 1); + if (CredProtectW(fAsSelf, const_cast(pszCredentials), cchCredentials, &sProtectedCredentials[0], &dwSize, ProtectionType)) return TRUE; - } } return FALSE; @@ -81,11 +77,9 @@ static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR return TRUE; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Allocate on heap and retry. - std::unique_ptr buf(new char[dwSize]); - if (CredUnprotectA(fAsSelf, const_cast(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) { - sCredentials.assign(buf.get(), dwSize); + sCredentials.resize(dwSize - 1); + if (CredUnprotectA(fAsSelf, const_cast(pszProtectedCredentials), cchCredentials, &sCredentials[0], &dwSize)) return TRUE; - } } return FALSE; @@ -109,11 +103,9 @@ static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR return TRUE; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Allocate on heap and retry. - std::unique_ptr buf(new wchar_t[dwSize]); - if (CredUnprotectW(fAsSelf, const_cast(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) { - sCredentials.assign(buf.get(), dwSize); + sCredentials.resize(dwSize - 1); + if (CredUnprotectW(fAsSelf, const_cast(pszProtectedCredentials), cchCredentials, &sCredentials[0], &dwSize)) return TRUE; - } } return FALSE; diff --git a/include/WinStd/Crypt.h b/include/WinStd/Crypt.h index e8710f73..13e64c5f 100644 --- a/include/WinStd/Crypt.h +++ b/include/WinStd/Crypt.h @@ -26,10 +26,8 @@ static 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. - std::unique_ptr szBuffer(new char[dwSize]); - dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize); - sNameString.assign(szBuffer.get(), dwSize - 1); - return dwSize; + sNameString.resize(dwSize - 1); + return ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, &sNameString[0], dwSize); } /// @@ -44,10 +42,8 @@ static 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. - std::unique_ptr szBuffer(new wchar_t[dwSize]); - dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize); - sNameString.assign(szBuffer.get(), dwSize - 1); - return dwSize; + sNameString.resize(dwSize - 1); + return ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, &sNameString[0], dwSize); } /// diff --git a/include/WinStd/MSI.h b/include/WinStd/MSI.h index 31bcad3a..c2c46000 100644 --- a/include/WinStd/MSI.h +++ b/include/WinStd/MSI.h @@ -34,10 +34,8 @@ static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inou return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to read the string data into and read it. - std::unique_ptr szBuffer(new char[++dwSize]); - uiResult = ::MsiGetPropertyA(hInstall, szName, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiGetPropertyA(hInstall, szName, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -64,10 +62,8 @@ static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Ino return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to read the string data into and read it. - std::unique_ptr szBuffer(new wchar_t[++dwSize]); - uiResult = ::MsiGetPropertyW(hInstall, szName, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiGetPropertyW(hInstall, szName, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -92,10 +88,8 @@ static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to read the string data into and read it. - std::unique_ptr szBuffer(new char[++dwSize]); - uiResult = ::MsiRecordGetStringA(hRecord, iField, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiRecordGetStringA(hRecord, iField, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -122,10 +116,8 @@ static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to read the string data into and read it. - std::unique_ptr szBuffer(new wchar_t[++dwSize]); - uiResult = ::MsiRecordGetStringW(hRecord, iField, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiRecordGetStringW(hRecord, iField, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -150,10 +142,8 @@ static UINT MsiFormatRecordA(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new char[++dwSize]); - uiResult = ::MsiFormatRecordA(hInstall, hRecord, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiFormatRecordA(hInstall, hRecord, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -180,10 +170,8 @@ static UINT MsiFormatRecordW(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new wchar_t[++dwSize]); - uiResult = ::MsiFormatRecordW(hInstall, hRecord, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiFormatRecordW(hInstall, hRecord, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -232,10 +220,8 @@ static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _ return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new char[++dwSize]); - uiResult = ::MsiGetTargetPathA(hInstall, szFolder, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiGetTargetPathA(hInstall, szFolder, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -262,10 +248,8 @@ static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, return ERROR_SUCCESS; } else if (uiResult == ERROR_MORE_DATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new wchar_t[++dwSize]); - uiResult = ::MsiGetTargetPathW(hInstall, szFolder, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0); - return uiResult; + sValue.resize(dwSize++); + return ::MsiGetTargetPathW(hInstall, szFolder, &sValue[0], &dwSize); } else { // Return error code. return uiResult; @@ -288,10 +272,8 @@ static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR return state; } else if (state == INSTALLSTATE_MOREDATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new char[++dwSize]); - state = ::MsiGetComponentPathA(szProduct, szComponent, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), state >= INSTALLSTATE_BROKEN ? dwSize : 0); - return state; + sValue.resize(dwSize++); + return ::MsiGetComponentPathA(szProduct, szComponent, &sValue[0], &dwSize); } else { // Return error code. return state; @@ -318,10 +300,8 @@ static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWST return state; } else if (state == INSTALLSTATE_MOREDATA) { // Allocate buffer on heap to format the string data into and read it. - std::unique_ptr szBuffer(new wchar_t[++dwSize]); - state = ::MsiGetComponentPathW(szProduct, szComponent, szBuffer.get(), &dwSize); - sValue.assign(szBuffer.get(), state >= INSTALLSTATE_BROKEN ? dwSize : 0); - return state; + sValue.resize(dwSize++); + return ::MsiGetComponentPathW(szProduct, szComponent, &sValue[0], &dwSize); } else { // Return error code. return state; diff --git a/include/WinStd/Sec.h b/include/WinStd/Sec.h index 314d152e..96083633 100644 --- a/include/WinStd/Sec.h +++ b/include/WinStd/Sec.h @@ -34,11 +34,9 @@ static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std: } if (::GetLastError() == ERROR_MORE_DATA) { // Allocate buffer on heap and retry. - std::unique_ptr szBuffer(new char[ulSize]); - if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) { - sName.assign(szBuffer.get(), ulSize); + sName.resize(ulSize - 1); + if (::GetUserNameExA(NameFormat, &ulSize[0], &ulSize)) return TRUE; - } } return FALSE; } @@ -64,11 +62,9 @@ static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std: } if (::GetLastError() == ERROR_MORE_DATA) { // Allocate buffer on heap and retry. - std::unique_ptr szBuffer(new wchar_t[ulSize]); - if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) { - sName.assign(szBuffer.get(), ulSize); + sName.resize(ulSize - 1); + if (::GetUserNameExW(NameFormat, &sName[0], &ulSize)) return TRUE; - } } return FALSE; } diff --git a/include/WinStd/WLAN.h b/include/WinStd/WLAN.h index 8132a209..5d90b567 100644 --- a/include/WinStd/WLAN.h +++ b/include/WinStd/WLAN.h @@ -43,15 +43,15 @@ static DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_ sSize = SIZETAdd(sSize, 1024); if (sSize > DWORD_MAX) throw std::runtime_exception("Data too big"); - std::unique_ptr szBuffer(new wchar_t[sSize]); + sValue.resize(sSize - 1); // Try! - DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, static_cast(sSize), szBuffer.get(), pReserved); + DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, static_cast(sSize), &sValue[0], pReserved); if (dwResult == ERROR_SUCCESS) { - SIZE_T sLength = wcsnlen(szBuffer.get(), sSize); + SIZE_T sLength = wcsnlen(&sValue[0], sSize); if (sLength < sSize - 1) { // Buffer was long enough. - sValue.assign(szBuffer.get(), sLength); + sValue.resize(sLength); return ERROR_SUCCESS; } } else { diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index 744ce99f..55aa983b 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -38,10 +38,10 @@ static DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_strin } else { for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(char);; dwCapacity *= 2) { // Allocate on heap and retry. - std::unique_ptr szBuffer(new char[dwCapacity]); - dwResult = ::GetModuleFileNameA(hModule, szBuffer.get(), dwCapacity); + sValue.resize(dwCapacity - 1); + dwResult = ::GetModuleFileNameA(hModule, &sValue[0], dwCapacity); if (dwResult < dwCapacity) { - sValue.assign(szBuffer.get(), dwResult); + sValue.resize(dwResult); return dwResult; } } @@ -67,10 +67,10 @@ static DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_strin } else { for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t);; dwCapacity *= 2) { // Allocate on heap and retry. - std::unique_ptr szBuffer(new wchar_t[dwCapacity]); - dwResult = ::GetModuleFileNameW(hModule, szBuffer.get(), dwCapacity); + sValue.resize(dwCapacity - 1); + dwResult = ::GetModuleFileNameW(hModule, &sValue[0], dwCapacity); if (dwResult < dwCapacity) { - sValue.assign(szBuffer.get(), dwResult); + sValue.resize(dwResult); return dwResult; } } @@ -88,18 +88,9 @@ static _Success_(return != 0) int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basi // 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 szBuffer(new char[++iResult]); - iResult = ::GetWindowTextA(hWnd, szBuffer.get(), iResult); - sValue.assign(szBuffer.get(), iResult); - } - return iResult; + // Allocate buffer on heap and read the string data into it. + sValue.resize(iResult++); + return ::GetWindowTextA(hWnd, &sValue[0], iResult); } sValue.clear(); @@ -121,18 +112,9 @@ static _Success_(return != 0) int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basi // 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 szBuffer(new wchar_t[++iResult]); - iResult = ::GetWindowTextW(hWnd, szBuffer.get(), iResult); - sValue.assign(szBuffer.get(), iResult); - } - return iResult; + // Allocate buffer on heap and read the string data into it. + sValue.resize(iResult++); + return ::GetWindowTextW(hWnd, &sValue[0], iResult); } sValue.clear(); @@ -185,14 +167,14 @@ static _Success_(return != 0) DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSr if (sSizeOut > DWORD_MAX) throw std::invalid_argument("String too big"); DWORD dwSizeIn = static_cast(sSizeOut); - std::unique_ptr szBuffer(new char[(size_t)dwSizeIn + 2]); // Note: ANSI version requires one extra char. - sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, szBuffer.get(), dwSizeIn); + sValue.resize((size_t)dwSizeIn + 1); // Note: ANSI version requires one extra char. + sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, &sValue[0], dwSizeIn); if (sSizeOut == 0) { // Error or zero-length input. break; } else if (sSizeOut <= dwSizeIn) { // The buffer was sufficient. - sValue.assign(szBuffer.get(), sSizeOut - 1); + sValue.resize(sSizeOut - 1); return static_cast(sSizeOut); } } @@ -213,14 +195,14 @@ static _Success_(return != 0) DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpS if (sSizeOut > DWORD_MAX) throw std::invalid_argument("String too big"); DWORD dwSizeIn = static_cast(sSizeOut); - std::unique_ptr szBuffer(new wchar_t[(size_t)dwSizeIn + 1]); - sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, szBuffer.get(), dwSizeIn); + sValue.resize(dwSizeIn); + sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, &sValue[0], dwSizeIn); if (sSizeOut == 0) { // Error or zero-length input. break; } else if (sSizeOut <= dwSizeIn) { // The buffer was sufficient. - sValue.assign(szBuffer.get(), sSizeOut - 1); + sValue.resize(sSizeOut - 1); return static_cast(sSizeOut); } } @@ -455,15 +437,17 @@ static 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. - std::unique_ptr szBuffer(new CHAR[dwSize / sizeof(CHAR)]); - if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { + sValue.resize(dwSize / sizeof(CHAR) - 1); + if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast(&sValue[0]), &dwSize)) == ERROR_SUCCESS) { dwSize /= sizeof(CHAR); - sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize); + sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize); } } else if (dwType == REG_EXPAND_SZ) { // The value is REG_EXPAND_SZ. Read it and expand environment variables. - std::unique_ptr szBuffer(new CHAR[dwSize / sizeof(CHAR)]); + std::unique_ptr szBuffer(new CHAR[dwSize / sizeof(CHAR) + 1]); if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { + dwSize /= sizeof(CHAR); + szBuffer[dwSize] = 0; if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0) lResult = ::GetLastError(); } @@ -519,15 +503,17 @@ static 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. - std::unique_ptr szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]); - if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { + sValue.resize(dwSize / sizeof(WCHAR) - 1); + if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast(&sValue[0]), &dwSize)) == ERROR_SUCCESS) { dwSize /= sizeof(WCHAR); - sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize); + sValue.resize(dwSize && sValue[dwSize - 1] == 0 ? dwSize - 1 : dwSize); } } else if (dwType == REG_EXPAND_SZ) { // The value is REG_EXPAND_SZ. Read it and expand environment variables. - std::unique_ptr szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]); + std::unique_ptr szBuffer(new WCHAR[dwSize / sizeof(WCHAR) + 1]); if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { + dwSize /= sizeof(WCHAR); + szBuffer[dwSize] = 0; if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0) lResult = ::GetLastError(); } @@ -623,8 +609,8 @@ static LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR pszValue, _O sOut.assign(szStackBuffer, wcsnlen(szStackBuffer, dwSize/sizeof(wchar_t))); } else if (lResult == ERROR_MORE_DATA) { // Allocate buffer on heap and retry. - std::unique_ptr 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); + sOut.resize((dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t) - 1); + sOut.resize((lResult = RegLoadMUIStringW(hKey, pszValue, &sOut[0], dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? wcsnlen(&sOut[0], dwSize/sizeof(wchar_t)) : 0); } return lResult; @@ -653,10 +639,10 @@ static _Success_(return > 0) int NormalizeString(_In_ NORM_FORM NormForm, _In_ L for (int i = 10; i--;) { // Allocate buffer. Then convert again. cch = -cch; - std::unique_ptr szBuffer(new WCHAR[cch]); - cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, szBuffer.get(), cch); + sDstString.resize((size_t)cch - 1); + cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, &sDstString[0], cch); if (cch > 0) { - sDstString.assign(szBuffer.get(), cwSrcLength != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1); + sDstString.resize(cwSrcLength != -1 ? wcsnlen(&sDstString[0], cch) : (size_t)cch - 1); break; } if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { @@ -696,12 +682,10 @@ static _Success_(return > 0) int NormalizeString(_In_ NORM_FORM NormForm, _In_ c for (int i = 10; i--;) { // Allocate buffer. Then convert again. cch = -cch; - std::unique_ptr szBuffer(new WCHAR[cch]); - cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), szBuffer.get(), cch); - if (cch > 0) { - sDstString.assign(szBuffer.get(), cch); + sDstString.resize(cch - 1); + cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), &sDstString[0], cch); + if (cch > 0) break; - } if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { sDstString.clear(); break; @@ -807,10 +791,8 @@ static _Success_(return != 0) int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dw int iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, NULL, 0); if (iResult) { // Allocate buffer on heap and retry. - std::unique_ptr szBuffer(new char[iResult]); - iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult); - sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0); - return iResult; + sDate.resize(iResult - 1); + return GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult); } return iResult; @@ -827,10 +809,8 @@ static _Success_(return != 0) int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dw int iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, NULL, 0); if (iResult) { // Allocate buffer on heap and retry. - std::unique_ptr szBuffer(new wchar_t[iResult]); - iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult); - sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0); - return iResult; + sDate.resize(iResult - 1); + return GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult); } return iResult; @@ -976,10 +956,10 @@ static _Success_(return != 0) BOOL QueryFullProcessImageNameA(_In_ HANDLE hProce } for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(char); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) { // Allocate on heap and retry. - std::unique_ptr szBuffer(new char[dwCapacity]); + sExeName.resize(dwCapacity - 1); dwSize = dwCapacity; - if (::QueryFullProcessImageNameA(hProcess, dwFlags, szBuffer.get(), &dwSize)) { - sExeName.assign(szBuffer.get(), dwSize); + if (::QueryFullProcessImageNameA(hProcess, dwFlags, &sExeName[0], &dwSize)) { + sExeName.resize(dwSize); return TRUE; } } @@ -1005,10 +985,10 @@ static _Success_(return != 0) BOOL QueryFullProcessImageNameW(_In_ HANDLE hProce } 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 szBuffer(new wchar_t[dwCapacity]); + sExeName.resize(dwCapacity - 1); dwSize = dwCapacity; - if (::QueryFullProcessImageNameW(hProcess, dwFlags, szBuffer.get(), &dwSize)) { - sExeName.assign(szBuffer.get(), dwSize); + if (::QueryFullProcessImageNameW(hProcess, dwFlags, &sExeName[0], &dwSize)) { + sExeName.resize(dwSize); return TRUE; } } @@ -2145,11 +2125,9 @@ _Success_(return != 0) BOOL GetThreadPreferredUILanguages(_In_ DWORD dwFlags, _O ulSize = 0; GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, NULL, &ulSize); // Allocate on heap and retry. - std::unique_ptr szBuffer(new WCHAR[ulSize]); - if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, szBuffer.get(), &ulSize)) { - sValue.assign(szBuffer.get(), ulSize - 1); + sValue.resize(ulSize - 1); + if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, &sValue[0], &ulSize)) return TRUE; - } } return FALSE; }