Разработка драйвера, распознающего USB-устройство как виртуальный COM-порт в системе Windows NT

Архитектура ввода/вывода Windows NT. Внутренняя организация шины USB. Сущностная характеристика драйверной модели WDM. Точки входа разрабатываемого драйвера, размещение кода в памяти, установка драйвера в системе. Реализация кода драйвера на языке C.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 27.09.2014
Размер файла 1,2 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

}

if (NT_SUCCESS (status))

{ // Если возврат пакета удачен, тов первую очередь установим состояние в Started.

SET_NEW_PNP_STATE(deviceExtension, Started);

}

Irp->IoStatus.Status = status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

// Удаление устройства

case IRP_MN_REMOVE_DEVICE:

// Ждем завершения всех ставшихся запросов

IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);

IoSkipCurrentIrpStackLocation(Irp);

status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);

SET_NEW_PNP_STATE(deviceExtension, Deleted);

// Удаление объекта устройства

IoDetachDevice(deviceExtension->NextLowerDriver);

IoDeleteDevice(DeviceObject);

return status;

// Остановка устройства для обновления состояния ресурсов

case IRP_MN_QUERY_STOP_DEVICE:

SET_NEW_PNP_STATE(deviceExtension, StopPending);

status = STATUS_SUCCESS;

break;

// Отмена останова устройства

case IRP_MN_CANCEL_STOP_DEVICE:

if (StopPending == deviceExtension->DevicePnPState)

{

// мы получили стоповую последовательность, восстанавление предыдущего состояния

RESTORE_PREVIOUS_PNP_STATE(deviceExtension);

}

// Этот пакет обязательно должен быть обработан.

status = STATUS_SUCCESS;

break;

case IRP_MN_STOP_DEVICE:

SET_NEW_PNP_STATE(deviceExtension, Stopped);

status = STATUS_SUCCESS;

break;

// Останов устройства

case IRP_MN_QUERY_REMOVE_DEVICE:

SET_NEW_PNP_STATE(deviceExtension, RemovePending);

status = STATUS_SUCCESS;

break;

// Сообщаем драйверу что устройство более не доступно для I/O

case IRP_MN_SURPRISE_REMOVAL:

SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending);

status = STATUS_SUCCESS;

break;

// Устройство не будет удалено

case IRP_MN_CANCEL_REMOVE_DEVICE:

if (RemovePending == deviceExtension->DevicePnPState)

{

//При получении стоповой последовательности проводим восстановление предыдущего состояния.

RESTORE_PREVIOUS_PNP_STATE(deviceExtension);

}

status = STATUS_SUCCESS;

break;

// Сообщение драйверу о специальноых данных(страницы, дампы, и т.д.)

case IRP_MN_DEVICE_USAGE_NOTIFICATION:

// Если над нами нет других драйверов, просто флаг страничной передачи.

if ((DeviceObject->AttachedDevice == NULL) ||

(DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {

DeviceObject->Flags |= DO_POWER_PAGABLE;

}

// Копируем текущую очередь ниже и завершаем запрос

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(

Irp,

FilterDeviceUsageNotificationCompletionRoutine,

NULL,

TRUE,

TRUE,

TRUE

);

return IoCallDriver(deviceExtension->NextLowerDriver, Irp);

default:

// если мы не обрабатываем никакой IRP пакет, то оставляем текущий статус неизменным

status = Irp->IoStatus.Status;

break;

}

// Отправляем пакет IRP вниз и забываем про него.

Irp->IoStatus.Status = status;

// Модифицируем текущий указатель на IRP пакет

IoSkipCurrentIrpStackLocation (Irp);

// Вызываем нижестоящий драйвер

status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

NTSTATUS

FilterStartCompletionRoutine(

__in PDEVICE_OBJECT DeviceObject,

__in PIRP Irp,

__in PVOID Context

)

/*++

Функция завершения для нижестоящих объектов устройств

к которым прикреплен наш объект фильтр-драйвера

--*/

{

PKEVENT event = (PKEVENT)Context;

UNREFERENCED_PARAMETER (DeviceObject);

// Если нижний драйвер не вернул STATUS_PENDING, нам не нужно ждать появления нового события. Это позволяет избежать захвата блокировки диспетчера.

if (Irp->PendingReturned == TRUE) {

KeSetEvent (event, IO_NO_INCREMENT, FALSE);

}

// Процедура отправки обязана вызвать IoCompleteRequest

return STATUS_MORE_PROCESSING_REQUIRED;

}

NTSTATUS

FilterDeviceUsageNotificationCompletionRoutine(

__in PDEVICE_OBJECT DeviceObject,

__in PIRP Irp,

__in PVOID Context

)

/*++

Функция обработки специальных данных

--*/

{

PDEVICE_EXTENSION deviceExtension;

UNREFERENCED_PARAMETER(Context);

deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

if (Irp->PendingReturned) {

IoMarkIrpPending(Irp);

}

// При отправке выше страница очищается

if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {

DeviceObject->Flags &= ~DO_POWER_PAGABLE;

}

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return STATUS_CONTINUE_COMPLETION;

}

NTSTATUS

FilterDispatchPower(

__in PDEVICE_OBJECT DeviceObject,

__in PIRP Irp

)

/*++

Функция обработки power IRP пакетов.

--*/

{

PDEVICE_EXTENSION deviceExtension;

NTSTATUS status;

deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);

if (!NT_SUCCESS (status)) {

Irp->IoStatus.Status = status;

PoStartNextPowerIrp(Irp);

IoCompleteRequest (Irp, IO_NO_INCREMENT);

return status;

}

/*++

Подготовка передачи нижестоящему драйверу расположение пакета в стеке и вызов нижестоящего драйвера физического устройства--*/

PoStartNextPowerIrp(Irp);

IoSkipCurrentIrpStackLocation(Irp);

status = PoCallDriver(deviceExtension->NextLowerDriver, Irp);

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

VOID

FilterUnload(

__in PDRIVER_OBJECT DriverObject

)

/*++

Функция выгружает драйвер, освобождая все занятые рускрсы из DriverEntry

--*/

{

PAGED_CODE ();

// Объекты устройств должны быть в состоянии NULL Все объекты устройств, ассоциируемые с этим драйвером должны быть удалены

ASSERT(DriverObject->DeviceObject == NULL);

// Нельзя выгружаться пока все подконтрольные устройства не удалены из очереди

return;

}

NTSTATUS

FilterDispatchIoXp(

__in PDEVICE_OBJECT DeviceObject,

__in PIRP Irp

)

/*++

Функция обработки поддерживаемых пакетов для Windows XP. Если пакет удовлетворяет условиям, то запрос он будет обработан и завершен, если нет, то отправим его вниз по стеку драйверов.

--*/

{

PDEVICE_EXTENSION deviceExtension;

PURB urb = URB_FROM_IRP(Irp);

NTSTATUS status;

static UCHAR intr_addr;

PAGED_CODE ();

deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);

// Проверка подключения устройства

if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

return status;

}

// Получение адреса канала прерывания

if( URB_FUNCTION_SELECT_CONFIGURATION==urb->UrbHeader.Function ) {

USB_CONFIGURATION_DESCRIPTOR *pdsc;

UCHAR *ptr;

UCHAR *pend;

pdsc = urb->UrbSelectConfiguration.ConfigurationDescriptor;

ptr = (UCHAR *)pdsc;

for( pend=ptr+pdsc->wTotalLength,ptr+=*ptr; ptr<pend; ptr+=*ptr ) {

if( *(ptr+1)==USB_ENDPOINT_DESCRIPTOR_TYPE && *(ptr+3)==USB_ENDPOINT_TYPE_INTERRUPT ) {

intr_addr = *(ptr+2);

break;

}

}

}

// Игнорировать неиспользуемые запросы прерываний

if( URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER==urb->UrbHeader.Function &&

*((UCHAR *)urb->UrbBulkOrInterruptTransfer.PipeHandle+6)==intr_addr ) {

IoSkipCurrentIrpStackLocation (Irp);

Irp->IoStatus.Status = status = STATUS_INTERNAL_ERROR;

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

IoSkipCurrentIrpStackLocation (Irp);

status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

NTSTATUS

FilterDispatchIoVista(

__in PDEVICE_OBJECT DeviceObject,

__in PIRP Irp

)

/*++

Функция обработки поддерживаемых пакетов для Windows Vista - 7.Если пакет удовлетворяет условиям, то запрос он будет обработан и завершен, если нет, то отправим его вниз по стеку драйверов.

--*/

{

PDEVICE_EXTENSION deviceExtension;

PURB urb = URB_FROM_IRP(Irp);

NTSTATUS status;

static UCHAR intr_addr;

static BOOLEAN use_bulk;

PAGED_CODE ();

deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);

//Проверка подключения устройства

if (!NT_SUCCESS (status)) {

Irp->IoStatus.Status = status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

return status;

}

// Исправление дескриптора конфигурации

if( URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE==urb->UrbHeader.Function &&

USB_CONFIGURATION_DESCRIPTOR_TYPE==urb->UrbControlDescriptorRequest.DescriptorType ) {

KEVENT event;

KeInitializeEvent(&event, NotificationEvent, FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(Irp,

(PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine,

&event,

TRUE,

TRUE,

TRUE

);

status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);

if (status == STATUS_PENDING) {

KeWaitForSingleObject(&event,

Executive, // Ожидать событие

KernelMode, // обязательно находиться в режиме ядра для предотвращения выхода стека за пределы страницы

FALSE,

NULL

);

status = Irp->IoStatus.Status;

}

if( NT_SUCCESS(status) &&

urb->UrbControlDescriptorRequest.TransferBuffer!=NULL &&

urb->UrbControlDescriptorRequest.TransferBufferLength<256 ) {

UCHAR *pdsc, *ptr, *pend, *p0, *p1, buf[256];

ULONG len;

// Заменяем классы дескрипторов для интерфейса данных/коммуникации

pdsc = urb->UrbControlDescriptorRequest.TransferBuffer;

len = urb->UrbControlDescriptorRequest.TransferBufferLength;

memcpy( buf, pdsc, len );

p0 = NULL;

p1 = NULL;

for( ptr=buf,pend=ptr+len; ptr<pend; ptr+=*ptr ) {

if( *(ptr+1)==USB_INTERFACE_DESCRIPTOR_TYPE ) {

if( *(ptr+5)==2 ) // Калсс коммуникации

p0 = ptr;

else if( *(ptr+5)==10 ) // Класс данных

p1 = ptr;

if( p0!=NULL && p1!=NULL && p0<p1 ) {

memcpy( pdsc+(p0-buf), p1, len-(p1-buf) );

memcpy( pdsc+(len-(p1-p0)), p0, p1-p0 );

break;

}

}

}

}

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

#define MAX_NUMBER_OF_ENDPOINTS 8

// Установить канал массива как прерывание

if( URB_FUNCTION_SELECT_CONFIGURATION==urb->UrbHeader.Function ) {

USB_CONFIGURATION_DESCRIPTOR *pdsc;

UCHAR *ptr;

UCHAR *pend;

int i, j, bulk_count = 0;

UCHAR bulk_addr[MAX_NUMBER_OF_ENDPOINTS];

// Присваиваем переменной конфигурацию дескриптора

pdsc = urb->UrbSelectConfiguration.ConfigurationDescriptor;

// Проверка ключа в регистре

use_bulk = RtlCheckRegistryKey(RTL_REGISTRY_SERVICES,USE_BULK)==STATUS_SUCCESS;

// Собственно замена канала массива на прерывание

ptr = (UCHAR *)pdsc;

for( pend=ptr+pdsc->wTotalLength,ptr+=*ptr; ptr<pend; ptr+=*ptr ) {

if( *(ptr+1)==USB_ENDPOINT_DESCRIPTOR_TYPE ) {

if( *(ptr+3)==USB_ENDPOINT_TYPE_BULK ) {

*(ptr+3) = USB_ENDPOINT_TYPE_INTERRUPT;

if( !use_bulk ) {

if( *(ptr+4)<8 )

*(ptr+4) = 8;

}

*(ptr+6) = 10;

if( bulk_count<MAX_NUMBER_OF_ENDPOINTS )

bulk_addr[bulk_count++] = *(ptr+2);

}

else if( *(ptr+3)==USB_ENDPOINT_TYPE_INTERRUPT )

intr_addr = *(ptr+2);

}

}

// Модифицируем текущий указатель на IRP пакет

IoSkipCurrentIrpStackLocation (Irp);

// Вызываем нижестоящий драйвер

status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);

if( NT_SUCCESS(status) && bulk_count ) {

USBD_INTERFACE_INFORMATION *interface_info;

interface_info = (USBD_INTERFACE_INFORMATION *)&urb

->UrbSelectConfiguration.Interface;

if( interface_info!=NULL ) {

for( i=0; i<(int)interface_info->NumberOfPipes; i++ ) {

USBD_PIPE_INFORMATION *pipe_info = &interface_info->Pipes[i];

// Извлекаем перемещенные конечные точки

if( pipe_info!=NULL ) {

for( j=0; j<bulk_count; j++ ) {

if( pipe_info->EndpointAddress==bulk_addr[j] ) {

if(pipe_info->PipeHandle!=NULL) {

if( use_bulk ) {

UCHAR *ph = (UCHAR *)pipe_info->PipeHandle;

if( *(ph+7)==UsbdPipeTypeInterrupt ) {

*(ph+7) = UsbdPipeTypeBulk;

*(ph+10) = 0;

}

}

pipe_info->PipeType = UsbdPipeTypeBulk;

pipe_info->Interval = 0;

}

break;

}

}

}

}

}

}

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

// Игнорировать неиспользуемые запросы прерываний

if( URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER==urb->UrbHeader.Function &&

*((UCHAR *)urb->UrbBulkOrInterruptTransfer.PipeHandle+6)==intr_addr ) {

IoSkipCurrentIrpStackLocation (Irp);

Irp->IoStatus.Status = status = STATUS_INTERNAL_ERROR;

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

// Модифицируем текущий указатель на IRP пакет

IoSkipCurrentIrpStackLocation (Irp);

// Вызываем нижестоящий драйвер

status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return status;

}

Заключение

В ходе проектирования драйвера были выполнены задачи подключения и отключения USB-устройства в системе в общей устройств Windows. Реализованы алгоритмы загрузки и выгрузки драйвера с освобождением памяти, основные запросы IRP пакетов, распределение не идентифицированных пакетов нижестоящим драйверам, а также возможность подключения нескольких подобных USB-устройств.

Установка драйвера осуществляется использованием Мастера установки устройств PnP Windows с использованием .inf файла настроек. Для компиляции самого драйвера мной применялся пакет WDK (Windows Driver Kit 7600.1). Отладка драйвера осуществлялась применением средств WDK и Windbg.

Список использованных источников

1. Солдатов В.П. Интерфейсы USB. Практика использования и программирования. -- СПб.: БХВ-Петербург, 2010.--576 с.

2. Комиссарова В. - Программирование драйверов для Windows 2008

3. Агуров, П.В. Интерфейс USB. Практика использования и программирование/ П.В. Агуров. - СПб:БХВ-Петербург, 2011. - 576с.

4. Материалы сайта www.microsoft.com

5. Developing a WDF USB Kernel Mode Driver [электронный ресурс]. - Режим доступа: http://www.codeproject.com/Articles/13620/Developing-a-WDF-USB-Kernel-Mode-Driver-for-the-OS

Размещено на Allbest.ru


Подобные документы

  • Архитектура Windows NT 5. Приоритеты выполнения программного кода. Описание формата MIDI-данных. Установка драйвера в системе. Выбор средств разработки программного обеспечения. Обработка запросов драйверной модели WDM. Использование библиотеки DirectKS.

    курсовая работа [498,8 K], добавлен 24.06.2009

  • Разработка драйвера под Linux, отслеживающего выделение и освобождение процессами виртуальной памяти и выделение физических страниц при страничных отказах. Компиляция драйвера и работа с ним. Экспериментальная проверка работоспособности драйвера.

    курсовая работа [43,5 K], добавлен 18.06.2009

  • Использование драйвера режима ядра и управляющего приложения для создания системных потоков. Имитация обработки данных и организация задержек. Разработка драйвера на языке C++. Конфигурация тестового стенда. Точность изменения задержек и работы таймера.

    курсовая работа [182,4 K], добавлен 24.06.2009

  • Повышение быстродействия операционной системы. Разработка драйверов для средств хранения данных, управление работой устройства командами PnP. Создание, настройка параметров и установка классового драйвера виртуального диска, его структура и свойства.

    курсовая работа [163,2 K], добавлен 18.06.2009

  • Механизмы взаимодействия драйвера режима ядра и пользовательского приложения: многослойная драйверная архитектура, алгоритм сокрытия данных, взаимодействие драйвера и приложения, пользовательский интерфейс программы фильтрации доступа к файлам.

    курсовая работа [1023,3 K], добавлен 23.06.2009

  • Описание принципа работы драйвера. Установка и регистрация драйвера. Назначение и возможности утилиты TestTerminals.exe. Использование редактора форм. Создание форм с помощью редактора задач. Последовательность выполнения операций и обработок данных.

    курсовая работа [843,6 K], добавлен 09.11.2011

  • Разработка драйверов ядра Windows. Драйвер виртуальных устройств Windows - компьютерная программа, с помощью которой другая программа получает доступ к аппаратному обеспечению стандартным образом. Доступ к драйверам из приложений пользовательского режима.

    курсовая работа [436,1 K], добавлен 25.10.2012

  • Зростання ролі світлодіодного освітлення. Застосування надяскравих світлодіодів. Огляд драйверів живлення світлодіодних світильників. Опис роботи мікроконтролера на мікросхемі VIPer17 по схемі функціональній. Схема принципова драйвера білих світлодіодів.

    дипломная работа [2,2 M], добавлен 22.04.2011

  • Инициализация графического драйвера и режима. Функции доступа к видеопамяти. Подключение графической библиотеки. Инициализация графического режима. Включение драйвера, шрифтов в исполняемый файл. Рисование геометрических фигур. Вывод числовой информации.

    лабораторная работа [77,2 K], добавлен 06.07.2009

  • Призначення драйверів та порядок роботи з драйверами в MS-DOS. Розробка драйверів консолі. Структура драйвера та призначення компонентів. Розробка структури алгоритму, програми налагодження драйвера. Опис змінних програми та роботи модулів програми.

    курсовая работа [1,0 M], добавлен 22.06.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.