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