From 9ca1e7d79a6d461a8f18407f7a3104bb91cf3cf6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Fri, 10 Sep 2010 16:23:47 +0200 Subject: [PATCH] Debugger: Move some windows functionality around. --- src/libs/utils/winutils.cpp | 6 ++ src/libs/utils/winutils.h | 4 + src/plugins/debugger/cdb/corebreakpoint.cpp | 82 +-------------------- src/plugins/debugger/shared/dbgwinutils.cpp | 75 +++++++++++++++++++ src/plugins/debugger/shared/dbgwinutils.h | 8 ++ 5 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp index afc003bb342..6b25890c6d0 100644 --- a/src/libs/utils/winutils.cpp +++ b/src/libs/utils/winutils.cpp @@ -155,4 +155,10 @@ QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name, QString *er return rc; } +unsigned long winQPidToPid(const Q_PID qpid) +{ + const PROCESS_INFORMATION *processInfo = reinterpret_cast<const PROCESS_INFORMATION*>(qpid); + return processInfo->dwProcessId; +} + } // namespace Utils diff --git a/src/libs/utils/winutils.h b/src/libs/utils/winutils.h index 8a9ff270c18..1eb2bd6e529 100644 --- a/src/libs/utils/winutils.h +++ b/src/libs/utils/winutils.h @@ -32,6 +32,8 @@ #include "utils_global.h" +#include <QtCore/QProcess> // Q_PID (is PROCESS_INFORMATION*) + QT_BEGIN_NAMESPACE class QString; QT_END_NAMESPACE @@ -52,5 +54,7 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name, QString *errorMessage); +QTCREATOR_UTILS_EXPORT unsigned long winQPidToPid(const Q_PID qpid); + } // namespace Utils #endif // WINUTILS_H diff --git a/src/plugins/debugger/cdb/corebreakpoint.cpp b/src/plugins/debugger/cdb/corebreakpoint.cpp index 9c2551675ec..4effa092d48 100644 --- a/src/plugins/debugger/cdb/corebreakpoint.cpp +++ b/src/plugins/debugger/cdb/corebreakpoint.cpp @@ -29,6 +29,7 @@ #include "corebreakpoint.h" #include "coreengine.h" +#include "dbgwinutils.h" #include <utils/qtcassert.h> @@ -37,8 +38,6 @@ #include <QtCore/QDebug> #include <QtCore/QMap> -#include <psapi.h> - enum { debugBP = 0 }; namespace CdbCore { @@ -239,83 +238,6 @@ bool BreakPoint::add(CIDebugControl* debugControl, return true; } -// Helper for normalizing file names: -// Map the device paths in a file name to back to drive letters -// "/Device/HarddiskVolume1/file.cpp" -> "C:/file.cpp" - -static bool mapDeviceToDriveLetter(QString *s) -{ - enum { bufSize = 512 }; - // Retrieve drive letters and get their device names. - // Do not cache as it may change due to removable/network drives. - TCHAR driveLetters[bufSize]; - if (!GetLogicalDriveStrings(bufSize-1, driveLetters)) - return false; - - TCHAR driveName[MAX_PATH]; - TCHAR szDrive[3] = TEXT(" :"); - for (const TCHAR *driveLetter = driveLetters; *driveLetter; driveLetter++) { - szDrive[0] = *driveLetter; // Look up each device name - if (QueryDosDevice(szDrive, driveName, MAX_PATH)) { - const QString deviceName = QString::fromWCharArray(driveName); - if (s->startsWith(deviceName)) { - s->replace(0, deviceName.size(), QString::fromWCharArray(szDrive)); - return true; - } - } - } - return false; -} - -// Helper for normalizing file names: -// Determine normalized case of a Windows file name (camelcase.cpp -> CamelCase.cpp) -// as the debugger reports lower case file names. -// Restriction: File needs to exists and be non-empty and will be to be opened/mapped. -// This is the MSDN-recommended way of doing that. The result should be cached. - -static inline QString normalizeFileNameCaseHelper(const QString &f) -{ - HANDLE hFile = CreateFile((const wchar_t*)f.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile == INVALID_HANDLE_VALUE) - return f; - // Get the file size. We need a non-empty file to map it. - DWORD dwFileSizeHi = 0; - DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); - if (dwFileSizeLo == 0 && dwFileSizeHi == 0) { - CloseHandle(hFile); - return f; - } - // Create a file mapping object. - HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 1, NULL); - if (!hFileMap) { - CloseHandle(hFile); - return f; - } - - // Create a file mapping to get the file name. - void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); - if (!pMem) { - CloseHandle(hFileMap); - CloseHandle(hFile); - return f; - } - - QString rc; - WCHAR pszFilename[MAX_PATH]; - pszFilename[0] = 0; - // Get a file name of the form "/Device/HarddiskVolume1/file.cpp" - if (GetMappedFileName (GetCurrentProcess(), pMem, pszFilename, MAX_PATH)) { - rc = QString::fromWCharArray(pszFilename); - if (!mapDeviceToDriveLetter(&rc)) - rc.clear(); - } - - UnmapViewOfFile(pMem); - CloseHandle(hFileMap); - CloseHandle(hFile); - return rc.isEmpty() ? f : rc; -} - // Make sure file can be found in editor manager and text markers // Use '/', correct case and capitalize drive letter. Use a cache. @@ -328,7 +250,7 @@ QString BreakPoint::normalizeFileName(const QString &f) const NormalizedFileCache::const_iterator it = normalizedFileNameCache()->constFind(f); if (it != normalizedFileNameCache()->constEnd()) return it.value(); - QString normalizedName = QDir::fromNativeSeparators(normalizeFileNameCaseHelper(f)); + QString normalizedName = QDir::fromNativeSeparators(Debugger::Internal::winNormalizeFileName(f)); // Upcase drive letter for consistency even if case mapping fails. if (normalizedName.size() > 2 && normalizedName.at(1) == QLatin1Char(':')) normalizedName[0] = normalizedName.at(0).toUpper(); diff --git a/src/plugins/debugger/shared/dbgwinutils.cpp b/src/plugins/debugger/shared/dbgwinutils.cpp index c2ed55d5078..e4de625e22c 100644 --- a/src/plugins/debugger/shared/dbgwinutils.cpp +++ b/src/plugins/debugger/shared/dbgwinutils.cpp @@ -167,5 +167,80 @@ unsigned long winGetCurrentProcessId() return GetCurrentProcessId(); } +// Helper for normalizing file names: +// Map the device paths in a file name to back to drive letters +// "/Device/HarddiskVolume1/file.cpp" -> "C:/file.cpp" + +static bool mapDeviceToDriveLetter(QString *s) +{ + enum { bufSize = 512 }; + // Retrieve drive letters and get their device names. + // Do not cache as it may change due to removable/network drives. + TCHAR driveLetters[bufSize]; + if (!GetLogicalDriveStrings(bufSize-1, driveLetters)) + return false; + + TCHAR driveName[MAX_PATH]; + TCHAR szDrive[3] = TEXT(" :"); + for (const TCHAR *driveLetter = driveLetters; *driveLetter; driveLetter++) { + szDrive[0] = *driveLetter; // Look up each device name + if (QueryDosDevice(szDrive, driveName, MAX_PATH)) { + const QString deviceName = QString::fromWCharArray(driveName); + if (s->startsWith(deviceName)) { + s->replace(0, deviceName.size(), QString::fromWCharArray(szDrive)); + return true; + } + } + } + return false; +} + +// Determine normalized case of a Windows file name (camelcase.cpp -> CamelCase.cpp) +// Restriction: File needs to exists and be non-empty and will be to be opened/mapped. +// This is the MSDN-recommended way of doing that. + +QString winNormalizeFileName(const QString &f) +{ + HANDLE hFile = CreateFile((const wchar_t*)f.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE) + return f; + // Get the file size. We need a non-empty file to map it. + DWORD dwFileSizeHi = 0; + DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); + if (dwFileSizeLo == 0 && dwFileSizeHi == 0) { + CloseHandle(hFile); + return f; + } + // Create a file mapping object. + HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 1, NULL); + if (!hFileMap) { + CloseHandle(hFile); + return f; + } + + // Create a file mapping to get the file name. + void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); + if (!pMem) { + CloseHandle(hFileMap); + CloseHandle(hFile); + return f; + } + + QString rc; + WCHAR pszFilename[MAX_PATH]; + pszFilename[0] = 0; + // Get a file name of the form "/Device/HarddiskVolume1/file.cpp" + if (GetMappedFileName (GetCurrentProcess(), pMem, pszFilename, MAX_PATH)) { + rc = QString::fromWCharArray(pszFilename); + if (!mapDeviceToDriveLetter(&rc)) + rc.clear(); + } + + UnmapViewOfFile(pMem); + CloseHandle(hFileMap); + CloseHandle(hFile); + return rc.isEmpty() ? f : rc; +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/shared/dbgwinutils.h b/src/plugins/debugger/shared/dbgwinutils.h index 10d94c722bc..573c7ebd65e 100644 --- a/src/plugins/debugger/shared/dbgwinutils.h +++ b/src/plugins/debugger/shared/dbgwinutils.h @@ -49,6 +49,14 @@ bool winDebugBreakProcess(unsigned long pid, QString *errorMessage); unsigned long winGetCurrentProcessId(); +/* Helper for (case-)normalizing file names: + * Determine normalized case of a Windows file name (camelcase.cpp -> CamelCase.cpp) + * as the debugger reports lower case file names. + * Restriction: File needs to exist and be non-empty and will be to be opened/mapped. + * The result should be cached as the function can be extensive. */ + +QString winNormalizeFileName(const QString &f); + } // namespace Internal } // namespace Debugger -- GitLab