Should first determine the required buffer length, then allocate the buffer as needed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
std::string get_system_directory(void)
{
std::string result;
const UINT len = GetSystemDirectoryA(NULL, 0U);
if (len > 0)
{
std::vector<CHAR> buffer(len);
const UINT ret = GetSystemDirectoryA(buffer.data(), len);
if ((ret > 0) && (ret < len))
{
result = std::string(buffer.data(), ret);
}
}
return result;
}
| |
Note: If
GetSystemDirectoryA()
returns a value
greater than uSize, then the function has failed because of insufficient buffer size, and it tells you the required buffer size,
including the terminating NULL character.
So, you can call the function with
uSize set to
0 to determine the required buffer size.
(BTW: In case of success, the return value will always be
smaller than the given
uSize, because in that case the return value does
not include the terminating NULL character!)
________
SHGetKnownFolderPath
only has a
wide-string version. And you
should be working with
wide-strings anyway, if you are dealing with paths on the Windows platform – because NTFS is fully Unicode-aware, and therefore an ANSI-string can
not represent all possible file/path names that may exist on an NTFS volume!
1 2 3 4 5 6 7 8 9 10 11
|
std::wstring get_known_folder_path(const GUID &folder_id)
{
std::wstring result;
WCHAR *buffer;
if (SHGetKnownFolderPath(folder_id, KF_FLAG_DEFAULT, NULL, &buffer) == S_OK)
{
result = std::wstring(buffer);
CoTaskMemFree(buffer);
}
return result;
}
| |
If you
really want to, you can
convert the wide string into an ANSI-string, but this will get you into troubles if the
wide-string path contains characters that can not be represented in the user's local ANSI codepage!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
std::string wstring_to_string(const std::wstring& wide_string)
{
const wchar_t *wstr = wide_string.c_str();
size_t len;
mbstate_t state;
memset(&state, 0, sizeof state);
if (wcsrtombs_s(&len, NULL, 0, &wstr, _TRUNCATE, &state) == 0)
{
std::vector<char> buffer(len);
if (wcsrtombs_s(&len, buffer.data(), buffer.size(), &wstr, _TRUNCATE, &state) == 0)
{
return std::string(buffer.data());
}
}
return std::string();
}
| |