在GetMsgProc钩子中调用GetPointerFrameTouchInfo遇Error 998求解决
在GetMsgProc钩子中调用GetPointerFrameTouchInfo返回Error 998的原因及解决方法
我之前在钩子场景里调用指针相关API时也踩过类似的坑,咱们一步步拆解这个Error 998(内存访问无效)的问题:
常见原因
- 缓冲区分配逻辑错误:
GetPointerFrameTouchInfo需要先查询所需的缓冲区大小,再对应分配内存。如果直接用固定大小的缓冲区,或者分配的内存不足/未正确初始化,函数会尝试访问超出缓冲区范围的内存,触发998错误。 - 无效的Pointer ID:你传入的指针ID可能不是当前有效触摸指针的ID,或者在钩子触发时该指针的上下文已经失效,导致函数尝试访问无效的内存区域。
- 线程上下文不匹配:
GetMsgProc是运行在目标线程的上下文中的,如果你的缓冲区是在钩子所在的外部线程分配的(比如主进程堆),目标线程没有访问权限,也会触发内存访问错误。
针对性解决方法
严格遵循"先查大小再分配"的流程
这是最容易踩坑的点,一定要先调用函数获取所需的触摸点数量,再分配对应内存,示例代码如下:UINT touchCount = 0; // 第一次调用:仅获取所需的触摸点数量 if (GetPointerFrameTouchInfo(pointerId, &touchCount, NULL) == FALSE) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // 在当前线程堆上分配内存(适配钩子的线程上下文) PTOUCH_POINTER_INFO pTouchData = (PTOUCH_POINTER_INFO)LocalAlloc(LPTR, touchCount * sizeof(TOUCH_POINTER_INFO)); if (pTouchData != NULL) { // 第二次调用:获取实际触摸数据 if (GetPointerFrameTouchInfo(pointerId, &touchCount, pTouchData)) { // 在这里处理触摸数据 } // 用完记得释放内存 LocalFree(pTouchData); } } }这里用
LocalAlloc是因为它会在当前线程的堆上分配内存,避免跨线程内存访问权限问题。先验证Pointer ID的有效性
在调用GetPointerFrameTouchInfo前,先确认指针ID是有效的触摸类型:POINTER_INPUT_TYPE pointerType; if (GetPointerType(pointerId, &pointerType) && pointerType == PT_TOUCH) { // 确认是有效触摸指针后,再调用获取帧信息的函数 }避免在钩子中使用跨线程内存
绝对不要在钩子过程中使用主进程分配的全局缓冲区,必须在钩子执行的线程内分配内存(比如用LocalAlloc或HeapAlloc(GetCurrentProcessHeap(), ...)),确保目标线程拥有访问权限。检查钩子的注入与权限
如果是全局GetMsgProc钩子,确保你的DLL已经正确注入到目标进程,并且拥有足够的内存访问权限。另外,不要在钩子中执行耗时操作,防止破坏目标线程的上下文。
内容的提问来源于stack exchange,提问作者Wolverine
相关产品推荐
相关产品推荐

