Rob van der Woude's Scripting Pages

Solutions found in alt.msdos.batch

and alt.msdos.batch.nt

Discover the CD-ROM Drive Letter

Find that CD-ROM drive

Finding the CD-ROM drive is a Frequently Returning Question in alt.msdos.batch.
This solution by Charles Dye uses DEBUG and will work in other DOS versions too (successfully tested in Windows NT 4 and in OS/2 Warp 4 DOS box!).

On Mon, 13 Dec 1999 21:42:58 +0100, Outsider
<nonvalid_email@yahoo.com> wrote:

>G.Pohl wrote:
>> 
>> Hello all,
>> 
>> excuse me for this extra long posting. :-)
>> 
>> last week I had a problem: how to find my cd-rom. Well - in thge most cases
>> it is found in front of the PC. But that's not the problem. I was searching
>> for the drive letter of this beauty.
>> 
>> I searched and found a solution. I would like the hear what other people
>> think of it.
>> 
>>  [snip:  parsing AUTOEXEC.BAT]
>
>I don't think that's good enough Georg. Someone could have several
>config.sys and autoexec.bat on their system, and there may be many
>batch files with "MSCDEX ... /L:D", who knows?

I'm using DR-DOS, and I load NWCDEX via an AUTO.BAT file....

>I believe it was Charles Dye that posted a debug routine for this
>purpose a while back. Perhaps he'll be good enough to re-post it.
>I think I have it but I can't put my finger on it right now.

<lurch> You rang? </lurch>

---------------------------------------- begin MAKEUTIL.BAT -----
@echo off
echo >$ n FIND-CD.COM
echo >>$ e100 E8 "P"0 BA 96 2 B4 9 CD "!1"C9 B8 B 15 "1"DB CD "/"81
echo >>$ e114 FB AD AD "u"B 9 C0 "u"19 "A"81 F9 1A 0 "r"E8 BA A4 2 B4
echo >>$ e128 9 CD "!"BD B9 2 E8 D3 0 B8 1 "L"CD "!"80 C1 "A"88 E B4
echo >>$ e13C 2 88 E BF 2 BA B1 2 B4 9 CD "!"BD B9 2 E8 DC 0 B8 0 "L"
echo >>$ e151 CD "!"8B 1E 16 0 83 FB 8 "vY"8E C3 "&"A1 0 0 "="CD " u"
echo >>$ e166 "N&"A1 ","0 "H"8E C0 40 "&"8A E 0 0 80 F9 "Mt"5 80 F9
echo >>$ e17B "Zu7&;"1E 1 0 "u0&"8B 1E 3 0 83 FB 2 "r&"F6 C7 F0 "u!"
echo >>$ e194 B1 4 D3 E3 89 1E "^"0 A3 "\"0 8E C0 BE FF FF "F&"83 "<"
echo >>$ e1A8 0 "u"F9 "FF)"F3 89 1E "`"0 F8 C3 "1"C0 A3 "\"0 A3 "^"0
echo >>$ e1BD A3 "`"0 F9 C3 A1 "\"0 83 F8 0 "t4"8E C0 "1"DB "&9"1F 74
echo >>$ e1D2 "+1"F6 8A 2 "&:"0 "u"11 "F<=u"F4 "&"80 "8"0 "t"3 "F"EB
echo >>$ e1E9 F7 "F"F8 C3 "&"8B 0 "F<"0 "u"F8 80 FC 0 "t"4 1 F3 EB D5
echo >>$ e1FE "1"DB 89 DE F9 C3 E8 BB FF "r"1F 1 "6`"0 "&"80 "8"0 "u"
echo >>$ e212 7 "&"C7 7 0 0 F8 C3 "&"8B 0 "&"89 7 "C"83 F8 0 "u"F4 F8
echo >>$ e227 C3 F9 C3 A1 "\"0 83 F8 0 "tb"8E C0 "1"F6 89 F2 8A 2 "F"
echo >>$ e23B "<=u"6 9 D2 "u"2 89 F2 "<"0 "u"EF 9 D2 "tGB9"F2 "t"B2
echo >>$ e252 89 F1 E8 "k"FF A1 "`"0 "r"2 1 F0 "9"C1 "w2"E8 9F FF "1"
echo >>$ e266 DB "&9"1F "u"8 A1 "`"0 ")"C8 "H"EB C 8B 1E "^"0 A1 "`"0
echo >>$ e27B ")"C3 "K)"C8 A3 "`"0 "1"F6 8A 2 "&"88 0 "F<"0 "u"F6 "&"
echo >>$ e290 88 0 F8 C3 F9 C3 "CD-ROM drive $not found."D A "$is A:"
echo >>$ e2B6 D A "$CDROM=A:"0
echo >>$ rCX
echo >>$ 1C2
echo >>$ w
echo >>$ q
debug <$ >nul
del $
---------------------------------------- end MAKEUTIL.BAT -----

raster@highfiber.com

And some explanation on what it actually does:

On Tue, 14 Dec 1999 13:29:48 GMT, Todd <todd552@my-deja.com> wrote:

>In article <834tkd$i9b$1@news.rp-plus.de>,
>  "G.Pohl" <gEPo@rp-plus.de> wrote:
>> Good morning all,
>>
>> First I'll try to understand the MAKEUTIL.BAT of Charles Dye (seems
>> to be

Unintelligible, yeah.

>I'm not sure how it works either but would appreciate the info too. I'm
>guessing it gets the data directly from interupts, but I have no idea
>how it's done really.

You're spot on -- the program basically just loops through drive
letters calling 2F/150B.  Ralf Brown's indispensable List documents
this interrupt:

: --------d-2F150B-----------------------------
: INT 2F - CD-ROM v2.00+ - DRIVE CHECK
: 	AX = 150Bh
: 	CX = drive number (0=A:)
: Return: BX = ADADh if MSCDEX.EXE installed
: 	    AX = support status
: 		0000h if drive not supported
: 		nonzero if supported
: SeeAlso: AX=150Dh

(Incidentally, "MSCDEX.EXE" in this case includes NWCDEX and
the Windows 95 CD-ROM support VxD.)

The bulk of the program is just code to find and manipulate
the environment.  I'm not going to post the source code here
(longish, and off-topic for alt.msdos.batch) but anyone who
really wants it can mail me.

raster@highfiber.com
 
Click to view source Click to download source
 

Back to the top of this page... ]

 


CD-ROM Drive Letter in Windows 95/98

 

Presented here is a way to check which drive letter is assigned to the CD-ROM drive by Windows 95/98. It was posted to alt.msdos.batch by Bill James, who adapted it from code posted earlier by Tom Lavedas.

Here is a routine I adapted from a batch file written by
Tom Lavedas:

  ::CDletter.bat - A routine to locate the CD-ROM drive letter.  Win 9x.
  ::Based on FindCD.bat by Tom Lavedas
  @%2 echo off
  regedit /e C$D$L$A$.bxt "HKEY_LOCAL_MACHINE\Enum\SCSI"
  find "ntDriveLe" <C$D$L$A$.bxt>C$D$L$A$.bat
  echo %0 %%1 goto:2nd>CurrentDriveLetterAssignment.bat
  C$D$L$A$.bat
  :2nd
  del C*D*L*A*.b?t
  for %%v in (%1) do set CDROM=%%v:
  echo CD-ROM drive letter is %CDROM%
  :End
  set CDROM=

Bill James

KFason wrote in message <7ouobj$81f$1@nnrp1.deja.com>...
>Here is my predicament.  I am using IE4 to roll out my companies Y2K
>solution.  In the case of windows 95 and Mcafee VirusScan, I need to get
>switches to the program.  I'm doing this via a batch file that contains
>just the program and the switches needed (ie w95y2k.exe /ii /ar).  The
>user should select run file from current location.  Windows95 opens a
>dosbox to run the batch file, but will not change the dosbox over to the
>correct path.  It tries to run from c:\windows\desktop.  NOrmally I
>would just put a working directory path but not all my users have their
>CDROM at say "D:\".
>
>I need a way to find out the machines cdrom drive letter.  All the
>machines are running windows95, most are using 950B, some are using 950A
>(retail plus service pack 1).
>
>Any suggestions would be appreciated!!
>
>
>Sent via Deja.com http://www.deja.com/
>Share what you know. Learn what you don't.

Back to the top of this page... ]

 


 

Update ... update ... update ...

Now ignores ZIP drives and supports Windows NT

 

The monstrous batch file following here is an adaptation of the batch file posted above.
I found that the batch file as presented above returned my ZIP drive's letter instead of the CD-ROM drive's.
So I added a second pass through the registry, the first one enumerating all drives in HKEY_LOCAL_MACHINE\Enum\SCSI, and the second pass checking the sub-key left after filtering out the ZIP drive.
The most difficult part was stripping the square brackets from the resulting entry. The old DOS trick using the PROMPT with $H as a backspace doesn't work in Windows 95/98.
So I used CHOICE, a trick I saw in one of "Outsider"'s postings on alt.msdos.batch.

I later added sections to support Windows NT 4 and Windows 2000 too.
The NT 4 part comes down to this:

@ECHO OFF
START /WAIT REGEDIT /E %TEMP%.\CDROM1.REG "HKEY_LOCAL_MACHINE\SYSTEM\DISK"
FOR /F "tokens=*" %%A IN ('TYPE %TEMP%.\CDROM1.REG ^| FIND /I "\\Device\\CdRom"') DO CALL :Parse %%A
DEL %TEMP%.\CDROM1.REG
GOTO:EOF

:Parse
SET Line=%*
SET Line=%Line:"=%
FOR /F "tokens=2,3 delims=\= " %%A IN ('ECHO.%Line%') DO SET %%A=%%B
FOR /F "tokens=2,3 delims=\= " %%A IN ('ECHO.%Line%') DO ECHO CD-ROM drive detected, drive letter assigned is %%B
SET LINE=
GOTO:EOF

The Windows 2000 part comes down to this:

START /WAIT REGEDIT /E Temp1.reg "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices"
TYPE Temp1.reg > Temp2.reg
TYPE Temp2.reg | FIND "\\DosDevices\\" | FIND /V "\\DosDevices\\A:" | FIND "=hex:5c," > Temp1.reg
FOR /F "tokens=3 delims=\:" %%A IN (Temp1.reg) DO CALL :ParseW2K %%A
SET CDROMS
GOTO:EOF

:ParseW2K
IF DEFINED CDROMS (SET CDROMS=%CDROMS%,%1:) ELSE (SET CDROMS=%1:)
GOTO:EOF

I inserted this code into the original Windows 95/98 batch file, so it now supports most 32-bits Windows versions.

I know this batch file could be made at least 50% smaller, but I think it is already hard enough to read it as it is. If you still would like to give it a try, don't forget the 127 character limit for command lines (this may already be a problem with "deep" TEMP directories).

@ECHO OFF
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * CDROM.BAT,  Version 3.00                              *
REM * Read the CD-ROM drive letter from Windows' registry   *
REM * Written by Rob van der Woude                          *
REM *                                                       *
REM * Sorry, for 32-bit Windows only.                       *
REM *                                                       *
REM * Inspired by Tom Lavedas' batch file with the same     *
REM * functionality, which was adapted by Bill James.       * 
REM * I added a second pass through the registry to skip    *
REM * a ZIP drive, plus separate sections for NT 4 & 2000.  *
REM * The CHOICE trick to strip the square brackets from    *
REM * the registry entry's name came from "Outsider".       *
REM *                                                       *
REM * Thanks, guys.                                         *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

REM * * * * * * * * * *
REM * Recursive calls *
REM * * * * * * * * * *
IF "%1"=="Environment" GOTO Environment
IF "%1"=="Loop"        GOTO Loop

REM * * * * * * * * * * * * * * * * * *
REM * For Windows 95/98/NT4/2000 only *
REM * * * * * * * * * * * * * * * * * *
VER | FIND "Windows 9" >NUL
IF NOT ERRORLEVEL 1 GOTO Win9x
VER | FIND "Windows NT" >NUL
IF NOT ERRORLEVEL 1 GOTO NT
VER | FIND "Windows 2000" >NUL
IF NOT ERRORLEVEL 1 GOTO NT
ECHO Sorry, for Windows 95/98/NT4/2000 only
GOTO End


:: For Windows NT4
:NT
:: Find all registry sub-keys of HKEY_LOCAL_MACHINE\SYSTEM\DISK
START /WAIT REGEDIT /E %TEMP%.\CDROM1.REG "HKEY_LOCAL_MACHINE\SYSTEM\DISK"
:: Find the CD-ROM drives and parse the strings using a subroutine
FOR /F "tokens=*" %%A IN ('TYPE %TEMP%.\CDROM1.REG ^| FIND /I "\\Device\\CdRom"') DO CALL :ParseNT4 %%A
:: Remove temporary files
GOTO Cleanup

:: Parse lines from REG file and store the results in environment variables
:ParseNT4
:: Store command line parameters in temporary variable LINE
SET Line=%*
:: Strip quotes
SET Line=%Line:"=%
:: Strip leading space in NT 4 only
VER | FIND "Windows NT" >NUL
IF NOT ERRORLEVEL 1 SET Line=%Line:~1%
:: Remove quotes, backslashes and "Device" and store drive
:: letters in environment variables named after CD-ROM devices
FOR /F "tokens=2,3 delims=\= " %%A IN ('ECHO.%Line%') DO SET %%A=%%B
:: Once more to display the result
FOR /F "tokens=2,3 delims=\= " %%A IN ('ECHO.%Line%') DO ECHO CD-ROM drive detected, drive letter assigned is %%B
:: Flush temporary variable
SET LINE=
GOTO:EOF


:: For Windows 2000
:W2K
SETLOCAL
SET CDROMS=
SET Temp1=%Temp%.\%~n0%Random%1.reg
SET Temp2=%Temp%.\%~n0%Random%2.reg
START /WAIT REGEDIT /E %Temp1% "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices"
TYPE %Temp1% > %Temp2%
TYPE %Temp2% | FIND "\\DosDevices\\" | FIND /V "\\DosDevices\\A:" | FIND "=hex:5c," > %Temp1%
FOR /F "tokens=3 delims=\:" %%A IN (%Temp1%) DO CALL :ParseW2K %%A
SET CDROMS
DEL %Temp1%
DEL %Temp2%
ENDLOCAL & SET CDROMS=%CDROMS%
GOTO:EOF

:ParseW2K
IF DEFINED CDROMS (SET CDROMS=%CDROMS%,%1:) ELSE (SET CDROMS=%1:)
GOTO:EOF


REM * * * * * * * * * * *
REM * For Windows 95/98 *
REM * * * * * * * * * * *
:Win9x
REM * * * * * * * * * * * * * * * * * * * * * * * *
REM * Make sure there is enough environment space *
REM * * * * * * * * * * * * * * * * * * * * * * * *
%COMSPEC% /E:2048 /C %0 Environment
SET CMDLINE=
CALL %TEMP%.\CDROM1.BAT
GOTO Cleanup

:Environment
REM * * * * * * * * * *
REM * Reset variables *
REM * * * * * * * * * *
SET CDROM=
SET KEY=

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Find all registry sub-keys of HKEY_LOCAL_MACHINE\Enum\SCSI  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
START /WAIT REGEDIT /E %TEMP%.\CDROM1.REG "HKEY_LOCAL_MACHINE\Enum\SCSI"

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Extract the registry sub-key that is NOT the ZIP    *
REM * drive and store it in the environment variable KEY  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TYPE %TEMP%.\CDROM1.REG | FIND "[" | FIND /V "_ZIP" | FIND /V "SCSI]" | FIND /V "&" > %TEMP%.\CDROM1.TMP
ECHO.>>%TEMP%.\CDROM1.TMP
TYPE %TEMP%.\CDROM1.TMP|DATE|FIND "):"|FIND "[">%TEMP%.\CDROM1.BAT

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Temporary batch files VOER.BAT and TYP.BAT are for Dutch Win9x  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ECHO SET KEY=%%6>VOER.BAT
ECHO SET KEY=%%4>TYP.BAT
ECHO SET KEY=%%3>CURRENT.BAT
CALL %TEMP%.\CDROM1.BAT

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Strip the square brackets [] from the KEY variable  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ECHO ]|CHOICE /C:%KEY%; %0 Loop >%TEMP%.\CDROM1.BAT
SET KEY=
CALL %TEMP%.\CDROM1.BAT
GOTO End

:Second
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Find all registry sub-keys of the registry entry found earlier  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
START /W REGEDIT /E %TEMP%.\CDROM1.REG "%KEY%"

REM * * * * * * * * * * * * * * * * * * * * * * *
REM * Check if this really is the CD-ROM entry  *
REM * * * * * * * * * * * * * * * * * * * * * * *
TYPE %TEMP%.\CDROM1.REG|FIND "Class"|FIND "CDROM">NUL
IF ERRORLEVEL 1 GOTO NoCdRom

REM * * * * * * * * * * * * * * * * * * * * * * * *
REM * Read the drive letter assignment and store  *
REM * store it in the environment variable CDROM  *
REM * * * * * * * * * * * * * * * * * * * * * * * *
TYPE %TEMP%.\CDROM1.REG|FIND "CurrentDriveLetterAssignment">%TEMP%.\CDROM1.TMP
ECHO.>> %TEMP%.\CDROM1.TMP
TYPE %TEMP%.\CDROM1.TMP|DATE|FIND "):"|FIND "Assignment">%TEMP%.\CDROM1.BAT

REM * * * * * * * * * * * * * * * * * * * * * * * *
REM * Make sure there is enough environment space *
REM * * * * * * * * * * * * * * * * * * * * * * * *
SET KEY=
SET CMDLINE=

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Temporary batch files VOER.BAT and TYP.BAT are for Dutch Win9x  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ECHO SET CDROM=%%7>VOER.BAT
ECHO SET CDROM=%%5>TYP.BAT
ECHO SET CDROM=%%4>CURRENT.BAT
CALL %TEMP%.\CDROM1.BAT

REM * * * * * * * * * * * * * * * * * *
REM * If variable not set, aparently  *
REM * no CD-ROM drive was detected    *
REM * * * * * * * * * * * * * * * * * *
IF "%CDROM%"=="" GOTO NoCdRom

REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Strip double quotes "" from the CDROM variable and create *
REM * a temporary batch file to change the master environment   *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ECHO @ECHO OFF>%TEMP%.\CDROM1.BAT
FOR %%A IN (%CDROM%) DO ECHO SET CDROM=%%A:>>%TEMP%.\CDROM1.BAT
CALL %TEMP%.\CDROM1.BAT

REM * * * * * * * * * * * *
REM * Display the result  *
REM * * * * * * * * * * * *
ECHO CD-ROM drive detected, drive letter assigned is %CDROM%
GOTO End

:NoCdRom
REM * * * * * * * * * * * *
REM * Display the result  *
REM * * * * * * * * * * * *
ECHO No CD-ROM drive detected
GOTO End

:Loop
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Strip the square brackets [] from the KEY variable  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * *
SHIFT
IF "%1"=="]" GOTO Second
IF NOT "%1"=="[[" SET KEY=%KEY%%1
GOTO Loop

:Cleanup
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM * Clean up the ugly mess in the TEMP directory and the environment  *
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
SET KEY=
SET CMDLINE=
IF EXIST CURRENT.BAT      DEL CURRENT.BAT
IF EXIST TYP.BAT          DEL TYP.BAT
IF EXIST VOER.BAT         DEL VOER.BAT
IF EXIST %TEMP%.\CDROM1.* DEL %TEMP%.\CDROM1.*

:End
 
Click to view source Click to download source
 

This batch file does have one limitation: it needs to write its temporary batch files to the current directory. You may prevent that by using fully qualified file names, as long as you make sure they will be found in the PATH. One way to do that is by adding your TEMP directory to the PATH.

Back to the top of this page... ]

 


 

I also created some alternative scripts with the same functionality in KiXtart, Rexx and VBScript.


page last modified: 2016-09-19; loaded in 0.0063 seconds