Using VWIN32 to Carry Out MS-DOS Functions

Windows 95 provides a VxD named VWIN32.VXD that supports a set of control codes that Win32-based applications can use to carry out selected MS-DOS system functions. These system-defined control codes consist of the following values. 


Control code (value) 



Meaning 

VWIN32_DIOC_DOS_DRIVEINFO (6) 



Performs Interrupt 21h Function 730X commands. This value is supported in Windows 95 OEM Service Release 2 and later. 

VWIN32_DIOC_DOS_INT13 (4) 
Performs Interrupt 13h commands 


VWIN32_DIOC_DOS_INT25 (2) 
Performs the Absolute Disk Read command (Interrupt 25h) 


VWIN32_DIOC_DOS_INT26 (3) 
Performs the Absolute Disk Write command (Interrupt 25h) 


VWIN32_DIOC_DOS_IOCTL (1) 
Performs the specified MS-DOS device I/O control function (Interrupt 21h Function 4400h through 4411h) 



When an application calls the DeviceIoControl function with the dwIoControlCode parameter set to one of the predefined control codes, the lpvInBuffer and lpvOutBuffer parameters must specify the addresses of DIOC_REGISTERS structures. The DIOC_REGISTERS structure specified by lpvInBuffer contains a set of register values that specify a command for the VxD to execute and any data that the VxD needs to execute the command. After completing the command, the VxD fills the DIOC_REGISTERS structure specified by lpvOutBuffer with the register values that resulted from executing the command. The meaning of the register values depends on the specified command. Many of the MS-DOS and BIOS functions require segment:offset register pairs for pointers. However, because 32-bit code does not have segments, the DIOC_REGISTERS structure does not contain members for segment registers. Place the full pointer that would go into a real-mode segment:offset register pair into the structure member that corresponds to the offset of the register pair. For example, use the reg_EDI member for the pointer that would go into the ES:DI registers. When an application uses the DeviceIoControl function to send commands to a VxD other than VWIN32.VXD, the meaning of the function's parameters are defined by the VxD. The system does not validate the parameters. The system VxD, VWIN32.VXD, supports the IOCTL functions originally provided by MS-DOS Interrupt 21h. The following example shows how to call Get Media ID (Interrupt 21h Function 440Dh Minor Code 66h) from a Win32-based application. 

#define VWIN32_DIOC_DOS_IOCTL 1

typedef struct _DIOC_REGISTERS {
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
} DIOC_REGISTERS, *PDIOC_REGISTERS;

// Important: All MS_DOS data structures must be packed on a 
// one-byte boundary. 

#pragma pack(1) 
typedef struct _MID {
    WORD  midInfoLevel;
    DWORD midSerialNum;
    BYTE  midVolLabel[11];
    BYTE  midFileSysType[8];
} MID, *PMID;
#pragma pack()

HANDLE hDevice;
DIOC_REGISTERS reg;
MID mid;
BOOL fResult;
DWORD cb;
int nDrive = 3;  // Drive C:

hDevice = CreateFile("\\\\.\\vwin32",
    0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);

reg.reg_EAX = 0x440D;       // IOCTL for block devices 
reg.reg_EBX = nDrive;       // zero-based drive identifier 
reg.reg_ECX = 0x4866;       // Get Media ID command 
reg.reg_EDX = (DWORD) &mid; // receives media identifier information 
reg.reg_Flags = 0x0001;     // assume error (carry flag is set) 

fResult = DeviceIoControl(hDevice, 
    VWIN32_DIOC_DOS_IOCTL,
    &reg, sizeof(reg), 
    &reg, sizeof(reg), 
    &cb, 0);

if (!fResult || (reg.reg_Flags & 0x0001))
    ; // error if carry flag is set 

CloseHandle(hDevice);
 


// lock physical volume
Interrupt 21h Function 440Dh Minor Code 4Bh

[Windows 95 only.] 

Locks the physical volume. 

mov ax, 440Dh        ; generic IOCTL
mov bh, LockLevel    ; see below
mov bl, DriveNum     ; see below
mov ch, 08h          ; device category (must be 08h)
mov cl, 4Bh          ; Lock Physical Volume
mov dx, Permissions  ; see below
int 21h

jc error





Parameters

LockLevel 

Level of the lock. This parameter must be either 0, 1, 2, or 3. 

DriveNum 

Drive to lock. This parameter must be one of these values (same device unit numbers as for Interrupt 13h): 


00 - 7Fh 



Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on). 

80 - FFh 



Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on). 



Permissions 

Operations that the system permits while the volume is locked. This parameter is specified only when a level 1 lock is obtained or when a level 0 lock is obtained for the second time for formatting the volume. For other lock levels, this parameter is zero. When a level 1 lock is obtained, bits 0 and 1 of this parameter specify whether the system permits write operations, new file mappings, or both by other processes during a level 1 lock as well as during level 2 and 3 locks. If this parameter specifies that write operations, new file mappings, or both are failed, these operations are failed during level 1, 2, and 3 locks. This parameter has the following form: 


Bit 



Meaning 

0 



0 = Write operations are failed (specified when a level 1 lock is obtained). 

0 



1 = Write operations are allowed (specified when a level 1 lock is obtained). 

1 



0 = New file mapping are allowed (specified when a level 1 lock is obtained). 

1 



1 = New file mapping are failed (specified when a level 1 lock is obtained). 

2 



1 = The volume is locked for formatting (specified when a level 0 lock is obtained for the second time). 



Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value. 

Remarks

The volume must be locked before the application performs direct disk write operations by using Interrupt 13h, Interrupt 26h, or the Interrupt 21h IOCTL functions. A single physical volume may be divided into more than one logical volume, which is also called a partition. The system automatically takes a logical volume lock on all logical volumes on the specified physical drive. If the application performs disk writes only to a logical drive, Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah) is used instead of this function. Unlock Physical Volume (Interrupt 21h Function 440Dh Minor Code 6Bh) should be called to release the lock. 

//unlock
Int 21h Function 440Dh Minor Code 6Bh (FAT32) 

[Windows 95 only.] 

Unlocks the physical volume or decrements the lock level. 

mov ax, 440Dh      ; generic IOCTL
mov bl, DriveNum   ; see below
mov ch, DeviceCat  ; see below
mov cl, 6Bh        ; Unlock Physical Volume
int 21h
 
jc error_handler





Parameters

DriveNum 

Drive to unlock. This parameter must be one of these values (same device unit numbers as for Interrupt 13h): 


00 - 7Fh 



Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on). 

80 - FFh 



Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on). 



DeviceCat 

Specifies a FAT16, FAT12 or FAT32 drive. 


08h 



FAT32, FAT16, or FAT12 drive. 

48h 



FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later. 



Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails. 

Return Values

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value. 

Remarks

This function is used to release the lock obtained by using Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh (FAT32)). Only the lock owner can release the lock on a volume. 

To release the lock on the volume, an application must call Unlock Physical Volume the same number of times that Lock Physical Volume was called. 