百度空间 | 百度首页 
 
查看文章
 
Inside of ServiceMessageBox
2009-06-16 02:42

MB_SERVICE_NOTIFICATION,这是MessageBox函数提供的一个Type值,这个值允许通过CSRSS.exe而不是进程本身来弹出一个MessageBox。

当调用MessageBox时nType参数中包含了MB_SERVICE_NOTIFICATION或MB_DEFAULT_DESKTOP_ONLY标志,MessageBox将调用use32.dll内部的一个函数:ServiceMessageBox,代码如下:

MessageBoxWorker(...)

{

....省略无关代码...

    if (dwStyle & (MB_DEFAULT_DESKTOP_ONLY | MB_SERVICE_NOTIFICATION)) {

        if (pMsgBoxParams->hwndOwner != NULL) {
             SetLastError(ERROR_INVALID_PARAMETER);
            return 0;
        }

        return ServiceMessageBox(pMsgBoxParams->lpszText,
                                 pMsgBoxParams->lpszCaption,
                                 dwStyle & ~MB_SERVICE_NOTIFICATION);
    }
    }

ServiceMessageBox根据当前的会话状况不同调用不同的函数来实现弹框。

XP的话首先会判断当前是否是终端服务器版本(通过UserSharedData->SuiteMasks是否包含VER_SUITE_TERMINAL ),如果不是服务器版本,直接调用NtRaiseHardError 来通知CSRSS,VISTA则不会走这一步,因为VISTA默认就会有1个以上的会话在运行。

接着ServiceMessageBox会通过NtOpenThreadToken函数来试图打开当前线程的Token,此函数仅在当前线程进行了Token 模拟(Impersonation)时才会返回成功。若此函数返回了被模拟的线程Token,则通过NtQueryInformationToken(TokenSessionId)取得此TOKEN所在的会话ID。

接着,会通过kernel32!ProcessIdToSessionId调用NtQueryInformationProcess(ProcessSessionInformation)获得当前进程的SessionId(若失败,则从NtCurretnTeb()->Peb->SessionId获取)

最后,比较模拟的Token的SessionId是否等于当前进程的SessionId,若不等于,说明当前进程和被模拟的TOKEN不属于同一会话,此时,ServiceMessageBox会通过调用winsta!WinStationSendMessageW来实现弹框,WinStationSendMessageW函数调用CSmartSession::ShowMessageBox找到当前活动会话中的CSRSS,并调用RpcShowMessageBox来通知当前活动会话中的csrss来弹出通知对话框。

若会话相同,则仍旧调用NtRaiseHardError来通知默认ExceptionPort的csrss.

通常系统服务在弹出对话框前都会模拟当前活动会话中的TOKEN,这样调用MessageBox弹框时就可以在当前用户上显示出来。

在VISTA之前,因为默认会话和服务是在同一个会话中,所以我们一般感受到的服务弹框都是调用NtRaiseHardError实现的,只有在切换到其他会话时,才会出现调用 RpcShowMessageBox的情况

但VISTA之后,由于服务进程单独享有一个会话(0号会话),因此所有来自服务的弹框,都会通过RpcShowMessageBox来显示出来。

至于CSRSS如何处理MESSAGEBOX的RPC(HandleHandError等),早已是众所周之了,在这里不多赘述,感兴趣的可以参考WIN2K源代码


类别:默认分类 | 添加到搜藏 | 浏览() | 评论 (3)
 
最近读者:
 
网友评论:
1
2009-06-16 07:40 | 回复
mark
 
2
2009-06-16 10:14 | 回复
问个白痴问题……
“程序无法关闭,因为被系统锁住”是不是用这个方式弹出的?
 
3
2009-06-16 12:01 | 回复
这个东西是拿来做什么的?
是出于兴趣对MessageBox实现的分析吗
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu