Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Написать самый простой USB драйвер?

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


Код:
/*==================================================================================*/
#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;
}
/*==================================================================================*/
446
07 декабря 2012 года
Meander
487 / / 04.09.2011
Смотрел ли ты вот это?
У меня получилось реализовать этот пример для ATmega8. Пример использует некую библиотеку состоящую из исходного кода на c++ и языке ассемблера. Прилагаю архив с проектом. Там много закомментированного кода, так как сначала управлял светодиодами, а потом экспериментировал с АЦП. Возможно тебе стоит проанализировать содержимое библиотеки.
Прикрепленные файлы:
161 Кб
Загрузок: 847
446
08 декабря 2012 года
Meander
487 / / 04.09.2011
Хотел дополнить. Прямо на твой вопрос ответить не смогу, т.к. не интересовался вопросом, но к книге прилагается диск с кучей рабочих примеров. В этой раздаче он есть.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог