Help - Search - Members - Calendar
Full Version: Get list of drives?
The CD Forum > Bart's PE Builder > General
cquirke
It would be good to populate nu2menu (environment) variables with %HDs%, %CD1%, %CD2%, etc. for use in batch files. %CD1% would be the Bart CD while %CD2%, if defined, would be a second CD drive, and %CDR% if this is known to be writable.

This would help automate certain things, e.g. CLI parameters to an av to scan all HD volumes (given that you can't pass My Computer from @GetFolderDialog() as a generic CLI parameter). Batch files could also use For logic to sequentially process drive letters, or select the first or last of these.

Now the BGInfo plugin seems to have this info, in that it displays it as a static part of the wallpaper bitmap when the PC starts up. Does it store this info anywhere in a harvestable form?

Unlikely, given that it runs from CDR, which is read-only - so the next question is; can we derive the same info in a similar way, e.g. from a (Bart, not redirected) registry query?
dog
Saw this by Jaclaz on robvanderwoude.com
Not tried it
CODE
@ECHO OFF
::
::Small batch file to list all unused drive letters (works ONLY on 2000/XP/2003)
::adapted by Jacopo Lazzari from an example found on Rob van der Woude Scripting Pages
::http://www.robvanderwoude.com/index.html
::
SET FREEDRV=
::This lists all used drives from the Registry and stores them in Temp2.rtm
START /WAIT REGEDIT /E Temp1.rtm "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices\"
TYPE Temp1.rtm > Temp2.rtm
TYPE Temp2.rtm ¦ FIND "\\DosDevices\\" > Temp1.rtm
Type NUL > Temp2.rtm
FOR /F "tokens=3 delims=\:" %%A IN (Temp1.rtm) DO CALL :ParseW2K %%A

::This makes a list of all possible drives(except A: and B: reserved for floppies)
::and stores them in Temp1.rtm
Type NUL > Temp1.rtm
for %%A in (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 :ParseW2K2 %%A

::This makes a new list excluding drives found in the Registry
FOR /F "tokens=1 delims=" %%A IN (Temp2.rtm) DO CALL :ParseW2K3 %%A

::This takes the results and stuffs them in FREEDRV  
FOR /F "tokens=1 delims=" %%A IN (Temp1.rtm) DO CALL :ParseW2K4 %%A

::This shows the environment variable FREEDRV
SET FREEDRV
GOTO :END

:ParseW2K
ECHO %1: >> Temp2.rtm
GOTO :EOF


:ParseW2K2
ECHO %1 >> Temp1.rtm
GOTO :EOF

:ParseW2K3
TYPE Temp1.rtm ¦ FIND /V "%1"  > Temp2.rtm
TYPE Temp2.rtm > Temp1.rtm
GOTO :EOF

:ParseW2K4
IF DEFINED FREEDRV (SET FREEDRV=%FREEDRV%,%1) ELSE (SET FREEDRV=%1)
GOTO :EOF

:END
::Clear up the temp files
del Temp1.rtm > nul
del Temp2.rtm > nul
cquirke
QUOTE (dog @ Sep 16 2005, 01:02 PM)
Saw this by Jaclaz on robvanderwoude.com
Not tried it
*


Looks like code I could learn from - I read about intrafile Call but haven't used it, and haven't really used Find either. I don't like spawning temp files in ., unless I know where . is (is it writable, etc.) Some odd bits...

CODE
FOR /F "tokens=3 delims=\:" %%A IN (Temp1.rtm) DO CALL :ParseW2K %%A
I didn't know you could use a : there...
CODE
GOTO :END
...or there.

QUOTE
"HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices\"

I saw this (and similar but less cluttered values within per-user keys) but it retains "historical" letters, e.g. those of USB drives not connected at the time. Might be OK if the OS defines it on the fly, and one reads it from the Bart registry rather than the HD installation's registry - you'd wantto do that anyway, given the two OSs will assign different letters to the drives.
cquirke
[quote=cquirke,Sep 17 2005, 01:49 AM]I read about intrafile Call but haven't used it[/quote]
CODE
FOR /F "tokens=3 delims=\:" %%A IN (Temp1.rtm) DO CALL :ParseW2K %%A
The leading : is required for intrafile Call syntax, OK

This returns a list of drives:
CODE
@Echo Off

:; Adapted by Jacopo Lazzari from an example found on Rob van der Woude Scripting Pages

Set Drives=

Reg Query "HKLM\SYSTEM\MountedDevices\" > %Temp%\Drives1.txt
Type %Temp%\Drives1.txt > %Temp%\Drives2.txt
Type %Temp%\Drives2.txt | Find "\DosDevices\" > %Temp%\Drives1.txt
Type NUL > %Temp%\Drives2.txt
For /F "tokens=3 delims=\:" %%D In (%Temp%\Drives1.txt) Do Echo %%D >> %Temp%\Drives2.txt
Type NUL > %Temp%\Drives1.txt
Type %Temp%\Drives2.txt | Sort > %Temp%\Drives1.txt
For /F "tokens=1 delims="   %%D In (%Temp%\Drives1.txt) Do Call :BuildList %%D

Set Drives
Pause
GoTo End


:BuildList
 If Defined Drives (Set Drives=%Drives% %1) Else (Set Drives=%1)
GoTo EOF

:End

Del %Temp%\Drives1.txt > nul
Del %Temp%\Drives2.txt > nul

:EOF
*

[/quote]
solara
From an old filedisk.xml that I had briefly used before Sherpya came out with the nice GUI.

This is a very crude way to use nu2menu to display currently valid drives in the menu itself - actually it disables any valid drives since this was for filedisk - but you can change it easily to display only valid drives...with NOT instead of OR.

CODE
<MENU ID="SelectDrive">
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(A:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', A:\)) @Reload()">A:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(B:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', B:\)) @Reload()">B:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(C:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', C:\)) @Reload()">C:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(D:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', D:\)) @Reload()">D:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(E:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', E:\)) @Reload()">E:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(F:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', F:\)) @Reload()">F:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(G:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', G:\)) @Reload()">G:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(H:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', H:\)) @Reload()">H:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(I:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', I:\)) @Reload()">I:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(J:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', J:\)) @Reload()">J:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(K:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', K:\)) @Reload()">K:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(L:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', L:\)) @Reload()">L:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(M:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', M:\)) @Reload()">M:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(N:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', N:\)) @Reload()">N:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(O:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', O:\)) @Reload()">O:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(P:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', P:\)) @Reload()">P:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(Q:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', Q:\)) @Reload()">Q:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(R:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', R:\)) @Reload()">R:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(S:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', S:\)) @Reload()">S:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(T:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', T:\)) @Reload()">T:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(U:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', U:\)) @Reload()">U:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(V:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', V:\)) @Reload()">V:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(W:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', W:\)) @Reload()">W:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(X:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', X:\)) @Reload()">X:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(Y:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', Y:\)) @Reload()">Y:\</MITEM>
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(Z:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', Z:\)) @Reload()">Z:\</MITEM>


This was used along with a batch file. See the post here: http://www.911cd.net/forums//index.php?showtopic=7052&hl=
cquirke
QUOTE (solara @ Sep 17 2005, 11:06 AM)
This is a very crude way to use nu2menu to display currently valid drives in the menu itself - actually it disables any valid drives since this was for filedisk - but you can change it easily to display only valid drives...with NOT instead of OR.
CODE
<MENU ID="SelectDrive">
<MITEM TYPE="ITEM" DISABLED="@OR(@FileExists(C:\*.*))" CMD="RUN" FUNC="@SetEnvVar('filedisk_drive', C:\)) @Reload()">C:\</MITEM>
Hm yes; how safe is that for at-risk HD volumes? Won't it miss empty volumes too, or nag for empty disks?
solara
QUOTE
Hm yes; how safe is that for at-risk HD volumes? Won't it miss empty volumes too, or nag for empty disks?


No idea on the effects nu2menu would have while scanning for existing drives. I can't imagine it is any different from any other program that queries for the existence of drives like BGInfo. Not sure how Windows handles the detection of drives.

And it does not nag for empty or non-existent drives - it just greys out those drives that do not fit the argument: the OR used above would highlight drives that do not exist. Using NOT will do the opposite. I'd have to check to see if it flags completely empty drives or not.

Not sure you could even use the above method to automate anything, but it's something to try if nothing else works.
cquirke
QUOTE (solara @ Sep 17 2005, 06:33 PM)
No idea on the effects nu2menu would have while scanning for existing drives.  I can't imagine it is any different from any other program that queries for the existence of drives like BGInfo.  Not sure how Windows handles the detection of drives

If Exist %SomePath%\NUL writes to target, and fails if target is read-only, when I tested that a while back - but it's possible XP behaves differently to Win9x.

*
CWorks
yup just tried it in pe and it doesn't work
tried it in xp also

CODE
@echo off
If Exist x:\nul echo it works
if not exist x:\nul echo it doesn't work
jaclaz
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
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2013 Invision Power Services, Inc.