Recover label of drive(s)

DOS specific questions.
Post Reply
Cpcdos
Posts: 207
Joined: Mar 06, 2013 13:52
Location: France - LYON 69003
Contact:

Recover label of drive(s)

Post by Cpcdos »

Hello
I would know how to recover label of drive(s) ? (on dos)

Thank's :)



(ps: Previous thread : http://www.freebasic.net/forum/viewtopi ... =3&t=21745 )
fxm
Moderator
Posts: 12158
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Recover label of drive(s)

Post by fxm »

Rustic workaround because I don't found DOS interrupt for that!

We can display the disk volume label and serial number, if the disk has them, by using the DOS command 'vol'.
An 'open pipe' instruction can be used to get the text returned from this DOS command.

The previous QB program, still modified one time more:
(then, you are free to extract the only useful information from the text returned from the DOS command)

Code: Select all

#lang "fblite"

'====================================================================
' Quick Basic Forum
'   Date : 02-Jun-91
'   From : Larry Stone
'     To : Steve Halko
'Subject : Code to get disk drives
'===================================================================

'**** DRIVLIST.BAS - Drive Listing functions by Larry Stone, 1991
'**** Based on a routine published in MicroHelp's BUG Newsletter, 1/1/90

DECLARE FUNCTION HardDriveList$ ()

#include "dos\dpmi.bi"

CLS

HardDrives$ = HardDriveList$()
HardDrives% = LEN(HardDrives$)

PRINT "This system has"; HardDrives%; " hard drive(s) ==> ";
FOR N = 1 TO HardDrives%
    PRINT MID$(HardDrives$, N, 1); ": ";
NEXT
PRINT
sleep
END

FUNCTION HardDriveList$ ()
    DIM Reg AS __dpmi_regs

    'DOS function AH = 44h & AL = 09h is "Device Driver Control (IOCTL)" and
    'tests whether a drive is local or remote.  If the carry flag is set then
    'AX will return 0Fh when drive letter is invalid.  This routine simply
    'checks to see if the carry flag is set and ends if it is.

    FOR BL% = 1 TO 26         'Roll through possible hard drives.
        Reg.x.AX = &H4409                 'DOS function "Device Driver Control"
        Reg.x.BX = BL%                    'Drive letter in BL register.
        __dpmi_int(&H21, @Reg)        'Call Mr DOS (INT 21h).
        IF (Reg.x.Flags AND 1) THEN continue for        'Check carry flag.
        scratch$ = scratch$ + CHR$(64 + Reg.x.BX)   'Add the letter
        Print CHR$(64 + Reg.x.BX) & ":"
        Open Pipe "vol " & CHR$(64 + Reg.x.BX) & ":" For Input As #1
        Do Until EOF(1)
          Line Input #1, ln$
          Print ln$
        Loop
        Close #1
        Print "Any key to continue."
        Sleep
        Print
    NEXT

    HardDriveList$ = scratch$           'Set the function.
    scratch$ = ""                       'Garbage collection.
END FUNCTION
Always cross-compiled to a DOS target and tested under Windows XP.

Code: Select all

C:

 Le volume dans le lecteur C s'appelle SYSTEM
 Le numéro de série du volume est E83D-6BCC

Any key to continue.

D:

 Le volume dans le lecteur D s'appelle DATA
 Le numéro de série du volume est DC99-3129

Any key to continue.

E:

 Le volume dans le lecteur E n'a pas de nom
 Le numéro de série du volume est 0000-0000

Any key to continue.

I:

 Le volume dans le lecteur I s'appelle 22XXMLU
 Le numéro de série du volume est 4802-FE2D

Any key to continue.

J:

 Le volume dans le lecteur J s'appelle SHIKRA
 Le numéro de série du volume est 48D1-FE2D

Any key to continue.

K:

 Le volume dans le lecteur K s'appelle INT_NORM
 Le numéro de série du volume est 4866-FE2D

Any key to continue.

L:

 Le volume dans le lecteur L s'appelle MRR_MLU
 Le numéro de série du volume est 487F-FE2D

Any key to continue.

N:

 Le volume dans le lecteur N s'appelle ECHANGE
 Le numéro de série du volume est 4840-FE2D

Any key to continue.

O:

 Le volume dans le lecteur O s'appelle DOORS_GM400
 Le numéro de série du volume est 483B-FE2D

Any key to continue.

P:

 Le volume dans le lecteur P s'appelle applis
 Le numéro de série du volume est 5502-147B

Any key to continue.

Q:

 Le volume dans le lecteur Q s'appelle echange
 Le numéro de série du volume est 0F93-2B3B

Any key to continue.

R:

 Le volume dans le lecteur R s'appelle FLOADV
 Le numéro de série du volume est 4847-FE2D

Any key to continue.

S:

 Le volume dans le lecteur S s'appelle Ne_pas_util
 Le numéro de série du volume est 486E-5712

Any key to continue.

T:

 Le volume dans le lecteur T s'appelle RET3_HER
 Le numéro de série du volume est 48BE-FE2D

Any key to continue.

U:

 Le volume dans le lecteur U s'appelle Minicita
 Le numéro de série du volume est FE14-8248

Any key to continue.

V:

 Le volume dans le lecteur V s'appelle MFCR3_PAON
 Le numéro de série du volume est 487A-FE2D

Any key to continue.

W:

 Le volume dans le lecteur W s'appelle master
 Le numéro de série du volume est 0FF4-2B3B

Any key to continue.

X:

 Le volume dans le lecteur X s'appelle nora
 Le numéro de série du volume est 0F0B-2B3B

Any key to continue.

Y:

 Le volume dans le lecteur Y n'a pas de nom
 Le numéro de série du volume est 0000-0000

Any key to continue.

Z:

 Le volume dans le lecteur Z s'appelle DOORS_GM200
 Le numéro de série du volume est 483A-FE2D

Any key to continue.

This system has 20 hard drive(s) ==> C: D: E: I: J: K: L: N: O: P: Q: R: S: T: U
: V: W: X: Y: Z:
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Recover label of drive(s)

Post by MichaelW »

There is a DOS interrupt to return that information, and it was available starting with version 4.0

Code: Select all

''=============================================================================
'' This is a test of the DOS Get Media ID function.
''=============================================================================

#include "dos/dpmi.bi"

''=============================================================================

''------------------------------------------------
'' This is a port of the Microsoft MID structure.
''------------------------------------------------

type __MID field = 1
    midInfoLevel as ushort            '' always 0
    midSerialNum as uinteger
    midVolumeLabel(0 to 10) as ubyte
    midFileSysType(0 to 7) as ubyte   '' FAT, FAT16, FAT32, ?
end type

''=============================================================================

dim as integer paragraphs = int(sizeof(__MID)/16)+1
dim as integer fError
dim as ushort seg, sel, driveNumber
dim as string drive
dim as __dpmi_regs dpmir
dim as __MID _mid

''----------------------------------------------
'' For the drive use "@" to specify the default
'' drive, otherwise "A","B","C"..."Z".
''----------------------------------------------

drive = "C"
driveNumber = asc(drive) - asc("@")

asm
    ''-----------------------------------------------------
    '' Allocate a DOS memory block to receive the media ID
    '' information, in the form of a __MID structure, from
    '' the Get Media ID function.
    ''-----------------------------------------------------

    mov ax, 0x100
    mov bx, [paragraphs]
    int 0x31
    jc  0f
    mov [seg], ax
    mov [sel], dx
  0:
end asm

if seg = 0 then print "allocation failed"

''-------------------------------------------------------------
'' Since the Get Media ID function requires that DS be loaded
'' with the RM segment address of the memory block, and loading
'' a RM segment address into a segment register from PM would
'' trigger an exception, the call must be done via the DPMI
'' Simulate Real Mode Interrupt function.
''-------------------------------------------------------------

''--------------------------------------------------------------
'' Set up the RM call register structure for the function call.
''--------------------------------------------------------------

dpmir.x.bx = driveNumber
dpmir.x.ax = &h440d       '' function code
dpmir.h.ch = 8            '' device category, must be 8
dpmir.h.cl = &h66         '' minor function code
dpmir.x.ds = seg          '' RM segment of memory block
dpmir.x.dx = 0            '' starting offset

asm
    mov ax, 0x300
    mov bx, 0x21
    xor cx, cx
    lea edi, [dpmir]
    int 0x31
    jnc 0f                '' carry flag set on error
    inc DWORD PTR [fError]
  0:
end asm

if fError then print "Simulate RM Interrupt failed"

''---------------------------------------------------------------------
'' The Get Media ID function returns with the carry flag set on error,
'' and on return the function's return registers, including the flags
'' register, are copied to the RM call register structure, so we can
'' detect an error by checking the the carry flag (bit0) of the flags
'' member.
''---------------------------------------------------------------------

if dpmir.x.flags and 1 then print "Get Media ID failed"

''-----------------------------------------------------------------
'' Copy the __MID structure from the RM memory block to PM memory.
''-----------------------------------------------------------------

asm
    push ds
    mov ax, [sel]
    mov ds, ax
    xor esi, esi
    lea edi, [_mid]
    mov ecx, 25
    rep movsb
    pop ds
end asm

''----------------------------------
'' Free the allocated memory block.
''----------------------------------

asm
    mov ax, 0x101
    mov dx, [sel]
    int 0x31
    jnc 0f
    inc DWORD PTR [fError]
  0:
end asm
if fError then print "Free DOS memory block failed"

dim as string r

print hex(_mid.midSerialNum)
print
for i as integer = 0 to 10
    r &= chr(_mid.midVolumeLabel(i))
next
print r
print
for i as integer = 0 to 7
    print chr(_mid.midFileSysType(i));
next
print

sleep
I used 0.24.0, cross-compiled to a DOS executable, and tested under Windows XP. None of my hard drives have a volume label but the returned serial numbers and file system types (all FAT32) are correct. Testing my Plextor CDRW drive with an Enya CD in it I get:

Code: Select all

12A6268

Audi

CDFS
So far I have not found any way to verify the serial number, and I’m not sure what to make out of the volume label, but the file system type appears to be correct.

Testing my diskette drive with a 1.44MB diskette that I formatted with the volume label “12345678” I get:

Code: Select all

7CCC882C

123

FAT
I have not found any way to verify the serial number, I have no idea what is going on with the volume label, or why the file system type shows as FAT instead of FAT12.
fxm
Moderator
Posts: 12158
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Recover label of drive(s)

Post by fxm »

Result of your program on my PC (Windows XP):

Code: Select all

E83D6BCC

SYST

NTFS
To be compared with the result of the DOS command 'vol c:':

Code: Select all

 Le volume dans le lecteur C s'appelle SYSTEM
 Le numéro de série du volume est E83D-6BCC
Only difference: 'SYST' (followed by 7 spaces) instead of 'SYSTEM'.
Cpcdos
Posts: 207
Joined: Mar 06, 2013 13:52
Location: France - LYON 69003
Contact:

Re: Recover label of drive(s)

Post by Cpcdos »

fxm thank you but on dosbox there is "unknown command Vol."

MichaelW Thank you, your code work perfectely on dosbox !
i will test just now after school, on freedos (if interrupts exist on freedos)
Cpcdos
Posts: 207
Joined: Mar 06, 2013 13:52
Location: France - LYON 69003
Contact:

Re: Recover label of drive(s)

Post by Cpcdos »

Thank's you ! it's work :)
Post Reply