Click here to Skip to main content
15,880,503 members
Articles / Programming Languages / C++
Article

The COM Macro-Architecture Topology

Rate me:
Please Sign up or sign in to vote.
4.97/5 (49 votes)
24 Jul 200141 min read 207.2K   2.6K   156   25
An article about COM Architecture, and deployment of COM Clients and COM Servers

Overview

Shortcuts for the main chapters in this article:

  1. The COM Macro-Architecture Topology
  2. Some Theory
  3. Some Practice
  4. Conclusion
  5. Bibliography

Purpose

First, I have to define what does "COM Macro-Architecture" mean.
By "Macro" I do not mean "pre-processor" or "script command". No, by "Macro" I am referring to a high level of observation, also used in financial terminology: "Macro economy" and "Micro economy" refer to the global economy and the country economy respectively, where the country being the delimiter.

Because "COM Architecture" is so huge, I had to split it into two pieces. I defined the unit of deployment (from a technical point of view we call it an Executable file or DLL file) as the delimiter of the split. Therefore we have the two following groups:

  • Macro-Architecture: as a unit of deployment, we will talk about Client applications and COM Servers.
  • Micro-Architecture: inside a unit of deployment we will talk about running process, COM apartment, thread concurrency and synchronisation, memory sharing.
I also used the Term "Topology". By definition, in computer science, Topology is likely to be the arrangement in which the nodes of a LAN are connected to each other. Here I wanted to point out how COM applications (Client & Server) are connected to each other.

This series of articles is just about "Macro-Architecture".

You will learn how to make COM Server and Client Application. You will see how to deploy and install them (on local machine and remote machine).

This series of articles want to be more practical than theoretical. However, you can find many good books and articles that go deeper into details in the bibliography section.

The series is called "COM Macro-Architecture Topology" and this is the main article. It will give you:
  • an overview of the relationships between Client applications and COM Servers.
  • all the instructions you need to build your system (Client application and COM Server).
  • all the process you need to install, configure and uninstall your system.
Here are the links to other articles:

Who should read this article ?

I have made the assumption that the reader:
  • should know the C++ language as all code samples are written in C++.
  • should have a basic knowledge of COM, such as Client/Server model, COM Interface, Interface marshalling (Proxy/Stub).
  • should have a basic knowledge of Windows NT/2000 security aspect.
  • ought to be interested more in COM architecture than in development aspect.
For this reason, I classified this article as an Intermediate level.

However, beginners can still read this series and used the practical section like a tutorial. From my own experience, I have started to learn COM by practice and then books helped me to put it down and understand the theory.

I do remind to COM developers who are reading this series that the main subject is COM architecture. I am not going to explain or compare the different COM helper tools, C++ libraries (e.g. ATL) or even C++ design aspects (e.g. smart pointers or wrapper classes) available to develop COM Client applications or Servers.

Requirements

All the code in these samples have been written in C++, using Visual C++ 6.0 (sp4) under Windows 2000.
They also use the Active-X Template Library (ATL).

Downloading

  • Demo files - You will find the necessary tools (Executables, DLLs, Registry configuration and Batch files) to try the different cases. Download demo project - 127 KB
  • Source files - You will find all the source code for making the 3 different COM Servers (Executable, 2DLLs and 1DLL) and the Client Application. Download source - 70 KB
  • The project's structure on my computer is like that:

    Image 1

    All the Executable and DLL files are output in the \Implementation\Bin directory.

    Deployment considerations

    Be careful when deploying the components described in this article.
    Take into account these points:
    • In order to install them you need to have the Administrator rights (Client and Server machine).
    • Allow the Server to use the identity of the Interactive user or a user's account with the Interactive rights (so dialog boxes could be showed).
    • When calling the Server remotely, be sure that the User associated to your Server is locally logged-on onto the server machine as the Interactive user, so that the Dialog boxes can appear.
    • Using the "Terminal Services Client" does not give you the Interactive user account, although your account has the Interactive rights (For further information read [Bi6]).
      The Interactive User is the user currently logged-on the Server machine.

    Limitations

    Although COM is available in many operating systems, I have just considered the Windows implementation. This means that some aspects of COM could have different restrictions based on their operating system implementation (e.g. the Security, the COM information storage, etc.) .

    Some Theory

    COM & Infrastructure

    Before moving on to practice and building COM Servers you have to understand how the information you will provide to COM will be used to bind a Client Application to a COM Server.
    Here, I will just talk about 2 COM Infrastructure points:
    Look at the article "COM IDs & Registry keys in a nutshell" for information on the registry and COM vocabulary.

    The Activation mechanism

    The activation mechanism is the process used by COM to locate, load and launch a COM Server (DLL or Executable). The result, if all goes to plan, will be to instantiate a COM object or COM class object. As you can understand, Activation is a dynamic action and it occurs at runtime.

    COM proposed 3 activation models to bring COM objects into memory (see [Bi1], chapter 5 and [Bi11], chapter 3):
    • Clients can ask COM to bind to the class object or class factory of a given class (using CoGetClassObject()).

    • Clients can ask COM to create new instances of a class based on a CLSID (using CoCreateInstance/Ex()).

    • Clients can ask COM to bring a persistent object to life based on the persistent state of the object (using CoGetInstanceFromFile()).
    You can also define a custom way to activate your COM object based on one of these 3 basic activation models.

    All these activation models use the services of the COM Service Control Manager (SCM). The COM SCM is not the same as the Windows NT or Windows 2000 SCM (used to start logon-independent processes known as Windows Services). Every host that supports COM has a COM SCM. His role is to activate the COM objects on a particular machine (locally or remotely).

    Static/Dynamic aspect of a COM server

    At this stage you should look at your COM Server from its Static and Dynamic aspect:
    • The static aspect of a COM Server is its package: it can be built as an Executable or as a Dynamic Link Library (DLL) file.

    • The dynamic aspect of a COM Server relates to the Server categories defined by COM at runtime: In-process and Out-of-process.
    The figure below expresses that idea:

    Image 2

    From a location point of view, COM Servers that reside on the client machine are called "local servers" and the ones that reside on a remote machine are called "remote servers".
    This figure points out 3 results:
    • A COM Server packaged as an Executable file will never run as In-process server. It will always run as an Out-of-process server (locally or remotely).

    • A COM Server packaged as a DLL file will run either as an In-process or as an Out-of-process server (locally or remotely).
      Notice that a DLL COM Server always needs a process to run into. As In-process server it will be loaded into the Client process space and as Out-of-process it should be loaded into a Surrogate process space.

    • Only COM Servers use as Out-of-process servers can be called on remote machine.

    Every route leads to a COM Server...

    When deploying and installing your COM Server you must give some information to COM, such as where your component will be (physically), which COM class object(s) your component provides and so on.
    All these information will allow COM library to answer to Client's requests about launching and creating COM Server's objects.
    Under Windows NT 4.0, COM stores these information on its local configuration database also called the Registry. Under Windows 2000 (or v5.0), COM uses a distributed secured database, i.e. the Active Directory.

    Generally, all COM servers should support self-registration. This means that:
    • the Executable COM Server must check the command line for these switches:
      • /RegServer or -RegServer: will insert keys in the registry and register its class factories by calling CoRegisterClassObject().
      • /UnregServer or -UnregServer: will suppress keys in the registry and unregister its class factories by calling CoRevokeClassObject().

      All these 4 switches are case insensitive.

    • the DLL COM Server must export these 2 functions:
      • DllRegisterServer(): will insert keys in the registry.
      • DllUnregisterServer(): will suppress keys in the registry.

      To register a DLL COM Server, you can use the utility REGSVR32.EXE in the Win32 SDK. This application will call these 2 exported functions to register or unregister the DLL COM server.
    To illustrate the work done by COM in order to bind the Client application and the COM Server together, let assume the client code is like this:
    ISampleClass   *psc = NULL;
    HRESULT        hr = CoGetClassObject(GUID1, CLSTX_ALL,
                                         0, IID_IClassFactory, (void**)&psc);
    
    • CoGetClassObject() provides us an IClassFactory interface pointer on a class object (i.e. a class factory) associated with the specified class ID: GUID1.
    • CoGetClassObject() takes as its second parameter a bitmask value that specifies the desired context the client wants to activate the COM Server: In-process, Out-of-process, locally or remotely.
      CLSTX_ALL is a pre-processor macro defined like this:
      #define CLSCTX_ALL   (CLSCTX_INPROC_SERVER| \
                            CLSCTX_INPROC_HANDLER| \
                            CLSCTX_LOCAL_SERVER| \
                            CLSCTX_REMOTE_SERVER)
      
      These values are defined in the standard enumeration of CLSCTX as:
      typedef enum tagCLSCTX
         { CLSCTX_INPROC_SERVER  = 0x1,
           CLSCTX_INPROC_HANDLER = 0x2,
           CLSCTX_LOCAL_SERVER   = 0x4,
           CLSCTX_REMOTE_SERVER  = 0x10,
          ...
         }CLSCTX;
      
      You can find as well 2 other shortcut macros in the SDK header file (objbase.h):
      #define CLSCTX_INPROC   (CLSCTX_INPROC_SERVER|\
                               CLSCTX_INPROC_HANDLER)
      
      #define CLSCTX_SERVER   (CLSCTX_INPROC_SERVER|\
                               CLSCTX_LOCAL_SERVER|\
                               CLSCTX_REMOTE_SERVER)
      

      It is worth to know that environments such as Visual Basic and Visual Java always use CLSTX_ALL, indicating that any available implementation will be good ([Bi11], chapter 3).

    Here is the Activation chain used by COM in order to locate, load and launch the COM Server and return a interface pointer to the client (look at [Bi1], chapter 6, [Bi3], chapter 5 and [Bi11], chapter 6):

    Image 3

    In the figure above, a yellow rectangle indicates a registry key or subkey under [HKEY_CLASSES_ROOT\CLSID] and a green rectangle indicates one under [HKEY_CLASSES_ROOT\AppID].
    For simplicity, I have not taken into account the security aspect. So, let see what happens:
    1. The client calls CoGetClassObject() which gives control to the COM Service Control Manager (SCM). Because the third parameter of CoGetClassObject() is not set with a host name, the SCM will first look in the local registry for the key:
      [HKCR\CLSID\{GUID1}]
      
      • Notice that in Windows 2000, the SCM will look first under the key [HKEY_CURRENT_USER] and then [HKEY_CLASSES_ROOT] (aliased as [HKCR]).
      • If the key does not exist locally, the SCM will then try to find information on the Windows 2000 Active Directory and install the component locally.
      • If the key is not available, the call will fail with the HRESULT code REGDB_E_CLASSNOTREG: CLSID is not properly registered.
        This code error might also indicate that the value you specified in the second parameter of CoGetClassObject() is not in the registry.
    COM SCM is looking for an In-process
    1. At this stage, the class ID GUID1 is available the SCM will then look for the subkey:
      [HKCR\CLSID\{GUID1}\InprocServer32]
      @="C:\myserver.dll"
      
      If the key is present, it should contain a valid path with a DLL file name. COM will load the DLL into the client process space, call DllGetClassObject() to get the IClassFactory interface pointer and return it to the client.
    2. If this key is not present, then the SCM will look for the subkey:
      [HKCR\CLSID\{GUID1}\InprocHandler32]
      @="C:\myserver.dll"
      
      Again, if the key is present, it should contain a valid path with a DLL file name. COM will load the DLL into the client process space, call DllGetClassObject() to get the IClassFactory interface pointer and return it to the client.
    If neither In-process subkey is available, the SCM will look for an Out-of-process activation. After this stage, the client will always get back an interface pointer on a proxy.

    COM SCM is looking for an Out-of-process locally
    1. The SCM is now looking on its cache to see whether the requested COM class object (class factory) is currently registered. If so, the SCM will return a marshalled interface pointer to the client.
      The COM server will register its class factories with the SCM using the helper function CoRegisterClassObject().

      If the server uses the flag REGCLS_SINGLEUSE, then the SCM will not put the class factory as public level and so will not be available for subsequent activation request. In fact, for subsequent activation calls, the SCM will start a new process using the step #5 and followings.
    2. If the class factory is not registered in its cache (or has been removed from the public view of the SCM), this means that there is not any Out-of-process currently running and providing this class factory as public level.
      Under Windows NT 4.0 or 2000, COM supports 3 process models for creating servers:
      • NT Services.
      • Normal processes.
      • Surrogate processes. They are used to host DLL servers:
        • locally it provides fault isolation and security context.
        • remotely it provides remote activation and distributed architecture.

      Whatever the process model is used to create a server process, the server will have 120 seconds (or 30 seconds under Windows NT service Pack 2 or earlier) to register the requested class factory. If the server process fails to do so in time, the SCM will fail the client's activation request ([Bi11], chapter 6).

      When creating a server process, the SCM will first look for a local service. It will try to get an AppID:
      • by looking under the named value:
        [HKCR\CLSID\{GUID1}]
        AppID={GUID2}
        
        If it finds a value, e.g. GUID2, it will look for the named value under the AppID root:
        [HKCR\AppID\{GUID2}]
        LocalService="MyService"
        
      • If it can not find the AppID value GUID2 under the key [HKCR\CLSID\{GUID1}] it takes the class ID value itself GUID1 as an AppID and look under the AppID root:
        [HKCR\AppID\{GUID1}]
        LocalService="MyService"
        
      In the figure above, GUID1 and GUID2 could have the same value, but it is preferable if it is not the case.

      GUID1 represents the class ID of the COM class factory whilst GUID2 represents the COM Application ID used by the COM class factory.

      If a value exists, the (COM) SCM will ask to the Windows SCM to start the service MyService. The service will register its class factories with the SCM using the helper function CoRegisterClassObject(). Now, COM can query for the class factory GUID1 and ask it to return a pointer for the IClassFactory interface, which is to be marshalled back to the client.

    3. If the SCM can not find this named value, then it will try to start a normal process, so it will look for the subkey:
      [HKCR\CLSID\{GUID1}\LocalServer32]
      @="C:\myserver.exe"
      
      If a value exists, the SCM will try to launch the local server by using API functions such as CreateProcess() or CreateProcessAsUser().
    After this step, the SCM could no start neither a Local service nor a Local Server, so it would try to create an Out-of-process remotely.

    COM SCM is looking for an Out-of-process remotely
    1. If the SCM can not find a local server, it will look for the named value:
      [HKCR\AppID\{GUID2}]
      RemoteServerName="\\MyRemoteComputer"
      
      If this value is available, the activation request will be forwarded to the SCM on the designated host machine. It is worth noting that although the client application will only use the CLSCTX_LOCAL_SERVER flag when querying the activation, the request will be forwarded to the remote machine if no local servers are registered.

      The remote SCM will, following steps #4 through #6 (i.e. steps #7.c through #7.e), try to find and launch a remote server that supports the requested class factory. If it will succeed it will return a pointer for the IClassFactory interface, which is to be marshalled back to the client machine.

      1. If neither a Local service nor a Local Server could be launched, then the remote SCM will check for the named value on the remote machine:
        [HKCR\AppID\{GUID2}]
        DllSurrogate="C:\MySurrogate.exe"
        
        If this named value exists, the remote SCM will start the Surrogate process (e.g. MYSURROGATE.EXE) and ask it to load the DLL COM server designated under the subkey:
        [HKCR\CLSID\{GUID1}\InprocServer32]
        @="C:\myserver.dll"
        
        then it will ask it to return a pointer for the IClassFactory interface, which is to be marshalled back to the client machine.

        If the named value DllSurrogate is empty:
        [HKCR\AppID\{GUID2}]
        DllSurrogate=""
        
        then the remote SCM will start the default Surrogate process (called DLLHOST.EXE) and ask it to load the DLL COM server.
    Maybe, you are now wondering "Why the SCM will not try to create a Surrogate process after step #6 ?"
    As I wrote before, there are three process models. Until step #6, the SCM have tried to create the first two: NT service and normal process. The last process model is Surrogate process and it can be used locally to load and activate DLL COM Server as Out-of-process. Nevertheless to activate this kind of process locally the client application must explicitly ask it to COM by using the CLSCTX_LOCAL_SERVER flag only instead of the CLSCTX_ALL flag.

    "Why ? (again)"
    In order to use the Surrogate process the SCM still need to have the DLL file name under the subkey [HKCR\CLSID\{GUID1}\InprocServer32]. That is fine, but when the client specified CLSCTX_ALL, it is specified CLSCTX_INPROC_SERVER as the same time, the SCM will look first for the subkey [HKCR\CLSID\{GUID1}\InprocServer32] and if it exists then it will launch the COM Server as an In-process server into the client space. In this situation, the SCM will never reach the named value DllSurrogate.

    Some remarks:
    • if on the remote machine the named value RemoteServerName exists the remote SCM will not consider it when it will be executing a remote activation. This means that you can not reroute the remote activation into another machine and so on.
    • The third parameter of CoGetClassObject() takes as its third parameter a pointer into a COSERVERINFO structure. You can use this structure to explicitly set the remote machine name.
      When this parameter is NULL, the SCM will look for the value named RemoteServerName in the registry.

    The Security

    In general, you use a security infrastructure to protect your private data, or any resource, against wrong hands.

    At the beginning, COM did not have a specific security infrastructure to protect the client or the server application. The release of Windows NT 4.0 introduced processes and threads security levels and permitted server processes to be accessed remotely. On the Windows platforms implementation (particularly NT 4.0 and 2000), the COM security infrastructure is built by using:
    • the operating system features,
    • and the RPC security infrastructure (see [Bi11], chapter 6).
    Before to go deeper in the COM Security Infrastructure, it is useful to have a brief introduction to Windows NT/2000 Security.

    The Windows NT/2000 security infrastructure

    Windows NT/2000 has a support for security based on user accounts, groups, and domains. Windows 95/98 security support is lower than Windows NT/2000. In this section I will talk only about Windows NT/2000 security aspect, for specific Windows 95/98 implementations please refer to the platform documentation.
    For the rest of this section, the word Windows will refer as Windows NT/2000 when there is no need to distinguish between them.

    Windows focuses on 2 areas ([Bi12], chapter 18):
    • Authentication. Authentication try to answer to the question "Are you really who you claim to be ?" . One of the most use of authentication in Windows is when a user try to log on.
    • Access control. Access control in Windows allows or limits certain users access to specific resources or services.
    In order to log on to Windows, the user must have a user account. Each user and user group is identified by a unique value called a Security IDenfier (SID). Once the user logged on successfully, Windows associated to the user an access token. This access token contains information related to the user such as the user SID, the list of the groups the user belong to and other privileges.

    Every time a process is started under the session opened by the user, Windows (by default) associated the user's access token to it. Then, when the process wants to access a system object (e.g. a thread, a mutex, or a file) Windows compares the security information attached to it and the access token of the process. After comparison, Windows grants or denies the access.

    Every system object can contain a Security Descriptor that is composed of:
    • the owner SID.
    • the primary group SID to which the user belong to.
    • the System Access Control List (SACL), for audit messages
    • the Discretionary Access Control List (DACL), for the control access.
    Both types of access control lists (SACL and DACL) are lists of Access Control Entries (ACEs). An ACE contains the SID of a user or group of user and some type of access (e.g. Read, Write, Execute, etc.) that is either granted to (access-allowed ACE) or denied (access-denied ACE).

    I think it is time to have a picture:

    Image 4

    The ACE-Denied entries are always placed in first positions.
    In Windows, the job of authenticating a user is done by a Security Support Provider (SSP). The Win32 API defines a security API called the Security Support Provider Interface (SSPI). A SSP is a DLL that implements the SSPI and generally contains common authentication and cryptographic data schemes.
    In Windows NT 4.0, there was only one SSP deliver with the operating system: the NT LAN Manager Security Support Provider (NTLM SSP).
    In Windows 2000, there are more:
    • NTLM SSP, as in Windows NT 4.0 .
    • Kerberos is a more sophisticated authentication protocol than NTLM SSP.
    • Snego for Simple GSS-API Negotiation Mechanism. In fact, Snego is not really a SSP itself. It is protocol used to negotiate between real SSPs. It chooses Kerberos if it supported by both sides (client and server), otherwise it chooses NTLM.
    This is an open architecture as third parties can develop new SSP and install them without interfering with the existing ones. An application that already uses an SSP would require few or maybe no modification with a new SSP.

    The COM security infrastructure

    COM distinguishes between 4 fundamental aspects of security ([Bi4]):
    • Launch security: Which security users are allowed to create a new object in a new process ?
      => Protecting the server machine
    • Access security: Which security users are allowed to call an object ?
      => Protecting the object
    • Identity: What is the security user of the object itself ?
      => Controlling the object
    • Connection policy: Integrity- can messages be altered? Privacy- can messages be intercepted by others? Authentication- can the object find out or even assume the identity of the caller?
      => Protecting the data
    These aspects can be set at different levels, i.e. the security grain:
    • Machine-wide security level,
    • Application-wide security level (or per-Server basis),
    • per-Class basis
    • per-Interface basis
    • per-Method call basis
    Nota: when talking about the last 3 levels (per-class, per-Interface, and per-method call basis) they are generally called fined-grain security.

    You can set the security information in 2 complementary ways:
    • by Configuration. The security informations are stored in the registry. You can use DCOMCNFG.EXE to set these informations. Many books explain how to use this tool, such as [Bi3], chapter 5, [Bi12], chapter 18, [Bi10], chapter 10, and the MSDN article [Bi5].
    • by Programmation. You can use the COM Security API to set security information.
    By Configuration you can not set all the security aspect information, and it is the same with Programmation. For this reason, they are complementary.
    Settings on the registry are also called the default settings.

    If you set security information on more than one level, what happens ? In fact, according to the security levels, you can override the settings of the lower level by a higher level. Here is a figure pointing out the security level ordered:

    Image 5

    An per-Method security level override a per-Interface security level, an so on.

    And to terminate this high-level view of COM security model, some of these security informations can be set only on the client side, only on the server side, or in both sides.

    All these parameters and combinations of settings make COM Security a huge subject by itself, but if you are developing distributed applications you must look at them.

    Some Practice

    The COM Macro-Topology

    After finishing a COM component, we have to deploy, install and configure it. There could be many situations to deploy our components.
    By deployment I mean:
    • What kind of unit (Executable or DLL) will you use for your Client or your Server ?
    • Where do you copy the Client unit and the Server unit ?
    We can define 3 criterias to determine the COM deployment Architecture, or like I call it the "COM Macro-Architecture":
    • The location (2):
      • Local means that the Client and the Server are in the same machine. However maybe not in the same process.
      • Remote means that the Client and the Server are not in the same machine.
    • The client (2): an Executable or a DLL.
    • The COM server (3): an executable, DLLs or a DLL merged.
      • an Executable. You have to be aware about DCOM Application security and the Proxy/Stub DLL.
      • DLLs. This case corresponds to 2 DLLs : one for the COM Server itself and one more for the Proxy/Stub DLL.
      • DLL with Proxy/Stub merged. only one DLL.

    So, with those 3 criterias there are 12 cases (2 x 2 x 3).

    The 12 cases

    We will see case by case how to make and install our COM applications: Client & Server.

    Image 6 Here are the 12 cases:

    COM Macro-Architecture
    Topology's cases
    Location

    Local: Image 7
    Remote: Image 8
    Client

    Executable: Image 9
    DLL: Image 10
    Server

    Executable: Image 11
    DLLs: Image 12
    DLL (merged): Image 13
    Case 1Image 14Image 15Image 16
    Case 2Image 17Image 18Image 19
    Case 3Image 20Image 21Image 22
    Case 4Image 23Image 24Image 25
    Case 5Image 26Image 27Image 28
    Case 6Image 29Image 30Image 31
    Case 7Image 32Image 33Image 34
    Case 8Image 35Image 36Image 37
    Case 9Image 38Image 39Image 40
    Case 10Image 41Image 42Image 43
    Case 11Image 44Image 45Image 46
    Case 12Image 47Image 48Image 49

    Picture legends Image 50

    Here are the picture symbol's legend used in the 12 cases:

    Image 51

    Case 1 Image 52

    Here are the steps to build this case:
    1. Create the COM Server as an Executable (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server files (Executable and Proxy/Stub DLL) and client file to the target machine.
    4. Register the Server using the "Local consideration".
      • Step 7.
    5. Launch the Client application and use the COM Server.
    The results are showed in the picture below:

    Image 53
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM server objects will never run in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM Server and a Client application might be:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      This depend on the initialisation of the Class Factories in the COM Server (using the COM API function CoRegisterClassObject()) but this is out of the scope of this series.
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • COM Server Executable can be developed as a Windows Service.
    When you want to uninstall the system (Client application and COM Server):
    1. Remove the Client application by simply deleting the Client executable file.
    2. Unregister the COM Server following the instructions in the article "COM Macro-Architecture Topology (Servers)".
      • Step 9 using the "Local consideration".
    3. Remove the COM Server files by simply deleting the COM Server executable file and the Proxy/Stub DLL file.

    Case 2 Image 54

    For this deployment, you can have 2 different configurations:
    • the COM DLL server loaded into the client process. COM refers as this server as an in-process server.
    • the COM DLL server running outside the client process but in the same machine. COM refers as this server as a (local) out-of-process server.

    In-process Server

    Here are the steps to build this case:
    1. Create the COM Server as 2 DLLs (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server files (COM DLL Server and Proxy/Stub DLL) and client file to the target machine.
    4. Register the Server using the "Local In-process consideration".
      • Step 7.
    5. Launch the Client application and use the COM DLL Server.
    The results are showed in the picture below:

    Image 55
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM DLL server will run in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM DLL Server and a Client application is:
      • 1 to 1: Each client application has its own COM DLL Server. In reality, the instance of the DLL will be shared between clients' processes. This means that every global data will be shared as well, so they should be safe multithreaded. Nevertheless, every runtime instances (heap and stack) will be part of the client's memory space process.
       
    • COM Security aspect
      • A DLL can never run without a process. All the security aspects will be managed by this process, i.e. the client process.
       
    • Other:
      • The client code can access the COM object indirectly (links 1.a, 1.b and 1.c) if they are in different COM apartments or directly (link 2) if they are in the same, but this matter is out of the scope of this series.
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Remove the Client application by simply deleting the Client executable file.
    2. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)".
      • Step 9 using the "Local In-process consideration".
    3. Remove the COM Server files by simply deleting the COM DLL Server file and the Proxy/Stub DLL file.

    Out-of-process Server

    Here are the steps to build this case:
    1. Create the COM Server as 2 DLLs (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server files (COM DLL Server and Proxy/Stub DLL) and client file to the target machine.
    4. Register the Server using the "Local Surrogate consideration".
      • Step 7.
    5. Launch the Client application and use the COM DLL Server.
    The results are showed in the picture below:

    Image 56
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM DLL server will run in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM DLL Server and a Client application is:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      The fact to have many instances of the default Surrogate application (DLLHOST.EXE) running in the same machine and then of your COM DLL Server depends on the security values set (see at The activation mechanism).
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • Other:
      • If in the client code you use flags such as CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_SERVER or CLSCTX_ALL the in-process server will be launched first by COM.
       
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Remove the Client application by simply deleting the Client executable file.
    2. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)".
      • Step 9 using the "Local Surrogate consideration".
    3. Remove the COM Server files by simply deleting the COM DLL Server file and the Proxy/Stub DLL file.

    Case 3 Image 57

    For this deployment, you can have 2 different configurations:
    • the COM DLL server loaded into the client process. COM refers as this server as an in-process server.
    • the COM DLL server running outside the client process but in the same machine. COM refers as this server as a (local) out-of-process server.

    In-process Server

    Here are the steps to build this case:
    1. Create the COM Server as 1 DLL (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server file (this time the COM DLL Server is merged with the Proxy/Stub code) and the client file to the target machine.
    4. Register the Server using the "Local In-process consideration".
      • Step 7.
    5. Launch the Client application and use the COM DLL Server.
    The results are showed in the picture below:

    Image 58
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM DLL server will run in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM DLL Server and a Client application is:
      • 1 to 1: Each client application has its own COM DLL Server. In reality, the instance of the DLL will be shared between clients' processes. This means that every global data will be shared as well, so they should be safe multithreaded. Nevertheless, every runtime instances (heap and stack) will be part of the client's memory space process.
       
    • COM Security aspect
      • A DLL can never run without a process. All the security aspects will be managed by this process, i.e. the client process.
       
    • Other:
      • The client code can access the COM object indirectly (links 1.a, 1.b and 1.c) if they are in different COM apartments or directly (link 2) if they are in the same, but this matter is out of the scope of this series.
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Remove the Client application by simply deleting the Client executable file.
    2. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)".
      • Step 9 using the "Local In-process consideration".
    3. Remove the COM DLL Server file by simply deleting the file.

    Out-of-process Server

    Here are the steps to build this case:
    1. Create the COM Server as 1 DLL (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server file (this time the COM DLL Server is merged with the Proxy/Stub code) and the client file to the target machine.
    4. Register the Server using the "Local Surrogate consideration".
      • Step 7.
    5. Launch the Client application and use the COM DLL Server.
    The results are showed in the picture below:

    Image 59
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM DLL server will run in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM DLL Server and a Client application is:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      The fact to have many instances of the default Surrogate application (DLLHOST.EXE) running in the same machine and then of your COM DLL Server depends on the security values set (see at The activation mechanism).
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • Other:
      • In that configuration, we have lost the benefit to have only one DLL. Because we want our component to run out-of-process, the client application still needs the marshalling code (Proxy/Stub code) in its space process. Therefore, you have to build and install the Proxy/Stub DLL.
      • If in the client code you use flags such as CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_SERVER or CLSCTX_ALL the in-process server will be launched first by COM.
       
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Remove the Client application by simply deleting the Client executable file.
    2. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)".
      • Step 9 using the "Local Surrogate consideration".
    3. Remove the COM DLL Server file by simply deleting the file.

    Case 4, Case 5, Case 6 Image 60

    Here for deployment sake I have made the difference between Client DLL and Executable, but there are "no differences" from a functional point a view. I mean the Client code to write is the same in both cases.
    However, with in-process COM Server (DLL) you have to take in account the COM Apartment consideration, but this is outbound the subject of this article.
    Obviously, if your client is also a COM server, you have to apply the same rules for the COM server explained before. So:
    • For the case 4 refer to the Case 1,
    • For the case 5 refer to the Case 2,
    • For the case 6 refer to the Case 3.

    Case 7 Image 61

    Here are the steps to build this case:
    1. Create the COM Server as an Executable (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server files (Executable and Proxy/Stub DLL) to the server machine (see below as HOST B).
    4. Copy the server Proxy/Stub DLL and the client application to the client machine (see below as HOST A).
    5. Register the Server using the "Remote consideration". There are 2 registrations: one for the Client machine and one for the Server machine.
      • Step 7.
    6. Configure the DCOM security aspect of the Server.
      • Step 8.
    7. Launch the Client application and use the COM Server.
    The results are showed in the picture below:

    Image 62
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM server objects will never run on the same machine and so in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM Server and a Client application might be:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      This depend on the initialisation of the Class Factories in the COM Server (using the COM API function CoRegisterClassObject()) but this is out of the scope of this series.
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • DCOM aspect
      • You have to enable DCOM on both machines: Client and Server. You can use DCOMCNFG.EXE (on the Default Properties tab).
       
    • If you have more than one server machine (many HOST B), you can configure client machines to use different server machine by simply changing the "RemoteServerName" value (under the AppID key) in the registry.
      You can as well use, in your client application code, the API function CoCreateInstanceEx() to determine the machine on which the object will be instantiated.

    • COM Server Executable can be developed as a Windows Service.
    When you want to uninstall the system (Client application and COM Server):
    1. Unregister the COM Server following the instructions in the article "COM Macro-Architecture Topology (Servers)". There are 2 unregistrations: one for the Client machine and one for the Server machine.
      • Step 9 using the "Remote consideration".
    2. On the Client machine, remove the Client application and the Server Proxy/Stub DLL by simply deleting these files.
    3. On the Server machine, remove the COM Server files by simply deleting the COM Server executable file and the Proxy/Stub DLL file.

    Case 8 Image 63

    Here are the steps to build this case:
    1. Create the COM Server as 2 DLLs (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server files (COM DLL Server and Proxy/Stub DLL) to the server machine (see below as HOST B).
    4. Copy the server Proxy/Stub DLL and the client application to the client machine (see below as HOST A).
    5. Register the Server using the "Remote consideration". There are 2 registrations: one for the Client machine and one for the Server machine.
      • Step 7.
    6. Configure the DCOM security aspect of the Server.
      • Step 8.
    7. Launch the Client application and use the COM Server.
    The results are showed in the picture below:

    Image 64
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM server objects will never run on the same machine and so in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM Server and a Client application might be:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      The fact to have many instances of the default Surrogate application (DLLHOST.EXE) running in the same machine and then of your COM DLL Server depends on the security values set (see at The activation mechanism).
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • DCOM aspect
      • You have to enable DCOM on both machines: Client and Server. You can use DCOMCNFG.EXE (on the Default Properties tab).
       
    • If you have more than one server machine (many HOST B), you can configure client machines to use different server machine by simply changing the "RemoteServerName" value (under the AppID key) in the registry.
      You can as well use, in your client application code, the API function CoCreateInstanceEx() to determine the machine on which the object will be instantiated.
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)". There are 2 unregistrations: one for the Client machine and one for the Server machine.
      • Step 9 using the "Remote consideration".
    2. On the Client machine, remove the Client application and the Server Proxy/Stub DLL by simply deleting these files.
    3. On the Server machine, remove the COM Server files by simply deleting the COM DLL Server file and the Proxy/Stub DLL file.

    Case 9 Image 65

    Here are the steps to build this case:
    1. Create the COM Server as 1 DLL (Look at the "COM Macro-Architecture Topology (Servers)" article).
      • Go through step 1 to 6.
    2. Create the Client application as an Executable (Look at the "COM Macro-Architecture Topology - Clients" article).
    3. Copy the server file (this time the COM DLL Server is merged with the Proxy/Stub code) to the server machine (see below as HOST B).
    4. Copy the server Proxy/Stub DLL and the client application to the client machine (see below as HOST A).
    5. Register the Server using the "Remote consideration". There are 2 registrations: one for the Client machine and one for the Server machine.
      • Step 7.
    6. Configure the DCOM security aspect of the Server.
      • Step 8.
    7. Launch the Client application and use the COM Server.
    The results are showed in the picture below:

    Image 66
    Legend

    Some remarks about this deployment architecture:
    • Process relation:
      • The client application and the COM server objects will never run on the same machine and so in the same process.
       
    • The cardinality of the relation between instances (processes) of a COM Server and a Client application might be:
      • 1 to 1: Each client application could have its own COM Server.
      • 1 to n: A COM Server could be shared between many client applications.
      • n to 1: A client application could have many COM Servers.
      The fact to have many instances of the default Surrogate application (DLLHOST.EXE) running in the same machine and then of your COM DLL Server depends on the security values set (see at The activation mechanism).
    • COM Security aspect
      • You can use DCOMCNFG.EXE to set the different security details (Access, Launch, User, etc.).
       
    • DCOM aspect
      • You have to enable DCOM on both machines: Client and Server. You can use DCOMCNFG.EXE (on the Default Properties tab).
       
    • If you have more than one server machine (many HOST B), you can configure client machines to use different server machine by simply changing the "RemoteServerName" value (under the AppID key) in the registry.
      You can as well use, in your client application code, the API function CoCreateInstanceEx() to determine the machine on which the object will be instantiated.
    When you want to uninstall the system (Client application and COM DLL Server):
    1. Unregister the COM DLL Server following the instructions in the article "COM Macro-Architecture Topology (Servers)". There are 2 unregistrations: one for the Client machine and one for the Server machine.
      • Step 9 using the "Remote consideration".
    2. On the Client machine, remove the Client application and the Server Proxy/Stub DLL by simply deleting these files.
    3. On the Server machine, remove the COM DLL Server file by simply deleting the file.

    Case 10, Case 11, Case 12 Image 67

    Same explanation as for Case 4, Case 5 and Case 6.
    The corresponding cases are :
    • For the case 10 refer to the Case 7,
    • For the case 11 refer to the Case 8,
    • For the case 12 refer to the Case 9.

    Conclusion

    A final question might be: "Should I build in-process servers or out-of-process servers ?" (see [Bi10]).
    In reality it will depend of your requirements and your constraints, but I think now you have enough information to answer that question by yourself. Main ideas to keep in mind is that:
    • A COM Server as an Executable will never be used as an in-process Server.
    • A COM Server as a DLL could be used as both: in-process and out-of-process Server.
    • In-process vs. Out-of-process:
      • You can have performance by using in-process server (COM object ought to share the same apartment of the Client code).
      • You can have robustness by using out-of-process server.
    • An in-process server will benefit from security privileges of its parent process.
    • An in-process server has its life tight to the client process life.
    I hope I have given you an informative overview to "COM Macro-Architecture". You should have now a good understanding on how to create and deploy your COM applications locally or remotely and some things you should consider in building COM application systems.

    When I started this series of articles I have tried to organise my work around a duality idea and I chose the duality concept of Macro/Micro. Now, I maybe release that a better duality concept would be Static/Dynamic:
    • The split is still the same: the unit of deployment.
    • We can use Static instead of Macro, as once a component is deployed it will not move from its physical location (Host machine) and unit (Executable or DLL file).
    • We can use Dynamic instead of Micro, as at runtime, when we instantiate our COM objects, we can talk about what it is happening inside the Application and COM Server (such as Thread, Memory, Apartment, etc.) and the relation between these instances.
    One more remark about this article: I did not talk about mixing cases, such as local and remote deployment at the same time (e.g. case 1 and 7). Maybe I will write this section on a future update.

    For my part, I will try to write the "COM Micro-Architecture" article, or maybe "COM Dynamic-Architecture".

    Thanks

    I would like to thank Minh, my wife, to her support; Dave Haste and Anne-Sophie Merot for spending the time to review my article.

    Bibliography

    [Bi1]
    Specification for COM,
    version 0.9, October 24, 1995.
    [Bi2]
    Inside Distributed COM, Guy Eddon and Henry Eddon, 1998,
    Microsoft Press.
    [Bi3]
    Learning DCOM, Thuan L. Thai, April 1999,
    O'Reilly edition.
    [Bi4]
    DCOM Architecture, Markus Horstmann and Mary Kirtland,
    July 23, 1997, MSDN Library.
    [Bi5]
    COM Security in Practice, Rajiv Dulepet,
    MSDN Library.
    [Bi6]
    Run Your Applications on a Variety of Desktop Platforms with Terminal Server, Frank Kim,
    Microsoft Interactive Developer, December 1998.
    [Bi7]
    Inside ATL, George Shepherd and Brad King, 1999,
    Microsoft Press.
    [Bi8]
    The Rules of the Component Object Model, Charlie Kindel, October 20, 1995,
    MSDN Library.
    [Bi9]
    Designing COM Interfaces, Charlie Kindel, October 20, 1995,
    MSDN Library.
    [Bi10]
    ActiveX/COM Q & A, Don Box, 1997,
    Question: "I am building a suite of COM objects that have little or no user interface and will be called from a variety of client languages, perhaps over a network. Should I build inproc servers or outofproc servers ?" ,
    MSDN Library / reproduced from Microsoft Systems Journal.
    [Bi11]
    Essential COM, Don Box, 1998,
    Addison Wesley.
    [Bi12]
    Inside COM+ Base Services, Guy Eddon and Henry Eddon, 1999,
    Microsoft Press.
    [Bi13]
    The COM and COM+ programming primer, Alan Gordon, 2000,
    Prentice Hall PTR.
    [Bi14]
    COM Security Primer, Part I & II, Jeff Prosise, November 2000,
    Codeguru Web site

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    France France
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    GeneralSuperb Article Pin
    Shiva Asthana8-Jan-07 1:34
    Shiva Asthana8-Jan-07 1:34 
    GeneralRe: Superb Article Pin
    chandean21-Feb-08 21:15
    chandean21-Feb-08 21:15 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.