Contrib/ExperienceUI/Utils/Source/Patcher.nsi
changeset 0 d5ce4c64ef88
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Contrib/ExperienceUI/Utils/Source/Patcher.nsi	Tue Oct 16 00:07:41 2007 -0400
@@ -0,0 +1,383 @@
+; ExperienceUI Patch Installer
+; Rewritten as of ExperienceUI 1.11
+; Copyright © 2006 Dan Fuhry
+
+; Licensed under the zlib/libpng license
+
+; Written during Bush's State of the Union address on Jan 31, 2006 (also my birthday)
+
+; Dependencies:
+; * DcryptDll
+; * ZipDLL
+; * SigVerify.exe (closed-source application that does the actual signature verification)
+; * ExperienceUI
+; * System.dll
+
+Name "ExperienceUI Patch/Skin Installer"
+Caption "ExperienceUI Patch/Skin Installer"
+OutFile ..\PatchInstaller.exe
+
+SetCompressor /FINAL /SOLID lzma
+Var TYPE
+Var CURRENT
+Var TOTAL
+Var NAME
+Var SILENT
+Var SIGSTAT
+Var APPEND
+Var SRCFILE
+Var BHWND
+
+!define XPUI_ICON patcher.ico
+!define XPUI_UNICON patcher.ico
+
+!define XPUI_WELCOMEPAGE_TEXT_TOP "Welcome to the $(^Name)"
+!define XPUI_WELCOMEPAGE_TEXT     "This wizard will guide you through the installation of the patch you opened.\r\n\r\nClick Next to start."
+!define XPUI_WELCOMEPAGE_TITLE    "Welcome"
+!define XPUI_WELCOMEPAGE_SUBTITLE "Welcome to the $(^Name)."
+
+!define XPUI_INSTFILESPAGE_TITLE    "Installing"
+!define XPUI_INSTFILESPAGE_SUBTITLE "Please wait while the $TYPE you opened is being installed."
+!define XPUI_INSTFILESPAGE_DONE_SUBTITLE "The $TYPE you opened was installed successfully."
+
+!define XPUI_INSTCONFIRMPAGE_TEXT_TOP "The $(^Name) is ready to install the $TYPE."
+
+!define XPUI_FINISHPAGE_TITLE    "Installation Complete"
+!define XPUI_FINISHPAGE_SUBTITLE "The $(^Name) has successfully applied the $TYPE to your ExperienceUI installation."
+!define XPUI_FINISHPAGE_TEXT_TOP "Completing the ExperienceUI Patch/Skin installation wizard"
+!define XPUI_FINISHPAGE_TEXT     "The $(^Name) has finished installing the $TYPE you opened.\r\n\r\nPlease click $(^CloseBtn) to exit the $(^Name)."
+
+InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ExperienceUI for NSIS" UninstallString
+SetPluginUnload alwaysoff
+!include system.nsh
+
+!define SOUND_DEFAULT "${MB_OK}"
+!define SOUND_STOP "${MB_ICONHAND}"
+!define SOUND_ASTERISK "${MB_ICONASTERISK}"
+!define SOUND_ERROR "${MB_ICONEXCLAMATION}"
+!define SOUND_QUESTION "${MB_ICONQUESTION}"
+
+!macro AboutDlg
+  System::Call '${sysMessageBeep} (${SOUND_ASTERISK})'
+  !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'
+!macroend
+
+!macro VERIFY FILE HASH
+  Push $1
+  Push $OUTDIR
+  Push $0
+    WriteINIStr $TEMP\Sigdata.ini SigVerify Append $APPEND
+    ExecWait '"$PLUGINSDIR\SigVerify.exe" ${FILE} /Hash=${HASH}' $0
+    StrCmp $0 0 +3
+      StrCpy $1 "Bad"
+      Goto +2
+      StrCpy $1 "Good"
+  Pop $0
+  Pop $OUTDIR
+  Exch $1
+!macroend
+
+!macro CLS
+Push $9
+FindWindow $9 "#32770" "" $HWNDPARENT
+GetDlgItem $9 $9 1016
+SendMessage $9 0x1009 0 0
+Pop $9
+!macroend
+
+!macro ERROR TITLE MSG
+  !insertmacro XPUI_HEADER_TEXT "Installation Failed" "The $TYPE installation failed."
+  System::Call '${sysMessageBeep} (${SOUND_STOP})'
+  !insertmacro smMessageBox `$\`$EXEDIR\XPUIRes.dll$\`` `${MSG}` `${TITLE}` `${MB_OK}` `i 1`
+!macroend
+
+!include XPUI.nsh
+
+!insertmacro XPUI_PAGE_WELCOME
+!insertmacro XPUI_PAGE_INSTCONFIRM
+!insertmacro XPUI_PAGE_INSTFILES
+!insertmacro XPUI_PAGE_FINISH
+
+!insertmacro XPUI_LANGUAGE English
+
+VIProductVersion "1.1.0.0"
+VIAddVersionKey /LANG=1033 "FileVersion" "${VERSION}"
+VIAddVersionKey /LANG=1033 "ProductVersion" "${VERSION}"
+VIAddVersionKey /LANG=1033 "ProductName" "ExperienceUI for NSIS"
+VIAddVersionKey /LANG=1033 "Comments" "This program was written by Dan Fuhry using Nullsoft Scriptable Install System (http://nsis.sourceforge.net)"
+VIAddVersionKey /LANG=1033 "CompanyName" "Dan Fuhry a. k. a. dandaman32"
+VIAddVersionKey /LANG=1033 "LegalTrademarks" "ExperienceUI for NSIS by Dan Fuhry. Copyright © 2004-2006 Dan Fuhry"
+VIAddVersionKey /LANG=1033 "LegalCopyright" "Copyright © Dan Fuhry"
+VIAddVersionKey /LANG=1033 "FileDescription" "ExperienceUI for NSIS Patch/Skin Installer"
+VIAddVersionKey /LANG=1033 "SpecialBuild" "ExperienceUI for NSIS Patching/Skinning Engine, version ${VERSION}, built on ${__TIMESTAMP__}"
+
+!macro DO_INSTALL
+  BringToFront
+  StrCpy $CURRENT 0
+  StrCmp $SILENT 1 "" loop
+  Banner::show /NOUNLOAD ""
+  Banner::getWindow
+  Pop $BHWND
+  GetDlgItem $BHWND $BHWND 1030
+  Loop:
+    IntOp $CURRENT $CURRENT + 1
+    ReadINIStr $2 $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT"
+    StrCmp $SILENT 1 0 +2
+    SendMessage $BHWND 0xC 0 "STR:Installing $TYPE: $NAME$\nCurrent file: $2"
+    ReadINIStr $SRCFILE $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT SName"
+      StrCmp $SRCFILE "" "" +2
+      StrCpy $SRCFILE $2
+    IfFileExists $TEMP\EUI-Setup\$SRCFILE FoundIt
+      !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"
+      Call .onGUIend
+      RMDir /r $TEMP\EUI-Setup
+      SetErrorLevel 1
+      Quit
+    FoundIt:
+    ReadINIStr $4 $TEMP\EUI-Setup\Content.dat EUI-$TYPE "File$CURRENT Sig"
+    StrCmp $4 "" NoSig
+      SetDetailsPrint none
+      !insertmacro VERIFY $TEMP\EUI-Setup\$SRCFILE $4
+      Pop $0
+      StrCmp $0 Good NoSig
+      StrCmp $SIGSTAT "Signed and verified" Forged
+      !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"
+      Call .onGUIend
+      RMDir /r $TEMP\EUI-Setup
+      SetErrorLevel 1
+      Quit
+      Forged:
+      !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"
+      Call .onGUIend
+      RMDir /r $TEMP\EUI-Setup
+      SetErrorLevel 1
+      Quit
+    NoSig:
+    StrCmp $4 "" 0 +2
+      StrCmp $SIGSTAT "Signed and verified" Forged ; a backup check
+    ReadINIStr $4 $TEMP\EUI-Setup\Content.dat EUI-$TYPE "File$CURRENT Desc"
+    StrCmp $4 "" NoDesc
+    SetDetailsPrint listonly
+    DetailPrint "Install: $4 - $2 to $INSTDIR\$3"
+    SetDetailsPrint textonly
+    DetailPrint "Installing file: $2 ($4) to $INSTDIR\$3"
+    SetDetailsPrint none
+    Goto cont
+    NoDesc:
+    ReadINIStr $SRCFILE $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT SName"
+    StrCmp $SRCFILE "" 0 +2
+      StrCpy $SRCFILE $2
+    SetDetailsPrint listonly
+    DetailPrint "Install: $2 to $3"
+    SetDetailsPrint textonly
+    DetailPrint "Installing file: $2 to $INSTDIR\$3"
+    SetDetailsPrint none
+    cont:
+    ReadINIStr $3 $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" "File$CURRENT Path"
+    CreateDirectory $INSTDIR\$3
+    CopyFiles $TEMP\EUI-Setup\$SRCFILE $INSTDIR\$3\$2
+    IntCmp $CURRENT $TOTAL 0 Loop
+  ; We are done
+  StrCmp $SILENT 1 "" ns1
+  Banner::destroy
+  ns1:
+  RMDir /r $TEMP\EUI-Setup
+  SetAutoClose false
+  SetDetailsPrint both
+!macroend
+
+Function .onInit
+  ; Get rid of compiler warnings
+  ;Goto +4
+  ;  Call GetInstallerEXEName
+  ;  Call systemGetFileSysTime
+  ;  Call systemSplash
+    
+  Call GetParameters
+  Pop $0
+  StrCmp $0 "" 0 NotBlank
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  NotBlank:
+  StrCpy $SILENT 0
+  Push $0
+  Push "/Silent"
+  Call StrStr
+  Pop $1
+  StrCmp $1 "/Silent" "" NoSilent
+    StrCpy $SILENT 1
+    StrLen $2 $1
+    StrLen $3 $0
+    IntOp $2 $3 - $2
+    IntOp $2 $2 - 1
+    StrCpy $0 $0 $2
+  NoSilent:
+  IfFileExists $0 FoundTarget
+    !insertmacro ERROR "Missing File" "The file specified on the command line cannot be found.$\n$\nError: F-PI002 Missing file"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  FoundTarget:
+  IfFileExists $INSTDIR\XPUI.nsh FoundXPUI
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  FoundXPUI:
+  StrLen $1 $0
+  IntOp $1 $1 - 3
+  StrCpy $1 $0 3 $1
+  StrCmp $1 "eup" validext-p
+  StrCmp $1 "eus" validext-s
+    !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"
+  validext-s:
+  StrCpy $TYPE "skin"
+  Goto valid
+  validext-p:
+  StrCpy $TYPE "patch"
+  Goto valid
+  valid:
+  RMDir /r $TEMP\EUI-Setup
+  CreateDirectory "$TEMP\EUI-Setup"
+  ClearErrors
+  ZipDLL::extractall "$0" "$TEMP\EUI-Setup"
+  Pop $2
+  StrCmp $2 "success" goodZip
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  goodZip:
+  IfFileExists $TEMP\EUI-Setup\Content.dat FoundScript
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  FoundScript:
+  ClearErrors
+  ReadINIStr $TOTAL $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" NumFiles
+  IntCmp $TOTAL 1 FilesGood 0 FilesGood
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  FilesGood:
+  ; Check for a digital signature
+  
+  ; Extract the verification utility
+  SetOutPath $PLUGINSDIR
+    File SigVerify.exe
+    
+  IfFileExists $TEMP\EUI-Setup\content.sig "" Unsigned
+  FileOpen $R1 $TEMP\EUI-Setup\content.sig r
+    FileRead $R1 $R0 32
+  FileClose $R1
+  StrCmp $SILENT 1 nob1
+  Banner::show /NOUNLOAD "Validating $TYPE digital signature..."
+  nob1:
+  StrCpy $SIGSTAT "Signed and verified"
+  !insertmacro VERIFY $TEMP\EUI-Setup\content.dat $R0
+  StrCmp $SILENT 1 nob2
+  Banner::destroy
+  nob2:
+  Pop $R1
+  StrCmp $R1 Good GoodSig
+    !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"
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+    Unsigned:
+    StrCmp $SILENT 1 "" NoS1
+      !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"
+      RMDir /r $TEMP\EUI-Setup
+      Quit
+    NoS1:
+    StrCpy $SIGSTAT "Unsigned"
+    System::Call '${sysMessageBeep} (${SOUND_QUESTION})'
+    !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`
+    StrCmp $R0 6 SigDone
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  GoodSig:
+    ReadINIStr $R0 $TEMP\EUI-Setup\Content.dat SigInfo PN
+    ReadINIStr $R1 $TEMP\EUI-Setup\Content.dat SigInfo PE
+    ReadINIStr $R2 $TEMP\EUI-Setup\Content.dat SigInfo CN
+    ReadINIStr $R3 $TEMP\EUI-Setup\Content.dat SigInfo CE
+    StrCmp $R0 "" SigDone
+    StrCpy $APPEND ";PN=$R0;PE=$R1;CN=$R2;CE=$R3"
+    StrCpy $SIGSTAT "$SIGSTAT$\n  Signed by: $R2$\n  Signer's E-mail: $R3"
+  SigDone:
+  ReadINIStr $NAME $TEMP\EUI-Setup\Content.dat "EUI-$TYPE" Name
+  StrCmp $SILENT 1 "" NoS2
+    !insertmacro DO_INSTALL
+    SetErrorLevel 0
+    Quit
+  NoS2:
+FunctionEnd
+
+Section
+  StrCmp $NAME "" NoName
+    HideWindow
+    System::Call '${sysMessageBeep} (${SOUND_QUESTION})'
+    !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'
+    StrCmp $R0 7 0 NoName
+    Call .onGUIEnd
+    RMDir /r $TEMP\EUI-Setup
+    Quit
+  NoName:
+  !insertmacro DO_INSTALL
+SectionEnd
+
+Function GetParameters
+Push $R0
+Push $R1
+Push $R2
+Push $R3
+StrCpy $R2 1
+StrLen $R3 $CMDLINE
+;Check for quote or space
+StrCpy $R0 $CMDLINE $R2
+StrCmp $R0 '"' 0 +3
+StrCpy $R1 '"'
+Goto loop
+StrCpy $R1 " "
+loop:
+IntOp $R2 $R2 + 1
+StrCpy $R0 $CMDLINE 1 $R2
+StrCmp $R0 $R1 get
+StrCmp $R2 $R3 get
+Goto loop
+get:
+IntOp $R2 $R2 + 1
+StrCpy $R0 $CMDLINE 1 $R2
+StrCmp $R0 " " get
+StrCpy $R0 $CMDLINE "" $R2
+Pop $R3
+Pop $R2
+Pop $R1
+Exch $R0
+FunctionEnd
+
+ Function StrStr
+   Exch $R1 ; st=haystack,old$R1, $R1=needle
+   Exch    ; st=old$R1,haystack
+   Exch $R2 ; st=old$R1,old$R2, $R2=haystack
+   Push $R3
+   Push $R4
+   Push $R5
+   StrLen $R3 $R1
+   StrCpy $R4 0
+   ; $R1=needle
+   ; $R2=haystack
+   ; $R3=len(needle)
+   ; $R4=cnt
+   ; $R5=tmp
+   loop:
+     StrCpy $R5 $R2 $R3 $R4
+     StrCmp $R5 $R1 done
+     StrCmp $R5 "" done
+     IntOp $R4 $R4 + 1
+     Goto loop
+ done:
+   StrCpy $R1 $R2 "" $R4
+   Pop $R5
+   Pop $R4
+   Pop $R3
+   Pop $R2
+   Exch $R1
+ FunctionEnd
\ No newline at end of file