Device Input and Output Control (IOCTL)
Windows中的DeviceIoControl 函数提供了一个设备输入和输出控制(IOCTL)接口,应用程序可通过该接口与设备驱动程序直接通信。DeviceIoControl 函数是一个通用接口,可以向各种设备发送控制代码。每个控制代码都代表驱动程序要执行的操作。例如,控制代码可以要求设备驱动程序返回相应设备的信息,或指示驱动程序在设备上执行一项操作,如格式化磁盘。
The DeviceIoControl function provides a device input and output control (IOCTL) interface through which an application can communicate directly with a device driver. The DeviceIoControl function is a general-purpose interface that can send control codes to a variety of devices. Each control code represents an operation for the driver to perform. For example, a control code can ask a device driver to return information about the corresponding device, or direct the driver to carry out an action on the device, such as formatting a disk.
直接向指定设备驱动程序发送控制代码,使相应设备执行相应操作。
Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation.
SDK 头文件中定义了许多标准控制代码。此外,设备驱动程序还可以定义自己的特定设备控制代码。有关 SDK 文档中包含的标准控制代码列表,请参阅 DeviceIoControl 的备注部分。
A number of standard control codes are defined in the SDK header files. In addition, device drivers can define their own device-specific control codes. For a list of standard control codes included in the SDK documentation, see the Remarks section of DeviceIoControl.
可以指定的控制代码类型取决于访问的设备和运行应用程序的平台。应用程序可以使用标准控制代码或特定设备控制代码,在软盘驱动器、硬盘驱动器、磁带驱动器或 CD-ROM 驱动器上执行直接输入和输出操作。
The types of control codes you can specify depend on the device being accessed and the platform on which your application is running. Applications can use the standard control codes or device-specific control codes to perform direct input and output operations on a floppy disk drive, hard disk drive, tape drive, or CD-ROM drive.
Calling DeviceIoControl (调用)
下面的示例演示了如何检索系统中第一个物理驱动器的信息。该示例使用 CreateFile 函数检索第一个物理驱动器的设备句柄,然后使用带有 IOCTL_DISK_GET_DRIVE_GEOMETRY 控制代码的 DeviceIoControl 将驱动器的信息填充到 DISK_GEOMETRY 结构中。
The following example demonstrates how to retrieve information about the first physical drive in the system. It uses the CreateFile function to retrieve the device handle to the first physical drive, and then uses DeviceIoControl with the IOCTL_DISK_GET_DRIVE_GEOMETRY control code to fill a DISK_GEOMETRY structure with information about the drive.
C++ Syntax
BOOL DeviceIoControl(
[in] HANDLE hDevice,
[in] DWORD dwIoControlCode,
[in, optional] LPVOID lpInBuffer,
[in] DWORD nInBufferSize,
[out, optional] LPVOID lpOutBuffer,
[in] DWORD nOutBufferSize,
[out, optional] LPDWORD lpBytesReturned,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
C++ Example
#define UNICODE 1
#define _UNICODE 1
/* The code of interest is in the subroutine GetDriveGeometry. The
code in main shows how to interpret the results of the call. */
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#define wszDrive L"\\\\.\\PhysicalDrive0"
BOOL GetDriveGeometry(LPWSTR wszPath, DISK_GEOMETRY *pdg)
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
hDevice = CreateFileW(wszPath, // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform
NULL, 0, // no input buffer
pdg, sizeof(*pdg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
CloseHandle(hDevice);
return (bResult);
}
int wmain(int argc, wchar_t *argv[])
{
DISK_GEOMETRY pdg = { 0 }; // disk drive geometry structure
BOOL bResult = FALSE; // generic results flag
ULONGLONG DiskSize = 0; // size of the drive, in bytes
bResult = GetDriveGeometry (wszDrive, &pdg);
if (bResult)
{
wprintf(L"Drive path = %ws\n", wszDrive);
wprintf(L"Cylinders = %I64d\n", pdg.Cylinders);
wprintf(L"Tracks/cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder);
wprintf(L"Sectors/track = %ld\n", (ULONG) pdg.SectorsPerTrack);
wprintf(L"Bytes/sector = %ld\n", (ULONG) pdg.BytesPerSector);
DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
(ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
wprintf(L"Disk size = %I64d (Bytes)\n"
L" = %.2f (Gb)\n",
DiskSize, (double) DiskSize / (1024 * 1024 * 1024));
}
else
{
wprintf (L"GetDriveGeometry failed. Error %ld.\n", GetLastError ());
}
return ((int)bResult);
}
Linux的IOCTL
在 Linux 中,IOCTL(输入/输出控制)用于用户空间和内核空间之间的通信。它允许用户空间进程向内核中的设备驱动程序发送命令,使其能够对设备执行特定操作或更改设备设置。这种通信对于与硬件设备交互至关重要,例如配置网络接口、控制输入/输出操作以及管理其他与硬件相关的任务。总之,IOCTL 为管理和控制 Linux 操作系统中的各种设备提供了一个标准化接口。
In Linux, IOCTL (input/output control) is used to communicate between user-space and kernel-space. It allows user-space processes to send commands to device drivers in the kernel, enabling them to perform specific operations on devices or change device settings. This communication is essential for interacting with hardware devices, such as configuring network interfaces, controlling input/output operations, and managing other hardware-related tasks. Overall, IOCTL provides a standardized interface for managing and controlling various devices in the Linux operating system.
另外,平时编写代码也是以定义自己的DeviceIoControl函数,用于操作设备对象或底层驱动。
参考:
1,Microsoft
DeviceIoControl function (ioapiset.h) - Win32 apps | Microsoft Learn
Device Input and Output Control (IOCTL) - Win32 apps | Microsoft Learn
Calling DeviceIoControl - Win32 apps | Microsoft Learn
2,Quora Assistant