Sign in to follow this  
Followers 0
cherdeg

Change Drive Letters in Seconds

1 post in this topic

Hello All,

Today, as once in a while, I would like to contribute some lines for those to need 'em. The following code uses functions created by "MSLx Fanboy" (_FindGUID) and "PsaltyDS" (_2DArrayAdd): Thank you, guys!

Due to the fact, that the WMI class "Win32_Volume" does not exist on Windows XP and Windows 2000, I instead use the CLI-tool "mountvol.exe" (comes with Windows) to do un- and remounts. The new drive letters are hardcoded, but it is simple to read them from an .ini-file or an inputbox.

Do with it whatever you like to:

#include <Array.au3>

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$s_ComputerName = "localhost"

$o_WMIService       = ObjGet("winmgmts:{impersonationLevel=Impersonate}!\\" & $s_ComputerName & "\root\CIMV2")

$o_HardDrives       = $o_WMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE Description = 'Local Fixed Disk'", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
$o_OpticalDrives    = $o_WMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE Description = 'CD-ROM Disc'", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
$o_RemovableDrives  = $o_WMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE Description = 'Removalbe Disk'", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)


; Create an array containing the harddisk-GUIDs and their DriveLetters
Global $a_HardDriveList[1][2]
For $o_items in $o_HardDrives
    $s_DriveLetter = $o_items.Caption
    $s_DriveLetterChar = StringLeft($o_items.Caption, 1)
    Local $a_TempAdd[2] = [$s_DriveLetterChar, _FindGUID($s_DriveLetter)]
    _2DArrayAdd($a_HardDriveList, $a_TempAdd, False)
Next
_ArrayDelete($a_HardDriveList, 0)

; Create an array containing the CDROM-GUIDs and their DriveLetters
Global $a_OpticalDriveList[1][2]
For $o_items in $o_OpticalDrives
    $s_DriveLetter = $o_items.Caption
    $s_DriveLetterChar = StringLeft($o_items.Caption, 1)
    Local $a_TempAdd[2] = [$s_DriveLetterChar, _FindGUID($s_DriveLetter)]
    _2DArrayAdd($a_OpticalDriveList, $a_TempAdd, False)
Next
_ArrayDelete($a_OpticalDriveList, 0)

; Create an array containing the removabledisk-GUIDs and their DriveLetters
Global $a_RemovableDriveList[1][3]
For $o_items in $o_RemovableDrives
    $s_DriveLetter = $o_items.Caption
    $s_DriveLetterChar = StringLeft($o_items.Caption, 1)
    Local $a_TempAdd[3] = [$s_DriveLetterChar, $s_DriveLetter, _FindGUID($s_DriveLetter)]
    _2DArrayAdd($a_RemovableDriveList, $a_TempAdd, False)
Next
_ArrayDelete($a_OpticalDriveList, 0)

; Do something with the found harddrives, dunnoyetwhat
; lines to come
; lines to come

; Change DriveLetters for the optical drives, starting with "O:" for "optical"
$s_FirstOpticalDrive = "x"
For $i = 0 to UBound($a_OpticalDriveList) - 1
    $s_cmd = "mountvol " & $a_OpticalDriveList[$i][0] & " /D"
    RunWait(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
    $s_DriveLetterCharNew = Chr((Asc($s_FirstOpticalDrive)) + $i)
    $a_OpticalDriveList[$i][1] = $s_DriveLetterCharNew & ":"
    $s_cmd = "mountvol " & $a_OpticalDriveList[$i][0] & " " & $a_OpticalDriveList[$i][1]
    RunWait(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
Next

; Change DriveLetters for the removable drives (USB), starting with "R:" for "removable"
$s_FirstRemovableDrive = "x"
For $i = 0 to UBound($a_OpticalDriveList) - 1
    $s_cmd = "mountvol " & $a_OpticalDriveList[$i][1] & " /D"
    RunWait(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
    $s_DriveLetterCharNew = Chr((Asc($s_FirstRemovableDrive)) + $i)
    $a_OpticalDriveList[$i][1] = $s_DriveLetterCharNew & ":"
    $s_cmd = "mountvol " & $a_OpticalDriveList[$i][1] & " " & $a_OpticalDriveList[$i][2]
    RunWait(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
Next




; Function _FindGUID to find the GUID belonging to a DriveLetter
; ==============================================================================================
Func _FindGUID($Drive)
    Local Const $DevList = 'HKLM\SYSTEM\MountedDevices'
    Local $i
    Do
        If RegRead($DevList, '\DosDevices\' & $Drive) = RegRead($DevList, RegEnumVal($DevList, $i)) Then Return StringReplace(RegEnumVal($DevList, $i), '\??\', '\\?\', 1)
        $i += 1
    Until 0
EndFunc   ;==>_FindGUID


; Function _2DArrayAdd to add lines to a two-dimensional array
; ==============================================================================================
Func _2DArrayAdd(ByRef $avArray, $vValue, $NestArray = True)
    Local $iBoundArray0, $iBoundArray1, $iBoundArray2, $iBoundValue1
    ; $avArray is not an array
    If IsArray($avArray) = 0 Then Return SetError(1, 0, -1)
    ; No. of dimesions in array
    $iBoundArray0 = UBound($avArray, 0)
    ; $avArray is more than 2D
    If $iBoundArray0 > 2 Then Return SetError(1, 1, -1)
    ; Size of array in first dimension
    $iBoundArray1 = UBound($avArray, 1)
    ; Size of array in second dimension
    If $iBoundArray0 = 2 Then $iBoundArray2 = UBound($avArray, 2)

    ; If input array is 1D, or $vValue is not an array, or $NestArray = True (default) then save $vValue literally
    If ($iBoundArray0 = 1) Or (IsArray($vValue) = 0) Or $NestArray Then
        If $iBoundArray0 = 1 Then
            ; Add to 1D array
            ReDim $avArray[$iBoundArray1 + 1]
            $avArray[$iBoundArray1] = $vValue
        Else
            ; Add to 2D array at [n][0]
            ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2]
            $avArray[$iBoundArray1][0] = $vValue
        EndIf
    Else
        ; If input array is 2D, and $vValue is an array, and $NestArray = False,
        ; then $vValue is a 1D array of values to add as a new row.
        ; $vValue array is not 1D
        If UBound($vValue, 0) <> 1 Then Return SetError(1, 2, -1)
        $iBoundValue1 = UBound($vValue, 1)
        ; $vValue array has too many elements
        If $iBoundArray2 < $iBoundValue1 Then Return SetError(1, 3, -1)
        ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2]
        For $n = 0 To $iBoundValue1 - 1
            $avArray[$iBoundArray1][$n] = $vValue[$n]
        Next
    EndIf

    ; Return index of new last row in $avArray
    Return $iBoundArray1
EndFunc   ;==>_2DArrayAdd

Best Regards, Chris

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0