Destiny
Гость
|
|
« : 10-11-2005 09:46 » |
|
Добрый день. Помогите пожалуйста с драйвером... Никак не могу понять, что не так? Просматриваю журнал сообщений драйвера с помощью DegugView, но не вижу, чтобы передавалось управление Read функцию. Что может быть не так??? Добрый день. Помогите пожалуйста с драйвером... Я в этом деле новичок, поэтому может слишком глупые вопросы задаю, но сам как-то не могу разобраться... Никак не могу понять, что не так? Просматриваю журнал сообщений драйвера с помощью DegugView, но не вижу, чтобы передавалось управление Read в функцию. Что может быть не так??? Также вопрос по Айсу: установил 4.27, загрузил в символ лоадер сис-файл драйвера, преобразовал отладочную информацию в nms файл. Что делать дальше? может подскажете где взять детальную инструкцию по Айсу? Может надо загружать в Айс драйвер, находящийся в C:\Windows\System32\drivers, а то я загрузил прямо из того места, куда build'er положил... Вот, собственно, текст: #include "LaserPU.h"
#ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, LaserPU_AddDevice) #pragma alloc_text(PAGE, LaserPU_Unload) #pragma alloc_text(PAGE, LaserPU_DispatchPnp) #pragma alloc_text(PAGE, LaserPU_DispatchPower) #endif
//------------------------------------------------------------------ // DriverEntry() // Инициализация драйвера при установке //------------------------------------------------------------------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{ ULONG i; DebugPrint(("Entered the Driver Entry\n"));
// Заполняю массив главных функций указателем на функцию, // пропускающую пакеты вниз по стеку. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = LaserPU_DispatchPassThrough; } // Обновляю указатели на используемые объекты DriverObject->MajorFunction[IRP_MJ_PNP] = LaserPU_DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = LaserPU_DispatchPower; DriverObject->MajorFunction[IRP_MJ_READ] = LaserPU_Read; DriverObject->DriverExtension->AddDevice = LaserPU_AddDevice; DriverObject->DriverUnload = LaserPU_Unload;
return STATUS_SUCCESS; }
//------------------------------------------------------------------ // LaserPU_AddDevice() // Добавление драйвера в стек драйверов мыши //------------------------------------------------------------------
NTSTATUS LaserPU_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
{ NTSTATUS status; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension = NULL;
PAGED_CODE(); DebugPrint(("Entered in add device\n")); // Создаем объект-фильтр устройства. status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), NULL, // No Name FILE_DEVICE_MOUSE, 0, FALSE, &deviceObject );
if (!NT_SUCCESS(status)) { return status; } DebugPrint(( "AddDevice PDO (0x%x) FDO (0x%x)\n", PhysicalDeviceObject, deviceObject ));
// Заполняем блок памяти, отведенной под DeviceExtension нулями. RtlZeroMemory(deviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION)); // Получаем указатель на расширение нашего устройства. deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; // Save some information for later. deviceExtension->Self = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; // Создаем объект устройства, находящегося в данный момент на вершине стека; // Сохраняем указатель на него и подключаем фильтр к вершине стека. deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (deviceObject, PhysicalDeviceObject); // Проверка на корректное подключение к стеку. if (NULL == deviceExtension->NextLowerDriver) { IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; }
// Копирование флагов устройства из устройства ниже по стеку. deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH); deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType; deviceObject->Characteristics = deviceExtension->NextLowerDriver->Characteristics;
// Инициализирование состояния устройства. INITIALIZE_PNP_STATE(deviceExtension);
DebugPrint(( "AddDevice: %x to %x->%x \n", deviceObject, deviceExtension->NextLowerDriver, PhysicalDeviceObject ));
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; }
//--------------------------------------------------------------------- // LaserPU_Unload() // Выгрузка драйвера //---------------------------------------------------------------------
VOID LaserPU_Unload( IN PDRIVER_OBJECT DriverObject) { PAGED_CODE();
ASSERT(DriverObject->DeviceObject == NULL);
DebugPrint(("unload\n"));
return; }
//------------------------------------------------------------------- // LaserPU_DispatchPnp() // Обработка PnP пакетов. Мы обрабатываем PnP пакеты, чтобы вовремя отсоединиться //-------------------------------------------------------------------
NTSTATUS LaserPU_DispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; KIRQL oldIrql; KEVENT event;
PAGED_CODE(); DebugPrint(("entered dispatch pnp\n")); // Получить ячейку стека для нашего драйвера. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); /* DebugPrint(( "FilterDO %s IRP:0x%x \n", PnPMinorFunctionString(irpStack->MinorFunction), Irp )); */ // Просмотр доп. функции в пакете. switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: {
// Драйвер стартует. // Нельзя работать с драйвером, пока пакет не обработается // всеми драйверами стека. IoCopyCurrentIrpStackLocationToNext(Irp); KeInitializeEvent(&event, NotificationEvent, FALSE );
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) LaserPU_CompleteIRP, &event, TRUE, TRUE, TRUE); // No need for Cancel
status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
if (STATUS_PENDING == status) { KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Waiting in kernel mode FALSE, // No allert NULL); // No timeout }
if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) { // Устройство стартовало. SET_NEW_PNP_STATE(deviceExtension, Started); }
// We must now complete the IRP, since we stopped it in the // completetion routine with MORE_PROCESSING_REQUIRED. Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; }
case IRP_MN_SURPRISE_REMOVAL: // // Same as a remove device, but don't call IoDetach or IoDeleteDevice // SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); break;
case IRP_MN_REMOVE_DEVICE: SET_NEW_PNP_STATE(deviceExtension, Deleted); Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject);
break;
case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_CAPABILITIES: case IRP_MN_QUERY_DEVICE_TEXT: case IRP_MN_QUERY_RESOURCES: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_READ_CONFIG: case IRP_MN_WRITE_CONFIG: case IRP_MN_EJECT: case IRP_MN_SET_LOCK: case IRP_MN_QUERY_ID: case IRP_MN_QUERY_PNP_DEVICE_STATE: default: // // Here the filter driver might modify the behavior of these IRPS // Please see PlugPlay documentation for use of these IRPs. // IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); break; } return status; /*++
Module Name:
LaserPU.c
Abstract:
Этот модуль содержит код драйвера-фильтра для LPU.
Environment:
Kernel mode
Revision History:
Валерий Петриев - Написан 30 октября 2005 г.
--*/
#include "LaserPU.h"
#ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, LaserPU_AddDevice) #pragma alloc_text(PAGE, LaserPU_Unload) #pragma alloc_text(PAGE, LaserPU_DispatchPnp) #pragma alloc_text(PAGE, LaserPU_DispatchPower) #endif
//------------------------------------------------------------------ // DriverEntry() // Инициализация драйвера при установке //------------------------------------------------------------------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{ ULONG i; DebugPrint(("Entered the Driver Entry\n"));
// Заполняю массив главных функций указателем на функцию, // пропускающую пакеты вниз по стеку. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = LaserPU_DispatchPassThrough; } // Обновляю указатели на используемые объекты DriverObject->MajorFunction[IRP_MJ_PNP] = LaserPU_DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = LaserPU_DispatchPower; DriverObject->MajorFunction[IRP_MJ_READ] = LaserPU_Read; DriverObject->DriverExtension->AddDevice = LaserPU_AddDevice; DriverObject->DriverUnload = LaserPU_Unload;
return STATUS_SUCCESS; }
//------------------------------------------------------------------ // LaserPU_AddDevice() // Добавление драйвера в стек драйверов мыши //------------------------------------------------------------------
NTSTATUS LaserPU_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
{ NTSTATUS status; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension = NULL;
PAGED_CODE(); DebugPrint(("Entered in add device\n")); // Создаем объект-фильтр устройства. status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), NULL, // No Name FILE_DEVICE_MOUSE, 0, FALSE, &deviceObject );
if (!NT_SUCCESS(status)) { return status; } DebugPrint(( "AddDevice PDO (0x%x) FDO (0x%x)\n", PhysicalDeviceObject, deviceObject ));
// Заполняем блок памяти, отведенной под DeviceExtension нулями. RtlZeroMemory(deviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION)); // Получаем указатель на расширение нашего устройства. deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; // Save some information for later. deviceExtension->Self = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; // Создаем объект устройства, находящегося в данный момент на вершине стека; // Сохраняем указатель на него и подключаем фильтр к вершине стека. deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (deviceObject, PhysicalDeviceObject); // Проверка на корректное подключение к стеку. if (NULL == deviceExtension->NextLowerDriver) { IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; }
// Копирование флагов устройства из устройства ниже по стеку. deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH); deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType; deviceObject->Characteristics = deviceExtension->NextLowerDriver->Characteristics;
// Инициализирование состояния устройства. INITIALIZE_PNP_STATE(deviceExtension);
DebugPrint(( "AddDevice: %x to %x->%x \n", deviceObject, deviceExtension->NextLowerDriver, PhysicalDeviceObject ));
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; }
//--------------------------------------------------------------------- // LaserPU_Unload() // Выгрузка драйвера //---------------------------------------------------------------------
VOID LaserPU_Unload( IN PDRIVER_OBJECT DriverObject) { PAGED_CODE();
ASSERT(DriverObject->DeviceObject == NULL);
DebugPrint(("unload\n"));
return; }
//------------------------------------------------------------------- // LaserPU_DispatchPnp() // Обработка PnP пакетов. Мы обрабатываем PnP пакеты, чтобы вовремя отсоединиться //-------------------------------------------------------------------
NTSTATUS LaserPU_DispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; KIRQL oldIrql; KEVENT event;
PAGED_CODE(); DebugPrint(("entered dispatch pnp\n")); // Получить ячейку стека для нашего драйвера. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); /* DebugPrint(( "FilterDO %s IRP:0x%x \n", PnPMinorFunctionString(irpStack->MinorFunction), Irp )); */ // Просмотр доп. функции в пакете. switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: {
// Драйвер стартует. // Нельзя работать с драйвером, пока пакет не обработается // всеми драйверами стека. IoCopyCurrentIrpStackLocationToNext(Irp); KeInitializeEvent(&event, NotificationEvent, FALSE );
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) LaserPU_CompleteIRP, &event, TRUE, TRUE, TRUE); // No need for Cancel
status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
if (STATUS_PENDING == status) { KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Waiting in kernel mode FALSE, // No allert NULL); // No timeout }
if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) { // Устройство стартовало. SET_NEW_PNP_STATE(deviceExtension, Started); }
// We must now complete the IRP, since we stopped it in the // completetion routine with MORE_PROCESSING_REQUIRED. Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; }
case IRP_MN_SURPRISE_REMOVAL: // // Same as a remove device, but don't call IoDetach or IoDeleteDevice // SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); break;
case IRP_MN_REMOVE_DEVICE: SET_NEW_PNP_STATE(deviceExtension, Deleted); Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject);
break;
case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_CAPABILITIES: case IRP_MN_QUERY_DEVICE_TEXT: case IRP_MN_QUERY_RESOURCES: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_READ_CONFIG: case IRP_MN_WRITE_CONFIG: case IRP_MN_EJECT: case IRP_MN_SET_LOCK: case IRP_MN_QUERY_ID: case IRP_MN_QUERY_PNP_DEVICE_STATE: default: // // Here the filter driver might modify the behavior of these IRPS // Please see PlugPlay documentation for use of these IRPs. // IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); break; } return status; }
//--------------------------------------------------------------------- // LaserPU_CompleteIRP() // Позволяет драйверу посылать IRP вниз по стеку, отлавливать их на обратном пути // (используется в LaserPU_DispatchPnp) //---------------------------------------------------------------------
NTSTATUS LaserPU_CompleteIRP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{ PKEVENT event;
event = (PKEVENT) Context;
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp);
// // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // KeSetEvent(event, 0, FALSE);
// // Allows the caller to use the IRP after it is completed // return STATUS_MORE_PROCESSING_REQUIRED; }
//--------------------------------------------------------------------- // LaserPU_DispatchPower() // Управление энергопотреблением //---------------------------------------------------------------------
NTSTATUS LaserPU_DispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(deviceExtension->NextLowerDriver, Irp); return status; }
//--------------------------------------------------------------------- // LaserPU_DispatchPassThrough() // Функция, пропускающая пакеты, которые мы не обрабатываем //---------------------------------------------------------------------
NTSTATUS LaserPU_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; NTSTATUS status; DebugPrint(("entered dispatch pass through\n")); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); return status; }
//----------------------------------------------------------------------- // LaserPU_Read() // Здесь устаналиваем callback-функцию для перехвата Irp пакетов // чтения //-----------------------------------------------------------------------
NTSTATUS LaserPU_Read( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION currentIrpStack; PIO_STACK_LOCATION nextIrpStack;
DebugPrint(("Entered the Major Read\n")); // Инициализируем наши переменные deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; currentIrpStack = IoGetCurrentIrpStackLocation(Irp); nextIrpStack = IoGetNextIrpStackLocation(Irp);
// Пропускаем пакет ниже, к драйверу класса *nextIrpStack = *currentIrpStack;
// Здесь устанавливаем свою callback-функцию для того чтобы // подправить данные мыши IoSetCompletionRoutine( Irp, LaserPU_ReadComplete, DeviceObject, TRUE, TRUE, TRUE );
// Возвращаем результаты вызова драйверу класса return IoCallDriver( deviceExtension->NextLowerDriver, Irp ); }
//--------------------------------------------------------------------- // LaserPU_ReadComplete() // Получает управление после завершения операции чтения //--------------------------------------------------------------------- NTSTATUS LaserPU_ReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID pContext ) { PIO_STACK_LOCATION currentIrpStack; PMOUSE_INPUT_DATA pMouseData; int numMoves; int i;
DebugPrint(("entered read complete\n")); // Обработка закончена ловим результаты currentIrpStack = IoGetCurrentIrpStackLocation(Irp); if (NT_SUCCESS(Irp->IoStatus.Status)) { // Отключаем события средней кнопки. // Просто удаляем их из пакета pMouseData = Irp->AssociatedIrp.SystemBuffer; numMoves = Irp->IoStatus.Information/sizeof(MOUSE_INPUT_DATA);
for (i=1;i<numMoves;i++) { if (pMouseData[i].ButtonFlags & MOUSE_LEFT_BUTTON_DOWN) pMouseData[i].ButtonFlags &= !(MOUSE_LEFT_BUTTON_DOWN); if (pMouseData[i].ButtonFlags & MOUSE_LEFT_BUTTON_UP) pMouseData[i].ButtonFlags &= !(MOUSE_LEFT_BUTTON_UP); } }
if (Irp->PendingReturned) IoMarkIrpPending(Irp);
return Irp->IoStatus.Status; } }
|
|
« Последнее редактирование: 24-05-2010 17:09 от Алексей1153++ »
|
Записан
|
|
|
|
Destiny
Гость
|
|
« Ответ #4 : 24-11-2005 08:55 » |
|
Все, закончил я работу над драйвером - выкладываю результаты (может кому пригодится?). Отлов событий от мыши происходит не по обработке IRP_MJ_READ а путем подключения к очереди пакетов Mouclass'а. /*++
Module Name:
LaserPU.c
Abstract:
Этот модуль содержит код драйвера-фильтра для LPU.
Environment:
Kernel mode
Revision History:
Валерий Петриев - Написан 20 ноября 2005 г.
(На основе примера Firefly в DDK 2003)
--*/
#include "LaserPU.h"
#ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, LaserPUAddDevice) #pragma alloc_text(PAGE, LaserPUUnload) #pragma alloc_text(PAGE, LaserPUDispatchPnp) #pragma alloc_text(PAGE, LaserPUDispatchPower) #endif
//------------------------------------------------------------------ // DriverEntry() // Инициализация драйвера при установке //------------------------------------------------------------------ NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{ USHORT regPathLen; ULONG ulIndex; PDRIVER_DISPATCH * dispatch;
DebugPrint(("Entered the Driver Entry\n"));
// Заполняю массив главных функций указателем на функцию, // пропускающую пакеты вниз по стеку. for (ulIndex = 0, dispatch = DriverObject->MajorFunction; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++, dispatch++) {
*dispatch = LaserPU_DispatchPassThrough; }
// Обновляю указатели на используемые объекты DriverObject->MajorFunction[IRP_MJ_PNP] = LaserPUDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = LaserPUDispatchPower; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = LaserPU_DispatchDeviceControl; DriverObject->DriverExtension->AddDevice = LaserPUAddDevice; DriverObject->DriverUnload = LaserPUUnload;
return STATUS_SUCCESS; }
//------------------------------------------------------------------ // LaserPU_AddDevice() // Добавление драйвера в стек драйверов мыши //------------------------------------------------------------------ NTSTATUS LaserPUAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
{ NTSTATUS status; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension = NULL;
PAGED_CODE(); // Создаем объект-фильтр устройства. status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), NULL, // No Name FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &deviceObject );
if (!NT_SUCCESS(status)) {
// // Returning failure here prevents the entire stack from functioning, // but most likely the rest of the stack will not be able to create // device objects either, so it is still OK. // return status; }
DebugPrint(( "AddDevice PDO (0x%x) FDO (0x%x)\n", PhysicalDeviceObject, deviceObject ));
// Получаем указатель на расширение нашего устройства. deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
// Сохраняю для дальнейшего использования. deviceExtension->Self = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
// Создаем объект устройства, находящегося в данный момент на вершине стека; // Сохраняем указатель на него и подключаем фильтр к вершине стека. deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack( deviceObject, PhysicalDeviceObject );
// Если не подсоединился - проблема в PnP, удалить объект устройства if (NULL == deviceExtension->NextLowerDriver) { IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; }
// Копирование флагов устройства из устройства ниже по стеку. deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH);
deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;
deviceObject->Characteristics = deviceExtension->NextLowerDriver->Characteristics;
// Инициализирование состояния устройства. INITIALIZE_PNP_STATE(deviceExtension);
IoInitializeRemoveLock (&deviceExtension->RemoveLock , POOL_TAG, 1, // MaxLockedMinutes 5); // HighWatermark, this parameter is // used only on checked build. DebugPrint(( "AddDevice: %x to %x->%x \n", deviceObject, deviceExtension->NextLowerDriver, PhysicalDeviceObject ));
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; }
//--------------------------------------------------------------------- // LaserPU_Unload() // Выгрузка драйвера //--------------------------------------------------------------------- VOID LaserPUUnload( IN PDRIVER_OBJECT DriverObject )
{ PAGED_CODE();
ASSERT(DriverObject->DeviceObject == NULL);
DebugPrint(("unload\n"));
return; }
//------------------------------------------------------------------- // LaserPU_DispatchPnp() // Обработка PnP пакетов. Мы обрабатываем PnP пакеты, чтобы вовремя отсоединиться //------------------------------------------------------------------- NTSTATUS LaserPUDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack, nextStack; NTSTATUS status; KEVENT event;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// Получить ячейку стека для нашего драйвера. irpStack = IoGetCurrentIrpStackLocation(Irp);
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } // Просмотр доп. функции в пакете. switch(irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:
// Драйвер стартует. // Нельзя работать с драйвером, пока пакет не обработается // всеми драйверами стека. KeInitializeEvent(&event, NotificationEvent, FALSE );
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine( Irp, LaserPU_CompleteIRP, &event, TRUE, TRUE, TRUE );
status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Waiting in kernel mode FALSE, // No alert NULL // No timeout );
status = Irp->IoStatus.Status; }
if (NT_SUCCESS(status)) { // Устройство стартовало. SET_NEW_PNP_STATE(deviceExtension, Started); }
// // We must now complete the IRP, since we stopped it in the // completion routine with STATUS_MORE_PROCESSING_REQUIRED. // Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status;
case IRP_MN_REMOVE_DEVICE:
SET_NEW_PNP_STATE(deviceExtension, Deleted);
// // Wait for all outstanding requests to complete // DebugPrint(("Waiting for outstanding requests\n")); IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
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:
// // Check to see whether you have received cancel-stop // without first receiving a query-stop. This could happen if someone // above us fails a query-stop and passes down the subsequent // cancel-stop. //
if(StopPending == deviceExtension->DevicePnPState) { // // We did receive a query-stop, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break;
case IRP_MN_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, StopPending); status = STATUS_SUCCESS; break;
case IRP_MN_QUERY_REMOVE_DEVICE:
SET_NEW_PNP_STATE(deviceExtension, RemovePending); status = STATUS_SUCCESS; break;
case IRP_MN_SURPRISE_REMOVAL:
SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); status = STATUS_SUCCESS; break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
// // Check to see whether you have received cancel-remove // without first receiving a query-remove. This could happen if // someone above us fails a query-remove and passes down the // subsequent cancel-remove. // if (RemovePending == deviceExtension->DevicePnPState) {
// // We did receive a query-remove, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); }
status = STATUS_SUCCESS; // We must not fail this IRP. break;
default:
// // If you don't handle any IRP you must leave the // status as is. // status = Irp->IoStatus.Status; break; }
// // Pass the IRP down and forget it. // Irp->IoStatus.Status = status; IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
//--------------------------------------------------------------------- // LaserPU_CompleteIRP() // Позволяет драйверу посылать IRP вниз по стеку, отлавливать их на обратном пути // (используется в LaserPU_DispatchPnp) //--------------------------------------------------------------------- NTSTATUS LaserPU_CompleteIRP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{ UNREFERENCED_PARAMETER(DeviceObject);
// // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
// // Allows the caller to use the IRP after it is completed // return STATUS_MORE_PROCESSING_REQUIRED; }
//--------------------------------------------------------------------- // LaserPU_DispatchPower() // Управление энергопотреблением //--------------------------------------------------------------------- NTSTATUS LaserPUDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { // may be device is being removed. 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; }
//--------------------------------------------------------------------- // LaserPU_DispatchPassThrough() // Функция, пропускающая пакеты, которые мы не обрабатываем //--------------------------------------------------------------------- NTSTATUS LaserPU_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PDEVICE_EXTENSION deviceExtension; NTSTATUS status; 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; } IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
//--------------------------------------------------------------------- // LaserPU_DispatchDeviceControl() // В данной функции подсоединяемся к очереди пакетов Mouclass для их фильтрации // Для этого регистрируется сервис возврата LaserPU_ServiceCallback //--------------------------------------------------------------------- NTSTATUS LaserPU_DispatchDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; PCONNECT_DATA connectData; NTSTATUS status;
DebugPrint(( "Wot i sluchilos DispatchDeviceControl\n"));
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } // Подключение классового драйвера к драйверу порта if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_CONNECT) {
// Допустимо только одно подключение if (deviceExtension->UpperConnectData.ClassService != NULL) { return STATUS_SHARING_VIOLATION; } if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { // Недопустимый буфер return STATUS_INVALID_PARAMETER; } // Копируем параметры в расширение устройства connectData = ((PCONNECT_DATA) (irpStack->Parameters.DeviceIoControl.Type3InputBuffer));
deviceExtension->UpperConnectData = *connectData;
// Подключаюсь к очереди пакетов. // Как только появится пакет, адресованный системе - // вызов LaserPU_ServiceCallback connectData->ClassDeviceObject = deviceExtension->Self; connectData->ClassService = LaserPU_ServiceCallback; }
if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT) {
// Очистка параметров соединения в расширении устройства deviceExtension->UpperConnectData.ClassDeviceObject = NULL; deviceExtension->UpperConnectData.ClassService = NULL;
status = STATUS_NOT_IMPLEMENTED; } IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
//--------------------------------------------------------------------- // LaserPU_ServiceCallback() // В данную функцию собственно передается управление при возникновении // события от мыши. Передачу управления производит менеджер ввода\вывода // когда Mouclass заполнит внутреннюю очередь пакетов. //--------------------------------------------------------------------- VOID LaserPU_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PMOUSE_INPUT_DATA InputDataStart, IN PMOUSE_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed )
{ PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; PCONNECT_DATA connectData; PMOUSE_INPUT_DATA MouseInputData; NTSTATUS status; int num; int i;
DebugPrint(( "Entered LaserPU_ServiceCallback\n"));
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// // UpperConnectData must be called at DISPATCH //
for (MouseInputData = InputDataStart; MouseInputData < InputDataEnd; MouseInputData++) {
MouseInputData->LastX = 0x0; MouseInputData->LastY = 0x0;
// обработка нажатия левой и правой кнопок мыши // если левая кнопка - текст вниз, правая - текст вверх // в противном случае - очистка событий if (MouseInputData->ButtonFlags == MOUSE_LEFT_BUTTON_DOWN) { MouseInputData->ButtonFlags = 0x400; MouseInputData -> ButtonData = 0x78; DebugPrint(( "LB\n")); } else if (InputDataStart->ButtonFlags == MOUSE_RIGHT_BUTTON_DOWN) { MouseInputData->ButtonFlags = 0x400; MouseInputData -> ButtonData = 0xff88; DebugPrint(( "RB\n")); } else { MouseInputData->ButtonFlags = 0x0; } }
(*(PSERVICE_CALLBACK_ROUTINE) deviceExtension->UpperConnectData.ClassService)( deviceExtension->UpperConnectData.ClassDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed ); return; }
Большое спасибо Scorp'у за помощь в начале работы...
|
|
« Последнее редактирование: 24-05-2010 17:10 от Алексей1153++ »
|
Записан
|
|
|
|