diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 1d06aa0f..6bf387ec 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -121,7 +121,7 @@ void Parser::Setup(ParserOptions^ Opts) clang::frontend::System, false, false); #ifdef _MSC_VER - std::vector SystemDirs = clang::driver::GetWindowsSystemIncludeDirs(); + std::vector SystemDirs = GetWindowsSystemIncludeDirs(); clang::HeaderSearchOptions& HSOpts = C->getHeaderSearchOpts(); for(size_t i = 0; i < SystemDirs.size(); ++i) diff --git a/src/Parser/VSLookup.cpp b/src/Parser/VSLookup.cpp index 2020b175..50a1bb53 100644 --- a/src/Parser/VSLookup.cpp +++ b/src/Parser/VSLookup.cpp @@ -9,6 +9,7 @@ #include #include +#include // Include the necessary headers to interface with the Windows registry and // environment. @@ -17,156 +18,115 @@ #define NOMINMAX #include -// Has all the registry lookup related code -struct MSVCRegLookup { - HKEY hRootKey; - HKEY hKey; - const char* subKey; +/// \brief Read registry string. +/// This also supports a means to look for high-versioned keys by use +/// of a $VERSION placeholder in the key path. +/// $VERSION in the key path is a placeholder for the version number, +/// causing the highest value path to be searched for and used. +/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION". +/// There can be additional characters in the component. Only the numeric +/// characters are compared. +static bool getSystemRegistryString(const char *keyPath, const char *valueName, + char *value, size_t maxLength) { + HKEY hRootKey = NULL; + HKEY hKey = NULL; + const char* subKey = NULL; DWORD valueType; - - MSVCRegLookup() - : hRootKey(NULL), hKey(NULL), subKey(NULL), valueType(0) { } - - bool InitializeRootKey(const char *keyPath) { - if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) { - hRootKey = HKEY_CLASSES_ROOT; - subKey = keyPath + 18; - } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) { - hRootKey = HKEY_USERS; - subKey = keyPath + 11; - } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) { - hRootKey = HKEY_LOCAL_MACHINE; - subKey = keyPath + 19; - } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) { - hRootKey = HKEY_CURRENT_USER; - subKey = keyPath + 18; - } else { - return false; - } - return true; + DWORD valueSize = maxLength - 1; + long lResult; + bool returnValue = false; + + if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) { + hRootKey = HKEY_CLASSES_ROOT; + subKey = keyPath + 18; + } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) { + hRootKey = HKEY_USERS; + subKey = keyPath + 11; + } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) { + hRootKey = HKEY_LOCAL_MACHINE; + subKey = keyPath + 19; + } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) { + hRootKey = HKEY_CURRENT_USER; + subKey = keyPath + 18; + } else { + return false; } - bool FindSimpleKeyValue(const char *valueName, char *value, DWORD valueSize) { - bool Ret = false; - long Res = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey); - if (Res == ERROR_SUCCESS) { - Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, - (LPBYTE)value, &valueSize); - if (Res == ERROR_SUCCESS) - Ret = true; - RegCloseKey(hKey); - } - return Ret; - } - - bool FindBestVersionKeyValue(const char* versionIndex, - const char *valueName, char *value, DWORD valueSize) { - bool Ret = false; - const char *keyEnd = versionIndex - 1; - const char *nextKey = versionIndex; - + const char *placeHolder = strstr(subKey, "$VERSION"); + char bestName[256]; + bestName[0] = '\0'; + // If we have a $VERSION placeholder, do the highest-version search. + if (placeHolder) { + const char *keyEnd = placeHolder - 1; + const char *nextKey = placeHolder; // Find end of previous key. while ((keyEnd > subKey) && (*keyEnd != '\\')) keyEnd--; - // Find end of key containing $VERSION. while (*nextKey && (*nextKey != '\\')) nextKey++; - size_t partialKeyLength = keyEnd - subKey; char partialKey[256]; if (partialKeyLength > sizeof(partialKey)) partialKeyLength = sizeof(partialKey); strncpy(partialKey, subKey, partialKeyLength); partialKey[partialKeyLength] = '\0'; - HKEY hTopKey = NULL; - long Res = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey); - - if (Res != ERROR_SUCCESS) - return false; - - char keyName[256]; - int bestIndex = -1; - char bestName[256]; - bestName[0] = '\0'; - double bestValue = 0.0; - - // Find the highest versioned key. - DWORD index, size = sizeof(keyName) - 1; - for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, - NULL, NULL, NULL) == ERROR_SUCCESS; index++) { - const char *sp = keyName; - while (*sp && !isdigit(*sp)) - sp++; - if (!*sp) - continue; - const char *ep = sp + 1; - while (*ep && (isdigit(*ep) || (*ep == '.'))) - ep++; - char numBuf[32]; - strncpy(numBuf, sp, sizeof(numBuf) - 1); - numBuf[sizeof(numBuf) - 1] = '\0'; - - double versionValue = strtod(numBuf, NULL); - if (versionValue > bestValue) { - // Better values are only better if the desired key exists for them. - std::string candidate = std::string(keyName) + nextKey; - Res = RegOpenKeyExA(hTopKey, candidate.c_str(), 0, KEY_READ, &hKey); - if (Res == ERROR_SUCCESS) { - Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, - (LPBYTE)value, &valueSize); - if (Res == ERROR_SUCCESS) { - bestIndex = (int)index; - bestValue = versionValue; - strcpy(bestName, keyName); - } + lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey); + if (lResult == ERROR_SUCCESS) { + char keyName[256]; + int bestIndex = -1; + double bestValue = 0.0; + DWORD index, size = sizeof(keyName) - 1; + for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, + NULL, NULL, NULL) == ERROR_SUCCESS; index++) { + const char *sp = keyName; + while (*sp && !isdigit(*sp)) + sp++; + if (!*sp) + continue; + const char *ep = sp + 1; + while (*ep && (isdigit(*ep) || (*ep == '.'))) + ep++; + char numBuf[32]; + strncpy(numBuf, sp, sizeof(numBuf) - 1); + numBuf[sizeof(numBuf) - 1] = '\0'; + double value = strtod(numBuf, NULL); + if (value > bestValue) { + bestIndex = (int)index; + bestValue = value; + strcpy(bestName, keyName); + } + size = sizeof(keyName) - 1; + } + // If we found the highest versioned key, open the key and get the value. + if (bestIndex != -1) { + // Append rest of key. + strncat(bestName, nextKey, sizeof(bestName) - 1); + bestName[sizeof(bestName) - 1] = '\0'; + // Open the chosen key path remainder. + lResult = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey); + if (lResult == ERROR_SUCCESS) { + lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType, + (LPBYTE)value, &valueSize); + if (lResult == ERROR_SUCCESS) + returnValue = true; RegCloseKey(hKey); } } + RegCloseKey(hTopKey); } - - // If we found the highest versioned key, open the key and get the value. - if (bestIndex != -1) { - // Append rest of key. - strncat(bestName, nextKey, sizeof(bestName) - 1); - bestName[sizeof(bestName) - 1] = '\0'; - // Open the chosen key path remainder. - Res = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey); - if (Res == ERROR_SUCCESS) { - Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, - (LPBYTE)value, &valueSize); - if (Res == ERROR_SUCCESS) - Ret = true; - RegCloseKey(hKey); - } + } else { + lResult = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey); + if (lResult == ERROR_SUCCESS) { + lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType, + (LPBYTE)value, &valueSize); + if (lResult == ERROR_SUCCESS) + returnValue = true; + RegCloseKey(hKey); } - RegCloseKey(hTopKey); - return Ret; } -}; - -/// \brief Read registry string. -/// This also supports a means to look for high-versioned keys by use -/// of a $VERSION placeholder in the key path. -/// $VERSION in the key path is a placeholder for the version number, -/// causing the highest value path to be searched for and used. -/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION". -/// There can be additional characters in the component. Only the numeric -/// characters are compared. -static bool getSystemRegistryString(const char *keyPath, const char *valueName, - char *value, size_t maxLength) { - MSVCRegLookup Reg; - if (!Reg.InitializeRootKey(keyPath)) - return false; - - const char* versionIndex = strstr(Reg.subKey, "$VERSION"); - // If we have a $VERSION placeholder, do the highest-version search. - if (versionIndex) - return Reg.FindBestVersionKeyValue(versionIndex, valueName, - value, maxLength-1); - else - return Reg.FindSimpleKeyValue(valueName, value, maxLength-1); + return returnValue; } /// \brief Get Windows SDK installation directory.