Bug 791019 - New parameter for checking all defaults for win32. r=jimm
authorBrian R. Bondy <netzen@gmail.com>
Fri, 21 Sep 2012 10:05:24 -0400
changeset 107793 9c386b44a2f981ce2aec8733a073f05e663ee2e7
parent 107792 b36820aa1f207b993682b45356b11eeb94f22602
child 107794 3c68fdd4f77acaaeffb4cd2905ce1477041ee171
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersjimm
bugs791019
milestone18.0a1
Bug 791019 - New parameter for checking all defaults for win32. r=jimm
browser/components/shell/src/nsWindowsShellService.cpp
browser/components/shell/src/nsWindowsShellService.h
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -315,17 +315,18 @@ IsWin8OrLater()
   OSVERSIONINFOW osInfo;
   osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
   GetVersionExW(&osInfo);
   return osInfo.dwMajorVersion > 6 || 
          osInfo.dwMajorVersion >= 6 && osInfo.dwMinorVersion >= 2;
 }
 
 bool
-nsWindowsShellService::IsDefaultBrowserVista(bool* aIsDefaultBrowser)
+nsWindowsShellService::IsDefaultBrowserVista(bool aCheckAllTypes,
+                                             bool* aIsDefaultBrowser)
 {
   IApplicationAssociationRegistration* pAAR;
   HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
                                 NULL,
                                 CLSCTX_INPROC,
                                 IID_IApplicationAssociationRegistration,
                                 (void**)&pAAR);
 
@@ -343,39 +344,53 @@ nsWindowsShellService::IsDefaultBrowserV
                                      &registeredApp);
       if (SUCCEEDED(hr)) {
         LPCWSTR firefoxHTTPProgID = L"FirefoxURL";
         *aIsDefaultBrowser = !wcsicmp(registeredApp, firefoxHTTPProgID);
         CoTaskMemFree(registeredApp);
       } else {
         *aIsDefaultBrowser = false;
       }
+      // If this is a startup check, then we don't check file type
+      // associations. This is because the win8 UI for file type
+      // association has to be done through the control panel.  If this
+      // is not a startup check, then we're checking through the control
+      // panel and we should also check for file type association.
+      if (aCheckAllTypes && *aIsDefaultBrowser) {
+        hr = pAAR->QueryCurrentDefault(L".html", AT_FILEEXTENSION, AL_EFFECTIVE,
+                                       &registeredApp);
+        if (SUCCEEDED(hr)) {
+          LPCWSTR firefoxHTMLProgID = L"FirefoxHTML";
+          *aIsDefaultBrowser = !wcsicmp(registeredApp, firefoxHTMLProgID);
+          CoTaskMemFree(registeredApp);
+        } else {
+          *aIsDefaultBrowser = false;
+        }
+      }
     }
 
     pAAR->Release();
     return true;
   }
   return false;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
+                                        bool aForAllTypes,
                                         bool* aIsDefaultBrowser)
 {
   // If this is the first browser window, maintain internal state that we've
-  // checked this session (so that subsequent window opens don't show the 
+  // checked this session (so that subsequent window opens don't show the
   // default browser dialog).
   if (aStartupCheck)
     mCheckedThisSession = true;
-  return IsDefaultBrowser(aIsDefaultBrowser);
-}
 
-nsresult
-nsWindowsShellService::IsDefaultBrowser(bool* aIsDefaultBrowser)
-{
+  // Assume we're the default unless one of the several checks below tell us
+  // otherwise.
   *aIsDefaultBrowser = true;
 
   PRUnichar exePath[MAX_BUF];
   if (!::GetModuleFileNameW(0, exePath, MAX_BUF))
     return NS_ERROR_FAILURE;
 
   // Convert the path to a long path since GetModuleFileNameW returns the path
   // that was used to launch Firefox which is not necessarily a long path.
@@ -443,17 +458,17 @@ nsWindowsShellService::IsDefaultBrowser(
         return NS_OK;
       }
     }
   }
 
   // Only check if Firefox is the default browser on Vista and above if the
   // previous checks show that Firefox is the default browser.
   if (*aIsDefaultBrowser) {
-    IsDefaultBrowserVista(aIsDefaultBrowser);
+    IsDefaultBrowserVista(aForAllTypes, aIsDefaultBrowser);
   }
 
   // To handle the case where DDE isn't disabled due for a user because there
   // account didn't perform a Firefox update this will check if Firefox is the
   // default browser and if dde is disabled for each handler
   // and if it isn't disable it. When Firefox is not the default browser the
   // helper application will disable dde for each handler.
   if (*aIsDefaultBrowser) {
@@ -583,43 +598,91 @@ DynSHOpenWithDialog(HWND hwndParent, con
       return NS_ERROR_FAILURE;
     }
   }
 
   return SUCCEEDED(SHOpenWithDialogFn(hwndParent, poainfo)) ? NS_OK :
                                                               NS_ERROR_FAILURE;
 }
 
+nsresult
+nsWindowsShellService::LaunchControlPanelDefaultPrograms()
+{
+  // Build the path control.exe path safely
+  WCHAR controlEXEPath[MAX_PATH + 1] = { '\0' };
+  if (!GetSystemDirectoryW(controlEXEPath, MAX_PATH)) {
+    return NS_ERROR_FAILURE;
+  }
+  LPCWSTR controlEXE = L"control.exe";
+  if (wcslen(controlEXEPath) + wcslen(controlEXE) >= MAX_PATH) {
+    return NS_ERROR_FAILURE;
+  }
+  if (!PathAppendW(controlEXEPath, controlEXE)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  WCHAR params[] = L"control.exe /name Microsoft.DefaultPrograms /page pageDefaultProgram";
+  STARTUPINFOW si = {sizeof(si), 0};
+  si.dwFlags = STARTF_USESHOWWINDOW;
+  si.wShowWindow = SW_SHOWDEFAULT;
+  PROCESS_INFORMATION pi = {0};
+  if (!CreateProcessW(controlEXEPath, params, NULL, NULL, FALSE, 0, NULL,
+                      NULL, &si, &pi)) {
+    return NS_ERROR_FAILURE;
+  }
+  CloseHandle(pi.hProcess);
+  CloseHandle(pi.hThread);
+
+  return NS_OK;
+}
+
+nsresult
+nsWindowsShellService::LaunchHTTPHandlerPane()
+{
+  OPENASINFO info;
+  info.pcszFile = L"http";
+  info.pcszClass = NULL;
+  info.oaifInFlags = OAIF_FORCE_REGISTRATION | 
+                     OAIF_URL_PROTOCOL |
+                     OAIF_REGISTER_EXT;
+  return DynSHOpenWithDialog(NULL, &info);
+}
+
 NS_IMETHODIMP
 nsWindowsShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers)
 {
   nsAutoString appHelperPath;
   if (NS_FAILED(GetHelperPath(appHelperPath)))
     return NS_ERROR_FAILURE;
 
   if (aForAllUsers) {
     appHelperPath.AppendLiteral(" /SetAsDefaultAppGlobal");
   } else {
     appHelperPath.AppendLiteral(" /SetAsDefaultAppUser");
   }
 
   nsresult rv = LaunchHelper(appHelperPath);
   if (NS_SUCCEEDED(rv) && IsWin8OrLater()) {
-    OPENASINFO info;
-    info.pcszFile = L"http";
-    info.pcszClass = NULL;
-    info.oaifInFlags = OAIF_FORCE_REGISTRATION | 
-                       OAIF_URL_PROTOCOL |
-                       OAIF_REGISTER_EXT;
-    nsresult rv = DynSHOpenWithDialog(NULL, &info);
-    NS_ENSURE_SUCCESS(rv, rv);
-    bool isDefaultBrowser = false;
-    rv = NS_SUCCEEDED(IsDefaultBrowser(&isDefaultBrowser)) &&
-         isDefaultBrowser ? NS_OK : NS_ERROR_FAILURE;
+    if (aClaimAllTypes) {
+      rv = LaunchControlPanelDefaultPrograms();
+      // The above call should never really fail, but just in case
+      // fall back to showing the HTTP association screen only.
+      if (NS_FAILED(rv)) {
+        rv = LaunchHTTPHandlerPane();
+      }
+    } else {
+      rv = LaunchHTTPHandlerPane();
+      // The above calls hould never really fail, but just in case
+      // fallb ack to showing control panel for all defaults
+      if (NS_FAILED(rv)) {
+        rv = LaunchControlPanelDefaultPrograms();
+      }
+    }
   }
+
   return rv;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
 
--- a/browser/components/shell/src/nsWindowsShellService.h
+++ b/browser/components/shell/src/nsWindowsShellService.h
@@ -20,16 +20,17 @@ public:
   nsWindowsShellService();
   virtual ~nsWindowsShellService();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
-  static nsresult IsDefaultBrowser(bool* aIsDefaultBrowser);
-  static bool IsDefaultBrowserVista(bool* aIsDefaultBrowser);
+  bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
+  nsresult LaunchControlPanelDefaultPrograms();
+  nsresult LaunchHTTPHandlerPane();
 
 private:
   bool      mCheckedThisSession;
 };
 
 #endif // nswindowsshellservice_h____