#########################################################3 ## Archiver Include Routines. ## ## Refined: Aug 17 2008. Andrew Wallo, Microneil, ArmResearch All Rights Reserved. ########################################################## # Main objectives is as follows: # Enable rollback of a folder to a previous folder state. # Create the log, and store it in the archive so that it understands what it nees to rollback. # Log should Contain, target directories, date and other relevent information. # Dependencies: # 1: Requires ${GetTime} to be defined in the master install script. # 2: Requires ${GetBetwee} to be defined in the master install script. Used to parse file lines. Var /GLOBAL SRS_CurrentArchiveFolder Var /GLOBAL SRS_Rollback_FileHandle Var /GLOBAL SRS_Rollback_FileCount Var /GLOBAL SRS_LogName !macro StartRollbackSession _ArchivePath _LogName _RootKey _RegistryKey StrCpy $SRS_LogName ${_LogName} StrCpy $SRS_CurrentArchiveFolder ${_ArchivePath} StrCpy $SRS_Rollback_FileCount "0" ; Now put the values onto the stack for the Rollback engine. Push `${_ArchivePath}` Push `${_LogName}` Call OpenRollback ;MessageBox MB_OK "Opened rollback with: $SRS_LogName / ${_ArchivePath} / $SRS_CurrentArchiveFolder" ${IF} "${_RootKey}" != "" ${IF} "${_RegistryKey}" != "" ${SetRegistry_with_RollbackControl} "${_RootKey}" "${_RegistryKey}" "SRS_RollbackPath" "$SRS_CurrentArchiveFolder" ${SetRegistry_with_RollbackControl} "${_RootKey}" "${_RegistryKey}" "SRS_LogName" "$SRS_LogName" ${ENDIF} ${ENDIF} !macroend !define StartRollbackSession "!insertmacro StartRollbackSession" #test !macro EndRollbackSession _RootKey _RegistryKey ${IF} "${_RootKey}" != "" ${IF} "${_RegistryKey}" != "" ${SetRegistry_with_RollbackControl} "${_RootKey}" "${_RegistryKey}" "SRS_COMPLETE" "1" ${SetRegistry_with_RollbackControl} "${_RootKey}" "${_RegistryKey}" "SRS_INSTDIR" "$INSTDIR" ${SetRegistry_with_RollbackControl} "${_RootKey}" "${_RegistryKey}" "SRS_SERVDIR" "$SNFServerInstallDir" ${ENDIF} ${ENDIF} FileWrite $SRS_Rollback_FileHandle "$SRS_Rollback_FileCount$\r$\n" StrCpy $SRS_Rollback_FileCount "0" FileWrite $SRS_Rollback_FileHandle "$\r$\n" FileClose $SRS_Rollback_FileHandle ; close this file StrCpy $SRS_Rollback_FileHandle "" ;and clear for new rollback session. !macroend !define EndRollbackSession "!insertmacro EndRollbackSession" Function OpenRollback ; First determine if we're trying to open a second consecutive rollback session... ( this would be bad. ) ;StrCmp $SRS_Rollback_FileHandle "" runOpenRollback 0 ; if cleared, then we can start a Rollback Session. If not clear, then set errors. ; push $1 ; saves $1 ; Exch ; pop $1 ; removes ArchivePath off stack ; Exch ; pop $1 ; removes LogNme off stack ; pop $1 ; restores $1 ; SetErrors ; MessageBox MB_OK "Archive in progress?" ; return ; sorry, can't do this right now.... ;runOpenRollback: ; ok, clear for take-off: ; First protect the stack by saving the values of the registers we're going to use. ; But they're covering the parameters that were passed...... ######################################## Stack Protection ################################### push $9 ; Save Register $9; Exch ; Swap Zeroth element in stack with the top most, which will be _LogName from the macro pop $9 ; put Log into register $9 push $8 ; Save register $8 Exch 2 ; Swap with position 1 from the top. So.... before exch was $1 $0 _ArchivePath ; After Exch was _ArchvePath $0 $1 pop $8 ; $8 holds ArchivePath push $7 ; Used Locally.... save on stack.... push $6 push $5 push $4 push $3 push $2 push $1 push $0 ###################################### End Stack Protection ################################# ; Ok, ifFileExists "$8\*.*" SRS_FolderExists 0 ; if the folder exists, skip create, otherwise create directory. CreateDirectory $8 SRS_FolderExists: StrCpy $SRS_CurrentArchiveFolder $8 ; Save master variable for local var. ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 ; set vars for oldfilerename ; $0="01" day ; $1="04" month ; $2="2005" year ; $3="Friday" day of week name ; $4="16" hour ; $5="05" minute ; $6="50" seconds ; Create the specific archive folder path. StrCpy $7 "Archive_$2$1$0$4$5$6" ; for keying the folder. ; Test for valid name... otherwise use default. StrCmp $9 "" 0 +2 StrCpy $9 "$7_rllbck.log" FileOpen $SRS_Rollback_FileHandle $8\$9 w ; Log File created for tracking rollback FileWrite $SRS_Rollback_FileHandle "Started Rollback Log$\r$\n" FileWrite $SRS_Rollback_FileHandle "$2.$1.$0,$4:$5:$6$\r$\n" ###################################### Restore the Stack #################################### pop $0 pop $1 pop $2 pop $3 pop $4 pop $5 pop $6 pop $7 pop $8 pop $9 return FunctionEnd ##################################################################################################################################################### ## ${SetRegistry_RollbackControl} sets a registry entry to a new value, and stores the old one. ##################################################################################################################################################### !macro SetRegistry_with_RollbackControl _RootKey _RegistryKey _SubKey _Value push $1 ${Switch} "${_RootKey}" ${Case} "HKLM" ReadRegStr $1 HKLM "${_RegistryKey}" "${_SubKey}" ; get keys value... ${Case} "HKCR" ReadRegStr $1 HKCR "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCU" ReadRegStr $1 HKCU "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKU" ReadRegStr $1 HKU "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCC" ReadRegStr $1 HKCC "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKDD" ReadRegStr $1 HKDD "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKPD" ReadRegStr $1 HKPD "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "SHCTX" ReadRegStr $1 SHCTX "${_RegistryKey}" "${_SubKey}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${EndSwitch} StrCmp $1 "" 0 +4 ; String is empty. Test for no key. ifErrors 0 +3 ; Means its a DWORD or something, but I'm not handling that here. ; Key didn't exist. FileWrite $SRS_Rollback_FileHandle "1${_RootKey}${_RegistryKey}${_SubKey}${_Value}$\r$\n" Goto +2 ; skip duplicate line and alter registry.... ; Else the key existed. FileWrite $SRS_Rollback_FileHandle "0${_RootKey}${_RegistryKey}${_SubKey}$1$\r$\n" ${Switch} "${_RootKey}" ${Case} "HKLM" WriteRegStr HKLM "${_RegistryKey}" "${_SubKey}" "${_Value}" ; get keys value... ${Case} "HKCR" WriteRegStr HKCR "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCU" WriteRegStr HKCU "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKU" WriteRegStr HKU "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCC" WriteRegStr HKCC "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKDD" WriteRegStr HKDD "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKPD" WriteRegStr HKPD "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "SHCTX" WriteRegStr SHCTX "${_RegistryKey}" "${_SubKey}" "${_Value}" ;$R1 $R2 $R3Goto EndSNFServiceTest ${EndSwitch} pop $1 !macroend !define SetRegistry_with_RollbackControl "!insertmacro SetRegistry_with_RollbackControl" ##################################################################################################################################################### ## ${Install_with_RollbackControl} assumes you have set your INSTALL Directory as it will call File _someFilename and put it ## wherever the SetOutPath is pointing.... ##################################################################################################################################################### !macro Install_with_RollbackControl _someFileName _CallbackHandler _onFailCommand StrCmp "1" "0" 0 +2 File ${_someFileName} ; can't ever happen but we need it here to force the compiler to include the file. IfFileExists `$OUTDIR\${_someFileName}` 0 +4 ; File exists. We need to make a copy of the original file. CopyFiles /SILENT `$OUTDIR\${_someFileName}` `$SRS_CurrentArchiveFolder\${_someFileName}` ; We need to save the target path seperately because later when we're rolling it back, we'll need to setOutPath for each file seperately. ; If a file has a potential of being tied up, we can specify the action to take on an overwrite failure. FileWrite $SRS_Rollback_FileHandle "0${_someFileName}$OUTDIR${_CallbackHandler}${_onFailCommand}$\r$\n" Goto +2 ; +4 jumps to here.....just Put The File FileWrite $SRS_Rollback_FileHandle "1${_someFileName}$OUTDIR${_CallbackHandler}${_onFailCommand}$\r$\n" File `${_someFileName}` ; ok, output the file into the install directory. IntOp $SRS_Rollback_FileCount $SRS_Rollback_FileCount + 1 !macroend !define Install_with_RollbackControl "!insertmacro Install_with_RollbackControl" ################################################################################################################################################### ## The difference here is that the macro doesn't rely on the SetOutPath or call the File "filename" command. It just archives a file into rollback ## based on the the fully qualified path name supplied. ################################################################################################################################################ !macro Copy_with_RollbackControl _someFileName _Path _CallbackHandler _onFailCommand ifFileExists ${_Path}\${_someFileName} 0 +5 CopyFiles /SILENT `${_Path}\${_someFileName}` `$SRS_CurrentArchiveFolder\${_someFileName}` CopyFiles /SILENT `${_Path}\${_someFileName}` `${_Path}\${_someFileName}_pre_sniffer_install.log` ; We need to save the target path seperately because later when we're rolling it back, we'll need to setOutPath for each file seperately. ; If a file has a potential of being tied up, we can specify the action to take on an overwrite failure. FileWrite $SRS_Rollback_FileHandle "0${_someFileName}${_Path}${_CallbackHandler}${_onFailCommand}$\r$\n" IntOp $SRS_Rollback_FileCount $SRS_Rollback_FileCount + 1 !macroend !define Copy_with_RollbackControl "!insertmacro Copy_with_RollbackControl" !macro RollBackTo _rollbackLocalPath _rollbackLogName push `${_rollbackLocalPath}` push `${_rollbackLogName}` Call RollBack !macroend !define RollBackTo "!insertmacro RollBackTo" Function RollBack push $0 ; save register 0 on stack. ( So stack looks like $0 "_rollbackLogName" _rollbackLocalPath Rest of Stack..... Exch ; swap the top two objects on the stack.... _rollbackLogName $0 _rollbackLocalPath pop $0 ; stack looks like $0.._rollbackLocalPath ...Rest of Stack.... Using $0 to hld the RollBackLogName push $1 ; stack looks like $1 $0.._rollbackLocalPath Rest of Stack Use this var for handling readlines. Exch 2 ; stack looks like _rollbackLocalPath $0 $1 Rest of Stack pop $1 ; Use this var for handling the local path of the list of archived files. Exch ; stack looks like $1 $0 Rest of Stack push $2 ; stack look like $2 $1 $0 Rest of stack. Use $2 to hold read lines..... push $3 ; stack looks like $3 $2 $1 $0 RestofStack. Use this var for handling tag parsing of lines.... push $4 ; saving $4 too... use this var for holding filename of file. push $5 ; saving $5 too... use this var for holding target path. push $6 ; use this var for the command line to exeute if failed to copy.... push $7 ; use this var for temp file handle ; registry temp vars.... push $R1 ; protect this and use for the Root of the registry handles... push $R2 ; protect this and use for the Key push $R3 ; protect this and use for the subkey push $R4 ; protected this and use for the Value..... ; Not sure what the situation would be..... but theoretically, if the file is open... then.... its still open and the caller wasn't careful about ; ending the rollback. StrCmp $SRS_Rollback_FileHandle "" ProceedToRollBack 0 ; File is open... crap... ok..well, reguardless of what our filename is, ( and it SHOULD be the same file, logically.... ) we want the other closed properly. MessageBox MB_OK "Had to close the file?" !insertmacro EndRollbackSession "" "" ; so end it cleanly. THEN open our rollback log. ; We're skipping the registry keys that record ; where the logfile and rollbackpath is... if this happens. ProceedToRollBack: ifFileExists "$1\$0" StartRollBack 0 SetErrors MessageBox MB_OK "Unable to find rollback file: $1\$0" Goto SRS_DONE Return ; perhaps the user just gave the file folder.... try to locate the .rllbck file in the folder.... if it exists. StartRollBack: clearerrors FileOpen $SRS_Rollback_FileHandle "$1\$0" r ; open file for read. IfErrors 0 SRS_RESTORE_ReadLine MessageBox MB_OK "Error opening the file for rollback: $1\$0" Goto SRS_DONE SRS_RESTORE_ReadLine: ClearErrors FileRead $SRS_Rollback_FileHandle $2 ; get line for parsing. ;MessageBox MB_OK $2 IfErrors SRS_DONE ; if errors, then EOF. Cleanup stack and exit. ; otherise parse line. StrCpy $3 $2 6 ;if this line is a file line, then the first six chars should be ;Handle Registry Alterations: StrCmp $3 "1${_someFileName}$OUTDIR${_onFailCommand} ;1${_RootKey}${_RegistryKey}${_SubKey}${_Value} #MessageBox MB_OK "$2" ; Because GetBetween only uses files as sources.... ( stupid, that I'm using that here, but I am.... ) ${GetBetween} "" "" "$1\SRS_TempFile.txt" $4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK $4 ${GetBetween} "" "" "$1\SRS_TempFile.txt" $R1 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${GetBetween} "" "" "$1\SRS_TempFile.txt" $R2 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${GetBetween} "" "" "$1\SRS_TempFile.txt" $R3 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${GetBetween} "" "" "$1\SRS_TempFile.txt" $R4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" #MessageBox MB_OK "$1, $4 , $R1 , $R2 , $R3 , $R4" StrCmp $4 "SRS_RollbackPath" RemoveIt 0 StrCmp $4 "SRS_Logname" RemoveIt 0 StrCmp $4 "1" 0 SRS_RESTORE_WRITE ; if the new marker is set to 1 then a rollback means remove it entirely..... RemoveIt: ${Switch} $R1 ${Case} "HKLM" DeleteRegValue HKLM $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCR" DeleteRegValue HKCR $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCU" DeleteRegValue HKCU $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKU" DeleteRegValue HKU $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCC" DeleteRegValue HKCC $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKDD" DeleteRegValue HKDD $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKPD" DeleteRegValue HKPD $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "SHCTX" DeleteRegValue SHCTX $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${EndSwitch} Goto SRS_RESTORE_ReadLine SRS_RESTORE_WRITE: ; if not then we need to restore the key..... ${Switch} $R1 ${Case} "HKLM" WriteRegStr HKLM $R2 $R3 $R4 ${Case} "HKCR" WriteRegStr HKCR $R2 $R3 $R4 ${Case} "HKCU" WriteRegStr HKCU $R2 $R3 $R4 ${Case} "HKU" WriteRegStr HKU $R2 $R3 $R4 ${Case} "HKCC" WriteRegStr HKCC $R2 $R3 $R4 ${Case} "HKDD" WriteRegStr HKDD $R2 $R3 $R4 ${Case} "HKPD" WriteRegStr HKPD $R2 $R3 $R4 ${Case} "SHCTX" WriteRegStr SHCTX $R2 $R3 $R4 ${EndSwitch} Goto SRS_RESTORE_ReadLine SRS_RESTORE_TestForFileLine: StrCmp $3 "" 0 SRS_RESTORE_ReadLine ; if its a file, then handle rolling back the file, otherwise get the next line. FileOpen $7 "$1\SRS_TempFile.txt" w FileWrite $7 $2 FileClose $7 ; Because GetBetween only uses files as sources.... ( stupid, that I'm using that here, but I am.... ) ${GetBetween} "" "" "$1\SRS_TempFile.txt" $4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 ${GetBetween} "" "" "$1\SRS_TempFile.txt" $R1 ; Get the marker that informed us if there WAS something to be copied, or if it was just installed. ;MessageBox MB_OK "Name:$4" ${GetBetween} "" "" "$1\SRS_TempFile.txt" $5 ; Get the targetpath between the file tags of the read_line_in->$2 and stick it in $5 ;MessageBox MB_OK "Target:$5" clearerrors ${GetBetween} "" "" "$1\SRS_TempFile.txt" $6 ; Get the CALLBACK name between the file tags of the read_line_in->$2 and stick it in $6 iferrors NoCallbackAvailable 0 StrCmp $6 "" NoCallbackAvailable 0 ; Ok, we have a callback, so we don't copy, we call file, and pass the filename. ;MessageBox MB_OK "Pushing $1\$4" push "$1\$4" ; push the file and path onto the stack. push $6 ; push the calback value onto the stack, Call ResolveFunction ; call the resolveFunction Call. Goto SRS_RESTORE_ReadLine ; No copy, just return for next line handle. NoCallbackAvailable: ; now deal with new vs archived files... StrCmp $R1 "1" 0 SRS_NOTNEW_RESTOREIT ; test to see if it was new, or if it required backin gup... ifFileExists "$5\$4" 0 SRS_RESTORE_ReadLine ; if it WAS new... test to see if file still exists... Delete "$5\$4" ; Since it was new we'll remove it on a restore.... Goto SRS_RESTORE_ReadLine SRS_NOTNEW_RESTOREIT: CopyFiles /SILENT "$1\$4" "$5\$4" iferrors 0 SRS_RESTORE_ReadLine clearerrors ${GetBetween} "" "" "$1\SRS_TempFile.txt" $6 ; Get the onfail name between the file tags of the read_line_in->$2 and stick it in $6 ; if we're here, then we need to rexecute the copy after executing the command line push "$1\$4" ; push the file and path onto the stack. push $6 ; push the callback value onto the stack, Call ResolveFunction ; call the resolveFunction Call. clearerrors CopyFiles /SILENT "$1\$4" "$5\$4" iferrors 0 SRS_RESTORE_ReadLine ; if still an error, then notify and try next line. ; MessageBox MB_OK "Error in rolling back file: $1\$4 to $5\$4" Goto SRS_RESTORE_ReadLine ; ok, either we parsed the file, or we quit with errors... either way. clean the stack.... SRS_DONE: ; done with readling lines from the file. Delete "$1\SRS_TempFile.txt" FileClose $SRS_Rollback_FileHandle ; Now parse the file name pop $R4 pop $R3 pop $R2 pop $R1 pop $7 pop $6 pop $5 pop $4 pop $3 pop $2 ;restore $2 pop $1 ;restore $1 pop $0 ; restore $0 to previous value.... return ; end FunctionEnd ;!macro moveRollbackArchive _ExistingPath _ExistingLogFile _NewPath ; ifFileExists "${_ExistingPath}" 0 +2 ; Delete "${_ExistingPath}\*.*" ; RMDir "${_ExistingPath}" ; rename "${_ExistingPath}\*.*" "${_NewPath}\*.*" ; Push "${_ExistingPath}" #text to be replaced ; Push "${_NewPath}" #replace with ; Push 0 #replace command ; Push 1 #replace but only one occurance.. not all close network references.... ; Push "${_NewPath}\${_ExistingLogFile}" #file to replace in ; Call AdvReplaceInFile ;; it reads the pushed variables as parameters.... ( Hey... I didn't design that interface... its confusing. ) ; ;!macroend !macro un.RollBackTo _rollbackLocalPath _rollbackLogName push `${_rollbackLocalPath}` push `${_rollbackLogName}` Call un.RollBack !macroend !define un.RollBackTo "!insertmacro un.RollBackTo" Function un.RollBack push $0 ; save register 0 on stack. ( So stack looks like $0 "_rollbackLogName" _rollbackLocalPath Rest of Stack..... Exch ; swap the top two objects on the stack.... _rollbackLogName $0 _rollbackLocalPath pop $0 ; stack looks like $0.._rollbackLocalPath ...Rest of Stack.... Using $0 to hld the RollBackLogName push $1 ; stack looks like $1 $0.._rollbackLocalPath Rest of Stack Use this var for handling readlines. Exch 2 ; stack looks like _rollbackLocalPath $0 $1 Rest of Stack pop $1 ; Use this var for handling the local path of the list of archived files. Exch ; stack looks like $1 $0 Rest of Stack push $2 ; stack look like $2 $1 $0 Rest of stack. Use $2 to hold read lines..... push $3 ; stack looks like $3 $2 $1 $0 RestofStack. Use this var for handling tag parsing of lines.... push $4 ; saving $4 too... use this var for holding filename of file. push $5 ; saving $5 too... use this var for holding target path. push $6 ; use this var for the command line to exeute if failed to copy.... push $7 ; use this var for temp file handle ; registry temp vars.... push $R1 ; protect this and use for the Root of the registry handles... push $R2 ; protect this and use for the Key push $R3 ; protect this and use for the subkey push $R4 ; protected this and use for the Value..... ifFileExists "$1\$0" StartRollBack 0 SetErrors MessageBox MB_OK "Unable to find rollback file for uninstall: $1\$0" Goto SRS_DONE Return ; perhaps the user just gave the file folder.... try to locate the .rllbck file in the folder.... if it exists. StartRollBack: clearerrors FileOpen $SRS_Rollback_FileHandle "$1\$0" r ; open file for read. IfErrors 0 SRS_RESTORE_ReadLine MessageBox MB_OK "Error opening the file for rollback: $1\$0" Goto SRS_DONE SRS_RESTORE_ReadLine: ClearErrors FileRead $SRS_Rollback_FileHandle $2 ; get line for parsing. ;MessageBox MB_OK $2 IfErrors SRS_DONE ; if errors, then EOF. Cleanup stack and exit. ; otherise parse line. StrCpy $3 $2 6 ;if this line is a file line, then the first six chars should be ;Handle Registry Alterations: StrCmp $3 "1${_someFileName}$OUTDIR${_onFailCommand} ;1${_RootKey}${_RegistryKey}${_SubKey}${_Value} #MessageBox MB_OK "$2" ; Because GetBetween only uses files as sources.... ( stupid, that I'm using that here, but I am.... ) ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK $4 ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $R1 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $R2 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $R3 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $R4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 #MessageBox MB_OK "$R1,$R2,$R3,$R4" #MessageBox MB_OK "$1, $4 , $R1 , $R2 , $R3 , $R4" StrCmp $4 "SRS_RollbackPath" RemoveIt 0 StrCmp $4 "SRS_Logname" RemoveIt 0 StrCmp $4 "1" 0 SRS_RESTORE_WRITE ; if the new marker is set to 1 then a rollback means remove it entirely..... RemoveIt: ${Switch} $R1 ${Case} "HKLM" DeleteRegValue HKLM $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCR" DeleteRegValue HKCR $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCU" DeleteRegValue HKCU $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKU" DeleteRegValue HKU $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKCC" DeleteRegValue HKCC $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKDD" DeleteRegValue HKDD $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "HKPD" DeleteRegValue HKPD $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${Case} "SHCTX" DeleteRegValue SHCTX $R2 $R3 ;$R1 $R2 $R3Goto EndSNFServiceTest ${EndSwitch} Goto SRS_RESTORE_ReadLine SRS_RESTORE_WRITE: ; if not then we need to restore the key..... ${Switch} $R1 ${Case} "HKLM" WriteRegStr HKLM $R2 $R3 $R4 ${Case} "HKCR" WriteRegStr HKCR $R2 $R3 $R4 ${Case} "HKCU" WriteRegStr HKCU $R2 $R3 $R4 ${Case} "HKU" WriteRegStr HKU $R2 $R3 $R4 ${Case} "HKCC" WriteRegStr HKCC $R2 $R3 $R4 ${Case} "HKDD" WriteRegStr HKDD $R2 $R3 $R4 ${Case} "HKPD" WriteRegStr HKPD $R2 $R3 $R4 ${Case} "SHCTX" WriteRegStr SHCTX $R2 $R3 $R4 ${EndSwitch} Goto SRS_RESTORE_ReadLine SRS_RESTORE_TestForFileLine: StrCmp $3 "" 0 SRS_RESTORE_ReadLine ; if its a file, then handle rolling back the file, otherwise get the next line. FileOpen $7 "$1\SRS_TempFile.txt" w FileWrite $7 $2 FileClose $7 ; Because GetBetween only uses files as sources.... ( stupid, that I'm using that here, but I am.... ) ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $4 ; Get the file name between the file tags of the read_line_in->$2 and stick it in $4 ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $R1 ; Get the marker that informed us if there WAS something to be copied, or if it was just installed. ;MessageBox MB_OK "Name:$4" ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $5 ; Get the targetpath between the file tags of the read_line_in->$2 and stick it in $5 ;MessageBox MB_OK "Target:$5" clearerrors ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $6 ; Get the CALLBACK name between the file tags of the read_line_in->$2 and stick it in $6 iferrors NoCallbackAvailable 0 StrCmp $6 "" NoCallbackAvailable 0 ; Ok, we have a callback, so we don't copy, we call file, and pass the filename. ;MessageBox MB_OK "Pushing $1\$4" push "$1\$4" ; push the file and path onto the stack. push $6 ; push the calback value onto the stack, Call un.ResolveFunction ; call the resolveFunction Call. Goto SRS_RESTORE_ReadLine ; No copy, just return for next line handle. NoCallbackAvailable: ; now deal with new vs archived files... StrCmp $R1 "1" 0 SRS_NOTNEW_RESTOREIT ; test to see if it was new, or if it required backin gup... ifFileExists "$5\$4" 0 SRS_RESTORE_ReadLine ; if it WAS new... test to see if file still exists... Delete "$5\$4" ; Since it was new we'll remove it on a restore.... Goto SRS_RESTORE_ReadLine SRS_NOTNEW_RESTOREIT: CopyFiles /SILENT "$1\$4" "$5\$4" iferrors 0 SRS_RESTORE_ReadLine clearerrors ${un.GetBetween} "" "" "$1\SRS_TempFile.txt" $6 ; Get the onfail name between the file tags of the read_line_in->$2 and stick it in $6 ; if we're here, then we need to rexecute the copy after executing the command line push "$1\$4" ; push the file and path onto the stack. push $6 ; push the callback value onto the stack, Call un.ResolveFunction ; call the resolveFunction Call. clearerrors CopyFiles /SILENT "$1\$4" "$5\$4" iferrors 0 SRS_RESTORE_ReadLine ; if still an error, then notify and try next line. ; MessageBox MB_OK "Error in rolling back file: $1\$4 to $5\$4" Goto SRS_RESTORE_ReadLine ; ok, either we parsed the file, or we quit with errors... either way. clean the stack.... SRS_DONE: ; done with readling lines from the file. Delete "$1\SRS_TempFile.txt" FileClose $SRS_Rollback_FileHandle ; Now parse the file name pop $R4 pop $R3 pop $R2 pop $R1 pop $7 pop $6 pop $5 pop $4 pop $3 pop $2 ;restore $2 pop $1 ;restore $1 pop $0 ; restore $0 to previous value.... return ; end FunctionEnd