Jump to content
    

Написать USB драйвер не в стиле WDM ?

Подскажите как написать USB драйвер не в стиле WDM (точнее без регистрации процедур IRP_MJ_POWER и IRP_MJ_PNP), как произвести нумерацию и подскажите как вообще делается регистрация конечных точек в драйвере?

Share this post


Link to post
Share on other sites

Помогите написать самый простой USB драйвер с использованием DDK, разобрался в заготовке драйвера из книги Агурова про USB, чуть подправил и написал приложение на Borland C++Builder 6 для работы с этим драйвером, но вот на этом пока что и все, не могу понять как получить контекст USB устройства, и как потом работать с конечными точками. Прошу помощи, и есть ли какая то русскоязычная литература именно по написанию USB драйвера двигаясь от самого простого до сложного?

Share this post


Link to post
Share on other sites

Код драйвера.

 

/*===============================================================================
===*/
#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;
}
/*===============================================================================
===*/

Share this post


Link to post
Share on other sites

У Вас стоит задача именно драйвер написать? Если просто подключить устройство к компьютеру с Windows то лучше воспользоваться одним из готовых классов. Если ни один из USB-классов не подходит, то можно пользовать WinUSB. Или реализовать сетевое подключение по RNDIS. Потому что чем "дальше в лес, тем толще партизаны" сложнее писать свои драйвера. Под Windows 8 уже поставить свои без цифровой подписи совсем сложно стало.

Share this post


Link to post
Share on other sites

Хочу написать именно свой драйвер и именно с использованием просто DDK, сейчас читаю Солдатова.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...