Рабочая процедура выгрузки драйвера
Процедура UnloadRoutine выполняет завершающую работу перед тем как драйвер растворится в небытии.
При следовании WDM модели, драйвер должен был бы зарегистрировать обработчик PnP запросов (то есть IRP_MJ_PNP) и перед вызовом UnloadRoutine получал бы IRP пакеты с кодом IRP_MJ_PNP и суб-кодом IRP_MN_STOP_DEVICE (например, когда пользователь решил отключить устройство, воспользовавшись окном Диспетчера Устройств в Настройках системы). В этом обработчике и следует выполнять действия, предшествующие удалению WDM драйвера. |
// // (Файл init.cpp) // UnloadRoutine: Выгружает драйвер, освобождая оставшиеся объекты // Вызывается системой, когда необходимо выгрузить драйвер. // Как и процедура AddDevice, регистрируется иначе чем // все остальные рабочие процедуры и не получает никаких IRP. // Arguments: указатель на объект драйвера //
#pragma code_seg("PAGE") // Допускает размещение в странично организованной памяти // VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextDevObj; int i;
// Задаем печать отладочных сообщений v если сборка отладочная #if DBG DbgPrint("-Example- In Unload Routine."); #endif //========================================================== // Нижеприведенные операции в полномасштабном WDM драйвере // следовало бы поместить в обработчике IRP_MJ_PNP запросов // с субкодом IRP_MN_REMOVE_DEVICE, но в силу простоты // драйвера, сделаем это здесь. // Проходим по всем объектам устройств, контролируемым // драйвером pNextDevObj = pDriverObject->DeviceObject;
for(i=0; pNextDevObj!=NULL; i++) { PEXAMPLE_DEVICE_EXTENSION dx = (PEXAMPLE_DEVICE_EXTENSION)pNextDevObj->DeviceExtension; // Удаляем символьную ссылку и уничтожаем FDO: UNICODE_STRING *pLinkName = & (dx->ustrSymLinkName); // !!! сохраняем указатель: pNextDevObj = pNextDevObj->NextDevice;
#if DBG DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.", i,dx->fdo); DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer); #endif
IoDeleteSymbolicLink(pLinkName); IoDeleteDevice( dx->fdo); } } #pragma code_seg() // end PAGE section