community.borland.com

Article #15521: Getting / Setting diskette serial # under Windows.

 Technical Information Database

TI521D.txt   Getting / Setting diskette serial # under Windows.
Category   :General Programming
Platform    :All
Product    :Pascal  All

Description:
(*
This example demonstrates how to get/set the volume serial
number of a diskette under Windows or DOS Protected Mode.
This sample demonstrates two important interrupts: Int $21,
service $69 (Get/Set media info) and Int $31 (simulate real
mode interrupt from DPMI).

NOTE: To use the following code under DPMI instead of Windows,
replace all of the occurances of "WinProcs" with "WinAPI"
in the USES clauses.
*)
unit MediaID;
{ Use this unit in your program }

Interface

Type
  PMediaID = ^TMediaID;
  TMediaID = Record
    InfoLvl:   Word;
    SerialNum: Longint;
    VolLabel:  Array[0..10] of Char;
    FileSys:   Array [0..7] of Char;
  end;

  TRMCS = record     { Real mode call structure }
    DI, SI, BP, Reserved, BX, DX, CX, AX : Longint;
    Flags, ES, DS, FS, GS, IP, SP, SS: Word;
  end;


FUNCTION GetMediaInfo( Drive: WORD; MID: PMediaID ): Boolean;
FUNCTION SetMediaInfo( Drive: WORD; MID: PMediaID ): Boolean;
  { MID should be a real mode pointer, that is, segment:offset }
  { Allocate memory for MID pointer using GlobalDOSAlloc }
  { Drive:  0=default, 1=A, 2=B, etc. }

Implementation

uses WinAPI;

var
  R: TRMCS;

function GetMediaInfo( Drive: WORD; MID: PMediaID ): Boolean;
var
  ErrorFlag : byte;
begin
  GetMediaInfo := True;
  R.BX := Drive;   { 0 = Default, 1 = A, 2 = B, etc }
  R.DS := HiWord(Longint(MID));  { Segment (not selector) of MID }
  R.DX := LoWord(Longint(MID));  { Offset of MID }
  R.AX := $6900;  { Real mode service $69, subfunc 0 }
  asm
    mov bx, 0021h { set flags to $00, Real mode interrupt $21 }
    mov cx, 0     { copy 0 words from protected mode stack }
    mov ax, seg R
    mov es, ax       { selector of real mode call structure }
    mov di, offset R { offset of real mode call structure }
    mov ax, 0300h    { DPMI simulate real mode interrupt }
    int 31h
    pushf            { push flags onto stack }
    pop   bx         { pop flags into bx }
    test  bx, 0      { error check: is CF flag 0? }
    je    

done     { if so, then there was no error }
  

error:
    mov   ErrorFlag, 1  { set error flag }
  

done:
  end;
  if ErrorFlag = 1 then
    GetMediaInfo := False;  { return False on error }
end;

function SetMediaInfo( Drive: WORD; MID: PMediaID ): Boolean;
var
  ErrorFlag : byte;
begin
  SetMediaInfo := True;
  R.BX := Drive;   { 0 = Default, 1 = A, 2 = B, etc }
  R.DS := HiWord(Longint(MID));  { Segment of MID }
  R.DX := LoWord(Longint(MID));  { Offset of MID }
  R.AX := $6901;  { Real mode service $69, subfunc 1 }
  asm
    mov bx, 0021h { Real mode interrupt $21 }
    mov cx, 0
    mov ax, seg R
    mov es, ax       { real mode selector call structure }
    mov di, offset R { offset of real mode call structure }
    mov ax, 0300h    { DPMI simulate real mode interrupt }
    int 31h
    pushf            { push flags onto stack }
    pop   bx         { pop flags into bx }
    test  bx, 0      { error check: is CF flag 0? }
    je    

done     { if so, then there was no error }
  

error:
    mov   ErrorFlag, 1  { set error flag }
  

done:
  end;
  if ErrorFlag = 1 then
    SetMediaInfo := False;  { return False on error }
end;

begin
end.   {*** End of MediaID unit ***}

Here is a small sample program that demonstrates
how to use the MediaID unit:

program DiskInfo;

uses MediaID, WinProcs, WinCRT;

var
  SReal, SProt : PMediaId;
  LongHandle : Longint;
begin
  { allocate some lower memory }
  LongHandle := GlobalDOSAlloc(SizeOf(TMediaID)); 
  { real mode pointer }
  SReal := PMediaID(Ptr(HiWord(LongHandle), 0)); 
  { protected mode pointer }
  SProt := PMediaID(Ptr(LoWord(LongHandle), 0)); 
  GetMediaInfo(3, SReal);      { call function }
  writeln(SProt^.SerialNum);   { write serial # }
  GlobalDOSFree(LoWord(LongHandle)); { free allocated memory }
end. {*** End of DiskInfo program ***}




Reference:


7/16/98 4:33:46 PM
 

Last Modified: 01-SEP-99