Ллирик
|
|
« : 06-10-2015 21:17 » |
|
Здравствуйте! Мой драйвер сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice, отвечает на IRP_MN_QUERY_ID соответствующим образом, винда находит и ставит мой драйвер, вызывает AddDevice, драйвер подключается к стеку и начинает функционировать. Но при перезагрузке винды AddDevice почему-то не вызывается. Приходится выключать - включать это устройство в диспетчере устройств, тогда оно снова начинает функционировать. Чем это лечится?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 07-10-2015 11:03 » |
|
Добрый день) а кто загружает ваш драйвер чтобы он "сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice"?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #2 : 07-10-2015 13:36 » |
|
Добрый день) а кто загружает ваш драйвер чтобы он "сообщает винде о появлении нового устройства с помощью IoReportDetectedDevice"?
Изначально мой драйвер это фильтр клавиатуры. Когда обнаруживается новая клава в AddDevice вызываю IoReportDetectedDevice. Я научился различать стеки устройств, так что AddDevice ведёт себя по-разному, в зависимости от стека.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 07-10-2015 15:10 » |
|
ставите вы его как?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #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
|
|
« Ответ #5 : 07-10-2015 21:24 » |
|
ничего не понял) вы говорили что "Изначально мой драйвер это фильтр клавиатуры" а тут вдруг inf от мыши) а "фильтр клавы, прописываю в реестре, как драйвер класса клавиатур"... а почему не как фильтр? так что лучше сначала и подробно.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #6 : 07-10-2015 22:12 » |
|
ничего не понял) вы говорили что "Изначально мой драйвер это фильтр клавиатуры" а тут вдруг inf от мыши) а "фильтр клавы, прописываю в реестре, как драйвер класса клавиатур"... а почему не как фильтр? так что лучше сначала и подробно.
Всё верно Изначально мой драйвер это фильтр клавиатуры по типу kbfiltr DDK. Прописывается там где Kbclass.sys и стоит под ним, но вдобавок к трём различным функциям, которые он выполняет по работе с клавиатурой, он теперь создаёт виртуальные мыши - по одной на каждую клавиатуру. Я сейчас перевёл кое-что из toaster.c на масм. Сейчас буду тестировать
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #7 : 08-10-2015 00:08 » |
|
Думал, может это из-за того, что я не сделал синхронизацию некоторых IRP, как в toaster.c. Вот сделал. Не помогло
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #8 : 08-10-2015 09:14 » |
|
мало) еще подробнее)
PS Едет автобус по сельской местности и вдруг ломается. Водитель выходит, начанает чинить. Подходит мальчик... - Дядя, а я знаю, что у вас сломалось. - Мальчик, иди не мешай... - Дядя, а я знаю, что у вас сломалось. - Мальчик, я занят, иди поиграй с кем-нибудь. Минут через десять снова мальчик подходит. - Дядя, а я знаю, что у вас cломалось. - Ну что сломалось? После долгой паузы. - Автобус.
|
|
« Последнее редактирование: 08-10-2015 09:17 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #9 : 08-10-2015 15:35 » |
|
Хорошо. Попробую объяснить по порядку. Когда обнаруживается клавиатура, вызывается AddDevice моего драйвера. В ней создаётся устройство №1 и подключается к стеку клавиатуры. Затем тут же создаётся устройство №2, вызывается IoReportDetectedDevice и устройство №2 подключается к устройству, полученному из IoReportDetectedDevice. Далее винда посылает устройству №2 IRP_MN_QUERY_ID и оно отвечает соответствующим образом. Винда находит и ставит inf, приведённый выше. Далее винда повторно вызывает AddDevice, в которой создаётся устройство №3 подключается к стеку мыши и начинает функционировать. Но при перезагрузке винды AddDevice повторно почему-то не вызывается. Соответственно устройство №3 не создаётся.
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #10 : 09-10-2015 16:06 » |
|
А так это обычный драйвер типа kbfiltr естественно с нестандартной функцией KbFilter_ServiceCallback
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #11 : 09-10-2015 18:43 » |
|
Скажите, какая информация Вам ещё нужна и я её предоставлю, а то я уже замаялся блуждать во тьме ища то, не знаю что (я - самоучка)
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #12 : 10-10-2015 19:46 » |
|
выложите код, попробуем разобраться) и опишите словами, что вы собственно хотите достичь)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #13 : 14-10-2015 18:28 » |
|
Теперь уже и я ничего не понимаю Решил упростить код до минимума, чтобы нам с Вами легче разобраться, а он вообще перестал почему-то работать. Похоже к драйверу просто не поступают IRP`ы .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
|
|
« Ответ #14 : 15-10-2015 14:45 » |
|
ох жестоко то как) на асме... это я долго понимаю поэтому посмотреть код успею нескоро(
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #15 : 15-10-2015 15:07 » |
|
Вся суть в приведённом коде в функции DriverEntry1, остальное можно как бы и не смотреть
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #16 : 15-10-2015 23:36 » |
|
Я для Вас сделал код на С /*-- 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 »
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #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
|
|
« Ответ #18 : 19-10-2015 11:54 » |
|
IoReportDetectedDevice routineThe 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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #19 : 19-10-2015 12:44 » |
|
IoReportDetectedDevice routineThe 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
|
|
« Ответ #20 : 20-10-2015 12:56 » |
|
не ну погодите... а зачем вам собственно AddDevice если у вас не PnP? у вас драйвер грузится? делайте все то же самое в DriverEntry.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #21 : 20-10-2015 17:12 » |
|
не ну погодите... а зачем вам собственно AddDevice если у вас не PnP? у вас драйвер грузится? делайте все то же самое в DriverEntry.
Так это просто пример на самом деле в моём драйвере все гораздо сложнее. Мне нужно при подключении реального устройства создать ещё и виртуальное. И это у меня получилось, но действует это только один раз - до перезагрузки компа. Я там подключаюсь сразу к трём стекам устройств, а после перезагрузки ХР третий стек не создаётся
|
|
« Последнее редактирование: 20-10-2015 17:22 от Ллирик »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #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
|
|
« Ответ #24 : 21-10-2015 11:00 » |
|
ну так открываете драйвер и шлете ему какой нить IOCTL.
Добавлено через 57 секунд: типа через какой нить IoGetDeviceObjectPointer
|
|
« Последнее редактирование: 21-10-2015 11:02 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #25 : 21-10-2015 14:20 » |
|
ну так открываете драйвер и шлете ему какой нить IOCTL.
Добавлено через 57 секунд: типа через какой нить IoGetDeviceObjectPointer
Извините ничего не понял Какой драйвер открывать-то, то есть что передавать IoGetDeviceObjectPointer? Какой слать IOCTL да при том ещё и из AddDevice? И как всё это мне поможет, то есть в чём суть всех этих телодвижений?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #26 : 21-10-2015 14:29 » |
|
это я к вопросу о "как я после перезагрузки буду узнавать указатель на устройство шины и различать стеки устройств?")
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #27 : 21-10-2015 15:40 » |
|
Я об этом же Как всё выше сказанное Вами поможет мне узнавать указатель на устройство шины и различать стеки устройств в моей AddDevice?
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #28 : 21-10-2015 21:29 » |
|
Есть ещё вопрос такой: что надо сделать, чтобы запустить по стеку IRP_MN_REMOVE_DEVICE, то есть сказать системе, что legacy-устройство отключили? Если использовать IoInvalidateDeviceState, то почему-то получается BSOD Crash-dump прилагаю
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #29 : 22-10-2015 11:49 » |
|
а у legacy устройства может быть IRP_MN_REMOVE_DEVICE? если ему IRP_MN_START_DEVICE не шлется то скорее всего и IRP_MN_REMOVE_DEVICE ему не нужно?
скорее всего SCManager поможет.. правда это API
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #30 : 22-10-2015 13:35 » |
|
а у legacy устройства может быть IRP_MN_REMOVE_DEVICE? если ему IRP_MN_START_DEVICE не шлется то скорее всего и IRP_MN_REMOVE_DEVICE ему не нужно?
скорее всего SCManager поможет.. правда это API
Но все равно SCManager затем вызывает какую-то функцию ядра. Вопрос какую?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #31 : 22-10-2015 14:33 » |
|
вот тут товарищ x64, говорил что "Legacy-фильтры невыгружаемы (кроме файловых фильтров, поддерживающих fast detach)."... и вот тут ветку гляньте, что то подобное человек делал и похоже с тем же сталкивался...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #32 : 22-10-2015 15:10 » |
|
и вот тут ветку гляньте, что то подобное человек делал и похоже с тем же сталкивался... Да. Я уже эту тему читал. Вот и попробовал IoInvalidateDeviceState, но похоже придётся искать другое решение
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #33 : 22-10-2015 16:47 » |
|
а вообще есть ли в ХР другой способ динамически создавать виртуальные устройства?
|
|
« Последнее редактирование: 22-10-2015 16:49 от Ллирик »
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #34 : 24-10-2015 01:09 » |
|
И invoke IoInvalidateDeviceRelations, [edx].BusMDeviceObject, RemovalRelations почему-то не работает хотя я точно знаю, что после установки inf или после отключения моей мыши в диспетчере устройств IRP_MN_QUERY_DEVICE_RELATIONS RemovalRelations по стеку проходят, а после IoInvalidateDeviceRelations нет
|
|
|
Записан
|
|
|
|
Ллирик
|
|
« Ответ #35 : 31-10-2015 13:46 » |
|
Решил сделать что-то похожее на toaster из DDK, но мне ещё нужен верхний фильтр шины, но он почему-то не грузится. вот Inf: [Version]
Signature="$Windows NT$" Class=System ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} LayoutFile=layout.inf Provider=%Mfg% DriverVer=1/9/2015,1.0
[DestinationDirs] DefaultDestDir = 12
[Manufacturer] %Mfg%=Vendor
[Vendor] %LlirikBus.DeviceDesc%= LlirikBus, root\LlirikBus
[LlirikBus.NT] ; Copy the driver over
CopyFiles=LlirikBus.CopyFiles
[LlirikBus_Device.NT.HW] AddReg=LlirikBus_Device.NT.HW.AddReg
; ; File sections ;
[LlirikBus.CopyFiles] LlirikBus.sys Keymouse.sys
[LlirikBus_Device.NT.HW.AddReg] HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens HKR,,Security,,"D:P(A;;GA;;;BA)(A;;GA;;;SY)" ; Allow generic-all access to Built-in administrators and Local system HKR,,"UpperFilters",0x00010000,"Keymouse" ; ; Service Installation ;
[LlirikBus.NT.Services] AddService = LlirikBus,%SPSVCINST_ASSOCSERVICE%, LlirikBus_Service_Inst AddService = Keymouse,, Keymouse_Service_Inst
[LlirikBus_Service_Inst] DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 0 ; SERVICE_ERROR_IGNORE LoadOrderGroup = Extended Base ServiceBinary = %12%\LlirikBus.sys
[Keymouse_Service_Inst] DisplayName = %KMSvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 0 ; SERVICE_ERROR_IGNORE LoadOrderGroup = PNP Filter ServiceBinary = %12%\Keymouse.sys
[Strings] ;localized strings SPSVCINST_ASSOCSERVICE= 0x00000002 Mfg = "Llirik SoftWare" SvcDesc = "LlirikBus driver" LlirikBus.DeviceDesc = "LlirikBus" KMSvcDesc = "KeyMouse driver" LlirikBus.sys грузится, а Keymouse.sys нет P.S. Шина пока не создаёт никаких дочерних устройств.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #36 : 09-11-2015 15:36 » |
|
проверяем вот так, при помощи утилиты Chkinf из DDK. Errors:
Line 0: (E22.1.1003) Section [SourceDisksNames] not defined. Line 1: (E22.1.1081) Directive: CatalogFile required (and must not be blank) in section [Version] for WHQL digital signature. Line 8: (E22.1.1314) Month must be in two digit format. Line 8: (E22.1.1315) Day must be in two digit format. Warnings:
Line 0: (W22.1.2212) No Copyright information found. Line 0: (W22.1.2111) [SourceDisksFiles] section not defined - full CopyFiles checking not done. Line 6: (W22.1.2202) Unrecognized directive: LayoutFile Line 25: (W22.1.2083) Section [LLIRIKBUS_DEVICE.NT.HW] not referenced Line 33: (W22.1.2112) File "LlirikBus.sys" is not listed in the [SourceDisksFiles]. Line 34: (W22.1.2112) File "Keymouse.sys" is not listed in the [SourceDisksFiles]. Line 36: (W22.1.2083) Section [LLIRIKBUS_DEVICE.NT.HW.ADDREG] not referenced выделенные варнинги - это как раз ответ на ваш вопрос)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ллирик
|
|
« Ответ #37 : 09-11-2015 17:24 » |
|
проверяем вот так, при помощи утилиты Chkinf из DDK. Errors:
Line 0: (E22.1.1003) Section [SourceDisksNames] not defined. Line 1: (E22.1.1081) Directive: CatalogFile required (and must not be blank) in section [Version] for WHQL digital signature. Line 8: (E22.1.1314) Month must be in two digit format. Line 8: (E22.1.1315) Day must be in two digit format. Warnings:
Line 0: (W22.1.2212) No Copyright information found. Line 0: (W22.1.2111) [SourceDisksFiles] section not defined - full CopyFiles checking not done. Line 6: (W22.1.2202) Unrecognized directive: LayoutFile Line 25: (W22.1.2083) Section [LLIRIKBUS_DEVICE.NT.HW] not referenced Line 33: (W22.1.2112) File "LlirikBus.sys" is not listed in the [SourceDisksFiles]. Line 34: (W22.1.2112) File "Keymouse.sys" is not listed in the [SourceDisksFiles]. Line 36: (W22.1.2083) Section [LLIRIKBUS_DEVICE.NT.HW.ADDREG] not referenced выделенные варнинги - это как раз ответ на ваш вопрос) спасибо. разобрался
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #38 : 10-11-2015 12:38 » |
|
пожалуйста, пардон что долго(
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|