From f641369ceb7b7e2f95b9d0656b34c0517c5b95f7 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 13:20:09 +0000 Subject: Factored readRegistryKey implementation out of qmake This function is now implemented with its own header and source files, rather than being embedded within the MSVC qmake generator. The motivation for this is to allow code to be shared between qmake and configure, both of which query the registry when built for Windows. Reviewed-by: Miikka Heikkinen --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 7 ++ qmake/Makefile.win32-g++ | 5 + qmake/Makefile.win32-g++-sh | 5 + qmake/generators/win32/msvc_vcproj.cpp | 97 +------------------- qmake/qmake.pri | 7 +- qmake/qmake.pro | 4 + tools/shared/windows/registry.cpp | 161 +++++++++++++++++++++++++++++++++ tools/shared/windows/registry.h | 64 +++++++++++++ 9 files changed, 259 insertions(+), 100 deletions(-) create mode 100644 tools/shared/windows/registry.cpp create mode 100644 tools/shared/windows/registry.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index fcf43c8..e343803 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -10,7 +10,8 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ mingw_make.o option.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ - symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o + symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ + registry.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -20,6 +21,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ + registry.o \ $(QTOBJS) @@ -32,6 +34,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/makefiledeps.cpp option.cpp generators/win32/mingw_make.cpp generators/makefile.cpp \ generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ + $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -62,6 +65,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \ -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \ -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \ + -I$(BUILD_PATH)/tools/shared \ -DQT_NO_PCRE \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \ @@ -281,6 +285,9 @@ symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index e6bbcd5..3cd180c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -34,6 +34,7 @@ CFLAGS = -c -Fo$@ \ -I$(BUILD_PATH)\src\corelib\global \ -I$(BUILD_PATH)\src\corelib\xml \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \ @@ -59,6 +60,7 @@ CFLAGS = -c -o$@ \ -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \ -I$(BUILD_PATH)\src\corelib\global \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT @@ -75,6 +77,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ + registry.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -198,6 +201,7 @@ clean:: -del symmake_abld.obj -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj + -del registry.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -397,6 +401,9 @@ symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ade379b..ebc7fe2 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -278,6 +280,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 8d2723c..1d55da2 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -277,6 +279,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 47986f5..58f95e9 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -67,6 +67,7 @@ QT_END_NAMESPACE #ifdef Q_OS_WIN32 #include +#include QT_BEGIN_NAMESPACE @@ -93,102 +94,6 @@ struct { {NETUnknown, "", ""}, }; -static QString keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -static QString keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == "Default" || res == ".") - res = ""; - return res; -} - -static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) -{ - - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = 0; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); - - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - QString result; - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(", "); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); - break; - } - - RegCloseKey(handle); - return result; -} QT_END_NAMESPACE #endif diff --git a/qmake/qmake.pri b/qmake/qmake.pri index efe4f36..a2ffe15 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -17,7 +17,8 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ - generators/symbian/initprojectdeploy_symbian.cpp + generators/symbian/initprojectdeploy_symbian.cpp \ + windows/registry.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -29,8 +30,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ - generators/symbian/epocroot.h \ - generators/symbian/initprojectdeploy_symbian.h + generators/symbian/initprojectdeploy_symbian.h \ + windows/registry.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 00dcbce..f3f9d53 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -27,5 +27,9 @@ INCPATH += generators \ $$QT_SOURCE_TREE/include \ $$QT_SOURCE_TREE/include/QtCore \ $$QT_SOURCE_TREE/qmake + +VPATH += $$QT_SOURCE_TREE/tools/shared +INCPATH += $$QT_SOURCE_TREE/tools/shared + include(qmake.pri) diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp new file mode 100644 index 0000000..d342d78 --- /dev/null +++ b/tools/shared/windows/registry.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "registry.h" + +/*! + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/*! + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == "Default" || res == ".") + res = ""; + return res; +} + +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = 0; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(", "); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %d type in windows registry", dataType); + break; + } + + RegCloseKey(handle); +#endif + + return result; +} + + diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry.h new file mode 100644 index 0000000..3896527 --- /dev/null +++ b/tools/shared/windows/registry.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWS_REGISTRY_H +#define WINDOWS_REGISTRY_H + +#include + +#ifdef Q_OS_WIN32 + #include +#else + typedef void* HKEY; +#endif + +#include + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + */ +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey); + +#endif // WINDOWS_REGISTRY_H -- cgit v0.12