Hosting COM DLLs in a Surrogate Process

 < Free Open Study > 



Before we examine the set of COM marshaling options, let's perform a little experiment to illustrate COM's location transparency and run our existing CarInProcServer.dll server in its own surrogate process. Follow along if you wish; just make sure you have completed the CarInProcServer lab from Chapter 4.

Since the release of NT SP2, we have had the ability to host legacy in-proc COM servers within an EXE shell, using a utility named dllhost.exe. This application provides the necessary hooks to allow existing COM DLLs to behave as a local (or remote) server by wrapping them into a surrogate process. There are a number of reasons a person may wish to do this:

  • You have a great set of coclasses dwelling in an existing DLL and you would rather not have to rewrite the component housing code to access them remotely.

  • You want to isolate the DLL from the client process to avoid hard crashes (recall that if a bug is hit in your DLL, the client's process goes down with it as well).

  • You wish to configure security options for the legacy DLL (by their nature, DLL servers always have the security settings of the client host).

The dllhost.exe utility will load your COM-based DLLs and expose its functionality from a distinct process on your behalf, leaving your server's code base unaltered. As you can probably guess, this requires altering the system registry to instruct SCM to load the in-process server into the dllhost.exe shell, rather than the client's process. This feat requires an understanding of yet another incarnation of the GUID-the AppID.

Understanding Application Identifiers (AppIDs)

In order to allow client access to distant COM servers (local or remote), we find yet another use for the omnipresent GUID, termed an AppID or application identifier. An AppID is assigned to the entire COM server and is used to describe security and activation settings for the application at large. Given this, you can correctly assume that a single AppID collectively identifies all the coclasses in a given executable. For convenience, a server's AppID can be assigned to the same GUID as a given CLSID contained in the server. The reasoning behind this is simple: Many legacy COM servers did not register an AppID as part of their installation process. Because AppIDs and CLSIDs are used under different circumstances, we can get away with a bit of creative GUID swapping.

Figure 5-8 illustrates the LocalShapes.exe server containing four COM objects, each of which has been assigned a unique CLSID. Now, assume for the sake of illustration that CoDot has a CLSID of {5D432C50-F507-11d2-B8E0-0020781238D4}. Next, assume the server itself is identified by a single AppID, which happens to be the same GUID as CoDot's CLSID:

click to expand
Figure 5-8: AppIDs identify the entire COM application.

AppID Registry Settings: HKEY_CLASSES_ROOT\AppID

Now that we can collectively identify all coclasses held within a component home using an AppID, we may associate a number of attributes to the binary. In general, the AppID is used to associate activation and security attributes to the objects it contains. As you introduce the idea of remote access to your objects, security is injected into the picture. You do not need to be a full-fledged system administrator to configure COM security options, but it will be helpful to understand the basics. The system registry holds such information for every COM application under the AppID key of HKEY_CLASSES_ROOT:

click to expand
Figure 5-9: HKCR\AppID holds all registered COM applications.

A given entry under HKCR\AppID can specify several named values which control how the COM application should be used. Here are some of the more common settings found under a single AppID listing:

AppID Value

Meaning in Life

AccessPermission

Sets up the access control list (ACL) of users that can access the server.

AuthenticationLevel

Sets the authentication level.

DllSurrogate

Names the correct surrogate to host a DLL. If blank, the default dllhost.exe will be used.

LaunchPermissions

Sets up the ACL of users that can launch this application.

RemoteServerName

Identifies the name of a remote server machine.

For this DLL surrogate experiment, we are only interested with the DllSurrogate value. Assume we have written a REG file to enter an AppID for CoCar, which has been merged into the registry. Notice that the AppID listing has an empty DllSurrogate value; this tells SCM to use the default dllhost.exe:

click to expand
Figure 5-10: The DllSurrogate value under an AppID listing specifies who should host legacy in-proc servers.

Beyond adding a listing for HKCR\AppID, you should also update your REG file to modify the HKCR\CLSID entry for each coclass in the COM application to specify the correct AppID. Recall that each coclass in the server points to the same AppID, thus each coclass in a given server will have an AppID value with the same GUID:

click to expand
Figure 5-11: Each CLSID in a COM application maps to the same AppID.

With the addition of two new registry entries (which we have yet to enter) we are now able to load a DLL into a separate process using dllhost.exe. To get these entries into the system registry, we can simply run the dcomcnfg.exe utility and get an AppID for free (no pain). This approach will generate an AppID for the server based on an existing CLSID. We will introduce dcomcnfg.exe later in this chapter.

Using other approaches, we could update our REG files by hand (some pain) or even enter the information programmatically using DllRegisterServer() (greater pain). We do, however, have another alternative for entering AppID information into the registry: Configure the AppID of a server using the OLE/COM Object Viewer and call it a day.

Configuring a Surrogate with the OLE/COM Object Viewer

If you launch the OLE/COM Object Viewer utility and locate your existing DLL server from the All Object category, you may configure it to run under the system surrogate. Doing so will merge the necessary AppID entries automatically. To do so, select the Use Surrogate Process option from the Implementation tab:

click to expand
Figure 5-12: Configuring a DLL to use dllhost.exe

By selecting this option, the OLE/COM Object Viewer creates an HKCR\AppID listing for the DLL (using the first CLSID defined in the type library) and modifies each CLSID to point to the newly assigned AppID. To verify the OLE/COM viewer-generated entries, switch back to the Registry tab of the viewer and examine the registry entries (Figure 5-13):

click to expand
Figure 5-13: The generated AppID entries.

Note that the OLE/COM Object Viewer has modified your existing CLSID value with the AppID and created a new AppID listing for the server, using the creative GUID swapping approach mentioned earlier in this chapter. This is all you need to do in order to inform SCM to load your legacy DLL into the dllhost.exe surrogate process.

Programming a Surrogate Client

We do have one minor adjustment to make in the C++ client-side code. Open an existing C++ client project workspace, and modify your CLSCTX flag to specify a local, rather than an in-process, server:

// By asking for a LOCAL server instance of this DLL, // we run the server within a surrogate process. hr = CoGetClassObject(CLSID_CoCar, CLSCTX_LOCAL_SERVER,                     NULL, IID_IClassFactory, (void**)&pCF); // Create the CoCar. Access interfaces. Release interfaces.

We are now telling SCM to load our DLL into a surrogate. First SCM consults HKCR\CLSID for a given AppID entry. If such an entry exists, SCM then checks HKCR\AppID and discovers that it should use the default surrogate. Recompile and run the client. If you examine the NT Task Manager (CTRL + SHIFT + ESC) you will see your CoCarClient program is loaded as well as an instance of dllhost.exe:

So there you have it! We have just launched a DLL COM server in its own protected process. Remember the promise of location transparency: Clients can activate objects at various locations without reworking their code base. So did I lie? After all, we did need to change the CLSCTX flag. OK, you've got me. At times we will modify an occasional flag or send in an extra parameter to some COM library function to achieve location transparency. But think about the benefits of changing a flag versus writing DDE or sockets code! Later in this chapter we will use the dcomcnfg.exe utility to redirect SCM to access a remote server without any code adjustments at all (see, I'm honest).

click to expand
Figure 5-14: A running surrogate process and launching client.



 < Free Open Study > 



Developer's Workshop to COM and ATL 3.0
Developers Workshop to COM and ATL 3.0
ISBN: 1556227043
EAN: 2147483647
Year: 2000
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net