Professional ATL COM Programming
Home About Workshops Articles Writing Talks Books Contact
ISBN: 1-86100-060-X
Richard Grimes

Buy this book from Richard Grimes
Download code

Chapter 1

Distributed Objects

The first chapter is devoted to explaining what distributed objects are and the technologies you could use to achieve it. The sections include a comparison of Sockets, DCE RPC, Inferno, CORBA and COM. It also gives examples of client-server and distributed applications written in Java using sockets, RMI and JavaIDL.

Chapter 2

Distributing Objects in Windows

The second chapter focuses on Windows as a platform, but the concepts described are relevant to other platforms too. The chapter explains methods to distribute code and shared data on the windows platform, so it explains Windows DLLs, memory mapped files, shared memory sections and Winsock. The section on DLLs introduces the concept of interfaces and this is expanded further in Chapter 3. The section on Winsock gives an example of developing a client-server application using the MFC CSocket classes, the main point behind this example is to introduce the concepts of data marshalling and of method dispatching.

Chapter 3

Component Object Model

This chapter serves as a general introduction to COM. It starts by giving a brief history lesson about sharing data in Windows, and charts the progress from sharing static data via the clipboard (using the Windows clipboard formats) and then onto more dynamic methods starting with DDE, and then OLE1, 16-bit OLE2, 32-bit OLE2 and finally DCOM on NT4 and Windows95. (This section was shamelessly copied by other authors, in their book on DCOM published after Professional DCOM Programming.)

After that the chapter goes through the features of the COM binary standard. The topics covered are memory allocation, interfaces, IUnknown, reference counting, status codes, globally unique identifiers, and COMs use of the registry.

The second half of the chapter covers the API used in instantiating objects and writing object servers. It starts with COM initialization, class factories, object instantiation and object location transparency. There are sections describing inproc, local and remote servers and inproc handlers giving details about the differences between the server implementations. After that I get into the details of how you would actually write a server in C++ and show the two common methods of writing an object with multiple interfaces: multiple inheritance and nested classes.

Chapter 4

Distributed Component Object Model

 This chapter outlines what DCOM adds to COM, it explains that DCOM is layered over Microsoft RPC (which is compliant with DCE RPC) and thus can use one of several network protocols. It then goes on to explain how the lifetime of remote objects are managed, how it can manage connections to multiple clients and react to the unexpected death of a client: delta pinging and remote garbage collection.

Objects can be written specifically to use DCOM (and hence the code can explicitly do things like set the access control lists for which accounts can use them), or you can configure a pre-DCOM object to be used remotely. Similarly, a COM client can either be written specifically to use remote objects (hence they will specify the host server where the object server resides) or a pre-DCOM client can be configured to use remote objects. What do I mean by 'configure'? This is carried out using the registry. This chapter explains the registry entries used by DCOM for clients and servers, and explains the entries used by DCOM objects and legacy objects.

If you want to activate a remote object it means that the object must be running in an EXE (by definition, you cannot run a DLL on its own). So what if you have a DLL object server and you want to use these objects remotely? To do this you have to have a 'wrapper' EXE called a surrogate and there are two general surrogates that you can use. The first sort (and the one that will be increasingly important in the near future) is MTS, which is covered in Chapter 10. The other type of surrogate is either a custom surrogate (ie one you write yourself, but that is not common), or the system provided surrogate DllHost.exe. This chapter explains custom surrogates and DllHost.exe and how to configure the registry to use them.

The final part of the chapter presents some code for a simple ATL 2.1 server and a MFC 4.2 client. The text explains how to write a simple EXE-based COM object (ie no remote-specific code) to return the time on the host machine. The client has DCOM code to locate the host machine and explains how to use DCOMCnfg and register proxy-stub code.

Chapter 5

Writing DCOM Clients and Servers

This chapter looks at the details of writing DCOM clients and servers. The chapter starts with an overview of IDL and MIDL, explaining the variable types that you can use and how to use arrays, structs and unions. It then explains interfaces and the differences between 'custom', dual, and dispinterfaces. This leads on to the oleautomation attribute and type libraries and how this applies to type library marshaling.

Type library marshaling is illustrated with an example that allows a client to view the environment variables set for an account on the remote host machine. To use type library marshaling the client machine must have relevant registry entries, in particular the type library must be registered on the client machine. The chapter shows one way to do this, using a RegEdit script.

The chapter then takes a look at connection points. These are one way that you can set up bi-directional communications between a client and object. The chapter explains what connection points are, the interfaces that are used and how to use them. The example shows an extension to the time server example from Chapter 4 where the client can set an alarm time and when that time is reached the server will remotely inform the client using connection points. To do this the server uses a worker thread in an MTA apartment - more details are given in chapter 9.

Chapter 6

DCOM Under the Hood

This chapter explains the packets that are sent across the wire when a client attaches to a remote object and when that object returns information back to the client. I use network monitor to view DCOM packets to illustrate that DCOM is just an extension of Microsoft RPC. I create two examples: one that uses RPC and the other that uses DCOM and then I compare the packets that both examples use. Further I compare a local COM object and a remote COM object to see how they compare and do some grungy memory work to illustrate the work that Microsoft has done on your behalf to make an inproc, local and remote object all look the same to a client.

The chapter finishes with an example that passes strings across the wire. The point of the example is to illustrate that for network efficiency it is best to make a few calls that will bring large amounts of data across the network, than to make many calls that will each bring small amounts of data.

When you read this chapter you will become aware that it is very similar to the corresponding chapter in a book by some other authors (whose names I will not mention). Their book was published 7 months after Professional DCOM Programming so clearly their chapter plagiarised mine. Indeed, those authors even had the nerve to publish their copy in a well respected magazine devoted to Microsoft technologies. My message is that although they had the opportunity to update my work for the DCOM protocol, they did not do the work that I had to, to present how DCOM works; it makes me sad that these authors could not make the effort that I did. 

Chapter 7


One of the new things that DCOM brought to COM was security. It must do this to make sure that only authenticated accounts can launch object servers and then access objects created by those servers. In NT4 the security that is used is NT's native NTLM security. Thus this chapter starts with an overview of NTLM security explaining terms like SID, privileges and rights, security descriptors, ACLs, SACLs, DACLs, Access Tokens and TRUSTEEs. To do this the chapter shows you how to write an MFC application to view the privileges that your account has, and shows you how to change those privileges with the NT user manager. Next the chapter introduces NT Services to show the security aspects that they have, and explains Window stations, which are important when you choose an identity for a server to use with DCOMCnfg.

The second half of the chapter explains how security is applied with DCOM. This part of the chapter explains how to use DCOMCnfg and how to programmatically apply security. In particular, it explains the client and server aspects including the IClientSecurity and IServerSecurity interfaces. The first example in this section shows you how changing the identity and access and launch permissions with DCOMCnfg affect the accounts that will be used on the server and whether client accounts are suitable to use the object.

The second example allows you to programmatically change the client's security settings and hence play around with the client account details, authentication and impersonation levels. The example applies these levels and illustrates the accounts that are used by the object.

Chapter 8

DCOM Servers as NT Services

The second important change that DCOM added to COM was to allow you to implement local servers within NT services. As the last chapter explained, this has a security effect, but in addition, this also has an effect on the server module's lifetime. When you place a COM server in an NT service you change the server lifetime from dynamic to permanent. What do I mean by this? Well, one of the exciting things about COM is that when you ask for an object COM will locate the object server and if necessary launch that server (subject to correct security conditions). EXEs take up resources, and they can take a while to launch. To get round this you can make sure that only one server is ever launched (by setting the identity to an appropriate account, and making the server multiple use) and you can pre-launch the server. If you make the server an NT service it can be pre-launched when NT boots. As a bonus you can also make the server have the identity of the NT LocalSystem account which means that it uses the SYSTEM security credentials.

This chapter is split into two. The first half explains what NT services are, and the second explains how this applies to DCOM. To illustrate DCOM NT services I use ATL 2.1 AppWizard's NT services option and I explain how to replace ATL's rather weak use of the NT Event Log to a more robust and flexible version that allows you to use many event log messages that can be used by several locales. In addition I also explain how to use Event Log message categories.

The example in this chapter extends the example from Chapter 2 to show all of the running processes on a host machine to a client process on a remote machine. The example uses DCOM to remote this information and places this code in an NT service.

Chapter 9


The final major change that DCOM added to previous versions of COM was new threading models. Basically DCOM on NT4 (and DCOM9x when added to Win9x) will allow you to use COM in apartments. There are two types, your code can have zero or more Single Threaded Apartments, each one has a single thread, or your code can have zero or one Multi Threaded Apartment, which can have one or more threads. Remember, multithreading does not mean better performance and on a single processor machine it could mean worse performance. However, multi-threading does mean better availability of your code to clients; that is, you can arrange it so that when more than one client attempts to connect to your server if you have a single thread only one client will connect, blocking the others. If you have more than one thread then more clients will be able to connect, but the processor execution time will be shared between servicing those clients.

This chapter starts by introducing you to Win32 threading issues, how to create threads and how to destroy them. It then explains how to synchronise actions between threads to prevent some of the common multi threading problems of race conditions, deadlocking and corruption of shared data. This section of the book explains some popular threading models and illustrates this with code.

The second half of the chapter explains the threading issues applied to COM. It starts by explaining the two new apartments and how you create objects in those apartments. It also explains the difference between client and server threading models and the problems that occur when you create an inproc object in an incompatible apartment.

As an aside the diagrams in this section were devised by me, and it is rather strange that the aforementioned plagiarists' book use the same diagrams - they could not be bothered to create their own diagrams to explain apartments.

The example in this chapter shows you how to write a server using ATL2.1 that uses either of the COM apartment types.

Chapter 10

Microsoft Transaction Server

This final chapter was written when MTS was still in beta, so you do have to excuse the places where it may appear na´ve (indeed, in some cases I just could not get MTS to work and had no choice but to revert to the Microsoft documentation). MTS is more than a transaction processing monitor; it is true that it gives you ACID properties to your transactions, but in addition it is a COM surrogate that will handle concurrency and threading issues, state control and connection pooling.

This chapter explains the various components that make up MTS and how MTS is used to create a context around your object. It also explains terms like resource managers, resource dispensers and the shared property manager. Finally, the chapter takes a look at the role based security that MTS uses (this will be important for Microsoft's future operating systems).


Debugging Tips

This appendix explains how to debug COM servers using Visual Studio and it gives some tips on what to do if you get a problem and can't determine whether it is the client or server that generated it.

Buy this book from Richard Grimes

(c) 2006 Richard Grimes