Write directly into std::string buffer

This removes extra memory allocation.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2024-01-05 20:39:28 +01:00
parent 49542a5f64
commit 9f5a68e789
7 changed files with 128 additions and 206 deletions

View File

@ -243,23 +243,6 @@ inline SIZE_T SIZETAdd(SIZE_T a, SIZE_T b)
/// \addtogroup WinStdStrFormat /// \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()`. /// 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)]; _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
// Try with stack buffer first. // Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf) - 1, format, arg); int count = vsnprintf(buf, _countof(buf), format, arg);
if (count >= 0) { if (0 <= count && count < _countof(buf)) {
// Copy from stack. // Copy from stack.
str.assign(buf, count); str.append(buf, count);
} else { return count;
for (size_t capacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; capacity *= 2) { }
// Allocate on heap and retry. if (count < 0) {
auto buf_dyn = std::make_unique<_Elem[]>(capacity); switch (errno) {
count = vsnprintf(buf_dyn.get(), capacity - 1, format, arg); case 0:
if (count >= 0) { count = vsnprintf(NULL, 0, format, arg);
str.assign(buf_dyn.get(), count); assert(count >= 0);
break; 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; return count;
} }
@ -346,9 +334,9 @@ static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ D
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]); sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1); sMultiByteStr.resize(cchWideChar != -1 ? strnlen(&sMultiByteStr[0], cch) : (size_t)cch - 1);
} }
return cch; return cch;
@ -399,9 +387,8 @@ static _Success_(return != 0) int WideCharToMultiByte(_In_ UINT CodePage, _In_ D
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]); sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cch);
} }
return cch; return cch;
@ -428,10 +415,9 @@ static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage,
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]); sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1); sMultiByteStr.resize(cchWideChar != -1 ? strnlen(&sMultiByteStr[0], cch) : (size_t)cch - 1);
SecureZeroMemory(szBuffer.get(), sizeof(CHAR) * cch);
} }
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
@ -490,10 +476,8 @@ static _Success_(return != 0) int SecureWideCharToMultiByte(_In_ UINT CodePage,
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar);
std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]); sMultiByteStr.resize(cch);
cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), &sMultiByteStr[0], cch, lpDefaultChar, lpUsedDefaultChar);
sMultiByteStr.assign(szBuffer.get(), cch);
SecureZeroMemory(szBuffer.get(), sizeof(CHAR) * cch);
} }
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); 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) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch); cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, &sWideCharStr[0], cch);
sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1); sWideCharStr.resize(cbMultiByte != -1 ? wcsnlen(&sWideCharStr[0], cch) : (size_t)cch - 1);
} }
return cch; return cch;
@ -573,9 +557,8 @@ static _Success_(return != 0) int MultiByteToWideChar(_In_ UINT CodePage, _In_ D
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0); cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch); cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), &sWideCharStr[0], cch);
sWideCharStr.assign(szBuffer.get(), cch);
} }
return cch; return cch;
@ -602,10 +585,9 @@ static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage,
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch); cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, &sWideCharStr[0], cch);
sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1); sWideCharStr.resize(cbMultiByte != -1 ? wcsnlen(&sWideCharStr[0], cch) : (size_t)cch - 1);
SecureZeroMemory(szBuffer.get(), sizeof(WCHAR) * cch);
} }
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));
@ -664,10 +646,8 @@ static _Success_(return != 0) int SecureMultiByteToWideChar(_In_ UINT CodePage,
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0); cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0);
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sWideCharStr.resize(cch);
cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch); cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), &sWideCharStr[0], cch);
sWideCharStr.assign(szBuffer.get(), cch);
SecureZeroMemory(szBuffer.get(), sizeof(WCHAR) * cch);
} }
SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer));

View File

@ -29,11 +29,9 @@ static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR ps
return TRUE; return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]); sProtectedCredentials.resize(dwSize - 1);
if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) { if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, &sProtectedCredentials[0], &dwSize, ProtectionType))
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
@ -57,11 +55,9 @@ static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR p
return TRUE; return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]); sProtectedCredentials.resize(dwSize - 1);
if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) { if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, &sProtectedCredentials[0], &dwSize, ProtectionType))
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
@ -81,11 +77,9 @@ static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR
return TRUE; return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]); sCredentials.resize(dwSize - 1);
if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) { if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, &sCredentials[0], &dwSize))
sCredentials.assign(buf.get(), dwSize);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
@ -109,11 +103,9 @@ static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR
return TRUE; return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]); sCredentials.resize(dwSize - 1);
if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) { if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, &sCredentials[0], &dwSize))
sCredentials.assign(buf.get(), dwSize);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;

View File

@ -26,10 +26,8 @@ static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[dwSize]); sNameString.resize(dwSize - 1);
dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize); return ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, &sNameString[0], dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
} }
/// ///
@ -44,10 +42,8 @@ static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]); sNameString.resize(dwSize - 1);
dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize); return ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, &sNameString[0], dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
} }
/// ///

View File

@ -34,10 +34,8 @@ static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inou
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it. // Allocate buffer on heap to read the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiGetPropertyA(hInstall, szName, szBuffer.get(), &dwSize); return ::MsiGetPropertyA(hInstall, szName, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -64,10 +62,8 @@ static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Ino
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it. // Allocate buffer on heap to read the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiGetPropertyW(hInstall, szName, szBuffer.get(), &dwSize); return ::MsiGetPropertyW(hInstall, szName, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -92,10 +88,8 @@ static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it. // Allocate buffer on heap to read the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiRecordGetStringA(hRecord, iField, szBuffer.get(), &dwSize); return ::MsiRecordGetStringA(hRecord, iField, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -122,10 +116,8 @@ static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to read the string data into and read it. // Allocate buffer on heap to read the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiRecordGetStringW(hRecord, iField, szBuffer.get(), &dwSize); return ::MsiRecordGetStringW(hRecord, iField, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -150,10 +142,8 @@ static UINT MsiFormatRecordA(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiFormatRecordA(hInstall, hRecord, szBuffer.get(), &dwSize); return ::MsiFormatRecordA(hInstall, hRecord, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -180,10 +170,8 @@ static UINT MsiFormatRecordW(_In_opt_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiFormatRecordW(hInstall, hRecord, szBuffer.get(), &dwSize); return ::MsiFormatRecordW(hInstall, hRecord, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -232,10 +220,8 @@ static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiGetTargetPathA(hInstall, szFolder, szBuffer.get(), &dwSize); return ::MsiGetTargetPathA(hInstall, szFolder, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -262,10 +248,8 @@ static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else if (uiResult == ERROR_MORE_DATA) { } else if (uiResult == ERROR_MORE_DATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++dwSize]); sValue.resize(dwSize++);
uiResult = ::MsiGetTargetPathW(hInstall, szFolder, szBuffer.get(), &dwSize); return ::MsiGetTargetPathW(hInstall, szFolder, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), uiResult == ERROR_SUCCESS ? dwSize : 0);
return uiResult;
} else { } else {
// Return error code. // Return error code.
return uiResult; return uiResult;
@ -288,10 +272,8 @@ static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR
return state; return state;
} else if (state == INSTALLSTATE_MOREDATA) { } else if (state == INSTALLSTATE_MOREDATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[++dwSize]); sValue.resize(dwSize++);
state = ::MsiGetComponentPathA(szProduct, szComponent, szBuffer.get(), &dwSize); return ::MsiGetComponentPathA(szProduct, szComponent, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), state >= INSTALLSTATE_BROKEN ? dwSize : 0);
return state;
} else { } else {
// Return error code. // Return error code.
return state; return state;
@ -318,10 +300,8 @@ static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWST
return state; return state;
} else if (state == INSTALLSTATE_MOREDATA) { } else if (state == INSTALLSTATE_MOREDATA) {
// Allocate buffer on heap to format the string data into and read it. // Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++dwSize]); sValue.resize(dwSize++);
state = ::MsiGetComponentPathW(szProduct, szComponent, szBuffer.get(), &dwSize); return ::MsiGetComponentPathW(szProduct, szComponent, &sValue[0], &dwSize);
sValue.assign(szBuffer.get(), state >= INSTALLSTATE_BROKEN ? dwSize : 0);
return state;
} else { } else {
// Return error code. // Return error code.
return state; return state;

View File

@ -34,11 +34,9 @@ static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std:
} }
if (::GetLastError() == ERROR_MORE_DATA) { if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry. // Allocate buffer on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[ulSize]); sName.resize(ulSize - 1);
if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) { if (::GetUserNameExA(NameFormat, &ulSize[0], &ulSize))
sName.assign(szBuffer.get(), ulSize);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
} }
@ -64,11 +62,9 @@ static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std:
} }
if (::GetLastError() == ERROR_MORE_DATA) { if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry. // Allocate buffer on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]); sName.resize(ulSize - 1);
if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) { if (::GetUserNameExW(NameFormat, &sName[0], &ulSize))
sName.assign(szBuffer.get(), ulSize);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
} }

View File

@ -43,15 +43,15 @@ static DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_
sSize = SIZETAdd(sSize, 1024); sSize = SIZETAdd(sSize, 1024);
if (sSize > DWORD_MAX) if (sSize > DWORD_MAX)
throw std::runtime_exception("Data too big"); throw std::runtime_exception("Data too big");
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[sSize]); sValue.resize(sSize - 1);
// Try! // Try!
DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, static_cast<DWORD>(sSize), szBuffer.get(), pReserved); DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, static_cast<DWORD>(sSize), &sValue[0], pReserved);
if (dwResult == ERROR_SUCCESS) { if (dwResult == ERROR_SUCCESS) {
SIZE_T sLength = wcsnlen(szBuffer.get(), sSize); SIZE_T sLength = wcsnlen(&sValue[0], sSize);
if (sLength < sSize - 1) { if (sLength < sSize - 1) {
// Buffer was long enough. // Buffer was long enough.
sValue.assign(szBuffer.get(), sLength); sValue.resize(sLength);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} else { } else {

View File

@ -38,10 +38,10 @@ static DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_strin
} else { } else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(char);; dwCapacity *= 2) { for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(char);; dwCapacity *= 2) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[dwCapacity]); sValue.resize(dwCapacity - 1);
dwResult = ::GetModuleFileNameA(hModule, szBuffer.get(), dwCapacity); dwResult = ::GetModuleFileNameA(hModule, &sValue[0], dwCapacity);
if (dwResult < dwCapacity) { if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), dwResult); sValue.resize(dwResult);
return dwResult; return dwResult;
} }
} }
@ -67,10 +67,10 @@ static DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_strin
} else { } else {
for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t);; dwCapacity *= 2) { for (DWORD dwCapacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t);; dwCapacity *= 2) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwCapacity]); sValue.resize(dwCapacity - 1);
dwResult = ::GetModuleFileNameW(hModule, szBuffer.get(), dwCapacity); dwResult = ::GetModuleFileNameW(hModule, &sValue[0], dwCapacity);
if (dwResult < dwCapacity) { if (dwResult < dwCapacity) {
sValue.assign(szBuffer.get(), dwResult); sValue.resize(dwResult);
return 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. // Query the final string length first.
iResult = ::GetWindowTextLengthA(hWnd); iResult = ::GetWindowTextLengthA(hWnd);
if (iResult > 0) { if (iResult > 0) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(char)) { // Allocate buffer on heap and read the string data into it.
// Read string data to stack. sValue.resize(iResult++);
char szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)]; return ::GetWindowTextA(hWnd, &sValue[0], iResult);
iResult = ::GetWindowTextA(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
std::unique_ptr<char[]> szBuffer(new char[++iResult]);
iResult = ::GetWindowTextA(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
return iResult;
} }
sValue.clear(); sValue.clear();
@ -121,18 +112,9 @@ static _Success_(return != 0) int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basi
// Query the final string length first. // Query the final string length first.
iResult = ::GetWindowTextLengthW(hWnd); iResult = ::GetWindowTextLengthW(hWnd);
if (iResult > 0) { if (iResult > 0) {
if (++iResult < WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)) { // Allocate buffer on heap and read the string data into it.
// Read string data to stack. sValue.resize(iResult++);
wchar_t szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)]; return ::GetWindowTextW(hWnd, &sValue[0], iResult);
iResult = ::GetWindowTextW(hWnd, szBuffer, _countof(szBuffer));
sValue.assign(szBuffer, iResult);
} else {
// Allocate buffer on heap and read the string data into it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[++iResult]);
iResult = ::GetWindowTextW(hWnd, szBuffer.get(), iResult);
sValue.assign(szBuffer.get(), iResult);
}
return iResult;
} }
sValue.clear(); sValue.clear();
@ -185,14 +167,14 @@ static _Success_(return != 0) DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSr
if (sSizeOut > DWORD_MAX) if (sSizeOut > DWORD_MAX)
throw std::invalid_argument("String too big"); throw std::invalid_argument("String too big");
DWORD dwSizeIn = static_cast<DWORD>(sSizeOut); DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
std::unique_ptr<char[]> szBuffer(new char[(size_t)dwSizeIn + 2]); // Note: ANSI version requires one extra char. sValue.resize((size_t)dwSizeIn + 1); // Note: ANSI version requires one extra char.
sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, szBuffer.get(), dwSizeIn); sSizeOut = ::ExpandEnvironmentStringsA(lpSrc, &sValue[0], dwSizeIn);
if (sSizeOut == 0) { if (sSizeOut == 0) {
// Error or zero-length input. // Error or zero-length input.
break; break;
} else if (sSizeOut <= dwSizeIn) { } else if (sSizeOut <= dwSizeIn) {
// The buffer was sufficient. // The buffer was sufficient.
sValue.assign(szBuffer.get(), sSizeOut - 1); sValue.resize(sSizeOut - 1);
return static_cast<DWORD>(sSizeOut); return static_cast<DWORD>(sSizeOut);
} }
} }
@ -213,14 +195,14 @@ static _Success_(return != 0) DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpS
if (sSizeOut > DWORD_MAX) if (sSizeOut > DWORD_MAX)
throw std::invalid_argument("String too big"); throw std::invalid_argument("String too big");
DWORD dwSizeIn = static_cast<DWORD>(sSizeOut); DWORD dwSizeIn = static_cast<DWORD>(sSizeOut);
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[(size_t)dwSizeIn + 1]); sValue.resize(dwSizeIn);
sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, szBuffer.get(), dwSizeIn); sSizeOut = ::ExpandEnvironmentStringsW(lpSrc, &sValue[0], dwSizeIn);
if (sSizeOut == 0) { if (sSizeOut == 0) {
// Error or zero-length input. // Error or zero-length input.
break; break;
} else if (sSizeOut <= dwSizeIn) { } else if (sSizeOut <= dwSizeIn) {
// The buffer was sufficient. // The buffer was sufficient.
sValue.assign(szBuffer.get(), sSizeOut - 1); sValue.resize(sSizeOut - 1);
return static_cast<DWORD>(sSizeOut); return static_cast<DWORD>(sSizeOut);
} }
} }
@ -455,15 +437,17 @@ static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
} else if (lResult == ERROR_MORE_DATA) { } else if (lResult == ERROR_MORE_DATA) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) { if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ. Read it now. // The value is REG_SZ or REG_MULTI_SZ. Read it now.
std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR)]); sValue.resize(dwSize / sizeof(CHAR) - 1);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(CHAR); 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) { } else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables. // The value is REG_EXPAND_SZ. Read it and expand environment variables.
std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR)]); std::unique_ptr<CHAR[]> szBuffer(new CHAR[dwSize / sizeof(CHAR) + 1]);
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(CHAR);
szBuffer[dwSize] = 0;
if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0) if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError(); lResult = ::GetLastError();
} }
@ -519,15 +503,17 @@ static LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
} else if (lResult == ERROR_MORE_DATA) { } else if (lResult == ERROR_MORE_DATA) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) { if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
// The value is REG_SZ or REG_MULTI_SZ. Read it now. // The value is REG_SZ or REG_MULTI_SZ. Read it now.
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]); sValue.resize(dwSize / sizeof(WCHAR) - 1);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(&sValue[0]), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(WCHAR); 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) { } else if (dwType == REG_EXPAND_SZ) {
// The value is REG_EXPAND_SZ. Read it and expand environment variables. // The value is REG_EXPAND_SZ. Read it and expand environment variables.
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]); std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[dwSize / sizeof(WCHAR) + 1]);
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast<LPBYTE>(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) {
dwSize /= sizeof(WCHAR);
szBuffer[dwSize] = 0;
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0) if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
lResult = ::GetLastError(); 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))); sOut.assign(szStackBuffer, wcsnlen(szStackBuffer, dwSize/sizeof(wchar_t)));
} else if (lResult == ERROR_MORE_DATA) { } else if (lResult == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry. // Allocate buffer on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[(dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t)]); sOut.resize((dwSize + sizeof(wchar_t) - 1)/sizeof(wchar_t) - 1);
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((lResult = RegLoadMUIStringW(hKey, pszValue, &sOut[0], dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? wcsnlen(&sOut[0], dwSize/sizeof(wchar_t)) : 0);
} }
return lResult; return lResult;
@ -653,10 +639,10 @@ static _Success_(return > 0) int NormalizeString(_In_ NORM_FORM NormForm, _In_ L
for (int i = 10; i--;) { for (int i = 10; i--;) {
// Allocate buffer. Then convert again. // Allocate buffer. Then convert again.
cch = -cch; cch = -cch;
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sDstString.resize((size_t)cch - 1);
cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, szBuffer.get(), cch); cch = ::NormalizeString(NormForm, lpSrcString, cwSrcLength, &sDstString[0], cch);
if (cch > 0) { 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; break;
} }
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 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--;) { for (int i = 10; i--;) {
// Allocate buffer. Then convert again. // Allocate buffer. Then convert again.
cch = -cch; cch = -cch;
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]); sDstString.resize(cch - 1);
cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), szBuffer.get(), cch); cch = ::NormalizeString(NormForm, sSrcString.c_str(), (int)sSrcString.length(), &sDstString[0], cch);
if (cch > 0) { if (cch > 0)
sDstString.assign(szBuffer.get(), cch);
break; break;
}
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
sDstString.clear(); sDstString.clear();
break; 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); int iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
if (iResult) { if (iResult) {
// Allocate buffer on heap and retry. // Allocate buffer on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[iResult]); sDate.resize(iResult - 1);
iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult); return GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0);
return iResult;
} }
return 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); int iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, NULL, 0);
if (iResult) { if (iResult) {
// Allocate buffer on heap and retry. // Allocate buffer on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[iResult]); sDate.resize(iResult - 1);
iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, szBuffer.get(), iResult); return GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, &sDate[0], iResult);
sDate.assign(szBuffer.get(), iResult ? iResult - 1 : 0);
return iResult;
} }
return 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) { for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(char); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[dwCapacity]); sExeName.resize(dwCapacity - 1);
dwSize = dwCapacity; dwSize = dwCapacity;
if (::QueryFullProcessImageNameA(hProcess, dwFlags, szBuffer.get(), &dwSize)) { if (::QueryFullProcessImageNameA(hProcess, dwFlags, &sExeName[0], &dwSize)) {
sExeName.assign(szBuffer.get(), dwSize); sExeName.resize(dwSize);
return TRUE; 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) { for (DWORD dwCapacity = 2 * WINSTD_STACK_BUFFER_BYTES / sizeof(wchar_t); GetLastError() == ERROR_INSUFFICIENT_BUFFER; dwCapacity *= 2) {
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwCapacity]); sExeName.resize(dwCapacity - 1);
dwSize = dwCapacity; dwSize = dwCapacity;
if (::QueryFullProcessImageNameW(hProcess, dwFlags, szBuffer.get(), &dwSize)) { if (::QueryFullProcessImageNameW(hProcess, dwFlags, &sExeName[0], &dwSize)) {
sExeName.assign(szBuffer.get(), dwSize); sExeName.resize(dwSize);
return TRUE; return TRUE;
} }
} }
@ -2145,11 +2125,9 @@ _Success_(return != 0) BOOL GetThreadPreferredUILanguages(_In_ DWORD dwFlags, _O
ulSize = 0; ulSize = 0;
GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, NULL, &ulSize); GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, NULL, &ulSize);
// Allocate on heap and retry. // Allocate on heap and retry.
std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[ulSize]); sValue.resize(ulSize - 1);
if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, szBuffer.get(), &ulSize)) { if (GetThreadPreferredUILanguages(dwFlags, pulNumLanguages, &sValue[0], &ulSize))
sValue.assign(szBuffer.get(), ulSize - 1);
return TRUE; return TRUE;
}
} }
return FALSE; return FALSE;
} }