Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
Name: Judago
I got bored so I optimized an old script of mine, can
someone please give it a test to see If it works on vista
properly (Don't own a copy and would prefer not to have
to go over it at work).What I'm interested in is:
1. Does it still detect usb flash drives properly?
2. Are multiple drives listed alphabetically by drive letter?
3. How does it deal with volume labels?One thing to note it intentionally ignores drives a: and b:, this
is to avoid floppies being accessed.
@echo off setlocal set "svr=................................ !""#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................." :begin SETLOCAL ENABLEDELAYEDEXPANSION set svr=!svr:""="! cls echo.&echo.&echo.&echo.&echo. echo: Scanning for usb flash drives....... set dcnt= ver|find "n 5">nul&&goto nt5 for /f "delims=" %%V in ('2^>nul reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find /i "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do ( for /f "delims=" %%W in ('2^>nul reg query "%%V"^|find /i "%%V\"') do ( set flshtmp="%%W" set flshtmp=!flshtmp:%%V\=! for /f "tokens=1,2*" %%X in ('2^>nul reg query "%%W"^|find /i "FriendlyName"') do ( set /a dcnt+=1 set fname!dcnt!="%%Z" set id!dcnt!=!flshtmp! set flshtmp= ) ) ) goto merge :nt5 for /f "delims=" %%V in ('2^>nul reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find /i "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do ( for /f "delims=" %%W in ('2^>nul reg query "%%V"^|find /i "%%V\"') do ( set /a dcnt+=1 set chk=0 for /f "tokens=1,2*" %%X in ('2^>nul reg query "%%W"^|findstr /i "ParentIdPrefix FriendlyName"') do ( if /i "%%X"=="ParentIdPrefix" set id!dcnt!="%%Z"&&set /a chk+=1 if /i "%%X"=="FriendlyName" set fname!dcnt!="%%Z"&&set /a chk+=1 ) if !chk! lss 2 set /a dcnt-=1 ) ) :merge set lcnt= for /f "tokens=2,4 delims=\ " %%Y in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices^|find ":"^|find /v /i "a:"^|find /v /i "b:"') do ( 2>&1 dir %%Y\|>nul find /i "volume" && ( set /a lcnt+=1 set drvltt!lcnt!=%%Y set drvdat!lcnt!=%%Z ) ) for /l %%W in (1,1,!lcnt!) do ( set tdat= call :delin %%W set drvdat%%W=!drvdat%%W:00¼=! set drvdat%%W=!drvdat%%W:¼00=! set hexval=!svr! for %%X in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do ( for %%Y in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do ( for /f "delims=" %%Z in ("!hexval:~0,1!") do set drvdat%%W=!drvdat%%W:%%X%%Y=%%Z! set hexval=!hexval:~1! ) ) set drvdat%%W=!drvdat%%W:¼=! ) set output1=Exit set output2=Rescan to detect newly connected devices. set fcnt=2 for /l %%W in (1,1,!dcnt!) do ( for /l %%X in (1,1,!lcnt!) do ( echo "!drvdat%%X!"|find !id%%W!>nul&& ( set lbl= for /f "tokens=5*" %%Y in ('2^>nul vol !drvltt%%X!^|find /v /i "Volume Serial Number is"^|find /v /i "has no label"') do set lbl=, Label "%%Z" set /a fcnt+=1 set itmed!fcnt!=Drive "!drvltt%%X!", Device !fname%%W:~0,-12!"!lbl! ) ) ) set srtcnt=!fcnt! for %%Y in (z y x w v u t s r q p o n m l k j i h g f e d c) do ( for /l %%Z in (3,1,!fcnt!) do ( if /i "%%Y"=="!itmed%%Z:~7,1!" ( set output!srtcnt!=!itmed%%Z! set /a srtcnt-=1 ) ) ) cls :loop echo.&echo.&echo: Your options are.....&echo. for /l %%Z in (1,1,!fcnt!) do echo: %%Z. !output%%Z! echo. set /p fdrive= Please select a flash drive or option: for /l %%Z in (1,1,!fcnt!) do if "%%Z"=="!fdrive!" goto finish cls echo Invalid choice - select again goto loop :finish if /i "!output%fdrive%!"=="exit" exit /b if /i "!output%fdrive%!"=="Rescan to detect newly connected devices." endlocal&&goto begin set fdrive=!output%fdrive%:~7,2! endlocal&endlocal&set fdrive=%fdrive% echo You selected drive %fdrive% pause goto :eof :delin if not defined drvdat%1 set drvdat%1=%tdat:~1%&&goto :eof set tdat=%tdat%¼!drvdat%1:~0,2! set drvdat%1=!drvdat%1:~2! goto delin

Hi Judago,
Big thanks for the code that you've written its fitting the purpose I need it for perfectly. However I'm wondering what I need to modify in regards to get this to work with USB Hard drives also, is there any easy fix to enable that to work?
Any information you have would be appreciated.
Regards
Byron

This is quite an old thred, I've actually change that script quite
a bit since then....I don't own a usb hard drive so I'm not to sure of how the reg
build up is set out.If you can upload some reg exports to a file sharing site
I might find some time to look at it, be sure to have as many
usb hard drives connected as possible.These three commands will create three .reg files, zip them up
and upload them somewhere(there are lots of these sites
that don't even require an account) and post back the link along
with the brand(s) and model(s) of your drive(s).regedit /e usb.reg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB" regedit /e usbstor.reg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR" regedit /e mounted.reg "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices"

Hi Judago,
Thanks heaps for the quick reply. I'm sitting here trying to nut it out on how it works but I don't understand batch scripting well enough.
I've only got one usb hard drive and a usb flash drive at the moment so i'm going to have to hunt down some more. How does the code filter the results so that you only get flash drives, which particular part of the code is doing that?
Also you mentioned you have changed this code since, what changes have you made?
A little bit of insight into what i'm using it for also is that i'm creating a batch scripted used for scanning usb storage devices for viruses. Once the user selects the device using your script the storage device then gets scanned by three diffferent command line av scanners. Unfortunately i'm limited to just flash drives at the moment and not able to scan usb hard drives (although it will probably take hours for three av scanners to run over a hard drive).
I can get the output with one hard drive attached today but if you need more i'll have to get back to you on monday most likely. thanks in advance for your help

Here's how it basically works....
Firstly there are two different routines, one for vista and one for xp, for extracting the id and drive info. Both are located under "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR" on vista the device id's are the names of it's subkeys and the drive info are the "friendlyname" value of that subkey. On xp the subkey isn't the device id, the value of "parentidprefix" on the subkey is the device id and the friendly name is the same.
Each of these values is looped through and assigned to incremented variables, id!fcnt! and fname!dcnt! where !dcnt! is an incrementing counter.
The rest of the procedure is the same for both xp and vista.
The id's can also be found in the hex data under "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices" along with the corresponding drive letter. The hex data is assigned to a different set of incrementing variables drvltt!lcnt! and drvdat!lcnt! and drvdat!lcnt! is converted from hex to ascii.
Using the for /l commands the total of the counters is used to loop through all of the variables that were created and match the drive info and drive letter by using the find command to find the device id in the converted hex data, thus matching the drive letter to the drive info, then the dir command is used to ensure the drive is present.
Entries are then sorted by drive letter so the final list is ordered, more for cosmetic purposes than anything else.
Entries are then displayed and chosen, the drive letter is the separated from the selected string and set to the %fdrive% variable.
Volume labels are also added to the output in my more recent version.
It really depends how usb hard drives would fit into this whole process as to how easily they can be added........
I didn't realize that you were using this at a public terminal, please run the reg dumps from the cleanest machine possible, I don't want to wade through 1000's of usb flash drive leftovers... Oh and if you could run it once for vista and once for xp that would be great, as I would like to keep it working on both systems.....
Edit:I didn't really answer one of you questions very well, the reason it focuses on flash drives is because it only looks for the information eluding to them under hklm\SYSTEM\CurrentControlSet\Enum\USBSTOR, I believe that usb hard drives will also have their information here but may use different value names, i.e. friendly name may be called something else or their id string may also be somewhere else.....
Oh and one drive is enough, knowing it's letter would also be of some value. You know this situation is like very similar to how it ended up supporting vista he he ;).

Hi Judago,
Thanks for all your information this is really helpful. Unfortunately I don't have a vista machine to test on at this point but I will see if I can get one up and running that we can use.
The link for the registry files you specified are at http://www.filefactory.com/file/ag1... please let me know if you have any issues with downloading these files.
The drive at the time was connected to drive letter F:\ and the device is a Western Digital Hard drive WD2500
The machine i've used is just my test machine so I think its probably as clean as we can get. It hasn't had many USB devices plugged in, less than 20 I would think. I will continue to hunt down another hard drive so that we can test another one.
Thanks again for all your help, please let me know anything more I can get you.
Byron

I've had a look at the reg data and there is good news and
bad news.Bad news is that usb hard disks seem to be treated in
the same way as regular disks, this is bad because
they are really hard to match the friendly name to the disk
id(4 bytes starting at offset 01B8h of the disk itself) which
is needed to match the volumes to the physical disk.Good news is that it should be pretty easy to knock up
a script using the disk part utility included in windows
to perform the same task(doesn't seem to show the friendly
name of flash drives though, so the old script still stands for
them). The only caveat I can see is that an exclude list
will be needed to avoid listing system/internal/unwanted
disks, but this would also be present if the info was
scrapped from the registry...Can you run this script and let me know if it picks up the usb disk?
@ECHO OFF for /f "skip=7 tokens=2" %%a in ('^(echo list disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do ( for /f "skip=7 delims=" %%b in ('^(echo select disk %%a^&echo detail disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do echo %%b echo. echo. ) pauseEdit:
If the third line down "type:" says usb that could be the filter, allowing only usb drives....

Presuming "type : usb" is correct, here is a unpolished
script that I'm not going to bother doing anymore on until it is
confirmed that diskpart does indeed see these disks.If it does I will probably roll it into the other script.
@ECHO OFF :begin setlocal enabledelayedexpansion ::usb hard disks set drvcnt=3 set disk1=" 1. Exit" set disk2=" 2. Rescan." set prtout1=exit set prtout2=rescan set prtcnt=2 set carryon=1 for /f "skip=7 tokens=2" %%a in ('^(echo list disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do ( set holder= if !carryon!==1 (set /a drvcnt+=1) else set disk!drvcnt!= SET CARRYON= for /f "skip=7 tokens=1-10 delims=: " %%b in ('^(echo select disk %%a^&echo detail disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do ( if not defined disk!drvcnt! ( set disk!drvcnt!=%%bp for %%z in ("%%c" "%%d" "%%e" "%%f" "%%g" "%%h" "%%i" "%%j" "%%k") do ( for %%y in (!drvcnt!) do if not "%%~z"=="" set disk!drvcnt!='!disk%%y:~0,-1! %%~z' ) for %%z in (!drvcnt!) do set disk!drvcnt!="" "Disk !disk%%z!:" ) if /i "%%b"=="type" if /i "%%c"=="usb" set carryon=1 if /i "%%b"=="volume" if not "%%c"=="###" ( for %%Q in (!drvcnt!) do ( set /a prtcnt+=1 set prtout!prtcnt!=%%d:\ set disk!drvcnt!=!disk%%Q! " !prtcnt!. Volume %%d:\ for /f "tokens=5*" %%Y in ('2^>nul vol %%d:^|find /v /i "Volume Serial Number is"^|find /v /i "has no label"') do set disk!drvcnt!=!disk%%Q!, Label '%%Z'" if not !disk%%Q:~-1!==^" set disk%%Q=!disk%%Q!" ) ) ) ) IF NOT !CARRYON!==1 SET /A DRVCNT-=1 :sel echo. echo. echo Please select a drive or option: echo. for /l %%a in (1 1 !drvcnt!) do ( for %%b in (!disk%%a!) do echo.%%~b ) Set /p sel=Please choose a partition: cls for /l %%a in (1 1 !prtcnt!) do if "%%a"=="!sel!" goto finish echo Bad selection - try again. goto sel :finish if /i "!prtout%sel%!"=="exit" endlocal&goto :eof if /i "!prtout%sel%!"=="rescan" endlocal&goto begin echo You selected drive !prtout%sel%! pause

Hi Judago,
Once again thanks so much for your help and for doing this all so quickly. I really appreciate your help. Here is the output from the code you gave me in response 6
WDC WD800JD-75MSA3
Disk ID: 00000080
Type : IDE
Bus : 0
Target : 0
LUN ID : 0
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 1 C NTFS Partition 65 GB Healthy System
Volume 2 E Logs NTFS Partition 10 GB Healthy
WD 2500JB External USB Device
Disk ID: 0C037C2B
Type : USB
Bus : 0
Target : 0
LUN ID : 0
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 3 F USB Harddis NTFS Partition 233 GB Healthy
Press any key to continue . . .
Then in response 7 using the same script I have the following output.Please select a drive or option:
1. Exit
2. Rescan.Disk ''''WD 2500JB External USB Device':
5. Volume F:\, Label 'USB Harddisk'
Please choose a partition.So going by these results I think you are on the right track and it seems you are able to pick the correct disk out based on your script above. I can also select the drive by pressing 5 and then enter in the above example and it picks out drive F which is the correct drive.
Once you are happy with the level this script is at I think i should also be able to try this on a windows vista machine for you as well. I have a windows 7 machine here too so i'm sure I could try it on that as well.

Here's a quick job for testing, I wouldn't consider it optimized
and there are a few issues.1. Exclamation marks in volume labels are lost(same
goes for the script in post #1)
2. Drive letters are not sorted, this could be a good thing
though as usb disks will be listed in partition order.
3. It's a bit
of a mess inside the usb hard drive section and it could be
integrated more closely to the rest of the script.@echo off setlocal set "svr=................................ !""#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................." :begin SETLOCAL ENABLEDELAYEDEXPANSION set svr=!svr:""="! cls echo.&echo.&echo.&echo.&echo. echo: Scanning for usb flash drives....... set dcnt= ver|find "n 5">nul&&goto nt5 for /f "delims=" %%V in ('2^>nul reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find /i "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do ( for /f "delims=" %%W in ('2^>nul reg query "%%V"^|find /i "%%V\"') do ( set flshtmp="%%W" set flshtmp=!flshtmp:%%V\=! for /f "tokens=1,2*" %%X in ('2^>nul reg query "%%W"^|find /i "FriendlyName"') do ( set /a dcnt+=1 set fname!dcnt!="%%Z" set id!dcnt!=!flshtmp! set flshtmp= ) ) ) goto merge :nt5 for /f "delims=" %%V in ('2^>nul reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find /i "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do ( for /f "delims=" %%W in ('2^>nul reg query "%%V"^|find /i "%%V\"') do ( set /a dcnt+=1 set chk=0 for /f "tokens=1,2*" %%X in ('2^>nul reg query "%%W"^|findstr /i "ParentIdPrefix FriendlyName"') do ( if /i "%%X"=="ParentIdPrefix" set id!dcnt!="%%Z"&&set /a chk+=1 if /i "%%X"=="FriendlyName" set fname!dcnt!="%%Z"&&set /a chk+=1 ) if !chk! lss 2 set /a dcnt-=1 ) ) :merge set lcnt= for /f "tokens=2,4 delims=\ " %%Y in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices^|find ":"^|find /v /i "a:"^|find /v /i "b:"') do ( 2>&1 dir %%Y\|>nul find /i "volume" && ( set /a lcnt+=1 set drvltt!lcnt!=%%Y set drvdat!lcnt!=%%Z ) ) for /l %%W in (1,1,!lcnt!) do ( set tdat= call :delin %%W set drvdat%%W=!drvdat%%W:00¼=! set drvdat%%W=!drvdat%%W:¼00=! set hexval=!svr! for %%X in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do ( for %%Y in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do ( for /f "delims=" %%Z in ("!hexval:~0,1!") do set drvdat%%W=!drvdat%%W:%%X%%Y=%%Z! set hexval=!hexval:~1! ) ) set drvdat%%W=!drvdat%%W:¼=! ) set output1=Exit set output2=Rescan to detect newly connected devices. set fcnt=2 for /l %%W in (1,1,!dcnt!) do ( for /l %%X in (1,1,!lcnt!) do ( echo "!drvdat%%X!"|find !id%%W!>nul&& ( set lbl= for /f "tokens=5*" %%Y in ('2^>nul vol !drvltt%%X!^|find /v /i "Volume Serial Number is"^|find /v /i "has no label"') do set lbl=, Label "%%Z" set /a fcnt+=1 set itmed!fcnt!=Drive "!drvltt%%X!", Device !fname%%W!"!lbl! ) ) ) set srtcnt=!fcnt! for %%Y in (z y x w v u t s r q p o n m l k j i h g f e d c) do ( for /l %%Z in (3,1,!fcnt!) do ( if /i "%%Y"=="!itmed%%Z:~7,1!" ( set output!srtcnt!=!itmed%%Z! set /a srtcnt-=1 ) ) ) rem ******************************************************** rem ************** USB HARD DISK SECTION ******************* REM ******************************************************** set carryon=1 SET PRTCNT=!FCNT! for /f "skip=7 tokens=2" %%a in ('^(echo list disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do ( set holder= if !carryon!==1 (set /a drvcnt+=1) else set disk!drvcnt!= SET CARRYON= set dev= for /f "skip=7 tokens=1-10 delims=: " %%b in ('^(echo select disk %%a^&echo detail disk^&echo exit^)^|diskpart^|find /v /i "diskpart"') do ( if not defined disk!drvcnt! ( set disk!drvcnt!=%%bp for %%z in ("%%c" "%%d" "%%e" "%%f" "%%g" "%%h" "%%i" "%%j" "%%k") do ( for %%y in (!drvcnt!) do if not "%%~z"=="" ( set disk!drvcnt!=!disk%%y:~0,-1!" "%%~z set dev=!disk%%y! ) ) ) if /i "%%b"=="type" if /i "%%c"=="usb" set carryon=1 if /i "%%b"=="volume" if not "%%c"=="###" ( for %%r 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 if /i "%%r"=="%%d" for %%Q in (!drvcnt!) do ( set /a PRTCNT+=1 set disk!drvcnt!=!disk%%Q! ; " !prtcnt!. Drive "%%d:", Device "!dev!"" set label= for /f "tokens=5*" %%Y in ('2^>nul vol %%d:^|find /v /i "Volume Serial Number is"^|find /v /i "has no label"') do set label="%%Z"" if defined label set disk!drvcnt!=!disk%%Q:~0,-1!, Label !Label: =" "! SET OUTPUT!PRTCNT!=0000000%%d: ) ) ) ) IF NOT !CARRYON!==1 ( set disk%drvcnt%= SET /A DRVCNT-=1 ) cls REM ******************************************************** REM ************* END USB HARD DISK SECTION **************** REM ******************************************************** :loop echo.&echo.&echo: Your options are.....&echo. for /l %%Z in (1,1,!fcnt!) do echo: %%Z. !output%%Z! for /l %%a in (1 1 !drvcnt!) do ( for /f "tokens=1* delims=;" %%m in ("!Disk%%a!") do ( set tvar= for %%o in (%%n) do ( set tvar=%%~o echo !tvar:" "= ! ) ) ) echo. set /p fdrive= Please select a flash drive or option: for /l %%Z in (1,1,!prtcnt!) do if "%%Z"=="!fdrive!" goto finish cls echo Invalid choice - select again goto loop :finish if /i "!output%fdrive%!"=="exit" exit /b if /i "!output%fdrive%!"=="Rescan to detect newly connected devices." endlocal&&goto begin set fdrive=!output%fdrive%:~7,2! endlocal&endlocal&set fdrive=%fdrive% echo You selected drive %fdrive% pause goto :eof :delin if not defined drvdat%1 set drvdat%1=%tdat:~1%&&goto :eof set tdat=%tdat%¼!drvdat%1:~0,2! set drvdat%1=!drvdat%1:~2! goto delin

Ok i've tested on my computer and it all looks really good. Its finding the drives I put into the computer. I've sent it to someone else that has vista and a hard drive for testing also so i'll get back to you in the next day about that. In the meantime i'm going to try to hunt down some more hard drives and see if I can test those also.
Thanks again for the script I really appreciate how fast you've been with helping me out.

I've tested now on a number of computers with different model hard drives and all of them are working. Within that test I've tried around 4 usb hard drives two on xp and two on vista and both have been successful.
Once again I really appreciate all your help I'll look forward to integrating it into my own code.If you wish to optimize your code then please let me know and i'll be happy to do more tests for you.

I probably will go through and optimize, I'm pretty busy at the moment, maybe over the next week or so....

I've had another look at it and I don't think there is much to be gained by going over it again and as it's working as expected I'm going to leave it where it is.
I did have a few tweaks in mind but on closer inspection the parsing of diskpart doesn't allow them.......

No worries Judago. Sorry for late reply I've been away from my computer the past two days.
Its working really well for me and the wait to find drives does not take very long so i'm really happy with the solution you've come up with.
Once again really appreciate your help in regards to this.

![]() |
commands on openvms
|
read from user within lo...
|

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |