//下面是服务程序中的代码
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;
OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
TCHAR szParameter[10] = {0};
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
18 个解决方案
#1
牛人呢?
#2
牛人还没出现
#3
mark
#4
在你那个改桌面的进程里打断点调试啊!
调用设置桌面的函数后,GetLastError()看下
调用设置桌面的函数后,GetLastError()看下
#5
程序没有错,
原因是服务程序是和登陆用户无关的,先于WinLogon,而桌面是和用户相关的,一个用户对应一个或多个桌面——当然,只有一个是可见的。
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
看了一些牛人说可以用DACL和ACEs来做,可是改过后还是不行。因为我对DACL和ACEs不熟,所以希望能有人指点一下。
原因是服务程序是和登陆用户无关的,先于WinLogon,而桌面是和用户相关的,一个用户对应一个或多个桌面——当然,只有一个是可见的。
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
看了一些牛人说可以用DACL和ACEs来做,可是改过后还是不行。因为我对DACL和ACEs不熟,所以希望能有人指点一下。
#6
救命啊
#7
程序没有错
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
----------------------------------------------------------------
既然你硬要这么说,我也没办法
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
----------------------------------------------------------------
既然你硬要这么说,我也没办法
#8
错误信息是什么?
#9
1 CreateService 时 在dwServiceType加上SERVICE_INTERACTIVE_PROCESS标记.
2 http://www.osronline.com/showthread.cfm?link=102869
2 http://www.osronline.com/showthread.cfm?link=102869
#10
我的环境是Windows XP,我是用服务程序创建了一个客户程序,这个客户程序使用了IActiveDesktop来设置桌面.我想知道,客户程序里面要加上一些特别的代码吗?
下面是我在创建客户程序的代码
HANDLE hToken;
HDESK hdesk;
HWINSTA hwinsta;
PROCESS_INFORMATION pi;
PSID psid;
STARTUPINFO si;
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;
OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;
HWND hDesk = GetDesktopWindow();
// BOOL bOk = ImpersonateLoggedOnUser(hToken);
// GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");
//
// obtain a handle to the interactive windowstation
//
hwinsta = OpenWindowStation(
"winsta0",
FALSE,
READ_CONTROL | WRITE_DAC
);
if (hwinsta == NULL)
return RTN_ERROR;
HWINSTA hwinstaold = GetProcessWindowStation();
GenericLog(Info,"WindowStation Old = %.8x,Curr = %.8x",hwinstaold,hwinsta);
//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
if (!SetProcessWindowStation(hwinsta))
return RTN_ERROR;
//
// obtain a handle to the "default" desktop
//
hdesk = OpenDesktop(
"default",
0,
FALSE,
READ_CONTROL | WRITE_DAC |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
);
if (hdesk == NULL)
return RTN_ERROR;
//
// obtain the logon sid of the user fester
//
if (!ObtainSid(hToken, &psid))
return RTN_ERROR;
//
// add the user to interactive windowstation
//
if (!AddTheAceWindowStation(hwinsta, psid))
return RTN_ERROR;
//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, psid))
return RTN_ERROR;
//
// free the buffer for the logon sid
//
RemoveSid(&psid);
//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
//
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
TCHAR szParameter[10] = {0};
// ShellExecute(NULL,"open",lpAppName,NULL,NULL,SW_HIDE);
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
GenericLog(Info,"Running %s ....",lpAppName);
UnregisteTimer(TIMER_CONNECT);
RegisteTimer(TIMER_FEEDDOG,3000);
return 1;
}
else
{
GenericLog(Info,"CreateProcess %s Fails ,reason = %d",lpAppName,GetLastError());
}
SetProcessWindowStation(hwinstaold);
return RTN_OK;
下面是我在创建客户程序的代码
HANDLE hToken;
HDESK hdesk;
HWINSTA hwinsta;
PROCESS_INFORMATION pi;
PSID psid;
STARTUPINFO si;
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;
OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;
HWND hDesk = GetDesktopWindow();
// BOOL bOk = ImpersonateLoggedOnUser(hToken);
// GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");
//
// obtain a handle to the interactive windowstation
//
hwinsta = OpenWindowStation(
"winsta0",
FALSE,
READ_CONTROL | WRITE_DAC
);
if (hwinsta == NULL)
return RTN_ERROR;
HWINSTA hwinstaold = GetProcessWindowStation();
GenericLog(Info,"WindowStation Old = %.8x,Curr = %.8x",hwinstaold,hwinsta);
//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
if (!SetProcessWindowStation(hwinsta))
return RTN_ERROR;
//
// obtain a handle to the "default" desktop
//
hdesk = OpenDesktop(
"default",
0,
FALSE,
READ_CONTROL | WRITE_DAC |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
);
if (hdesk == NULL)
return RTN_ERROR;
//
// obtain the logon sid of the user fester
//
if (!ObtainSid(hToken, &psid))
return RTN_ERROR;
//
// add the user to interactive windowstation
//
if (!AddTheAceWindowStation(hwinsta, psid))
return RTN_ERROR;
//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, psid))
return RTN_ERROR;
//
// free the buffer for the logon sid
//
RemoveSid(&psid);
//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
//
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
TCHAR szParameter[10] = {0};
// ShellExecute(NULL,"open",lpAppName,NULL,NULL,SW_HIDE);
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
GenericLog(Info,"Running %s ....",lpAppName);
UnregisteTimer(TIMER_CONNECT);
RegisteTimer(TIMER_FEEDDOG,3000);
return 1;
}
else
{
GenericLog(Info,"CreateProcess %s Fails ,reason = %d",lpAppName,GetLastError());
}
SetProcessWindowStation(hwinstaold);
return RTN_OK;
#11
我要的不是与服务程序进行交互,我的目的只是让服务程序在用户登陆后创建一个新进程,这个新进程能够修改用户的桌面.
#12
这个线程能创建成功吗?
#13
线程创建是成功的,我的目的是让服务程序启动一个新进程,而不是要服务程序本身去和桌面交互
#14
我的客户进程里面用的IActiveDesktop来改变桌面,这有关系吗?
#15
应该是不用的,不过你还是在IActiveDesktop输出当前的用户名,看看是不是正确。
#16
那么我是该用"winsta0\\default"桌面呢?还是用其他的什么桌面呢?
#17
按照你所说的,我在客户程序里面调用GetUserName()得到的是当前用户的用户名.我试了一下,如果用服务程序打开客户程序,那么客户程序将不能显示桌面背景,可是如果这时打开IE的属性,点击确定,那么背景就会显示出来.而直接运行客户程序的话,就不会出现问题.
又,我的服务程序是用OpenProcessToken打开EXPLORER.EXE的令牌.在调用CreateProcessAsUser前调用ImpersonateLoggedOnUser,在调用完CreateProcessAsUser()后调用RevertToSelf().
又,我的服务程序是用OpenProcessToken打开EXPLORER.EXE的令牌.在调用CreateProcessAsUser前调用ImpersonateLoggedOnUser,在调用完CreateProcessAsUser()后调用RevertToSelf().
#18
呵呵,问题解决了,在ImpersonateLoggedOnUser之前调用LoadUserProfile(),因为IActiveDesktop在设置桌面的时候会用到一些HKEY_CURRENT_USER键里面的东西,CreateProcessAsUser不负责载入用户配置.
新问题又来了
在XP下测试没问题,怎么在Win2000下又不好使了呢?
新问题又来了
在XP下测试没问题,怎么在Win2000下又不好使了呢?
#1
牛人呢?
#2
牛人还没出现
#3
mark
#4
在你那个改桌面的进程里打断点调试啊!
调用设置桌面的函数后,GetLastError()看下
调用设置桌面的函数后,GetLastError()看下
#5
程序没有错,
原因是服务程序是和登陆用户无关的,先于WinLogon,而桌面是和用户相关的,一个用户对应一个或多个桌面——当然,只有一个是可见的。
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
看了一些牛人说可以用DACL和ACEs来做,可是改过后还是不行。因为我对DACL和ACEs不熟,所以希望能有人指点一下。
原因是服务程序是和登陆用户无关的,先于WinLogon,而桌面是和用户相关的,一个用户对应一个或多个桌面——当然,只有一个是可见的。
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
看了一些牛人说可以用DACL和ACEs来做,可是改过后还是不行。因为我对DACL和ACEs不熟,所以希望能有人指点一下。
#6
救命啊
#7
程序没有错
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
----------------------------------------------------------------
既然你硬要这么说,我也没办法
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
----------------------------------------------------------------
既然你硬要这么说,我也没办法
#8
错误信息是什么?
#9
1 CreateService 时 在dwServiceType加上SERVICE_INTERACTIVE_PROCESS标记.
2 http://www.osronline.com/showthread.cfm?link=102869
2 http://www.osronline.com/showthread.cfm?link=102869
#10
我的环境是Windows XP,我是用服务程序创建了一个客户程序,这个客户程序使用了IActiveDesktop来设置桌面.我想知道,客户程序里面要加上一些特别的代码吗?
下面是我在创建客户程序的代码
HANDLE hToken;
HDESK hdesk;
HWINSTA hwinsta;
PROCESS_INFORMATION pi;
PSID psid;
STARTUPINFO si;
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;
OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;
HWND hDesk = GetDesktopWindow();
// BOOL bOk = ImpersonateLoggedOnUser(hToken);
// GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");
//
// obtain a handle to the interactive windowstation
//
hwinsta = OpenWindowStation(
"winsta0",
FALSE,
READ_CONTROL | WRITE_DAC
);
if (hwinsta == NULL)
return RTN_ERROR;
HWINSTA hwinstaold = GetProcessWindowStation();
GenericLog(Info,"WindowStation Old = %.8x,Curr = %.8x",hwinstaold,hwinsta);
//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
if (!SetProcessWindowStation(hwinsta))
return RTN_ERROR;
//
// obtain a handle to the "default" desktop
//
hdesk = OpenDesktop(
"default",
0,
FALSE,
READ_CONTROL | WRITE_DAC |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
);
if (hdesk == NULL)
return RTN_ERROR;
//
// obtain the logon sid of the user fester
//
if (!ObtainSid(hToken, &psid))
return RTN_ERROR;
//
// add the user to interactive windowstation
//
if (!AddTheAceWindowStation(hwinsta, psid))
return RTN_ERROR;
//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, psid))
return RTN_ERROR;
//
// free the buffer for the logon sid
//
RemoveSid(&psid);
//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
//
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
TCHAR szParameter[10] = {0};
// ShellExecute(NULL,"open",lpAppName,NULL,NULL,SW_HIDE);
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
GenericLog(Info,"Running %s ....",lpAppName);
UnregisteTimer(TIMER_CONNECT);
RegisteTimer(TIMER_FEEDDOG,3000);
return 1;
}
else
{
GenericLog(Info,"CreateProcess %s Fails ,reason = %d",lpAppName,GetLastError());
}
SetProcessWindowStation(hwinstaold);
return RTN_OK;
下面是我在创建客户程序的代码
HANDLE hToken;
HDESK hdesk;
HWINSTA hwinsta;
PROCESS_INFORMATION pi;
PSID psid;
STARTUPINFO si;
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;
OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;
HWND hDesk = GetDesktopWindow();
// BOOL bOk = ImpersonateLoggedOnUser(hToken);
// GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");
//
// obtain a handle to the interactive windowstation
//
hwinsta = OpenWindowStation(
"winsta0",
FALSE,
READ_CONTROL | WRITE_DAC
);
if (hwinsta == NULL)
return RTN_ERROR;
HWINSTA hwinstaold = GetProcessWindowStation();
GenericLog(Info,"WindowStation Old = %.8x,Curr = %.8x",hwinstaold,hwinsta);
//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
if (!SetProcessWindowStation(hwinsta))
return RTN_ERROR;
//
// obtain a handle to the "default" desktop
//
hdesk = OpenDesktop(
"default",
0,
FALSE,
READ_CONTROL | WRITE_DAC |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
);
if (hdesk == NULL)
return RTN_ERROR;
//
// obtain the logon sid of the user fester
//
if (!ObtainSid(hToken, &psid))
return RTN_ERROR;
//
// add the user to interactive windowstation
//
if (!AddTheAceWindowStation(hwinsta, psid))
return RTN_ERROR;
//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, psid))
return RTN_ERROR;
//
// free the buffer for the logon sid
//
RemoveSid(&psid);
//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
//
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
TCHAR szParameter[10] = {0};
// ShellExecute(NULL,"open",lpAppName,NULL,NULL,SW_HIDE);
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
GenericLog(Info,"Running %s ....",lpAppName);
UnregisteTimer(TIMER_CONNECT);
RegisteTimer(TIMER_FEEDDOG,3000);
return 1;
}
else
{
GenericLog(Info,"CreateProcess %s Fails ,reason = %d",lpAppName,GetLastError());
}
SetProcessWindowStation(hwinstaold);
return RTN_OK;
#11
我要的不是与服务程序进行交互,我的目的只是让服务程序在用户登陆后创建一个新进程,这个新进程能够修改用户的桌面.
#12
这个线程能创建成功吗?
#13
线程创建是成功的,我的目的是让服务程序启动一个新进程,而不是要服务程序本身去和桌面交互
#14
我的客户进程里面用的IActiveDesktop来改变桌面,这有关系吗?
#15
应该是不用的,不过你还是在IActiveDesktop输出当前的用户名,看看是不是正确。
#16
那么我是该用"winsta0\\default"桌面呢?还是用其他的什么桌面呢?
#17
按照你所说的,我在客户程序里面调用GetUserName()得到的是当前用户的用户名.我试了一下,如果用服务程序打开客户程序,那么客户程序将不能显示桌面背景,可是如果这时打开IE的属性,点击确定,那么背景就会显示出来.而直接运行客户程序的话,就不会出现问题.
又,我的服务程序是用OpenProcessToken打开EXPLORER.EXE的令牌.在调用CreateProcessAsUser前调用ImpersonateLoggedOnUser,在调用完CreateProcessAsUser()后调用RevertToSelf().
又,我的服务程序是用OpenProcessToken打开EXPLORER.EXE的令牌.在调用CreateProcessAsUser前调用ImpersonateLoggedOnUser,在调用完CreateProcessAsUser()后调用RevertToSelf().
#18
呵呵,问题解决了,在ImpersonateLoggedOnUser之前调用LoadUserProfile(),因为IActiveDesktop在设置桌面的时候会用到一些HKEY_CURRENT_USER键里面的东西,CreateProcessAsUser不负责载入用户配置.
新问题又来了
在XP下测试没问题,怎么在Win2000下又不好使了呢?
新问题又来了
在XP下测试没问题,怎么在Win2000下又不好使了呢?