关于Windows Service中读取HKEY_CURRENT_USER中键值的问题

sexinshanghai 2013-03-18 10:15:52
各位大哥,小弟最近在研究Windows Service中读取HKEY_CURRENT_USER中键值的问题。按照msdn的说法,我做了以下的代码:
DWORD GetActiveConsoleSessionId()
{
DWORD dwConsoleSessionId = 0xFFFFFFFF;

dwConsoleSessionId = WTSGetActiveConsoleSessionId();
if(dwConsoleSessionId == 0xFFFFFFFF)
{

}else
{

}

return dwConsoleSessionId;
}

Void GetCurrentToken(HANDLE& hToken)
{
BOOL bRet = TRUE;
HANDLE hUserToken = NULL;
HANDLE hDupUserToken = NULL;


DWORD dwActiveSid = GetActiveConsoleSessionId();
BOOL BRet_WTSQueryUserToken = WTSQueryUserToken(dwActiveSid, &hUserToken);
if (BRet_WTSQueryUserToken == FALSE)
{

hToken = NULL;
return FALSE;
}

BOOL BRet_DuplicateToken = DuplicateToken(hUserToken, SecurityImpersonation, &hDupUserToken);
if (BRet_DuplicateToken == FALSE)
{

CloseHandle(hUserToken);
hToken = NULL;
return FALSE;
}

CloseHandle(hUserToken);
return bRet
}


下面是服务程序中的代码
TCHAR szUsername[MAX_PATH];
DWORD dwUsernameLen = MAX_PATH;
HANDLE hCurrentUserToken = NULL;
BOOL BRet_GetConsoleUserToken = GetConsoleUserToken(hCurrentUserToken);
if (BRet_GetConsoleUserToken == FALSE)
{
return FALSE;
}

BOOL BRet_ImpersonateLoggedOnUser = ImpersonateLoggedOnUser(hCurrentUserToken);
if (BRet_ImpersonateLoggedOnUser == FALSE)
{
CloseHandle(hCurrentUserToken);
return FALSE;
}

GetUserName(szUsername, &dwUsernameLen);
PROFILEINFO cuProfileInfo;
memset(&cuProfileInfo, 0, sizeof(cuProfileInfo));
cuProfileInfo.dwSize = sizeof(PROFILEINFOA);
cuProfileInfo.lpUserName = szUsername;
cuProfileInfo.dwFlags = 1;

BOOL BRet_LoadUserProfile = LoadUserProfile(hCurrentUserToken, &cuProfileInfo);
if (BRet_LoadUserProfile == FALSE)
{

CloseHandle(hCurrentUserToken);
return FALSE;
}

但是该程序在Windows服务中运行的时候在ImpersonateLoggedOnUser的时候失败了,GetLastError的结果是:6,句柄无效。不明白为什么。请各位大哥帮我看一下,谢谢
...全文
346 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-03-19
  • 打赏
  • 举报
回复
以下内容仅供参考: 用调试器(OD,WINDBG等)调试服务程序 To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName The ProgramName is the image file for the service application you are debugging. Do not specify a path. For example, the ProgramName might look like MyService.exe. Under this key create a string data value called Debugger. The value of this string should be set to the full path of the debugger that will be used. For example, c:\Debuggers\windbg.exe In addition to setting this registry key, the service application must be marked as "interactive". This allows your service to interact with the desktop, and allows the debugger window to appear on your desktop. This again requires modifying a registry key: you must bitwise-or the type entry for your service with 0x100 (this is the value for SERVICE_INTERACTIVE_PROCESS according to Winnt.h). The exact location and name of this registry entry varies. For example: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyServiceKey Finally, you need to adjust the service application timeout. Otherwise, the service application will kill the debugger within 20 seconds after starting. Adjusting the timeout involves setting an entry in the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control Under this key, create a DWORD data value called ServicesPipeTimeout. Set this entry to the amount of time in milliseconds that you want the service to wait before timing out. For example, 60,000 is one minute, while 86,400,000 is 24 hours. 设置ServicesPipeTimeout后需要重启系统才生效 Now, when the service is started, the debugger will also start. When the debugger starts, it will stop at the initial process breakpoint, before the service has begun running. This allows you to set breakpoints or otherwise configure your debugging session to let you monitor the startup of your service. Another option is to place calls to the DebugBreak function in your service from the point at which you would like to break into the debugger. (For more information, see DebugBreak in the Platform SDK documentation.) If your service is running with other services in a Service Host Process, you may need to isolate the service into its own Service Host Process.
sexinshanghai 2013-03-19
  • 打赏
  • 举报
回复
对于这个问题我找到了一种替代的办法: 通过查找进程explorer.exe来获得token,进而使用ImpersonateLoggedOnUser来模拟用户登入,然后再调用LoadUserProfile获取打开HKEY_CURRENT_USER的句柄。
sexinshanghai 2013-03-19
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
以下内容仅供参考: 用调试器(OD,WINDBG等)调试服务程序 To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a……
谢谢您的帮助。不过我通过打印日志的方式可以确认是什么问题,可是却不明白为什么产生了这个问题。我确实是按照msdn说的做的,可是一直得不到正确的结果,苦恼中
sexinshanghai 2013-03-18
  • 打赏
  • 举报
回复
补充一下,WTSGetActiveConsoleSessionId这个函数的调用返回的结果是0.

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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