Globally Unique Identifiers (GUIDs)

The problem of unique cross-network identification is not itself unique to OLE—it is, in fact, a problem that is present with basic Remote Procedure Calls (RPC). Because of this, the Open Software Foundation (OSF) created the Universally Unique Identifier, or UUID, as part of their Distributed Computing Environment (DCE), which is where the standards for the RPC used in Microsoft Windows, and thus in OLE, are defined.

A UUID, which is given the alias GUID1 in COM and OLE, is a 128-bit (16-byte) integer that is virtually guaranteed to be unique in the world across space and time. Claiming that such an integer is unique across the universe is presumptuous. Global uniqueness is more realistic; hence the G in GUID instead of U. Throughout OLE, GUIDs are used to programmatically identify component classes (in which case they are called class IDs, or CLSIDs) and to identify interfaces (in which case they are called interface IDs, or IIDs).2

In various situations you'll need to obtain one or more GUIDs to assign to components that you implement or to new interfaces that you define. For this fundamental purpose COM provides an API function named CoCreateGuid, which actually calls the Win32 RPC API (acronym city!) function UUIDCreate. This function executes the algorithm specified by OSF DCE,3 which uses a combination of the following information to generate the GUID:

The chance of this carefully developed algorithm generating duplicate GUIDs in two different places at different times, even without a network card, is about the same as two random atoms in the universe colliding to form a small California avocado mated to a New York City sewer rat. In other words, don't worry about it.

While you might have occasion to create a GUID at run time with CoCreateGuid, you'll normally obtain the GUIDs you need once and assign them to the components you're developing. Your development environment will include a tool called UUIDGEN.EXE or GUIDGEN.EXE, which will give you one or more GUIDs that you can incorporate into source code. While writing this paragraph, I ran UUIDGEN, and it spit out the following:


3fad3020-16b7-11ce-80eb-00aa003d7352

This is the DCE standard for spelling out a GUID in hexadecimal text digits. (The hyphens are part of the standard as well.) To show just how unique these things can be, I ran UUIDGEN again only a few seconds later and got this result:


42754580-16b7-11ce-80eb-00aa003d7352

If you'd like to have more than one sequential GUID to make them a little more consistent, use the command-line switch -n <number>. For example, I ran UUIDGEN -n5, and it gave me this sequence:


a4f8a400-16b7-11ce-80eb-00aa003d7352
a4f8a401-16b7-11ce-80eb-00aa003d7352
a4f8a402-16b7-11ce-80eb-00aa003d7352
a4f8a403-16b7-11ce-80eb-00aa003d7352
a4f8a404-16b7-11ce-80eb-00aa003d7352

The sequence is counted in the first 32 bits of each value. A number of other switches for UUIDGEN can generate GUID declarations for use in C/C++ source files as well. Run UUIDGEN -? for a complete listing.

The code you'll write for OLE will use symbols to refer to whatever GUIDs you need. While the OLE header files and link libraries include every GUID that OLE defines (mostly IIDs), you'll need to define your own GUIDs somewhere in your own sources. You can do this with a C structure such as the following, which defines a symbol "MYGUID":


MyGUID = {  /* 891a0d90-16b7-11ce-80eb-00aa003d7352 */ 0x891a0d90
, 0x16b7, 0x11ce, {0x80, 0xeb, 0x00, 0xaa, 0x00, 0x3d, 0x73
, 0x52} };

You can also use the OLE macro DEFINE_GUID to do the same thing, as was done for this book's central repository of GUIDs used in the sample code, INC\BOOKGUID.H:


DEFINE_GUID(IID_ISampleOne, 0x00021141, 0, 0, 0xC0,0,0,0,0,0,0,0x46);

All the GUIDs used in this book's samples start with 0x000211xx and should not be used in your own projects: you must run UUIDGEN.EXE to obtain your own GUIDs. (My GUIDs are fraught with zeros because they were allocated from a pool of GUIDs set aside for Microsoft's purposes. Unfortunately, you can't get clean GUIDs like this; you must use GUIDGEN or UUIDGEN.)

Reduced to its binary form, a GUID has the following data structure:


typedef struct GUID
{
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} GUID;

typedef GUID CLSID;
typedef GUID IID;

Each field of the structure represents a piece of the GUID between the hyphens, giving you an easy way to address each part. For example, it can be useful in debugging to dump out the first DWORD of a GUID; if you have a sequence of GUIDs, this will be enough to indicate which one is which. For the most part, however, you'll never manipulate GUIDs directly—they are almost always manipulated either as a symbolic constant or as a variable whose absolute value is unimportant. For example, a client might enumerate all component classes registered on the system and display a list of those classes to an end user. That user selects a class from the list, which the client then maps to an absolute CLSID value. The client does not care what that value is—the client simply knows that the value uniquely identifies the user's selection.

This last example brings up an interesting question: do you really want to show the end user ugly hex strings such as 42754580-16b7-11ce-80eb-00aa003d7352? I think not. Therefore, you can assign human-readable names to GUIDs in the system registry for the convenience of the end user—users will usually see only a few components at a time in any list, so the chances of confusion over a conflict are greatly reduced. We'll talk about the registry in a moment.

1. Pronounced goo-id similar to how you would say gooey. Perhaps this is why OLE can seem a little "sticky" at times. Pun definitely intended.

2. In traditional object-oriented technology an object ID is more like an IID than a CLSID. Tra-ditionally objects have only a single interface and the object ID identifies what one can access in that object which is how interfaces are used in OLE. A CLSID in OLE identifies a component with one or more objects each with one or more interfaces.

3. See "DEC/HP Network Computing Architecture Remote Procedure Call RunTime Extensions Specification Version OSF TX1.0.11" Steven Miller July 23 1992. This is part of the OSF DCE documentation. Chapter 10 describes the UUID/GUID allocation algorithm.