SHELL32!SHLoadPopupMenu函数分析之添加属性菜单项

SHELL32!SHLoadPopupMenu函数分析之添加属性菜单项

第一部分:

//
// user does not support pop-up only menu.
//
STDAPI_(HMENU) SHLoadPopupMenu(HINSTANCE hinst, UINT id)
{
    HMENU hmenuParent = LoadMenu(hinst, MAKEINTRESOURCE(id));
    if (hmenuParent)
    {
        HMENU hpopup = GetSubMenu(hmenuParent, 0);
        RemoveMenu(hmenuParent, 0, MF_BYPOSITION);
        DestroyMenu(hmenuParent);
        return hpopup;
    }
    return NULL;
}

FUNCLOG2(LOG_GENERAL, HMENU, WINAPI, LoadMenuW, HINSTANCE, hmod, LPCWSTR, lpName)
HMENU WINAPI LoadMenuW(
    HINSTANCE hmod,
    LPCWSTR lpName)
{
    HANDLE hRes;

    if (hRes = FINDRESOURCEW(hmod, (LPWSTR)lpName, RT_MENU))
        return CommonLoadMenu(hmod, hRes);
    else
        return NULL;
}


HMENU CommonLoadMenu(
    HINSTANCE hmod,
    HANDLE hResInfo
    )
{
    HANDLE h;
    PVOID p;
    HMENU hMenu = NULL;

    if (h = LOADRESOURCE(hmod, hResInfo)) {

        if (p = LOCKRESOURCE(h, hmod)) {

            hMenu = CreateMenuFromResource(p);

第二部分:
HMENU CreateMenuFromResource(
    LPBYTE lpMenuTemplate)
{
    HMENU hMenu = NULL;
    UINT menuTemplateVersion;
    UINT menuTemplateHeaderSize;

    /*
     * Win3 menu resource: First, strip version number word out of the menu
     * template.  This value should be 0 for Win3, 1 for win4.
     */
    menuTemplateVersion = *((WORD *)lpMenuTemplate)++;
    if (menuTemplateVersion > 1) {
        RIPMSG0(RIP_WARNING, "Menu Version number > 1");
        return NULL;
    }
    menuTemplateHeaderSize = *((WORD *)lpMenuTemplate)++;
    lpMenuTemplate += menuTemplateHeaderSize;
    switch (menuTemplateVersion) {
    case 0:
        MenuLoadWinTemplates(lpMenuTemplate, &hMenu);
        break;

    case 1:
        MenuLoadChicagoTemplates((PMENUITEMTEMPLATE2)lpMenuTemplate, &hMenu, 0, 0);
        break;
    }
    return hMenu;
}


第二部分:


typedef struct {        // version 1
    DWORD dwHelpID;
    DWORD fType;
    DWORD fState;
    DWORD menuId;
    WORD  wResInfo;
    WCHAR mtString[1];
} MENUITEMTEMPLATE2, *PMENUITEMTEMPLATE2;


1: kd> db 0x77a42b80            lpMenuTemplate对应的数据
77a42b80  01 00 04 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
77a42b90  00 00 00 00 81 00 00 00-00 00 00 00 00 00 00 00  ................
77a42ba0  00 00 00 00 00 00 00 00-80 00 50 00 26 00 72 00  ..........P.&.r.
77a42bb0  6f 00 70 00 65 00 72 00-74 00 69 00 65 00 73 00  o.p.e.r.t.i.e.s.
77a42bc0  00 00 00 00 00 00 00 00-01 00 04 00 00 00 00 00  ................

PMENUITEMTEMPLATE2 MenuLoadChicagoTemplates(
    PMENUITEMTEMPLATE2 lpMenuTemplate,
    HMENU *phMenu,
    WORD wResInfo,
    UINT mftRtl)
{
    HMENU hMenu;
    HMENU hSubMenu;
    long menuId = 0;
    LPWSTR lpmenuText;
    MENUITEMINFO    mii;
    UNICODE_STRING str;
    DWORD           dwHelpID;

    if (!(hMenu = NtUserCreateMenu()))
        goto memoryerror;

    do {
        if (!(wResInfo & MFR_POPUP)) {
            /*
             * If the PREVIOUS wResInfo field was not a POPUP, the
             * dwHelpID field is not there.  Back up so things fit.
             */
            lpMenuTemplate = (PMENUITEMTEMPLATE2)(((LPBYTE)lpMenuTemplate) -
                    sizeof(lpMenuTemplate->dwHelpID));
            dwHelpID = 0;
        } else
            dwHelpID = lpMenuTemplate->dwHelpID;

        menuId = lpMenuTemplate->menuId;

        RtlZeroMemory(&mii, sizeof(mii));
        mii.cbSize = sizeof(MENUITEMINFO);
        mii.fMask = MIIM_ID | MIIM_STATE | MIIM_FTYPE ;

        mii.fType = lpMenuTemplate->fType | mftRtl;
        if (mii.fType & ~MFT_MASK) {
            RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu Type flags %lX are invalid", mii.fType);
            goto memoryerror;
        }

        mii.fState  = lpMenuTemplate->fState;
        if (mii.fState & ~MFS_MASK) {
            RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu State flags %lX are invalid", mii.fState);
            goto memoryerror;
        }

        wResInfo = lpMenuTemplate->wResInfo;
        if (wResInfo & ~(MF_END | MFR_POPUP)) {
            RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu ResInfo flags %lX are invalid", wResInfo);
            goto memoryerror;
        }

        if (dwHelpID) {
            NtUserSetMenuContextHelpId(hMenu,dwHelpID);
        }
        if (lpMenuTemplate->mtString[0]) {
            lpmenuText = lpMenuTemplate->mtString;
            mii.fMask |= MIIM_STRING;
        } else {
            lpmenuText = NULL;
        }
        RtlInitUnicodeString(&str, lpmenuText);

        mii.dwTypeData = (LPWSTR) lpmenuText;

        /*
         * skip to next menu item template (DWORD boundary)
         */
        lpMenuTemplate = (PMENUITEMTEMPLATE2)
                (((LPBYTE)lpMenuTemplate) +
                sizeof(MENUITEMTEMPLATE2) +
                ((str.Length + 3) & ~3));

        if (mii.fType & MFT_OWNERDRAW)
        {
            mii.fMask |= MIIM_DATA;
            mii.dwItemData = (ULONG_PTR) mii.dwTypeData;
            mii.dwTypeData = 0;
        }

        /*
         * If MFT_RIGHTORDER is specified then all subsequent
         * menus are right-to-left as well.
         */
        if (mii.fType & MFT_RIGHTORDER)
        {
            mftRtl = MFT_RIGHTORDER;
            NtUserSetMenuFlagRtoL(hMenu);
        }

        if (wResInfo & MFR_POPUP) {
            mii.fMask |= MIIM_SUBMENU;
            lpMenuTemplate = MenuLoadChicagoTemplates(lpMenuTemplate,
                    &hSubMenu, MFR_POPUP, mftRtl);
            if (lpMenuTemplate == NULL)
                goto memoryerror;
            mii.hSubMenu = hSubMenu;
        }

        if (mii.fType & MFT_BITMAP) {

            /*
             * Don't allow bitmaps from the resource file.
             */
            mii.fType = (mii.fType | MFT_RIGHTJUSTIFY) & ~MFT_BITMAP;
        }

        mii.cch = (UINT)-1;
        mii.wID = menuId;
        if (!NtUserThunkedMenuItemInfo(hMenu, MFMWFP_NOITEM, TRUE, TRUE,
                    &mii, &str)) {
            if (wResInfo & MFR_POPUP)
                NtUserDestroyMenu(mii.hSubMenu);
            goto memoryerror;
        }
        wResInfo &= ~MFR_POPUP;
    } while (!(wResInfo & MFR_END));

    *phMenu = hMenu;
    return lpMenuTemplate;

memoryerror:
    if (hMenu != NULL)
        NtUserDestroyMenu(hMenu);
    *phMenu = NULL;
    return NULL;
}


第三部分:

1: kd> dv
 lpMenuTemplate = 0x77a42b88
         phMenu = 0x00faec48
       wResInfo = 0x80
         mftRtl = 0
            str = ""
          hMenu = 0x002e00b1                最终结果1
            mii = struct tagMENUITEMINFOW
       hSubMenu = 0x0009010f                最终结果2


1: kd> dt win32k!menu 0xbc694b74
   +0x000 head             : _PROCDESKHEAD
   +0x014 fFlags           : 0
   +0x018 iItem            : 0n0
   +0x01c cAlloced         : 8
   +0x020 cItems           : 1
   +0x024 cxMenu           : 0
   +0x028 cyMenu           : 0
   +0x02c cxTextAlign      : 0
   +0x030 spwndNotify      : (null)
   +0x034 rgItems          : 0xbc6979c4 tagITEM
   +0x038 pParentMenus     : (null)
   +0x03c dwContextHelpId  : 0
   +0x040 cyMax            : 0
   +0x044 dwMenuData       : 0
   +0x048 hbrBack          : (null)
   +0x04c iTop             : 0n0
   +0x050 iMaxTop          : 0n0
   +0x054 dwArrowsOn       : 0y00
1: kd> dx -id 0,0,89589d88 -r1 ((win32k!tagITEM *)0xbc6979c4)
((win32k!tagITEM *)0xbc6979c4)                 : 0xbc6979c4 [Type: tagITEM *]
    [+0x000] fType            : 0x800 [Type: unsigned int]
    [+0x004] fState           : 0x3 [Type: unsigned int]
    [+0x008] wID              : 0x0 [Type: unsigned int]
    [+0x00c] spSubMenu        : 0xbc694c2c [Type: tagMENU *]
    [+0x010] hbmpChecked      : 0x0 [Type: void *]
    [+0x014] hbmpUnchecked    : 0x0 [Type: void *]
    [+0x018] lpstr            : 0x0 [Type: unsigned short *]
    [+0x01c] cch              : 0x0 [Type: unsigned long]
    [+0x020] dwItemData       : 0x0 [Type: unsigned long]
    [+0x024] xItem            : 0x0 [Type: unsigned long]
    [+0x028] yItem            : 0x0 [Type: unsigned long]
    [+0x02c] cxItem           : 0x0 [Type: unsigned long]
    [+0x030] cyItem           : 0x0 [Type: unsigned long]
    [+0x034] dxTab            : 0x0 [Type: unsigned long]
    [+0x038] ulX              : 0x7fffffff [Type: unsigned long]
    [+0x03c] ulWidth          : 0x0 [Type: unsigned long]
    [+0x040] hbmp             : 0x0 [Type: HBITMAP__ *]
    [+0x044] cxBmp            : -1 [Type: int]
    [+0x048] cyBmp            : 0 [Type: int]
1: kd> dx -id 0,0,89589d88 -r1 ((win32k!tagMENU *)0xbc694c2c)
((win32k!tagMENU *)0xbc694c2c)                 : 0xbc694c2c [Type: tagMENU *]
    [+0x000] head             [Type: _PROCDESKHEAD]
    [+0x014] fFlags           : 0x1 [Type: unsigned long]
    [+0x018] iItem            : 0 [Type: int]
    [+0x01c] cAlloced         : 0x8 [Type: unsigned int]
    [+0x020] cItems           : 0x1 [Type: unsigned int]
    [+0x024] cxMenu           : 0x0 [Type: unsigned long]
    [+0x028] cyMenu           : 0x0 [Type: unsigned long]
    [+0x02c] cxTextAlign      : 0x0 [Type: unsigned long]
    [+0x030] spwndNotify      : 0x0 [Type: tagWND *]
    [+0x034] rgItems          : 0xbc696d24 [Type: tagITEM *]
    [+0x038] pParentMenus     : 0xbc693b2c [Type: tagMENULIST *]
    [+0x03c] dwContextHelpId  : 0x0 [Type: unsigned long]
    [+0x040] cyMax            : 0x0 [Type: unsigned long]
    [+0x044] dwMenuData       : 0x0 [Type: unsigned long]
    [+0x048] hbrBack          : 0x0 [Type: HBRUSH__ *]
    [+0x04c] iTop             : 0 [Type: int]
    [+0x050] iMaxTop          : 0 [Type: int]
    [+0x054 ( 1: 0)] dwArrowsOn       : 0x0 [Type: unsigned long]
1: kd> dx -id 0,0,89589d88 -r1 ((win32k!tagITEM *)0xbc696d24)
((win32k!tagITEM *)0xbc696d24)                 : 0xbc696d24 [Type: tagITEM *]
    [+0x000] fType            : 0x0 [Type: unsigned int]
    [+0x004] fState           : 0x0 [Type: unsigned int]
    [+0x008] wID              : 0x0 [Type: unsigned int]
    [+0x00c] spSubMenu        : 0x0 [Type: tagMENU *]
    [+0x010] hbmpChecked      : 0x0 [Type: void *]
    [+0x014] hbmpUnchecked    : 0x0 [Type: void *]
    [+0x018] lpstr            : 0xbc696fe4 : 0x50 [Type: unsigned short *]
    [+0x01c] cch              : 0xb [Type: unsigned long]
    [+0x020] dwItemData       : 0x0 [Type: unsigned long]
    [+0x024] xItem            : 0x0 [Type: unsigned long]
    [+0x028] yItem            : 0x0 [Type: unsigned long]
    [+0x02c] cxItem           : 0x0 [Type: unsigned long]
    [+0x030] cyItem           : 0x0 [Type: unsigned long]
    [+0x034] dxTab            : 0x0 [Type: unsigned long]
    [+0x038] ulX              : 0x7fffffff [Type: unsigned long]
    [+0x03c] ulWidth          : 0x0 [Type: unsigned long]
    [+0x040] hbmp             : 0x0 [Type: HBITMAP__ *]
    [+0x044] cxBmp            : -1 [Type: int]
    [+0x048] cyBmp            : 0 [Type: int]
1: kd> db 0xbc696fe4
bc696fe4  50 00 26 00 72 00 6f 00-70 00 65 00 72 00 74 00  P.&.r.o.p.e.r.t.
bc696ff4  69 00 65 00 73 00 00 00-55 48 5f 54 41 49 4c 00  i.e.s...UH_TAIL.
bc697004  ab ab ab ab ab ab ab ab-07 00 ca ca 00 00 00 00  ................
bc697014  00 00 00 00 3d 00 0f 00-07 00 ca 00 60 03 67 bc  ....=.......`.g.
bc697024  60 03 67 bc 07 00 ca ca-07 00 ca ca 07 00 ca ca  `.g.............
bc697034  07 00 ca ca 07 00 ca ca-07 00 ca ca 07 00 ca ca  ................
bc697044  07 00 ca ca 07 00 ca ca-07 00 ca ca 07 00 ca ca  ................
bc697054  07 00 ca ca 07 00 ca ca-07 00 ca ca 07 00 ca ca  ................

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将RocketMQ集成到了Spring Boot项目中,实现站内信功能

1. 添加依赖 首先,在pom.xml中添加RocketMQ的依赖: <dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot

C语言基础要素:安装 Visual Studio 2022

安装 Visual Studio 2022 Visual Studio 是由微软开发的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;支持多种编程语言和开发平台。它提供了丰富的工具和功能&#xff0c;帮助开发者高效地编写、调试和部署应用程序。无论是桌面应用、Web 应用还是移动应用&#…

[ TypeScript ] “undefined extends xxx“ 总是为 true 的 bug

版本号 "typescript": "^5.7.3", "unplugin": "^2.2.0",说明 在使用 unplugin 时 , 我定义插件的参数是 必填的, 使用时却是一个可空参数, 不传参也不会报错, (options?: UserOptions) > Return &#x1f632;&#x1f632;&…

[通俗易懂C++]:指针和const

之前的文章有说过,使用指针我们可以改变指针指向的内容(通过给指针赋一个新的地址)或者改变被保存地址的值(通过给解引用指针赋一个新值): int main() {int x { 5 }; // 创建一个整数变量 x&#xff0c;初始值为 5int* ptr { &x }; // 创建一个指针 ptr&#xff0c;指向 …

华为昇腾服务器(固件版本查询、驱动版本查询、CANN版本查询)

文章目录 1. **查看固件和驱动版本**2. **查看CANN版本**3. **其他辅助方法**注意事项 在华为昇腾服务器上查看固件、驱动和CANN版本的常用方法如下&#xff1a; 1. 查看固件和驱动版本 通过命令行工具 npu-smi 执行以下命令查看当前设备的固件&#xff08;Firmware&#xff0…

设计心得——解耦的实现技术

一、说明 在前面的“设计心得——解耦”中&#xff0c;对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明&#xff0c;以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践&#xff0c;就需要不断的…

Blaze RangePartitioning 算子Native实现全解析

引言&#xff1a;本文将全面且深入地解析Blaze RangePartitioning算子的Native实现过程。相较于原生Spark&#xff0c;RangePartitioning的Native实现在执行时间上达到了30%的显著下降&#xff0c;同时在资源开销方面节省了高达76%。这一改进大幅降低了运行成本&#xff0c;展现…

卷积与动态特征选择:重塑YOLOv8的多尺度目标检测能力

文章目录 1. YOLOv8的网络结构概述2. 添加注意力机制2.1 为什么添加注意力机制&#xff1f;2.2 如何将注意力机制集成到YOLOv8中&#xff1f;2.3 效果分析 3. C2f模块的集成3.1 C2f模块简介3.2 如何在YOLOv8中集成C2f模块&#xff1f;3.3 效果分析 4. 卷积操作的优化4.1 卷积操…

Web入侵实战分析-常见web攻击类应急处置实验2

场景说明 某天运维人员&#xff0c;发现运维的公司站点被黑页&#xff0c;首页标题被篡改&#xff0c;你获得的信息如下&#xff1a; 操作系统&#xff1a;windows server 2008 R2业务&#xff1a;公司官网网站架构&#xff1a;通过phpstudy运行apache mysqlphp开放端口&…

WebXR教学 02 配置开发环境

默认操作系统为Windows 1.VS Code VS Code 是一款轻量级、功能强大的代码编辑器&#xff0c;适用于多种编程语言。 下载 步骤 1&#xff1a;访问 VS Code 官方网站 打开浏览器&#xff08;如 Chrome、Edge 等&#xff09;。 在地址栏输入以下网址&#xff1a; https://code.v…

Flask实现高效日志记录模块

目录 一. 简介&#xff1a; 1. 为什么需要请求日志 二. 日志模块组成 1. 对应日志表创建&#xff08;包含日志记录的关键字段&#xff09; 2. 编写日志记录静态方法 3. 在Flask中捕获请求日志 4. 捕获异常并记录错误日志 5. 编写日志接口数据展示 6. 写入数据展…

前端框架虚拟DOM的产生

直接说结论&#xff1a;为了找出与命令式(原生实现步骤)所执行代码的最小差异化&#xff0c;从而优化代码性能。 命令式&#xff1a; 可以理解为面向过程编程&#xff0c;需要写好每个实现步骤 <div id"app"></div> const div document.querySelector…

RoCBert:具有多模态对比预训练的健壮中文BERT

摘要 大规模预训练语言模型在自然语言处理&#xff08;NLP&#xff09;任务上取得了最新的最优结果&#xff08;SOTA&#xff09;。然而&#xff0c;这些模型容易受到对抗攻击的影响&#xff0c;尤其是对于表意文字语言&#xff08;如中文&#xff09;。 在本研究中&#xff0…

Jetpack Architecture系列教程之(三)——ViewModel控制器

目录 介绍 如何使用 添加依赖 构建ViewModel 分析ViewModel ViewModel生命周期 ViewModel加载原理 介绍 ViewModel 的出现是为了解决数据因Android UI控制器在生命周期活动中造成数据丢失的问题。 在一般情况下&#xff0c;页面数据丢失&#xff08;转屏、闪退等生命周期…

在低功耗MCU上实现人工智能和机器学习

作者&#xff1a;Silicon Labs 人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术不仅正在快速发展&#xff0c;还逐渐被创新性地应用于低功耗的微控制器&#xff08;MCU&#xff09;中&#xff0c;从而实现边缘AI/ML解决方案。这些MCU是许多嵌入式…

rpc到自己java实现rpc调用再到rpc框架设计

目录 rpc(Remote Procedure Call)rpc一般架构为什么要引入rpc自己实现rpc调用1. 新建一个maven项目&#xff0c;加入hessian依赖2. 服务端3. Stub代理4. 客户端测试输出5. rpc程序分析附 请求参数和序列化程序 6. 总结 回顾RPCRPC 序列化协议RPC 网络协议注册中心的引入dubbo框…

【STM32 USB】USB CDC类

简介 USB CDC&#xff08;communication device class&#xff09;类是usb2.0标准下的一个子类&#xff0c;定义了通信相关设备的抽象集合。usb2.0标准下定义了很多子类&#xff0c;有音频类&#xff0c;CDC类&#xff0c;HID类&#xff0c;打印&#xff0c;大容量存储类&…

如何修改Windows系统Ollama模型存储位置

默认情况下&#xff0c;Ollama 模型会存储在 C 盘用户目录下的 .ollama/models 文件夹中&#xff0c;这会占用大量 C 盘空间&#xff0c;增加C盘“爆红”的几率。所以&#xff0c;我们就需要修改Ollama的模型存储位置 Ollama提供了一个环境变量参数可以修改Ollama的默认存在位…

DeepSeek掘金——VSCode 接入DeepSeek V3大模型,附使用说明

VSCode 接入DeepSeek V3大模型,附使用说明 由于近期 DeepSeek 使用人数激增,服务器压力较大,官网已 暂停充值入口 ,且接口响应也开始不稳定,建议使用第三方部署的 DeepSeek,如 硅基流动 或者使用其他模型/插件,如 豆包免费AI插件 MarsCode、阿里免费AI插件 TONGYI Lin…

【语音科学计算器】当前汇率

JSON_MARKER_HORN{“base”:“USD”,“rates”:{“EUR”:0.9758,“JPY”:157.68,“GBP”:0.8190,“CNY”:7.3327,“HKD”:7.7872,“AUD”:1.6260,“CAD”:1.4422,“CHF”:0.9157,“SGD”:1.3714,“KRW”:1473.05,“NZD”:1.7992,“THB”:34.54,“MYR”:4.4930,“PHP”:57.32,“…