Share via


Shared Services

One of the comments I made when doing my "first impressions" of the Mirra backup device was that the Windows software starts two separate services running in two different processes.

I see this a lot - people architect their product into multiple services (which is often a good thing), but they then run the services in separate processes.

Sometimes this is a good thing - for example, the Windows Media Connect add-on for Windows runs as two services - one service does very little, but runs as LocalSystem (full privileges).  The other service (which does most of the work) runs in a limited LocalService account.  By running as two services, in two different privilege levels, the Windows Media Connect carefully limits which functionality has to run with elevated privileges.  This is a good example of the principle of least privilege - isolate the parts of the functionality that need higher privileges and run them out-of-proc instead of running the entire service with elevated privileges.

But sometimes it doesn't really make sense.  Mirra is a good example, and there are others as well.  These products have multiple Windows Services, which run in the same security context, but use separate processes.

Why is this a big deal?  Well, unlike *nix, on Windows, a process is a relatively expensive entity.  It takes a non trivial amount of time to launch a process, and each process consumes a fair amount of system resources (something like 1M of virtual memory, just for the various process structures (virtual address map, handle table, etc), IIRC).  Each process running drains the system of resources that could be used for your application, so it's important to reduce the number of system processes running.  It always annoys me when I install some application and discover that it's installed three or four processes that run all the time on my machine, especially when those functions could have been combined into a single process.

For services, this is especially annoying - the NT service controller has had support for shared services built-in since NT 3.1.

You can see shared services in action on any Windows machine.  If you have the SDK tool tlist.exe, you can run "tlist -s" and see the services running in each process.  On my machine, tlist shows (among other things):

1280 svchost.exe Svcs: AudioSrv,BITS,CryptSvc,Dhcp,dmserver,ERSvc,EventSystem,helpsvc,lanmanserver,lanmanworkstation,Netman,Nla,RasMan,Schedule,seclogon,SENS,SharedAccess,ShellHWDetection,srservice,TapiSrv,Themes,W32Time,winmgmt,wuauserv,WZCSVC

In this example, svchost.exe is running 26 different services.  Without shared services, each of these would be a separate process, thus consuming a huge chunk of resources.  In fact, that's the entire purpose of svchost - it provides a common hosting framework for Windows to use for shared services.  svchost.exe is an internal-only facility, but the functionality on which it is based is available for everyone.  To specify a service as being a shared service, all you need to do is to specify the dwServiceType as SERVICE_WIN32_SHARE_PROCESS when you call CreateService and the service controller will do "the right thing".

You need to do a smidge more work - if you're a shared service, then when you call StartServiceCtrlDispatcher, you need to specify all the services that will be running in your process, but that's about it. 

When you ask the service controller to start a share process service, the service controller first looks to see if that service is started.  If it's not, it looks at the running service control dispatchers to see if there's a dispatcher running for the new service.  If there is a dispatcher running for the service, then it uses that dispatcher to start the new service, if there isn't, it launches the process that was specified in the lpBinaryPathName parameter to CreateService.

The bottom line is that if you're responsible for more than one service (or your product contains more than one service), you should seriously consider combining them into a single process - it's not that much extra effort, and the benefits can be huge.

Comments

  • Anonymous
    September 09, 2005
    The built-in Windows XP and 2003 utility tasklist.exe can also show the services hosted in a process.

    "tasklist /svc" will show similar information to "tlist -s".
  • Anonymous
    September 09, 2005
    I've written a service hosting framework for our company that allows running multiple services in one process via one DLL per each service and we did it for the exact reasons you gave: system resources. But Larry: If shared process services are such a darn good thing, why then doesn't MS document the svchost.exe interfaces so ISVs could use it as well?
  • Anonymous
    September 09, 2005
    The comment has been removed
  • Anonymous
    September 09, 2005
    Stefan, that's a good question. The answer is that people would start putting 3rd party code in the same process as the built-in services.


    And that in turn turns into a reliability nightmare - when an instance of svchost.exe goes down, it takes out all the services within the svchost, which can totally tank a system.

  • Anonymous
    September 09, 2005
    The comment has been removed
  • Anonymous
    September 09, 2005
    After reading the MSDN page of CreateService, may I ask one question?

    The article states that the "SERVICE_INTERACTIVE_PROCESS" attribute requires LocalSystem security context. But is it possible to create serivce that can be interactive with desktop, yet just run in normal user account?

    For example, if I'm writing a FTP server, I think a normal user account for that ftproot folder could be enough.
  • Anonymous
    September 09, 2005
    Cheong, do a google search for "shatter attack" before you consider deploying a service with the SERVICE_INTERACTIVE_PROCESS flag.

    Also note that the SERVICE_INTERACTIVE_PROCESS flag doesn't work correctly in FUS scenarios (the UI only pops up on session 0).

    For Vista, your service is highly unlikely to work correctly do to some significant security work that's been done to mitigate shatter attacks. You don't want to EVER pop UI up from a service.
  • Anonymous
    September 10, 2005
    The comment has been removed
  • Anonymous
    September 10, 2005
    >>You don't want to EVER pop UI up from a service. <<

    What about launching another "normal" program from a service, perhaps using CreateProcessAsUser? Does the same rule apply? Any implications from Vista on that?
  • Anonymous
    September 10, 2005
    CPAU will continue to work, it doesn't have the security problems that interactive services have.
  • Anonymous
    September 11, 2005
    The comment has been removed
  • Anonymous
    September 12, 2005
    The last time I wrote, I talked about shared services. One of the problems of working with shared services...
  • Anonymous
    August 06, 2007
    PingBack from http://www.nynaeve.net/?p=154