Booster Верно - это конечный автомат. Просто мне понравилась и запомнилась эта идея, возможно в связи с тем, что она для меня новая т.к. в ВУЗе нам паттерны не преподавали и встретился я с ними позже. Уже довольно редко я открываю для себя новые горизонты в программировании
Я изучал только ассемблер, но примеров того, что я сейчас делаю, на асме, к сожалению, нет, поэтому приходится копаться в примерах на С. Переведённая мною на асм функция работает (проверял), но я никак не могу получить скан-коды коды клавиш. Вот и хочу выяснить почему
я бы канеш не стал менять структуру из ddk... по поводу ошибок, пробуем так: Код (Text): #ifndef KBFILTER_H #define KBFILTER_H #include "ntddk.h" #include "kbdmou.h" #include <ntddkbd.h> #include <ntdd8042.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT Self; PDEVICE_OBJECT PDO; PDEVICE_OBJECT TopOfStack; BOOLEAN Started; BOOLEAN SurpriseRemoved; BOOLEAN Removed; struct _UPPER_CONNECT { PDEVICE_OBJECT ClassDeviceObject; PVOID ClassService; } UpperConnectData; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; typedef struct _KEYBOARD_INPUT_DATA { USHORT UnitId; USHORT MakeCode; USHORT Flags; USHORT Reserved; ULONG ExtraInformation; } KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA; // // Prototypes // VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed ); NTSTATUS KbFilter_InternIoCtl ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS FiDO_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); #endif // KBFILTER_H Код (Text): #include "kbfiltr.h" #ifdef ALLOC_PRAGMA #pragma alloc_text (PAGE, KbFilter_InternIoCtl) #endif extern int ScanCode; //extern int FiDO_DispatchPassThrough; NTSTATUS KbFilter_InternIoCtl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION devExt; PCONNECT_DATA connectData; NTSTATUS status = STATUS_SUCCESS; devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_INTERNAL_KEYBOARD_CONNECT: 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; } connectData = ((PCONNECT_DATA) (irpStack->Parameters.DeviceIoControl.Type3InputBuffer)); devExt->UpperConnectData = *connectData; connectData->ClassDeviceObject = devExt->Self; connectData->ClassService = KbFilter_ServiceCallback; break; // return FiDO_DispatchPassThrough(DeviceObject, Irp); } VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed ) { PDEVICE_EXTENSION devExt; devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)( devExt->UpperConnectData.ClassDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed); ScanCode = InputDataStart->MakeCode; }
Rel, теперь ошибки: Код (Text): 1>kbfiltr.h(24) : error C2011: '_KEYBOARD_INPUT_DATA' : 'struct' type redefinition 1>kbfiltr.c(40) : error C2115: '=' : incompatible types 1>kbfiltr.c(53) : error C2143: syntax error : missing ';' before 'type' 1>kbfiltr.c(67) : error C2065: 'InputDataStart' : undeclared identifier 1>kbfiltr.c(67) : error C4022: 'function through pointer' : pointer mismatch for actual parameter 2 1>kbfiltr.c(68) : error C2065: 'InputDataEnd' : undeclared identifier 1>kbfiltr.c(68) : error C4022: 'function through pointer' : pointer mismatch for actual parameter 3 1>kbfiltr.c(69) : error C2065: 'InputDataConsumed' : undeclared identifier 1>kbfiltr.c(69) : error C4022: 'function through pointer' : pointer mismatch for actual parameter 4 1>kbfiltr.c(70) : error C2223: left of '->MakeCode' must point to struct/union , а структуру _DEVICE_EXTENSION создаёт сам программист, просто в примере из ddk было: Код (Text): typedef struct _DEVICE_EXTENSION { ................... CONNECT_DATA UpperConnectData; .................... } DEVICE_EXTENSION, *PDEVICE_EXTENSION; а я просто сделал: Код (Text): _DEVICE_EXTENSION STRUCT .................... ClassDeviceObject PDEVICE_OBJECT ? ClassService PVOID ? ...................... _DEVICE_EXTENSION ENDS P_DEVICE_EXTENSION typedef ptr _DEVICE_EXTENSION и у меня размер структуры _DEVICE_EXTENSION почему-то получился меньше на байт
Оказывается просто } не хватало) осталась одна ошибка на строке devExt->UpperConnectData = *connectData; 1>kbfiltr.c(40) : error C2115: '=' : incompatible types
Rel, Благодарю. Код на С работает, но я никак не могу понять, почему получается разница в структурах байт. Оказывается именно из-за этого мой код на асме и не работает. С: асм: С: асм: Почему получается эта разница? Да и вообще правильно ли я перевёл с С на масм?
в си получается 16 потому, что три BOOLEAN'a выравниваются на стандартную границу в 4 байта... в асме, что написали - то и получили)
я вручную выровнял BOOLEAN`ы и коды вроде бы стали идентичны, но код на MASM`е по-прежнему не работает( Что я перевёл не так?? не понимаю( C: Код (Text): .......................... 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; } connectData = ((PCONNECT_DATA) (irpStack->Parameters.DeviceIoControl.Type3InputBuffer)); devExt->UpperConnectData = *((struct _UPPER_CONNECT*)connectData); connectData->ClassDeviceObject = devExt->Self; connectData->ClassService = KbFilter_ServiceCallback; ........................................ VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed ) { PDEVICE_EXTENSION devExt; ScanCode = InputDataStart->MakeCode; devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)( devExt->UpperConnectData.ClassDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed); } MASM: Код (Text): ........................ .if [ecx].icnd.ClassService != NULL mov status, STATUS_SHARING_VIOLATION .elseif [edi].Parameters.DeviceIoControl.InputBufferLength < 8 mov status, STATUS_INVALID_PARAMETER; .else mov eax, [edi].Parameters.DeviceIoControl.Type3InputBuffer assume eax:ptr ICONNECT_DATA mov ebx, [eax].ClassDeviceObject mov [ecx].icnd.ClassDeviceObject, ebx mov ebx, [eax].ClassService mov [ecx].icnd.ClassService, ebx mov ebx, [ecx].Self mov [eax].ClassDeviceObject, ebx mov [eax].ClassService, offset KKbFilter_ServiceCallback ............................................................ KKbFilter_ServiceCallback proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG movzx eax, (KEYBOARD_INPUT_DATA ptr [InputDataEnd]).MakeCode mov ScanCode, eax push InputDataConsumed mov eax, pDeviceObject push InputDataEnd assume eax:ptr DEVICE_OBJECT mov ecx, [eax].DeviceExtension assume eax:nothing assume ecx:ptr FiDO_DEVICE_EXTENSION push InputDataStart push [ecx].icnd.ClassDeviceObject call [ecx].icnd.ClassService ret KKbFilter_ServiceCallback endp Пожалуйста, помогите мне всё-таки докопаться до истины)
Rel, почему я не могу собрать этот проэтк? Выдаёт: Код (Text): 1>d:\winddk\2600~1.110\bin\makefile.def(758) : warning U1050: Your .\sources. file must define the TARGETPATH= macro 1>d:\winddk\2600~1.110\bin\makefile.def(758) : warning U1050: Your .\sources. file must define the TARGETPATH= macro 1>d:\winddk\2600~1.110\bin\makefile.def(758) : warning U1050: Your .\sources. file must define the TARGETPATH= macro
разобрался) теперь пишет: Код (Text): 1>d:\winddk\2600~1.110\bin\i386mk.inc(379) : warning U1023: syntax error in expression 1>d:\winddk\2600~1.110\bin\i386mk.inc(379) : warning U1023: syntax error in expression 1>d:\winddk\2600~1.110\bin\i386mk.inc(379) : warning U1023: syntax error in expression