Bug 1251819 - Use the classic Control Panel if the Settings app believes the current Windows logon is a Microsoft account while actually it is not. r=jimm
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Sat, 02 Apr 2016 08:17:16 +0900
changeset 291464 dbfc218a57449d4b3c0050322e47f83246600c48
parent 291463 57626d2359e0b625a7cdbb6eab381200ec0ebaf8
child 291465 6f4210b98c4b8f892fafddc1ca0b1c7638427f5c
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1251819
milestone48.0a1
Bug 1251819 - Use the classic Control Panel if the Settings app believes the current Windows logon is a Microsoft account while actually it is not. r=jimm
browser/components/shell/nsWindowsShellService.cpp
browser/components/shell/nsWindowsShellService.h
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -45,16 +45,19 @@
 #undef NTDDI_VERSION
 #define NTDDI_VERSION NTDDI_WIN8
 // Needed for access to IApplicationActivationManager
 #include <shlobj.h>
 
 #include <mbstring.h>
 #include <shlwapi.h>
 
+#include <lm.h>
+#undef ACCESS_READ
+
 #ifndef MAX_BUF
 #define MAX_BUF 4096
 #endif
 
 #define REG_SUCCEEDED(val) \
   (val == ERROR_SUCCESS)
 
 #define REG_FAILED(val) \
@@ -638,18 +641,105 @@ nsWindowsShellService::LaunchControlPane
   if (SUCCEEDED(hr)) {
     hr = pAARUI->LaunchAdvancedAssociationUI(APP_REG_NAME);
     pAARUI->Release();
   }
   return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
+nsWindowsShellService::LaunchControlPanelDefaultPrograms()
+{
+  // Default Programs is a Vista+ feature
+  if (!IsVistaOrLater()) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // 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, nullptr, nullptr, FALSE,
+                      0, nullptr, nullptr, &si, &pi)) {
+    return NS_ERROR_FAILURE;
+  }
+  CloseHandle(pi.hProcess);
+  CloseHandle(pi.hThread);
+
+  return NS_OK;
+}
+
+static bool
+IsWindowsLogonConnected()
+{
+  WCHAR userName[UNLEN + 1];
+  DWORD size = ArrayLength(userName);
+  if (!GetUserNameW(userName, &size)) {
+    return false;
+  }
+
+  LPUSER_INFO_24 info;
+  if (NetUserGetInfo(nullptr, userName, 24, (LPBYTE *)&info)
+      != NERR_Success) {
+    return false;
+  }
+  bool connected = info->usri24_internet_identity;
+  NetApiBufferFree(info);
+
+  return connected;
+}
+
+static bool
+SettingsAppBelievesConnected()
+{
+  nsresult rv;
+  nsCOMPtr<nsIWindowsRegKey> regKey =
+    do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
+                    NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\Shell\\Associations"),
+                    nsIWindowsRegKey::ACCESS_READ);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  uint32_t value;
+  rv = regKey->ReadIntValue(NS_LITERAL_STRING("IsConnectedAtLogon"), &value);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  return !!value;
+}
+
+nsresult
 nsWindowsShellService::LaunchModernSettingsDialogDefaultApps()
 {
+  if (!IsWindowsLogonConnected() && SettingsAppBelievesConnected()) {
+    // Use the classic Control Panel to work around a bug of Windows 10.
+    return LaunchControlPanelDefaultPrograms();
+  }
+
   IApplicationActivationManager* pActivator;
   HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager,
                                 nullptr,
                                 CLSCTX_INPROC,
                                 IID_IApplicationActivationManager,
                                 (void**)&pActivator);
 
   if (SUCCEEDED(hr)) {
--- a/browser/components/shell/nsWindowsShellService.h
+++ b/browser/components/shell/nsWindowsShellService.h
@@ -23,14 +23,15 @@ public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
   bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
   nsresult LaunchControlPanelDefaultsSelectionUI();
+  nsresult LaunchControlPanelDefaultPrograms();
   nsresult LaunchModernSettingsDialogDefaultApps();
   nsresult InvokeHTTPOpenAsVerb();
   nsresult LaunchHTTPHandlerPane();
 };
 
 #endif // nswindowsshellservice_h____