尝试显示我的屏幕保护程序的配置窗口时出现的问题(来自以高强制完整性级别运行的GUI应用程序)

时间:2015-05-25 02:16:07

标签: c++ c windows winapi windows-shell

我有一个带有自己的屏幕保护程序的旧项目。该项目的GUI应用程序有一个选项“配置屏幕保护程序”,它应该调出我的屏幕保护程序配置窗口(您通常从控制面板获取 - >显示 - >个性化 - >屏幕保护程序 - >设置。)

要显示配置窗口,需要使用/c参数described here来调用屏幕保护程序进程。屏幕保护程序本身放在系统目录中,即"C:\Windows\System32"

因此,为了从我的(32位)GUI应用程序模拟这个,我执行以下操作:

//Error checks are omitted for brevity
BOOL bResult = FALSE;

TCHAR buffSysFldr[MAX_PATH];
buffSysFldr[0] = 0;
::GetSystemDirectory(buffSysFldr, SIZEOF(buffSysFldr));

//Make the path, which basically becomes:
//  "C:\Windows\System32\mysvr.scr" /c
TCHAR buff[MAX_PATH];
buff[0] = 0;
::StringCbPrintf(buff, sizeof(buff), L"\"%s\\mysvr.scr\" /c", buffSysFldr);

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);

PVOID OldValue;
Wow64DisableWow64FsRedirection(&OldValue);

//And run it
if(CreateProcess(NULL, buff, NULL, NULL, FALSE, 
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, 
    NULL, NULL, &si, &pi))
{
    //Success
    bResult = TRUE;
}

Wow64RevertWow64FsRedirection(OldValue);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

当我将其部署到Windows 7计算机时,上面的代码返回bResult = TRUE,但我的屏幕保护程序的配置窗口永远不会显示。

我在32位和64位Windows 7上都尝试过,认为Wow64重定向与它有关,但它仍然没有改变结果。

知道为什么这不起作用?

PS。当我将该命令复制并粘贴到命令提示符中时,它运行正常并显示我的配置窗口没有问题:

enter image description here

编辑经过进一步审核后发现问题似乎与我的GUI应用程序以High Mandatory Integrity LevelS-1-16-12288一起运行这一事实有关这就是为什么屏幕保护程序的配置窗口没有显示的原因。如果我使用常规中等完整性级别或S-1-16-8192运行我的GUI应用程序,配置窗口将显示OK。

否则,我可以看到屏幕保护程序的RegisterDialogClasses方法被称为OK,但是当我从中返回TRUE时,ScreenSaverConfigureDialog永远不会被调用。

由于引入了完整性级别以防止具有较低级别的进程将消息发送到具有更高级别的进程,显然屏幕保护程序配置机制尝试将一些消息发送到我的GUI应用程序(出于任何未记录的原因)并且失败然后默默地失败好吧......

所以这是最新的。无论谁知道如何解决这个问题,我都会感激任何意见(除了降低我的GUI应用程序的完整性级别,我显然不想这样做。)

1 个答案:

答案 0 :(得分:0)

该死的微软documentation(对不起,我今天只是浪费了一整天来试图修复它。)

对于其他任何人来说 - 事实证明,人们需要这样称呼它:

  

" C:\ Windows \ System32下\ mysvr.scr" / C:N

其中N是父窗口的窗口句柄,表示为整数。通过检查通过控制面板显示的配置窗口的命令行找到它(使用Process Explorer完成。)

就我而言,由于我的GUI流程以更高的完整性级别运行,因此执行以下操作就足够了:

HWND hWndToUse = ::GetDesktopWindow();
::StringCbPrintf(buff, sizeof(buff), L"\"%s\\mysvr.scr\" /c:%d", buffSysFldr, (int)hWndToUse);

那就是它!