interact with service in vista, how?

In msdn, there is a classic codes “Interacting with the User in a
Service”. I call it as this:

UserMessageBox(NULL, “winsta0”, “default”, “myWindow”, NULL, MB_OK); It
works well.

But in vista, I found it don’t work. So, everyone, in vista, who can
tell me how can I interact with service?

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
RPC_BINDING_HANDLE h,
LPSTR lpszWindowStation,
LPSTR lpszDesktop,
LPSTR lpszText,
LPSTR lpszTitle,
UINT fuStyle)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;

// Ensure connection to service window station and desktop, and
// save their handles.

GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);

// Impersonate the client and connect to the User’s
// window station and desktop.

RpcImpersonateClient(h);
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE,
MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
RpcRevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RpcRevertToSelf();
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);

// Display message box.

dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;

// Restore window station and desktop.

SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);

return result;
}

Services should not directly interact with the user, especially when there can be multiple users logged in. instead you should have an agent exe running under each user’s session and communicate with that agent exe using RPC and have the agent display UI on behalf of the service

d


From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of ZHANGP
Sent: Tuesday, December 19, 2006 9:05 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] interact with service in vista, how?

??? In msdn, there is a classic codes “Interacting with the User in a Service”. I call it as this:
UserMessageBox(NULL, “winsta0”, “default”, “myWindow”, NULL, MB_OK); It works well.
??? But in vista, I found it don’t work. So, everyone, in vista, who can tell me how can I interact with service?

DWORD dwGuiThreadId = 0;
?
int
UserMessageBox(
???RPC_BINDING_HANDLE h,
???LPSTR lpszWindowStation,
???LPSTR lpszDesktop,
???LPSTR lpszText,
???LPSTR lpszTitle,
???UINT fuStyle)
{
???DWORD dwThreadId;
???HWINSTA hwinstaSave;
???HDESK hdeskSave;
???HWINSTA hwinstaUser;
???HDESK hdeskUser;
???int result;
?
???// Ensure connection to service window station and desktop, and
???// save their handles.

??? GetDesktopWindow();
???hwinstaSave = GetProcessWindowStation();
???dwThreadId = GetCurrentThreadId();
???hdeskSave = GetThreadDesktop(dwThreadId);
?
???// Impersonate the client and connect to the User’s
???// window station and desktop.

??? RpcImpersonateClient(h);
???hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
???if (hwinstaUser == NULL)
???{
???RpcRevertToSelf();
???return 0;
???}
???SetProcessWindowStation(hwinstaUser);
???hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
???RpcRevertToSelf();
???if (hdeskUser == NULL)
???{
???SetProcessWindowStation(hwinstaSave);
???CloseWindowStation(hwinstaUser);
???return 0;
???}
???SetThreadDesktop(hdeskUser);
?
???// Display message box.

??? dwGuiThreadId = dwThreadId;
???result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
???dwGuiThreadId = 0;
?
???// Restore window station and desktop.

??? SetThreadDesktop(hdeskSave);
???SetProcessWindowStation(hwinstaSave);
???CloseDesktop(hdeskUser);
???CloseWindowStation(hwinstaUser);
?
???return result;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

My codes do what you said should be done. But in vista, it doesn’t work.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: 2006年12月20日 13:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] interact with service in vista, how?

Services should not directly interact with the user, especially when there can be multiple users logged in. instead you should have an agent exe running under each user’s session and communicate with that agent exe using RPC and have the agent display UI on behalf of the service

d


From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of ZHANGP
Sent: Tuesday, December 19, 2006 9:05 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] interact with service in vista, how?

In msdn, there is a classic codes “Interacting with the User in a Service”. I call it as this:
UserMessageBox(NULL, “winsta0”, “default”, “myWindow”, NULL, MB_OK); It works well.
But in vista, I found it don’t work. So, everyone, in vista, who can tell me how can I interact with service?

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
RPC_BINDING_HANDLE h,
LPSTR lpszWindowStation,
LPSTR lpszDesktop,
LPSTR lpszText,
LPSTR lpszTitle,
UINT fuStyle)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;

// Ensure connection to service window station and desktop, and
// save their handles.

GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);

// Impersonate the client and connect to the User’s
// window station and desktop.

RpcImpersonateClient(h);
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
RpcRevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RpcRevertToSelf();
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);

// Display message box.

dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;

// Restore window station and desktop.

SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);

return result;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Take a look at the paper
http://www.microsoft.com/whdc/system/vista/services.mspx which both
describes the problem you are having and the solution. In general, if you
find a problem, seaching the WHDC site http://www.microsoft.com/whdc as
well as the OSR site http://www.osronline.com is a good way to start
looking for a solution.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply

l
“ZHANGP” wrote in message news:xxxxx@ntdev…
My codes do what you said should be done. But in vista, it doesn’t work.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: 2006?12?20? 13:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] interact with service in vista, how?

Services should not directly interact with the user, especially when there
can be multiple users logged in. instead you should have an agent exe
running under each user’s session and communicate with that agent exe using
RPC and have the agent display UI on behalf of the service

d

________________________________________
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of ZHANGP
Sent: Tuesday, December 19, 2006 9:05 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] interact with service in vista, how?

In msdn, there is a classic codes “Interacting with the User in a
Service”. I call it as this:
UserMessageBox(NULL, “winsta0”, “default”, “myWindow”, NULL, MB_OK); It
works well.
But in vista, I found it don’t work. So, everyone, in vista, who can
tell me how can I interact with service?

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
RPC_BINDING_HANDLE h,
LPSTR lpszWindowStation,
LPSTR lpszDesktop,
LPSTR lpszText,
LPSTR lpszTitle,
UINT fuStyle)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;

// Ensure connection to service window station and desktop, and
// save their handles.

GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);

// Impersonate the client and connect to the User’s
// window station and desktop.

RpcImpersonateClient(h);
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE,
MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
RpcRevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RpcRevertToSelf();
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);

// Display message box.

dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;

// Restore window station and desktop.

SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);

return result;
}


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> In msdn, there is a classic codes "Interacting with the User in a

Service". I call it as this:

UserMessageBox(NULL, “winsta0”, “default”, “myWindow”, NULL, MB_OK); It
works well.

But in vista, I found it don’t work.

The feature is completely removed from Vista due to security reasons. Services
in Vista cannot show any UI at all. Sorry.

The correct way is - add the RPC/DCOM server interface to your service, and
then write a client UI app which will call this interface.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

>My codes do what you said should be done. But in vista, it doesn’t work.

Correct. This is by design. MS prohibited this in Vista.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Maxim S. Shatskih wrote:

Vista due to security reasons.

The correct way is - add the RPC/DCOM server interface to your service, and
then write a client UI app which will call this interface.

And the punch line is some of the worst security holes over the past
five years have been in RPC/DCOM!

Does anyone know if that crap has been re-written for Vista?

> And the punch line is some of the worst security holes over the past

five years have been in RPC/DCOM!

So what? It is secure architecturally, with the holes being due to minor typo
bugs, and developing the client-server COM-based pair which will run local
only
without exposing itself to the network - is secure.

All Windows administrative tools run this way.

Showing the UI from the service is unsecure architecturally.

Does anyone know if that crap has been re-written for Vista?

It does not need any rewrite, just full code review with small bug fixes.
Rewrite of such a complex system will introduce more bugs, including
security-sensitive, so, with such a code, only the code age can help :slight_smile:

Anyway it is no more recommended for general-purpose development - .NET
Remoting is recommended. Why? Because it is too complex to develop for it, for
DCOM at least.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com