CreateDesktop() 与 vista 和 UAC on (C, windows)

标签 c windows windows-vista uac

我在 CreateDesktop() with Vista UAC (C Windows) 中问过这个 我设置了赏金,但在试图否决唯一的答案时,错误地按下了“接受”(我已经醒了超过 48 小时)。所以我再问一遍。

我正在使用 CreateDesktop() 创建一个临时桌面,应用程序将在其中运行、执行清理操作(同时保持不受影响)并终止。一旦应用程序消失,我将关闭该桌面。使用 Windows XP 甚至 Vista 时一切都很好。当您启用(烦人的)UAC 时会出现问题。

创建桌面时一切正常,但是当您调用 CreateProcess() 在该桌面上打开程序时,它会导致打开的应用程序崩溃,并出现 User32.dll 异常。

我已经阅读了很多有关 Windows 上的不同桌面和层以及内存限制的信息。然而,我打开的大多数程序(作为测试场景)都没有问题,但有少数(如 IE、记事本、Calc 和我自己的应用程序)导致崩溃。

任何人都知道为什么在带有 UAC 的 Vista 上会发生这种情况,或者更具体地说是针对那些特定程序?以及如何解决这个问题?

谁有一个很好的例子,说明如何在启用 UAC 的 Vista 下创建桌面并在其中打开应用程序而无需切换到桌面?

感谢代码。

谢谢

使用的代码是

SECURITY_ATTRIBUTES sa;

HDESK dOld;
HDESK dNew;

BOOL switchdesk, switchdesk2, closedesk;
int AppPid;

sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);

//Get handle to current desktop
dOld = OpenDesktopA("default", 0, TRUE, DESKTOP_SWITCHDESKTOP| 
                                        DESKTOP_WRITEOBJECTS|
                                        DESKTOP_READOBJECTS|
                                        DESKTOP_ENUMERATE|
                                        DESKTOP_CREATEWINDOW|
                                        DESKTOP_CREATEMENU);
if(!dOld)
{
    printf("Failed to get current desktop handle !!\n\n");
    return 0;
}

//Make a new desktop
dNew = CreateDesktopA("kaka", 0, 0, 0, DESKTOP_SWITCHDESKTOP|
                                          DESKTOP_WRITEOBJECTS|
                                          DESKTOP_READOBJECTS|
                                          DESKTOP_ENUMERATE|
                                          DESKTOP_CREATEWINDOW|
                                          DESKTOP_CREATEMENU, &sa);

if(!dNew)
{
    printf("Failed to create new desktop !!\n\n");
    return 0;
}

AppPid = PerformOpenApp(SomeAppPath);
if(AppPid == 0)
{
    printf("failed to open app, err = %d\n", GetLastError());
}
else
{
    printf("App pid = %d\n", AppPid);
}


closedesk = CloseDesktop(dNew);

if(!closedesk)
{
    printf("Failed to close new desktop !!\n\n");
    return 0;
}


return 0;

最佳答案

正确的解决方案是上面 ChristianWimmer 的简短评论:

The desktop must have a security descriptor that allows access to lower integrity level like IE has. Otherwise the GUI cannot access the desktop. – ChristianWimmer Jul 22 '10 at 17:00

由于答案有点隐蔽,也没有源代码示例,所以我在这里说清楚:

如果 IE 在保护模式下运行,则浏览器选项卡将创建为低完整性进程。如果桌面没有低完整性强制标签,低完整性选项卡进程将无法初始化。

因此,主 IE 进程也终止了。一个有趣的观察是,如果您从安全区域提供命令行 URL 启动 IE,那么 IE 将成功启动,因为安全区域默认禁用保护模式。

我检查了默认桌面的完整性级别,确实我能够验证默认桌面的完整性级别较低!因此,解决该问题的最简单方法是 (1) 创建新桌面,(2) 从默认桌面获取强制标签,以及 (3) 将其复制到新桌面中。对于(2)和(3),可以使用如下代码

PACL pSacl;
PSECURITY_DESCRIPTOR pSecurityDescriptor;
DWORD dwResult;

dwResult = GetSecurityInfo(hDefaultDesktop, SE_WINDOW_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, &pSacl, &pSecurityDescriptor);

if (dwResult == ERROR_SUCCESS) {
    if (pSacl != NULL) {
        dwResult = SetSecurityInfo(hNewDesktop, SE_WINDOW_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);

        if (dwResult != ERROR_SUCCESS)
            _tprintf(_T("SetSecurityInfo(hNewDesktop) failed, error = %d"), dwResult);
    }

    LocalFree(pSecurityDescriptor);
} else {
    _tprintf(_T("GetSecurityInfo(hDefaultDesktop) failed, error = %d"), dwResult);
}

@CristianWimmer:感谢您提供正确解决方案的提示。这节省了我很多时间!!

关于CreateDesktop() 与 vista 和 UAC on (C, windows),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1395351/

相关文章:

c++ - 无法使用 AMQP-CPP 在 RabbitMQ 服务器上成功发布消息

encryption - 跨机器加密/解密是禁忌

c# - 如何在 C#/Vista 中将鼠标事件传递给我背后的应用程序?

将一系列字符转换为各自的 int

使用结构时发出警告

windows - Git:查找大包文件中的最大文件

PHP hash_hmac() 操作系统差异

windows-7 - PnPUtil.exe 在 64 位系统中的位置是什么?

c - C 中标准输出的缓冲行为

c - 使用免费时程序 "sometimes"崩溃