Bug 872012 - Get default browser's path from the association when launching on the desktop. r=jmathies
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Wed, 29 May 2013 00:22:25 +0900
changeset 133148 0d177dbf23f46628fe9c3aec0d50edf554489390
parent 133147 2a028269a51be7d0d5f1849dfd138d37cdb469a4
child 133149 8f85cd6a1be564da7f042fa8e7ca9b206c05a588
push id24744
push userryanvm@gmail.com
push dateWed, 29 May 2013 01:22:47 +0000
treeherdermozilla-central@495b385ae811 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs872012
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 872012 - Get default browser's path from the association when launching on the desktop. r=jmathies
browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
--- a/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
+++ b/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
@@ -32,16 +32,19 @@
 #define REQUEST_WAIT_TIMEOUT 30
 // Pulled from desktop browser's shell
 #define APP_REG_NAME L"Firefox"
 
 static const WCHAR* kFirefoxExe = L"firefox.exe";
 static const WCHAR* kMetroFirefoxExe = L"firefox.exe";
 static const WCHAR* kDefaultMetroBrowserIDPathKey = L"FirefoxURL";
 
+static bool GetDesktopBrowserPath(CStringW& aPathBuffer);
+static bool GetDefaultBrowserPath(CStringW& aPathBuffer);
+
 template <class T>void SafeRelease(T **ppT)
 {
   if (*ppT) {
     (*ppT)->Release();
     *ppT = NULL;
   }
 }
 
@@ -273,48 +276,59 @@ public:
       *aLaunchType = AHE_IMMERSIVE;
       mIsDesktopRequest = false;
     }
     return S_OK;
   }
 
   bool IsDefaultBrowser()
   {
-    bool result = false;
     IApplicationAssociationRegistration* pAAR;
     HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
                                   NULL,
                                   CLSCTX_INPROC,
                                   IID_IApplicationAssociationRegistration,
                                   (void**)&pAAR);
-    if (SUCCEEDED(hr)) {
-      BOOL res;
-      hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE,
-                                      APP_REG_NAME,
-                                      &res);
-      Log(L"QueryAppIsDefaultAll: %d", res);
-      if (!res) 
-        return false;
-      // Make sure the Prog ID matches what we have
-      LPWSTR registeredApp;
-      hr = pAAR->QueryCurrentDefault(L"http", AT_URLPROTOCOL, AL_EFFECTIVE,
-                                      &registeredApp);
-      Log(L"QueryCurrentDefault: %X", hr);
-      if (SUCCEEDED(hr)) {
-        Log(L"registeredApp=%s", registeredApp);
-        result = !wcsicmp(registeredApp, kDefaultMetroBrowserIDPathKey);
-        CoTaskMemFree(registeredApp);
-      } else {
-        result = false;
-      }
+    if (FAILED(hr))
+      return false;
 
+    BOOL res = FALSE;
+    hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE,
+                                    APP_REG_NAME,
+                                    &res);
+    Log(L"QueryAppIsDefaultAll: %d", res);
+    if (!res) {
       pAAR->Release();
-      return result;
+      return false;
     }
-    return result;
+    // Make sure the Prog ID matches what we have
+    LPWSTR registeredApp;
+    hr = pAAR->QueryCurrentDefault(L"http", AT_URLPROTOCOL, AL_EFFECTIVE,
+                                    &registeredApp);
+    pAAR->Release();
+    Log(L"QueryCurrentDefault: %X", hr);
+    if (FAILED(hr))
+      return false;
+
+    Log(L"registeredApp=%s", registeredApp);
+    bool result = !wcsicmp(registeredApp, kDefaultMetroBrowserIDPathKey);
+    CoTaskMemFree(registeredApp);
+    if (!result)
+      return false;
+
+    // If the registry points another browser's path,
+    // activating the Metro browser will fail. So fallback to the desktop.
+    CStringW selfPath;
+    GetDesktopBrowserPath(selfPath);
+    selfPath.MakeLower();
+    CStringW browserPath;
+    GetDefaultBrowserPath(browserPath);
+    browserPath.MakeLower();
+
+    return selfPath == browserPath;
   }
 private:
   ~CExecuteCommandVerb()
   {
     SafeRelease(&mShellItemArray);
     SafeRelease(&mUnkSite);
   }
 
@@ -371,16 +385,42 @@ static bool GetDesktopBrowserPath(CStrin
   // ceh.exe sits in dist/bin root with the desktop browser. Since this
   // is a firefox only component, this hardcoded filename is ok.
   aPathBuffer.Append(L"\\");
   aPathBuffer.Append(kFirefoxExe);
   return true;
 }
 
 /*
+ * Retrieve the current default browser's path.
+ *
+ * @aPathBuffer Buffer to fill
+ */
+static bool GetDefaultBrowserPath(CStringW& aPathBuffer)
+{
+  WCHAR buffer[MAX_PATH];
+  DWORD length = MAX_PATH;
+
+  if (FAILED(AssocQueryStringW(ASSOCF_NOTRUNCATE | ASSOCF_INIT_IGNOREUNKNOWN,
+                               ASSOCSTR_EXECUTABLE,
+                               kDefaultMetroBrowserIDPathKey, NULL,
+                               buffer, &length))) {
+    Log(L"AssocQueryString failed.");
+    return false;
+  }
+
+  // sanity check
+  if (lstrcmpiW(PathFindFileNameW(buffer), kFirefoxExe))
+    return false;
+
+  aPathBuffer = buffer;
+  return true;
+}
+
+/*
  * Retrieve the app model id of the firefox metro browser.
  *
  * @aPathBuffer Buffer to fill
  * @aCharLength Length of buffer to fill in characters
  */
 static bool GetDefaultBrowserAppModelID(WCHAR* aIDBuffer,
                                         long aCharLength)
 {
@@ -535,16 +575,18 @@ void CExecuteCommandVerb::LaunchDesktopB
   if (!GetDesktopBrowserPath(browserPath)) {
     return;
   }
 
   // If a taskbar shortcut, link or local file is clicked, the target will
   // be the browser exe or file.
   CStringW params;
   if (!IsTargetBrowser()) {
+    // Fallback to the module path if it failed to get the default browser.
+    GetDefaultBrowserPath(browserPath);
     params += "-url ";
     params += "\"";
     params += mTarget;
     params += "\"";
   }
 
   Log(L"Desktop Launch: verb:%s exe:%s params:%s", mVerb, browserPath, params);