InputApc()函数是如何调用ProcessKeyboardInput()函数的?
InputApc()函数是如何调用ProcessKeyboardInput()函数的?下面是调用栈,这篇文章是表明第五行到第四行的。
.//ntuser/kernel/ntinput.c:2601:VOID xxxKeyEvent(
.//windows/core/ntuser/kernel/ntinput.c:4664:VOID xxxProcessKeyEvent(
.//core/ntuser/kernel/ntinput.c:58:VOID ProcessKeyboardInputWorker(PKEYBOARD_INPUT_DATA pkei,
.//core/ntuser/kernel/ntinput.c:4608:VOID ProcessKeyboardInput(PDEVICEINFO pDeviceInfo)
.//windows/core/ntuser/kernel/ntinput.c:2032:VOID NTAPI InputApc(
第一部分:userk.h
第一部分A
typedef struct tagKEYBOARD_DEVICE_INFO { // DEVICE_TYPE_KEYBOARD
KEYBOARD_ATTRIBUTES Attr;
KEYBOARD_ID_EX IdEx;
KEYBOARD_INPUT_DATA Data;
} KEYBOARD_DEVICE_INFO, *PKEYBOARD_DEVICE_INFO;
第一部分B
typedef struct tagGENERIC_DEVICE_INFO {
#ifdef GENERIC_INPUT
HEAD head;
#endif
struct tagDEVICEINFO *pNext;
BYTE type;
BYTE bFlags;
USHORT usActions;
BYTE nRetryRead;
UNICODE_STRING ustrName;
HANDLE handle;
PVOID NotificationEntry;
PKEVENT pkeHidChangeCompleted; // wake RequestDeviceChange()
IO_STATUS_BLOCK iosb;
NTSTATUS ReadStatus;
#ifdef DIAGNOSE_IO
HANDLE OpenerProcess;
NTSTATUS OpenStatus;
NTSTATUS AttrStatus;
ULONG timeStartRead; // tick before ZwReadFile
ULONG timeEndRead; // tick after ZwReadFile
int nReadsOutstanding; // ZwReadFile ++, consume data --
#endif
#ifdef PRERELEASE
UINT fForcedDetach : 1; // Set if the device is forced detached from TS
#endif
} GENERIC_DEVICE_INFO, *PGENERIC_DEVICE_INFO;
第一部分C
// valuse for GENERIC_DEVICE_INFO.type
#define DEVICE_TYPE_MOUSE 0
#define DEVICE_TYPE_KEYBOARD 1
#ifdef GENERIC_INPUT
#define DEVICE_TYPE_HID 2
#define DEVICE_TYPE_MAX 2
#else
#define DEVICE_TYPE_MAX 1
#endif
第一部分D
typedef struct tagDEVICEINFO {
GENERIC_DEVICE_INFO;
union {
MOUSE_DEVICE_INFO mouse;
KEYBOARD_DEVICE_INFO keyboard;
#ifdef GENERIC_INPUT
HID_DEVICE_INFO hid;
#endif
};
} DEVICEINFO, *PDEVICEINFO;
第一部分E
typedef struct tagDEVICE_TEMPLATE {
SIZE_T cbDeviceInfo; // bytes to allocate for DEVICEINFO
const GUID *pClassGUID; // GUID of the class
UINT uiRegistrySection; // Parameters for class (HKLM\SYSTEM\CurrentControlSet\Services\*\Parameters)
LPWSTR pwszClassName; // Class name (eg: L"mouclass")
LPWSTR pwszDefDevName; // Default Device Name
LPWSTR pwszLegacyDevName; // Legacy Device Name (eg: "PointerClassLegacy0")
ULONG IOCTL_Attr; // IOCTL_*_QUERY_ATTRIBUTES
UINT offAttr; // offset of *_ATTRIBUTES struct within DEVICEINFO
ULONG cbAttr; // sizeof *_ATTRIBUTES struct
UINT offData; // offset of *_INPUT_DATA buffer within DEVICEINFO
ULONG cbData; // sizeof *_INPUT_DATA buffer
VOID (*DeviceRead)(PDEVICEINFO); // routine to read the device
PKEVENT pkeHidChange; // event to signal changes to this sort of device
#ifdef GENERIC_INPUT
DWORD dwFlags; // Flags...
#endif
} DEVICE_TEMPLATE, *PDEVICE_TEMPLATE;
第二部分:pnp.c
DEVICE_TEMPLATE aDeviceTemplate = {
// DEVICE_TYPE_MOUSE
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(MOUSE_DEVICE_INFO), // cbDeviceInfo
&GUID_CLASS_MOUSE, // pClassGUID
PMAP_MOUCLASS_PARAMS, // uiRegistrySection
L"mouclass", // pwszClassName
DD_MOUSE_DEVICE_NAME_U L"0", // pwszDefDevName
DD_MOUSE_DEVICE_NAME_U L"Legacy0", // pwszLegacyDevName
IOCTL_MOUSE_QUERY_ATTRIBUTES, // IOCTL_Attr
FIELD_OFFSET(DEVICEINFO, mouse.Attr), // offAttr
sizeof((PDEVICEINFO)NULL)->mouse.Attr, // cbAttr
FIELD_OFFSET(DEVICEINFO, mouse.Data), // offData
sizeof((PDEVICEINFO)NULL)->mouse.Data, // cbData
ProcessMouseInput, // Reader routine
NULL // pkeHidChange
},
// DEVICE_TYPE_KEYBOARD
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(KEYBOARD_DEVICE_INFO), // cbDeviceInfo
&GUID_CLASS_KEYBOARD, // pClassGUID
PMAP_KBDCLASS_PARAMS, // uiRegistrySection
L"kbdclass", // pwszClassName
DD_KEYBOARD_DEVICE_NAME_U L"0", // pwszDefDevName
DD_KEYBOARD_DEVICE_NAME_U L"Legacy0", // pwszLegacyDevName
IOCTL_KEYBOARD_QUERY_ATTRIBUTES, // IOCTL_Attr
FIELD_OFFSET(DEVICEINFO, keyboard.Attr), // offAttr
sizeof((PDEVICEINFO)NULL)->keyboard.Attr, // cbAttr
FIELD_OFFSET(DEVICEINFO, keyboard.Data), // offData
sizeof((PDEVICEINFO)NULL)->keyboard.Data, // cbData
ProcessKeyboardInput, // Reader routine
NULL // pkeHidChange
},
#ifdef GENERIC_INPUT
// DEVICE_TYPE_HID
{
sizeof(GENERIC_DEVICE_INFO)+sizeof(HID_DEVICE_INFO), // cbDeviceInfo
&GUID_CLASS_INPUT, // pClassGUID
0, // uiRegistrySection. LATER: add real one
L"hid", // pwszClassName
L"", // pwszDefDevName
L"", // pwszLegacyDevName
0, // IOCTL_ATTR
0, // offAttr
0, // cbAttr
0, // offData
0, // cbData
ProcessHidInput, // Reader routine
NULL, // pkeHidChange,
DT_HID, // dwFlags
},
#endif
// Add new input device type template here
};
第三部分:ntinput.c
PDEVICE_TEMPLATE pDevTpl = &aDeviceTemplate;
对于键盘来说,pDeviceInfo->type等于1,
pDevTpl->DeviceRead 指针为函数指针ProcessKeyboardInput()
VOID NTAPI InputApc(
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
)
{
PDEVICEINFO pDeviceInfo = (PDEVICEINFO)ApcContext;
UNREFERENCED_PARAMETER(Reserved);
/*
* Check if the RIT is being terminated.
* If we hit this assertion, the RIT was killed by someone inadvertently.
* Not much can be done if it once happens.
*/
UserAssert(gptiRit);
UserAssert((gptiRit->TIF_flags & TIF_INCLEANUP) == 0);
#ifdef DIAGNOSE_IO
pDeviceInfo->nReadsOutstanding--;
#endif
/*
* If this device needs freeing, abandon reading now and request the free.
* (Don't even process the input that we received in this APC)
*/
if (pDeviceInfo->usActions & GDIAF_FREEME) {
#ifdef GENERIC_INPUT
CheckCritOut();
EnterCrit();
#endif
EnterDeviceInfoListCrit();
pDeviceInfo->bFlags &= ~GDIF_READING;
FreeDeviceInfo(pDeviceInfo);
LeaveDeviceInfoListCrit();
#ifdef GENERIC_INPUT
LeaveCrit();
#endif
return;
}
if (NT_SUCCESS(IoStatusBlock->Status) && pDeviceInfo->handle) {
PDEVICE_TEMPLATE pDevTpl = &aDeviceTemplate;
pDevTpl->DeviceRead(pDeviceInfo);
}
if (IsRemoteConnection()) {
PoSetSystemState(ES_SYSTEM_REQUIRED);
}
StartDeviceRead(pDeviceInfo);
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]