Объявление

#1 28-07-2010 06:48:43

Эмуляция нажатия кнопок из драйвера [WinXP]

Подскажите пожалуйста как осуществить. Псевдокод/код/исходники/теория.

 

#2 28-07-2010 08:13:22

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

если потоку, то проще всего заюзать Shadow-функции, ну или если нужен геморрой, то работать с очередью ввода потока напрямую.
если системе, то вообще не вижу сложностей, можно работать как с портами, так и с драйвером клавиатуры (почти с любым из стека).


То, что не удается запрограммировать на ассемблере, приходится паять.

 

#3 28-07-2010 09:16:03

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

если потоку, то проще всего заюзать Shadow-функции, ну или если нужен геморрой, то работать с очередью ввода потока напрямую.
если системе, то вообще не вижу сложностей, можно работать как с портами, так и с драйвером клавиатуры (почти с любым из стека).

Можно пожалуйсто поподробнее, лучше системе, хоть какой нить пседвдокод\код

 

#4 28-07-2010 09:23:37

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

out 0x64, 0xd2
out 0x60, key

конечно это может не работать, например, для usb-клавиш, однако часто бывает эмуляция ps/2.


То, что не удается запрограммировать на ассемблере, приходится паять.

 

#5 28-07-2010 09:47:33

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Еще вопрос такой,  почему keybd_event отрабатыает через раз-два?

 

#6 28-07-2010 09:51:23

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

n0name
Какие именно Shadow? Экспортируются? Если нет где адреса брать?

Используйте поиск, либо размышляйте. Иначе перенесём топ в бегинерс.

 

#7 28-07-2010 19:58:55

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

чем можно начетно из списка эмулировать кнопки. SendInput переходит в ntdll, потом в сервис...
Итого для эмуляции ввода получаем драйвер фильтр и порты клавы. Что надежнее использовать, что проще? Сталкиваюсь с Kernel Mode не так часто, знаний мало, но задачу нужно выпонить, так подскажите куда копать и что реализовывать. После непредсказуемости юзермодных функций вообще в шоке. Не уверен что сервисы спасут.

 

#8 28-07-2010 21:28:53

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Код:

#define _X86_
#define _DDK_DRIVER_

#include <ntddk.h>

VOID OnUnload (DRIVER_OBJECT theDrvObj)
{
    DbgPrint("I AM Unloading...");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT theDrvObj,PUNICODE_STRING theRegPath)
{
    DbgPrint ("I AM IN RING0");
    theDrvObj->DriverUnload=(PDRIVER_UNLOAD)OnUnload;
    return STATUS_SUCCESS;

}

Компилю студией,проект могу приложить. При загрузке на вин 7 ок при выгрузке бсод. при загрузке на икспи сп3 не видно отладочного вывода, при выгрузке бсод/
[студию на дров настраивал сам][xp sp3]

Отредактировано punxer (28-07-2010 21:36:31)

 

#9 28-07-2010 21:35:19

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Код:

VOID OnUnload (PDRIVER_OBJECT theDrvObj)

 

#10 28-07-2010 21:36:31

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

В висте и семерке надо в реестре править что-то чтобы видеть отладочный вывод.

 

#11 28-07-2010 21:37:07

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

ntcdm в  7 как раз видно

Отредактировано punxer (28-07-2010 21:37:27)

 

#12 28-07-2010 21:38:04

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

ntcdm

Код:
VOID OnUnload (PDRIVER_OBJECT theDrvObj)

и что

ЗЫ Этот 'дров' раньше работал

Отредактировано punxer (28-07-2010 21:39:27)

 

#13 28-07-2010 21:43:36

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

то что у тебя функция принимает структуру, а надо поинтер на структуру в итоге портится содержимое стека.

а бсод в этом месте может 100 раз не возникнуть, а возникнуть на 101 раз.

 

#14 29-07-2010 07:18:11

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

stdcall еще.


То, что не удается запрограммировать на ассемблере, приходится паять.

 

#15 29-07-2010 10:55:15

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Можно поставить фильтр на клавиатурный стек. При получении IRP_MJ_READ задерживать пакет, а вниз по стеку отсылать свой. Таким образом при реальном нажатии завершится свой IRP и надо будет скопировать в изначальный всё и завершить его. А если надо с эмулировать то, просто надо завершить изначальный IRP c нужными данными.

 

#16 29-07-2010 19:56:39

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

поможите плиз исходником драйвера который по IOCTL запросу генерирует нажатие клавиши в системе. Можно в личку ,$

 

#17 29-07-2010 19:58:08

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Код:

#define _X86_
#define _DDK_DRIVER_

#include <ntddk.h>
typedef struct tagDEVICE_EXTENSION {
    PDEVICE_OBJECT DeviceObject;       // device object this driver creates

    PDEVICE_OBJECT NextDeviceObject;   // next-layered device object in this

                                       // device stack

    DEVICE_CAPABILITIES pdc;           // device capability

    IO_REMOVE_LOCK RemoveLock;         // removal control locking structure

    LONG handles;                      // # open handles

    PVOID DataBuffer;                  // Internal Buffer for Read/Write I/O

    UNICODE_STRING Device_Description; // Device Description

    SYSTEM_POWER_STATE SysPwrState;    // Current System Power State

    DEVICE_POWER_STATE DevPwrState;    // Current Device Power State

    PIRP PowerIrp;                     // Current Handling Power-Related IRP

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS TestControl (IN PDEVICE_OBJECT fdo, IN PIRP irp)

{


    return STATUS_SUCCESS;
}
VOID OnUnload (PDRIVER_OBJECT theDrvObj)
{
    DbgPrint("I AM Unloading...");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT theDrvObj,PUNICODE_STRING theRegPath)
{
    PDEVICE_OBJECT pdo;
    PUNICODE_STRING pus;
    DbgPrint ("I AM IN RING0");
    theDrvObj->DriverUnload=(PDRIVER_UNLOAD)OnUnload;
    theDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TestControl;
    RtlInitUnicodeString(pus,L"12345");
    IoCreateDevice(theDrvObj, sizeof(DEVICE_EXTENSION),pus, 0, 0, FALSE, &pdo);
    return STATUS_SUCCESS;

}

бсодит сразу

Пусть бегиннерс, хоть коммерц.

Отредактировано punxer (29-07-2010 19:59:47)

 

#18 29-07-2010 20:05:56

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

UNICODE_STRING pus;
RtlInitUnicodeString не выделяет память, а просто заполняет структуру.

 

#19 29-07-2010 20:07:38

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

или хоть ткнить в исходники дрова управляемого приложением минимального.

 

#20 29-07-2010 20:11:17

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

izl3sa спасибо исправил
но kmdmanager не может послать IOCTL, cant get drv handle

 

#21 30-07-2010 00:07:26

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Хоть и Солдатова тут обхаяли, но все же возьми его книгу да посмотри, там был шаблон стандартного драйвера, у тебя ошибки просто на начальном этапе уже

 

#22 30-07-2010 10:39:47

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

2punxer
потомучто надо SymbolicLink создать на свой устройство в доступном месте (\??\, etc). Почитай Four-F =)), скачай Валтера Они и читай, читай, читай, изредка пробуя. Если проект горит, то тебя проще будет заплатить, тк драйверы не та область в которую можно въехать с ходу.

 

#23 30-07-2010 11:53:00

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

punxer

#define _X86_
#define _DDK_DRIVER_

терпеть не могу подобное в коде. Такое надо помещать или в свойствах проекта или в мэйк-файле или в батнике опцией к компиллеру "/D", если уж нато пошло

Отредактировано EvilsInterrupt (30-07-2010 11:53:21)


M есть модель системы S, если М может быть использована для получения ответов на вопросы относительно S, с некоторой точностью А.

 

#24 30-07-2010 19:33:18

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

Код:

#define _X86_
#define _DDK_DRIVER_
#define DBG

#include <ntddk.h>

#ifndef _DRIVER_H_04802_BASHBD_1UIWQ1_8239_1NJKDH832_901_
#define _DRIVER_H_04802_BASHBD_1UIWQ1_8239_1NJKDH832_901_
// Выше приведены две строки (в конце файла имеется еще #endif),
// которые в больших проектах запрещают повторные  проходы по тексту,
// который находится внутри h-файла (что весьма удобно для повышения
// скорости компиляции).
// (Файл Driver.h)

#ifdef __cplusplus
extern "C"
{
#endif

#include "ntddk.h"

//#include "wdm.h"
// ^^^^^^^^^^^^^^ если выбрать эту строку и закомментировать
// предыдущую, то компиляция  в среде DDK (при помощи утилиты Build)
// также пройдет успешно, однако драйвер Example не станет от этого
// настоящим WDM драйвером.

#ifdef __cplusplus
}
#endif
// Определяем структуру расширения устройства. Включим в нее
// указатель на FDO (для удобства последующей работы UnloadRoutine) и
// имя символьной ссылки в формате UNOCODE_STRING.

typedef struct _EXAMPLE_DEVICE_EXTENSION
{
    PDEVICE_OBJECT    fdo;
    UNICODE_STRING    ustrSymLinkName; // L"\\DosDevices\\Example"
} EXAMPLE_DEVICE_EXTENSION, *PEXAMPLE_DEVICE_EXTENSION;

// Определяем собственные коды IOCTL, с которыми можно будет
// обращаться к драйверу при помощи вызова DeviceIoControl.
// Определение макроса CTL_CODE можно найти в файле DDK Winioctl.h.
// Там же можно найти и численные значения, скрывающиеся под именами
// METHOD_BUFFERED и METHOD_NEITHER.

// Внимание! Текст приведенный ниже должен войти в файл Ioctl.h,
// который будет необходим для компиляции тестового приложения.
// (Разумеется, за исключением последней строки с "#endif".)

#define IOCTL_PRINT_DEBUG_MESS CTL_CODE( \
    FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_CHANGE_IRQL CTL_CODE(\
    FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_MAKE_SYSTEM_CRASH CTL_CODE( \
    FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_TOUCH_PORT_378H CTL_CODE( \
    FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_SEND_BYTE_TO_USER CTL_CODE( \
    FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)

// Вариант :
//#define IOCTL_SEND_BYTE_TO_USER CTL_CODE( \
//    FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_ANY_ACCESS)
#endif


// Предварительные объявления функций:
NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
VOID     UnloadRoutine(IN PDRIVER_OBJECT DriverObject);
NTSTATUS ReadWrite_IRPhandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS Close_HandleIRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info);

// Хотя и нехорошо делать глобальные переменные в драйвере...
KSPIN_LOCK MySpinLock;
#pragma code_seg("INIT") // начало секции INIT
/////////////////////////////////////////////////////////////////////
// (Файл init.cpp)
// DriverEntry - инициализация драйвера и необходимых объектов
// Аргументы:  указатель на объект драйвера
//             раздел реестра (driver service key) в UNICODE
// Возвращает: STATUS_Xxx


NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath  )
{
    NTSTATUS status = STATUS_SUCCESS;
    PDEVICE_OBJECT  fdo;
    UNICODE_STRING  devName;

    #if DBG
    DbgPrint("=Example= In DriverEntry.");
    DbgPrint("=Example= RegistryPath = %ws.", RegistryPath->Buffer);
    #endif

    // Экспорт точек входа в драйвер (AddDevice объявлять не будем)
    // DriverObject->DriverExtension->AddDevice= OurAddDeviceRoutine;
    DriverObject->DriverUnload = UnloadRoutine;
    DriverObject->MajorFunction[IRP_MJ_CREATE]= Create_File_IRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close_HandleIRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_READ]  = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DeviceControlRoutine;
    //========================================================
    // Действия по созданию символьной ссылки
    // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    // очень простой драйвер и эта процедура отсутствует):
    RtlInitUnicodeString( &devName, L"\\Device\\EXAMPLE" );

    // Создаем наш Functional Device Object (FDO) и получаем
    // указатель на созданный FDO в нашей переменной fdo.    
    // (В WDM драйвере эту работу также следовало бы выполнять
    // в процедуре OurAddDeviceRoutine.) При создании FDO
    // будет выделено место и под структуру расширения устройства
    // EXAMPLE_DEVICE_EXTENSION (для этого мы передаем в вызов
    // ее размер, вычисляемый оператором sizeof):
    status = IoCreateDevice(DriverObject,
                            sizeof(EXAMPLE_DEVICE_EXTENSION),
                            &devName, // может быть и NULL
                            FILE_DEVICE_UNKNOWN,
                            0,
                            FALSE, // без эксклюзивного доступа
                            &fdo);
    if(!NT_SUCCESS(status)) return status;

    // Получаем указатель на область, предназначенную под
    // структуру расширение устройства
    PEXAMPLE_DEVICE_EXTENSION dx = (PEXAMPLE_DEVICE_EXTENSION)fdo->DeviceExtension;
    dx->fdo = fdo;  // Сохраняем обратный указатель

    // Применяя прием условной компиляции, вводим функцию DbgPrint,
    // сообщения которой мы сможем увидеть в окне DebugView, если
    // выполним сборку нашего драйвера как checked (отладочную)
    // версию:
    #if DBG
    DbgPrint("=Example= FDO %X, DevExt=%X.",fdo,dx);
    #endif

    //=======================================
    // Действия по созданию символьной ссылки
    // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    // очень простой драйвер):
    UNICODE_STRING symLinkName;   // Сформировать символьное имя:
    // #define   SYM_LINK_NAME   L"\\??\\Example"
    // Такого типа символьные ссылки ^^ проходят только в NT.
    // (То есть, если перенести бинарный файл драйвера в
    // Windows 98, то пользовательские приложения заведомо
    // не смогут открыть файл по такой символьной ссылке.)
    // Для того, чтобы ссылка работала в и Windows 98 и в NT,
    // необходимо поступать следующим образом:
    #define    SYM_LINK_NAME    L"\\DosDevices\\Example"
    RtlInitUnicodeString( &symLinkName, SYM_LINK_NAME );
    dx->ustrSymLinkName = symLinkName;
    
    // Создаем символьную ссылку
    status = IoCreateSymbolicLink( &symLinkName, &devName );
    if (!NT_SUCCESS(status))
    { // при неудаче √ удалить Device Object и вернуть управление
        IoDeleteDevice( fdo );
        return status;
        } // Теперь можно вызывать CreateFile("\\\\.\\Example",...);
          // в пользовательских приложениях

        // Объект спин-блокировки, который будем использовать для
        // разнесения во времени выполнения кода обработчика
        // IOCTL запросов. Инициализируем его:
        KeInitializeSpinLock(&MySpinLock);

        // Снова используем условную компиляцию, чтобы выделить код,
        // компилируемый в отладочной версии и не компилируемый в
        // версии free (релизной):
        #if DBG
        DbgPrint("=Example= DriverEntry successfully completed.");
        #endif
        return status;
}
#pragma code_seg() // end INIT section

NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info)
{
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
    return status;
}
//
// (Файл init.cpp)
// ReadWrite_IRPhandler: Берет на себя обработку запросов
// чтения/записи и завершает обработку IRP вызовом CompleteIrp
// с числом переданных/полученных байт (BytesTxd) равным нулю.
// Аргументы:
// Указатель на объект нашего FDO
// Указатель на структуру IRP, поступившего от Диспетчера ввода/вывода
NTSTATUS ReadWrite_IRPhandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp )
{
    ULONG BytesTxd = 0;
    NTSTATUS status = STATUS_SUCCESS; //Завершение с кодом status
    // Задаем печать отладочных сообщений √ если сборка отладочная
    #if DBG
    DbgPrint("-Example- in ReadWrite_IRPhandler.");
    #endif
    return CompleteIrp(Irp,status,BytesTxd);
}

NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    // Задаем печать отладочных сообщений - если сборка отладочная
    #if DBG
    DbgPrint("-Example- Create File is %ws",
        &(IrpStack->FileObject->FileName.Buffer));
    #endif
return CompleteIrp(Irp,STATUS_SUCCESS,0); // Успешное завершение
}


NTSTATUS Close_HandleIRPprocessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    #if DBG
    // Задаем печать отладочных сообщений - если сборка отладочная
    DbgPrint("-Example- In Close handler.");
    #endif
return CompleteIrp(Irp,STATUS_SUCCESS,0);// Успешное завершение
}
NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG BytesTxd =0; // Число переданных/полученных байт (пока 0)
    PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);

    // Получаем указатель на расширение устройства
    PEXAMPLE_DEVICE_EXTENSION dx =
                 (PEXAMPLE_DEVICE_EXTENSION)fdo->DeviceExtension;
    //-------------------------------
    // Выделяем из IRP собственно значение IOCTL кода, по поводу
    // которого случился вызов:
    ULONG ControlCode =
    IrpStack->Parameters.DeviceIoControl.IoControlCode;
    ULONG method = ControlCode & 0x03;

    // Получаем текущее значение уровня IRQL √ приоритета,
    // на котором выполняется поток (вообще говоря, целое число):
    KIRQL irql,
    currentIrql = KeGetCurrentIrql();

    #if DBG
    DbgPrint("-Example- In DeviceControlRoutine (fdo= %X)\n",fdo);
    DbgPrint("-Example- DeviceIoControl: IOCTL %x.", ControlCode );
    if(currentIrql==PASSIVE_LEVEL)
        DbgPrint("-Example- PASSIVE_LEVEL (val=%d)",currentIrql);
    #endif
    // Запрашиваем владение объектом спин-блокировки. В данном
    // примере не выполняется никаких критичных действий, но,
    // вообще говоря, этот прием может быть полезен и даже
    // незаменим, если в приведенном ниже коде должны будут
    // выполнены манипуляции, которые можно делать только
    // эксклюзивно. Пока потоку выделен объект спин-блокировки √
    // никакой другой поток не сможет войти в оператор switch:
    KeAcquireSpinLock(&MySpinLock,&irql);

    // Диспетчеризация по IOCTL кодам:
    switch( ControlCode) {

    #ifndef SMALL_VERSION
    case IOCTL_PRINT_DEBUG_MESS:
    {     // Только вводим сообщение и только в отладочной версии
        #if DBG
        DbgPrint("-Example- IOCTL_PRINT_DEBUG_MESS.");
        #endif
        break;
    }
    case IOCTL_CHANGE_IRQL:
    {
        #if DBG
        // Эксперименты по искусственному повышению
        // IRQL √ только в отладочной версии!
        DbgPrint("-Example- IOCTL_CHANGE_IRQL.");
        KIRQL dl = DISPATCH_LEVEL, // только для распечатки (2)
        oldIrql,
        newIrql=25; // Новый уровень IRQL (например, 25)
        // Устанавливаем newIrql, сохраняя текущий в oldIrql:
        KeRaiseIrql(newIrql,&oldIrql);
        newIrql=KeGetCurrentIrql(); // Что реально получили?

        DbgPrint("-Example- DISPATCH_LEVEL value =%d",dl);
        DbgPrint("-Example- IRQLs are old=%d new=%d",
                        oldIrql,newIrql);
        KeLowerIrql(oldIrql); // Возвращаем старое значение
        #endif
        break;
    }
    #endif // SMALL_VERSION


    case IOCTL_MAKE_SYSTEM_CRASH:
    {
        int errDetected=0;
        char x = (char)0xFF;

        #if    DBG  // Вообще говоря, под NT мы этого уже не увидим:
        DbgPrint("-Example- IOCTL_MAKE_SYSTEM_CRASH.");
        #endif
        // Вызываем системный сбой обращением по нулевому адресу
        __try {
        x = *(char*)0x0L; // ошибочная ситуация
            //^^^^^^^^^^^^ здесь случится сбой NT, но не Win98
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {   // Перехват исключения не работает!
            // Эта занимательная ситуация объяснена в 10.2.6,
            // при рассмотрении объектов спин-блокировок.
            errDetected=1;
        };
        #if DBG
        DbgPrint("-Example- Value of x is %X.",x);
        if(errDetected)
            DbgPrint("-Example- Except detected in Example driver.");
        #endif
        break;
    }

    #ifndef SMALL_VERSION
    case IOCTL_TOUCH_PORT_378H:
    {    
        unsigned short ECRegister = 0x378+0x402;
        #if DBG
        DbgPrint("-Example- IOCTL_TOUCH_PORT_378H.");
        #endif
        // Пробуем программно перевести параллельный порт 378,
        // сконфигурированный средствами BIOS как ECP+EPP, в
        // режим EPP.
        _asm  {
            mov dx,ECRegister ;
            xor al,al    ;
            out dx,al    ;    Установить EPP mode 000
            mov al,095h  ;    Биты 7:5 = 100
            out dx,al    ;    Установить EPP mode 100
        }
        // Подобные действия в приложении пользовательского
        // режима под NT  обязательно привело бы к аварийной
        // выгрузке приложения с сообщением об ошибке!
        // Практически эти пять строк демонстрируют, что можно
        // работать с LPT портом под Windows NT !
        break;
    }

    case IOCTL_SEND_BYTE_TO_USER:
    {    
        // Размер данных, поступивших от пользователя:
        ULONG InputLength = //только лишь для примера
            IrpStack->Parameters.DeviceIoControl.InputBufferLength;
        // Размер буфера для данных, ожидаемых пользователем
        ULONG OutputLength =
        IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
        #if DBG
        DbgPrint("-Example- Buffer outlength %d",OutputLength);
        #endif

        if( OutputLength<1 )
        {// Если не предоставлен буфер √ завершить IRP с ошибкой
            status = STATUS_INVALID_PARAMETER;
            break;
        }
        UCHAR *buff; // unsigned char, привыкаем к новой нотации
        if(method==METHOD_BUFFERED)
        {
            buff = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            #if DBG
            DbgPrint("-Example- Method : BUFFERED.");
            #endif
        }
        else
            if (method==METHOD_NEITHER)
            {
                buff=(unsigned char*)Irp->UserBuffer;
                #if DBG
                DbgPrint("-Example- Method : NEITHER.");
                #endif
            }
            else
            {
                #if DBG
                DbgPrint("-Example- Method : unsupported.");
                #endif
                status = STATUS_INVALID_DEVICE_REQUEST;
                break;
            }
        #if DBG
        DbgPrint("-Example- Buffer address is %08X",buff);
        #endif
        *buff=33;     // Любимое число Штирлица
        BytesTxd = 1; // Передали 1 байт
        break;
    }
    #endif // SMALL_VERSION
    // Ошибочный запрос (код IOCTL, который не обрабатывается):
    default: status = STATUS_INVALID_DEVICE_REQUEST;
    }
    // Освобождение спин-блокировки
    KeReleaseSpinLock(&MySpinLock,irql);

    #if DBG
    DbgPrint("-Example- DeviceIoControl: %d bytes written.", (int)BytesTxd);
    #endif

return CompleteIrp(Irp,status,BytesTxd); // Завершение IRP
}
#pragma code_seg("PAGE")
// Допускает размещение в странично организованной памяти
//
VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject)
{
    PDEVICE_OBJECT    pNextDevObj;
    int i;

    // Задаем печать отладочных сообщений √ если сборка отладочная
    #if DBG
    DbgPrint("-Example- In Unload Routine.");
    #endif
    //==========================================================
    // Нижеприведенные  операции в полномасштабном WDM драйвере
    // следовало бы поместить в обработчике IRP_MJ_PNP запросов
    // с субкодом IRP_MN_REMOVE_DEVICE, но в силу простоты
    // драйвера, сделаем это здесь.
    // Проходим по всем объектам устройств, контролируемым
    // драйвером
    pNextDevObj = pDriverObject->DeviceObject;

    for(i=0; pNextDevObj!=NULL; i++)
    {
        PEXAMPLE_DEVICE_EXTENSION dx =
                (PEXAMPLE_DEVICE_EXTENSION)pNextDevObj->DeviceExtension;
        // Удаляем символьную ссылку и уничтожаем FDO:
        UNICODE_STRING *pLinkName = & (dx->ustrSymLinkName);
        // !!! сохраняем указатель:
        pNextDevObj = pNextDevObj->NextDevice;

        #if DBG
        DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.",
                            i,dx->fdo);
        DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer);
        #endif

        IoDeleteSymbolicLink(pLinkName);
        IoDeleteDevice( dx->fdo);
    }
}
#pragma code_seg() // end PAGE section


1>------ Rebuild All started: Project: drv, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'drv', configuration 'Debug|Win32'
1>Compiling...
1>main.c
1>.\main.c(134) : error C2275: 'PEXAMPLE_DEVICE_EXTENSION' : illegal use of this type as an expression
1>        .\main.c(38) : see declaration of 'PEXAMPLE_DEVICE_EXTENSION'
1>.\main.c(134) : error C2146: syntax error : missing ';' before identifier 'dx'
1>.\main.c(134) : error C2065: 'dx' : undeclared identifier
1>.\main.c(134) : warning C4047: '=' : 'int' differs in levels of indirection from 'PEXAMPLE_DEVICE_EXTENSION'
1>.\main.c(135) : error C2065: 'dx' : undeclared identifier
1>.\main.c(135) : error C2223: left of '->fdo' must point to struct/union
1>.\main.c(149) : error C2275: 'UNICODE_STRING' : illegal use of this type as an expression
1>        C:\WINDDK\2600\inc\ddk\wxp\ntdef.h(1092) : see declaration of 'UNICODE_STRING'
1>.\main.c(149) : error C2146: syntax error : missing ';' before identifier 'symLinkName'
1>.\main.c(149) : error C2065: 'symLinkName' : undeclared identifier
1>.\main.c(158) : error C2065: 'symLinkName' : undeclared identifier
1>.\main.c(158) : warning C4133: 'function' : incompatible types - from 'int *' to 'PUNICODE_STRING'
1>.\main.c(159) : error C2065: 'dx' : undeclared identifier
1>.\main.c(159) : error C2223: left of '->ustrSymLinkName' must point to struct/union
1>.\main.c(159) : error C2065: 'symLinkName' : undeclared identifier
1>.\main.c(162) : error C2065: 'symLinkName' : undeclared identifier
1>.\main.c(162) : warning C4133: 'function' : incompatible types - from 'int *' to 'PUNICODE_STRING'
1>.\main.c(370) : error C2275: 'UCHAR' : illegal use of this type as an expression
1>        C:\WINDDK\2600\inc\ddk\wxp\ntdef.h(409) : see declaration of 'UCHAR'
1>.\main.c(370) : error C2065: 'buff' : undeclared identifier
1>.\main.c(373) : error C2065: 'buff' : undeclared identifier
1>.\main.c(373) : warning C4047: '=' : 'int' differs in levels of indirection from 'PUCHAR'
1>.\main.c(381) : error C2065: 'buff' : undeclared identifier
1>.\main.c(381) : warning C4047: '=' : 'int' differs in levels of indirection from 'unsigned char *'
1>.\main.c(397) : error C2065: 'buff' : undeclared identifier
1>.\main.c(397) : error C2100: illegal indirection
1>Build log was saved at "file://d:\Workplace\_Creative\vc2008\drv\drv\Debug\BuildLog.htm"
1>drv - 19 error(s), 5 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

 

#25 30-07-2010 19:39:34

Re: Эмуляция нажатия кнопок из драйвера [WinXP]

пример из солдатова

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson