From 6b11da1d0c4b7773be3aa4888d87e37fe3011239 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 21 Mar 2004 05:24:19 +0000 Subject: [PATCH] nsis-service-20040320 Incorporate a new NSIS library ServiceLib.nsh which will allow us to avoid using the Service.exe which we must build from Service.cpp --- src/WINNT/install/NSIS/OpenAFS.nsi | 171 +++++++++++-- src/WINNT/install/NSIS/ServiceLib.nsh | 342 ++++++++++++++++++++++++++ 2 files changed, 492 insertions(+), 21 deletions(-) create mode 100644 src/WINNT/install/NSIS/ServiceLib.nsh diff --git a/src/WINNT/install/NSIS/OpenAFS.nsi b/src/WINNT/install/NSIS/OpenAFS.nsi index 9497359a3..26bed3117 100644 --- a/src/WINNT/install/NSIS/OpenAFS.nsi +++ b/src/WINNT/install/NSIS/OpenAFS.nsi @@ -32,7 +32,7 @@ VIAddVersionKey "CompanyName" "OpenAFS.org" VIAddVersionKey "ProductVersion" ${AFS_VERSION} VIAddVersionKey "FileVersion" ${AFS_VERSION} VIAddVersionKey "FileDescription" "OpenAFS for Windows Installer" -VIAddVersionKey "LegalCopyright" "(C)2000-2004" +VIAddVersionKey "LegalCopyright" "(C)2004" !ifdef DEBUG VIAddVersionKey "PrivateBuild" "Checked/Debug" !endif ; End DEBUG @@ -281,6 +281,9 @@ VIAddVersionKey "PrivateBuild" "Checked/Debug" !insertmacro MUI_RESERVEFILE_LANGDLL ;Language selection dialog ;-------------------------------- ; Macros + +!include "ServiceLib.nsh" + ; Macro - Upgrade DLL File ; Written by Joost Verburg ; ------------------------ @@ -455,6 +458,13 @@ var REG_DATA_3 Section "AFS Client" secClient SetShellVarContext all + + ; Check for bad previous installation (if we are doing a new install) + Call IsAnyAFSInstalled + Pop $R0 + StrCmp $R0 "0" +1 skipCheck + Call CheckPathForAFS +skipCheck: ; Stop any running services or we can't replace the files ; Stop the running processes GetTempFileName $R0 @@ -468,8 +478,8 @@ Section "AFS Client" secClient ;nsExec::Exec '$R0 krbcc32s.exe' !ENDIF - nsExec::Exec "net stop TransarcAFSDaemon" - nsExec::Exec "net stop TransarcAFSServer" + !insertmacro SERVICE "stop" "TransarcAFSDaemon" "" + !insertmacro SERVICE "stop" "TransarcAFSServer" "" ; Do client components SetOutPath "$INSTDIR\Client\Program" @@ -613,15 +623,16 @@ Section "AFS Client" secClient ; Create the AFS service SetOutPath "$INSTDIR\Common" - File "${AFS_WININSTALL_DIR}\Service.exe" - nsExec::Exec "net stop TransarcAFSDaemon" + ;File "${AFS_WININSTALL_DIR}\Service.exe" + !insertmacro SERVICE "stop" "TransarcAFSDaemon" "" ;IMPORTANT! If we are not refreshing the config files, do NOT remove the service ;Don't re-install because it must be present or we wouldn't have passed the Reg check ReadRegStr $R2 HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "Cell" StrCmp $R2 "" +1 skipremove - nsExec::Exec '$INSTDIR\Common\Service.exe u TransarcAFSDaemon' + !insertmacro SERVICE "delete" "TransarcAFSDaemon" "" nsExec::Exec '$INSTDIR\Common\Service.exe TransarcAFSDaemon "$INSTDIR\Client\Program\afsd_service.exe" "OpenAFS Client Service"' + ;insertmacro SERVICE "create" "TransarcAFSDaemon" "path=$INSTDIR\Client\Program\afsd_service.exe;autostart=1;interact=1;machine=;user=;password=" skipremove: Delete "$INSTDIR\Common\service.exe" @@ -632,6 +643,10 @@ skipremove: WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider" "AuthentProviderPath" "$INSTDIR\Client\Program\afslogon.dll" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider" "Class" 2 WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider" "VerboseLogging" 10 + ; Must also add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\HwOrder + ; and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order + ; to also include the service name. + Call AddProvider ReadINIStr $R0 $1 "Field 7" "State" ReadINIStr $R1 $1 "Field 9" "State" ; Complicated way to do $R1 = ($R1 *2) + $R0 @@ -649,7 +664,7 @@ skipremove: WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "SecurityLevel" $R0 ReadINIStr $R0 $1 "Field 5" "State" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "FreelanceClient" $R0 - ReadINIStr $R0 $1 "Field 11" "State" + ReadINIStr $R0 $1 "Field 11" "State" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "UseDNS" $R0 WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "NetbiosName" "AFS" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters" "MountRoot" "/afs" @@ -802,7 +817,8 @@ Section "AFS Server" secServer File "${AFS_WININSTALL_DIR}\Service.pdb" !endif ;Don't want to whack existing settings... Make users un-install and then re-install if they want that - ;nsExec::Exec '$INSTDIR\Common\service.exe u TransarcAFSServer' + !insertmacro SERVICE "delete" "TransarcAFSServer" "" + ;insertmacro SERVICE "create" "TransarcAFSServer" "path=$INSTDIR\Server\usr\afs\bin\bosctlsvc.exe;autostart=1" nsExec::Exec '$INSTDIR\Common\service.exe TransarcAFSServer "$INSTDIR\Server\usr\afs\bin\bosctlsvc.exe" "OpenAFS AFS Server"' Delete "$INSTDIR\Common\service.exe" @@ -1600,16 +1616,15 @@ StartRemove: !ENDIF ; Delete the AFS service - GetTempFileName $R0 - File /oname=$R0 "${AFS_WININSTALL_DIR}\Service.exe" - nsExec::Exec "net stop TransarcAFSDaemon" - nsExec::Exec "net stop TransarcAFSServer" - nsExec::Exec '$R0 u TransarcAFSDaemon' - ; After we stop the service, but before we delete it, we have to remove the volume data - ; This is because the storage locations are in the registry under the service key. - ; Call un.RemoveAFSVolumes - nsExec::Exec '$R0 u TransarcAFSServer' - Delete $R0 + ; New method for service manipulation + !undef "UN" + !define "UN" "un." + !insertmacro SERVICE "stop" "TransarcAFSDaemon" "" + !insertmacro SERVICE "stop" "TransarcAFSDaemon" "" + !insertmacro SERVICE "delete" "TransarcAFSDaemon" "" + !insertmacro SERVICE "delete" "TransarcAFSServer" "" + + Call un.RemoveProvider Push "$INSTDIR\Client\Program" Call un.RemoveFromPath @@ -2009,8 +2024,8 @@ StrCmp $R0 "1" done ReadINIStr $R0 $0 "Field 3" "State" StrCmp $R0 "1" UsePackaged -ReadINIStr $R0 $0 "Field 6" "State" -StrCmp $R0 "1" CheckOther +ReadINIStr $R0 $0 "Field 6" "State" + StrCmp $R0 "1" CheckOther ; If none of these, grab file from other location goto UsePackaged @@ -3591,4 +3606,118 @@ noClose: Pop $2 Pop $1 Exch $R0 -FunctionEnd \ No newline at end of file +FunctionEnd + +Function AddProvider + Push $R0 + Push $R1 + ReadRegStr $R0 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" + Push $R0 + StrCpy $R0 "TransarcAFSDaemon" + Push $R0 + Call StrStr + Pop $R0 + StrCmp $R0 "" +1 DoOther + ReadRegStr $R1 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" + StrCpy $R0 "$R1,TransarcAFSDaemon" + WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" $R0 +DoOther: + ReadRegStr $R0 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" + Push $R0 + StrCpy $R0 "TransarcAFSDaemon" + Push $R0 + Call StrStr + Pop $R0 + StrCmp $R0 "" +1 End + ReadRegStr $R1 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" + StrCpy $R0 "$R1,TransarcAFSDaemon" + WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" $R0 +End: + Pop $R1 + Pop $R0 +FunctionEnd + +Function un.RemoveProvider + Push $R0 + StrCpy $R0 "TransarcAFSDaemon" + Push $R0 + StrCpy $R0 "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" + Call un.RemoveFromProvider + StrCpy $R0 "TransarcAFSDaemon" + Push $R0 + StrCpy $R0 "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" + Call un.RemoveFromProvider + Pop $R0 +FunctionEnd + +Function un.RemoveFromProvider + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + + ReadRegStr $1 HKLM "$R0" "ProviderOrder" + StrCpy $5 $1 1 -1 # copy last char + StrCmp $5 "," +2 # if last char != , + StrCpy $1 "$1," # append , + Push $1 + Push "$0," + Call un.StrStr ; Find `$0,` in $1 + Pop $2 ; pos of our dir + StrCmp $2 "" unRemoveFromPath_done + ; else, it is in path + # $0 - path to add + # $1 - path var + StrLen $3 "$0," + StrLen $4 $2 + StrCpy $5 $1 -$4 # $5 is now the part before the path to remove + StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove + StrCpy $3 $5$6 + + StrCpy $5 $3 1 -1 # copy last char + StrCmp $5 "," 0 +2 # if last char == , + StrCpy $3 $3 -1 # remove last char + + WriteRegStr HKLM "$R0" "ProviderOrder" $3 + + unRemoveFromPath_done: + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + +Function CheckPathForAFS + Push $0 + Push $1 + Push $2 + Push $3 + ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" + StrCpy $1 "$1;" +loop: + Push $1 + Push ";" + Call StrStr + Pop $0 + StrLen $2 $0 + StrCpy $3 $1 -$2 + IfFileExists "$3\afsd_service.exe" Error + StrCpy $1 $0 32768 1 + StrLen $2 $1 + IntCmp $2 0 Done Done loop + goto Done +Error: + MessageBox MB_ICONSTOP|MB_OK|MB_TOPMOST "This installer is unable to upgrade the previous version of AFS. Please uninstall the current AFS version before continuing." + Abort "Unable to install OpenAFS" +Done: + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd diff --git a/src/WINNT/install/NSIS/ServiceLib.nsh b/src/WINNT/install/NSIS/ServiceLib.nsh new file mode 100644 index 000000000..bf07a7fb6 --- /dev/null +++ b/src/WINNT/install/NSIS/ServiceLib.nsh @@ -0,0 +1,342 @@ + +; NSIS SERVICE LIBRARY - servicelib.nsh +; Version 1.2 - 02/29/2004 +; Questions/Comments - dselkirk@hotmail.com +; +; Description: +; Provides an interface to window services +; +; Inputs: +; action - systemlib action ie. create, delete, start, stop, pause, +; continue, installed, running, status +; name - name of service to manipulate +; param - action parameters; usage: var1=value1;var2=value2;...etc. +; +; Actions: +; create - creates a new windows service +; Parameters: +; path - path to service executable +; autostart - automatically start with system ie. 1|0 +; interact - interact with the desktop ie. 1|0 +; machine - machine name where to install service +; user - user that runs the service +; password - password of the above user +; +; delete - deletes a windows service +; start - start a stopped windows service +; stop - stops a running windows service +; pause - pauses a running windows service +; continue - continues a paused windows service +; installed - is the provided service installed +; Parameters: +; action - if true then invokes the specified action +; running - is the provided service running +; Parameters: +; action - if true then invokes the specified action +; status - check the status of the provided service +; +; If run from uninstall define "UN" as "un." gefore running. +; +; Usage: +; Method 1: +; Push "action" +; Push "name" +; Push "param" +; Call Service +; Pop $0 ;response +; +; Method 2: +; !insertmacro SERVICE "action" "name" "param" +; +; History: +; 1.0 - 09/15/2003 - Initial release +; 1.1 - 09/16/2003 - Changed &l to i, thx brainsucker +; 1.2 - 02/29/2004 - Fixed documentation. + +!ifndef SERVICELIB + !define SERVICELIB + + !define SC_MANAGER_ALL_ACCESS 0x3F + !define SERVICE_ALL_ACCESS 0xF01FF + + !define SERVICE_CONTROL_STOP 1 + !define SERVICE_CONTROL_PAUSE 2 + !define SERVICE_CONTROL_CONTINUE 3 + + !define SERVICE_STOPPED 0x1 + !define SERVICE_START_PENDING 0x2 + !define SERVICE_STOP_PENDING 0x3 + !define SERVICE_RUNNING 0x4 + !define SERVICE_CONTINUE_PENDING 0x5 + !define SERVICE_PAUSE_PENDING 0x6 + !define SERVICE_PAUSED 0x7 + + !ifndef UN + !define UN "" + !endif + + !macro SERVICE ACTION NAME PARAM + Push '${ACTION}' + Push '${NAME}' + Push '${PARAM}' + Call ${UN}Service + !macroend + + !macro FUNC_GETPARAM + Push $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + Push $7 + Exch 8 + Pop $1 ;name + Exch 8 + Pop $2 ;source + StrCpy $0 "" + StrLen $7 $2 + StrCpy $3 0 + lbl_loop: + IntCmp $3 $7 0 0 lbl_done + StrLen $4 "$1=" + StrCpy $5 $2 $4 $3 + StrCmp $5 "$1=" 0 lbl_next + IntOp $5 $3 + $4 + StrCpy $3 $5 + lbl_loop2: + IntCmp $3 $7 0 0 lbl_done + StrCpy $6 $2 1 $3 + StrCmp $6 ";" 0 lbl_next2 + IntOp $6 $3 - $5 + StrCpy $0 $2 $6 $5 + Goto lbl_done + lbl_next2: + IntOp $3 $3 + 1 + Goto lbl_loop2 + lbl_next: + IntOp $3 $3 + 1 + Goto lbl_loop + lbl_done: + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Exch 2 + Pop $6 + Pop $7 + Exch $0 + !macroend + + !macro CALL_GETPARAM VAR NAME DEFAULT LABEL + Push $1 + Push ${NAME} + Call ${UN}GETPARAM + Pop $6 + StrCpy ${VAR} "${DEFAULT}" + StrCmp $6 "" "${LABEL}" 0 + StrCpy ${VAR} $6 + !macroend + + !macro FUNC_SERVICE UN + Push $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + Push $7 + Exch 8 + Pop $1 ;param + Exch 8 + Pop $2 ;name + Exch 8 + Pop $3 ;action + ;$0 return + ;$4 OpenSCManager + ;$5 OpenService + + + StrCpy $0 "false" + System::Call 'advapi32::OpenSCManagerA(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.r4' + IntCmp $4 0 lbl_done + StrCmp $3 "create" lbl_create + System::Call 'advapi32::OpenServiceA(i r4, t r2, i ${SERVICE_ALL_ACCESS}) i.r5' + IntCmp $5 0 lbl_done + + lbl_select: + StrCmp $3 "delete" lbl_delete + StrCmp $3 "start" lbl_start + StrCmp $3 "stop" lbl_stop + StrCmp $3 "pause" lbl_pause + StrCmp $3 "continue" lbl_continue + StrCmp $3 "installed" lbl_installed + StrCmp $3 "running" lbl_running + StrCmp $3 "status" lbl_status + Goto lbl_done + + ; create service + lbl_create: + Push $R1 ;machine + Push $R2 ;user + Push $R3 ;password + Push $R4 ;interact + Push $R5 ;autostart + Push $R6 ;path + + !insertmacro CALL_GETPARAM $R1 "machine" "n" "lbl_machine" + lbl_machine: + + !insertmacro CALL_GETPARAM $R2 "user" "n" "lbl_user" + lbl_user: + + !insertmacro CALL_GETPARAM $R3 "password" "n" "lbl_password" + lbl_password: + + !insertmacro CALL_GETPARAM $R4 "interact" "0x10" "lbl_interact" + StrCpy $6 0x10 + IntCmp $R4 0 +2 + IntOp $R4 $6 | 0x100 + StrCpy $R4 $6 + lbl_interact: + + !insertmacro CALL_GETPARAM $R5 "autostart" "0x3" "lbl_autostart" + StrCpy $6 0x3 + IntCmp $R5 0 +2 + StrCpy $6 0x2 + StrCpy $R5 $6 + lbl_autostart: + + !insertmacro CALL_GETPARAM $R6 "path" "n" "lbl_path" + lbl_path: + + System::Call 'advapi32::CreateServiceA(i r4, t r2, t r2, i ${SERVICE_ALL_ACCESS}, i R4, i R5, i 0, t R6, n, n, R1, R2, R3) i.r6' + Pop $R6 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Pop $R1 + StrCmp $6 0 lbl_done lbl_good + + ; delete service + lbl_delete: + System::Call 'advapi32::DeleteService(i r5) i.r6' + StrCmp $6 0 lbl_done lbl_good + + ; start service + lbl_start: + System::Call 'advapi32::StartServiceA(i r5, i 0, i 0) i.r6' + StrCmp $6 0 lbl_done lbl_good + + ; stop service + lbl_stop: + Push $R1 + System::Call '*(i,i,i,i,i,i,i) i.R1' + System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_STOP}, i $R1) i' + System::Free $R1 + Pop $R1 + StrCmp $6 0 lbl_done lbl_good + + ; pause service + lbl_pause: + Push $R1 + System::Call '*(i,i,i,i,i,i,i) i.R1' + System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_PAUSE}, i $R1) i' + System::Free $R1 + Pop $R1 + StrCmp $6 0 lbl_done lbl_good + + ; continue service + lbl_continue: + Push $R1 + System::Call '*(i,i,i,i,i,i,i) i.R1' + System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_CONTINUE}, i $R1) i' + System::Free $R1 + Pop $R1 + StrCmp $6 0 lbl_done lbl_good + + ; is installed + lbl_installed: + !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good" + StrCpy $3 $7 + Goto lbl_select + + ; is service running + lbl_running: + Push $R1 + System::Call '*(i,i,i,i,i,i,i) i.R1' + System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i' + System::Call '*$R1(i, i.r6)' + System::Free $R1 + Pop $R1 + IntFmt $6 "0x%X" $6 + StrCmp $6 ${SERVICE_RUNNING} 0 lbl_done + !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good" + StrCpy $3 $7 + Goto lbl_select + + lbl_status: + Push $R1 + System::Call '*(i,i,i,i,i,i,i) i.R1' + System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i' + System::Call '*$R1(i, i .r6)' + System::Free $R1 + Pop $R1 + IntFmt $6 "0x%X" $6 + StrCpy $0 "running" + IntCmp $6 ${SERVICE_RUNNING} lbl_done + StrCpy $0 "stopped" + IntCmp $6 ${SERVICE_STOPPED} lbl_done + StrCpy $0 "start_pending" + IntCmp $6 ${SERVICE_START_PENDING} lbl_done + StrCpy $0 "stop_pending" + IntCmp $6 ${SERVICE_STOP_PENDING} lbl_done + StrCpy $0 "running" + IntCmp $6 ${SERVICE_RUNNING} lbl_done + StrCpy $0 "continue_pending" + IntCmp $6 ${SERVICE_CONTINUE_PENDING} lbl_done + StrCpy $0 "pause_pending" + IntCmp $6 ${SERVICE_PAUSE_PENDING} lbl_done + StrCpy $0 "paused" + IntCmp $6 ${SERVICE_PAUSED} lbl_done + StrCpy $0 "unknown" + + lbl_good: + StrCpy $0 "true" + lbl_done: + IntCmp $5 0 +2 + System::Call 'advapi32::CloseServiceHandle(i r5) n' + IntCmp $4 0 +2 + System::Call 'advapi32::CloseServiceHandle(i r4) n' + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Exch 3 + Pop $5 + Pop $6 + Pop $7 + Exch $0 + !macroend + + Function Service + !insertmacro FUNC_SERVICE "" + FunctionEnd + + Function un.Service + !insertmacro FUNC_SERVICE "un." + FunctionEnd + + Function GetParam + !insertmacro FUNC_GETPARAM + FunctionEnd + + Function un.GetParam + !insertmacro FUNC_GETPARAM + FunctionEnd + +!endif -- 2.39.5