Программирование драйверов Windows


Исполняемый код драйвера - часть 5


// Создать символьную ссылку: status = IoCreateSymbolicLink( &symLinkName, &devName ); if (!NT_SUCCESS(status)) { // При неудаче - отключаемся от прерывания и // удаляем объект устройства: IoDisconnectInterrupt( pDevExt-&#62pIntObj ); IoDeleteDevice( pDevObj ); return status; } pDevExt-&#62ustrSymLinkName = symLinkName; #if DBG==1 DbgPrint("LPTPORT: Symbolic Link is created: %ws. \n", pDevExt-&#62ustrSymLinkName.Buffer); #endif return STATUS_SUCCESS; } //========================================================================= // Функция: DriverUnload // Назначение: Останавливает и удаляет объекты устройств, отключает // прерывания, подготавливает драйвер к выгрузке. // Аргументы: pDriverObject - поступает от Диспетчера ввода/вывода // Возвращаемое значение: нет // VOID DriverUnload ( IN PDRIVER_OBJECT pDriverObject ) { #if DBG==1 DbgPrint("LPTPORT: in DriverUnload now\n"); #endif PDEVICE_OBJECT pNextObj = pDriverObject-&#62DeviceObject; // Проход по всем устройствам, контролируемым драйвером for( ; pNextObj!=NULL; ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj-&#62DeviceExtension; // Удаляем объект прерываний: if (pDevExt-&#62pIntObj) { // На всякий случай блокируем поступление прерываний WriteControlRegister( pDevExt, CR_DEFAULT); IoDisconnectInterrupt( pDevExt-&#62pIntObj ); } // Удаляем символьную ссылку: IoDeleteSymbolicLink(&pDevExt-&#62ustrSymLinkName); #if DBG==1 DbgPrint("LPTPORT: SymLink %ws deleted\n", pDevExt-&#62ustrSymLinkName.Buffer); #endif // Сообщаем о прекращении использования объекта события if(pDevExt-&#62pEvent!=NULL) { ObDereferenceObject(pDevExt-&#62pEvent); #if DBG==1 DbgPrint("LPTPORT: Event object dereferenced.\n"); #endif } // Сохраняем ссылку на следующее устройство и удаляем // текущий объект устройства: pNextObj = pNextObj-&#62NextDevice; IoDeleteDevice( pDevExt-&#62pDevice ); } // Замечание. Поскольку мы использовали ресурс (параллельный порт) // объявленные не нами, то освобождение этого ресурса можно опустить. } //========================================================================= // Функция: DispatchCreate // Назначение: Обрабатывает запрос по поводу Win32 вызова CreateFile // Аргументы: pDevObj - поступает от Диспетчера ввода/вывода // pIrp - поступает от Диспетчера ввода/вывода // Возвращаемое значение: STATUS_SUCCESS // NTSTATUS DispatchCreate ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) { #if DBG==1 DbgPrint("LPTPORT: in DispatchCreate now\n"); #endif CompleteIrp( pIrp, STATUS_SUCCESS, 0 ); // ничего не передано return STATUS_SUCCESS; } //========================================================================= // Функция: DispatchClose // Назначение: Обрабатывает запрос по поводу Win32 вызова CloseHandle // Аргументы: pDevObj - поступает от Диспетчера ввода/вывода // pIrp - поступает от Диспетчера ввода/вывода // Возвращаемое значение: STATUS_SUCCESS // NTSTATUS DispatchClose ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pDevObj-&#62DeviceExtension; #if DBG==1 DbgPrint("LPTPORT: in DispatchClose now\n"); #endif // Сообщаем о прекращении использования объекта события if(pDevExt-&#62pEvent!=NULL) { // Удаляем объект события, поскольку клиент заканчивает // работу с драйвером и не сможет больше отдать команду // о прекращении работы с событием: #if DBG==1 DbgPrint("LPTPORT: DispatchClose, attempt to close handle %04X.\n", pDevExt-&#62hEvent ); #endif NTSTATUS sts = ZwClose(pDevExt-&#62hEvent); pDevExt-&#62pEvent = NULL; pDevExt-&#62hEvent = NULL; #if DBG==1 DbgPrint("LPTPORT: DispatchClose, event handle closed (status=%0X).\n", sts ); // sts == 0 &#60==&#62 sts == STATUS_SUCCESS #endif } CompleteIrp( pIrp, STATUS_SUCCESS, 0 ); // ничего не передано return STATUS_SUCCESS; } //========================================================================= // Функция: CancelRoutine // Назначение: Вызывается в случае отказа клиента от запроса на обработку // IRP пакета, который был отложен (для работы со StartIo) // Аргументы: pDevObj - поступает от Диспетчера ввода/вывода // pIrp - поступает от Диспетчера ввода/вывода // Возвращаемое значение: нет // VOID CancelRoutine ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pDevObj-&#62DeviceExtension; #if DBG==1 KIRQL currentIrql = KeGetCurrentIrql(); DbgPrint("LPTPORT: in CancelRoutine now, Irql=%d, IRP Canceled.\n", currentIrql ); #endif if(pIrp == pDevObj-&#62CurrentIrp) { IoReleaseCancelSpinLock(pIrp-&#62CancelIrql); CompleteIrp( pIrp, STATUS_CANCELLED, 0 ); //^^^^^^^^^ Что бы ни утверждалось в DDK, с этим // работает лучше! (Иначе - "глючит" Monitor) } else // Пакет - не текущий, удаляем его из системной очереди, { // если он там есть: KeRemoveEntryDeviceQueue( &pDevObj-&#62DeviceQueue, &pIrp-&#62Tail.Overlay.DeviceQueueEntry); IoReleaseCancelSpinLock(pIrp-&#62CancelIrql); CompleteIrp( pIrp, STATUS_CANCELLED, 0 ); } // Во всяком случае, обработка данного пакета завершена if(pDevExt-&#62pEvent!=NULL) { KeSetEvent(pDevExt-&#62pEvent, IO_NO_INCREMENT , FALSE ); } // Не повредит...


Начало  Назад  Вперед