'===========================================================================
' Subject: GET/SET/ERASE VOLUME LABEL         Date: 07-09-97 (23:44)       
'  Author: Hans Lunsing                       Code: QB, QBasic, PDS        
'  Origin: FidoNet QUIK_BAS Echo            Packet: DOS.ABC
'===========================================================================
' > Does any kind saul have a routine available for obtaining the
' > Disk Volume Label when:

' > a) The MS-DOS version running is less than MS-DOS 4.00

' >  OR

' > b) Where a disk has previously been formatted using a version
' > of MS-DOS before version 4.00.

'Do it with Extended File Control Blocks (EFCB):

' Module for handling volume labels
' Freeware by Hans Lunsing
' e-mail jlunsing@doge.nl
'-----------------------------------------------------------------------
'
' Available functions:
' GetVolumeLabel$       : gets volume label
' SetVolumeLabel%       : sets volume label
' EraseVolumeLabel%     : erases volume label
'
'***********************************************************************

DEFINT A-Z
'$INCLUDE: 'qb.bi'

TYPE ExtFCBType
  Signature AS STRING * 1
  Reserved AS STRING * 5
  Attribute AS STRING * 1
  Drive AS STRING * 1
  FileName AS STRING * 11
  Rest AS STRING * 25
END TYPE

DECLARE SUB InitExtFCB (ExtFCB AS ExtFCBType, Drive AS STRING, FileName AS STRING, Attribute AS INTEGER)
DECLARE FUNCTION PeekString$ (Offset AS INTEGER, Length AS INTEGER)

FUNCTION EraseVolumeLabel (Drive AS STRING, Label AS STRING)
'-----------------------------------------------------------------------
' The function returns
' - -1 (TRUE) if everything went right
' - 0 (FALSE) if an error occurred
'-----------------------------------------------------------------------
  DIM Reg AS RegTypeX, ExtFCB AS ExtFCBType
  InitExtFCB ExtFCB, Drive$, Label$, 8
  Reg.ds = VARSEG(ExtFCB)
  Reg.dx = VARPTR(ExtFCB)
  Reg.ax = &H1300
  CALL INTERRUPTX(&H21, Reg, Reg)
  EraseVolumeLabel = (Reg.ax AND 255) = 0
END FUNCTION

FUNCTION GetVolumeLabel$ (Drive AS STRING)
'-----------------------------------------------------------------------
' The function returns
' - the volume label if a volume label can be found
' - an empty string if not
'-----------------------------------------------------------------------
  DIM Reg AS RegTypeX, ExtFCB AS ExtFCBType
  InitExtFCB ExtFCB, Drive$, STRING$(11, "?"), 8
  Reg.ds = VARSEG(ExtFCB)
  Reg.dx = VARPTR(ExtFCB)
  Reg.ax = &H1100
  CALL INTERRUPTX(&H21, Reg, Reg)
  IF (Reg.ax AND 255) THEN
    GetVolumeLabel$ = ""
  ELSE
    Reg.ax = &H2F00
    CALL INTERRUPTX(&H21, Reg, Reg)
    DEF SEG = Reg.es
    GetVolumeLabel$ = PeekString$(Reg.bx + 8, 11)
  END IF
END FUNCTION

SUB InitExtFCB (ExtFCB AS ExtFCBType, Drive AS STRING, FileName AS STRING, Attribute AS INTEGER)
'-----------------------------------------------------------------------
'Initializes volume label handling
'-----------------------------------------------------------------------
  ExtFCB.Signature = CHR$(255)
  ExtFCB.Reserved = STRING$(5, 0)
  ExtFCB.Attribute = CHR$(Attribute)
  ExtFCB.Drive = CHR$(ASC(UCASE$(Drive$)) - 64)
  ExtFCB.FileName = FileName$
  ExtFCB.Rest = STRING$(25, 0)
END SUB

FUNCTION PeekString$ (Offset AS INTEGER, Length AS INTEGER)
'-----------------------------------------------------------------------
' Reads a string with a certain length from memory.
' The memory segment must be set beforehand with the DEF SEG command.
'-----------------------------------------------------------------------
  DIM i AS INTEGER
  IF Length > 0 THEN
    PeekString$ = STRING$(Length, 0)
    FOR i = 1 TO Length
	 MID$(PeekString$, i, 1) = CHR$(PEEK(Offset - 1 + i))
    NEXT i
  ELSE
    PeekString$ = ""
  END IF
END FUNCTION

FUNCTION SetVolumeLabel (Drive AS STRING, Label AS STRING)
'-----------------------------------------------------------------------
' The function returns
' - -1 (TRUE) if everything went right
' - 0 (FALSE) if an error occurred
'-----------------------------------------------------------------------
  DIM Reg AS RegTypeX, ExtFCB AS ExtFCBType
  InitExtFCB ExtFCB, Drive$, Label$, 8
  Reg.ds = VARSEG(ExtFCB)
  Reg.dx = VARPTR(ExtFCB)
  Reg.ax = &H1600
  CALL INTERRUPTX(&H21, Reg, Reg)
  SetVolumeLabel = (Reg.ax AND 255) = 0
END FUNCTION
