Developers.GUIDs

From Shareaza Wiki
Jump to navigation Jump to search

How Shareaza Uses GUIDs

A GUID is a Globally Unique Identifier. It's 128 bits, which is 16 bytes, of seemingly random data. A program can ask Windows for a GUID, and it will get one.

Every time a program does this, the GUID Windows gives it will be different than all the GUIDs it gave it before. In fact, GUIDs are big enough and generated so that every GUID ever created anywhere is and will be unique.

You could have a database filled with thousands of GUIDs, and your friend could have a database filled with thousands more. You could combine your two databases, and none of the GUIDs would clash. If you had used numbers like 1, 2, and 3 instead of GUIDs, you couldn't do this. It would be more work to combine the databases, or you would have had to coordinate what numbers you would each use before you got started.

This is what makes GUIDs so useful. Separate programs working without contact can use GUIDs to identify things, and know that no matter what new foreign data gets mixed in later, the GUIDs will still be unique.

GUIDs help peer-to-peer networks work. Each Gnutella program has a GUID called the client ID. Another program can tell if it is talking to the same program as before by remembering its client ID. Each Gnutella packet has a GUID. Gnutella programs can notice packets looping back by checking their GUIDs.

Programming GUIDs

Windows has a type called GUID. It is 16 bytes of memory. Windows isn't open source, but Microsoft includes many .h files with Visual Studio so developers can look at them. To see how Windows defines GUID, open up guiddef.h:

typedef struct {
    unsigned long  Data1;
    unsigned short Data2;
    unsigned short Data3;
    byte           Data4[ 8 ];
} GUID;

Instead of just defining it as 16 bytes, the structure breaks it into parts. Data1 is 4 bytes, and Data2 and Data3 are 2 more each. The last 8 bytes are in an array called Data4.

Here's some code that makes a GUID:

GUID g;
CoCreateGuid(&g);

The first line, GUID g;, is just like int i;. The type is GUID instead of int, and we're naming our local variable g instead of i. The Win32 API call CoCreateGuid takes the memory address of our GUID, and fills it with the data of a new unique guid.

Windows also has a function that expresses the data of a GUID as text. Here's code that does it:

// Takes a GUID
// Writes it out as base 16 text with punctuation, like "{76687996-B879-498E-A10E-0B0002E67CA5}"
string guidtostring(GUID guid) {

    // Make a local buffer of wide characters with enough room to hold the 38 characters
    WCHAR bay[39];

    // Write the guid out as text
    int characters = StringFromGUID2( // Writes 78 bytes for both the ASCII and Unicode compile
        guid,                         // The GUID to describe as text
        (LPOLESTR)bay,                // Where StringFromGUID2 can write
        39);                          // The number of wide characters it has room to write
    if (characters != 39) throw false;

    // Clip the 38 characters into a string, and return it
    return clipwbyte *)bay, 38 * sizeof(WCHAR;
}

Shareaza has a type called GGUID. It's defined in StdAfx.h.

typedef union
{
	BYTE	n[16];
	BYTE	b[16];
	DWORD	w[4];
} GGUID;

It looks like this is a structure that contains an array of 16 bytes called n, followed by an array of 16 more bytes called b, and an array of 4 DWORDs after that. But, it's not. Notice the word union at the top. This means that all of the contents are different ways to look at the same data. A GGUID is 16 bytes. You can look at those bytes as an array of 16 bytes called n or b, or as an array of 4 DWORDs called w.