Программирование для Windows NT© Александр Фролов, Григорий ФроловТом 26, часть 1, М.: Диалог-МИФИ, 1996, 272 стр. Прямое управление дисковым устройствомНесмотря на то что набор функций, предназначенных для работы с дисками и файлами в среде Microsoft Windows NT, достаточно мощный и удобный, иногда его возможностей может оказаться недостаточно. Например, если вы разрабатываете систему защиты от несанкционированного копирования дискет, вам могут потребоваться средства нестандартного форматирования дискет. Вам также может потребоваться выполнять из приложения извлечение сменного носителя данных или блокировку последнего в накопителе, проверку замены сменного носителя данных или другие “необычные” операции. Создавая аналогичную програму MS-DOS, вы можете выполнить нестандартное форматиование, например, с помощью функций BIOS XE "BIOS" или обращаясь непосредственно к портам дискового контроллера. В среде Microsoft Windows NT оба эти способа непригодны, так как функции BIOS и порты контроллера диска недоступны для обычных приложений, работающих в защищенном режиме. Выход, однако, есть. Он заключается в прямом обращении к драйверу дискового устройства с помощью функции управления вводом/выводом, которая называется DeviceIoControl XE "DeviceIoControl" . По своим возможностям он напоминает способ, описанный нами в 19 томе “Библиотеки системного программиста” и связанный с использованием функций GENERIC IOCTL XE "GENERIC IOCTL" . Прототип функции DeviceIoControl мы привели ниже: BOOL DeviceIoControl( HANDLE hDevice, // идентификатор устройства DWORD dwIoControlCode, // код выполняемой операции LPVOID lpInBuffer, // буфер для входных данных DWORD nInBufferSize, // размер буфера lpInBuffer LPVOID lpOutBuffer, // буфер для выходных данных DWORD nOutBufferSize, // размер буфера lpOutBuffer LPDWORD lpBytesReturned, // указатель на счетчик // выведенных байт LPOVERLAPPED lpOverlapped); // указатель на // структуру OVERLAPPED Через параметр hDevice вы должны передать идентификатор устройства, полученный от функции CreateFile. Для того чтобы воспользоваться этой функцией для открывания устройства, вы должны указать имя устройства следующим образом (пример приведен для диска C:): hDevice = CreateFile("\\\\.\\C:", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); С помощью параметра dwIoControlCode можно задать один из следующих кодов операции:
Через параметр lpInBuffer вы должны передать функции DeviceIoControl адрес управляющего блока, необходимого для выполнения опрации. Формат этого блока зависит от кода выполняемой операции. В документации SDK приведены форматы управляющих блоков для всех перечисленных выше кодов операций. В буфер, адрес которого передается через параметр lpOutBuffer, будет записан результат выполнения операции. Формат этого буфера также зависит от кода операции. При необходимости с помощью функции DeviceIoControl вы можете выполнять асинхронные операции, подготовив структуру типа OVERLAPPED XE "OVERLAPPED" и передав ее адрес через параметр lpOverlapped. Не забудьте также при открывании устройства указать функции CreateFile XE "CreateFile" флаг FILE_FLAG_OVERLAPPED XE "FILE_FLAG_OVERLAPPED" . |