; $Id$ ; Script generated by the HM NIS Edit Script Wizard. ; Update for Vista RequestExecutionLevel admin ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Firefly Media Server" !define PRODUCT_SERVICE "Firefly Media Server" !define /date DATEVER "%Y%m%d" !define PRODUCT_VERSION "svn-$WCREV$" !define PRODUCT_PUBLISHER "Ron Pedde" !define PRODUCT_WEB_SITE "http://www.fireflymediaserver.org" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\firefly.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PROJROOT "..\..\.." !define MTDROOT "..\.." !define MTD_SOURCE "${MTDROOT}\win32\Release" !define CONFIG_SOURCE "${MTDROOT}\win32\FireflyShell\Release" !define DLL_SOURCE "${PROJROOT}\win32\dll" !define ADMIN_ROOT "${MTDROOT}\admin-root" !define REDIST_SOURCE "${PROJROOT}\win32\redist" ; MUI 1.67 compatible ------ !include "MUI.nsh" ; MUI Settings ;!define MUI_WELCOMEFINISHPAGE_BITMAP "ffsetup4.bmp" !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !define MUI_PAGE_CUSTOMFUNCTION_LEAVE LicensePost !insertmacro MUI_PAGE_LICENSE "${ADMIN_ROOT}\gpl-license.txt" ; Directory page !define MUI_PAGE_CUSTOMFUNCTION_PRE DirectoryPre !define MUI_PAGE_CUSTOMFUNCTION_SHOW DirectoryShow !define MUI_PAGE_CUSTOMFUNCTION_LEAVE DirectoryLeave !insertmacro MUI_PAGE_DIRECTORY ; Music Directory Page !define MUI_PAGE_CUSTOMFUNCTION_PRE DirectoryPre !define MUI_PAGE_CUSTOMFUNCTION_SHOW DirectoryShow !define MUI_PAGE_CUSTOMFUNCTION_LEAVE DirectoryLeave !insertmacro MUI_PAGE_DIRECTORY ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; MUI end ------ !macro LANG_LOAD LANGLOAD !insertmacro MUI_LANGUAGE "${LANGLOAD}" ; !verbose !include "localizations\${LANGLOAD}.nsh" ; !verbose on !undef LANG !macroend !macro LANG_STRING NAME VALUE LangString "${NAME}" "${LANG_${LANG}}" "${VALUE}" !macroend !macro LANG_UNSTRING NAME VALUE !insertmacro LANG_STRING "un.${NAME}" "${VALUE}" !macroend !macro LANG_BOTHSTRING NAME VALUE !insertmacro LANG_STRING "${NAME}" "${VALUE}" !insertmacro LANG_UNSTRING "${NAME}" "${VALUE}" !macroend !insertmacro LANG_LOAD "English" !insertmacro LANG_LOAD "French" !insertmacro LANG_LOAD "Dutch" !insertmacro LANG_LOAD "German" !insertmacro LANG_LOAD "Japanese" !insertmacro LANG_LOAD "Swedish" !insertmacro LANG_LOAD "Italian" Name "${PRODUCT_NAME}" Icon "..\ff.ico" UninstallIcon "..\ff.ico" OutFile "${PRODUCT_NAME} (${PRODUCT_VERSION}).exe" InstallDir "$PROGRAMFILES\${PRODUCT_NAME}\" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show ShowUnInstDetails show Section -Pre !include WinMessages.nsh FindWindow $0 "" "FireflyShellNotifyIconHidden" SendMessage $0 ${WM_CLOSE} 0 0 nsSCM::QueryStatus "Bonjour Service" Pop $0 Pop $1 StrCmp $0 "success" lbl_got_bonjour MessageBox MB_OK "$(STRING_BONJOUR_ERROR)" Quit lbl_got_bonjour: IntOp $9 0 + 0 nsSCM::QueryStatus "${PRODUCT_NAME}" Pop $0 Pop $1 StrCmp $0 "success" lbl_stop_service goto lbl_continue lbl_stop_service: DetailPrint "$(STRING_STOPPING_SERVICE)" nsSCM::Stop "$(PRODUCT_NAME)" lbl_wait_stop: Sleep 1000 nsSCM::QueryStatus "$(PRODUCT_NAME)" Pop $0 Pop $1 ; DetailPrint $0 StrCmp $0 "success" lbl_check_status goto lbl_continue lbl_check_status: IntCmp $1 1 lbl_continue lbl_wait_stop lbl_wait_stop lbl_continue: ; should really loop until service stops... DetailPrint "$(STRING_WAITING_FOR_STOP)" IntOp $9 $9 + 1 IntCmp $9 10 +1 +1 lbl_done_pre Sleep 1500 Delete $2\firefly.exe IfErrors lbl_continue lbl_done_pre: SectionEnd Section "MainSection" SEC01 SetOutPath "$2" IfFileExists "$SMPROGRAMS\${PRODUCT_NAME}" HasProgramItems goto NoProgramItems HasProgramItems: Delete "$SMPROGRAMS\${PRODUCT_NAME}\*" NoProgramItems: SetOverwrite on File /oname=firefly.exe "${MTD_SOURCE}\mt-daapd.exe" File "${CONFIG_SOURCE}\FireflyShell.exe" Delete "$2\FireflyShell.exe.manifest" File "${CONFIG_SOURCE}\FireflyShell-0c.dll" File "${CONFIG_SOURCE}\FireflyShell-07.dll" File "${CONFIG_SOURCE}\FireflyShell-13.dll" File "${CONFIG_SOURCE}\FireflyShell-1d.dll" File "${CONFIG_SOURCE}\FireflyShell-11.dll" File "${CONFIG_SOURCE}\FireflyShell-10.dll" File "${CONFIG_SOURCE}\svcctrl.exe" File "${DLL_SOURCE}\gnu_regex.dll" File "${DLL_SOURCE}\pthreadVC2.dll" File "${DLL_SOURCE}\sqlite.dll" File "${DLL_SOURCE}\sqlite3.dll" File "${DLL_SOURCE}\zlib1.dll" File "${DLL_SOURCE}\avutil.dll" File "${DLL_SOURCE}\avcodec.dll" File "${DLL_SOURCE}\avformat.dll" File "${DLL_SOURCE}\libFLAC.dll" SetOutPath "$2\plugins" File "${MTD_SOURCE}\rsp.dll" File "${MTD_SOURCE}\out-daap.dll" File "${MTD_SOURCE}\w32-event.dll" File "${MTD_SOURCE}\ssc-ffmpeg.dll" File "${MTD_SOURCE}\ssc-wma.dll" SetOutPath "$2\admin-root" File "${ADMIN_ROOT}\thanks.html" File "${ADMIN_ROOT}\about.html" File "${ADMIN_ROOT}\status.js" File "${ADMIN_ROOT}\smartpopup.html" File "${ADMIN_ROOT}\smart.js" File "${ADMIN_ROOT}\smart.html" File "${ADMIN_ROOT}\required.gif" File "${ADMIN_ROOT}\playlist.js" File "${ADMIN_ROOT}\playlist.html" File "${ADMIN_ROOT}\ff_logo_sm.gif" File "${ADMIN_ROOT}\firefly.js" File "${ADMIN_ROOT}\firefly.css" File "${ADMIN_ROOT}\index.css" File "${ADMIN_ROOT}\config.css" File "${ADMIN_ROOT}\linkTransparent.gif" File "${ADMIN_ROOT}\linkOpaque.gif" File "${ADMIN_ROOT}\index.html" File "${ADMIN_ROOT}\hdr.html" File "${ADMIN_ROOT}\gpl-license.txt" File "${ADMIN_ROOT}\gpl-license.html" File "${ADMIN_ROOT}\ftr.html" File "${ADMIN_ROOT}\feedback.html" File "${ADMIN_ROOT}\favicon.ico" File "${ADMIN_ROOT}\DAAPApplet-0.1.jar" File "${ADMIN_ROOT}\CREDITS" File "${ADMIN_ROOT}\config-update.html" File "${ADMIN_ROOT}\config.html" File "${ADMIN_ROOT}\config.js" File "${ADMIN_ROOT}\config.xml" File "${ADMIN_ROOT}\aspl-license.txt" File "${ADMIN_ROOT}\aspl-license.html" File "${ADMIN_ROOT}\applet.html" File "${ADMIN_ROOT}\spinner.gif" File "${ADMIN_ROOT}\spinner_stopped.gif" File "${ADMIN_ROOT}\util.js" File "${ADMIN_ROOT}\pngfix.js" File "${ADMIN_ROOT}\no_access.html" SetOutPath "$2\admin-root\lib-js" File "${ADMIN_ROOT}\lib-js\prototype.js" File "${ADMIN_ROOT}\lib-js\rico.js" SetOutPath "$2\admin-root\lib-js\script.aculo.us" File "${ADMIN_ROOT}\lib-js\script.aculo.us\builder.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\controls.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\dragdrop.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\effects.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\scriptaculous.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\slider.js" File "${ADMIN_ROOT}\lib-js\script.aculo.us\unittest.js" SetOutPath "$2" IfFileExists "$2\mapping.ini" HasMap File "mapping.ini" HasMap: IfFileExists "$2\firefly.log" HasLog File "firefly.log" HasLog: File "mt-daapd-example.conf" IfFileExists "$2\mt-daapd.conf" HasConf SetOverwrite off CopyFiles "$2\mt-daapd-example.conf" "$2\mt-daapd.conf" WriteINIStr "$2\mt-daapd.conf" "general" "mp3_dir" $3 HasConf: WriteINIStr "$2\mt-daapd.conf" "plugins" "plugin_dir" "plugins" WriteINIStr "$2\mt-daapd.conf" "plugins" "plugins" "" ReadINIStr $0 "$2\mt-daapd.conf" "general" "rescan_interval" StrCmp $0 "" rescan_set rescan_skip rescan_set: WriteINIStr "$2\mt-daapd.conf" "general" "rescan_interval" "600" rescan_skip: ReadINIStr $0 "$2\mt-daapd.conf" "general" "logfile" StrCmp $0 "" logfile_set logfile_skip logfile_set: WriteINIStr "$2\mt-daapd.conf" "general" "logfile" "firefly.log" logfile_skip: ; Check for default exts ReadINIStr $0 "$2\mt-daapd.conf" "general" "extensions" StrCmp $0 ".mp3,.m4a,.m4p" ext_set ext_skip ext_set: WriteINIStr "$2\mt-daapd.conf" "general" "extensions" ".mp3,.m4a,.m4p,.wma" ext_skip: ; Check for truncate ReadINIStr $0 "$2\mt-daapd.conf" "general" "truncate" StrCmp $0 "" trunc_set trunc_skip trunc_set: WriteINIStr "$2\mt-daapd.conf" "general" "truncate" "1" trunc_skip: WriteINIStr "$2\mt-daapd.conf" "general" "db_type" "sqlite3" AccessControl::SetOnFile "$2\mt-daapd.conf" "Everyone" "FullAccess" AccessControl::SetOnFile "$2\mapping.ini" "Everyone" "FullAccess" AccessControl::SetOnFile "$2\firefly.log" "Everyone" "FullAccess" SetAutoClose False SectionEnd Section -AdditionalIcons WriteIniStr "$2\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\$(STRING_WEBSITE).lnk" "$2\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\$(STRING_UNINSTALL).lnk" "$2\uninst.exe" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\$(STRING_DEBUG_MODE).lnk" "$2\firefly.exe" "-d9 -f" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\$(STRING_FF_CONFIGURATION).lnk" "$2\FireflyShell.exe" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\$(STRING_ADV_CONFIG).lnk" "notepad.exe" "$2\mt-daapd.conf" Delete "$SMPROGRAMS\Startup\Firefly Configuration.lnk" SectionEnd !include "LogicLib.nsh" !define UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall" !define APP_KEY "{A49F249F-0C91-497F-86DF-B2585E8E76B7}" Section -VCRedistributable ReadRegStr $R0 HKLM "${UNINSTALL_KEY}\${APP_KEY}\" "DisplayName" ${If} ${Errors} # reg value doesn't exist (ie, needs installed) SetOutPath "$2\" File "${REDIST_SOURCE}\WindowsInstaller-KB893803-v2-x86.exe" File "${REDIST_SOURCE}\VCRedist_x86.exe" ExecWait '"$2\WindowsInstaller-KB893803-v2-x86.exe" /quiet /norestart' ExecWait '"$2\VCRedist_x86.exe" /Q' ${EndIf} SectionEnd Section -Post WriteUninstaller "$2\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$2\mt-daapd.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$2\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$2\firefly.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "FireflyShell" '"$2\FireflyShell.exe" -q' DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "FireflyShell" ; ExecWait "$2\mt-daapd.exe -i" nsSCM::Install "${PRODUCT_NAME}" "${PRODUCT_SERVICE}" 16 2 "$2\firefly.exe" "" "Bonjour Service" "" "" Pop $0 Pop $1 StrCmp $0 "success" lbl_install_success IntCmp $1 1073 lbl_install_success ; service already exists MessageBox MB_OK "Error installing service: $1" lbl_install_success: ExecWait 'netsh firewall add allowedprogram "$2\firefly.exe" "${PRODUCT_NAME}" enable' nsSCM::Start "${PRODUCT_NAME}" Exec '"$2\FireflyShell.exe" -q' SectionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(un.STRING_UNINSTALLED)" FunctionEnd Function un.onInit MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(un.STRING_AREYOUSURE)" IDYES +2 Abort FunctionEnd Function .onInit ; Must set $INSTDIR here to avoid adding ${PRODUCT_NAME} to the end of the ; path when user selects a new directory using the 'Browse' button. StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT_NAME}" StrCpy $2 "$PROGRAMFILES\${PRODUCT_NAME}" StrCpy $3 "$DOCUMENTS\My Music" Push "" Push ${LANG_ENGLISH} Push English Push ${LANG_FRENCH} Push French Push ${LANG_DUTCH} Push Dutch Push ${LANG_GERMAN} Push German Push ${LANG_JAPANESE} Push Japanese Push ${LANG_SWEDISH} Push Swedish Push ${LANG_ITALIAN} Push Italian ; more Push A LangDLL::LangDialog "Installer Language" "Please select the language of the installer" Pop $LANGUAGE StrCmp $LANGUAGE "cancel" 0 +2 Abort FunctionEnd Function LicensePost StrCpy $9 "0" FunctionEnd Function DirectoryPre StrCmp $9 "0" OK ;Skip 2nd (Music) Directory Page if conf file Exists IfFileExists "$2\mt-daapd.conf" "" OK Abort OK: FunctionEnd Function DirectoryShow StrCmp $9 "0" AppDirectoryPage StrCmp $9 "1" MusicDirectoryPage AppDirectoryPage: StrCpy $9 "1" !insertmacro MUI_INNERDIALOG_TEXT 1041 "$(STRING_DESTFOLDER)" !insertmacro MUI_INNERDIALOG_TEXT 1019 "$PROGRAMFILES\${PRODUCT_NAME}\" !insertmacro MUI_INNERDIALOG_TEXT 1006 "$(STRING_DESTDETAIL)" Goto EndDirectoryShow MusicDirectoryPage: StrCpy $9 "2" !insertmacro MUI_HEADER_TEXT "$(STRING_MUSICTITLE)" "$(STRING_MUSICHEADER)" !insertmacro MUI_INNERDIALOG_TEXT 1041 "$(STRING_MUSICFOLDER)" !insertmacro MUI_INNERDIALOG_TEXT 1019 "$DOCUMENTS\My Music" !insertmacro MUI_INNERDIALOG_TEXT 1006 "$(STRING_MUSICDETAIL)" EndDirectoryShow: FunctionEnd Function DirectoryLeave StrCmp $9 "1" SaveInstallDir StrCmp $9 "2" SaveMusicDir Goto EndDirectoryLeave SaveInstallDir: StrCpy $2 $INSTDIR Goto EndDirectoryLeave SaveMusicDir: ; Push $INSTDIR ; Call GetParent ; Pop $3 StrCpy $3 $INSTDIR EndDirectoryLeave: FunctionEnd Function .onVerifyInstDir StrCmp $9 "2" DataPath All DataPath: ;all valid if UNC StrCpy $R2 $INSTDIR 2 StrCmp $R2 "\\" PathOK All: ; Invalid path if root Push $INSTDIR call GetRoot Pop $R1 StrCmp $R1 $INSTDIR "" PathOK Abort PathOK: FunctionEnd ;-------------------------------- ;Helper Functions ; GetParent ; input, top of stack (e.g. C:\Program Files\Poop) ; output, top of stack (replaces, with e.g. C:\Program Files) ; modifies no other variables. ; ; Usage: ; Push "C:\Program Files\Directory\Whatever" ; Call GetParent ; Pop $R0 ; ; at this point $R0 will equal "C:\Program Files\Directory" Function GetParent Exch $R0 Push $R1 Push $R2 Push $R3 StrCpy $R1 0 StrLen $R2 $R0 loop: IntOp $R1 $R1 + 1 IntCmp $R1 $R2 get 0 get StrCpy $R3 $R0 1 -$R1 StrCmp $R3 "\" get Goto loop get: StrCpy $R0 $R0 -$R1 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd Function GetRoot Exch $0 Push $1 Push $2 Push $3 Push $4 StrCpy $1 $0 2 StrCmp $1 "\\" UNC StrCpy $0 $1 Goto done UNC: StrCpy $2 3 StrLen $3 $0 loop: IntCmp $2 $3 "" "" loopend StrCpy $1 $0 1 $2 IntOp $2 $2 + 1 StrCmp $1 "\" loopend loop loopend: StrCmp $4 "1" +3 StrCpy $4 1 Goto loop IntOp $2 $2 - 1 StrCpy $0 $0 $2 done: Pop $4 Pop $3 Pop $2 Pop $1 Exch $0 FunctionEnd Section Uninstall SetAutoClose false !include WinMessages.nsh close_loop: FindWindow $0 "" "FireflyShellNotifyIconHidden" IntCmp $0 0 close_done SendMessage $0 ${WM_QUIT} 0 0 SendMessage $0 ${WM_CLOSE} 0 0 SendMessage $0 ${WM_DESTROY} 0 0 Sleep 125 Goto close_loop close_done: IntOp $9 0 + 0 nsSCM::QueryStatus "${PRODUCT_NAME}" Pop $0 Pop $1 StrCmp $0 "success" un_lbl_stop_service goto un_lbl_continue un_lbl_stop_service: DetailPrint "$(STRING_STOPPING_SERVICE)" nsSCM::Stop "$(PRODUCT_NAME)" un_lbl_wait_stop: Sleep 1000 nsSCM::QueryStatus "$(PRODUCT_NAME)" Pop $0 Pop $1 ; DetailPrint $0 StrCmp $0 "success" un_lbl_check_status goto un_lbl_continue un_lbl_check_status: IntCmp $1 1 un_lbl_continue un_lbl_wait_stop un_lbl_wait_stop un_lbl_continue: ; should really loop until service stops... DetailPrint "$(STRING_WAITING_FOR_STOP)" IntOp $9 $9 + 1 IntCmp $9 10 +1 +1 un_lbl_done_pre Sleep 1500 Delete "$INSTDIR\firefly.exe" IfErrors un_lbl_continue un_lbl_done_pre: Sleep 1000 nsSCM::Remove "${PRODUCT_NAME}" Pop $0 StrCmp $0 "success" lbl_continue_uninstall MessageBox MB_OK "Error Uninstalling service: $1" lbl_continue_uninstall: Delete "$INSTDIR\admin-root\lib-js\script.aculo.us\*" RMDir "$INSTDIR\admin-root\lib-js\script.aculo.us" Delete "$INSTDIR\admin-root\lib-js\*" RMDir "$INSTDIR\admin-root\lib-js" Delete "$INSTDIR\admin-root\*" RMDir "$INSTDIR\admin-root" Delete "$INSTDIR\plugins\*" RMDir "$INSTDIR\plugins" Delete "$INSTDIR\*" RMDir "$INSTDIR" Delete "$SMPROGRAMS\${PRODUCT_NAME}\*" RMDir "$SMPROGRAMS\${PRODUCT_NAME}" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SetAutoClose false SectionEnd