Contrib/ExperienceUI/Utils/Source/Patcher.nsi
changeset 0 d5ce4c64ef88
equal deleted inserted replaced
-1:000000000000 0:d5ce4c64ef88
       
     1 ; ExperienceUI Patch Installer
       
     2 ; Rewritten as of ExperienceUI 1.11
       
     3 ; Copyright © 2006 Dan Fuhry
       
     4 
       
     5 ; Licensed under the zlib/libpng license
       
     6 
       
     7 ; Written during Bush's State of the Union address on Jan 31, 2006 (also my birthday)
       
     8 
       
     9 ; Dependencies:
       
    10 ; * DcryptDll
       
    11 ; * ZipDLL
       
    12 ; * SigVerify.exe (closed-source application that does the actual signature verification)
       
    13 ; * ExperienceUI
       
    14 ; * System.dll
       
    15 
       
    16 Name "ExperienceUI Patch/Skin Installer"
       
    17 Caption "ExperienceUI Patch/Skin Installer"
       
    18 OutFile ..\PatchInstaller.exe
       
    19 
       
    20 SetCompressor /FINAL /SOLID lzma
       
    21 Var TYPE
       
    22 Var CURRENT
       
    23 Var TOTAL
       
    24 Var NAME
       
    25 Var SILENT
       
    26 Var SIGSTAT
       
    27 Var APPEND
       
    28 Var SRCFILE
       
    29 Var BHWND
       
    30 
       
    31 !define XPUI_ICON patcher.ico
       
    32 !define XPUI_UNICON patcher.ico
       
    33 
       
    34 !define XPUI_WELCOMEPAGE_TEXT_TOP "Welcome to the $(^Name)"
       
    35 !define XPUI_WELCOMEPAGE_TEXT     "This wizard will guide you through the installation of the patch you opened.\r\n\r\nClick Next to start."
       
    36 !define XPUI_WELCOMEPAGE_TITLE    "Welcome"
       
    37 !define XPUI_WELCOMEPAGE_SUBTITLE "Welcome to the $(^Name)."
       
    38 
       
    39 !define XPUI_INSTFILESPAGE_TITLE    "Installing"
       
    40 !define XPUI_INSTFILESPAGE_SUBTITLE "Please wait while the $TYPE you opened is being installed."
       
    41 !define XPUI_INSTFILESPAGE_DONE_SUBTITLE "The $TYPE you opened was installed successfully."
       
    42 
       
    43 !define XPUI_INSTCONFIRMPAGE_TEXT_TOP "The $(^Name) is ready to install the $TYPE."
       
    44 
       
    45 !define XPUI_FINISHPAGE_TITLE    "Installation Complete"
       
    46 !define XPUI_FINISHPAGE_SUBTITLE "The $(^Name) has successfully applied the $TYPE to your ExperienceUI installation."
       
    47 !define XPUI_FINISHPAGE_TEXT_TOP "Completing the ExperienceUI Patch/Skin installation wizard"
       
    48 !define XPUI_FINISHPAGE_TEXT     "The $(^Name) has finished installing the $TYPE you opened.\r\n\r\nPlease click $(^CloseBtn) to exit the $(^Name)."
       
    49 
       
    50 InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ExperienceUI for NSIS" UninstallString
       
    51 SetPluginUnload alwaysoff
       
    52 !include system.nsh
       
    53 
       
    54 !define SOUND_DEFAULT "${MB_OK}"
       
    55 !define SOUND_STOP "${MB_ICONHAND}"
       
    56 !define SOUND_ASTERISK "${MB_ICONASTERISK}"
       
    57 !define SOUND_ERROR "${MB_ICONEXCLAMATION}"
       
    58 !define SOUND_QUESTION "${MB_ICONQUESTION}"
       
    59 
       
    60 !macro AboutDlg
       
    61   System::Call '${sysMessageBeep} (${SOUND_ASTERISK})'
       
    62   !insertmacro smMessageBox '`$EXEDIR\XPUIRes.dll`' 'ExperienceUI for NSIS$\nPatch/Skin Installer (version ${VERSION})$\nCopyright © 2005 Dan Fuhry.$\n$\nTo install a skin or patch, double-click the file in Windows Explorer.$\nTo see this About dialog, run this program with the /ABOUT switch.$\n$\nThis program is a component of the ExperienceUI for NSIS.  Copyright © 2004-2005 Dan Fuhry.$\nThe ExperienceUI was written to provide a pretty alternative to the huge, slow InstallShield®* installers.  The default skin contains colors used by the NVidia® ForceWare™ Setup Program.$\n$\nMore information about the ExperienceUI can be found at http://forums.winamp.com/showthread.php?threadid=204836.$\n$\n*InstallShield is a registered trademark of MacroVision, Inc.  ForceWare is a registered trademark of NVidia, Inc.' 'About the ExperienceUI for NSIS Patch/Skin Installer' '${MB_OK}' 'i 5'
       
    63 !macroend
       
    64 
       
    65 !macro VERIFY FILE HASH
       
    66   Push $1
       
    67   Push $OUTDIR
       
    68   Push $0
       
    69     WriteINIStr $TEMP\Sigdata.ini SigVerify Append $APPEND
       
    70     ExecWait '"$PLUGINSDIR\SigVerify.exe" ${FILE} /Hash=${HASH}' $0
       
    71     StrCmp $0 0 +3
       
    72       StrCpy $1 "Bad"
       
    73       Goto +2
       
    74       StrCpy $1 "Good"
       
    75   Pop $0
       
    76   Pop $OUTDIR
       
    77   Exch $1
       
    78 !macroend
       
    79 
       
    80 !macro CLS
       
    81 Push $9
       
    82 FindWindow $9 "#32770" "" $HWNDPARENT
       
    83 GetDlgItem $9 $9 1016
       
    84 SendMessage $9 0x1009 0 0
       
    85 Pop $9
       
    86 !macroend
       
    87 
       
    88 !macro ERROR TITLE MSG
       
    89   !insertmacro XPUI_HEADER_TEXT "Installation Failed" "The $TYPE installation failed."
       
    90   System::Call '${sysMessageBeep} (${SOUND_STOP})'
       
    91   !insertmacro smMessageBox `$\`$EXEDIR\XPUIRes.dll$\`` `${MSG}` `${TITLE}` `${MB_OK}` `i 1`
       
    92 !macroend
       
    93 
       
    94 !include XPUI.nsh
       
    95 
       
    96 !insertmacro XPUI_PAGE_WELCOME
       
    97 !insertmacro XPUI_PAGE_INSTCONFIRM
       
    98 !insertmacro XPUI_PAGE_INSTFILES
       
    99 !insertmacro XPUI_PAGE_FINISH
       
   100 
       
   101 !insertmacro XPUI_LANGUAGE English
       
   102 
       
   103 VIProductVersion "1.1.0.0"
       
   104 VIAddVersionKey /LANG=1033 "FileVersion" "${VERSION}"
       
   105 VIAddVersionKey /LANG=1033 "ProductVersion" "${VERSION}"
       
   106 VIAddVersionKey /LANG=1033 "ProductName" "ExperienceUI for NSIS"
       
   107 VIAddVersionKey /LANG=1033 "Comments" "This program was written by Dan Fuhry using Nullsoft Scriptable Install System (http://nsis.sourceforge.net)"
       
   108 VIAddVersionKey /LANG=1033 "CompanyName" "Dan Fuhry a. k. a. dandaman32"
       
   109 VIAddVersionKey /LANG=1033 "LegalTrademarks" "ExperienceUI for NSIS by Dan Fuhry. Copyright © 2004-2006 Dan Fuhry"
       
   110 VIAddVersionKey /LANG=1033 "LegalCopyright" "Copyright © Dan Fuhry"
       
   111 VIAddVersionKey /LANG=1033 "FileDescription" "ExperienceUI for NSIS Patch/Skin Installer"
       
   112 VIAddVersionKey /LANG=1033 "SpecialBuild" "ExperienceUI for NSIS Patching/Skinning Engine, version ${VERSION}, built on ${__TIMESTAMP__}"
       
   113 
       
   114 !macro DO_INSTALL
       
   115   BringToFront
       
   116   StrCpy $CURRENT 0
       
   117   StrCmp $SILENT 1 "" loop
       
   118   Banner::show /NOUNLOAD ""
       
   119   Banner::getWindow
       
   120   Pop $BHWND
       
   121   GetDlgItem $BHWND $BHWND 1030
       
   122   Loop:
       
   123     IntOp $CURRENT $CURRENT + 1
       
   124     ReadINIStr $2 $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT"
       
   125     StrCmp $SILENT 1 0 +2
       
   126     SendMessage $BHWND 0xC 0 "STR:Installing $TYPE: $NAME$\nCurrent file: $2"
       
   127     ReadINIStr $SRCFILE $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT SName"
       
   128       StrCmp $SRCFILE "" "" +2
       
   129       StrCpy $SRCFILE $2
       
   130     IfFileExists $TEMP\EUI-Setup\$SRCFILE FoundIt
       
   131       !insertmacro ERROR "Cannot find file" "The $TYPE was opened, extracted, and parsed successfully, but the file $2 could not be found in the archive.  Please contact the author of this $TYPE with the following error code:$\n$\nError: F-PI009 Cannot find source file $2"
       
   132       Call .onGUIend
       
   133       RMDir /r $TEMP\EUI-Setup
       
   134       SetErrorLevel 1
       
   135       Quit
       
   136     FoundIt:
       
   137     ReadINIStr $4 $TEMP\EUI-Setup\Content.dat EUI-$TYPE "File$CURRENT Sig"
       
   138     StrCmp $4 "" NoSig
       
   139       SetDetailsPrint none
       
   140       !insertmacro VERIFY $TEMP\EUI-Setup\$SRCFILE $4
       
   141       Pop $0
       
   142       StrCmp $0 Good NoSig
       
   143       StrCmp $SIGSTAT "Signed and verified" Forged
       
   144       !insertmacro ERROR "Invalid Signature" "The ExperienceUI Patch Installer has found a digital signature assigned to one of the patch files, but the signature was checked and found to be invalid.  This is a fatal error.  Please contact the author of this $TYPE with the following error code:$\n$\nError: F-PI010 Invalid signature hash for file $2$\nAdditional information:$\n    hash value: $4$\n    Return value: $0"
       
   145       Call .onGUIend
       
   146       RMDir /r $TEMP\EUI-Setup
       
   147       SetErrorLevel 1
       
   148       Quit
       
   149       Forged:
       
   150       !insertmacro ERROR "Unsigned file" "The patch installer has found that though the patch itself is signed, one of the files within it is not.  This is a fatal error.  Please contact the author of this patch with the following information:$\n$\nError: F-PI013 Unsigned file in signed patch$\nAdditional information:$\n    File name: $2"
       
   151       Call .onGUIend
       
   152       RMDir /r $TEMP\EUI-Setup
       
   153       SetErrorLevel 1
       
   154       Quit
       
   155     NoSig:
       
   156     StrCmp $4 "" 0 +2
       
   157       StrCmp $SIGSTAT "Signed and verified" Forged ; a backup check
       
   158     ReadINIStr $4 $TEMP\EUI-Setup\Content.dat EUI-$TYPE "File$CURRENT Desc"
       
   159     StrCmp $4 "" NoDesc
       
   160     SetDetailsPrint listonly
       
   161     DetailPrint "Install: $4 - $2 to $INSTDIR\$3"
       
   162     SetDetailsPrint textonly
       
   163     DetailPrint "Installing file: $2 ($4) to $INSTDIR\$3"
       
   164     SetDetailsPrint none
       
   165     Goto cont
       
   166     NoDesc:
       
   167     ReadINIStr $SRCFILE $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT SName"
       
   168     StrCmp $SRCFILE "" 0 +2
       
   169       StrCpy $SRCFILE $2
       
   170     SetDetailsPrint listonly
       
   171     DetailPrint "Install: $2 to $3"
       
   172     SetDetailsPrint textonly
       
   173     DetailPrint "Installing file: $2 to $INSTDIR\$3"
       
   174     SetDetailsPrint none
       
   175     cont:
       
   176     ReadINIStr $3 $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT Path"
       
   177     CreateDirectory $INSTDIR\$3
       
   178     CopyFiles $TEMP\EUI-Setup\$SRCFILE $INSTDIR\$3\$2
       
   179     IntCmp $CURRENT $TOTAL 0 Loop
       
   180   ; We are done
       
   181   StrCmp $SILENT 1 "" ns1
       
   182   Banner::destroy
       
   183   ns1:
       
   184   RMDir /r $TEMP\EUI-Setup
       
   185   SetAutoClose false
       
   186   SetDetailsPrint both
       
   187 !macroend
       
   188 
       
   189 Function .onInit
       
   190   ; Get rid of compiler warnings
       
   191   ;Goto +4
       
   192   ;  Call GetInstallerEXEName
       
   193   ;  Call systemGetFileSysTime
       
   194   ;  Call systemSplash
       
   195     
       
   196   Call GetParameters
       
   197   Pop $0
       
   198   StrCmp $0 "" 0 NotBlank
       
   199     !insertmacro ERROR "Invalid Command Line" "You need to specify the patch/skin file on the command line.$\n$\nError: F-PI001 No parameters on command line"
       
   200     RMDir /r $TEMP\EUI-Setup
       
   201     Quit
       
   202   NotBlank:
       
   203   StrCpy $SILENT 0
       
   204   Push $0
       
   205   Push "/Silent"
       
   206   Call StrStr
       
   207   Pop $1
       
   208   StrCmp $1 "/Silent" "" NoSilent
       
   209     StrCpy $SILENT 1
       
   210     StrLen $2 $1
       
   211     StrLen $3 $0
       
   212     IntOp $2 $3 - $2
       
   213     IntOp $2 $2 - 1
       
   214     StrCpy $0 $0 $2
       
   215   NoSilent:
       
   216   IfFileExists $0 FoundTarget
       
   217     !insertmacro ERROR "Missing File" "The file specified on the command line cannot be found.$\n$\nError: F-PI002 Missing file"
       
   218     RMDir /r $TEMP\EUI-Setup
       
   219     Quit
       
   220   FoundTarget:
       
   221   IfFileExists $INSTDIR\XPUI.nsh FoundXPUI
       
   222     !insertmacro ERROR "Corrupt XPUI Installation" "The ExperienceUI cannot be found on this computer.  It can be downloaded from http://xpui.sourceforge.net/.$\n$\nError: F-PI003 Cannot find XPUI installation"
       
   223     RMDir /r $TEMP\EUI-Setup
       
   224     Quit
       
   225   FoundXPUI:
       
   226   StrLen $1 $0
       
   227   IntOp $1 $1 - 3
       
   228   StrCpy $1 $0 3 $1
       
   229   StrCmp $1 "eup" validext-p
       
   230   StrCmp $1 "eus" validext-s
       
   231     !insertmacro ERROR "Invalid file extension" "The file '$0' was found and the command line was correct, but the extension is not EUP (ExperienceUI Patch) or EUS (ExperienceUI Skin).  Setup will treat this file as a patch.$\n$\nThis is a non-fatal error.$\n$\nError: N-PI004 Invalid file extension $1"
       
   232   validext-s:
       
   233   StrCpy $TYPE "skin"
       
   234   Goto valid
       
   235   validext-p:
       
   236   StrCpy $TYPE "patch"
       
   237   Goto valid
       
   238   valid:
       
   239   RMDir /r $TEMP\EUI-Setup
       
   240   CreateDirectory "$TEMP\EUI-Setup"
       
   241   ClearErrors
       
   242   ZipDLL::extractall "$0" "$TEMP\EUI-Setup"
       
   243   Pop $2
       
   244   StrCmp $2 "success" goodZip
       
   245     !insertmacro ERROR "Zip extract error" "The file '$0' was found and the command line was correct, but the ZIP file extraction module failed.$\n$\nThe following error string was returned by ZipDLL: $2$\n$\nError: F-PI005 ZIP file extraction error"
       
   246     RMDir /r $TEMP\EUI-Setup
       
   247     Quit
       
   248   goodZip:
       
   249   IfFileExists $TEMP\EUI-Setup\Content.dat FoundScript
       
   250     !insertmacro ERROR "Missing script" "The installation script could not be found in the patch/skin file's root directory.  This is a fatal error.  Please contact the author of this patch with the following error code.$\n$\nError: F-PI006 Cannot find installation script"
       
   251     RMDir /r $TEMP\EUI-Setup
       
   252     Quit
       
   253   FoundScript:
       
   254   ClearErrors
       
   255   ReadINIStr $TOTAL $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" NumFiles
       
   256   IntCmp $TOTAL 1 FilesGood 0 FilesGood
       
   257     !insertmacro ERROR "Corrupt script" "The installation script in this patch file is corrupt.  Please redownload the patch file, or contact the author of this patch with the following error code:$\n$\nError: F-PI008 Cannot find INI key NumFiles under section EUI-$TYPE in $$TEMP\EUI-Setup\CONTENT.dat, or NumFiles !>=1"
       
   258     RMDir /r $TEMP\EUI-Setup
       
   259     Quit
       
   260   FilesGood:
       
   261   ; Check for a digital signature
       
   262   
       
   263   ; Extract the verification utility
       
   264   SetOutPath $PLUGINSDIR
       
   265     File SigVerify.exe
       
   266     
       
   267   IfFileExists $TEMP\EUI-Setup\content.sig "" Unsigned
       
   268   FileOpen $R1 $TEMP\EUI-Setup\content.sig r
       
   269     FileRead $R1 $R0 32
       
   270   FileClose $R1
       
   271   StrCmp $SILENT 1 nob1
       
   272   Banner::show /NOUNLOAD "Validating $TYPE digital signature..."
       
   273   nob1:
       
   274   StrCpy $SIGSTAT "Signed and verified"
       
   275   !insertmacro VERIFY $TEMP\EUI-Setup\content.dat $R0
       
   276   StrCmp $SILENT 1 nob2
       
   277   Banner::destroy
       
   278   nob2:
       
   279   Pop $R1
       
   280   StrCmp $R1 Good GoodSig
       
   281     !insertmacro ERROR "Corrupt Signature" "The author who packaged the $TYPE has specified that the file be signed with a digital signature, but after thorough testing, the patch's installation script was found to have an invalid signature.  This is a fatal error.  Please report the following information to the author of this patch:$\n$\nError: F-PI011 Master signature corrupt$\nAdditional information:$\n    BAD signature hash: $R0"
       
   282     RMDir /r $TEMP\EUI-Setup
       
   283     Quit
       
   284     Unsigned:
       
   285     StrCmp $SILENT 1 "" NoS1
       
   286       !insertmacro ERROR "Signature required for silent install" "The ExperienceUI patch installer does not allow silent installations of unsigned patch files.$\n$\nError: F-PI012 Signature required for silent install"
       
   287       RMDir /r $TEMP\EUI-Setup
       
   288       Quit
       
   289     NoS1:
       
   290     StrCpy $SIGSTAT "Unsigned"
       
   291     System::Call '${sysMessageBeep} (${SOUND_QUESTION})'
       
   292     !insertmacro smMessageBox `$\`$EXEDIR\XPUIRes.dll$\`` `The file you are opening is a valid $TYPE, but the Patch Installer has detected that it has not been signed with any digital signature.  While you may continue installing this $TYPE, it is important to remember that ExperienceUI $TYPE files are really just glorified ZIP files, and it is possible to put malicious code into them.  You should only continue if you trust the source of this $TYPE.$\n$\nDo you really want to continue?` `Unsigned $TYPE` `${MB_YESNO}` `i 1`
       
   293     StrCmp $R0 6 SigDone
       
   294     RMDir /r $TEMP\EUI-Setup
       
   295     Quit
       
   296   GoodSig:
       
   297     ReadINIStr $R0 $TEMP\EUI-Setup\Content.dat SigInfo PN
       
   298     ReadINIStr $R1 $TEMP\EUI-Setup\Content.dat SigInfo PE
       
   299     ReadINIStr $R2 $TEMP\EUI-Setup\Content.dat SigInfo CN
       
   300     ReadINIStr $R3 $TEMP\EUI-Setup\Content.dat SigInfo CE
       
   301     StrCmp $R0 "" SigDone
       
   302     StrCpy $APPEND ";PN=$R0;PE=$R1;CN=$R2;CE=$R3"
       
   303     StrCpy $SIGSTAT "$SIGSTAT$\n  Signed by: $R2$\n  Signer's E-mail: $R3"
       
   304   SigDone:
       
   305   ReadINIStr $NAME $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" Name
       
   306   StrCmp $SILENT 1 "" NoS2
       
   307     !insertmacro DO_INSTALL
       
   308     SetErrorLevel 0
       
   309     Quit
       
   310   NoS2:
       
   311 FunctionEnd
       
   312 
       
   313 Section
       
   314   StrCmp $NAME "" NoName
       
   315     HideWindow
       
   316     System::Call '${sysMessageBeep} (${SOUND_QUESTION})'
       
   317     !insertmacro smMessageBox '`$EXEDIR\XPUIRes.dll`' 'You are about to install a $TYPE from the following location:$\n$\n  Name: $NAME$\n  File location: $0$\n  Signature status: $SIGSTAT$\n$\nContinue?' 'ExperienceUI Setup' '${MB_YESNO}' 'i 2'
       
   318     StrCmp $R0 7 0 NoName
       
   319     Call .onGUIEnd
       
   320     RMDir /r $TEMP\EUI-Setup
       
   321     Quit
       
   322   NoName:
       
   323   !insertmacro DO_INSTALL
       
   324 SectionEnd
       
   325 
       
   326 Function GetParameters
       
   327 Push $R0
       
   328 Push $R1
       
   329 Push $R2
       
   330 Push $R3
       
   331 StrCpy $R2 1
       
   332 StrLen $R3 $CMDLINE
       
   333 ;Check for quote or space
       
   334 StrCpy $R0 $CMDLINE $R2
       
   335 StrCmp $R0 '"' 0 +3
       
   336 StrCpy $R1 '"'
       
   337 Goto loop
       
   338 StrCpy $R1 " "
       
   339 loop:
       
   340 IntOp $R2 $R2 + 1
       
   341 StrCpy $R0 $CMDLINE 1 $R2
       
   342 StrCmp $R0 $R1 get
       
   343 StrCmp $R2 $R3 get
       
   344 Goto loop
       
   345 get:
       
   346 IntOp $R2 $R2 + 1
       
   347 StrCpy $R0 $CMDLINE 1 $R2
       
   348 StrCmp $R0 " " get
       
   349 StrCpy $R0 $CMDLINE "" $R2
       
   350 Pop $R3
       
   351 Pop $R2
       
   352 Pop $R1
       
   353 Exch $R0
       
   354 FunctionEnd
       
   355 
       
   356  Function StrStr
       
   357    Exch $R1 ; st=haystack,old$R1, $R1=needle
       
   358    Exch    ; st=old$R1,haystack
       
   359    Exch $R2 ; st=old$R1,old$R2, $R2=haystack
       
   360    Push $R3
       
   361    Push $R4
       
   362    Push $R5
       
   363    StrLen $R3 $R1
       
   364    StrCpy $R4 0
       
   365    ; $R1=needle
       
   366    ; $R2=haystack
       
   367    ; $R3=len(needle)
       
   368    ; $R4=cnt
       
   369    ; $R5=tmp
       
   370    loop:
       
   371      StrCpy $R5 $R2 $R3 $R4
       
   372      StrCmp $R5 $R1 done
       
   373      StrCmp $R5 "" done
       
   374      IntOp $R4 $R4 + 1
       
   375      Goto loop
       
   376  done:
       
   377    StrCpy $R1 $R2 "" $R4
       
   378    Pop $R5
       
   379    Pop $R4
       
   380    Pop $R3
       
   381    Pop $R2
       
   382    Exch $R1
       
   383  FunctionEnd