rihkov 0 December 5, 2012 Posted December 5, 2012 · Report post Подскажите как написать USB драйвер не в стиле WDM (точнее без регистрации процедур IRP_MJ_POWER и IRP_MJ_PNP), как произвести нумерацию и подскажите как вообще делается регистрация конечных точек в драйвере? Quote Share this post Link to post Share on other sites More sharing options...
rihkov 0 December 6, 2012 Posted December 6, 2012 · Report post Помогите написать самый простой USB драйвер с использованием DDK, разобрался в заготовке драйвера из книги Агурова про USB, чуть подправил и написал приложение на Borland C++Builder 6 для работы с этим драйвером, но вот на этом пока что и все, не могу понять как получить контекст USB устройства, и как потом работать с конечными точками. Прошу помощи, и есть ли какая то русскоязычная литература именно по написанию USB драйвера двигаясь от самого простого до сложного? Quote Share this post Link to post Share on other sites More sharing options...
rihkov 0 December 7, 2012 Posted December 7, 2012 · Report post Код драйвера. /*=============================================================================== ===*/ #include <ntddk.h> #include "testdrv.h" //ИМЯ НАШЕГО ДРАЙВЕРА УСТРОЙСТВА #define DEVICE_NAME_STRING L"testdriver" /*=============================================================================== ===*/ //ЗАГОЛОВКИ ФУНКЦИЙ-ОБРАБОТЧИКОВ VOID OnUnloadHandle(IN PDRIVER_OBJECT); NTSTATUS IrpHandler(IN PDEVICE_OBJECT, IN PIRP); NTSTATUS OnDeviceControlHandle(IN PDEVICE_OBJECT, IN PIRP); NTSTATUS OnAddDeviceHandle(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject); /*=============================================================================== ===*/ /*ТОЧКА ВХОДА В ДРАЙВЕР. ВЫПОЛНЯЕТСЯ ПРИ ЗАГРУЗКЕ.*/ void TestDriver(void) { /*======================================================================*/ DbgPrint("TestDriver"); /*======================================================================*/ } /*=============================================================================== ===*/ /*ПРОЦЕДУРА ВХОДА ДРАЙВЕРА. ЭТА ПРОЦЕДУРА ВЫЗЫВАЕТСЯ ТОЛЬКО РАЗ ПОСЛЕ ЗАГРУЗКИ ДРАЙВЕРА В ПАМЯТЬ.*/ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT deviceObject; NTSTATUS status; int i; WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING; WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; UNICODE_STRING uniNameString, uniDOSString; /*======================================================================*/ DbgPrint("DriverEntry"); /*======================================================================*/ //СОЗДАНИЕ БУФЕРОВ ДЛЯ ИМЕН RtlInitUnicodeString(&uniNameString, NameBuffer); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); //ИНИЦИАЛИЗАЦИЯ ОБЪЕКТА ДРАЙВЕРА status = IoCreateDevice(DriverObject, 0, &uniNameString, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject); if(!NT_SUCCESS(status)) return status; //СОЗДАНИЕ СИМВОЛЬНОГО ИМЕНИ ДРАЙВЕРА status = IoCreateSymbolicLink(&uniDOSString, &uniNameString); if(!NT_SUCCESS(status)) return status; //ИНИЦИАЛИЗИРУЕМ ТОЧКИ ВХОДА ДРАЙВЕРА В ОБЪЕКТЕ ДРАЙВЕРА. for (i=0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i]= IrpHandler; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OnDeviceControlHandle; DriverObject->DriverUnload = OnUnloadHandle; DriverObject->DriverExtension->AddDevice = /*(PDRIVER_ADD_DEVICE)*/ OnAddDeviceHandle;/*???*/ return(STATUS_SUCCESS); } /*=============================================================================== ===*/ /*ВЫЗЫВАЕТСЯ ПРИ ВЫЗОВЕ CreateProcess() ИЗ ПОЛЬЗОВАТЕЛЬСКОГО РЕЖИМА РАБОТЫ. АДРЕС ЭТОЙ ПРОЦЕДУРЫ БЫЛ ЗАРЕГИСТРИРОВАН В ПРОЦЕДУРЕ DriverEntry, КАК ОБРАБОТЧИК РАБОЧЕЙ ПРОЦЕДУРЫ IRP_MJ_CREATE.*/ NTSTATUS OnAddDeviceHandle(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { /*======================================================================*/ DbgPrint("OnAddDeviceHandle"); /*======================================================================*/ return(STATUS_SUCCESS); } /*=============================================================================== ===*/ /*ВЫЗЫВАЕТСЯ ПРИ ОБРАБОТКЕ ЛЮБОЙ РАБОЧЕЙ ПРОЦЕДУРЫ, КРОМЕ ПРОЦЕДУРЫ IRP_MJ_DEVICE_CONTROL, ОБРАБАТЫВАЕМОЙ ОТДЕЛЬНО*/ NTSTATUS IrpHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { /*======================================================================*/ DbgPrint("IrpHandle"); /*======================================================================*/ //ЗАВЕРШЕНИЕ ОБРАБОТКИ Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /*=============================================================================== ===*/ /*ВЫЗЫВАЕТСЯ ПРИ ВЫГРУЗКЕ ДРАЙВЕРА. АДРЕС ЭТОЙ ПРОЦЕДУРЫ БЫЛ ЗАРЕГИСТРИРОВАН В ПРОЦЕДУРЕ DriverEntry, КАК ОБРАБОТЧИК СОБЫТИЯ DriverUnload.*/ VOID OnUnloadHandle(IN PDRIVER_OBJECT DriverObject) { //СИМВОЛЬНОЕ ИМЯ ДРАЙВЕРА WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; UNICODE_STRING uniDOSString; /*======================================================================*/ DbgPrint("OnUnloadHandle"); /*======================================================================*/ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);//ИНИЦИАЛИЗАЦИЯ БУФЕРА ДЛЯ СИМВОЛЬНОГО ИМЕНИ IoDeleteSymbolicLink (&uniDOSString);//УДАЛЕНИЕ СИМВОЛЬНОГО ИМЕНИ IoDeleteDevice(DriverObject->DeviceObject);//УДАЛЕНИЕ ОБЪЕКТА ДРАЙВЕРА } /*=============================================================================== ===*/ /*ВЫЗЫВАЕТСЯ ПРИ ВЫЗОВЕ DeviceIoControl ИЗ ПОЛЬЗОВАТЕЛЬСКОГО РЕЖИМА РАБОТЫ. АДРЕС ЭТОЙ ПРОЦЕДУРЫ БЫЛ ЗАРЕГИСТРИРОВАН В ПРОЦЕДУРЕ DriverEntry, КАК ОБРАБОТЧИК РАБОЧЕЙ ПРОЦЕДУРЫ IRP_MJ_DEVICE_CONTROL.*/ NTSTATUS OnDeviceControlHandle(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp) { NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION irpSp; ULONG inBufLength;//ДЛИНА ВХОДНОГО БУФЕРА ULONG outBufLength;//ДЛИНА ВЫХОДНОГО БУФЕРА PULONG ioBuffer;//УКАЗАТЕЛЬ НА ВХОДНОЙ И ВЫХОДНОЙ БУФЕР /*======================================================================*/ DbgPrint("OnDeviceControlHandle"); /*======================================================================*/ irpSp = IoGetCurrentIrpStackLocation(pIrp);//УКАЗАТЕЛЬ НА ДРАЙВЕРНЫЙ СТЕК //ВХОДНОЙ И ВЫХОДНОЙ БУФЕРА И ИХ ДЛИНЫ inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; ioBuffer = (PULONG) pIrp->AssociatedIrp.SystemBuffer; switch(irpSp->Parameters.DeviceIoControl.IoControlCode) { //ОБРАБОТКА КОДА ФУНКЦИИ IOCTL_IOPM_FUNCTION1 case IOCTL_IOPM_FUNCTION1: { /*======================================================================*/ DbgPrint(">IOCTL_IOPM_FUNCTION1"); /*======================================================================*/ if(inBufLength > 0) { /*======================================================================*/ DbgPrint(">IOCTL_IOPM_FUNCTION1 inBufLength > 0"); /*======================================================================*/ ioBuffer[0]++; } break; } //ОБРАБОТКА КОДА ФУНКЦИИ IOCTL_IOPM_FUNCTION2 case IOCTL_IOPM_FUNCTION2: { /*======================================================================*/ DbgPrint(">IOCTL_IOPM_FUNCTION1"); /*======================================================================*/ if(inBufLength > 0) { /*======================================================================*/ DbgPrint(">IOCTL_IOPM_FUNCTION2 inBufLength > 0"); /*======================================================================*/ ioBuffer[0]--; } break; } } //ЗАВЕРШЕНИЕ РАБОЧЕЙ ПРОЦЕДУРЫ pIrp->IoStatus.Information = inBufLength;/*РАЗМЕР ВЫХОДНОГО БУФЕРА*/ pIrp->IoStatus.Status = ntStatus; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus; } /*=============================================================================== ===*/ Quote Share this post Link to post Share on other sites More sharing options...
VslavX 0 December 7, 2012 Posted December 7, 2012 · Report post У Вас стоит задача именно драйвер написать? Если просто подключить устройство к компьютеру с Windows то лучше воспользоваться одним из готовых классов. Если ни один из USB-классов не подходит, то можно пользовать WinUSB. Или реализовать сетевое подключение по RNDIS. Потому что чем "дальше в лес, тем толще партизаны" сложнее писать свои драйвера. Под Windows 8 уже поставить свои без цифровой подписи совсем сложно стало. Quote Share this post Link to post Share on other sites More sharing options...
rihkov 0 December 14, 2012 Posted December 14, 2012 · Report post Хочу написать именно свой драйвер и именно с использованием просто DDK, сейчас читаю Солдатова. Quote Share this post Link to post Share on other sites More sharing options...