forked from qt-creator/qt-creator
qtcdebugger: Register as post-mortem debugger for 64bit applications as well.
Add mode argument to registry access helpers allowing to access the 64bit registry from 32bit applications and vice versa using special REGSAM values, similar to the new QSettings formats introduced in Qt 5.7. This allows for setting the 64bit post-mortem debugger when running as a 32bit application on 64bit Windows. The -wow argument is extended to indicate accessing the 64bit node from 32bit. Task-number: QTCREATORBUG-16386 Change-Id: I7f003673777e4b8c1b259ba1905a4207b4ce0b43 Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -98,6 +98,7 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
|
|||||||
const WCHAR *key,
|
const WCHAR *key,
|
||||||
bool readWrite,
|
bool readWrite,
|
||||||
HKEY *keyHandle,
|
HKEY *keyHandle,
|
||||||
|
AccessMode mode,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
Q_UNUSED(debuggerRegistryKeyC); // avoid warning from MinGW
|
Q_UNUSED(debuggerRegistryKeyC); // avoid warning from MinGW
|
||||||
@@ -105,6 +106,16 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
|
|||||||
REGSAM accessRights = KEY_READ;
|
REGSAM accessRights = KEY_READ;
|
||||||
if (readWrite)
|
if (readWrite)
|
||||||
accessRights |= KEY_SET_VALUE;
|
accessRights |= KEY_SET_VALUE;
|
||||||
|
switch (mode) {
|
||||||
|
case RegistryAccess::DefaultAccessMode:
|
||||||
|
break;
|
||||||
|
case RegistryAccess::Registry32Mode:
|
||||||
|
accessRights |= KEY_WOW64_32KEY;
|
||||||
|
break;
|
||||||
|
case RegistryAccess::Registry64Mode:
|
||||||
|
accessRights |= KEY_WOW64_64KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
const LONG rc = RegOpenKeyEx(category, key, 0, accessRights, keyHandle);
|
const LONG rc = RegOpenKeyEx(category, key, 0, accessRights, keyHandle);
|
||||||
if (rc != ERROR_SUCCESS) {
|
if (rc != ERROR_SUCCESS) {
|
||||||
*errorMessage = msgFunctionFailed("RegOpenKeyEx", rc);
|
*errorMessage = msgFunctionFailed("RegOpenKeyEx", rc);
|
||||||
|
|||||||
@@ -37,6 +37,12 @@
|
|||||||
|
|
||||||
namespace RegistryAccess {
|
namespace RegistryAccess {
|
||||||
|
|
||||||
|
enum AccessMode {
|
||||||
|
DefaultAccessMode,
|
||||||
|
Registry32Mode = 0x2, // Corresponds to QSettings::Registry32Format (5.7)
|
||||||
|
Registry64Mode = 0x4 // Corresponds to QSettings::Registry64Format (5.7)
|
||||||
|
};
|
||||||
|
|
||||||
static const char *debuggerApplicationFileC = "qtcdebugger";
|
static const char *debuggerApplicationFileC = "qtcdebugger";
|
||||||
static const WCHAR *debuggerRegistryKeyC = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
|
static const WCHAR *debuggerRegistryKeyC = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
|
||||||
static const WCHAR *debuggerRegistryValueNameC = L"Debugger";
|
static const WCHAR *debuggerRegistryValueNameC = L"Debugger";
|
||||||
@@ -68,8 +74,12 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
|
|||||||
const WCHAR *key,
|
const WCHAR *key,
|
||||||
bool readWrite,
|
bool readWrite,
|
||||||
HKEY *keyHandle,
|
HKEY *keyHandle,
|
||||||
|
AccessMode mode,
|
||||||
QString *errorMessage);
|
QString *errorMessage);
|
||||||
|
|
||||||
|
inline bool openRegistryKey(HKEY category, const WCHAR *key, bool readWrite, HKEY *keyHandle, QString *errorMessage)
|
||||||
|
{ return openRegistryKey(category, key, readWrite, keyHandle, DefaultAccessMode, errorMessage); }
|
||||||
|
|
||||||
QString debuggerCall(const QString &additionalOption = QString());
|
QString debuggerCall(const QString &additionalOption = QString());
|
||||||
|
|
||||||
bool isRegistered(HKEY handle, const QString &call, QString *errorMessage, QString *oldDebugger = 0);
|
bool isRegistered(HKEY handle, const QString &call, QString *errorMessage, QString *oldDebugger = 0);
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ static const char creatorBinaryC[] = "qtcreator.exe";
|
|||||||
enum Mode { HelpMode, RegisterMode, UnregisterMode, PromptMode, ForceCreatorMode, ForceDefaultMode };
|
enum Mode { HelpMode, RegisterMode, UnregisterMode, PromptMode, ForceCreatorMode, ForceDefaultMode };
|
||||||
|
|
||||||
Mode optMode = PromptMode;
|
Mode optMode = PromptMode;
|
||||||
|
// WOW: Indicates registry key access mode:
|
||||||
|
// - Accessing 32bit using a 64bit built Qt Creator or,
|
||||||
|
// - Accessing 64bit using a 32bit built Qt Creator on 64bit Windows
|
||||||
bool optIsWow = false;
|
bool optIsWow = false;
|
||||||
bool noguiMode = false;
|
bool noguiMode = false;
|
||||||
unsigned long argProcessId = 0;
|
unsigned long argProcessId = 0;
|
||||||
@@ -172,6 +175,14 @@ static void usage(const QString &binary, const QString &message = QString())
|
|||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is64BitWindowsSystem() // Courtesy utils library
|
||||||
|
{
|
||||||
|
SYSTEM_INFO systemInfo;
|
||||||
|
GetNativeSystemInfo(&systemInfo);
|
||||||
|
return systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64
|
||||||
|
|| systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64;
|
||||||
|
}
|
||||||
|
|
||||||
// ------- Registry helpers
|
// ------- Registry helpers
|
||||||
|
|
||||||
static inline bool registryWriteBinaryKey(HKEY handle,
|
static inline bool registryWriteBinaryKey(HKEY handle,
|
||||||
@@ -303,8 +314,15 @@ bool readDefaultDebugger(QString *defaultDebugger,
|
|||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
HKEY handle;
|
HKEY handle;
|
||||||
if (openRegistryKey(HKEY_LOCAL_MACHINE, optIsWow ? debuggerWow32RegistryKeyC : debuggerRegistryKeyC,
|
const RegistryAccess::AccessMode accessMode = optIsWow
|
||||||
false, &handle, errorMessage)) {
|
#ifdef Q_OS_WIN64
|
||||||
|
? RegistryAccess::Registry32Mode
|
||||||
|
#else
|
||||||
|
? RegistryAccess::Registry64Mode
|
||||||
|
#endif
|
||||||
|
: RegistryAccess::DefaultAccessMode;
|
||||||
|
|
||||||
|
if (openRegistryKey(HKEY_LOCAL_MACHINE, debuggerRegistryKeyC, false, &handle, accessMode, errorMessage)) {
|
||||||
success = registryReadStringKey(handle, debuggerRegistryDefaultValueNameC,
|
success = registryReadStringKey(handle, debuggerRegistryDefaultValueNameC,
|
||||||
defaultDebugger, errorMessage);
|
defaultDebugger, errorMessage);
|
||||||
RegCloseKey(handle);
|
RegCloseKey(handle);
|
||||||
@@ -372,12 +390,13 @@ bool chooseDebugger(QString *errorMessage)
|
|||||||
|
|
||||||
static bool registerDebuggerKey(const WCHAR *key,
|
static bool registerDebuggerKey(const WCHAR *key,
|
||||||
const QString &call,
|
const QString &call,
|
||||||
|
RegistryAccess::AccessMode access,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
HKEY handle = 0;
|
HKEY handle = 0;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
do {
|
do {
|
||||||
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, errorMessage))
|
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, access, errorMessage))
|
||||||
break;
|
break;
|
||||||
// Save old key, which might be missing
|
// Save old key, which might be missing
|
||||||
QString oldDebugger;
|
QString oldDebugger;
|
||||||
@@ -401,11 +420,16 @@ static bool registerDebuggerKey(const WCHAR *key,
|
|||||||
|
|
||||||
bool install(QString *errorMessage)
|
bool install(QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(), errorMessage))
|
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(), RegistryAccess::DefaultAccessMode, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
#ifdef Q_OS_WIN64
|
#ifdef Q_OS_WIN64
|
||||||
if (!registerDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(QLatin1String("-wow")), errorMessage))
|
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry32Mode, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
if (is64BitWindowsSystem()) {
|
||||||
|
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry64Mode, errorMessage))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -413,12 +437,13 @@ bool install(QString *errorMessage)
|
|||||||
// Unregister helper: Restore the original debugger key
|
// Unregister helper: Restore the original debugger key
|
||||||
static bool unregisterDebuggerKey(const WCHAR *key,
|
static bool unregisterDebuggerKey(const WCHAR *key,
|
||||||
const QString &call,
|
const QString &call,
|
||||||
|
RegistryAccess::AccessMode access,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
HKEY handle = 0;
|
HKEY handle = 0;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
do {
|
do {
|
||||||
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, errorMessage))
|
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, access, errorMessage))
|
||||||
break;
|
break;
|
||||||
QString debugger;
|
QString debugger;
|
||||||
if (!isRegistered(handle, call, errorMessage, &debugger) && !debugger.isEmpty()) {
|
if (!isRegistered(handle, call, errorMessage, &debugger) && !debugger.isEmpty()) {
|
||||||
@@ -448,12 +473,18 @@ static bool unregisterDebuggerKey(const WCHAR *key,
|
|||||||
|
|
||||||
bool uninstall(QString *errorMessage)
|
bool uninstall(QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(), errorMessage))
|
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(), RegistryAccess::DefaultAccessMode, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
#ifdef Q_OS_WIN64
|
#ifdef Q_OS_WIN64
|
||||||
if (!unregisterDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(QLatin1String("-wow")), errorMessage))
|
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry32Mode, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
if (is64BitWindowsSystem()) {
|
||||||
|
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry64Mode, errorMessage))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user