Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Legacy-устройство  (Прочитано 37921 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« : 06-10-2015 21:17 » 

Здравствуйте! Мой драйвер сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice, отвечает на IRP_MN_QUERY_ID соответствующим образом, винда находит и ставит мой драйвер, вызывает AddDevice, драйвер подключается к стеку и начинает функционировать. Но при перезагрузке винды AddDevice почему-то не вызывается. Приходится выключать - включать это устройство в диспетчере устройств, тогда оно снова начинает функционировать. Чем это лечится?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 07-10-2015 11:03 » 

Добрый день)
а кто загружает ваш драйвер чтобы он "сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice"?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 07-10-2015 13:36 » 

Добрый день)
а кто загружает ваш драйвер чтобы он "сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice"?
Изначально мой драйвер это фильтр клавиатуры. Когда обнаруживается новая клава в AddDevice вызываю IoReportDetectedDevice. Я научился различать стеки устройств, так что AddDevice ведёт себя по-разному, в зависимости от стека.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 07-10-2015 15:10 » 

ставите вы его как?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 07-10-2015 15:38 » 

ставите вы его как?
Если как фильтр клавы, то прописываю его в реестре, как драйвер класса клавиатур, перед kbdclass, а если как драйвер мыши, то вот inf:
Код:
[Version]

Signature="$Windows NT$"
ClassGUID={4D36E96F-E325-11CE-BFC1-08002BE10318}
Class=Mouse
Provider=%VENDOR%
DriverVer=1/9/2015,1.0

[DestinationDirs]
DefaultDestDir   = 12


[Manufacturer]
%VENDOR%=Vendor

[Vendor]
%Keymouse.DeviceDesc%= Keymouse, ROOT\Keymouse
[Keymouse]

; Copy the driver over
CopyFiles=Keymouse.CopyFiles


;
; File sections
;

[Keymouse.CopyFiles]
;Keymouse.sys


;
; Service Installation
;

[Keymouse.Services]
AddService = Keymouse,  , Keymouse_Service_Inst

[Keymouse_Service_Inst]
DisplayName    = %SvcDesc%
ServiceType    = 1                  ; SERVICE_KERNEL_DRIVER
StartType      = 3                  ; SERVICE_DEMAND_START
ErrorControl   = 0                  ; SERVICE_ERROR_IGNORE
LoadOrderGroup = Pointer Port
ServiceBinary  = %12%\Keymouse.sys

[Strings]
;localized strings
VENDOR          = "Llirik SoftWare"
SvcDesc         = "KeyMouse driver"
Keymouse.DeviceDesc   = "KeyMouse"
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 07-10-2015 21:24 » 

ничего не понял) вы говорили что "Изначально мой драйвер это фильтр клавиатуры" а тут вдруг inf от мыши)
а "фильтр клавы, прописываю в реестре, как драйвер класса клавиатур"... а почему не как фильтр?
так что лучше сначала и подробно.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 07-10-2015 22:12 » 

ничего не понял) вы говорили что "Изначально мой драйвер это фильтр клавиатуры" а тут вдруг inf от мыши)
а "фильтр клавы, прописываю в реестре, как драйвер класса клавиатур"... а почему не как фильтр?
так что лучше сначала и подробно.

Всё верно Улыбаюсь Изначально мой драйвер это фильтр клавиатуры по типу kbfiltr DDK. Прописывается там где Kbclass.sys и стоит под ним, но вдобавок к трём различным функциям, которые он выполняет по работе с клавиатурой, он теперь создаёт виртуальные мыши - по одной на каждую клавиатуру.

Я сейчас перевёл кое-что из toaster.c на масм.  Сейчас буду тестировать
Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 08-10-2015 00:08 » 

Думал, может это из-за того, что я не сделал синхронизацию некоторых IRP, как в toaster.c. Вот сделал. Не помогло А черт его знает...
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 08-10-2015 09:14 » 

мало) еще подробнее)

PS
Едет автобус по сельской местности и вдруг ломается.
Водитель выходит, начанает чинить. Подходит мальчик...
- Дядя, а я знаю, что у вас сломалось.
- Мальчик, иди не мешай...
- Дядя, а я знаю, что у вас сломалось.
- Мальчик, я занят, иди поиграй с кем-нибудь.
Минут через десять снова мальчик подходит.
- Дядя, а я знаю, что у вас cломалось.
- Ну что сломалось?
После долгой паузы.
- Автобус.
« Последнее редактирование: 08-10-2015 09:17 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 08-10-2015 15:35 » 

Хорошо. Попробую объяснить по порядку. Когда обнаруживается клавиатура, вызывается AddDevice моего драйвера. В ней создаётся устройство №1 и подключается к стеку клавиатуры. Затем тут же создаётся устройство №2, вызывается IoReportDetectedDevice и устройство №2 подключается к устройству, полученному  из IoReportDetectedDevice. Далее винда посылает устройству №2 IRP_MN_QUERY_ID и оно отвечает соответствующим образом. Винда находит и ставит inf, приведённый выше. Далее винда повторно вызывает AddDevice, в которой создаётся устройство №3 подключается к стеку мыши и начинает функционировать.  Но при перезагрузке винды AddDevice повторно почему-то не вызывается. Соответственно устройство №3 не создаётся.
Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 09-10-2015 16:06 » 

А так это обычный драйвер типа kbfiltr естественно с нестандартной функцией KbFilter_ServiceCallback
Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 09-10-2015 18:43 » 

Скажите, какая информация Вам ещё нужна и я её предоставлю, а то я уже замаялся блуждать во тьме ища то, не знаю что (я - самоучка)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 10-10-2015 19:46 » 

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

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 14-10-2015 18:28 » 

Теперь уже и я ничего не понимаю Здесь была моя ладья... Решил упростить код до минимума, чтобы нам с Вами легче разобраться, а он вообще перестал почему-то работать. Похоже к драйверу просто не поступают IRP`ы
Код: (ASM)
        .386p
option casemap:none
.model flat, stdcall

include \masm32\include\ntstatus.inc
include \masm32\include\ntddk.inc
include \masm32\include\ntdef.inc
include \masm32\include\ntoskrnl.inc
include \masm32\include\ntddkbd.inc
include \masm32\include\ntddmou.inc
include \masm32\include\hal.inc

includelib \masm32\lib\ntoskrnl.lib
includelib \masm32\lib\hal.lib
includelib \masm32\lib\wdm.lib

include \masm32\Macros\Strings.mac

zlpproc proto stdcall
remapproc proto stdcall :PDEVICE_OBJECT
oszlp proto stdcall :PDEVICE_OBJECT

POVTSTRUCT STRUCT
        UnitId                          WORD    ?
        MakeCode                        WORD    ?
        Flags                           WORD    ?
        Reserved                        WORD    ?
        ExtraInformation        DWORD   ?
        pTime                   DWORD   ?
        One                     BYTE    ?
        loctimer                BYTE    ?
    pDevObj PDEVICE_OBJECT ?
        keEvent2 KEVENT <>
        dpc KDPC <>
POVTSTRUCT ENDS
PPOVTSTRUCT typedef ptr POVTSTRUCT
EY_VALUE_PARTIAL_INFORMATION STRUCT     ; sizeof = 10h
        TitleIndex      DWORD   ?
        _Type           DWORD   ?       ; original field name Type
        DataLength      DWORD   ?
        Data            BYTE    ?       ; Variable size
                                db 3 dup(?)     ; padding
EY_VALUE_PARTIAL_INFORMATION ENDS
KKEY_VALUE_PARTIAL_INFORMATION typedef PTR EY_VALUE_PARTIAL_INFORMATION

ICONNECT_DATA STRUCT
    ClassDeviceObject PDEVICE_OBJECT ?
    ClassService PVOID ?
ICONNECT_DATA ENDS
PICONNECT_DATA typedef ptr ICONNECT_DATA

MOUSE_DEVICE_EXTENSION STRUCT
    TopOfStack PDEVICE_OBJECT ?
    UPPER_CONNECT_DATA ICONNECT_DATA <>
    UpperContext PVOID ?
MOUSE_DEVICE_EXTENSION ENDS
PMOUSE_DEVICE_EXTENSION typedef ptr MOUSE_DEVICE_EXTENSION

BUS_DEVICE_EXTENSION STRUCT
    TopOfStack PDEVICE_OBJECT ?
    UPPER_CONNECT_DATA ICONNECT_DATA <>
    UpperContext PVOID ?
BUS_DEVICE_EXTENSION ENDS
PBUS_DEVICE_EXTENSION typedef ptr BUS_DEVICE_EXTENSION
    NotStarted equ 0             ; Not started yet
    Started equ 1                ; Device has received the START_DEVICE IRP
    StopPending equ 3            ; Device has received the QUERY_STOP IRP
    Stopped equ 4                ; Device has received the STOP_DEVICE IRP
    RemovePending equ 5          ; Device has received the QUERY_REMOVE IRP
    SurpriseRemovePending equ 6  ; Device has received the SURPRISE_REMOVE IRP
    Deleted equ 7                ; Device has received the REMOVE_DEVICE IRP
 IOCTL_INTERNAL_KEYBOARD_CONNECT equ CTL_CODE(FILE_DEVICE_KEYBOARD, 0080h, METHOD_NEITHER, FILE_ANY_ACCESS)
IOCTL_INTERNAL_KEYBOARD_DISCONNECT equ CTL_CODE(FILE_DEVICE_KEYBOARD, 0100h, METHOD_NEITHER, FILE_ANY_ACCESS)
IOCTL_INTERNAL_MOUSE_CONNECT equ CTL_CODE(FILE_DEVICE_MOUSE, 0080h, METHOD_NEITHER, FILE_ANY_ACCESS)
IOCTL_INTERNAL_MOUSE_DISCONNECT equ CTL_CODE(FILE_DEVICE_MOUSE, 0100h, METHOD_NEITHER, FILE_ANY_ACCESS)
IOCTL_zlp equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_rem equ CTL_CODE(FILE_DEVICE_UNKNOWN, 802h, METHOD_BUFFERED, FILE_ANY_ACCESS)
.data
nkk dd ?
mkk dd ?
ckk db ?
ikk dd 0
okk dd 0
zl1 db 0
zl1zo db 0
zlos db 0
calllock db 0
calllock2 db 0
povtlock db 0
remlock db 0
remmm db 0
remzlp db 0
povt db 0
readkey db 0
poolkey dd 0
cbpoolkey dd 0
oMakeCode WORD  ?
oFlags WORD     ?
kkkk db 0
povtprov db 0
busguid  dd 0C05EAD84h
 dw 0E34Ch, 04ee2h, 0BF6Ah
db 05Dh, 04Bh, 0B7h, 0D2h, 0B1h, 022h
NumberDevices dw 0
CCOUNTED_UNICODE_STRING    "\\Device\\KeyMouse", Qg_usDeviceName, 4
;CCOUNTED_UNICODE_STRING    "\\HID\\LlirikHIDKeyMouse", hidDeviceName, 4
;CCOUNTED_UNICODE_STRING    "LlirikHIDKeyMouse", hidDeviceName2, 4
BusDeviceName dw "L","l","i","r","i","k","B","u","s","\","K","e","y","M","o","u","s","e", 0, 0
hidDeviceName dw "R","O","O","T","\","K","e","y","m","o","u","s","e", 0, 0
hidDeviceName2 dw "K","e","y","m","o","u","s","e", 0, 0
;CCOUNTED_UNICODE_STRING    "\\HID\\HIDKeyMouse", hidDeviceName, 4
;CCOUNTED_UNICODE_STRING    "HID_DEVICE_SYSTEM_MOUSE", hidDeviceName2, 4

CCOUNTED_UNICODE_STRING    "\\??\\KeyMouse", g_usSymbolicLinkName, 4
CCOUNTED_UNICODE_STRING "\\Registry\\Machine\\Software\\Kmkm", g_usUserKeyName, 4
gzlpKeyDataValueName dw "K","e","y","D","a","t","a"
wee dw "1"
weuuuee dw 0
zlpKeyDataValueName UNICODE_STRING {sizeof gzlpKeyDataValueName +2, sizeof gzlpKeyDataValueName +4, offset gzlpKeyDataValueName}
;;;;;;;;CCOUNTED_UNICODE_STRING "zlpKeyData1", zlpKeyDataValueName, 4
CCOUNTED_UNICODE_STRING "ghKeyData2", KeyData2ValueName, 4
CCOUNTED_UNICODE_STRING "zlpKeyFlag", zlpKeyFlagValueName, 4
CCOUNTED_UNICODE_STRING "KeyFlag2", KeyFlag2ValueName, 4
CCOUNTED_UNICODE_STRING "KeyFlag", KeyFlagValueName, 4
CCOUNTED_UNICODE_STRING "KeyFlag5", KeyFlag5ValueName, 4
CCOUNTED_UNICODE_STRING "KeyFlag4", KeyFlag4ValueName, 4
CCOUNTED_UNICODE_STRING "KeyFlag3", KeyFlag3ValueName, 4
poool dd ?
povtpool dd ?
zlpRegScanCode dd ?
zlpRegScanCodeDop dd ?
zlpRegScanCode2 dd ?
zlpcbCode dd  ?
zlpcbCode2 dd ?
remRegScanCode dd ?
remcbCode dd  ?
povtRegScanCode dd ?
povtcbCode dd  ?
MouseDeviceObject   PDEVICE_OBJECT ?
BusDeviceRel dd 0
ozUnitId                                WORD    ?
;KKEYBOARD_INPUT_DATA STRUCT
        UnitId                          WORD    ?
        MakeCode                        WORD    ?
        Flags                           WORD    ?
;       Reserved                        WORD    ?
;;      ExtraInformation        DWORD   ?
;KKEYBOARD_INPUT_DATA ENDS
;PKKEYBOARD_INPUT_DATA typedef ptr KKEYBOARD_INPUT_DATA
VInputDataStart PKEYBOARD_INPUT_DATA  offset UnitId
VInputDataEnd PKEYBOARD_INPUT_DATA  offset UnitId + 12
VInputDataConsumed PULONG  ?
jkInputDataConsumed ULONG  ?
keEvent KEVENT <>
.code
SetValueKey proc
local as:ANSI_STRING
 local oa:OBJECT_ATTRIBUTES
 local hKey:HANDLE

     lea ecx, oa
     InitializeObjectAttributes ecx, offset g_usUserKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL
     invoke ZwOpenKey, addr hKey, KEY_SET_VALUE, ecx
         invoke ZwSetValueKey, hKey, addr KeyFlagValueName, 0, REG_DWORD, \
                                 addr ikk, sizeof ikk
         invoke ZwSetValueKey, hKey, addr KeyFlag2ValueName, 0, REG_DWORD, \
                                 addr okk, sizeof okk
         invoke ZwSetValueKey, hKey, addr KeyFlag3ValueName, 0, REG_BINARY, \
                                 addr ckk, sizeof ckk
         invoke ZwSetValueKey, hKey, addr KeyFlag4ValueName, 0, REG_DWORD, \
                                 addr mkk, sizeof mkk
         invoke ZwSetValueKey, hKey, addr KeyFlag5ValueName, 0, REG_DWORD, \
                                 addr nkk, sizeof nkk
 invoke ZwClose, hKey
     ret

 SetValueKey endp
spbloc proc pcalllock:DWORD, pbytte:DWORD
invoke KeGetCurrentIrql
        .if eax == DISPATCH_LEVEL
                mov ecx, pbytte
                mov [ecx], al
                invoke KeAcquireSpinLockAtDpcLevel, pcalllock
        .else
                invoke KeAcquireSpinLock, pcalllock, pbytte
        .endif
ret
spbloc endp
relsbbloc proc pcalllock:DWORD
        .if al == DISPATCH_LEVEL
                invoke KeReleaseSpinLockFromDpcLevel, pcalllock
        .else
                 invoke KeReleaseSpinLock, pcalllock, al
        .endif
ret
relsbbloc endp

kbproc proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG
push ecx
        mov     eax, pDeviceObject
assume eax:ptr DEVICE_OBJECT
mov ecx, [eax].DeviceExtension
assume eax:nothing
assume ecx:ptr MOUSE_DEVICE_EXTENSION
        push    InputDataConsumed
        push    InputDataEnd
        push    InputDataStart
        push    [ecx].UPPER_CONNECT_DATA.ClassDeviceObject
        call    [ecx].UPPER_CONNECT_DATA.ClassService
assume ecx:nothing
pop ecx
ret
kbproc endp
killirp proc pIrp:PIRP

     mov eax, pIrp
     assume eax:ptr _IRP
     mov [eax].IoStatus.Status, STATUS_SUCCESS
     and [eax].IoStatus.Information, 0
     assume eax:nothing

     fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
     mov eax, STATUS_SUCCESS
     ret
killirp endp

KbFilter_Complete proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP, pContext:PVOID
     mov eax, pIrp
     assume eax:ptr _IRP
        .if [eax].PendingReturned == TRUE
    invoke KeSetEvent, pContext, IO_NO_INCREMENT, FALSE
        .endif
     assume eax:nothing
    mov eax, STATUS_MORE_PROCESSING_REQUIRED
    ret
KbFilter_Complete endp

FiDO_DispatchPassThrough proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
mov edx, (DEVICE_OBJECT ptr [eax]).DeviceExtension
        mov ecx, (MOUSE_DEVICE_EXTENSION ptr [edx]).TopOfStack
mov edx, pIrp
     assume edx:ptr _IRP
        inc [edx].CurrentLocation
        add [edx].Tail.Overlay.CurrentStackLocation, sizeof IO_STACK_LOCATION
;;;;IoSkipCurrentIrpStackLocation [esp+upIrp]
call    IofCallDriver
ret
FiDO_DispatchPassThrough endp

FiDO_DispatchPower proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

        invoke PoStartNextPowerIrp, pIrp
        invoke FiDO_DispatchPassThrough, pDeviceObject, pIrp
        ret
FiDO_DispatchPower endp

KbFilter_PnP proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
local event:KEVENT
local status:NTSTATUS
push edi
push esi
push ebx
    mov eax, pDeviceObject
assume eax:ptr DEVICE_OBJECT
        mov ebx, [eax].DeviceExtension
assume ebx:ptr MOUSE_DEVICE_EXTENSION
     mov esi, pIrp
     assume esi:ptr _IRP

     mov edi,DWORD PTR [esi+96]
     assume edi:ptr IO_STACK_LOCATION
        .if  [edi].MinorFunction == IRP_MN_REMOVE_DEVICE
    invoke FiDO_DispatchPassThrough, pDeviceObject, pIrp
  mov status, eax
    invoke IoDetachDevice, (MOUSE_DEVICE_EXTENSION ptr [ebx]).TopOfStack
    invoke IoDeleteDevice, pDeviceObject
        .elseif [edi].MinorFunction == IRP_MN_QUERY_ID
.if [edi].Parameters.QueryId.IdType == BusQueryDeviceID
mov status, STATUS_SUCCESS
     mov [esi].IoStatus.Status, STATUS_SUCCESS
     mov [esi].IoStatus.Information, offset hidDeviceName
.elseif [edi].Parameters.QueryId.IdType == BusQueryHardwareIDs
invoke ExAllocatePool, NonPagedPool, sizeof hidDeviceName
    .if eax != NULL
     mov [esi].IoStatus.Status, STATUS_SUCCESS
     mov [esi].IoStatus.Information, eax
push edi
push esi
mov ecx, sizeof hidDeviceName
mov esi, offset hidDeviceName
mov edi, eax
rep       movsb
pop esi
pop edi
inc ikk
mov status, STATUS_SUCCESS
.else
     mov [esi].IoStatus.Status, STATUS_INSUFFICIENT_RESOURCES
mov status, STATUS_INSUFFICIENT_RESOURCES
.endif
.elseif [edi].Parameters.QueryId.IdType == BusQueryInstanceID
mov status, STATUS_SUCCESS
 ;    mov [esi].IoStatus.Status, STATUS_SUCCESS
     mov [esi].IoStatus.Information, 0
.elseif [edi].Parameters.QueryId.IdType == BusQueryCompatibleIDs
     mov [esi].IoStatus.Information, 0
mov status, STATUS_NOT_SUPPORTED
.else
mov status, STATUS_NOT_SUPPORTED
.endif
    fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
        .elseif [edi].MinorFunction == IRP_MN_START_DEVICE
    IoCopyCurrentIrpStackLocationToNext esi
    invoke KeInitializeEvent, addr event, NotificationEvent, FALSE

    IoSetCompletionRoutine esi, KbFilter_Complete, addr event, TRUE, TRUE, TRUE
mov edx, pIrp
        mov ecx, (MOUSE_DEVICE_EXTENSION ptr [ebx]).TopOfStack
call    IofCallDriver
  mov status, eax
   cmp eax, STATUS_PENDING
    jne EXIT_START_DEVICE_SUB
WAIT_DRIVER:
    invoke KeWaitForSingleObject, addr event, Executive, KernelMode, FALSE, 0
   
EXIT_START_DEVICE_SUB:
    push status
    pop [esi].IoStatus.Status
    mov [esi].IoStatus.Information, 0
    fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
.else
     invoke FiDO_DispatchPassThrough, pDeviceObject, pIrp
  mov status, eax
.endif
pop ebx
pop esi
pop edi
     mov eax, status
     assume esi:nothing
ret
KbFilter_PnP    endp
conektproc proc
     assume edi:ptr _IRP
assume esi:ptr IO_STACK_LOCATION
assume edx:ptr MOUSE_DEVICE_EXTENSION
        .if [edx].UPPER_CONNECT_DATA.ClassService != NULL
     mov [edi].IoStatus.Status, STATUS_SHARING_VIOLATION
           mov eax, STATUS_SHARING_VIOLATION
        .elseif [esi].Parameters.DeviceIoControl.InputBufferLength < 8
     mov [edi].IoStatus.Status, STATUS_INVALID_PARAMETER;
   mov eax, STATUS_INVALID_PARAMETER;
    .else
    mov eax, [esi].Parameters.DeviceIoControl.Type3InputBuffer
    assume eax:ptr ICONNECT_DATA
    mov ecx, [eax].ClassDeviceObject
    mov [edx].UPPER_CONNECT_DATA.ClassDeviceObject, ecx
    mov ecx, [eax].ClassService
    mov [edx].UPPER_CONNECT_DATA.ClassService, ecx
    mov [eax].ClassDeviceObject, ebx
             assume eax:nothing
        mov edx, STATUS_SUCCESS
.endif
ret
conektproc endp
CDO_DispatchDeviceControl  proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
local status:NTSTATUS
push ebx
push edi
push esi
     mov edi, pIrp

     assume edi:ptr _IRP

     mov esi,DWORD PTR [edi+96]
     assume esi:ptr IO_STACK_LOCATION
        movzx eax, [esi].MajorFunction
.if eax == IRP_MJ_INTERNAL_DEVICE_CONTROL
     assume esi:ptr IO_STACK_LOCATION
         assume eax:nothing
mov ebx, pDeviceObject
assume ebx:ptr DEVICE_OBJECT
mov edx, [ebx].DeviceExtension
assume edx:ptr MOUSE_DEVICE_EXTENSION
assume ebx:nothing
    .if [esi].Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_CONNECT
invoke conektproc
 .if edx != STATUS_SUCCESS
     push edx
     fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
     pop eax
jmp eehyu
 .endif
    mov (ICONNECT_DATA ptr [eax]).ClassService, offset kbproc
   .elseif [esi].Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT
    mov [edx].UPPER_CONNECT_DATA.ClassDeviceObject, NULL
    mov [edx].UPPER_CONNECT_DATA.ClassService, NULL
      mov status, STATUS_NOT_IMPLEMENTED
.endif
.endif
     invoke FiDO_DispatchPassThrough, pDeviceObject, pIrp
     assume edi:nothing
     assume esi:nothing
     assume edx:nothing
eehyu:
pop esi
pop edi
pop ebx
     ret
CDO_DispatchDeviceControl endp

DriverUnload proc pDriverObject:PDRIVER_OBJECT
mov eax, pDriverObject
invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
mov eax, STATUS_SUCCESS
ret
DriverUnload endp

xKbFilter_AddDevice proc  pDriverObject:PDRIVER_OBJECT, pDeviceObject:PDEVICE_OBJECT
local pMouseDeviceObject:PDEVICE_OBJECT
Invoke IoCreateDevice, pDriverObject, sizeof MOUSE_DEVICE_EXTENSION, 0, FILE_DEVICE_MOUSE, \
                                              0, FALSE, addr pMouseDeviceObject

         .if eax == STATUS_SUCCESS
invoke IoAttachDeviceToDeviceStack, pMouseDeviceObject, pDeviceObject
.if eax != NULL
mov ecx, pMouseDeviceObject
                                        assume eax:ptr DEVICE_OBJECT
                                        assume ecx:ptr DEVICE_OBJECT
                                        mov ebx, [eax].Flags
                                        mov [ecx].Flags,ebx
or [ecx].Flags, DO_BUFFERED_IO or DO_POWER_PAGABLE
and [ecx].Flags, not DO_DEVICE_INITIALIZING
mov edx, [ecx].DeviceExtension
assume edx:ptr MOUSE_DEVICE_EXTENSION
        mov [edx].TopOfStack, eax
             assume eax:nothing
assume edx:nothing
        mov eax, STATUS_SUCCESS
         .else
             invoke IoDeleteDevice, pMouseDeviceObject
            mov eax, STATUS_DEVICE_NOT_CONNECTED
     .endif
        .else
            mov eax, STATUS_DEVICE_NOT_CONNECTED
     .endif
ret
xKbFilter_AddDevice endp


.code INIT
DriverEntry1 proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local BusDeviceObject:PDEVICE_OBJECT
 local status:NTSTATUS
     mov status, STATUS_DEVICE_CONFIGURATION_ERROR
invoke IoCreateDevice, pDriverObject, sizeof BUS_DEVICE_EXTENSION, 0, FILE_DEVICE_BUS_EXTENDER, \
                                               FILE_DEVICE_SECURE_OPEN + FILE_AUTOGENERATED_DEVICE_NAME, FALSE, addr MouseDeviceObject
 .if eax == STATUS_SUCCESS
           mov eax, pDriverObject
             assume eax:PTR DRIVER_OBJECT
        mov ecx, IRP_MJ_MAXIMUM_FUNCTION + 1
        .while ecx
        dec ecx
        mov [eax].MajorFunction[ecx*(sizeof PVOID)], offset FiDO_DispatchPassThrough
        .endw
        mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)], offset CDO_DispatchDeviceControl
        mov [eax].MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL*(sizeof PVOID)], offset CDO_DispatchDeviceControl
        mov [eax].MajorFunction[IRP_MJ_PNP*(sizeof PVOID)], offset KbFilter_PnP
        mov [eax].MajorFunction[IRP_MJ_POWER*(sizeof PVOID)], offset FiDO_DispatchPower
        mov ecx, [eax].DriverExtension
             assume ecx:PTR DRIVER_EXTENSION
        mov [ecx].AddDevice, offset xKbFilter_AddDevice;
        mov [eax].DriverUnload, offset DriverUnload
             assume eax:nothing
             assume ecx:nothing
mov BusDeviceObject, 0
invoke IoReportDetectedDevice, pDriverObject, InterfaceTypeUndefined, -1, -1, NULL, NULL, FALSE, addr BusDeviceObject
         .if eax != STATUS_SUCCESS
            mov status, STATUS_DEVICE_NOT_CONNECTED
             invoke IoDeleteDevice, MouseDeviceObject
.else
invoke IoAttachDeviceToDeviceStack, MouseDeviceObject, BusDeviceObject
.if eax != NULL
inc okk
mov ecx, MouseDeviceObject
                                        assume eax:ptr DEVICE_OBJECT
                                        assume ecx:ptr DEVICE_OBJECT
                                        mov ebx, [eax].Flags
                                        mov [ecx].Flags,ebx
or [ecx].Flags,  DO_BUS_ENUMERATED_DEVICE or DO_POWER_PAGABLE
and [ecx].Flags, not DO_DEVICE_INITIALIZING
assume eax:nothing
mov edx, [ecx].DeviceExtension
assume edx:ptr MOUSE_DEVICE_EXTENSION
        mov [edx].TopOfStack, eax
             assume eax:nothing
assume edx:nothing
            mov status, STATUS_SUCCESS
         .else
            mov status, STATUS_DEVICE_NOT_CONNECTED
             invoke IoDeleteDevice, MouseDeviceObject
.endif
     .endif
.endif

     mov eax, status
ret
DriverEntry1 endp
 end DriverEntry1
и надо в выше приведённом inf`е поменять значение StartType  на 1.
А в драйвере, о котором шла до этого речь выяснилось, что к устройству №3 (в этом коде оно в xKbFilter_AddDevice в переменной pMouseDeviceObject) почему-то не приходят IRP`ы удаления типа: IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE.... Поэтому и не выключается, а соответстенно, наверно, при следующем старте винды оно и не включается.
« Последнее редактирование: 15-10-2015 14:39 от Ochkarik » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 15-10-2015 14:45 » 

ох жестоко то как)
на асме... это я долго понимаю поэтому посмотреть код успею нескоро(
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 15-10-2015 15:07 » 

Вся суть в приведённом коде в функции DriverEntry1, остальное можно как бы и не смотреть Улыбаюсь
Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 15-10-2015 23:36 » 

Я для Вас сделал код на С
Код: (C)
/*--        
Copyright (c) 1998, 1999  Microsoft Corporation

Module Name:

    moufiltr.c

Abstract:

Environment:

    Kernel mode only.

Notes:


--*/


#include "moufiltr.h"

NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING);

#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MouFilter_AddDevice)
#pragma alloc_text (PAGE, MouFilter_CreateClose)
#pragma alloc_text (PAGE, MouFilter_IoCtl)
#pragma alloc_text (PAGE, MouFilter_InternIoCtl)
#pragma alloc_text (PAGE, MouFilter_PnP)
#pragma alloc_text (PAGE, MouFilter_Power)
#pragma alloc_text (PAGE, MouFilter_Unload)
#endif

NTSTATUS
DriverEntry (
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
/*++
Routine Description:

    Initialize the entry points of the driver.

--*/

{
    ULONG i;
    NTSTATUS                 status;
   PDEVICE_OBJECT newPdo;
   PDEVICE_OBJECT deviceObject;
      PSERIAL_DEVICE_EXTENSION deviceExtension;

    UNREFERENCED_PARAMETER (RegistryPath);

    //
    // Fill in all the dispatch entry points with the pass through function
    // and the explicitly fill in the functions we are going to intercept
    //
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = MouFilter_DispatchPassThrough;
    }

    DriverObject->MajorFunction [IRP_MJ_CREATE] =
    DriverObject->MajorFunction [IRP_MJ_CLOSE] =        MouFilter_CreateClose;
    DriverObject->MajorFunction [IRP_MJ_PNP] =          MouFilter_PnP;
    DriverObject->MajorFunction [IRP_MJ_POWER] =        MouFilter_Power;
    DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] =
                                                        MouFilter_InternIoCtl;
    //
    // If you are planning on using this function, you must create another
    // device object to send the requests to.  Please see the considerations
    // comments for MouFilter_DispatchPassThrough for implementation details.
    //
    // DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = MouFilter_IoCtl;

    DriverObject->DriverUnload = MouFilter_Unload;
    DriverObject->DriverExtension->AddDevice = MouFilter_AddDevice;

      newPdo = NULL;

      status = IoReportDetectedDevice(
                   DriverObject,
                   InterfaceTypeUndefined,
                   -1,
                   -1,
                   NULL,
                   NULL,
                   FALSE,
                   &newPdo
               );
 if(status == STATUS_SUCCESS)
        {
   status = IoCreateDevice(DriverObject, sizeof(SERIAL_DEVICE_EXTENSION),
                           NULL, FILE_DEVICE_SERIAL_PORT,
                           FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, TRUE, &deviceObject);
 if(status == STATUS_SUCCESS)
        {
      deviceExtension = deviceObject->DeviceExtension;
      deviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, newPdo);
      deviceExtension->Pdo = newPdo;
      deviceObject->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
    return STATUS_SUCCESS;
        }
        else
    return STATUS_DEVICE_CONFIGURATION_ERROR;
      }
        else
    return STATUS_DEVICE_CONFIGURATION_ERROR;
}

NTSTATUS
MouFilter_AddDevice(
    IN PDRIVER_OBJECT   Driver,
    IN PDEVICE_OBJECT   PDO
    )
{
    PDEVICE_EXTENSION        devExt;
    IO_ERROR_LOG_PACKET      errorLogEntry;
    PDEVICE_OBJECT           device;
     UNICODE_STRING  DeviceName1;
    NTSTATUS                 status = STATUS_SUCCESS;

    PAGED_CODE();

 RtlInitUnicodeString(&DeviceName1, L"\\Device\\MyDevice1");
 
        status = IoCreateDevice(Driver,                  
                            sizeof(DEVICE_EXTENSION),
                            &DeviceName1,            
                            FILE_DEVICE_MOUSE,    
                            0,                  
                            FALSE,              
                            &device            
                            );

    if (!NT_SUCCESS(status)) {
        return (status);
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
    devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);
    if (devExt->TopOfStack == NULL) {
        IoDeleteDevice(device);
        return STATUS_DEVICE_NOT_CONNECTED;
    }

    ASSERT(devExt->TopOfStack);

    devExt->Self =          device;
    devExt->PDO =           PDO;
    devExt->DeviceState =   PowerDeviceD0;

    devExt->SurpriseRemoved = FALSE;
    devExt->Removed =         FALSE;
    devExt->Started =         FALSE;

    device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    device->Flags &= ~DO_DEVICE_INITIALIZING;

    return status;
}

NTSTATUS
MouFilter_Complete(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
/*++
Routine Description:

    Generic completion routine that allows the driver to send the irp down the
    stack, catch it on the way up, and do more processing at the original IRQL.
   
--*/

{
    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;
}

NTSTATUS
MouFilter_CreateClose (
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:

    Maintain a simple count of the creates and closes sent against this device
   
--*/

{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    PDEVICE_EXTENSION   devExt;

    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    status = Irp->IoStatus.Status;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:
   
        if (NULL == devExt->UpperConnectData.ClassService) {
            //
            // No Connection yet.  How can we be enabled?
            //
            status = STATUS_INVALID_DEVICE_STATE;
        }
        else if ( 1 >= InterlockedIncrement(&devExt->EnableCount)) {
            //
            // First time enable here
            //
        }
        else {
            //
            // More than one create was sent down
            //
        }
   
        break;

    case IRP_MJ_CLOSE:

        ASSERT(0 < devExt->EnableCount);
   
        if (0 >= InterlockedDecrement(&devExt->EnableCount)) {
            //
            // successfully closed the device, do any appropriate work here
            //
        }

        break;
    }

    Irp->IoStatus.Status = status;

    //
    // Pass on the create and the close
    //
    return MouFilter_DispatchPassThrough(DeviceObject, Irp);
}

NTSTATUS
MouFilter_DispatchPassThrough(
        IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp
        )
/*++
Routine Description:

    Passes a request on to the lower driver.
     
Considerations:
     
    If you are creating another device object (to communicate with user mode
    via IOCTLs), then this function must act differently based on the intended
    device object.  If the IRP is being sent to the solitary device object, then
    this function should just complete the IRP (becuase there is no more stack
    locations below it).  If the IRP is being sent to the PnP built stack, then
    the IRP should be passed down the stack.
   
    These changes must also be propagated to all the other IRP_MJ dispatch
    functions (such as create, close, cleanup, etc.) as well!

--*/

{
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // Pass the IRP to the target
    //
    IoSkipCurrentIrpStackLocation(Irp);
       
    return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack, Irp);
}          

NTSTATUS
MouFilter_InternIoCtl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for internal device control requests.
    There are two specific control codes that are of interest:
   
    IOCTL_INTERNAL_MOUSE_CONNECT:
        Store the old context and function pointer and replace it with our own.
        This makes life much simpler than intercepting IRPs sent by the RIT and
        modifying them on the way back up.
                                     
    IOCTL_INTERNAL_I8042_HOOK_MOUSE:
        Add in the necessary function pointers and context values so that we can
        alter how the ps/2 mouse is initialized.
                                           
    NOTE:  Handling IOCTL_INTERNAL_I8042_HOOK_MOUSE is *NOT* necessary if
           all you want to do is filter MOUSE_INPUT_DATAs.  You can remove
           the handling code and all related device extension fields and
           functions to conserve space.
                                         
Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/

{
    PIO_STACK_LOCATION          irpStack;
    PDEVICE_EXTENSION           devExt;
    KEVENT                      event;
    PCONNECT_DATA               connectData;
    PINTERNAL_I8042_HOOK_MOUSE  hookMouse;
     UNICODE_STRING DosDeviceName1, DeviceName1;
    NTSTATUS                    status = STATUS_SUCCESS;

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    Irp->IoStatus.Information = 0;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {

    //
    // Connect a mouse class device driver to the port driver.
    //
    case IOCTL_INTERNAL_MOUSE_CONNECT:
        //
        // Only allow one connection.
        //
        if (devExt->UpperConnectData.ClassService != NULL) {
            status = STATUS_SHARING_VIOLATION;
            break;
        }
        else if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(CONNECT_DATA)) {
            //
            // invalid buffer
            //
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // Copy the connection parameters to the device extension.
        //
        connectData = ((PCONNECT_DATA)
            (irpStack->Parameters.DeviceIoControl.Type3InputBuffer));

        devExt->UpperConnectData = *connectData;

        //
        // Hook into the report chain.  Everytime a mouse packet is reported to
        // the system, MouFilter_ServiceCallback will be called
        //
        connectData->ClassDeviceObject = devExt->Self;
        connectData->ClassService = MouFilter_ServiceCallback;

    RtlInitUnicodeString(&DosDeviceName1, L"\\??\\MyDosDevice1");
    RtlInitUnicodeString(&DeviceName1, L"\\Device\\MyDevice1");
IoCreateSymbolicLink(&DosDeviceName1, &DeviceName1);
        break;

    //
    // Disconnect a mouse class device driver from the port driver.
    //
    case IOCTL_INTERNAL_MOUSE_DISCONNECT:

        //
        // Clear the connection parameters in the device extension.
        //
        // devExt->UpperConnectData.ClassDeviceObject = NULL;
        // devExt->UpperConnectData.ClassService = NULL;

        status = STATUS_NOT_IMPLEMENTED;
        break;

    //
    // Attach this driver to the initialization and byte processing of the
    // i8042 (ie PS/2) mouse.  This is only necessary if you want to do PS/2
    // specific functions, otherwise hooking the CONNECT_DATA is sufficient
    //
    case IOCTL_INTERNAL_I8042_HOOK_MOUSE:  

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                 sizeof(INTERNAL_I8042_HOOK_MOUSE)) {
            //
            // invalid buffer
            //
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // Copy the connection parameters to the device extension.
        //
        hookMouse = (PINTERNAL_I8042_HOOK_MOUSE)
            (irpStack->Parameters.DeviceIoControl.Type3InputBuffer);

        //
        // Set isr routine and context and record any values from above this driver
        //
        devExt->UpperContext = hookMouse->Context;
        hookMouse->Context = (PVOID) DeviceObject;

        if (hookMouse->IsrRoutine) {
            devExt->UpperIsrHook = hookMouse->IsrRoutine;
        }
        hookMouse->IsrRoutine = (PI8042_MOUSE_ISR) MouFilter_IsrHook;

        //
        // Store all of the other functions we might need in the future
        //
        devExt->IsrWritePort = hookMouse->IsrWritePort;
        devExt->CallContext = hookMouse->CallContext;
        devExt->QueueMousePacket = hookMouse->QueueMousePacket;

        break;

    //
    // These internal ioctls are not supported by the new PnP model.
    //
#if 0       // obsolete
    case IOCTL_INTERNAL_MOUSE_ENABLE:
    case IOCTL_INTERNAL_MOUSE_DISABLE:
        status = STATUS_NOT_SUPPORTED;
        break;
#endif  // obsolete

    //
    // Might want to capture this in the future.  For now, then pass it down
    // the stack.  These queries must be successful for the RIT to communicate
    // with the mouse.
    //
    case IOCTL_MOUSE_QUERY_ATTRIBUTES:
    default:
        break;
    }

    if (!NT_SUCCESS(status)) {
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
    }

    return MouFilter_DispatchPassThrough(DeviceObject, Irp);
}

NTSTATUS
MouFilter_PnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for plug and play irps

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/

{
    PDEVICE_EXTENSION           devExt;
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;        

    PAGED_CODE();

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE: {

        //
        // The device is starting.
        //
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        KeInitializeEvent(&event,
                          NotificationEvent,
                          FALSE
                          );

        IoSetCompletionRoutine(Irp,
                               (PIO_COMPLETION_ROUTINE) MouFilter_Complete,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE); // No need for Cancel

        status = IoCallDriver(devExt->TopOfStack, 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)) {
            //
            // As we are successfully now back from our start device
            // we can do work.
            //
            devExt->Started = TRUE;
            devExt->Removed = FALSE;
            devExt->SurpriseRemoved = FALSE;
        }

        //
        // 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
        //
        devExt->SurpriseRemoved = TRUE;

        // Remove code here

        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);
        break;

    case IRP_MN_REMOVE_DEVICE:
       
        devExt->Removed = TRUE;

        // remove code here
        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);

        IoDetachDevice(devExt->TopOfStack);
        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(devExt->TopOfStack, Irp);
        break;
    }

    return status;
}

NTSTATUS
MouFilter_Power(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for power irps   Does nothing except
    record the state of the device.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/

{
    PIO_STACK_LOCATION  irpStack;
    PDEVICE_EXTENSION   devExt;
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;

    PAGED_CODE();

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    powerType = irpStack->Parameters.Power.Type;
    powerState = irpStack->Parameters.Power.State;

    switch (irpStack->MinorFunction) {
    case IRP_MN_SET_POWER:
        if (powerType  == DevicePowerState) {
            devExt->DeviceState = powerState.DeviceState;
        }

    case IRP_MN_QUERY_POWER:
    case IRP_MN_WAIT_WAKE:
    case IRP_MN_POWER_SEQUENCE:
    default:
        break;
    }

    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver(devExt->TopOfStack, Irp);
}

BOOLEAN
MouFilter_IsrHook (
    PDEVICE_OBJECT          DeviceObject,
    PMOUSE_INPUT_DATA       CurrentInput,
    POUTPUT_PACKET          CurrentOutput,
    UCHAR                   StatusByte,
    PUCHAR                  DataByte,
    PBOOLEAN                ContinueProcessing,
    PMOUSE_STATE            MouseState,
    PMOUSE_RESET_SUBSTATE   ResetSubState
)
/*++

Remarks:
    i8042prt specific code, if you are writing a packet only filter driver, you
    can remove this function

Arguments:

    DeviceObject - Our context passed during IOCTL_INTERNAL_I8042_HOOK_MOUSE
   
    CurrentInput - Current input packet being formulated by processing all the
                    interrupts

    CurrentOutput - Current list of bytes being written to the mouse or the
                    i8042 port.
                   
    StatusByte    - Byte read from I/O port 60 when the interrupt occurred                                            
   
    DataByte      - Byte read from I/O port 64 when the interrupt occurred.
                    This value can be modified and i8042prt will use this value
                    if ContinueProcessing is TRUE

    ContinueProcessing - If TRUE, i8042prt will proceed with normal processing of
                         the interrupt.  If FALSE, i8042prt will return from the
                         interrupt after this function returns.  Also, if FALSE,
                         it is this functions responsibilityt to report the input
                         packet via the function provided in the hook IOCTL or via
                         queueing a DPC within this driver and calling the
                         service callback function acquired from the connect IOCTL
                                             
Return Value:

    Status is returned.

  --+*/

{
    PDEVICE_EXTENSION   devExt;
    BOOLEAN             retVal = TRUE;

    devExt = DeviceObject->DeviceExtension;

    if (devExt->UpperIsrHook) {
        retVal = (*devExt->UpperIsrHook) (
            devExt->UpperContext,
            CurrentInput,
            CurrentOutput,
            StatusByte,
            DataByte,
            ContinueProcessing,
            MouseState,
            ResetSubState
            );

        if (!retVal || !(*ContinueProcessing)) {
            return retVal;
        }
    }

    *ContinueProcessing = TRUE;
    return retVal;
}

VOID
MouFilter_ServiceCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN PMOUSE_INPUT_DATA InputDataStart,
    IN PMOUSE_INPUT_DATA InputDataEnd,
    IN OUT PULONG InputDataConsumed
    )
/*++

Routine Description:

    Called when there are mouse packets to report to the RIT.  You can do
    anything you like to the packets.  For instance:
   
    o Drop a packet altogether
    o Mutate the contents of a packet
    o Insert packets into the stream
                   
Arguments:

    DeviceObject - Context passed during the connect IOCTL
   
    InputDataStart - First packet to be reported
   
    InputDataEnd - One past the last packet to be reported.  Total number of
                   packets is equal to InputDataEnd - InputDataStart
   
    InputDataConsumed - Set to the total number of packets consumed by the RIT
                        (via the function pointer we replaced in the connect
                        IOCTL)

Return Value:

    Status is returned.

--*/

{
    PDEVICE_EXTENSION   devExt;

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //
    // UpperConnectData must be called at DISPATCH
    //
    (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
        devExt->UpperConnectData.ClassDeviceObject,
        InputDataStart,
        InputDataEnd,
        InputDataConsumed
        );
}

VOID
MouFilter_Unload(
   IN PDRIVER_OBJECT Driver
   )
/*++

Routine Description:

   Free all the allocated resources associated with this driver.

Arguments:

   DriverObject - Pointer to the driver object.

Return Value:

   None.

--*/


{
    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    ASSERT(NULL == Driver->DeviceObject);
}
Прошу прощения за мой плохой С. Я его как бы не учил и знаю его лишь постольку поскольку Скромно так...
« Последнее редактирование: 27-11-2015 11:19 от Ochkarik » Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 19-10-2015 02:07 » 

Прошу прощения. Я в код на С забыл добавить обработку IRP_MN_QUERY_ID Скромно так... Вот рабочий вариант
Код:
/*--         
Copyright (c) 1998, 1999  Microsoft Corporation

Module Name:

    moufiltr.c

Abstract:

Environment:

    Kernel mode only.

Notes:


--*/

#include "moufiltr.h"

NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING);

#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MouFilter_AddDevice)
#pragma alloc_text (PAGE, MouFilter_CreateClose)
#pragma alloc_text (PAGE, MouFilter_IoCtl)
#pragma alloc_text (PAGE, MouFilter_InternIoCtl)
#pragma alloc_text (PAGE, MouFilter_PnP)
#pragma alloc_text (PAGE, MouFilter_Power)
#pragma alloc_text (PAGE, MouFilter_Unload)
#endif

NTSTATUS
DriverEntry (
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
/*++
Routine Description:

    Initialize the entry points of the driver.

--*/
{
    ULONG i;
    NTSTATUS                 status;
   PDEVICE_OBJECT newPdo;
   PDEVICE_OBJECT deviceObject;
      PSERIAL_DEVICE_EXTENSION deviceExtension;

    UNREFERENCED_PARAMETER (RegistryPath);

    //
    // Fill in all the dispatch entry points with the pass through function
    // and the explicitly fill in the functions we are going to intercept
    //
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = MouFilter_DispatchPassThrough;
    }

    DriverObject->MajorFunction [IRP_MJ_CREATE] =
    DriverObject->MajorFunction [IRP_MJ_CLOSE] =        MouFilter_CreateClose;
    DriverObject->MajorFunction [IRP_MJ_PNP] =          MouFilter_PnP;
    DriverObject->MajorFunction [IRP_MJ_POWER] =        MouFilter_Power;
    DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] =
                                                        MouFilter_InternIoCtl;
    //
    // If you are planning on using this function, you must create another
    // device object to send the requests to.  Please see the considerations
    // comments for MouFilter_DispatchPassThrough for implementation details.
    //
    // DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = MouFilter_IoCtl;

    DriverObject->DriverUnload = MouFilter_Unload;
    DriverObject->DriverExtension->AddDevice = MouFilter_AddDevice;

      newPdo = NULL;

      status = IoReportDetectedDevice(
                   DriverObject,
                   InterfaceTypeUndefined,
                   -1,
                   -1,
                   NULL,
                   NULL,
                   FALSE,
                   &newPdo
               );
 if(status == STATUS_SUCCESS)
{
   status = IoCreateDevice(DriverObject, sizeof(SERIAL_DEVICE_EXTENSION),
                           NULL, FILE_DEVICE_SERIAL_PORT,
                           FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, TRUE, &deviceObject);
 if(status == STATUS_SUCCESS)
{
      deviceExtension = deviceObject->DeviceExtension;
      deviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, newPdo);
      deviceExtension->Pdo = newPdo;
      deviceObject->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
    return STATUS_SUCCESS;
}
else
    return STATUS_DEVICE_CONFIGURATION_ERROR;
      }
else
    return STATUS_DEVICE_CONFIGURATION_ERROR;
}

NTSTATUS
MouFilter_AddDevice(
    IN PDRIVER_OBJECT   Driver,
    IN PDEVICE_OBJECT   PDO
    )
{
    PDEVICE_EXTENSION        devExt;
    IO_ERROR_LOG_PACKET      errorLogEntry;
    PDEVICE_OBJECT           device;
    NTSTATUS                 status = STATUS_SUCCESS;

    PAGED_CODE();

        status = IoCreateDevice(Driver,                   
                            sizeof(DEVICE_EXTENSION),
                            NULL,
                            FILE_DEVICE_MOUSE,   
                            0,                   
                            FALSE,             
                            &device           
                            );

    if (!NT_SUCCESS(status)) {
        return (status);
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
    devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);
    if (devExt->TopOfStack == NULL) {
        IoDeleteDevice(device);
        return STATUS_DEVICE_NOT_CONNECTED;
    }

    ASSERT(devExt->TopOfStack);

    devExt->Self =          device;
    devExt->PDO =           PDO;
    devExt->DeviceState =   PowerDeviceD0;

    devExt->SurpriseRemoved = FALSE;
    devExt->Removed =         FALSE;
    devExt->Started =         FALSE;

    device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    device->Flags &= ~DO_DEVICE_INITIALIZING;

    return status;
}

NTSTATUS
MouFilter_Complete(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
/*++
Routine Description:

    Generic completion routine that allows the driver to send the irp down the
    stack, catch it on the way up, and do more processing at the original IRQL.
   
--*/
{
    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;
}

NTSTATUS
MouFilter_CreateClose (
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:

    Maintain a simple count of the creates and closes sent against this device
   
--*/
{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    PDEVICE_EXTENSION   devExt;

    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    status = Irp->IoStatus.Status;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:
   
        if (NULL == devExt->UpperConnectData.ClassService) {
            //
            // No Connection yet.  How can we be enabled?
            //
            status = STATUS_INVALID_DEVICE_STATE;
        }
        else if ( 1 >= InterlockedIncrement(&devExt->EnableCount)) {
            //
            // First time enable here
            //
        }
        else {
            //
            // More than one create was sent down
            //
        }
   
        break;

    case IRP_MJ_CLOSE:

        ASSERT(0 < devExt->EnableCount);
   
        if (0 >= InterlockedDecrement(&devExt->EnableCount)) {
            //
            // successfully closed the device, do any appropriate work here
            //
        }

        break;
    }

    Irp->IoStatus.Status = status;

    //
    // Pass on the create and the close
    //
    return MouFilter_DispatchPassThrough(DeviceObject, Irp);
}

NTSTATUS
MouFilter_DispatchPassThrough(
        IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp
        )
/*++
Routine Description:

    Passes a request on to the lower driver.
     
Considerations:
     
    If you are creating another device object (to communicate with user mode
    via IOCTLs), then this function must act differently based on the intended
    device object.  If the IRP is being sent to the solitary device object, then
    this function should just complete the IRP (becuase there is no more stack
    locations below it).  If the IRP is being sent to the PnP built stack, then
    the IRP should be passed down the stack.
   
    These changes must also be propagated to all the other IRP_MJ dispatch
    functions (such as create, close, cleanup, etc.) as well!

--*/
{
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // Pass the IRP to the target
    //
    IoSkipCurrentIrpStackLocation(Irp);
       
    return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack, Irp);
}           

NTSTATUS
MouFilter_InternIoCtl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for internal device control requests.
    There are two specific control codes that are of interest:
   
    IOCTL_INTERNAL_MOUSE_CONNECT:
        Store the old context and function pointer and replace it with our own.
        This makes life much simpler than intercepting IRPs sent by the RIT and
        modifying them on the way back up.
                                     
    IOCTL_INTERNAL_I8042_HOOK_MOUSE:
        Add in the necessary function pointers and context values so that we can
        alter how the ps/2 mouse is initialized.
                                           
    NOTE:  Handling IOCTL_INTERNAL_I8042_HOOK_MOUSE is *NOT* necessary if
           all you want to do is filter MOUSE_INPUT_DATAs.  You can remove
           the handling code and all related device extension fields and
           functions to conserve space.
                                         
Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/
{
    PIO_STACK_LOCATION          irpStack;
    PDEVICE_EXTENSION           devExt;
    KEVENT                      event;
    PCONNECT_DATA               connectData;
    PINTERNAL_I8042_HOOK_MOUSE  hookMouse;
    NTSTATUS                    status = STATUS_SUCCESS;

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    Irp->IoStatus.Information = 0;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {

    //
    // Connect a mouse class device driver to the port driver.
    //
    case IOCTL_INTERNAL_MOUSE_CONNECT:
        //
        // Only allow one connection.
        //
        if (devExt->UpperConnectData.ClassService != NULL) {
            status = STATUS_SHARING_VIOLATION;
            break;
        }
        else if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(CONNECT_DATA)) {
            //
            // invalid buffer
            //
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // Copy the connection parameters to the device extension.
        //
        connectData = ((PCONNECT_DATA)
            (irpStack->Parameters.DeviceIoControl.Type3InputBuffer));

        devExt->UpperConnectData = *connectData;

        //
        // Hook into the report chain.  Everytime a mouse packet is reported to
        // the system, MouFilter_ServiceCallback will be called
        //
        connectData->ClassDeviceObject = devExt->Self;
        connectData->ClassService = MouFilter_ServiceCallback;
        break;

    //
    // Disconnect a mouse class device driver from the port driver.
    //
    case IOCTL_INTERNAL_MOUSE_DISCONNECT:

        //
        // Clear the connection parameters in the device extension.
        //
        // devExt->UpperConnectData.ClassDeviceObject = NULL;
        // devExt->UpperConnectData.ClassService = NULL;

        status = STATUS_NOT_IMPLEMENTED;
        break;

    //
    // Attach this driver to the initialization and byte processing of the
    // i8042 (ie PS/2) mouse.  This is only necessary if you want to do PS/2
    // specific functions, otherwise hooking the CONNECT_DATA is sufficient
    //
    case IOCTL_INTERNAL_I8042_HOOK_MOUSE:   

        if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                 sizeof(INTERNAL_I8042_HOOK_MOUSE)) {
            //
            // invalid buffer
            //
            status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // Copy the connection parameters to the device extension.
        //
        hookMouse = (PINTERNAL_I8042_HOOK_MOUSE)
            (irpStack->Parameters.DeviceIoControl.Type3InputBuffer);

        //
        // Set isr routine and context and record any values from above this driver
        //
        devExt->UpperContext = hookMouse->Context;
        hookMouse->Context = (PVOID) DeviceObject;

        if (hookMouse->IsrRoutine) {
            devExt->UpperIsrHook = hookMouse->IsrRoutine;
        }
        hookMouse->IsrRoutine = (PI8042_MOUSE_ISR) MouFilter_IsrHook;

        //
        // Store all of the other functions we might need in the future
        //
        devExt->IsrWritePort = hookMouse->IsrWritePort;
        devExt->CallContext = hookMouse->CallContext;
        devExt->QueueMousePacket = hookMouse->QueueMousePacket;

        break;

    //
    // These internal ioctls are not supported by the new PnP model.
    //
#if 0       // obsolete
    case IOCTL_INTERNAL_MOUSE_ENABLE:
    case IOCTL_INTERNAL_MOUSE_DISABLE:
        status = STATUS_NOT_SUPPORTED;
        break;
#endif  // obsolete

    //
    // Might want to capture this in the future.  For now, then pass it down
    // the stack.  These queries must be successful for the RIT to communicate
    // with the mouse.
    //
    case IOCTL_MOUSE_QUERY_ATTRIBUTES:
    default:
        break;
    }

    if (!NT_SUCCESS(status)) {
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
    }

    return MouFilter_DispatchPassThrough(DeviceObject, Irp);
}

NTSTATUS
MouFilter_PnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for plug and play irps

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/
{
    PDEVICE_EXTENSION           devExt;
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;       
    PWCHAR                  buffer;
UNICODE_STRING devId;
    PAGED_CODE();

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE: {

        //
        // The device is starting.
        //
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        KeInitializeEvent(&event,
                          NotificationEvent,
                          FALSE
                          );

        IoSetCompletionRoutine(Irp,
                               (PIO_COMPLETION_ROUTINE) MouFilter_Complete,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE); // No need for Cancel

        status = IoCallDriver(devExt->TopOfStack, 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)) {
            //
            // As we are successfully now back from our start device
            // we can do work.
            //
            devExt->Started = TRUE;
            devExt->Removed = FALSE;
            devExt->SurpriseRemoved = FALSE;
        }

        //
        // 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
        //
        devExt->SurpriseRemoved = TRUE;

        // Remove code here

        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);
        break;

    case IRP_MN_REMOVE_DEVICE:
       
        devExt->Removed = TRUE;

        // remove code here
        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);

        IoDetachDevice(devExt->TopOfStack);
        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:
break;
    case IRP_MN_QUERY_ID:
RtlInitUnicodeString(&devId, L"ROOT\\Keymouse\0");
     switch (irpStack->Parameters.QueryId.IdType) {
//LPWSTR  devId = L"ROOT\\Keymouse\0";
    case BusQueryDeviceID:
        Irp->IoStatus.Information = (ULONG_PTR) devId.Buffer;

    case BusQueryHardwareIDs:

         buffer = ExAllocatePool (PagedPool, devId.MaximumLength);
        if (!buffer) {
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
       }
else
        RtlCopyMemory (buffer, devId.Buffer, devId.MaximumLength);
        Irp->IoStatus.Information =  (ULONG_PTR) buffer;
       }
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
return  STATUS_SUCCESS;
       
   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(devExt->TopOfStack, Irp);
        break;
    }

    return status;
}

NTSTATUS
MouFilter_Power(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for power irps   Does nothing except
    record the state of the device.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/
{
    PIO_STACK_LOCATION  irpStack;
    PDEVICE_EXTENSION   devExt;
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;

    PAGED_CODE();

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    powerType = irpStack->Parameters.Power.Type;
    powerState = irpStack->Parameters.Power.State;

    switch (irpStack->MinorFunction) {
    case IRP_MN_SET_POWER:
        if (powerType  == DevicePowerState) {
            devExt->DeviceState = powerState.DeviceState;
        }

    case IRP_MN_QUERY_POWER:
    case IRP_MN_WAIT_WAKE:
    case IRP_MN_POWER_SEQUENCE:
    default:
        break;
    }

    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver(devExt->TopOfStack, Irp);
}

BOOLEAN
MouFilter_IsrHook (
    PDEVICE_OBJECT          DeviceObject,
    PMOUSE_INPUT_DATA       CurrentInput,
    POUTPUT_PACKET          CurrentOutput,
    UCHAR                   StatusByte,
    PUCHAR                  DataByte,
    PBOOLEAN                ContinueProcessing,
    PMOUSE_STATE            MouseState,
    PMOUSE_RESET_SUBSTATE   ResetSubState
)
/*++

Remarks:
    i8042prt specific code, if you are writing a packet only filter driver, you
    can remove this function

Arguments:

    DeviceObject - Our context passed during IOCTL_INTERNAL_I8042_HOOK_MOUSE
   
    CurrentInput - Current input packet being formulated by processing all the
                    interrupts

    CurrentOutput - Current list of bytes being written to the mouse or the
                    i8042 port.
                   
    StatusByte    - Byte read from I/O port 60 when the interrupt occurred                                           
   
    DataByte      - Byte read from I/O port 64 when the interrupt occurred.
                    This value can be modified and i8042prt will use this value
                    if ContinueProcessing is TRUE

    ContinueProcessing - If TRUE, i8042prt will proceed with normal processing of
                         the interrupt.  If FALSE, i8042prt will return from the
                         interrupt after this function returns.  Also, if FALSE,
                         it is this functions responsibilityt to report the input
                         packet via the function provided in the hook IOCTL or via
                         queueing a DPC within this driver and calling the
                         service callback function acquired from the connect IOCTL
                                             
Return Value:

    Status is returned.

  --+*/
{
    PDEVICE_EXTENSION   devExt;
    BOOLEAN             retVal = TRUE;

    devExt = DeviceObject->DeviceExtension;

    if (devExt->UpperIsrHook) {
        retVal = (*devExt->UpperIsrHook) (
            devExt->UpperContext,
            CurrentInput,
            CurrentOutput,
            StatusByte,
            DataByte,
            ContinueProcessing,
            MouseState,
            ResetSubState
            );

        if (!retVal || !(*ContinueProcessing)) {
            return retVal;
        }
    }

    *ContinueProcessing = TRUE;
    return retVal;
}

VOID
MouFilter_ServiceCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN PMOUSE_INPUT_DATA InputDataStart,
    IN PMOUSE_INPUT_DATA InputDataEnd,
    IN OUT PULONG InputDataConsumed
    )
/*++

Routine Description:

    Called when there are mouse packets to report to the RIT.  You can do
    anything you like to the packets.  For instance:
   
    o Drop a packet altogether
    o Mutate the contents of a packet
    o Insert packets into the stream
                   
Arguments:

    DeviceObject - Context passed during the connect IOCTL
   
    InputDataStart - First packet to be reported
   
    InputDataEnd - One past the last packet to be reported.  Total number of
                   packets is equal to InputDataEnd - InputDataStart
   
    InputDataConsumed - Set to the total number of packets consumed by the RIT
                        (via the function pointer we replaced in the connect
                        IOCTL)

Return Value:

    Status is returned.

--*/
{
    PDEVICE_EXTENSION   devExt;

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //
    // UpperConnectData must be called at DISPATCH
    //
    (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
        devExt->UpperConnectData.ClassDeviceObject,
        InputDataStart,
        InputDataEnd,
        InputDataConsumed
        );
}

VOID
MouFilter_Unload(
   IN PDRIVER_OBJECT Driver
   )
/*++

Routine Description:

   Free all the allocated resources associated with this driver.

Arguments:

   DriverObject - Pointer to the driver object.

Return Value:

   None.

--*/

{
    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    ASSERT(NULL == Driver->DeviceObject);
}
Теперь главный вопрос. Почему у этого драйвера не вызывается AddDevice?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 19-10-2015 11:54 » new

IoReportDetectedDevice routine
Цитата
The PnP manager considers the device to be started and therefore does not call the driver's AddDevice routine and does not send an IRP_MN_START_DEVICE request. The driver must be prepared to handle all other PnP IRPs, however.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 19-10-2015 12:44 » 

IoReportDetectedDevice routine
Цитата
The PnP manager considers the device to be started and therefore does not call the driver's AddDevice routine and does not send an IRP_MN_START_DEVICE request. The driver must be prepared to handle all other PnP IRPs, however.
А по-русски можно? английский я плохо знаю

Добавлено через 1 час, 10 минут и 55 секунд:
Если я правильно перевёл, то Менеджер PnP полагает, что устройство запущено и поэтому не вызывает AddDevice драйвера и не отправляет запрос IRP_MN_START_DEVICE. Но если вызвать IoReportDetectedDevice не из DriverEntry, то Менеджер PnP в первый раз всё выше сказанное делает. Вопрос: как дать понять Менеджеру PnP, что устройство не запущено, чтобы он каждый раз при старте винды его запускал?
« Последнее редактирование: 20-10-2015 12:35 от Ллирик » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 20-10-2015 12:56 » 

не ну погодите... а зачем вам собственно AddDevice если у вас не PnP? у вас драйвер грузится? делайте все то же самое в DriverEntry.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 20-10-2015 17:12 » 

не ну погодите... а зачем вам собственно AddDevice если у вас не PnP? у вас драйвер грузится? делайте все то же самое в DriverEntry.
Так это просто пример Улыбаюсь на самом деле в моём драйвере все гораздо сложнее. Мне нужно при подключении реального устройства создать ещё и виртуальное. И это у меня получилось, но действует это только один раз - до перезагрузки компа.
Я там подключаюсь сразу к трём стекам устройств, а после перезагрузки ХР третий стек не создаётся Жаль
« Последнее редактирование: 20-10-2015 17:22 от Ллирик » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 20-10-2015 17:34 » 

там же предлагают
Цитата
Drivers only need to call IoReportDetectedDevice the first time they are loaded because the PnP manager caches the reported information. Drivers that use this routine should store a flag in the registry to indicate whether they have already done device detection.one device detection.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 20-10-2015 18:33 » 

там же предлагают
Цитата
Drivers only need to call IoReportDetectedDevice the first time they are loaded because the PnP manager caches the reported information. Drivers that use this routine should store a flag in the registry to indicate whether they have already done device detection.one device detection.
Я эту инфу вчера в инете уже нашёл на русском языке и думал об этом. Но если я буду вызывать IoReportDetectedDevice только один раз то вернётся другая проблема над которой я уже прилично поломал голову, как я после перезагрузки буду узнавать указатель на устройство шины и различать стеки устройств?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 21-10-2015 11:00 » 

ну так открываете драйвер и шлете ему какой нить IOCTL.

Добавлено через 57 секунд:
типа через какой нить IoGetDeviceObjectPointer
« Последнее редактирование: 21-10-2015 11:02 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 21-10-2015 14:20 » 

ну так открываете драйвер и шлете ему какой нить IOCTL.

Добавлено через 57 секунд:
типа через какой нить IoGetDeviceObjectPointer
Извините ничего не понял С ума сойти... Какой драйвер открывать-то, то есть что передавать IoGetDeviceObjectPointer? Какой слать IOCTL да при том ещё и из AddDevice? И как всё это мне поможет, то есть в чём суть всех этих телодвижений? Я шокирован! Не понял
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 21-10-2015 14:29 » 

это я к вопросу о "как я после перезагрузки буду узнавать указатель на устройство шины и различать стеки устройств?")
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 21-10-2015 15:40 » 

Я об этом же Улыбаюсь Как всё выше сказанное Вами поможет мне узнавать указатель на устройство шины и различать стеки устройств в моей AddDevice?
Записан
Ллирик
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 21-10-2015 21:29 » 

Есть ещё вопрос такой: что надо сделать, чтобы запустить по стеку IRP_MN_REMOVE_DEVICE, то есть сказать системе, что legacy-устройство отключили? Если использовать IoInvalidateDeviceState, то почему-то получается BSOD Жаль Crash-dump прилагаю

* Mini102015-02.dmp (92 Кб - загружено 668 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 22-10-2015 11:49 » 

а у legacy устройства может быть IRP_MN_REMOVE_DEVICE?  если ему IRP_MN_START_DEVICE  не шлется то скорее всего и IRP_MN_REMOVE_DEVICE ему не нужно?

скорее всего SCManager поможет.. правда это API
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines