diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index a1ab1d4c4e6c9198d1834a424166c94153bb90f1..6ac5997efa9c610c48920b59481b94bfe55bb5f6 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -62,6 +62,7 @@ SOURCES += \
 
 FORMS += $$PWD/cdboptionspagewidget.ui
 
+LIBS+=-lpsapi
 } else {
    message("Debugging Tools for Windows could not be found in $$CDB_PATH")
 } # exists($$CDB_PATH)
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
index 40bec69fae03245705bd45dd02c2e8124da52521..4393c6a36122f5bb9b8232bc86120ed53f85b305 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.cpp
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
@@ -37,6 +37,8 @@
 #include <QtCore/QDebug>
 #include <QtCore/QMap>
 
+#include <psapi.h>
+
 enum { debugBP = 0 };
 
 namespace Debugger {
@@ -215,16 +217,106 @@ bool CDBBreakPoint::add(CIDebugControl* debugControl,
     return true;
 }
 
-// Make sure file can be found in editor manager and text markers
-// Use '/' and capitalize drive letter
-QString CDBBreakPoint::canonicalSourceFile(const QString &f)
+// 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)
 {
-    if (f.isEmpty())
+    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::fromUtf16(driveName);
+            if (s->startsWith(deviceName)) {
+                s->replace(0, deviceName.size(), QString::fromUtf16(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(f.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+    if(hFile == INVALID_HANDLE_VALUE)
         return f;
-    QString rc = QDir::fromNativeSeparators(f);
-    if (rc.size() > 2 && rc.at(1) == QLatin1Char(':'))
-        rc[0] = rc.at(0).toUpper();
-    return rc;
+    // 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::fromUtf16(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.
+
+typedef QHash<QString, QString> NormalizedFileCache;
+Q_GLOBAL_STATIC(NormalizedFileCache, normalizedFileNameCache)
+
+QString CDBBreakPoint::normalizeFileName(const QString &f)
+{
+    QTC_ASSERT(!f.isEmpty(), return f)
+    const NormalizedFileCache::const_iterator it = normalizedFileNameCache()->constFind(f);
+    if (it != normalizedFileNameCache()->constEnd())
+        return it.value();
+    QString normalizedName = QDir::fromNativeSeparators(normalizeFileNameCaseHelper(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();
+    normalizedFileNameCache()->insert(f, normalizedName);
+    return f;
+}
+
+void CDBBreakPoint::clearNormalizeFileNameCache()
+{
+    normalizedFileNameCache()->clear();
 }
 
 bool CDBBreakPoint::retrieve(CIDebugBreakpoint *ibp, QString *errorMessage)
@@ -267,7 +359,7 @@ bool CDBBreakPoint::parseExpression(const QString &expr)
         conditionPos = expr.indexOf(sourceFileQuote, colonPos + 1);
         if (conditionPos == -1)
             return false;
-        fileName = canonicalSourceFile(expr.mid(1, colonPos - 1));
+        fileName = normalizeFileName(expr.mid(1, colonPos - 1));
         const QString lineNumberS = expr.mid(colonPos + 1, conditionPos - colonPos - 1);
         bool lineNumberOk = false;
         lineNumber = lineNumberS.toInt(&lineNumberOk);
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.h b/src/plugins/debugger/cdb/cdbbreakpoint.h
index 7b1379617e506e449003fe7dad0c75e6cab759db..3a1e8e09b5f7b787b8788f444fd204e46336f47d 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.h
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.h
@@ -80,7 +80,8 @@ struct CDBBreakPoint
                                        QString *errorMessage, QStringList *warnings);
 
     // Return a 'canonical' file (using '/' and capitalized drive letter)
-    static QString canonicalSourceFile(const QString &f);
+    static QString normalizeFileName(const QString &f);
+    static void clearNormalizeFileNameCache();
 
     QString fileName;       // short name of source file
     QString condition;      // condition associated with breakpoint
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 9f74ec7f9ef1f91f9f6df87f8632db11e0ab8f0d..ae17ff1ea0f3842c3534fa4b601c1eaa320ff704 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -625,12 +625,14 @@ void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters>
 {
     if (debugCDBExecution)
         qDebug() << "startDebugger" << *sp;
+    CDBBreakPoint::clearNormalizeFileNameCache();
     setState(AdapterStarting, Q_FUNC_INFO, __LINE__);
     m_d->checkVersion();
     if (m_d->m_hDebuggeeProcess) {
         warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged."));
         setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__);
         emit startFailed();
+        return;
     }
     m_d->clearDisplay();
     m_d->m_inferiorStartupComplete = false;
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index 90329dfe04fbfbc34bf5b41d0fbe5b672353851b..e0c4ba0c798f4b50d06bd239af388a158cafd202 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -116,7 +116,7 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
             frame.line = ulLine;
             // Vitally important  to use canonical file that matches editormanager,
             // else the marker will not show.
-            frame.file = CDBBreakPoint::canonicalSourceFile(QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf)));
+            frame.file = CDBBreakPoint::normalizeFileName(QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf)));
         }
         m_frames.push_back(frame);
     }