Calling DeviceIoControl on Windows 95/98 An application running on Windows 95/98 can use the DeviceIoControl function to send control codes directly to a virtual device driver (VxD). Any VxD can support any number of control codes, or none at all. The system VxD, VWIN32.VXD, supports the input and output control (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
reg.reg_EAX = 0x440D; // IOCTL for block devices reg.reg_EBX = nDrive; // zero-based drive ID reg.reg_ECX = 0x0866; // Get Media ID command reg.reg_EDX = (DWORD) pmid; // receives media ID info
if (!DoIOCTL(®)) return FALSE;
if (reg.reg_Flags & 0x8000) // error if carry flag set return FALSE;
if (bytesReturned != sizeof(deviceInfo)) return FALSE;
// Put values into the passed pointers
*diskNumberPtr = deviceInfo.DeviceNumber; *partitionNumberPtr = deviceInfo.PartitionNumber; char msgbuf[128]; sprintf(msgbuf,"%d %d\n", deviceInfo.DeviceNumber, deviceInfo.PartitionNumber); AfxMessageBox(msgbuf); // Close the handle to the raw disk and return success
// Open the raw disk char rawDiskName[] = "c:\\windows\\system\\VMM32.VXD"; AfxMessageBox(rawDiskName); fileHandle = CreateFile(rawDiskName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { AfxMessageBox("文件打开失败"); return FALSE; } // Get disk and partition number information using a device control // request
if (!DeviceIoControl(fileHandle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &deviceInfo, sizeof(deviceInfo), &bytesReturned, NULL)) { AfxMessageBox("建立控制失败"); return FALSE; } if (bytesReturned != sizeof(deviceInfo)) return FALSE;
// Put values into the passed pointers
*diskNumberPtr = deviceInfo.DeviceNumber; *partitionNumberPtr = deviceInfo.PartitionNumber; char msgbuf[128]; sprintf(msgbuf,"%d %d\n", *diskNumberPtr, *partitionNumberPtr); AfxMessageBox(msgbuf); // Close the handle to the raw disk and return success
可我明明看到过MSDN上有这么用的例子啊。
An application running on Windows 95/98 can use the DeviceIoControl function to send control codes directly to a virtual device driver (VxD). Any VxD can support any number of control codes, or none at all. The system VxD, VWIN32.VXD, supports the input and output control (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 _DEVIOCTL_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DEVIOCTL_REGISTERS, *PDEVIOCTL_REGISTERS;
typedef struct _MID
{
WORD midInfoLevel;
DWORD midSerialNum;
BYTE midVolLabel[11];
BYTE midFileSysType[8];
} MID, *PMID;
BOOL GetMediaID(PMID pmid, UINT nDrive)
{
DEVIOCTL_REGISTERS reg;
reg.reg_EAX = 0x440D; // IOCTL for block devices
reg.reg_EBX = nDrive; // zero-based drive ID
reg.reg_ECX = 0x0866; // Get Media ID command
reg.reg_EDX = (DWORD) pmid; // receives media ID info
if (!DoIOCTL(®))
return FALSE;
if (reg.reg_Flags & 0x8000) // error if carry flag set
return FALSE;
return TRUE;
}
BOOL DoIOCTL(PDEVIOCTL_REGISTERS preg)
{
HANDLE hDevice;
BOOL fResult;
DWORD cb;
preg->reg_Flags = 0x8000; // assume error (carry flag set)
hDevice = CreateFile("\\\\.\\vwin32",
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
if (hDevice == (HANDLE) INVALID_HANDLE_VALUE)
return FALSE;
else
{
fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0);
if (!fResult)
return FALSE;
}
CloseHandle(hDevice);
return TRUE;
}
STORAGE_DEVICE_NUMBER deviceInfo;
DWORD bytesReturned;
char rawDiskName[] = "\\\\.\\C:";
// Open the raw disk
rawDiskName[4] = driveLetter;
fileHandle = CreateFile(rawDiskName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(fileHandle);
if (fileHandle == INVALID_HANDLE_VALUE) return FALSE;
// Get disk and partition number information using a device control
// request
if (!DeviceIoControl(fileHandle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
0, &deviceInfo, sizeof(deviceInfo), &bytesReturned,
NULL))
return FALSE;
if (bytesReturned != sizeof(deviceInfo))
return FALSE;
// Put values into the passed pointers
*diskNumberPtr = deviceInfo.DeviceNumber;
*partitionNumberPtr = deviceInfo.PartitionNumber;
char msgbuf[128];
sprintf(msgbuf,"%d %d\n", deviceInfo.DeviceNumber, deviceInfo.PartitionNumber);
AfxMessageBox(msgbuf);
// Close the handle to the raw disk and return success
CloseHandle(fileHandle);
return TRUE; 这段程序运行时总是出错
HANDLE fileHandle;
STORAGE_DEVICE_NUMBER deviceInfo;
DWORD bytesReturned;
// Open the raw disk
char rawDiskName[] = "c:\\windows\\system\\VMM32.VXD";
AfxMessageBox(rawDiskName);
fileHandle = CreateFile(rawDiskName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle == INVALID_HANDLE_VALUE)
{
AfxMessageBox("文件打开失败");
return FALSE;
}
// Get disk and partition number information using a device control
// request
if (!DeviceIoControl(fileHandle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
0, &deviceInfo, sizeof(deviceInfo), &bytesReturned,
NULL))
{
AfxMessageBox("建立控制失败");
return FALSE;
}
if (bytesReturned != sizeof(deviceInfo))
return FALSE;
// Put values into the passed pointers
*diskNumberPtr = deviceInfo.DeviceNumber;
*partitionNumberPtr = deviceInfo.PartitionNumber;
char msgbuf[128];
sprintf(msgbuf,"%d %d\n", *diskNumberPtr, *partitionNumberPtr);
AfxMessageBox(msgbuf);
// Close the handle to the raw disk and return success
CloseHandle(fileHandle);
return TRUE;
}
是获得磁盘的句柄吗?
GetVolumeInformation
int track, int numsec)
{// getting logical sector from absolute
// head/track/sector ...
int LogicalSector = (sector-1) +
(head*SECTORSPERTRACK) +
(track*SECTORSPERTRACK*NUMOFHEADS) ;// DIOC_REGISTER structure stores the contents
// of the registers
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 ;
// char *buffer , errah[10], erral[10] ;
char *buffer ;
HANDLE hDevice ;
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd ...win 95/98!hDevice = CreateFile ( "\\\\.\\vwin32",
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );// ---------------------------------------------------------
// CODE TO ACCESS DISK SECTORS ( ABSOLUTE DISK READ ) THRU
// INT 25 for int 25 sector read
// ==> AL must contain the logical drive number ( 0 for
// floppy drive A: )
// ==> CX must contain the number of sectors to read
// ==> DX must contain the starting logical sector number
// to read
// ==> BX must point to the data buffer to store data
// ---------------------------------------------------------
reg.reg_EAX = 0 ;
reg.reg_ECX = 1 ;buffer = (char*) malloc ( 512 * numsec ) ;
strset ( buffer , ' ' );
for ( int i = 0; i < numsec; i++ )
{ reg.reg_EDX = LogicalSector + i ;
reg.reg_EBX = (DWORD)( buffer + i*512 );// try atleast 3 times to ensure correct read/write
// 2 is the control code for absolute disk read fResult = DeviceIoControl (hDevice,
2,
& reg,
sizeof (reg),
& reg,
sizeof (reg),
&cb,
0 ) ;
fResult = DeviceIoControl (hDevice,
2,
& reg,
sizeof (reg),
& reg,
sizeof (reg),
&cb, 0 ) ;
fResult = DeviceIoControl (hDevice,
2,
& reg,
sizeof (reg),
& reg,
sizeof (reg),
&cb,
0 ) ;
if (!fResult || (reg.reg_Flags & 0x0001))
{
/*MessageBox ( "Error doing DeviceIoControl () !" ) ;
int a, b ;
a = reg.reg_EAX ; // ah ;- error code al ;-
// bios error code
b = reg.reg_EAX ;
a &= 255 ;
b >>= 8 ;
itoa ( a , erral , 10 ) ;
itoa ( b , errah , 10 ) ;
//MessageBox ( errah , "Error cOdE AH " ) ;
//MessageBox ( erral , "Error cODe AL " ) ;
return NULL ; */
}
}CloseHandle(hDevice);
return buffer ;
}
VWIN32_DIOC_DOS_IOCTL (1) Interrupt 21h Function 4400h through 4411h
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_INT13 (4) Performs Interrupt 13h commands
VWIN32_DIOC_DOS_DRIVEINFO (6) Performs Interrupt 21h Function 730X commands lpvInBuffer和lpvOutBuffer参数必须指向DIOC_REGISTERS结构的地址。