xxxRealInternalGetMessage分析之While循环分析----后传第二部分win32k!xxxDoPaint函数分析

综述:
xxxRealInternalGetMessage分析之While循环分析----干货第二部分win32k!xxxDoPaint函数分析

scrnsave屏保会调用GetMessage函数

00 win32k!xxxDoPaint
01 win32k!xxxRealInternalGetMessage
02 win32k!NtUserGetMessage
03 nt!_KiSystemService
04 SharedUserData!SystemCallStub
05 USER32!NtUserGetMessage
06 USER32!GetMessageA_wrapper
07 scrnsave!main
08 scrnsave!mainCRTStartup
09 kernel32!BaseProcessStart

位置windows\core\ntuser\kernel
下面只是调用关系。
下一篇具体分析。

第一部分:

/***************************************************************************\
* xxxCompositedTraverse
*使用从最后一个子对象开始的预购遍历来渲染
以自下而上的顺序显示窗口。
*使用从最后一个子窗口开始的按前序遍历来渲染
按照自下而上的顺序打开窗口。
* Uses pre-order traversal starting with the last child to render the
* windows in a bottom-up order.
*
* 9/30/1999       vadimg      created
\***************************************************************************/

BOOL xxxCompositedTraverse(PWND pwnd)
{
    TL tlpwnd;
    BOOL fPainted = FALSE;

    CheckLock(pwnd);

    if (NEEDSPAINT(pwnd)) {
        xxxSendMessage(pwnd, WM_PAINT, 0, 0);
        fPainted = TRUE;
    }

    pwnd = GetLastChild(pwnd);
    ThreadLock(pwnd, &tlpwnd);

    while (pwnd != NULL) {

        if (xxxCompositedTraverse(pwnd)) {
            fPainted = TRUE;
        }
        pwnd = pwnd->spwndPrev;

        if (ThreadLockExchange(pwnd, &tlpwnd) == NULL) {
            break;
        }
    }

    ThreadUnlock(&tlpwnd);
    return fPainted;
}

/***************************************************************************\
* xxxCompositedPaint
* Composited  合成
* 9/30/1999       vadimg      created
\***************************************************************************/

VOID xxxCompositedPaint(PWND pwnd)
{
    BOOL fPainted;
    HBITMAP hbm, hbmOld;
    PREDIRECT prdr;
    HDC hdc;
    LPRECT prc;
    SIZE size;
    POINT pt;

    CheckLock(pwnd);
    UserAssert(TestWF(pwnd, WEFCOMPOSITED));

    SetWF(pwnd, WEFPCOMPOSITING);

    /*
     * Render the child windows in a bottom-up order.
     */
    fPainted = xxxCompositedTraverse(pwnd);

    ClrWF(pwnd, WEFPCOMPOSITING);

    /*
     * While we were compositing, an invalid region may have accumulated.
     * So, let's go and invalidate that area of the window.
     */
    BEGINATOMICCHECK();
    prdr = _GetProp(pwnd, PROP_LAYER, TRUE);
    if (prdr != NULL && prdr->hrgnComp != NULL) {

        xxxInternalInvalidate(pwnd, prdr->hrgnComp, RDW_INVALIDATE |
                RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);

        if (prdr->hrgnComp != HRGN_FULL) {
            GreDeleteObject(prdr->hrgnComp);
        }

        prdr->hrgnComp = NULL;
    }
    ENDATOMICCHECK();

#ifdef REDIRECTION
    if (TestWF(pwnd, WEFEXTREDIRECTED)) {
        return;
    }
#endif // REDIRECTION

    BEGINATOMICCHECK();

    if (fPainted && TestWF(pwnd, WEFPREDIRECTED)) {

        prdr = (PREDIRECT)_GetProp(pwnd, PROP_LAYER, TRUE);
        prc = &prdr->rcUpdate;
        hbm = prdr->hbm;
        UserAssert(hbm != NULL);

        if (TestWF(pwnd, WEFLAYERED)) {

            hbmOld = GreSelectBitmap(ghdcMem, hbm);

            size.cx = pwnd->rcWindow.right - pwnd->rcWindow.left;
            size.cy = pwnd->rcWindow.bottom - pwnd->rcWindow.top;

            pt.x = pt.y = 0;
            GreUpdateSprite(gpDispInfo->hDev, PtoHq(pwnd), NULL, NULL, NULL,
                    &size, ghdcMem, &pt, 0, NULL, ULW_DEFAULT_ATTRIBUTES, prc);

            GreSelectBitmap(ghdcMem, hbmOld);
        } else {

            /*
             * Temporarily clear the redirected bit so that we can get the dc
             * with proper screen clipping.
             */
            ClrWF(pwnd, WEFPREDIRECTED);

            hbmOld = GreSelectBitmap(ghdcMem, hbm);
            hdc = _GetDCEx(pwnd, NULL, DCX_USESTYLE | DCX_WINDOW | DCX_CACHE);
    
            /*
             * Transfer the bits for the window from the redirection bitmap
             * to the screen.
             */
            GreBitBlt(hdc, prc->left, prc->top, prc->right - prc->left,
                    prc->bottom - prc->top, ghdcMem,
                    prc->left, prc->top, SRCCOPY, 0);
    
            _ReleaseDC(hdc);
            GreSelectBitmap(ghdcMem, hbmOld);
    
            /*
             * Restore the redirection bit on the window.
             */
            SetWF(pwnd, WEFPREDIRECTED);
        }

        SetRectEmpty(prc);
    }

    ENDATOMICCHECK();
}


第二部分:xxxCompositedPaint函数被xxxInternalDoPaint函数调用


/***************************************************************************\
* InternalDoPaint
*返回当前线程创建的等于或低于pwnd的窗口,这需要绘画。
* Return a window equal to or below pwnd, created by the current thread,
* which needs painting.
*
* pwnd       - Window to start searching from. Search is depth first.
* ptiCurrent - The current thread.
*
* History:
* 16-Jul-1991 DarrinM   Ported from Win 3.1 sources.
\***************************************************************************/

PWND xxxInternalDoPaint(
    PWND        pwnd,
    PTHREADINFO ptiCurrent)
{
    PWND pwndT;
    TL tlpwnd;

    /*
     * Enumerate all windows, top-down, looking for one that
     * needs repainting.  Skip windows of other tasks.
     */
    while (pwnd != NULL) {

        if (GETPTI(pwnd) == ptiCurrent) {

            if (TestWF(pwnd, WEFCOMPOSITED)) {

                ThreadLock(pwnd, &tlpwnd);

                xxxCompositedPaint(pwnd);
                pwnd = pwnd->spwndNext;

                if (ThreadUnlock(&tlpwnd) == NULL) {
                    return NULL;
                }
                continue;

            } else if (NEEDSPAINT(pwnd)) {

                /*
                 * If this window is transparent, we don't want to
                 * send it a WM_PAINT until all its siblings below it
                 * have been repainted.  If we find an unpainted sibling
                 * below, return it instead.
                 */
                if (TestWF(pwnd, WEFTRANSPARENT)) {

                    pwndT = pwnd;
                    while ((pwndT = pwndT->spwndNext) != NULL) {

                        /*
                         * Make sure sibling window belongs to same app
                         */
                        if ((GETPTI(pwndT) == ptiCurrent) && NEEDSPAINT(pwndT)) {

                            if (TestWF(pwndT, WEFTRANSPARENT))
                                continue;

                            return pwndT;
                        }
                    }
                }

                return pwnd;
            }
        }

        if (pwnd->spwndChild &&
                (pwndT = xxxInternalDoPaint(pwnd->spwndChild, ptiCurrent))) {

            return pwndT;
        }

        pwnd = pwnd->spwndNext;
    }

    return pwnd;
}


第三部分:xxxInternalDoPaint函数被xxxInternalDoPaint函数递归调用或被xxxDoPaint函数调用


/***************************************************************************\
* DoPaint
*

*查看所有桌面上需要涂漆的窗口,并放置WM_PAINT在其队列中。
* Looks at all the desktops for the window needing a paint and places a
* WM_PAINT in its queue.
*
* History:
* 16-Jul-91 DarrinM     Ported from Win 3.1 sources.
\***************************************************************************/

BOOL xxxDoPaint(
    PWND  pwndFilter,
    LPMSG lpMsg)
{
    PWND        pwnd;
    PWND        pwndT;
    PTHREADINFO ptiCurrent = PtiCurrent();

    CheckLock(pwndFilter);

#if 0 // CHRISWIL: WIN95 SPECIFIC

    /*
     * If there is a system modal up and it is attached to another task,
     * DON'T do paints.  We don't want to return a message for a window in
     * another task!
     */
    if (hwndSysModal && (hwndSysModal->hq != hqCurrent)) {

        /*
         * Poke this guy so he wakes up at some point in the future,
         * otherwise he may never wake up to realize he should paint.
         * Causes hangs - e.g. Photoshop installation program
         *   PostThreadMessage32(Lpq(hqCurrent)->idThread, WM_NULL, 0, 0, 0);
         */
        return FALSE;
    }

#endif

    /*
     * If this is a system thread, then walk the windowstation desktop-list
     * to find the window which needs painting.  For other threads, we
     * reference off the thread-desktop.
     */
    if (ptiCurrent->TIF_flags & TIF_SYSTEMTHREAD) {

        PWINDOWSTATION pwinsta;
        PDESKTOP       pdesk;

        if ((pwinsta = ptiCurrent->pwinsta) == NULL) {
            RIPMSG0(RIP_ERROR, "DoPaint: SYSTEMTHREAD does not have (pwinsta)");
            return FALSE;
        }

        pwnd = pwinsta->pTerm->spwndDesktopOwner;
        if (!NEEDSPAINT(pwnd)) {

            pwnd = NULL;
            for(pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) {
    
                if (pwnd = xxxInternalDoPaint(pdesk->pDeskInfo->spwnd, ptiCurrent))
                    break;
            }
        }

    } else {

        pwnd = xxxInternalDoPaint(ptiCurrent->rpdesk->pDeskInfo->spwnd,
                                  ptiCurrent);
    }

    if (pwnd != NULL) {

        if (!CheckPwndFilter(pwnd, pwndFilter))
            return FALSE;

        /*
         * We're returning a WM_PAINT message, so clear WFINTERNALPAINT so
         * it won't get sent again later.
         */
        if (TestWF(pwnd, WFINTERNALPAINT)) {

            ClrWF(pwnd, WFINTERNALPAINT);

            /*
             * If there is no update region, then no more paint for this
             * window.
             */
            if (pwnd->hrgnUpdate == NULL)
                DecPaintCount(pwnd);
        }

        /*
         * Set the STARTPAINT so that any other calls to BeginPaint while
         * painting is begin performed, will prevent painting on those
         * windows.
         *
         * Clear the UPDATEDIRTY since some apps (DBFast) don't call
         * GetUpdateRect, BeginPaint/EndPaint.
         */
        ClrWF(pwnd, WFSTARTPAINT);
        ClrWF(pwnd, WFUPDATEDIRTY);

        /*
         * If we get an invalidate between now and the time the app calls
         * BeginPaint() and the windows parent is not CLIPCHILDREN, then
         * the parent will paint in the wrong order.  So we are going to
         * cause the child to paint again.  Look in beginpaint and internal
         * invalidate for other parts of this fix.
         *
         * Set a flag to signify that we are in the bad zone.
         *
         * Must go up the parent links to make sure all parents have
         * WFCLIPCHILDREN set otherwise set the WFWMPAINTSENT flag.
         * This is to fix Excel spreadsheet and fulldrag. The speadsheet
         * parent window (class XLDESK) has WFCLIPCHILDREN set but it's
         * parent (class XLMAIN) doesn't. So the main window erases  the
         * background after the child window paints.
         *
         * JOHANNEC : 27-Jul-1994
         */
        
        /*
         * NT Bug 400167: As we walk up the tree, we need to stop short of
         * desktop windows and mother desktop windows.  We can't do a test
         * for WFCLIPCHILDREN on the mother desktop window's parent because
         * it doesn't exist.  This means that no desktop window will get
         * WFWMPAINTSENT set, but the message window will be able to get
         * WFWMPAINTSENT set.
         */
        
        pwndT = pwnd;
        while (pwndT && (GETFNID(pwndT) != FNID_DESKTOP)) {

            if (!TestWF(pwndT->spwndParent, WFCLIPCHILDREN)) {
                SetWF(pwnd, WFWMPAINTSENT);
                break;
            }

            pwndT = pwndT->spwndParent;
        }

        /*
         * If the top level "tiled" owner/parent of this window is iconed,
         * send a WM_PAINTICON rather than a WM_PAINT.  The wParam
         * is TRUE if this is the tiled window and FALSE if it is a
         * child/owned popup of the minimized window.
         *
         * BACKWARD COMPATIBILITY HACK
         *
         * 3.0 sent WM_PAINTICON with wParam == TRUE for no apparent
         * reason.  Lotus Notes 2.1 depends on this for some reason
         * to properly change its icon when new mail arrives.
         */
        if (!TestWF(pwnd, WFWIN40COMPAT) &&
            TestWF(pwnd, WFMINIMIZED)    &&
            (pwnd->pcls->spicn != NULL)) {

            StoreMessage(lpMsg, pwnd, WM_PAINTICON, (DWORD)TRUE, 0L, 0L);

        } else {

            StoreMessage(lpMsg, pwnd, WM_PAINT, 0, 0L, 0L);
        }

        return TRUE;
    }

    return FALSE;
}

第四部分:xxxDoPaint函数被xxxRealInternalGetMessage函数调用

xxxRealInternalGetMessage分析之While循环分析----干货
https://blog.csdn.net/oldlinux/article/details/141813955

BOOL xxxRealInternalGetMessage(
    LPMSG lpMsg,
    HWND hwndFilter,
    UINT msgMin,
    UINT msgMax,
    UINT flags,
    BOOL fGetMessage)
{


。。。。。。

        /*
         * Does the caller want paint messages? If so, try to find a paint.
         */
        if (fsWakeBits & fsWakeMask & QS_PAINT) {
            if (xxxDoPaint(pwndFilter, lpMsg)) {
                PATHTAKEN(0x100);
                break;
            }
        }

。。。。。。

Error:
    PATHTAKEN(0x8000);
    DUMPPATHTAKEN();
    return fExit;
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解Transformer的笔记记录(精简版本)----Seq2Seq → Seq2Seq with Attention

只要是符合类似的框架,都可以统称为 Encoder-Decoder 模型。 1、RNN RNN引入了隐状态h(hidden state)的概念,隐状态h可以对序列形的数据提取特征,接着再转换为输出。 x1,x2,x3,x4如: 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推语音处…

2024 闽盾杯-黑盾赛道WP

CRYPTO 签到题-学会SM https://www.json.cn/encrypt/sm3 题目要求小写所以需要转换一下 或者脚本: import hashlib message "heidun2024" hash_object hashlib.new(sm3) hash_object.update(message.encode(utf-8)) hash_value hash_object.hexdigest(…

AI助力智慧农田作物病虫害监测,基于YOLOv9全系列【yolov9/t/s/m/c/e】参数模型开发构建花田作物种植场景下棉花作物常见病虫害检测识别系统

智慧农业是一个很大的应用市场,将当下如火如荼的AI模型技术与现实的农业生产场景相结合能够有效提升生产效率,农作物在整个种植周期中有很多工作需要进行,如:浇水、施肥、除草除虫等等,传统的农业作物种植生产管理周期…

带你走近CCV(一)

从事多媒体互动行业8年了,最近才想着自己可以独自写一个识别软件,应该说想把公司里的识别统统临摹一遍,这样在接外包的时候可以游刃有余了 什么是CCV? CCV是一个建立在openCV基础上的一个开源的架构,其全称是Communit…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置)

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置) 前言多数据源配置引入aop依赖1. properties配置多数据源2. 创建数据源枚举类3. 线程参数配置类4. 数据源动态切换类5. 多数据源配置类HikariCP 版本…

Java基础(2) 之面向对象

文章目录 Java基础(2) 之面向对象1.对象2.类类的注意事项 3.this关键字4.构造器注意 5.封装性6.实体JavaBean实体类 7.成员变量和局部变量的区别8.staticstatic修饰成员变量static修饰成员方法static的注意事项工具类单例设计模式 9.代码块静态代码块实例代码块 10.继承权限修饰…

Springboot——使用poi实现excel动态图片导入解析

文章目录 前言依赖引入导入实现方式一方式二 前言 最近要实现一个导入导出的功能点,需要能将带图片的列表数据导出到excel中,且可以导入带图片的excel列表数据。 考虑到低代码平台的表头与数据的不确定性,技术框架上暂定使用Apache-POI。 …

java 自定义填充excel并导出

首先在resources下面放一个excel模板 1. 方法签名和请求映射 RequestMapping(value "/ExportXls") public ResponseEntity<byte[]> rwzcExportXls(HttpServletRequest request, RequestBody JSONArray jsonArray) throws IOException { RequestMapping(val…

ubuntu 开放 8080 端口快捷命令

文章目录 查看防火墙状态开放 80 端口开放 8080 端口开放 22端口开启防火墙重启防火墙**使用 xhell登录**&#xff1a; 查看防火墙状态 sudo ufw status [sudo] password for crf: Status: inactivesudo ufw enable Firewall is active and enabled on system startup sudo…

微服务实战——登录(普通登录、社交登录、SSO单点登录)

登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…

进阶功法:SQL 优化指南

目录标题 SQL 优化指南1. 插入数据优化1.1 批量插入数据1.2 手动提交事务1.3 主键顺序插入1.4 大批量插入数据步骤&#xff1a; 2. 主键优化主键设计原则拓展知识 3. ORDER BY 优化3.1 Using filesort3.2 Using index示例 3.3 ORDER BY 优化原则 4. GROUP BY 优化示例 4.1 GROU…

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…

电力设备图像分割系统源码&数据集分享

电力设备图像分割系统系统源码&#xff06;数据集分享 [yolov8-seg-efficientViT&#xff06;yolov8-seg-C2f-DCNV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI G…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

鸿蒙微内核IPC数据结构

鸿蒙内核IPC数据结构 内核为任务之间的通信提供了多种机制&#xff0c;包含队列、事件、互斥锁、信号量等&#xff0c;其中还有Futex(用户态快速锁)&#xff0c;rwLock(读写锁)&#xff0c;signal(信号)。 队列 队列又称为消息队列&#xff0c;是一种常用于任务间通信的数据…

ASP.NET MVC-懒加载-逐步加载数据库信息

环境&#xff1a; win10, .NET 6.0 目录 问题描述解决方案基础版数据库查询部分&#xff08;Entity Framework&#xff09;控制器前端页面 加载到表格版 问题描述 假设我数据库中有N个表&#xff0c;当我打开某页面时&#xff0c;每个表都先加载一部分&#xff08;比如20条&am…

Chainlit集成Dashscope实现语音交互网页对话AI应用

前言 本篇文章讲解和实战&#xff0c;如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型&#xff0c;阿里巴巴在github提供的有开…