MORE INFORMATION
The general architecture for an interactive service on a
multiuser system is described in the following section. However, it may be
helpful for you to first read the section later in this article titled
"Understanding Services and Terminal Server". That section provides terms and
architectural information that pertain to this design.
Designing an Interactive Service for Terminal Server
If a service that is running on a multiuser system must interact
with the logged-on user, Microsoft recommends that the service interact by
means of a separate GUI application that runs in the user's session. Microsoft
recommends that this GUI application be designed to communicate with the
service through some method of interprocess communication, such as through a
named pipe.
Note This is a client/server architecture. You can configure the
client process (the GUI application) to run in each user session as a hidden
process. The easiest way to cause the client to run in each session is to add
the client process to the
Run key in the
HKEY_LOCAL_MACHINE hive of the registry.
For additional information, click the following
article number to view the article in the Microsoft Knowledge Base:
137367
Definition of the RunOnce Keys in the Registry
The server process (your service) then communicates
with the appropriate client through some means of interprocess communication to
tell the client when to display the GUI. The client, in turn, communicates the
results of the user's interaction back to the service so that the service can
act appropriately.
Because there will be multiple clients running on
the system (a separate client running in each user session), the service must
have a well-defined method to distinguish the clients. The most common method
to distinguish clients is to name the channel of communication by using the
client's session ID.
For example, if the client is running in session
4, the client may create a pipe whose name is a concatenation of an unpublished
GUID, followed by "Channel_4". The client will then pass its session ID to the
service (perhaps by connecting to another pipe that is created by the service)
so that the service knows to connect to the "Channel_4" pipe. The client can
obtain its session ID by calling
WTSQuerySessionInformation() with
WTSSessionId as the information class.
Important For maximum security, the client must specify
FILE_FLAG_FIRST_PIPE_INSTANCE in the
dwOpenMode parameter when calling
CreateNamedPipe(). This protects against attempts by rogue applications to connect
to a process that runs in the LocalSystem account.
When you are
designing the client and service applications, a final consideration is the
sharing of named kernel objects (for example, events, mutexes, semaphores, file
mapping objects, and other objects). By default, a kernel object is accessible
only in the session where the object was created. This is named the
local session namespace. If the client application and the service application must both
access the same kernel object, you must create the object in the global
namespace. To create an object in the global namespace, prefix the object name
with "Global\". Global objects are accessible across Terminal Services
sessions.
Note By default, pipes are global. Therefore, the "Global\" prefix is
not required on the pipe name. To determine whether the "Global\" prefix is
required for an object, see the Platform SDK documentation for the object.
Understanding Services and Terminal Server
A service is an application that can execute even when no user is
logged on to the system. A service typically runs under a special user account
named the
LocalSystem account. Applications that run under the LocalSystem account have
special privileges that give them a lot of power on the local computer. Under
most circumstances, you do not want to give a user to this kind of power (it
can be used to bypass system security).
To additionally isolate a
service from the interactive user, the service typically runs in a
noninteractive window station. This means that even if the service does display
a GUI, the interface will not be visible to the user.
Before
Terminal Server, if a service had to display a GUI, the service was installed
as an
interactive service. In this way, the service ran under the LocalSystem
account on the interactive window station. On a single-user system, a GUI that
is displayed by an interactive service appears on the desktop of the
interactive user.
Terminal Services-based servers use the concept of
a user
session. When multiple users log on to the Terminal Services-based
server, there are multiple user sessions. Each session is identified by a
unique session ID (beginning at session 0 and incrementing by one for each
session), and each session receives its own interactive window station. When a
user logs on to a Terminal Services-based server, the user connects to an
existing session. At that point, the system creates a new session to accept the
next connection. If a user logs off the Terminal Services-based computer, the
user's session is destroyed (unless it is session 0), and the session ID is
available for reuse.
A user can log on to a Terminal Services server
either locally or remotely:
- To log on locally, the user is physically present at the
Terminal Services-based server computer and logs on to the console session.
- To log on remotely, the user connects to the Terminal
Services-based server across a network through a Terminal Services client application.
On Windows NT 4.0 and Windows 2000, the console session always
has a session ID of 0, and remote sessions always have a session ID that is
greater than 0. On Windows XP, however, the console session can have
any session ID (including a session ID greater than 0). Likewise,
remote sessions can have
any session ID (including session 0).
When you design a
service, keep in mind that
all services run in session 0. Therefore, if an interactive service displays a GUI, it will be
visible only to the user who is connected to session 0.
Note A service cannot interact directly with any session except
session 0.
Because there is no way to guarantee that the interactive
user is connected to session 0, Microsoft recommends that a service not be
configured as an interactive service on Terminal Services-based servers.
Note Windows XP introduced a feature named
fast user switching (FUS). This feature is an implementation of Terminal Services
that allows multiple users to share a single computer. When FUS is turned on,
the user does not have to log off before another user dynamically initiates a
new user session (or switches to an existing user session) on the same
computer. This creates the dilemma where there is no way to know whether the
current interactive user is connected to session 0. Therefore, Microsoft
recommends that a service that is designed for Windows XP not be configured as
an interactive service.