summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2016-06-23 14:33:53 +0000
committerAaron Ballman <aaron@aaronballman.com>2016-06-23 14:33:53 +0000
commitd50bbd28750fdacc54a56b807bb0c513e19c02a6 (patch)
treefa5b9445452b468f4be042852315a559fe512ca9
parentb26c917a04e5f34f92a1a16378ab41de273a4348 (diff)
Fixing a FIXME related to Unicode support on Windows. Converted the Win32 APIs to explicitly use the W version when it involves strings that can hold non-ASCII characters (like file paths). Now explicitly using the A version for strings that will always be ASCII (like registry key paths).
No extra tests required as this is currently covered by existing testing, and this is basically impossible to write Unicode-specific tests for. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273563 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Driver/MSVCToolChain.cpp45
1 files changed, 27 insertions, 18 deletions
diff --git a/lib/Driver/MSVCToolChain.cpp b/lib/Driver/MSVCToolChain.cpp
index 567c7e31d3..b8de5ad491 100644
--- a/lib/Driver/MSVCToolChain.cpp
+++ b/lib/Driver/MSVCToolChain.cpp
@@ -95,23 +95,31 @@ bool MSVCToolChain::isPICDefaultForced() const {
#ifdef USE_WIN32
static bool readFullStringValue(HKEY hkey, const char *valueName,
std::string &value) {
- // FIXME: We should be using the W versions of the registry functions, but
- // doing so requires UTF8 / UTF16 conversions similar to how we handle command
- // line arguments. The UTF8 conversion functions are not exposed publicly
- // from LLVM though, so in order to do this we will probably need to create
- // a registry abstraction in LLVMSupport that is Windows only.
+ std::wstring WideValueName;
+ if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
+ return false;
+
DWORD result = 0;
DWORD valueSize = 0;
DWORD type = 0;
// First just query for the required size.
- result = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize);
- if (result != ERROR_SUCCESS || type != REG_SZ)
+ result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
+ &valueSize);
+ if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
return false;
std::vector<BYTE> buffer(valueSize);
- result = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize);
- if (result == ERROR_SUCCESS)
- value.assign(reinterpret_cast<const char *>(buffer.data()));
- return result;
+ result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
+ &valueSize);
+ if (result == ERROR_SUCCESS) {
+ std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
+ valueSize / sizeof(wchar_t));
+ // The destination buffer must be empty as an invariant of the conversion
+ // function; but this function is sometimes called in a loop that passes in
+ // the same buffer, however. Simply clear it out so we can overwrite it.
+ value.clear();
+ return llvm::convertWideToUTF8(WideValue, value);
+ }
+ return false;
}
#endif
@@ -152,14 +160,15 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
strncpy(partialKey, keyPath, partialKeyLength);
partialKey[partialKeyLength] = '\0';
HKEY hTopKey = NULL;
- lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
- &hTopKey);
+ lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
+ &hTopKey);
if (lResult == ERROR_SUCCESS) {
char keyName[256];
double bestValue = 0.0;
DWORD index, size = sizeof(keyName) - 1;
- for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
- NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
+ for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
+ NULL, NULL) == ERROR_SUCCESS;
+ index++) {
const char *sp = keyName;
while (*sp && !isDigit(*sp))
sp++;
@@ -178,8 +187,8 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
bestName = keyName;
// Append rest of key.
bestName.append(nextKey);
- lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0,
- KEY_READ | KEY_WOW64_32KEY, &hKey);
+ lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
+ KEY_READ | KEY_WOW64_32KEY, &hKey);
if (lResult == ERROR_SUCCESS) {
lResult = readFullStringValue(hKey, valueName, value);
if (lResult == ERROR_SUCCESS) {
@@ -197,7 +206,7 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
}
} else {
lResult =
- RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
+ RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
if (lResult == ERROR_SUCCESS) {
lResult = readFullStringValue(hKey, valueName, value);
if (lResult == ERROR_SUCCESS)