Hey guys, just to let you know that I found that my little batch script cited previously has a problem, here is a new version using a different approach.
As a matter of fact it is actually a Win2k misbehaviour, but still it is
annoying:
once a letter has been assigned to, say, a USB drive, the setting in the registry in HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices\DosDevices\ remains "sticky", even when the USB key has been removed.
Thus my script will report as "FREE" only letters that were NEVER assigned, not the ones ACTUALLY not assigned.
After a bit of thinking, and a lot of trials and errors, I wrote another small script which completely ignores the Registry, but uses the output of the mountvol.exe command.
CODE
@echo off
::
::FREEDRIVELETTER
::Small batch file to list all unused drive letters (works ONLY on 2000/XP/2003)
::by Jacopo Lazzari
::go to Rob van der Woude Scripting Pages for more (and better) examples
::http://www.robvanderwoude.com/index.html
::
SETLOCAL ENABLEDELAYEDEXPANSION
SET BUSYDRV=
SET FREEDRV=
::Following excludes drives A: and B: (normally floppies)
SET ALLDRIVES=C D E F G H I J K L M N O P Q R S T U V W X Y Z
::Here we set a couple of temporary files
SET TEMPFILE1=mvol.txt
SET TEMPFILE2=mvol2.txt
::Here we make sure that %TEMPFILE1% is empty
Type nul > %TEMPFILE1%
::Here we call the "BUSY" routine once for each drive
FOR %%A in (%ALLDRIVES%) DO call :BUSYONES %%A
::Following two lines are just two alternate ways to show the BUSYDRV
variable contents
SET BUSYDRV
FOR %%A in (%BUSYDRV%) DO ECHO %%A BUSY
::Here we make sure that %TEMPFILE2% is empty
Type nul > %TEMPFILE2%
::Here we fill it with all drives letters
FOR %%A in (%ALLDRIVES%) DO echo %%A: >> %TEMPFILE2%
::Here we call the "FREE" routine once for each drive already found as "BUSY"
FOR %%A in (%BUSYDRV%) DO call :FREEONES %%A
::This stuffs the found "FREE" drives in the FREEDRV variable
FOR /F %%A in (%TEMPFILE1%) DO IF DEFINED FREEDRV (SET FREEDRV=!FREEDRV!,%%A)
ELSE (SET FREEDRV=%%A)
::Again, following two lines are just two alternate ways to show the
FREEDRV variable contents
SET FREEDRV
FOR %%A in (%FREEDRV%) DO ECHO %%A FREE
goto :END
:BUSYONES
::This lists output of mountvol.exe command to %TEMPFILE2%
Mountvol.exe %1: /L > %TEMPFILE2%
FOR /F %%A in (%TEMPFILE2%) DO SET TEMPVAR=%%A
::This checks whether there is a corresponding mounting point to the drive letter
::and if it is, adds the drive letter to the BUSYDRV variable
IF "%TEMPVAR:~0,4%"=="\\?\" IF DEFINED BUSYDRV (SET BUSYDRV=!BUSYDRV!,%1:)
ELSE (SET BUSYDRV=%1:)
goto :EOF
:FREEONES
::This makes a list excluding from "ALLDRIVES" those already found as "BUSY"
TYPE %TEMPFILE2% | FIND /V "%1" > %TEMPFILE1%
TYPE %TEMPFILE1% > %TEMPFILE2%
goto :EOF
:END
::Clear up the temp files
if exist %TEMPFILE1% del %TEMPFILE1% > nul
if exist %TEMPFILE1% del %TEMPFILE1% > nul
If anyone needs it, I am putting together another small script to determine WHICH kind of drive is assigned to a letter, i.e. Hard disk, CD, USB key, etc.
What I got so far:
(WARNING, it is just a PREVIEW, NOT a finished work as the above)
CODE
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set mytemp1=mytemp0.txt
set mytemp2=mytemp1.txt
START /WAIT REGEDIT /E %mytemp1% "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices\"
FOR %%A IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO call :testparse6 %%A:
call :testparse7
set VOLUME_
goto :END
:testparse6
SET valtemp=VOLUME_%1
call :testparse7 %1
goto :EOF
:testparse7
type %mytemp1% | FIND "%1" > %mytemp2%
FOR /F "tokens=3,8,11,13 delims=:," %%A IN (%mytemp2%) DO (
REM 13=54 means USB stick
REM 13=43 means Virtual CD ROM
REM %%A%%B%%C%%D=5c004644 Floppy
REM %%B%%C%%D=7e0000 Hard disk primary
REM %%B%%C%%D=xxxxxx Hard disk logical
REM %%A%%B%%C%%D=5c004944 ATAPI CD ROM
REM %%A%%B%%C%%D=5c005343 SCSI or virtual CD ROM
REM %%A%%B%%C%%D=5c005354 USB STICK
IF %%A==5c (
IF %%C==46 SET %VALTEMP%=!%VALTEMP%! Type:Floppy
IF %%C==56 SET %VALTEMP%=!%VALTEMP%! Type:Virtual Floppy
IF %%C==49 SET %VALTEMP%=%1 Type:ATAPI CD ROM
IF %%C==53 SET %VALTEMP%=%1 Type:SCSI or Virtual CD ROM
) ELSE (
IF %%B==7e (
SET %VALTEMP%=!%VALTEMP%! Type:Hard Disk Primary Partition
) ELSE (
SET %VALTEMP%=!%VALTEMP%! Type:NOT DETECTED for the moment
)
)
)
goto :EOF
:END
pause
jaclaz