;-- TIME_STAMP 2022-12-30 12:54:04 v 0.2 #AutoIt3Wrapper_Change2CUI=y #cs CMD Line Syntax: "Path to DefineDosDeviceCMD.exe" [Switch] [Full Target Path] [Drive Letter] The parameters can be specified in any order. The search for free drive letters starts at "E:". However, if not occupied, "A:" or "B:" can also be specified. "Path to DefineDosDeviceCMD.exe" Compiled program path [Switch] /c Create drive (default, omit this parameter) /d Delete drive /l Listing of Dos devices and their paths, if any /? Shows the help [Full Target Path] /target="Path to link the drive letter to" [Drive Letter] /drive=F: or /drive=x Drive letter of the drive to create or delete - omit this, to create with next free letter #ce If $CMDLINE[0] = 0 Then Exit ConsoleWrite('"' & @ScriptName & '"' & @CRLF & 'The program was called without parameters! Call the help (/?)!' & @CRLF) Global $sHelp = 'Creates or removes a Virtual Drive or lists existing drives. The Drive(s) will be removed automatically on shutdown.' & @CRLF & @CRLF $sHelp &= '"Path to DefineDosDeviceCMD.exe" [Switch] [Full Target Path] [Drive Letter]' & @CRLF $sHelp &= 'The parameters can be specified in any order.' & @CRLF $sHelp &= 'The search for free drive letters starts at "E:". However, if not occupied, "A:" or "B:" can also be specified.' & @CRLF & @CRLF $sHelp &= '"Path to DefineDosDeviceCMD.exe" Compiled program path' & @CRLF $sHelp &= '[Switch] /c Create drive (default, omit this parameter)' & @CRLF $sHelp &= ' /d Delete drive' & @CRLF $sHelp &= ' /l Listing of Dos devices and their paths, if any' & @CRLF $sHelp &= ' /? Shows the help' & @CRLF $sHelp &= '[Full Target Path] /target="Path to link the drive letter to"' & @CRLF $sHelp &= '[Drive Letter] /drive=F: or /drive=x Drive letter of the drive to create or delete - omit this, to create with next free letter' & @CRLF Global $aMatch, $sSwitch, $iFlag, $sTarget, $sDrive, $sOut ; check for switch $aMatch = StringRegExp(StringLower($CMDLINERAW), '(\/[cdl\?])(?!\w)', 1) If @error Then $sSwitch = '/c' Else $sSwitch = $aMatch[0] EndIf If $sSwitch = '/?' Then Exit ConsoleWrite($sHelp & @CRLF) If $sSwitch = '/c' Then $iFlag = 0 If $sSwitch = '/d' Then $iFlag = 1 If $sSwitch = '/l' Then $iFlag = 2 ; check for target path $aMatch = StringRegExp(StringLower($CMDLINERAW), '\/target=(?:"|\x27)(.+)(?:"|\x27)', 1) If @error Then $sTarget = "" If $iFlag = 0 Then Exit ConsoleWrite('[CREATION] ERROR The creation requires the specification of a target path!' & @CRLF) Else $sTarget = $aMatch[0] EndIf ; check for drive letter $aMatch = StringRegExp(StringLower($CMDLINERAW), '\/drive=([a-z]:?)', 1) If @error Then $sDrive = "" Else $sDrive = $aMatch[0] EndIf Global $vResult = _DefineDosDevice($sTarget, $sDrive, $iFlag) Global $iErr = @error, $iExt = @extended Switch $iFlag Case 0 If $iErr = 2 And $iExt = 1 Then $sOut = '[CREATION] ERROR No free drive letter available!' & @CRLF ElseIf $iErr = 2 And $iExt = 2 Then $sOut = '[CREATION] ERROR The passed drive letter already exists!' & @CRLF ElseIf $iErr = 3 Then $sOut = '[CREATION] ERROR The path to link to is not valid!' & @CRLF Else $sOut = '[CREATION] SUCCESS Drive "' & StringUpper($vResult) & '" has been created.' & @CRLF EndIf Case 1 If $iErr = 4 Then $sOut = '[DELETION] ERROR The action has failed!' & @CRLF Else $sOut = '[DELETION] SUCCESS Drive "' & StringUpper($vResult) & '" has been deleted.' & @CRLF EndIf Case 2 If $vResult[0][0] = 0 Then $sOut = '[LISTING] No DOS devices defined!' & @CRLF Else $sOut = '[LISTING] DRIVE LINKED_TO' & @CRLF For $i = 1 To $vResult[0][0] $sOut &= ' ' & StringUpper($vResult[$i][0]) & ' ' & $vResult[$i][1] & @CRLF Next EndIf EndSwitch ConsoleWrite($sOut) ;=================================================================================================== ; Function Name .: _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0) ; Description ...: Creates or removes a Virtual Drive or lists existing drives. The Drive will be removed automatically on shutdown. ; Parameter(s) ..: $_sTargetPath Path to link the driveletter to ; Create: with "" link to @MyDocumentsDir (default) ; $_sDeviceName Driveletter of the Drive to create / delete, ; Create: with "" the first free drive letter - starts with "E:" - is used (default) ; Delete: pass "" - the path connected with the driveletter will be found automatically. ; $_iActionFlag 0 = Creation (default) ; 1 = Deletion of the Drive ; 2 = Return an array of dos drives, if available; [0][0]=counter, [['drive','path']] ; Return Value(s): Success Driveletter of the created/deleted virtual Drive or array with found dos drives ; Failure 0 @error=1 wrong action flag ; @error=2 wrong drive letter @extended: 1=no free drive letter available; 2=drive letter already exists ; @error=3 no valid path to link to ; @error=4 action failed ; @error=5 no valid drive to delete ; Author(s) : BugFix (autoit@bug-fix.info) ; Note : The function corrects incorrect entries for drive and path specifications. ; Thus "c:\folder1\folder2\" and "f" are evaluated as correct entries. ; Requires : AutoIt stable min. 3.3.16.1 ;=================================================================================================== Func _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0) If $_iActionFlag < 0 Or $_iActionFlag > 2 Then Return SetError(1,0,0) $_sTargetPath = $_sTargetPath = '' ? @MyDocumentsDir : StringRegExpReplace($_sTargetPath, '\\$', '') $_sDeviceName = $_sDeviceName <> '' ? (StringRegExpReplace(StringLower($_sDeviceName), ':*$', '') & ':') : '' Local $aDrives, $ret Switch $_iActionFlag Case 0 ; create new dos device If $_sDeviceName = '' Then ; get next free drive letter $aDrives = DriveGetDrive("ALL") Local $mDrives[] For $i = 1 To UBound($aDrives) -1 $mDrives[StringLeft($aDrives[$i],1)] = 1 Next For $j = 101 To 122 If Not MapExists($mDrives, Chr($j)) Then $_sDeviceName = Chr($j) & ':' ExitLoop EndIf Next If $_sDeviceName = '' Then Return SetError(2,1,0) Else ; check if passed drive letter already exists If FileExists($_sDeviceName) Then Return SetError(2,2,0) EndIf If Not FileExists($_sTargetPath) Then Return SetError(3,0,0) $ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _ 'long', 0x0, 'str', $_sDeviceName, 'str', $_sTargetPath) Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0)) Case 1 ; determine the path associated with the drive to be deleted $ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $_sDeviceName, "str", "", "long", 260) If $ret[0] = 0 Then Return SetError(4,0,0) Else $_sTargetPath = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2') If Not FileExists($_sTargetPath) Then Return SetError(5,0,0) $ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _ 'long', 0x2, 'str', $_sDeviceName, 'str', $_sTargetPath) Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0)) EndIf Case 2 ; array of existing dos devices, [0][0]=counter, [['drive','path']] $aDrives = DriveGetDrive('FIXED') Local $aOut[27][2] = [[0]] For $i = 1 To UBound($aDrives) - 1 $ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $aDrives[$i], "str", "", "long", 260) Local $path = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2') If StringRegExp($path, '[a-zA-Z]:.*') Then $aOut[0][0] += 1 $aOut[$aOut[0][0]][0] = $aDrives[$i] $aOut[$aOut[0][0]][1] = $path EndIf Next ReDim $aOut[$aOut[0][0]+1][2] Return $aOut EndSwitch EndFunc