CBT_CREATEWND 结构的名称无效

Posted

技术标签:

【中文标题】CBT_CREATEWND 结构的名称无效【英文标题】:CBT_CREATEWND structure has invalid name 【发布时间】:2013-12-14 12:48:50 【问题描述】:

这是我的挂钩程序,当我尝试读取存储在 CBTHOOKCREATE->lpcs->lpszName 中的名称时,它会遇到垃圾值,例如:

79 77A064700 Created!~ 
0 00F915BC0 Created!~ 
68 000DF5BC0 Created!~ 
0 00F915BC0 Created!~ 
0 00F915BC0 Created!~ 
67 7630D8200 Created!~ 
77 000DEF340 Created!~ 
79 77A064700 Created!~ 

同样的事情也适用于lpszClass。 关于取消引用 lparam 有什么我应该做的,但还没有做的事情!? 这是有问题的功能:

LRESULT CALLBACK HookProcedure(int nCode, WPARAM wparam, LPARAM lparam)


    if (nCode < 0) return CallNextHookEx(hookID, nCode, wparam, lparam);

    std::ofstream outfile;
    CBT_CREATEWND   *CBTHOOKCREATE;
    RECT            *CBTRECTPTR;
    RECT            CBTRECT;
    wstring         Message;

    CBTHOOKCREATE = (CBT_CREATEWND*) lparam;
    LPWSTR str = L"                     ";
    outfile.open(("d:\\test.txt"), std::ios_base::app);

    if (nCode >= 0) 
        switch (nCode)
        
        case HCBT_CREATEWND:
            outfile << *(CBTHOOKCREATE->lpcs->lpszName) << " " << CBTHOOKCREATE->lpcs->lpszName << " Created!~ " << endl;
            //cout << "Created!~" << endl;
            break;
        case HCBT_DESTROYWND:
            outfile << "Destroied!~" << endl;
            //cout << "Destroied!~" << endl;
            break;
        default:
            //cout << "sth else" << endl;
            break;
        
    
    outfile.close();
    return 0;

【问题讨论】:

【参考方案1】:

*强文本*尝试将IsWindowUnicode 与wParam 中的窗口句柄一起使用。 如果 Window 是 Unicode 的,lpcs 指向一个 CREATESTRUCTW 结构,lpszName 指向一个宽字符串,您将不得不对其进行转换。

将以下代码添加到 DLL CPP 文件的顶部。

std::string wc2s( const wchar_t * pw ) 
    int length = (int)wcslen( pw ) + 1;
    int newlen = WideCharToMultiByte( CP_ACP, 0, pw, length, 0, 0, 0, 0 ); 
    std::string r( newlen , '\0' );
    WideCharToMultiByte( CP_ACP, 0, pw, length, &r[0], newlen, 0, 0 ); 
    return r;

对传递给 CreateWindow 的文本使用以下代码

case HCBT_CREATEWND: 
    CBT_CREATEWND * pCBT_CW = (CBT_CREATEWND *)lParam;
    std::string strCreatText;
    if ( pCBT_CW->lpcs->lpszName != NULL ) 
        if ( IsWindowUnicode( (HWND)wParam ) ) 
            strCreatText = wc2s( pCBT_CW->lpcs->lpszName );
         else 
            strCreatText = (char*)pCBT_CW->lpcs->lpszName;  
        
    
    outfile << strCreatText << " Created!~ " << endl;
    break;

PS:未经测试

更新:根据 IInspectable 评论。非侵入式 CBT_HOOK 必须遵循 hooks 的一般规则:返回 CallNextHookEx 返回的内容。

LRESULT CALLBACK HookProcedure(int nCode, [...]

    if ( nCode >= 0 ) 

        [...]

    

    return CallNextHookEx(NULL, nCode, wparam, lparam);


【讨论】:

我尝试了您的解决方案,但这不起作用!除此之外,这使我的 explorer.exe 每次安装挂钩时都会崩溃:这是代码:pastebin.com/X63H7zX8 它崩溃是因为您将 lparam 转换为 CREATESTRUCTW*。等待更新的答案。 另外两点需要用原始代码(不是你的)修复:1 HookProcedure 应该总是调用CallNextHookEx - return 0; 语句会破坏其他代码。 2 lpszClass 不一定是指向字符串的指针;它也可以是ATOM 的类,需要检查。 @IInspectable 对于您的第一点,我认为 CBT_HOOK 是“特价商品”。见msdn.microsoft.com/en-us/library/windows/desktop/…第二点,他想记录lpszName,而不是lpszClass CBT 钩子并不特别。 SetWindowsHookEx 中关于链接的规则仍然有效。 CBTProc 的返回值规则仅适用于您想积极参与窗口创建的情况。对于非侵入式监控,您应该始终调用CallNextHookEx

以上是关于CBT_CREATEWND 结构的名称无效的主要内容,如果未能解决你的问题,请参考以下文章

收到无效的 JSON 有效负载。未知名称 click_action

Impala 通过 jdbc 使元数据无效

无效的捆绑包结构 - 应用程序可能只包含一个可执行文件。

SQL Server 上表包含点时生成错误的 FROM 子句导致 Sqoop 无效对象名称错误

最佳重载方法匹配...有一些无效参数

Cloudera Impala:文件的版本号无效。这可能是由于元数据过时