【问】GDI API Bitblt 在 lsass.exe 中执行失败??【200】

CCED136 2006-11-16 01:58:59
我在 dll 中使用了 Bitblt ,经过测试完全正常,但是当我使用线程注入方式将 dll 注入到 lsass.exe
中后, Bitblt 执行失败 ,GetLassError 返回 6 ,我使用 VC7 及 C++Builder6 分别重写了这个dll

然后将 dll 注入到 lsass.exe 中,Bitblt 仍然执行失败。不知道到底怎么回事?

我的操作系统 Windows 2003 server,该问题还有一贴有相关描述,解决后一并给分。

http://community.csdn.net/Expert/topic/5162/5162746.xml?temp=.2476007
...全文
181 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
CCED136 2006-11-17
  • 打赏
  • 举报
回复
问题解决。根据 wangk(倒之) 的回答,从网上找了 n 多关于 服务与桌面交互的东西,然后经过自己测试,确实是这个问题。这里有点奇怪的地方就是,通过 Windows 服务管理器,我在 lsass 服务的配置中,选中了“允许服务与桌面交互”选项,并且重新启动计算机后,仍然发生 Bitblt 错误,可是通过下面的代码就能解决这个问题,不知道为什么。公布一下解决方法:

BOOL WINAPI ScreenCaptureDesktop()
{
BOOL IsSucceed = FALSE;

// 保存当前窗口属性
HWINSTA hwinstaLsass = GetProcessWindowStation();

if ( hwinstaLsass != NULL )
{
// 保存当前线程桌面
HDESK hdeskLsass = GetThreadDesktop( GetCurrentThreadId() );

if ( hdeskLsass != NULL )
{
// 获取目标窗口属性
HWINSTA hwinstaUser = OpenWindowStation(DefaultWindowStation, FALSE, MAXIMUM_ALLOWED);

if ( hwinstaUser != NULL )
{
// 设置目标窗口属性
if ( SetProcessWindowStation(hwinstaUser) )
{
// 获取目标桌面
HDESK hdeskUser = OpenDesktop(DefaultDesktop, 0, FALSE, MAXIMUM_ALLOWED);

if ( hdeskUser != NULL )
{
// 设置线程桌面
if ( SetThreadDesktop(hdeskUser) )
{
// to do something // 完成需要与桌面进行交互的功能
IsSucceed = ScreenCapture(); // 我在这里完成截屏操作

// 恢复线程原始桌面
SetThreadDesktop( hdeskLsass );
}

// 关闭目标桌面
CloseDesktop( hdeskUser );
}

// 恢复进程原始窗口属性
SetProcessWindowStation( hwinstaLsass );
}

// 关闭目标窗口属性
CloseWindowStation( hwinstaUser );
}
}
}

return IsSucceed;
}

好了,再次感谢 wangk(倒之) ,没有你的帮助,我就不能这么快的解决问题。

结帖了。
CCED136 2006-11-17
  • 打赏
  • 举报
回复
好,我现在就测试一下。还有,我在服务管理器上将 lsass.exe 服务的配置项“允许服务与桌面交互”选中,重启计算机后,还是不行。这个选项和你上面介绍的是不是一回事?
DentistryDoctor 2006-11-17
  • 打赏
  • 举报
回复
同意wangk说的。

在MSDN中查找"Starting an Interactive Client Process"
wangk 2006-11-16
  • 打赏
  • 举报
回复
1.lsass.exe在Service桌面环境中,顶层窗口句柄是存在的,但不是当前可见桌面。
2.lsass.exe不包含GUI线程,没有初始化GUI环境需要你手动进行。
3.service与桌面交互的方法我记得以前在CSDN中有帖子讨论过,你可以搜索一下。

用service取当前用户桌面图像的代码可以去参考开源的VNC软件。
CCED136 2006-11-16
  • 打赏
  • 举报
回复
我获取顶层窗口句柄这些过程都是正确的(我那个类里面已经判断了 句柄有效),错误出现在 BitBlt 这个地方。

你的意思是不是说我获取的 顶层窗口句柄 是错误的?

可是我改成 CreateDc("DISPLAY", NULL,NULL,NULL) ,返回的句柄仍然有效,错误仍然发生在 BitBlt 这个地方。

能不能给我说说,到底是怎么回事?还有,创建窗口没问题,但怎样才能“让它和用户桌面交互”?
wangk 2006-11-16
  • 打赏
  • 举报
回复
你在lsass.exe内创建一窗口,让它和用户桌面交互。之后才能去获取桌面顶层窗口句柄。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧