FILE: HELSVC.EXE Implements an OLE Server in a Service

ID: Q156673

The information in this article applies to:

SUMMARY

The HELSVC sample is a simple OLE Automation server implemented in a service called "Hello OLE Server Service."

The following file is available for download from the Microsoft Software Library:

 ~ Helsvc.exe (size: 39742 bytes) 

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from
               Online Services

MORE INFORMATION

This server implements one application object with a dual interface. It also registers the application object in the RunningObjectTable so that any client can access it. The sample includes a Visual Basic client that can control the server. The sample does not use any framework such as MFC, ATL, etc.

Implementation Notes

NT 4.0 removes the limitations of using OLE in services that are described in the following article in the Microsoft Knowledge Base:

   ARTICLE_ID: Q149571
   TITLE     : Using OLE in Services in Windows NT 3.51

For an overview of implementing an OLE server in a service in NT 4.0 and later versions, read the following topics in the Win32 SDK Online documentation:

   "LocalService"
   "Installing as a Win32 Service or User Account"

To find these topics, query using the LocalService keyword.

When the service starts, it registers a multiple-use class factory. It then registers an object in the Running Object Table using ROTFLAGS_ALLOWANYCLIENT, which allows clients in any security context to bind to the object using IRunningObjectTable::GetObject or GetActiveObject (if the appropriate permissions are specified in the server's access permissions using the DCOMCNFG tool).

If ROTFLAGS_ALLOWANYCLIENT is not used in the ROT registration, only clients in the same security context as the server will be able to bind to it. RegisterActiveObject currently does not support ROTFLAGS_ALLOWANYCLIENT, so the sample provides a new function, MyRegisterActiveObject, which supports this flag.

IRunningObjectTable::Register supports this flag. Registration using this flag requires a registry entry similar to the following to prevent a CO_E_WRONG_SERVER_IDENTITY error:

   [HKEY_CLASSES_ROOT\APPID\helloservice.exe]
   "APPID"="{0bf52b15-8cab-11cf-8572-00aa00c006cf}"

Because of a bug in NT 4.0, Build 1381, registration using ROTFLAGS_ALLOWCLIENT is always weak, even if ROTFLAGS_REGISTRATIONKEEPSALIVE is also specified. As a consequence, the ROT will release its reference on the object when the last client releases its reference and clients that are launched later will not be able to bind to the running object. A workaround is for the server to place a strong lock on the registered object using CoLockObjectExternal while it is in the ROT.

NOTE: The bug mentioned in the paragraph above has been fixed in NT 4.0, Service Pack 2.

See the .reg file for information of the registry entries used by the service.

Many services are debugged by running them as console applications in the interactive user's identity. For example, this sample service can be debugged by running it as follows:

   helloservice -debug

Because the service is already registered to run in a different identity (configurable by the Services control panel applet), OLE will fail CoRegisterClassObject and IRunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) by returning CO_E_WRONG_SERVER_IDENTITY to enforce security and to prevent malicious servers from spoofing the server. To debug by running in the interactive user's identity, make the following changes in the server's registry entries to prevent these failures:

1. To prevent CoRegisterClassObject failure, remove the following named

   value:

   [HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
   LocalService"="HelloOleServerService"

2. To prevent IRunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT)
   failure, do the following:

   Remove the following named value:

   [HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
   "LocalService"="HelloOleServerService"

   and then add the following named value:

   [HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
   "RunAs"="Interactive User"

   Make sure that you restore the modified registry entries after
   debugging.

To Compile

NT 4.0 or later is required. To compile, type:

   nmake

To compile a version without debug information and without message boxes that are displayed to indicate progress or failure, type:

   nmake DEBUG=0

To Run

1. Change hello.reg to provide the full path of helloservice.tlb.

2. Register hello.reg in the registration database by double-clicking it.

3. Type helloservice -install to install the service. (NOTE: This will not

   run the service.)

4. Add INTERACTIVE to the DefaultAccessPermissions using the DCOMCNFG.EXE
   tool in the NT system32 directory. Make sure that INTERACTIVE is
   included in the DefaultLaunchPermissions. This allows the Visual Basic
   client in the interactive user's security context to access the service.

5. Use the Visual Basic file, vb.vbp, to control the object. Press the
   CoCreateInstance button to launch the service if required, and to create
   the object. Use the GetObject button to bind to a running object.
   GetObject can be used only if the service is already running. Use the
   GetMessage and SetMessage buttons to access the HelloMessage property,
   the SayHello button to invoke the SayHello method, and the CloseService
   button to invoke the Quit method to shut down the service. The service
   can also be configured using the Services control panel applet to run
   automatically when the system starts. It will be listed as ?Hello OLE
   Server Service? in the Services applet.

6. helloservice -remove can be used to uninstall the service.

Files

SERVICE.C & SERVICE.H have the code to create a service and are copied from the SERVICE sample in the WIn32 SDK. (See the comments in service.h for information on command line arguments accepted by the service.)

MAIN.CPP and HELLO.CPP implement the automation object.

HELLOCF.CPP implements the class factory.

HELLO.ODL is the object description language that describes the property and methods that HELLO exposes.

TLB.H is the header file generated by MIDL.

MAKEFILE is the Makefile for project.

HELLO.REG is the Registry information.

Additional query words: COM DCOM

Keywords          : kbsample LeTwoAto LeTwoCom 
Version           : 4.0
Platform          : NT WINDOWS

Last Reviewed: May 23, 1997