Bug 1120673 - Verify Firewall service is running before adding Firewall exceptions - Fx 35 installer crashes on XP x86 SP3 at the end (creating shortcuts) if the xp firewall service is stopped. r=bbondy, a=sledru
authorRobert Strong <robert.bugzilla@gmail.com>
Thu, 15 Jan 2015 13:13:13 -0800
changeset 242891 bc2de4c07f1b
parent 242890 f154bf489b34
child 242892 66f61f3f9664
push id4330
push userryanvm@gmail.com
push date2015-01-16 15:19 +0000
treeherdermozilla-beta@0b7d9ce1cdc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, sledru
bugs1120673
milestone36.0
Bug 1120673 - Verify Firewall service is running before adding Firewall exceptions - Fx 35 installer crashes on XP x86 SP3 at the end (creating shortcuts) if the xp firewall service is stopped. r=bbondy, a=sledru
browser/installer/windows/nsis/installer.nsi
browser/installer/windows/nsis/shared.nsh
browser/installer/windows/nsis/uninstaller.nsi
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -584,19 +584,16 @@ Section "-Application" APP_IDX
         ; know the correct full path.
         ${LogMsg} "Added Quick Launch Shortcut: ${BrandFullName}.lnk"
         GetFunctionAddress $0 AddQuickLaunchShortcut
         UAC::ExecCodeSegment $0
       ${EndIf}
     ${EndUnless}
   ${EndIf}
 
-  ; Add the Firewall entries during install
-  Call AddFirewallEntries
-
 !ifdef MOZ_MAINTENANCE_SERVICE
   ${If} $TmpVal == "HKLM"
     ; Add the registry keys for allowed certificates.
     ${AddMaintCertKeys}
   ${EndIf}
 !endif
 SectionEnd
 
@@ -622,16 +619,19 @@ Section "-InstallEndCleanup"
     ${EndIf}
     ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details).
     ${MigrateTaskBarShortcut}
   ${EndUnless}
 
   ${GetShortcutsLogPath} $0
   WriteIniStr "$0" "TASKBAR" "Migrated" "true"
 
+  ; Add the Firewall entries during install
+  Call AddFirewallEntries
+
   ; Refresh desktop icons
   System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_DWORDFLUSH}, i 0, i 0)"
 
   ${InstallEndCleanupCommon}
 
   ${If} $PreventRebootRequired == "true"
     SetRebootFlag false
   ${EndIf}
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -933,17 +933,17 @@ FunctionEnd
     ReadRegStr $2 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
     System::Call "advapi32::RegLoadKey(i ${HKEY_USERS}, t 'User-$0', t '$2\ntuser.dat')"
     System::Call "advapi32::RegLoadKey(i ${HKEY_USERS}, t 'User-$0_Classes', t '$2\AppData\Local\Microsoft\Windows\UsrClass.dat')"
     IntOp $0 $0 + 1
   ${Loop}
 !macroend
 !define MountRegistryIntoHKU "!insertmacro MountRegistryIntoHKU"
 !define un.MountRegistryIntoHKU "!insertmacro MountRegistryIntoHKU"
-;
+
 ; Unmounts all user ntuser.dat files into the registry as a subkey of HKU
 !macro UnmountRegistryIntoHKU
   ; $0 is used as an index for HKEY_USERS enumeration
   StrCpy $0 0
   ${Do}
     EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
     ${If} $1 == ""
       ${Break}
@@ -1551,16 +1551,82 @@ FunctionEnd
   Push "sandboxbroker.dll"
   Push "xpcom.dll"
   Push "crashreporter.exe"
   Push "updater.exe"
   Push "${FileMainEXE}"
 !macroend
 !define PushFilesToCheck "!insertmacro PushFilesToCheck"
 
+
+; Pushes the string "true" to the top of the stack if the Firewall service is
+; running and pushes the string "false" to the top of the stack if it isn't.
+!define SC_MANAGER_ALL_ACCESS 0x3F
+!define SERVICE_QUERY_CONFIG 0x0001
+!define SERVICE_QUERY_STATUS 0x0004
+!define SERVICE_RUNNING 0x4
+
+!macro IsFirewallSvcRunning
+  Push $R9
+  Push $R8
+  Push $R7
+  Push $R6
+  Push "false"
+
+  System::Call 'advapi32::OpenSCManagerW(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.R6'
+  ${If} $R6 != 0
+    ; MpsSvc is the Firewall service on Windows Vista and above.
+    ; When opening the service with SERVICE_QUERY_CONFIG the return value will
+    ; be 0 if the service is not installed.
+    System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_CONFIG}) i.R7'
+    ${If} $R7 != 0
+      System::Call 'advapi32::CloseServiceHandle(i R7) n'
+      ; Open the service with SERVICE_QUERY_CONFIG so its status can be queried.
+      System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_STATUS}) i.R7'
+    ${Else}
+      ; SharedAccess is the Firewall service on Windows XP.
+      ; When opening the service with SERVICE_QUERY_CONFIG the return value will
+      ; be 0 if the service is not installed.
+      System::Call 'advapi32::OpenServiceW(i R6, t "SharedAccess", i ${SERVICE_QUERY_CONFIG}) i.R7'
+      ${If} $R7 != 0
+        System::Call 'advapi32::CloseServiceHandle(i R7) n'
+        ; Open the service with SERVICE_QUERY_CONFIG so its status can be
+        ; queried.
+        System::Call 'advapi32::OpenServiceW(i R6, t "SharedAccess", i ${SERVICE_QUERY_STATUS}) i.R7'
+      ${EndIf}
+    ${EndIf}
+    ; Did the calls to OpenServiceW succeed?
+    ${If} $R7 != 0
+      System::Call '*(i,i,i,i,i,i,i) i.R9'
+      ; Query the current status of the service.
+      System::Call 'advapi32::QueryServiceStatus(i R7, i $R9) i'
+      System::Call '*$R9(i, i.R8)'
+      System::Free $R9
+      System::Call 'advapi32::CloseServiceHandle(i R7) n'
+      IntFmt $R8 "0x%X" $R8
+      ${If} $R8 == ${SERVICE_RUNNING}
+        Pop $R9
+        Push "true"
+      ${EndIf}
+    ${EndIf}
+    System::Call 'advapi32::CloseServiceHandle(i R6) n'
+  ${EndIf}
+
+  Exch 1
+  Pop $R6
+  Exch 1
+  Pop $R7
+  Exch 1
+  Pop $R8
+  Exch 1
+  Pop $R9
+!macroend
+!define IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning"
+!define un.IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning"
+
 ; Sets this installation as the default browser by setting the registry keys
 ; under HKEY_CURRENT_USER via registry calls and using the AppAssocReg NSIS
 ; plugin for Vista and above. This is a function instead of a macro so it is
 ; easily called from an elevated instance of the binary. Since this can be
 ; called by an elevated instance logging is not performed in this function.
 Function SetAsDefaultAppUserHKCU
   ; Only set as the user's StartMenuInternet browser if the StartMenuInternet
   ; registry keys are for this install.
@@ -1614,18 +1680,23 @@ FunctionEnd
 ; Helper for updating the shortcut application model IDs.
 Function FixShortcutAppModelIDs
   ${If} ${AtLeastWin7}
   ${AndIf} "$AppUserModelID" != ""
     ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "$AppUserModelID" $0
   ${EndIf}
 FunctionEnd
 
+; Helper for adding Firewall exceptions during install and after app update.
 Function AddFirewallEntries
-	liteFirewallW::AddRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)"
+  ${IsFirewallSvcRunning}
+  Pop $0
+  ${If} "$0" == "true"
+    liteFirewallW::AddRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)"
+  ${EndIf}
 FunctionEnd
 
 ; The !ifdef NO_LOG prevents warnings when compiling the installer.nsi due to
 ; this function only being used by the uninstaller.nsi.
 !ifdef NO_LOG
 
 Function SetAsDefaultAppUser
   ; On Win8, we want to avoid having a UAC prompt since we'll already have
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -459,18 +459,16 @@ Section "Uninstall"
         FileOpen $0 "$INSTDIR\${FileMainEXE}.moz-delete" w
         FileWrite $0 "Will be deleted on restart"
         Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete"
         FileClose $0
       ${EndUnless}
     ${EndIf}
   ${EndIf}
 
-	liteFirewallW::RemoveRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)"
-
   ; Refresh desktop icons otherwise the start menu internet item won't be
   ; removed and other ugly things will happen like recreation of the app's
   ; clients registry key by the OS under some conditions.
   System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i 0, i 0, i 0)"
 
 !ifdef MOZ_MAINTENANCE_SERVICE
   ; Get the path the allowed cert is at and remove it
   ; Keep this block of code last since it modfies the reg view
@@ -484,16 +482,21 @@ Section "Uninstall"
     DeleteRegKey HKLM "$MaintCertKey"
     ${If} ${RunningX64}
       SetRegView lastused
     ${EndIf}
   ${EndIf}
   Call un.UninstallServiceIfNotUsed
 !endif
 
+  ${un.IsFirewallSvcRunning}
+  Pop $0
+  ${If} "$0" == "true"
+    liteFirewallW::RemoveRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)"
+  ${EndIf}
 SectionEnd
 
 ################################################################################
 # Language
 
 !insertmacro MOZ_MUI_LANGUAGE 'baseLocale'
 !verbose push
 !verbose 3