Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование для 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 можно задать один из следующих кодов операции:

 Код операции

 Описание

 FSCTL_DISMOUNT_VOLUME

 Размонтирование тома

 FSCTL_GET_COMPRESSION

 Определение состояния компрессии для каталога или файла

 FSCTL_LOCK_VOLUME

 Блокирование тома

 FSCTL_SET_COMPRESSION

 Установка состояния компрессии для каталога или файла

 FSCTL_UNLOCK_VOLUME

 Разблокирование тома

 IOCTL_DISK_CHECK_VERIFY

 Проверка замены носителя данных для устройства со сменным носителем

 IOCTL_DISK_EJECT_MEDIA

 Извлечение носителя данных из устройства с интерфейсом SCSI

 IOCTL_DISK_FORMAT_TRACKS

 Форматирование нескольких дорожек диска

 IOCTL_DISK_GET_DRIVE_GEOMETRY

 Получение информации о физической геометрии диска

 IOCTL_DISK_GET_DRIVE_LAYOUT

 Получение информации о всех разделах диска

 IOCTL_DISK_GET_MEDIA_TYPES

 Получение информации о среде, которую можно использовать для хранения данных в устройстве

 IOCTL_DISK_GET_PARTITION_INFO

 Полечение информации о разделе диска

 IOCTL_DISK_LOAD_MEDIA

 Загрузка носителя данных в устройство

 IOCTL_DISK_MEDIA_REMOVAL

 Включение или отключение механизма извлечения носителя данных

 IOCTL_DISK_PERFORMANCE

 Получение информации о производительности устройства

 IOCTL_DISK_REASSIGN_BLOCKS

 Перевод блоков диска в область резервных блоков

 IOCTL_DISK_SET_DRIVE_LAYOUT

 Создание разделов на диске

 IOCTL_DISK_SET_PARTITION_INFO

 Установка типа разделов диска

 IOCTL_DISK_VERIFY

 Выполнение логического форматирования

 IOCTL_SERIAL_LSRMST_INSERT

 Разрешение или запрещение добавления информации о состоянии линии и модема в поток передаваемых данных

Через параметр lpInBuffer вы должны передать функции DeviceIoControl адрес управляющего блока, необходимого для выполнения опрации. Формат этого блока зависит от кода выполняемой операции. В документации SDK приведены форматы управляющих блоков для всех перечисленных выше кодов операций.

В буфер, адрес которого передается через параметр lpOutBuffer, будет записан результат выполнения операции. Формат этого буфера также зависит от кода операции.

При необходимости с помощью функции DeviceIoControl вы можете выполнять асинхронные операции, подготовив структуру типа OVERLAPPED XE "OVERLAPPED" и передав ее адрес через параметр lpOverlapped. Не забудьте также при открывании устройства указать функции CreateFile XE "CreateFile" флаг FILE_FLAG_OVERLAPPED XE "FILE_FLAG_OVERLAPPED" .

[Назад] [Содеожание] [Дальше]