Subject: Volume Serial Number 83. ***** Q: How can I read a disk's Volume Serial Number? A: The Volume Serial Number for disks was introduced in MS-DOS version 4.0. Here is an example code uses Dos; {} (* Convert a longint to a hexadecimal string *) function LHEXFN (decimal : longint) : string; const hexDigit : array [0..15] of char = '0123456789ABCDEF'; var i : byte; hexString : string; begin FillChar (hexString, SizeOf(hexString), ' '); hexString[0] := chr(8); for i := 0 to 7 do hexString[8-i] := HexDigit[(decimal shr (4*i)) and $0F]; lhexfn := hexString; end; (* lhexfn *) {} (* Get disk serial number. Requires MS-DOS 4.0+. Else, or on an error, returns an empty string. The default drive can be pointed to by using '0' *) function GETSERFN (drive : char) : string; type diskInfoRecordType = record infoLevel : word; { zero } serialNumber : longint; { DWORD actually } volumeLabel : array [1..11] of char; { NO NAME if none present } filesystemType : array [1..8] of char; { FAT12 or FAT16 } end; var regs : registers; diskInfo : diskInfoRecordType; serial : string; begin getserfn := ''; if swap(DosVersion) < $0400 then exit; FillChar (regs, SizeOf(regs), 0); drive := UpCase (drive); if drive <> '0' then if (drive < 'A') or (drive > 'Z') then exit; regs.ah := $69; { Interrrupt 21 function $69 } regs.al := $00; { subfunction: get serial number } if drive <> '0' then regs.bl := ord(drive) - ord('A') + 1 else regs.bl := 0; regs.ds := Seg(diskInfo); { the diskInfo address: } regs.dx := Ofs(diskInfo); { its segment and offset } Intr ($21, regs); if (regs.flags and FCarry) <> 0 then exit; { CF is set on error } serial := LHEXFN (diskInfo.serialNumber); getserfn := Copy (serial, 1, 4) + '-' + Copy (serial, 5, 4); end; (* getserfn *) {} begin writeln ('C: ', GETSERFN('C')); end. A2: The second alternative has been modified from a posting by Robert B. Clark rclark@su1.in.net. I have also utilized INTERRUP.E from Ralf Brown's listing of interrupt calls ftp://garbo.uwasa.fi/pc/programming/inter48b.zip {} uses Dos; function GETSERFN2 (drive : char): longint; var ParBlock : array [0..24] of char; { IOCTL parameter block Table 0785 } regs : registers; sernum : longint; begin FillChar (ParBlock, SizeOf(ParBlock), 0); FillChar (regs, SizeOf(regs), 0); regs.ax := $440D; { IOCTL - generic block device request } if drive <> '0' then { '0' points to the default drive } regs.bl := ord(UpCase(drive)) - ord('A') + 1 { drive as byte } else regs.bl := 0; regs.ch := $08; { block device IOCTL category code: disk drive } regs.cl := $66; { IOCTL minor code: get volume serial number } regs.ds := Seg(ParBlock); { Parameter block segment address } regs.dx := Ofs(ParBlock); { Parameter block offset } MsDos (regs); { Call interrupt $21 } if regs.Flags and FCarry = 0 then sernum := word(ord(ParBlock[4]) + ord(ParBlock[5]) shl 8) * 65536 + word (ord(ParBlock[2]) + ord(ParBlock[3]) shl 8) else sernum := 0; getserfn2 := sernum; end; (* getsetfn2 *) {} begin writeln ('C: ', LHEXFN(GETSERFN2('0'))); end. A3: Setting a disk's serial number, instead of just reading it, is more complicated and will not be covered here. If you need it, the routine without source code is available (for floppies only for security reasons) as "SETSER Set floppy's serial number (MsDos 4.0+)" in TSUNTK.TPU in ftp://garbo.uwasa.fi/pc/ts/tspa3470.zip --------------------------------------------------------------------