I have been trying unsuccessfully to extract hard disk information using vwin32 vxd, I am not too familiar with 16 bit programming and think that it might be a matter of misinterpretting Browns interrupts documentation or the way the inofrmation is passed to the DeviceIOControl function. My test code is as follows...

GetWin95DiskInfo FRAME
LOCAL hDisk :D
LOCAL diocr :DIOCRegs
LOCAL DriveInfo :INT13_48H_DIOC
LOCAL szTempText[256] :B
LOCAL cbReturned :D

invoke CreateFileA,"\\.\vwin32",0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL
mov ,eax
test eax,eax
js >>.EXIT
// Convert drive letter to a number 1=A 2=B 3=C etc...
mov eax,"c:\"
mov ebx,eax
and ebx,0FFh
test ebx,ebx
jz >>
or ebx,20H
cmp ebx,"z"
jge >>
sub ebx,60h
js >>

mov D,ebx ; DL = Drive number (80H-FFH)
mov D,4800h ; AH=48h
mov D,0 ; Flags = 0
mov W,SIZEOF INT13_48H_DIOC ; Buffer size
mov eax,offset DriveInfo ; Buffer address
mov D,eax
mov eax,VWIN32_DIOC_DOS_INT13
mov esi,offset diocr
mov ebx,
invoke DeviceIoControl,,VWIN32_DIOC_DOS_INT13,offset diocr,SIZEOF DIOCRegs,offset diocr,SIZEOF DIOCRegs,offset cbReturned,NULL
test eax,eax
jz >>

mov eax,
invoke wsprintfA,offset szTempText,"%u",eax
add esp,12
invoke MessageBoxA,NULL,offset szTempText,0,0
invoke CloseHandle,

Structures and equates...

wSize DW ;(call) size of buffer (001Ah for v1.x, 001Eh for v2.x, 42h for v3.0) (ret) size of returned data
iFlags DW ;information flags (see #00274)
nCylinders DD ;number of physical cylinders on drive
nHeads DD ;number of physical heads on drive
nSectTrack DD ;number of physical sectors per track
nSectors DQ ;total number of sectors on drive
nBytesSect DW ;bytes per sector
// v2.0
EDDConfig DD ;EDD configuration parameters
// v3.0
Signature DD ;signature BEDDh to indicate presence of Device Path info
cbPathInfo DB ;length of Device Path information, including signature and this byte (24h for v3.0)
reserved1 DB
szHostBus DB 4 DUP (?) ;ASCIZ name of host bus ("ISA" or "PCI")
szInterface DB 8 DUP (?) ;ASCIZ name of interface type
;"1394" IEEE 1394 (FireWire)
;"FIBRE" Fibre Channel
szIFPath DB 8 DUP (?) ;Interface Path (see #00275)
szDevPath DB 8 DUP (?) ;Device Path
reserved2 DB
checksum DB ;checksum of bytes 1Eh-40h (two's complement of sum, which makes the 8-bit sum of bytes 1Eh-41h equal 00h)

reg_EBX DD
reg_EDX DD
reg_ECX DD
reg_EAX DD
reg_EDI DD
reg_ESI DD
reg_Flags DD

#define VWIN32_DIOC_DOS_IOCTL  1  // DOS ioctl calls 4400h-4411h
#define VWIN32_DIOC_DOS_INT25  2  // absolute disk read, DOS int 25h
#define VWIN32_DIOC_DOS_INT26 3
#define VWIN32_DIOC_DOS_INT13 4
#define VWIN32_DIOC_DOS_DRIVEINFO 6 // OEM Service Release 2

Note that this code will NOT run on an NT based system, only 95/98/98SE/ME so if you don't have one of those OSes installed it will just exit the function. I am running it under Win95 on VPC which may be another issue since I don't have a dedicated Win9x box.

Any help or advice would as usual be appreciated.

Posted on 2006-10-09 10:32:40 by donkey
Hello donkey,

Have you tried using IOCTL_DISK_GET_DRIVE_GEOMETRY_EX ?  Check this knowledge base article: http://support.microsoft.com/kb/q137176/

Hope this is helpful.
best regards,

Posted on 2006-10-09 12:40:42 by czDrillard
Hi czDrillard,

IOCTL_DISK_GET_DRIVE_GEOMETRY_EX requires XP or Vista and the deprecated IOCTL_DISK_GET_DRIVE_GEOMETRY works only with 2K+, as I said I am trying to extract the information from a 9x system.

Posted on 2006-10-09 15:10:47 by donkey