$version = "0.97" ; Give the user a warning and ask if its ok to continue. $continue = MsgBox(4, "Comtrol Driver Uninstallation Script "& $version, "This script will remove files, directories, and registry entries to purge a driver from your machine."&@CRLF&"This can be a dangerous process and we cant be held responsible for data loss."&@CRLF&"Please backup your system!"&@CRLF&@CRLF&"Do you wish to continue?") If $continue = 7 OR $continue = -1 OR $continue = 2 OR $continue = 3 Then Exit EndIf $badchoicemsg = "" $bLoop = 1 While $bLoop = 1 $choice = InputBox("Product Choice", "Choose a product" & @CRLF & " 1) DeviceMaster/RocketPort Serial Hubs si/ia" & @CRLF & " 2) RocketPort ISA/PCI/uPCI Cards" & @CRLF & " 3) RocketPort 550 PCI/uPCI Cards" & @CRLF & @CRLF & "Please choose a number and press enter", $badchoicemsg) If @error = 1 Then Exit Else Select Case $choice = 1 $product = "DeviceMaster/RPSH" $bLoop = 0 Case $choice = 2 $product = "RocketPort" $bLoop = 0 Case $choice = 3 $product = "RocketPort 550" $bLoop = 0 Case Else $badchoicemsg = "Invalid choice selected!" EndSelect EndIf WEnd ; Check to make sure dependencies are met for the application ; I wish I did not require external apps for this to work correctly If @compiled Then If NOT FileInstall("SetACL.exe", "SetACL.exe", 1) Then MsgBox(0, "File Installation Error", "This script could not copy 'SetACL.exe' to the same directory the script is in.") Exit EndIf EndIf dim $errorcount = 0, $errors[32000] dim $recurse = 0 $logfilename = "Uninstallation-" & @ComputerName & "-" &@YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&".log" $backupdir = "Backup-" & @ComputerName & "-" &@YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC ; Create timestamped directory all the backed up files and logs will go into If DirCreate ( $backupdir ) Then Else Output(2,"Could not create backup directory '" & $backupdir & "'") Exit EndIf dim $log = OpenLogOutput($logfilename) dim $percent = 0; Output(0,"#### System and Test Information ####") Output(0,@HOUR & ":" & @MIN & ":" & @SEC & " " & @MON & "/" & @MDAY & "/" & @YEAR) Output(0,"Script Version:" & $version) Output(0,"Product:" & $product) Output(0,"OS:" & @OSVersion) Output(0,"Windows Directory:" & @WindowsDir) Output(0,@CRLF & "#### Uninstallation Output ####") Select Case $choice = 1 Select Case @OSType = "WIN32_NT" DMWIN2000to2003() Case Else MsgBox(0, "Unsupported OS", "I am sorry, but your current OS is not supported by this application.") Exit EndSelect Case $choice = 2 Select Case @OSType = "WIN32_NT" RPWIN2000to2003() Case Else MsgBox(0, "Unsupported OS", "I am sorry, but your current OS is not supported by this application.") Exit EndSelect Case $choice = 3 Select Case @OSType = "WIN32_NT" RP550WIN2000to2003() Case Else MsgBox(0, "Unsupported OS", "I am sorry, but your current OS is not supported by this application.") Exit EndSelect EndSelect PrintErrorSummary() CloseLogOutput() ProgressOff() If $errorcount > 0 Then $exiterrormsg = @CRLF & $errorcount & " error(s) occured during uninstallation, examine log file!" Else $exiterrormsg = @CRLF & "No errors detected during uninstallation." EndIf MsgBox(0, "Uninstallation Complete", "Uninstallation Complete. Please REBOOT your computer now!" & @CRLF & @CRLF & "Logfile Created As: " & $logfilename & $exiterrormsg) Func DMWIN2000to2003 () dim $steps = 6, $stepcount = 0 $files = "inf\ctmaport.inf inf\cpmaport.pnf inf\ctmproto.inf inf\ctmproto.pnf inf\ctmsport.inf inf\ctmsport.pnf inf\ctmvport.inf inf\ctmvport.pnf system32\ctmnslnt.cat system32\ctmsclas.dll system32\ctmsport.inf system32\drivers\devmast.bin system32\drivers\rpshsi.bin system32\drivers\rpshsi.sys system32\drivers\rpshsi2p.bin system32\sisetup.dll system32\drivers\sisetup.dll system32\drivers\vslinka.bin system32\drivers\vslinka.sys" $directories = "system32\rpshsi system32\vslink" $infsearchstrings = "NS Link install script, CtmSPort, RPSHsi Protocol Driver, nslink.cat" $regentries = "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\CtmPort\SiPORT, HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\rpshsi" ; Tell the user to remove all devicemasters and rpshsi from their device manager before proceding $continue = MsgBox(4, "Comtrol Driver Uninstallation Script "& $version, "Its recommended, but not required, that you go to the Device Manager, uninstall all Device Masters, RocketPort Serial Hubs, and VS1000s before continuing" & @CRLF & "This is also your last chance to cancel" & @CRLF & @CRLF & "Continue?") If $continue = 7 OR $continue = -1 OR $continue = 2 OR $continue = 3 Then Exit EndIf ; Open the progress bar to display status ProgressOn("Comtrol " & $product & " Driver Uninstallation Script", "0 Percent" , "Startup") ProgressSet( $percent, @OSVersion, $percent & " Percent") SetProgress("Deleting driver files", $steps, $stepcount, 1) DeleteFiles(@WindowsDir, $files) SetProgress("Deleting driver directories", $steps, $stepcount, 1) DeleteDirectories(@WindowsDir, $directories) SetProgress("Deleting related .inf files", $steps, $stepcount, 1) If FileExists(@WindowsDir & "\inf") Then $results = SearchFiles(@WindowsDir & "\inf", "oem*.inf", $infsearchstrings) If StringLen ( $results ) Then DeleteFiles(@WindowsDir & "\inf", $results) EndIf EndIf SetProgress("Deleting related registry entries", $steps, $stepcount, 1) DeleteRegistryEntries($regentries) SetProgress("Searching/Deleting related registry entries", $steps, $stepcount, 1) DeleteMultiRegistryEntries("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\Root\MULTIPORTSERIAL\", "Services", "rpshsi", 0) SetProgress("Completed", $steps, $stepcount, 1) EndFunc Func RPWIN2000to2003 () dim $steps = 5, $stepcount = 0 $files = "system32\drivers\rocket.sys" $directories = "system32\rocket" $infsearchstrings = "netctmrk.inf" $regentries = "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\RKPORT, HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\RocketPort" ; Tell the user to remove all rocketports from their device manager before proceding $continue = MsgBox(4, "Comtrol RocketPort Driver Uninstallation Script "& $version, "Please go to the Device Manager, uninstall all RocketPort cards, and reboot before continuing" & @CRLF & "This is also your last chance to cancel" & @CRLF & @CRLF & "Continue?") If $continue = 7 OR $continue = -1 OR $continue = 2 OR $continue = 3 Then Exit EndIf ; Open the progress bar to display status ProgressOn("Comtrol " & $product & " Driver Uninstallation Script", "0 Percent" , "Startup") ProgressSet( $percent, @OSVersion, $percent & " Percent") SetProgress("Deleting driver files", $steps, $stepcount, 1) DeleteFiles(@WindowsDir, $files) SetProgress("Deleting driver directories", $steps, $stepcount, 1) DeleteDirectories(@WindowsDir, $directories) SetProgress("Deleting related .inf files", $steps, $stepcount, 1) If FileExists(@WindowsDir & "\inf") Then $results = SearchFiles(@WindowsDir & "\inf", "oem*.inf", $infsearchstrings) If StringLen ( $results ) Then DeleteFiles(@WindowsDir & "\inf", $results) EndIf EndIf SetProgress("Deleting related registry entries", $steps, $stepcount, 1) DeleteRegistryEntries($regentries) SetProgress("Completed", $steps, $stepcount, 1) EndFunc Func RP550WIN2000to2003 () dim $steps = 5, $stepcount = 0 $files = "inf\Rckt550b.inf inf\Rckt550b.pnf system32\drivers\rcktmf.sys system32\drivers\rcktmfuf.sys system32\drivers\rcktser.sys" ;$directories = "" $infsearchstrings = "Rckt550.inf" $regentries = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Rckt550, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RcktMf, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Rcktmfuf" ; Tell the user to remove all rocketports from their device manager before proceding $continue = MsgBox(4, "Comtrol RocketPort Driver Uninstallation Script "& $version, "Its recommended, but not required, that you go to the Device Manager, uninstall all RocketPort 550 cards, and reboot before continuing" & @CRLF & "This is also your last chance to cancel" & @CRLF & @CRLF & "Continue?") If $continue = 7 OR $continue = -1 OR $continue = 2 OR $continue = 3 Then Exit EndIf ; Open the progress bar to display status ProgressOn("Comtrol " & $product & " Driver Uninstallation Script", "0 Percent" , "Startup") ProgressSet( $percent, @OSVersion, $percent & " Percent") SetProgress("Deleting driver files", $steps, $stepcount, 1) DeleteFiles(@WindowsDir, $files) ;SetProgress("Deleting driver directories", $steps, $stepcount, 1) ;DeleteDirectories(@WindowsDir, $directories) SetProgress("Deleting related .inf files", $steps, $stepcount, 1) If FileExists(@WindowsDir & "\inf") Then $results = SearchFiles(@WindowsDir & "\inf", "oem*.inf", $infsearchstrings) If StringLen ( $results ) Then DeleteFiles(@WindowsDir & "\inf", $results) EndIf EndIf SetProgress("Deleting related registry entries", $steps, $stepcount, 1) DeleteRegistryEntries($regentries) SetProgress("Searching/Deleting related registry entries", $steps, $stepcount, 1) DeleteMultiRegistryEntries("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class", "InfPath", "rckt550b.inf", 0) DeleteMultiRegistryEntries("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum", "Service", "RcktMf", 0) DeleteMultiRegistryEntries("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum", "Service", "Rckt550", 0) SetProgress("Completed", $steps, $stepcount, 1) EndFunc Func DeleteFiles ($dir, $files) $allfiles = StringSplit($files, " ") For $file = 1 To ($allfiles[0]) Step 1 If FileExists($dir & "\" & $allfiles[$file]) Then $lastslash = StringInStr( $allfiles[$file], "\" ,0 ,-1 ) $path = StringLeft ( $allfiles[$file], ($lastslash-1) ) If FileExists($backupdir & "\" & $path) Then Else DirCreate ($backupdir & "\" & $path) EndIf If FileCopy ( $dir & "\" & $allfiles[$file], $backupdir & "\" & $path & "\") Then FileDelete($dir & "\" & $allfiles[$file]) If FileExists($dir & "\" & $allfiles[$file]) Then Output(2,"File " & $dir & "\" & $allfiles[$file] & " was found but couldnt be deleted") Else Output(1,"File " & $dir & "\" & $allfiles[$file] & " was found and successfully deleted") Endif Else Output(2, "Could not backup '"&$dir & "\" & $allfiles[$file]&"' to '"&$backupdir&"'") Exit EndIf Else Output(1,"File " & $dir & "\" & $allfiles[$file] & " was not found on the system") EndIf Next EndFunc Func DeleteDirectories ($dir, $dirs) $alldirs = StringSplit($dirs, " ") For $onedir = 1 To ($alldirs[0]) Step 1 If FileExists($dir & "\" & $alldirs[$onedir]) Then $lastslash = StringInStr( $alldirs[$onedir], "\" ,0 ,-1 ) $path = StringLeft ( $alldirs[$onedir], ($lastslash-1) ) $file = StringRight ( $alldirs[$onedir], (StringLen ($alldirs[$onedir]) - $lastslash) ) If DirCopy ( $dir & "\" & $alldirs[$onedir], $backupdir & "\" & $alldirs[$onedir]) Then If FileExists($backupdir & "\" & $alldirs[$onedir]) Then DirRemove($dir & "\" & $alldirs[$onedir], 1) If FileExists($dir & "\" & $alldirs[$onedir]) AND $alldirs[$onedir] <> "system32\rocket" Then Output(2,"Directory " & $dir & "\" & $alldirs[$onedir] & " was found but couldnt be deleted") Else Output(1,"Directory " & $dir & "\" & $alldirs[$onedir] & " was found and successfully deleted") Endif Else Output(2,"Directory backup doesnt exist for '"&$dir & "\" & $alldirs[$onedir]&"' to '"&$backupdir&"\'") EndIf Else Output(2,"Could not backup '"&$dir & "\" & $alldirs[$onedir]&"' to '"&$backupdir&"\'") Exit EndIf Else Output(1,"Directory " & $dir & "\" & $alldirs[$onedir] & " was not found on the system") EndIf Next EndFunc Func DeleteRegistryEntries ($entries) $allentries = StringSplit($entries, ",") For $entrynum = 1 To ($allentries[0]) Step 1 $allentries[$entrynum] = StringStripWS($allentries[$entrynum], 3) $lastslash = StringInStr( $allentries[$entrynum], "\" ,0 ,-1 ) $path = StringLeft ( $allentries[$entrynum], ($lastslash-1) ) $key = StringRight ( $allentries[$entrynum], (StringLen ($allentries[$entrynum]) - $lastslash) ) $key = StringReplace( $key, "&", "") RunWait(@ComSpec & " /c" & @WindowsDir & "\regedit /e " & $backupdir & "\" & $key & ".reg """ & $allentries[$entrynum] & """",) RunWait(@ComSpec & " /c" & @ScriptDir & '\SetACL.exe -on "'&$allentries[$entrynum]&'" -ot reg -actn ace -rec yes -ace "n:Administrator;p:full"') If FileExists($backupdir & "\" & $key & ".reg") Then $return = RegDelete($allentries[$entrynum]) Select Case $return = 0 Output(1, "Registry entry '" & $allentries[$entrynum] & "' does not exist, hence was not deleted") Case $return = 1 Output(1, "Registry entry '" & $allentries[$entrynum] & "' successfully deleted") Case $return = 2 Output(2, "Registry entry '" & $allentries[$entrynum] & "' exists but could not be deleted") EndSelect Else Output(1, "Registry backup file not created, delete will not procede for '" & $allentries[$entrynum] & "'") EndIf Next EndFunc Func DeleteMultiRegistryEntries ($path, $key, $strings, $recurse) $allstrings = StringSplit($strings, ",") $maxrecurse = 5 $keynum = 1 $subkey = 1 dim $count While $subkey $subkey = RegEnumKey($path, $keynum) If $subkey Then ;Output(100, "DeleteMultiReg Func: subkey:" & $path & "\" & $subkey) If $recurse < $maxrecurse Then DeleteMultiRegistryEntries ($path & "\" & $subkey, $key, $strings, $recurse + 1) EndIf For $stringnum = 1 To ($allstrings[0]) Step 1 If RegRead($path & "\" & $subkey, $key) = $allstrings[$stringnum] Then $lastslash = StringInStr( $path, "\" ,0 ,-1 ) $parentpath = StringLeft ( $path, ($lastslash-1) ) Output(1, "Registry key '" & $path & "\" & $subkey &"' contains '" & $allstrings[$stringnum] & "' and is queued for deletion") ; set the permissions on the parent directory so admin can delete, this is bad, but what can ya do huh RunWait(@ComSpec & " /c" & @ScriptDir & '\SetACL.exe -on "$parentpath" -ot reg -actn ace -rec yes -ace "n:Administrator;p:full"') ;Output(100, "DeleteMultiReg Func: deleting:" & $path & "\" & $subkey) DeleteRegistryEntries($path & "\" & $subkey) $count = $count + 1 EndIf Next EndIf $keynum = $keynum + 1 WEnd ;If $count = 0 AND $recurse = 0 Then ; Output(1, "No Multiport Serial registry entries in '" & $path & "' matching '" & $strings & "', so none deleted") ;EndIf EndFunc Func CloseLogOutput () dim $log FileClose($log) EndFunc Func OpenLogOutput ($filename) $log = FileOpen ( $backupdir & "\" & $filename, 2 ) If $log = -1 Then MsgBox(0, "Error", "Unable to create/open log file.") Exit EndIf Return $log EndFunc Func Output ($error, $msg) dim $log dim $errors, $errorcount Select Case $error = 0 Case $error = 1 $msg = "[PASS] " & $msg Case $error = 2 $errors[$errorcount] = $msg $errorcount = $errorcount + 1 $msg = "[FAIL] " & $msg Case $error = 100 $msg = "DEBUG: " & $msg EndSelect FileWriteLine ($log, $msg ) EndFunc Func PrintErrorSummary () dim $errors, $errorcount Output(0,@CRLF & "#### Total Error Summary ####") If $errorcount = 0 Then Output(0,"No Errors Occured.") Else For $count = 0 to ($errorcount-1) Step 1 Output(0,($errors[$count])) Next EndIf EndFunc Func SetProgress ($msg, $steps, ByRef $stepcount, $increase) If $increase Then $stepcount = $stepcount + 1 EndIf $percent = Round($stepcount/$steps*100) ProgressSet($percent, $msg, $percent & " Percent") EndFunc Func SearchFiles ($dir, $search, $searchstring) $searchresult = FileFindFirstFile($dir & "\" & $search) $strings = StringSplit($searchstring, ",") $matching = "" If $searchresult = -1 Then Output(2, "Could not search the specified path of '" & $search & "'") EndIf While 1 $file = FileFindNextFile($searchresult) If @error Then ExitLoop if $file <> "." AND $file <> ".." Then $filecontents = FileOpen($dir & "\" & $file,0) If $filecontents = -1 Then Output(2, "Could not open inf file '"& $dir & "\" & $file &"' for searching") EndIf $searchfile = 1 While 1 AND $searchfile $line = FileReadLine($filecontents) If @error Then ExitLoop For $stringnum = 1 To ($strings[0]) Step 1 $strings[$stringnum] = StringStripWS ( $strings[$stringnum], 3 ) If StringInStr($line, $strings[$stringnum]) Then $matching = $matching & " " & $file Output(1,"File '" & $dir & "\" & $file & "' matched '" & $strings[$stringnum] & "' and is now queued for deletion") $searchfile = 0 ExitLoop EndIf Next Wend FileClose($filecontents) EndIf WEnd FileClose($searchresult) If $matching = "" Then Output(1, "No files found in '"& $dir & "\" & $search & "' containing '" & $searchstring & "'") EndIf $matching = $matching & StringReplace ( $matching, ".inf", ".pnf") $matching = StringStripWS ( $matching, 3 ) Return $matching EndFunc