Browse Source

Actually commit working registry lookup code...

pull/1/head
triton 12 years ago
parent
commit
79eef3e725
  1. 2
      src/Parser/Parser.cpp
  2. 216
      src/Parser/VSLookup.cpp

2
src/Parser/Parser.cpp

@ -121,7 +121,7 @@ void Parser::Setup(ParserOptions^ Opts)
clang::frontend::System, false, false); clang::frontend::System, false, false);
#ifdef _MSC_VER #ifdef _MSC_VER
std::vector<std::string> SystemDirs = clang::driver::GetWindowsSystemIncludeDirs(); std::vector<std::string> SystemDirs = GetWindowsSystemIncludeDirs();
clang::HeaderSearchOptions& HSOpts = C->getHeaderSearchOpts(); clang::HeaderSearchOptions& HSOpts = C->getHeaderSearchOpts();
for(size_t i = 0; i < SystemDirs.size(); ++i) for(size_t i = 0; i < SystemDirs.size(); ++i)

216
src/Parser/VSLookup.cpp

@ -9,6 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <cctype>
// Include the necessary headers to interface with the Windows registry and // Include the necessary headers to interface with the Windows registry and
// environment. // environment.
@ -17,156 +18,115 @@
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
// Has all the registry lookup related code /// \brief Read registry string.
struct MSVCRegLookup { /// This also supports a means to look for high-versioned keys by use
HKEY hRootKey; /// of a $VERSION placeholder in the key path.
HKEY hKey; /// $VERSION in the key path is a placeholder for the version number,
const char* subKey; /// 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; DWORD valueType;
DWORD valueSize = maxLength - 1;
MSVCRegLookup() long lResult;
: hRootKey(NULL), hKey(NULL), subKey(NULL), valueType(0) { } bool returnValue = false;
bool InitializeRootKey(const char *keyPath) { if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) { hRootKey = HKEY_CLASSES_ROOT;
hRootKey = HKEY_CLASSES_ROOT; subKey = keyPath + 18;
subKey = keyPath + 18; } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
} else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) { hRootKey = HKEY_USERS;
hRootKey = HKEY_USERS; subKey = keyPath + 11;
subKey = keyPath + 11; } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
} else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) { hRootKey = HKEY_LOCAL_MACHINE;
hRootKey = HKEY_LOCAL_MACHINE; subKey = keyPath + 19;
subKey = keyPath + 19; } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
} else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) { hRootKey = HKEY_CURRENT_USER;
hRootKey = HKEY_CURRENT_USER; subKey = keyPath + 18;
subKey = keyPath + 18; } else {
} else { return false;
return false;
}
return true;
} }
bool FindSimpleKeyValue(const char *valueName, char *value, DWORD valueSize) { const char *placeHolder = strstr(subKey, "$VERSION");
bool Ret = false; char bestName[256];
long Res = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey); bestName[0] = '\0';
if (Res == ERROR_SUCCESS) { // If we have a $VERSION placeholder, do the highest-version search.
Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, if (placeHolder) {
(LPBYTE)value, &valueSize); const char *keyEnd = placeHolder - 1;
if (Res == ERROR_SUCCESS) const char *nextKey = placeHolder;
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;
// Find end of previous key. // Find end of previous key.
while ((keyEnd > subKey) && (*keyEnd != '\\')) while ((keyEnd > subKey) && (*keyEnd != '\\'))
keyEnd--; keyEnd--;
// Find end of key containing $VERSION. // Find end of key containing $VERSION.
while (*nextKey && (*nextKey != '\\')) while (*nextKey && (*nextKey != '\\'))
nextKey++; nextKey++;
size_t partialKeyLength = keyEnd - subKey; size_t partialKeyLength = keyEnd - subKey;
char partialKey[256]; char partialKey[256];
if (partialKeyLength > sizeof(partialKey)) if (partialKeyLength > sizeof(partialKey))
partialKeyLength = sizeof(partialKey); partialKeyLength = sizeof(partialKey);
strncpy(partialKey, subKey, partialKeyLength); strncpy(partialKey, subKey, partialKeyLength);
partialKey[partialKeyLength] = '\0'; partialKey[partialKeyLength] = '\0';
HKEY hTopKey = NULL; HKEY hTopKey = NULL;
long Res = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey); lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
if (lResult == ERROR_SUCCESS) {
if (Res != ERROR_SUCCESS) char keyName[256];
return false; int bestIndex = -1;
double bestValue = 0.0;
char keyName[256]; DWORD index, size = sizeof(keyName) - 1;
int bestIndex = -1; for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL,
char bestName[256]; NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
bestName[0] = '\0'; const char *sp = keyName;
double bestValue = 0.0; while (*sp && !isdigit(*sp))
sp++;
// Find the highest versioned key. if (!*sp)
DWORD index, size = sizeof(keyName) - 1; continue;
for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, const char *ep = sp + 1;
NULL, NULL, NULL) == ERROR_SUCCESS; index++) { while (*ep && (isdigit(*ep) || (*ep == '.')))
const char *sp = keyName; ep++;
while (*sp && !isdigit(*sp)) char numBuf[32];
sp++; strncpy(numBuf, sp, sizeof(numBuf) - 1);
if (!*sp) numBuf[sizeof(numBuf) - 1] = '\0';
continue; double value = strtod(numBuf, NULL);
const char *ep = sp + 1; if (value > bestValue) {
while (*ep && (isdigit(*ep) || (*ep == '.'))) bestIndex = (int)index;
ep++; bestValue = value;
char numBuf[32]; strcpy(bestName, keyName);
strncpy(numBuf, sp, sizeof(numBuf) - 1); }
numBuf[sizeof(numBuf) - 1] = '\0'; size = sizeof(keyName) - 1;
}
double versionValue = strtod(numBuf, NULL); // If we found the highest versioned key, open the key and get the value.
if (versionValue > bestValue) { if (bestIndex != -1) {
// Better values are only better if the desired key exists for them. // Append rest of key.
std::string candidate = std::string(keyName) + nextKey; strncat(bestName, nextKey, sizeof(bestName) - 1);
Res = RegOpenKeyExA(hTopKey, candidate.c_str(), 0, KEY_READ, &hKey); bestName[sizeof(bestName) - 1] = '\0';
if (Res == ERROR_SUCCESS) { // Open the chosen key path remainder.
Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, lResult = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey);
(LPBYTE)value, &valueSize); if (lResult == ERROR_SUCCESS) {
if (Res == ERROR_SUCCESS) { lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
bestIndex = (int)index; (LPBYTE)value, &valueSize);
bestValue = versionValue; if (lResult == ERROR_SUCCESS)
strcpy(bestName, keyName); returnValue = true;
}
RegCloseKey(hKey); RegCloseKey(hKey);
} }
} }
RegCloseKey(hTopKey);
} }
} else {
// If we found the highest versioned key, open the key and get the value. lResult = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey);
if (bestIndex != -1) { if (lResult == ERROR_SUCCESS) {
// Append rest of key. lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
strncat(bestName, nextKey, sizeof(bestName) - 1); (LPBYTE)value, &valueSize);
bestName[sizeof(bestName) - 1] = '\0'; if (lResult == ERROR_SUCCESS)
// Open the chosen key path remainder. returnValue = true;
Res = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey); RegCloseKey(hKey);
if (Res == ERROR_SUCCESS) {
Res = RegQueryValueExA(hKey, valueName, NULL, &valueType,
(LPBYTE)value, &valueSize);
if (Res == ERROR_SUCCESS)
Ret = true;
RegCloseKey(hKey);
}
} }
RegCloseKey(hTopKey);
return Ret;
} }
}; return returnValue;
/// \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);
} }
/// \brief Get Windows SDK installation directory. /// \brief Get Windows SDK installation directory.

Loading…
Cancel
Save