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. 132
      src/Parser/VSLookup.cpp

2
src/Parser/Parser.cpp

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

132
src/Parser/VSLookup.cpp

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
#include <string>
#include <vector>
#include <cctype>
// Include the necessary headers to interface with the Windows registry and
// environment.
@ -17,17 +18,24 @@ @@ -17,17 +18,24 @@
#define NOMINMAX
#include <Windows.h>
// 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;
DWORD valueSize = maxLength - 1;
long lResult;
bool returnValue = false;
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;
@ -43,56 +51,32 @@ struct MSVCRegLookup { @@ -43,56 +51,32 @@ struct MSVCRegLookup {
} else {
return false;
}
return true;
}
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;
lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
if (lResult == ERROR_SUCCESS) {
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++) {
@ -107,66 +91,42 @@ struct MSVCRegLookup { @@ -107,66 +91,42 @@ struct MSVCRegLookup {
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) {
double value = strtod(numBuf, NULL);
if (value > bestValue) {
bestIndex = (int)index;
bestValue = versionValue;
bestValue = value;
strcpy(bestName, keyName);
}
RegCloseKey(hKey);
}
}
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.
Res = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey);
if (Res == ERROR_SUCCESS) {
Res = RegQueryValueExA(hKey, valueName, NULL, &valueType,
lResult = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey);
if (lResult == ERROR_SUCCESS) {
lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
(LPBYTE)value, &valueSize);
if (Res == ERROR_SUCCESS)
Ret = true;
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);
} 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);
}
}
return returnValue;
}
/// \brief Get Windows SDK installation directory.

Loading…
Cancel
Save