当前位置: 首页 > article >正文

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.kler.cn/a/556502.html

相关文章:

  • 1.22作业
  • 基于 JavaWeb 的 Spring Boot 网上商城系统设计和实现(源码+文档+部署讲解)
  • 【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(8-15)
  • RabbitMQ的脑裂(网络分区)问题
  • go 网络编程 websocket gorilla/websocket
  • python网络安全怎么学 python做网络安全
  • 视觉应用工程师(面试)
  • C语言之宏定义
  • 在低功耗MCU上实现人工智能和机器学习
  • DeepSeek 点燃关键技术突破的科技引擎,驶向未来新航道
  • 电商搜索API的Elasticsearch优化策略
  • CSS 布局技术深度解析:从传统到现代的核心布局方案
  • 猿大师播放器:网页播放RTSP H.265零转码革命延迟低更流畅智慧安防首选
  • 华为昇腾服务器固件Firmware、驱动Drive、CANN各自的作用与联系?
  • 大模型产品Deepseek(八)、数据嵌入+知识库管理+联网搜索,实现精准的知识查询
  • 回溯算法:非递减子序列子集,这题的去重并不是通解!!!!
  • Spring 核心技术解析【纯干货版】- XIV:Spring 消息模块 Spring-Jms 模块精讲
  • 如何恢复苹果手机置出厂设置
  • 新版Tomcat MySQL IDEA 安装配置过程遇到的问题
  • C#上位机--选择语句(switch)