| DCOM Explained by Rosemary Rock-Evans Digital Press ISBN: 1555582168 Pub Date: 09/01/98

Previous | Table of Contents | Next

A client can create an instance of a server in one of two ways. It can call the COM function CoCreateInstance, which creates an object with the given Class ID, or it can use a special COM class called the Class Factory, which is responsible for creating instances of the server. If the Class Factory is used, the client calls CoGetClassObject which obtains the interface pointer to the class factory object (IClassFactory) then uses this interface to ask the class factory to manufacture an object on its behalf. In fact, the more direct CoCreateInstance function internally calls the CoGetClassObject anyway. It is at this point that the Vtable is populated with the pointers to the relevant objects and functions.

Once the Class factory has created the instance, the Class Table is updated to show that a new instance has been created on the machine. The Class Table thus provides a list of the Class IDs (identifiers of the components), together with Class Factory pointers to the currently running COM servers on that machine.

So how does DCOM find components at runtime? The DCOM component responsible for handling this is called the Service Control Manager (SCM).

When the client wants to find a component it uses the Class Identifier (CLSID)—the unique identifier of the component. The COM library contacts the local SCM and requests that the appropriate server be located.

The SCM then looks up its local Class Table to see if a server is already running on that host with that ID. If a server is already running, the client is simply given the pointer to the running server.

If no such server is running, the SCM then looks up the local Registry to see if the server can be found on that host. As we saw, COM servers can be DLLs or EXEs on the local machine or could be remotely located. If they are remotely located, they will be described as a “proxy” entry in the Registry.

If the server is an “in-process” DLL, the SCM returns the path name of the DLL and the COM library then uses the Class Factory to create an instance of the DLL. Once the Class factory has created the instance, the Class Table is updated to show that a new instance has been created on the machine.

If the server is not “in-process”—an EXE—the SCM uses the Class factory to create an instance of the EXE. Again, once the Class factory has created the instance, the Class Table is updated to show that a new instance has been created on the machine.

Where the server is remote, in other words, a proxy object exists for the component, the SCM contacts the SCMs running on all the machines to which it is connected. These SCMs search their host’s Class Table and Registry in the same way that the local SCM operated. This searching process continues across machines until the component is either found, or the SCMs return with a message that the component cannot be found. At the moment, the first SCM to find the server is the one that is then used to invoke the component, but clearly there is the potential here for more sophisticated load-balancing algorithms to be employed if Microsoft wanted to.

Where the component can be found, the remote SCM establishes a connection with its Class Factory. It passes the pointer to this remote Class Factory back to the local SCM, which invokes (via an RPC) the remote Class Factory. The remote Class Factory then creates an instance of the remote component and updates the remote Class Table. The local SCM, meanwhile, uses the local Class Factory to create an instance of the proxy object. The proxy object is given a pointer to the remote component and communication can proceed—proxy and remote component communicate rather than client and remote component.

So how does Microsoft’s current Registry stand up in our assessment of the design goals of available, secure, reliable, and high performance Directory services? Although some features are built into the Directory services that help in the registration of servers and components, the security information has to be set up manually on each machine, and the information on servers and components has to be kept up-to-date manually once it has been registered. There is thus a fairly high administrative overhead involved in maintaining the Registry information, and as a consequence, errors may creep in and reliability suffer.

Furthermore, although security checks can be applied to the Registry to prevent unauthorized access, the fact that these have to be set up on each node for each Registry is tedious, prone to error, and prone to abuse. As we all know, whenever anything starts to get tedious to perform, we tend not to do it, meaning that our administrator could well decide not to bother to set up all the restrictions on access to save himself some effort.

Availability should not be a problem. Each node has the information it needs to access components, and as such the applications will not be reliant on a single node.

But performance may not be so hot. Despite the fact that the file is a local one, each Registry only contains the addresses of the local processes. Where remote processes are to be accessed, the address has to be found by searching the Registries of other nodes—a process that both increases network traffic (and thus leads to performance degradation) and that itself incurs a performance overhead. A further overhead is incurred because accesses are disk not memory based. Overall, then, not an ideal solution—available maybe but not high performance, secure, and not giving the sort of full reliability we would want.

Previous | Table of Contents | Next