In-process servers
can never run without a parent process. Period. However, since
the release of Windows NT 4.0 Service Pack 2, in-process servers
can be remoted as long as a surrogate is available to provide the
needed address space. One such surrogate is the file dllhost.exe
that can be remoted and then instructed to load any in-process
component, providing the component with a surrogate parent
process and security context. But how do you set security
permissions, identity, client's authentication level, and the set
of protocols and endpoints for use by clients for such an in-process
component? One easy way of setting this up is to use DCOMCNFG
utility. However, by default DCOMCNFG utility won't list
components housed in in-process servers. It will list only
component executables registered on the system.
Run OLEViewer and
select any in-process DLL server object. Select the
Implementation tab, and select the Use Surrogate Process check
box. Provide a path to custom surrogate or the default <\winnt\system32\dllhost.exe>
surrogate. Select the Registry tab (this will add the
DllSurrogate named value under the AppID key).
Now run the
DCOMCNFG utility. The in-process DLL server object will show up
in the list of applications. Basically, we convinced the DCOMCNFG
utility that the in-process DLL server object is no longer alone
and that it has a parent process where it will be housed when it
is remoted.
Example project:
1. Choose ATL COM AppWizard and DLLSurr as name of the project. Be sure to choose
the Server type as Dynamic Link Library (DLL).
2. Add a new ATL object with a short name ATest.
Build and register
the server. Select the component ATest in OLEViewer (Object
Classes->All Objects->ATest). Select the Implementation tab,
and select the Use Surrogate Process check box. Provide a path to
the default surrogate as <\winnt\system32\dllhost.exe>.
Select the Registry tab (this will add the DllSurrogate named
value under the AppID key). Now run DCOMCNFG and select ATest.
Choose Properties, Security, and edit Use custom access
permissions and select an NT user name (for demo purpose, you may
want to choose your NT user name). Select Deny access from the
Type of Access combo box. Click OK all the way to close the
DCOMCNFG utility.
Client code to
launch the server:
#include "stdafx.h"
#include <comdef.h>
#import "..\DLLSurr.tlb" no_namespace named_guids
{
try
{
IATestPtr ptrTest = NULL;
HRESULT hr = ptrTest.CreateInstance(CLSID_ATest,
NULL, CLSCTX_LOCAL_SERVER );
if(FAILED(hr))
{
TRACE("Failed to create ATest component.\n");
_com_issue_error(hr);
}
}
catch(_com_error& e)
{
TRACE(e.ErrorMessage() + _bstr_t("\n"));
if(e.ErrorInfo())
TRACE(e.Description() + "\n");
}
}
Alternatively, you
can also test the server in OLEViewer. From the menu, choose
Object...CoCreateInstance flags, select CLSCTX_LOCAL_SERVER and
deselect all other items. Right click on the component name,
select Create Instance On..., and enter your machine name.
Conclusion:
This article
discussed DLL surrogates briefly and how legacy in-process
components can participate in a distributed environment.
It is interesting
to note that Microsoft SQL Server extended procedures (which are
nothing but DLLs) runs in SQL Server address space and that a
badly behaved extended stored procedure could crash SQL Server.
References:
1. Inside
Distributed COM, Guy Eddon and Henry Eddon, Microsoft Press 1998.
2. MSDN Library April 1999.
System Requirements:
Microsoft Visual C++ 6.0 w/ sp3, NT 4.0 w/ sp4.