|
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 |