[idd] install: quiesce devices during driver updates

Stop LGIddHelper before updating either UMDF stack. Disable LGInput
before LGIdd, update both packages while quiesced, then restore the
provider before its dependent and start the service last.

Use in-use replacement for UMDF binaries and prevent the INF from
restarting the Helper during package installation. Report each
SetupAPI restart result and propagate it through NSIS.

Roll back transaction-owned devices, packages, and service state on
fresh-install failure. Preserve dependency order during removal and
select the package actually installed on each devnode.
This commit is contained in:
Geoffrey McRae
2026-08-15 18:50:44 +10:00
parent fd2357565a
commit a1f11bcc3e
4 changed files with 781 additions and 80 deletions

View File

@@ -50,6 +50,9 @@ InstallDir "$PROGRAMFILES64\Looking Glass (IDD)"
!define MUI_TEXTCOLOR "ffffff"
!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\nsis3-grey.bmp"
!define /file VERSION "VERSION"
!define LGIDD_EXIT_RESTART_REQUIRED 12
; The operation failed, but a partial change or rollback still needs reboot.
!define LGIDD_EXIT_FAILURE_RESTART_REQUIRED 13
!define MUI_WELCOMEPAGE_TEXT "\
You are about to install $(^Name) version ${VERSION}.$\n$\n\
@@ -118,18 +121,6 @@ Function .onInit
FunctionEnd
!macro StopLGIddHelper
;Attempt to stop existing LG service only if it exists
nsExec::Exec 'sc.exe query LGIddHelper'
Pop $0 ; SC.exe error level
${If} $0 == 0 ; If error level is 0, service exists
DetailPrint "Stop service: LGIddHelper"
nsExec::ExecToLog 'net.exe STOP LGIddHelper'
${EndIf}
!macroend
;Install
!ifdef IVSHMEM
Section "IVSHMEM Driver" Section0
@@ -207,23 +198,44 @@ Section "!Indirect Display Driver (IDD)" Section1
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Looking Glass (IDD)" \
"DisplayVersion" ${VERSION}
!insertmacro StopLGIddHelper
DetailPrint "Installing IDD"
nsExec::ExecToLog '"$INSTDIR\LGIddInstall.exe" install'
Pop $0
${If} $0 == 12
${If} $0 == ${LGIDD_EXIT_RESTART_REQUIRED}
DetailPrint "Restart is required to complete driver install."
SetRebootFlag true
${ElseIf} $0 == ${LGIDD_EXIT_FAILURE_RESTART_REQUIRED}
DetailPrint "Driver installation failed and a restart is required."
SetRebootFlag true
SetErrorLevel $0
Abort
${ElseIf} $0 != 0
DetailPrint "Driver installation failed with exit code $0."
SetErrorLevel $0
Abort
${EndIf}
SectionEnd
Section "Uninstall" Section6
!insertmacro StopLGIddHelper
DetailPrint "Uninstalling IDD"
nsExec::ExecToLog '"$INSTDIR\LGIddInstall.exe" uninstall'
Pop $0
${If} $0 == ${LGIDD_EXIT_RESTART_REQUIRED}
DetailPrint "Restart is required to complete driver uninstall."
SetRebootFlag true
${ElseIf} $0 == ${LGIDD_EXIT_FAILURE_RESTART_REQUIRED}
DetailPrint "Driver uninstallation failed and a restart is required."
SetRebootFlag true
SetErrorLevel $0
Abort
${ElseIf} $0 != 0
DetailPrint "Driver uninstallation failed with exit code $0."
SetErrorLevel $0
Abort
${EndIf}
DetailPrint "Clean up helper service"
nsExec::Exec 'sc.exe delete LGIddHelper'