3.4.4 Обработка запросов Plug and Play
При запуске устройства мы получаем IRP пакет с кодом IRP_MN_START_DEVICE:
case IRP_MN_START_DEVICE:
{
KeInitializeEvent( &event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE) RamDskIoCompletionRoutine,
(PVOID) &event, TRUE, TRUE, TRUE );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
}
if ( NT_SUCCESS(status) )
{
// успешно запущен нижний драйвер
devExt->DevState = WORKING;
}
COMPLETE_REQUEST( Irp, status, 0 );
break;
}
Мы пересылаем пакет драйверу, который находится ниже при помощи вызова функции IoCallDriver. Если нижние драйвер находится в состоянии обработки (STATUS_PENDING), то просто усыплем наш драйвер с помощью функции KeWaitForSingleObject и просыпаемся по событию завершения операции нижним драйвером.
При остановке устройства(IRP_MN_STOP_DEVICE), просто пересылаем запрос нижнему драйверу и устанавливаем состояние устройства STOPPED:
case IRP_MN_STOP_DEVICE:
{
devExt->DevState = STOPPED;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation( Irp );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
break;
}
При обработке запросов IRP_MN_SURPRISE_REMOVAL, IRP_MN_QUERY_ REMOVE_DEVICE, IRP_MN_QUERY_STOP_DEVICE, производятся аналогичные действия, с установкой соответствующего статуса:
case IRP_MN_QUERY_STOP_DEVICE:
{
devExt->DevState = PENDINGSTOP;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation( Irp );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
break;
}
case IRP_MN_STOP_DEVICE:
{
devExt->DevState = STOPPED;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation( Irp );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
break;
}
case IRP_MN_QUERY_REMOVE_DEVICE:
{
devExt->DevState = PENDINGREMOVE;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation( Irp );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
break;
}
case IRP_MN_SURPRISE_REMOVAL:
{
devExt->DevState = SURPRISEREMOVED;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation( Irp );
status = IoCallDriver( devExt->LowerDeviceObject, Irp );
break;
}
При удалении устройства IRP_MN_REMOVE_DEVICE, мы вызываем функцию RamDskRemoveDevice, которая освобождает выделенную при инициализации память, символическую ссылку (она будет описана далее):
case IRP_MN_REMOVE_DEVICE:
{
RamDskRemoveDevice( DeviceObject, Irp );
lockHeld = FALSE;
break;
}
- 1. АНАЛИТИЧЕСКИЙ РАЗДЕЛ
- 1.1 Постановка задачи
- 1.2 Архитектура Windows 2000
- 1.3 Многослойная архитектура драйверов
- 1.4 Архитектура драйверов устройств хранения
- 1.5 Выбор файловой системы
- 2. КОНСТРУКТОРСКИЙ РАЗДЕЛ
- 2.1 Структура классового драйвера
- 2.2 Организация внутреннего хранения данных диска
- 2.3 Доступ к передаваемым данным
- 2.4 Обработка запросов Plug and Play
- 2.5 Обработка расширенных запросов
- 3. ТЕХНОЛОГИЧЕСКИЙ РАЗДЕЛ
- 3.1 Выбор и обоснование языка и среды программирования
- 3.2 Структуры данных классового драйвера
- 3.3 Блокировка выгрузки устройства
- 3.4 Процедуры драйвера виртуального диска
- 3.4.1 Инициализация драйвера
- 3.4.2 Обработка запросов записи/чтения
- 3.4.3 Обработка расширенных запросов
- 3.4.4 Обработка запросов Plug and Play
- 3.4.5 Выгрузка драйвера
- 3.5 Программа настройки параметров виртуального диска
- 3.6 Установка драйвера