177 lines
4.2 KiB
C
177 lines
4.2 KiB
C
/*
|
|
*
|
|
* maioctl.c -- Disk-querying IOCTLs for MigApp.
|
|
*
|
|
*/
|
|
|
|
#include "pch.h"
|
|
#include "migappp.h"
|
|
|
|
#ifdef UNICODE
|
|
#error "UNICODE not supported for maioctl.c"
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#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;
|
|
|
|
typedef struct _DEVPARAMS {
|
|
BYTE dpSpecFunc;
|
|
BYTE dpDevType;
|
|
WORD dpDevAttr;
|
|
WORD dpCylinders;
|
|
BYTE dpMediaType;
|
|
BYTE dpBiosParameterBlock[25];
|
|
} DEVPARAMS, *PDEVPARAMS;
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
BOOL
|
|
IsDriveRemoteOrSubstituted(
|
|
UINT nDrive, // 'A'==1, etc.
|
|
BOOL *fRemote,
|
|
BOOL *fSubstituted)
|
|
{
|
|
DEVIOCTL_REGISTERS reg;
|
|
MID mid;
|
|
|
|
reg.reg_EAX = 0x4409; /* "Check if block device remote" */
|
|
reg.reg_EBX = nDrive; /* zero-based drive ID */
|
|
reg.reg_ECX = 0; /* Believe this is no-care */
|
|
reg.reg_EDX = (DWORD) ∣ /* Believe this is no-care */
|
|
|
|
if (!DoIOCTL(®)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (reg.reg_Flags & 0x8000) /* error if carry flag set */ {
|
|
return FALSE;
|
|
}
|
|
|
|
// Check bit 15 for SUBST-ness
|
|
*fSubstituted = (0 != (reg.reg_EDX & 0x8000));
|
|
|
|
// Check bit 12 for REMOTE-ness
|
|
*fRemote = (0 != (reg.reg_EDX & 0x1000));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL GetMediaID(
|
|
PMID pmid,
|
|
UINT nDrive) // 'A'==1, etc.
|
|
{
|
|
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
|
|
IsFloppyDrive(
|
|
UINT nDrive) // 'A'==1, etc.
|
|
{
|
|
DEVIOCTL_REGISTERS reg;
|
|
DEVPARAMS devparams;
|
|
DWORD driveType;
|
|
TCHAR szDriveRoot[] = TEXT("A:\\");
|
|
|
|
*szDriveRoot += (TCHAR)(nDrive - 1);
|
|
driveType = GetDriveType(szDriveRoot);
|
|
if (driveType != DRIVE_REMOVABLE) {
|
|
return FALSE;
|
|
}
|
|
|
|
reg.reg_EAX = 0x440d; /* Generic IOctl */
|
|
reg.reg_EBX = nDrive; /* zero-based drive ID */
|
|
reg.reg_ECX = 0x0860; /* device category (must be 08h) and "Get Device Parameters" */
|
|
reg.reg_EDX = (DWORD)&devparams; /* offset of Device Parameters Structure */
|
|
devparams.dpSpecFunc = 0; /* request default information */
|
|
|
|
if (!DoIOCTL(®) || (reg.reg_Flags & 0x8000)) {
|
|
return FALSE;
|
|
}
|
|
|
|
switch (devparams.dpDevType) {
|
|
case (0x00): // 320/360KB
|
|
case (0x01): // 1.2MB
|
|
case (0x02): // 720KB
|
|
case (0x03): // 8-inch, single-density
|
|
case (0x04): // 8-inch, single-density
|
|
return TRUE;
|
|
case (0x05): // Hard disk
|
|
case (0x06): // Tape drive
|
|
return FALSE;
|
|
case (0x07): // 1.44MB
|
|
return TRUE;
|
|
case (0x08): // Read/Write optical
|
|
return FALSE;
|
|
case (0x09): // 2.88MB
|
|
return TRUE;
|
|
default: // other
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|