Developers.GUIDs: Difference between revisions

From Shareaza Wiki
Jump to navigation Jump to search
m (1 revision)
m (wiki formatting fix)
 
Line 1: Line 1:
===How Shareaza Uses GUIDs===
= 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.
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.


Line 10: Line 10:
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.
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====
== 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''':
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''':


<source lang="c">
typedef struct {
typedef struct {
    unsigned long  Data1;
    unsigned long  Data1;
    unsigned short Data2;
    unsigned short Data2;
    unsigned short Data3;
    unsigned short Data3;
    byte          Data4[ 8 ];
    byte          Data4[ 8 ];
} GUID;
} GUID;
</source>


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''.
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''.
Line 26: Line 24:
Here's some code that makes a GUID:
Here's some code that makes a GUID:


<source lang="c">
GUID g;
GUID g;
CoCreateGuid(&g);
CoCreateGuid(&g);
</source>


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.
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.
Line 35: Line 31:
Windows also has a function that expresses the data of a GUID as text. Here's code that does it:
Windows also has a function that expresses the data of a GUID as text. Here's code that does it:


<source lang="c">
// Takes a GUID
// Takes a GUID
// Writes it out as base 16 text with punctuation, like "{76687996-B879-498E-A10E-0B0002E67CA5}"
// Writes it out as base 16 text with punctuation, like "{76687996-B879-498E-A10E-0B0002E67CA5}"
string guidtostring(GUID guid) {
string guidtostring(GUID guid) {
 
    // Make a local buffer of wide characters with enough room to hold the 38 characters
    // Make a local buffer of wide characters with enough room to hold the 38 characters
    WCHAR bay[39];
    WCHAR bay[39];
 
    // Write the guid out as text
    // Write the guid out as text
    int characters = StringFromGUID2( // Writes 78 bytes for both the ASCII and Unicode compile
    int characters = StringFromGUID2( // Writes 78 bytes for both the ASCII and Unicode compile
        guid,                        // The GUID to describe as text
        guid,                        // The GUID to describe as text
        (LPOLESTR)bay,                // Where StringFromGUID2 can write
        (LPOLESTR)bay,                // Where StringFromGUID2 can write
        39);                          // The number of wide characters it has room to write
        39);                          // The number of wide characters it has room to write
    if (characters != 39) throw false;
    if (characters != 39) throw false;
 
    // Clip the 38 characters into a string, and return it
    // Clip the 38 characters into a string, and return it
    return clipw[[byte *)bay, 38 * sizeof(WCHAR]];
    return clipw[[byte *)bay, 38 * sizeof(WCHAR]];
}
}
</source>


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


[code StdAfx.h]
typedef union
typedef union
{
{
BYTE n[16];
BYTE n[16];
BYTE b[16];
BYTE b[16];
DWORD w[4];
DWORD w[4];
} GGUID;
} GGUID;
</source>


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 ''DWORD''s 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 ''DWORD''s called ''w''.
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 ''DWORD''s 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 ''DWORD''s called ''w''.

Latest revision as of 13:26, 27 October 2010

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.