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)
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)

132
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,17 +18,24 @@
#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;
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) { if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
hRootKey = HKEY_CLASSES_ROOT; hRootKey = HKEY_CLASSES_ROOT;
subKey = keyPath + 18; subKey = keyPath + 18;
@ -43,56 +51,32 @@ struct MSVCRegLookup {
} else { } else {
return false; 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. // 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)
return false;
char keyName[256]; char keyName[256];
int bestIndex = -1; int bestIndex = -1;
char bestName[256];
bestName[0] = '\0';
double bestValue = 0.0; double bestValue = 0.0;
// Find the highest versioned key.
DWORD index, size = sizeof(keyName) - 1; DWORD index, size = sizeof(keyName) - 1;
for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL,
NULL, NULL, NULL) == ERROR_SUCCESS; index++) { NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
@ -107,66 +91,42 @@ struct MSVCRegLookup {
char numBuf[32]; char numBuf[32];
strncpy(numBuf, sp, sizeof(numBuf) - 1); strncpy(numBuf, sp, sizeof(numBuf) - 1);
numBuf[sizeof(numBuf) - 1] = '\0'; numBuf[sizeof(numBuf) - 1] = '\0';
double value = strtod(numBuf, NULL);
double versionValue = strtod(numBuf, NULL); if (value > bestValue) {
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; bestIndex = (int)index;
bestValue = versionValue; bestValue = value;
strcpy(bestName, keyName); strcpy(bestName, keyName);
} }
RegCloseKey(hKey); size = sizeof(keyName) - 1;
}
}
} }
// If we found the highest versioned key, open the key and get the value. // If we found the highest versioned key, open the key and get the value.
if (bestIndex != -1) { if (bestIndex != -1) {
// Append rest of key. // Append rest of key.
strncat(bestName, nextKey, sizeof(bestName) - 1); strncat(bestName, nextKey, sizeof(bestName) - 1);
bestName[sizeof(bestName) - 1] = '\0'; bestName[sizeof(bestName) - 1] = '\0';
// Open the chosen key path remainder. // Open the chosen key path remainder.
Res = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey); lResult = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey);
if (Res == ERROR_SUCCESS) { if (lResult == ERROR_SUCCESS) {
Res = RegQueryValueExA(hKey, valueName, NULL, &valueType, lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
(LPBYTE)value, &valueSize); (LPBYTE)value, &valueSize);
if (Res == ERROR_SUCCESS) if (lResult == ERROR_SUCCESS)
Ret = true; returnValue = true;
RegCloseKey(hKey); RegCloseKey(hKey);
} }
} }
RegCloseKey(hTopKey); RegCloseKey(hTopKey);
return Ret;
} }
}; } else {
lResult = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey);
/// \brief Read registry string. if (lResult == ERROR_SUCCESS) {
/// This also supports a means to look for high-versioned keys by use lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
/// of a $VERSION placeholder in the key path. (LPBYTE)value, &valueSize);
/// $VERSION in the key path is a placeholder for the version number, if (lResult == ERROR_SUCCESS)
/// causing the highest value path to be searched for and used. returnValue = true;
/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION". RegCloseKey(hKey);
/// There can be additional characters in the component. Only the numeric }
/// characters are compared. }
static bool getSystemRegistryString(const char *keyPath, const char *valueName, return returnValue;
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