- Сообщения
- 8,034
- Решения
- 19
- Реакции
- 6,845
DeviceIoControl — это функция в Windows API, которая используется для отправки управляющих команд (IOCTL — Input/Output Control) драйверам устройств. Она предоставляет приложениям возможность взаимодействовать с аппаратным обеспечением или виртуальными устройствами на более низком уровне, чем стандартные операции чтения/записи.
Основная цель функции — выполнять специфические операции, которые не входят в стандартный набор функций ввода/вывода. Например, с её помощью можно:
Применение DeviceIoControl востребовано в задачах системного программирования, разработке драйверов и работе с низкоуровневым оборудованием.
Данные коды объявлены в заголовочном файле winioctl.h
Например:
Если вам нужно узнать результирующее число (например, чтобы использовать в другой среде, не C++), обратимся к объявлению CTL_CODE:
Что соответствует:
Либо можно взять готовые константы по ссылкам:
http://www.ioctls.net/
https://github.com/wine-mirror/wine/blob/master/include/winioctl.h
Наиболее надежным способом является поиск констант и описания в официальной документации Microsoft:
https://github.com/MicrosoftDocs/sdk-api/tree/docs
либо из официального хидера, который можно получить вместе с установкой Visual Studio или пакета WDK.
Установка Visual Studio и создание проекта для общения с драйвером устройства
Чтобы создать программу на языке C/C++ и подключить winioctl.h, можно установить Visual Studio 2022.
Во время установки выбрать дополнительные отдельные компоненты, как:
- Пакет SDK для Windows 11 последней версии
- MSVC 143 библиотеки C++ для VS 2022 с устранением рисков Spectre (последняя версия)
- Windows Driver Kit
Затем Установить по этой инструкции:
- Пакет SDK
- Пакет WDK
Свой проект можно создать, запустив Visual Studio - Создание проекта - тип Driver - выбираем к примеру Empty Desktop Application for Drivers (Universal):
Затем, допустим, пишем такой код:
В нём мы подключили хидеры windows.h и winioctl.h. Код перечисляет все диски, проверяет их тип и выводит стиль разметки: MBR или GPT с помощью запроса DeviceIoControl с кодом IOCTL_DISK_GET_PARTITION_INFO_EX, который возвращает результат в структуру PARTITION_INFORMATION_EX.
Здесь мы не общаемся ни с каким драйвером, однако задачей было показать простейший вызов.
Готовые проекты с примерами непосредственной комуникации с драйверами и исходники самих драйверов можно скачать из репозитория Майкрософт: Driver samples for Windows 11
Основная цель функции — выполнять специфические операции, которые не входят в стандартный набор функций ввода/вывода. Например, с её помощью можно:
- Управлять физическими устройствами (например, дисками, принтерами или сетевыми адаптерами).
- Выполнять диагностику или получать подробную информацию о состоянии устройств.
- Отправлять команды для выполнения уникальных задач, поддерживаемых конкретным драйвером устройства.
Применение DeviceIoControl востребовано в задачах системного программирования, разработке драйверов и работе с низкоуровневым оборудованием.
Данные коды объявлены в заголовочном файле winioctl.h
Например:
Код:
#define FSCTL_FILESYSTEM_GET_STATISTICS CTL_CODE(FILE_DEVICE_FILE_SYSTEM,24,METHOD_BUFFERED,FILE_ANY_ACCESS)
Код:
#define CTL_CODE(DeviceType,Function,Method,Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
Рассчет выглядеть будет так:DeviceType: #define FILE_DEVICE_FILE_SYSTEM 0x00000009
Function: 24 (Passed in as constant)
Method: #define METHOD_BUFFERED 0
Access: #define FILE_ANY_ACCESS 0
Код:
= (9 << 16) | (0 << 14) | (24 << 2) | (0)
= 0x00090060 (в 16-ричном виде), или 589920 (в десятичном виде)
Либо можно взять готовые константы по ссылкам:
http://www.ioctls.net/
https://github.com/wine-mirror/wine/blob/master/include/winioctl.h
Наиболее надежным способом является поиск констант и описания в официальной документации Microsoft:
https://github.com/MicrosoftDocs/sdk-api/tree/docs
либо из официального хидера, который можно получить вместе с установкой Visual Studio или пакета WDK.
Установка Visual Studio и создание проекта для общения с драйвером устройства
Чтобы создать программу на языке C/C++ и подключить winioctl.h, можно установить Visual Studio 2022.
Во время установки выбрать дополнительные отдельные компоненты, как:
- Пакет SDK для Windows 11 последней версии
- MSVC 143 библиотеки C++ для VS 2022 с устранением рисков Spectre (последняя версия)
- Windows Driver Kit
Затем Установить по этой инструкции:
- Пакет SDK
- Пакет WDK
Свой проект можно создать, запустив Visual Studio - Создание проекта - тип Driver - выбираем к примеру Empty Desktop Application for Drivers (Universal):
Затем, допустим, пишем такой код:
C++:
#include <windows.h>
#include "winioctl.h"
#include <iostream>
#include <string>
void CheckPartitionStyle(const std::string& drive)
{
std::string drivePath = "\\\\.\\" + drive;
HANDLE hDevice = CreateFileA(
drivePath.c_str(),
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, OPEN_EXISTING, 0, nullptr
);
if (hDevice == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open drive " << drive << ". Error: " << GetLastError() << std::endl;
return;
}
PARTITION_INFORMATION_EX partitionInfo;
DWORD bytesReturned = 0;
if (DeviceIoControl(
hDevice, IOCTL_DISK_GET_PARTITION_INFO_EX,
nullptr, 0, &partitionInfo, sizeof(partitionInfo), &bytesReturned, nullptr))
{
if (partitionInfo.PartitionStyle == PARTITION_STYLE_MBR) {
std::cout << "Partition Style: MBR" << std::endl;
}
else if (partitionInfo.PartitionStyle == PARTITION_STYLE_GPT) {
std::cout << "Partition Style: GPT" << std::endl;
}
else if (partitionInfo.PartitionStyle == PARTITION_STYLE_RAW) {
std::cout << "Partition Style: RAW" << std::endl;
}
else {
std::cout << "Partition Style: UNKNOWN" << std::endl;
}
}
else {
std::cerr << "Failed to get partition information for " << drive << ". Error: " << GetLastError() << std::endl;
}
CloseHandle(hDevice);
}
int main()
{
char driveLetter = 'A';
for (; driveLetter <= 'Z'; ++driveLetter)
{
std::string drive = std::string(1, driveLetter) + ":";
UINT driveType = GetDriveTypeA(drive.c_str());
if (driveType != DRIVE_UNKNOWN && driveType != DRIVE_NO_ROOT_DIR)
{
std::cout << "Drive: " << drive.c_str() << std::endl;
CheckPartitionStyle(drive);
}
}
system("pause");
return 0;
}
В нём мы подключили хидеры windows.h и winioctl.h. Код перечисляет все диски, проверяет их тип и выводит стиль разметки: MBR или GPT с помощью запроса DeviceIoControl с кодом IOCTL_DISK_GET_PARTITION_INFO_EX, который возвращает результат в структуру PARTITION_INFORMATION_EX.
Здесь мы не общаемся ни с каким драйвером, однако задачей было показать простейший вызов.
Готовые проекты с примерами непосредственной комуникации с драйверами и исходники самих драйверов можно скачать из репозитория Майкрософт: Driver samples for Windows 11
Последнее редактирование: