Monday, April 28, 2008

Invisible USB Flash drives due to network drives in Windows XP.

#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=Flasher.ico
#AutoIt3Wrapper_outfile=Flasher.exe
#AutoIt3Wrapper_UseAnsi=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
AutoItSetOption ("RunErrorsFatal", 0)
AutoItSetOption ("TrayIconHide",1)
#include <array.au3>
#include <Date.au3>
#include <ServiceControl.au3>
 
Dim $ADrv[26], $RDrv[26], $NDrv[26], $Available[23]
dim $i
Dim $InstallPath
if $CmdLine[0] = "" then Exit
 
$InstallPath = "C:\Program Files\NYITSUPPORT\Flasher\"
 
Select
    case @OSVersion = "WIN_XP"
        Call ("StartSequence")
    case @OSVersion = "WIN_2000"
        $ver = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions", "ProductType")
        If $ver = "ServerNT" then Exit
        Call ("StartSequence")
    case Else
        Exit
EndSelect    
    
Func StartSequence()
    Select
        case $CmdLine [1] = "/uninstall"
            if not IsAdmin() then Exit
            call ("Uninstall")
            
        case $CmdLine [1] = "/install" 
            if not IsAdmin() then Exit
            if FileExists($InstallPath) then Exit
            Call ("Install")
            Exit
            
        case $CmdLine [1] = "/client"
            call ("Client")
            Exit
            
        case $CmdLine [1] = "/service"
            if not IsAdmin() then Exit
            call ("Service")
 
        case Else
            Exit
            
    EndSelect
EndFunc
 
Func Install()
    FileCopy (@ScriptFullPath, $InstallPath,8)
    FileCopy (@ScriptDir & "\RunAsSvc.exe", $InstallPath, 8)
    ShellExecute("cacls.exe", '"' & StringLeft($InstallPath, StringLen($InstallPath)-1) & '" /e /c /g BUILTIN\Users:F')
    $args = ' -i --displayname "NYITSUPPORT Flasher" --description "NYITSUPPORT Flasher SERVICE" --exe "' & $InstallPath & "flasher.exe" & '" --params "/service" --quiet'
    FileCreateShortcut($InstallPath & "Flasher.exe", @StartupCommonDir & "\NYITSUPPORT Flasher.lnk", $InstallPath, "/client", "NYITSUPPORT Flasher CLIENT")
    RunWait ($InstallPath & "RunAsSvc.exe" & $args)
EndFunc
 
Func Uninstall()
    FileDelete (@StartupCommonDir & "\NYITSUPPORT Flasher.lnk")
    ;Kill the Flasher SERVICE
    $objWMIService = ObjGet("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")
    $colListOfServices = $objWMIService.ExecQuery ("Select * from Win32_Service Where DisplayName = 'NYITSUPPORT Flasher'")
    For $objService in $colListOfServices
        $objService.StopService()
        $objService.Delete()
    Next
    ;Kill running Flasher CLIENT and delete the Flasher folder
    Dim $objWMIService, $objProcess, $colProcess
    $objWMIService =ObjGet("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2") 
    $colProcess = $objWMIService.ExecQuery ("Select * from Win32_Process Where Name = " & "'flasher.exe'")
    For $objProcess in $colProcess
        DirRemove($InstallPath,1)
        $objProcess.Terminate()
    Next 
 
EndFunc
 
Func Client()
    While 1=1
        Sleep(30000)
        Call("Available")
    WEnd
EndFunc
 
Func Available()     ;collect D:-Z: into the $Available array
    for $p = 1 to 23
        _ArrayDelete($Available,$p)
    Next
    For $i = 68 To 90
        _ArrayInsert($Available, $i - 68, Chr($i) & ":")
    Next
    Call("Existing")
EndFunc
 
Func Existing() ;delete any existing drives from the $Available array
    $ADrv = DriveGetDrive("ALL")
    For $a = 1 To UBound($ADrv) - 1
        $b = _ArraySearch($Available, $ADrv[$a], 0, 0, 0)
        If $b <> -1 Then _ArrayDelete($Available, $b)
    Next
    If $Available[1] = "" Then
        sleep(120000)
    Else
        _ArraySort($Available, 1)
        Call("REMAP")
    EndIf    
EndFunc   ;==>Existing
 
Func REMAP()
    $NDrv = DriveGetDrive("NETWORK")
    If $NDrv <> 0 Then
        For $i = 1 To UBound($NDrv) - 1
            $j = RegRead("HKLM\SYSTEM\MountedDevices", "\DosDevices\" & $NDrv[$i]) ;check for presense of HKLM\SYSTEM\MountedDevices\DosDevices\(n): Drive
            If $j <> "" Then
                    $ChangeFile = FileOpen($InstallPath & "Flasher.Change", 2)
                    $fwl = FileWriteLine ($ChangeFile, $NDrv[$i] & "-" & $Available[1])
                    FileClose($ChangeFile)
            EndIf
        Next
    EndIf
EndFunc
 
Func Service()
    while 1 = 1
    sleep(30000)
    $ChangeFile = $InstallPath & "Flasher.Change"
        if FileExists ($ChangeFile) Then
            $ChangeFile = FileOpen($InstallPath & "Flasher.Change",0)
            $Flasher_Change = FileReadLine ($ChangeFile)
            $Before = StringMid ($Flasher_Change, 1, 2)
            $After = StringMid ($Flasher_Change, 4, 2)
            $Data = RegRead("HKLM\SYSTEM\MountedDevices", "\DosDevices\" & $Before)
            $rd = RegDelete("HKLM\SYSTEM\MountedDevices", "\DosDevices\" & $Before)
                if $rd = 1 then 
                    RegWrite("HKLM\SYSTEM\MountedDevices", "\DosDevices\" & $After, "REG_BINARY", $Data)
                    FileClose($ChangeFile)
                    FileDelete($ChangeFile)
                EndIf
        EndIf
        FileClose($ChangeFile)
        FileDelete($ChangeFile)
    WEnd
EndFunc

This application was written to address a known issue in Microsoft Windows XP/2000 with drive letter usage. If a user logs in and has drives mapped starting at F and higher, and connects a flash drive, Windows will assign the next available system drive ignoring the user's mapped drive letters. Now since the user has a drive mapped at the letter already, he will not see the flash drive. You can correct this by going into compmgmt.msc - drive manager, and change the physical letter there. The only problem is unless the user does not have admin rights, he would not be able to change anything. There is a hotfix that Microsoft has released for XP http://support.microsoft.com/kb/297694 If you cannot acquire the hotfix, or have some other issues for not installing it. You can use flasher.exe, it has a small footprint while running and is hardly noticable. I created this application before the hotfix became available. It has worked great in our parent company deployment for many months. I originally saw another application that was available for free for personal use, but you have to buy for a corporate environment. It worked in a test environment, and is probably better written, I needed my own solution that i can troubleshoot programmatically, not to mention it was free (minus my time). http://www.uwe-sieber.de/usbdlm_e.html My approach is very different though as you can tell in the code. In any case youre free to use and reuse the code any way you please as long as you dont hold me responsible for any damage. I also rely on a ServiceControl.au3 http://www.autoitscript.com/forum/index.php?showtopic=6487

Global $STANDARD_RIGHTS_REQUIRED = 0x000F0000
 
; Service Control Manager access types
Global $SC_MANAGER_CONNECT = 0x0001
Global $SC_MANAGER_CREATE_SERVICE = 0x0002
Global $SC_MANAGER_ENUMERATE_SERVICE = 0x0004
Global $SC_MANAGER_LOCK = 0x0008
Global $SC_MANAGER_QUERY_LOCK_STATUS = 0x0010
Global $SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020
 
Global $SC_MANAGER_ALL_ACCESS = BitOR($STANDARD_RIGHTS_REQUIRED, _
                                      $SC_MANAGER_CONNECT, _
                                      $SC_MANAGER_CREATE_SERVICE, _
                                      $SC_MANAGER_ENUMERATE_SERVICE, _
                                      $SC_MANAGER_LOCK, _
                                      $SC_MANAGER_QUERY_LOCK_STATUS, _
                                      $SC_MANAGER_MODIFY_BOOT_CONFIG)
 
; Service access types
Global $SERVICE_QUERY_CONFIG = 0x0001
Global $SERVICE_CHANGE_CONFIG = 0x0002
Global $SERVICE_QUERY_STATUS = 0x0004
Global $SERVICE_ENUMERATE_DEPENDENTS = 0x0008
Global $SERVICE_START = 0x0010
Global $SERVICE_STOP = 0x0020
Global $SERVICE_PAUSE_CONTINUE = 0x0040
Global $SERVICE_INTERROGATE = 0x0080
Global $SERVICE_USER_DEFINED_CONTROL = 0x0100
 
Global $SERVICE_ALL_ACCESS = BitOR($STANDARD_RIGHTS_REQUIRED, _
                                   $SERVICE_QUERY_CONFIG, _
                                   $SERVICE_CHANGE_CONFIG, _
                                   $SERVICE_QUERY_STATUS, _
                                   $SERVICE_ENUMERATE_DEPENDENTS, _
                                   $SERVICE_START, _
                                   $SERVICE_STOP, _
                                   $SERVICE_PAUSE_CONTINUE, _
                                   $SERVICE_INTERROGATE, _
                                   $SERVICE_USER_DEFINED_CONTROL)
 
; Service controls
Global $SERVICE_CONTROL_STOP = 0x00000001
Global $SERVICE_CONTROL_PAUSE = 0x00000002
Global $SERVICE_CONTROL_CONTINUE = 0x00000003
Global $SERVICE_CONTROL_INTERROGATE = 0x00000004
Global $SERVICE_CONTROL_SHUTDOWN = 0x00000005
Global $SERVICE_CONTROL_PARAMCHANGE = 0x00000006
Global $SERVICE_CONTROL_NETBINDADD = 0x00000007
Global $SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
Global $SERVICE_CONTROL_NETBINDENABLE = 0x00000009
Global $SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
Global $SERVICE_CONTROL_DEVICEEVENT = 0x0000000B
Global $SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C
Global $SERVICE_CONTROL_POWEREVENT = 0x0000000D
Global $SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E
 
; Service types
Global $SERVICE_KERNEL_DRIVER = 0x00000001
Global $SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
Global $SERVICE_ADAPTER = 0x00000004
Global $SERVICE_RECOGNIZER_DRIVER = 0x00000008
Global $SERVICE_DRIVER = BitOR($SERVICE_KERNEL_DRIVER, _
                               $SERVICE_FILE_SYSTEM_DRIVER, _
                               $SERVICE_RECOGNIZER_DRIVER)
Global $SERVICE_WIN32_OWN_PROCESS = 0x00000010
Global $SERVICE_WIN32_SHARE_PROCESS = 0x00000020
Global $SERVICE_WIN32 = BitOR($SERVICE_WIN32_OWN_PROCESS, _
                              $SERVICE_WIN32_SHARE_PROCESS)
Global $SERVICE_INTERACTIVE_PROCESS = 0x00000100
Global $SERVICE_TYPE_ALL = BitOR($SERVICE_WIN32, _
                                 $SERVICE_ADAPTER, _
                                 $SERVICE_DRIVER, _
                                 $SERVICE_INTERACTIVE_PROCESS)
 
; Service start types
Global $SERVICE_BOOT_START = 0x00000000
Global $SERVICE_SYSTEM_START = 0x00000001
Global $SERVICE_AUTO_START = 0x00000002
Global $SERVICE_DEMAND_START = 0x00000003
Global $SERVICE_DISABLED = 0x00000004
 
; Service error control
Global $SERVICE_ERROR_IGNORE = 0x00000000
Global $SERVICE_ERROR_NORMAL = 0x00000001
Global $SERVICE_ERROR_SEVERE = 0x00000002
Global $SERVICE_ERROR_CRITICAL = 0x00000003
 
;===============================================================================
; Description:   Starts a service on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to start
; Requirements:  None
; Return Values: On Success - 1
;                On Failure - 0 and @error is set to extended Windows error code
; Note:          This function does not check to see if the service has started successfully
;===============================================================================
Func _StartService($sComputerName, $sServiceName)
   Local $hAdvapi32
   Local $hKernel32
   Local $arRet
   Local $hSC
   Local $hService
   Local $lError = -1
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $hKernel32 = DllOpen("kernel32.dll")
   If $hKernel32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _ 
                    "long", $SC_MANAGER_CONNECT)
   If $arRet[0] = 0 Then
      $arRet = DllCall($hKernel32, "long", "GetLastError")
      $lError = $arRet[0]
   Else
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_START)
      If $arRet[0] = 0 Then
         $arRet = DllCall($hKernel32, "long", "GetLastError")
         $lError = $arRet[0]
      Else
         $hService = $arRet[0]
         $arRet = DllCall($hAdvapi32, "int", "StartService", _
                          "long", $hService, _
                          "long", 0, _
                          "str", "")
         If $arRet[0] = 0 Then
            $arRet = DllCall($hKernel32, "long", "GetLastError")
            $lError = $arRet[0]
         EndIf
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService)         
      EndIf
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)
   DllClose($hKernel32)
   If $lError <> -1 Then 
      SetError($lError)
      Return 0
   EndIf
   Return 1
EndFunc
 
;===============================================================================
; Description:   Stops a service on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to stop
; Requirements:  None
; Return Values: On Success - 1
;                On Failure - 0 and @error is set to extended Windows error code
; Note:          This function does not check to see if the service has stopped successfully
;===============================================================================
Func _StopService($sComputerName, $sServiceName)
   Local $hAdvapi32
   Local $hKernel32
   Local $arRet
   Local $hSC
   Local $hService
   Local $lError = -1
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $hKernel32 = DllOpen("kernel32.dll")
   If $hKernel32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_CONNECT)
   If $arRet[0] = 0 Then
      $arRet = DllCall($hKernel32, "long", "GetLastError")
      $lError = $arRet[0]
   Else
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_STOP)
      If $arRet[0] = 0 Then
         $arRet = DllCall($hKernel32, "long", "GetLastError")
         $lError = $arRet[0]
      Else
         $hService = $arRet[0]
         $arRet = DllCall($hAdvapi32, "int", "ControlService", _
                          "long", $hService, _
                          "long", $SERVICE_CONTROL_STOP, _
                          "str", "")
         If $arRet[0] = 0 Then
            $arRet = DllCall($hKernel32, "long", "GetLastError")
            $lError = $arRet[0]
         EndIf
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService)         
      EndIf
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)
   DllClose($hKernel32)   
   If $lError <> -1 Then 
      SetError($lError)
      Return 0
   EndIf
   Return 1
EndFunc
 
;===============================================================================
; Description:   Checks if a service exists on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to check
; Requirements:  None
; Return Values: On Success - 1
;                On Failure - 0
;===============================================================================
Func _ServiceExists($sComputerName, $sServiceName)
   Local $hAdvapi32
   Local $arRet
   Local $hSC
   Local $bExist = 0
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_CONNECT)
   If $arRet[0] <> 0 Then
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_INTERROGATE)
      If $arRet[0] <> 0 Then
         $bExist = 1
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $arRet[0])
      EndIf
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)
   Return $bExist
EndFunc
 
;===============================================================================
; Description:   Checks if a service is running on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to check
; Requirements:  None
; Return Values: On Success - 1
;                On Failure - 0
; Note:          This function relies on the fact that only a running service responds
;                to a SERVICE_CONTROL_INTERROGATE control code. Check the ControlService
;                page on MSDN for limitations with using this method.
;===============================================================================
Func _ServiceRunning($sComputerName, $sServiceName)
   Local $hAdvapi32
   Local $arRet
   Local $hSC
   Local $hService   
   Local $bRunning = 0
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_CONNECT)
   If $arRet[0] <> 0 Then
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_INTERROGATE)
      If $arRet[0] <> 0 Then
         $hService = $arRet[0]
         $arRet = DllCall($hAdvapi32, "int", "ControlService", _
                          "long", $hService, _
                          "long", $SERVICE_CONTROL_INTERROGATE, _
                          "str", "")
         $bRunning = $arRet[0]
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService)
      EndIf
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)   
   Return $bRunning
EndFunc
 
;===============================================================================
; Description:   Creates a service on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to create
;                $sDisplayName - display name of the service
;                $sBinaryPath - fully qualified path to the service binary file
;                               The path can also include arguments for an auto-start service
;                $sServiceUser - [optional] default is LocalSystem
;                                name of the account under which the service should run
;                $sPassword - [optional] default is empty
;                             password to the account name specified by $sServiceUser
;                             Specify an empty string if the account has no password or if the service 
;                             runs in the LocalService, NetworkService, or LocalSystem account
;                 $nServiceType - [optional] default is $SERVICE_WIN32_OWN_PROCESS
;                 $nStartType - [optional] default is $SERVICE_AUTO_START
;                 $nErrorType - [optional] default is $SERVICE_ERROR_NORMAL
;                 $nDesiredAccess - [optional] default is $SERVICE_ALL_ACCESS
;                 $sLoadOrderGroup - [optional] default is empty
;                                    names the load ordering group of which this service is a member
; Requirements:  Administrative rights on the computer
; Return Values: On Success - 1
;                On Failure - 0 and @error is set to extended Windows error code
; Note:          Dependencies cannot be specified using this function
;                Refer to the CreateService page on MSDN for more information
;===============================================================================
Func _CreateService($sComputerName, _
                    $sServiceName, _
                    $sDisplayName, _
                    $sBinaryPath, _
                    $sServiceUser = "LocalSystem", _
                    $sPassword = "", _
                    $nServiceType = 0x00000010, _
                    $nStartType = 0x00000002, _
                    $nErrorType = 0x00000001, _
                    $nDesiredAccess = 0x000f01ff, _
                    $sLoadOrderGroup = "")
   Local $hAdvapi32
   Local $hKernel32
   Local $arRet
   Local $hSC
   Local $lError = -1   
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $hKernel32 = DllOpen("kernel32.dll")
   If $hKernel32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_ALL_ACCESS)
   If $arRet[0] = 0 Then
      $arRet = DllCall($hKernel32, "long", "GetLastError")
      $lError = $arRet[0]
   Else
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_INTERROGATE)
      If $arRet[0] = 0 Then
         $arRet = DllCall($hAdvapi32, "long", "CreateService", _
                          "long", $hSC, _
                          "str", $sServiceName, _
                          "str", $sDisplayName, _
                          "long", $nDesiredAccess, _
                          "long", $nServiceType, _
                          "long", $nStartType, _
                          "long", $nErrorType, _
                          "str", $sBinaryPath, _
                          "str", $sLoadOrderGroup, _
                          "ptr", 0, _
                          "str", "", _
                          "str", $sServiceUser, _
                          "str", $sPassword)
         If $arRet[0] = 0 Then            
            $arRet = DllCall($hKernel32, "long", "GetLastError")
            $lError = $arRet[0]
         Else
            DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $arRet[0])
         EndIf
      Else
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $arRet[0])
      EndIf      
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)
   DllClose($hKernel32)   
   If $lError <> -1 Then 
      SetError($lError)
      Return 0
   EndIf
   Return 1
EndFunc
 
;===============================================================================
; Description:   Deletes a service on a computer
; Parameters:    $sComputerName - name of the target computer. If empty, the local computer name is used
;                $sServiceName - name of the service to delete
; Requirements:  Administrative rights on the computer
; Return Values: On Success - 1
;                On Failure - 0 and @error is set to extended Windows error code
;===============================================================================
Func _DeleteService($sComputerName, $sServiceName)
   Local $hAdvapi32
   Local $hKernel32
   Local $arRet
   Local $hSC
   Local $hService
   Local $lError = -1   
 
   $hAdvapi32 = DllOpen("advapi32.dll")
   If $hAdvapi32 = -1 Then Return 0
   $hKernel32 = DllOpen("kernel32.dll")
   If $hKernel32 = -1 Then Return 0
   $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _
                    "str", $sComputerName, _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_ALL_ACCESS)
   If $arRet[0] = 0 Then
      $arRet = DllCall($hKernel32, "long", "GetLastError")
      $lError = $arRet[0]
   Else
      $hSC = $arRet[0]
      $arRet = DllCall($hAdvapi32, "long", "OpenService", _
                       "long", $hSC, _
                       "str", $sServiceName, _
                       "long", $SERVICE_ALL_ACCESS)
      If $arRet[0] = 0 Then
         $arRet = DllCall($hKernel32, "long", "GetLastError")
         $lError = $arRet[0]
      Else
         $hService = $arRet[0]
         $arRet = DllCall($hAdvapi32, "int", "DeleteService", _
                          "long", $hService)
         If $arRet[0] = 0 Then
            $arRet = DllCall($hKernel32, "long", "GetLastError")
            $lError = $arRet[0]
         EndIf
         DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService)
      EndIf
      DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC)
   EndIf
   DllClose($hAdvapi32)
   DllClose($hKernel32)   
   If $lError <> -1 Then 
      SetError($lError)
      Return 0
   EndIf
   Return 1
EndFunc
Install info: Two exe files need to be placed in the same folder in an install directory. 1: flasher.exe - The actual application 2: RunAsSvc.exe - A file used for setting the exe as a Windows Service. It will set the flasher to run in the SYSTEM context as a service. The flasher.exe has 4 modes of operation called by switches following the command. It will exit unless a switch is included. /install Checks and exits if it was executed on a server. Otherwise installs on a workstation 2000/XP only. Did not test with 2000.Copies itself and RunAsSvc.exe to c:\program files\NYITSUPPORT\Flasher folder.Registers itself as a service using RunAsSvc by calling itself with a /service switch.Creates a shortcut to itself with a /client switch, and places it into c:\documents and settings\all users\start menu\startup.Changes NTFS permissions on c:\program files\NYITSUPPORT\Flasher to users Allow-Full rights. /client Runs in the user context and checks for any drive letter conflicts. If a conflict is detected, a value with the "existing letter-new letter" is written to c:\program files\NYITSUPPORT\Flasher\drive.change file.Example: F:-Z:Checks every 30 seconds /service Runs in the SYSTEM context and checks for any entries in the drive.change file.If an entry is present it will remap the physical drives based on the letters the client instance provided in the file. Using the example given above will change the F drive to Z.The change is performed by changing letters in HKLM\system\MountedDevices\DosDevices\x instances.Deletes the change file.Checks every 30 seconds. /uninstall Stops/deletes it's own service instance.Kills/deletes the client instance.Deletes the shortcut created in the All Users startup.Deletes the Flasher folder. The application has to be rolled out in administrative context for the setup to complete. Computer Startup has to be used as a means for deployment with Group Policy.

No comments: