summaryrefslogtreecommitdiffstats
path: root/o3d/nbguidgen
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/nbguidgen')
-rw-r--r--o3d/nbguidgen/build.scons44
-rw-r--r--o3d/nbguidgen/win/md5.cc254
-rw-r--r--o3d/nbguidgen/win/md5.h46
-rw-r--r--o3d/nbguidgen/win/nbguidgen.cc166
-rw-r--r--o3d/nbguidgen/win/nbguidgen.exebin0 -> 155648 bytes
5 files changed, 510 insertions, 0 deletions
diff --git a/o3d/nbguidgen/build.scons b/o3d/nbguidgen/build.scons
new file mode 100644
index 0000000..8dbd45f
--- /dev/null
+++ b/o3d/nbguidgen/build.scons
@@ -0,0 +1,44 @@
+# Copyright 2009, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Import('env')
+
+if env.Bit('windows'):
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'],
+ LIBS=['ole32'])
+
+inputs = [
+ 'win/md5.cc',
+ 'win/nbguidgen.cc',
+ ]
+
+exe = env.ComponentProgram('nbguidgen', inputs)
+# Copy the resulting executable to the Artifacts directory.
+exe_install = env.Replicate('$ARTIFACTS_DIR', [exe])
diff --git a/o3d/nbguidgen/win/md5.cc b/o3d/nbguidgen/win/md5.cc
new file mode 100644
index 0000000..dad056e
--- /dev/null
+++ b/o3d/nbguidgen/win/md5.cc
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+// This is adapted from libtomcrypt, which has been released into the
+// public domain.
+
+#include "nbguidgen/win/md5.h"
+#include <memory.h>
+
+#undef MAX
+#undef MIN
+#define MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
+#define MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
+
+#ifdef _MSC_VER
+
+/* instrinsic rotate */
+#include <stdlib.h>
+#pragma intrinsic(_lrotr, _lrotl)
+#define ROR(x, n) _lrotr(x, n)
+#define ROL(x, n) _lrotl(x, n)
+
+#else
+
+/* rotates the hard way */
+#define ROL(x, y) ( (((unsigned long)(x) << (unsigned long)((y) & 31)) | \
+ (((unsigned long)(x) & 0xFFFFFFFFUL) >> \
+ (unsigned long)(32-((y) & 31)))) & 0xFFFFFFFFUL)
+#define ROR(x, y) ( ((((unsigned long)(x) & 0xFFFFFFFFUL) >> \
+ (unsigned long)((y) & 31)) | \
+ ((unsigned long)(x) << \
+ (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
+
+#endif
+
+#define STORE32L(x, y) \
+ { (y)[3] = (unsigned char)(((x) >> 24)&255); \
+ (y)[2] = (unsigned char)(((x) >> 16)&255); \
+ (y)[1] = (unsigned char)(((x) >> 8)&255); \
+ (y)[0] = (unsigned char)((x) & 255); }
+
+#define LOAD32L(x, y) \
+ { x = ((unsigned long)((y)[3] & 255)<<24) | \
+ ((unsigned long)((y)[2] & 255)<<16) | \
+ ((unsigned long)((y)[1] & 255)<<8) | \
+ ((unsigned long)((y)[0] & 255)); }
+
+#define STORE64L(x, y) \
+ { (y)[7] = (unsigned char)(((x) >> 56) & 255); \
+ (y)[6] = (unsigned char)(((x) >> 48) & 255); \
+ (y)[5] = (unsigned char)(((x) >> 40) & 255); \
+ (y)[4] = (unsigned char)(((x) >> 32) & 255); \
+ (y)[3] = (unsigned char)(((x) >> 24) & 255); \
+ (y)[2] = (unsigned char)(((x) >> 16) & 255); \
+ (y)[1] = (unsigned char)(((x) >> 8) & 255); \
+ (y)[0] = (unsigned char)((x) & 255); }
+
+#define F(x, y, z) (z ^ (x & (y ^ z)))
+#define G(x, y, z) (y ^ (z & (y ^ x)))
+#define H(x, y, z) (x^y^z)
+#define I(x, y, z) (y^(x|(~z)))
+
+#define FF(a, b, c, d, M, s, t) \
+ a = (a + F(b, c, d) + M + t); \
+ a = ROL(a, s) + b;
+
+#define GG(a, b, c, d, M, s, t) \
+ a = (a + G(b, c, d) + M + t); \
+ a = ROL(a, s) + b;
+
+#define HH(a, b, c, d, M, s, t) \
+ a = (a + H(b, c, d) + M + t); \
+ a = ROL(a, s) + b;
+
+#define II(a, b, c, d, M, s, t) \
+ a = (a + I(b, c, d) + M + t); \
+ a = ROL(a, s) + b;
+
+static void md5_compress(md5_t *md) {
+ unsigned long i, W[16], a, b, c, d;
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++) {
+ LOAD32L(W[i], md->buf + (4*i));
+ }
+
+ /* copy state */
+ a = md->state[0];
+ b = md->state[1];
+ c = md->state[2];
+ d = md->state[3];
+
+ FF(a, b, c, d, W[0], 7, 0xd76aa478UL)
+ FF(d, a, b, c, W[1], 12, 0xe8c7b756UL)
+ FF(c, d, a, b, W[2], 17, 0x242070dbUL)
+ FF(b, c, d, a, W[3], 22, 0xc1bdceeeUL)
+ FF(a, b, c, d, W[4], 7, 0xf57c0fafUL)
+ FF(d, a, b, c, W[5], 12, 0x4787c62aUL)
+ FF(c, d, a, b, W[6], 17, 0xa8304613UL)
+ FF(b, c, d, a, W[7], 22, 0xfd469501UL)
+ FF(a, b, c, d, W[8], 7, 0x698098d8UL)
+ FF(d, a, b, c, W[9], 12, 0x8b44f7afUL)
+ FF(c, d, a, b, W[10], 17, 0xffff5bb1UL)
+ FF(b, c, d, a, W[11], 22, 0x895cd7beUL)
+ FF(a, b, c, d, W[12], 7, 0x6b901122UL)
+ FF(d, a, b, c, W[13], 12, 0xfd987193UL)
+ FF(c, d, a, b, W[14], 17, 0xa679438eUL)
+ FF(b, c, d, a, W[15], 22, 0x49b40821UL)
+ GG(a, b, c, d, W[1], 5, 0xf61e2562UL)
+ GG(d, a, b, c, W[6], 9, 0xc040b340UL)
+ GG(c, d, a, b, W[11], 14, 0x265e5a51UL)
+ GG(b, c, d, a, W[0], 20, 0xe9b6c7aaUL)
+ GG(a, b, c, d, W[5], 5, 0xd62f105dUL)
+ GG(d, a, b, c, W[10], 9, 0x02441453UL)
+ GG(c, d, a, b, W[15], 14, 0xd8a1e681UL)
+ GG(b, c, d, a, W[4], 20, 0xe7d3fbc8UL)
+ GG(a, b, c, d, W[9], 5, 0x21e1cde6UL)
+ GG(d, a, b, c, W[14], 9, 0xc33707d6UL)
+ GG(c, d, a, b, W[3], 14, 0xf4d50d87UL)
+ GG(b, c, d, a, W[8], 20, 0x455a14edUL)
+ GG(a, b, c, d, W[13], 5, 0xa9e3e905UL)
+ GG(d, a, b, c, W[2], 9, 0xfcefa3f8UL)
+ GG(c, d, a, b, W[7], 14, 0x676f02d9UL)
+ GG(b, c, d, a, W[12], 20, 0x8d2a4c8aUL)
+ HH(a, b, c, d, W[5], 4, 0xfffa3942UL)
+ HH(d, a, b, c, W[8], 11, 0x8771f681UL)
+ HH(c, d, a, b, W[11], 16, 0x6d9d6122UL)
+ HH(b, c, d, a, W[14], 23, 0xfde5380cUL)
+ HH(a, b, c, d, W[1], 4, 0xa4beea44UL)
+ HH(d, a, b, c, W[4], 11, 0x4bdecfa9UL)
+ HH(c, d, a, b, W[7], 16, 0xf6bb4b60UL)
+ HH(b, c, d, a, W[10], 23, 0xbebfbc70UL)
+ HH(a, b, c, d, W[13], 4, 0x289b7ec6UL)
+ HH(d, a, b, c, W[0], 11, 0xeaa127faUL)
+ HH(c, d, a, b, W[3], 16, 0xd4ef3085UL)
+ HH(b, c, d, a, W[6], 23, 0x04881d05UL)
+ HH(a, b, c, d, W[9], 4, 0xd9d4d039UL)
+ HH(d, a, b, c, W[12], 11, 0xe6db99e5UL)
+ HH(c, d, a, b, W[15], 16, 0x1fa27cf8UL)
+ HH(b, c, d, a, W[2], 23, 0xc4ac5665UL)
+ II(a, b, c, d, W[0], 6, 0xf4292244UL)
+ II(d, a, b, c, W[7], 10, 0x432aff97UL)
+ II(c, d, a, b, W[14], 15, 0xab9423a7UL)
+ II(b, c, d, a, W[5], 21, 0xfc93a039UL)
+ II(a, b, c, d, W[12], 6, 0x655b59c3UL)
+ II(d, a, b, c, W[3], 10, 0x8f0ccc92UL)
+ II(c, d, a, b, W[10], 15, 0xffeff47dUL)
+ II(b, c, d, a, W[1], 21, 0x85845dd1UL)
+ II(a, b, c, d, W[8], 6, 0x6fa87e4fUL)
+ II(d, a, b, c, W[15], 10, 0xfe2ce6e0UL)
+ II(c, d, a, b, W[6], 15, 0xa3014314UL)
+ II(b, c, d, a, W[13], 21, 0x4e0811a1UL)
+ II(a, b, c, d, W[4], 6, 0xf7537e82UL)
+ II(d, a, b, c, W[11], 10, 0xbd3af235UL)
+ II(c, d, a, b, W[2], 15, 0x2ad7d2bbUL)
+ II(b, c, d, a, W[9], 21, 0xeb86d391UL)
+
+ md->state[0] = md->state[0] + a;
+ md->state[1] = md->state[1] + b;
+ md->state[2] = md->state[2] + c;
+ md->state[3] = md->state[3] + d;
+}
+
+void MD5Init(md5_t *md) {
+ md->state[0] = 0x67452301UL;
+ md->state[1] = 0xefcdab89UL;
+ md->state[2] = 0x98badcfeUL;
+ md->state[3] = 0x10325476UL;
+ md->curlen = 0;
+ md->length = 0;
+}
+
+void MD5Process(md5_t *md, const unsigned char *buf, unsigned long len) {
+ unsigned long n;
+ while (len > 0) {
+ n = MIN(len, (64 - md->curlen));
+ memcpy(md->buf + md->curlen, buf, (size_t)n);
+ md->curlen += n;
+ buf += n;
+ len -= n;
+
+ /* is 64 bytes full? */
+ if (md->curlen == 64) {
+ md5_compress(md);
+ md->length += 512;
+ md->curlen = 0;
+ }
+ }
+}
+
+void MD5Finish(md5_t *md, unsigned char *hash) {
+ int i;
+
+ /* increase the length of the message */
+ md->length += md->curlen * 8;
+
+ /* append the '1' bit */
+ md->buf[md->curlen++] = (unsigned char)0x80;
+
+ /* if the length is currently above 56 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+ if (md->curlen > 56) {
+ while (md->curlen < 64) {
+ md->buf[md->curlen++] = (unsigned char)0;
+ }
+ md5_compress(md);
+ md->curlen = 0;
+ }
+
+ /* pad upto 56 bytes of zeroes */
+ while (md->curlen < 56) {
+ md->buf[md->curlen++] = (unsigned char)0;
+ }
+
+ /* store length */
+ STORE64L(md->length, md->buf+56);
+ md5_compress(md);
+
+ /* copy output */
+ for (i = 0; i < 4; i++) {
+ STORE32L(md->state[i], hash+(4*i));
+ }
+}
diff --git a/o3d/nbguidgen/win/md5.h b/o3d/nbguidgen/win/md5.h
new file mode 100644
index 0000000..8a47e57
--- /dev/null
+++ b/o3d/nbguidgen/win/md5.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_NBGUIDGEN_WIN_MD5_H_
+#define O3D_NBGUIDGEN_WIN_MD5_H_
+
+typedef struct {
+ __int64 length;
+ unsigned long state[4], curlen;
+ unsigned char buf[64];
+} md5_t;
+
+void MD5Init(md5_t *md);
+void MD5Process(md5_t *md, const unsigned char *buf, unsigned long len);
+void MD5Finish(md5_t * md, unsigned char *hash);
+
+#endif // O3D_NBGUIDGEN_WIN_MD5_H_
diff --git a/o3d/nbguidgen/win/nbguidgen.cc b/o3d/nbguidgen/win/nbguidgen.cc
new file mode 100644
index 0000000..8720d90
--- /dev/null
+++ b/o3d/nbguidgen/win/nbguidgen.cc
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <windows.h>
+#include <objbase.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "nbguidgen/win/md5.h"
+
+// This tool generates name-based GUIDs.
+
+// The quoted comments refer to various sections of RFC 4122, which explains
+// inter alia how to generate a name-based GUID.
+
+void GenerateNameBasedGUID(const unsigned char *namespace_guid_bytes,
+ const char *name, unsigned char *guid_bytes) {
+ // "Compute the hash of the name space ID concatenated with the name."
+ int concatenated_input_len = 16 + static_cast<int>(strlen(name));
+ unsigned char *concatenated_inputs =
+ static_cast<unsigned char *>(malloc(concatenated_input_len));
+ memcpy(concatenated_inputs, namespace_guid_bytes, 16);
+ memcpy(&concatenated_inputs[16], name, strlen(name));
+
+ md5_t md5;
+ MD5Init(&md5);
+ MD5Process(&md5, concatenated_inputs, concatenated_input_len);
+ free(concatenated_inputs);
+ MD5Finish(&md5, guid_bytes);
+
+ // "Set the four most significant bits (bits 12 through 15) of the
+ // time_hi_and_version field to the appropriate 4-bit version number
+ // from Section 4.1.3."
+ //
+ // Msb0 Msb1 Msb2 Msb3 Version Description
+ // 0 0 1 1 3 The name-based version
+ // specified in this document
+ // that uses MD5 hashing.
+ guid_bytes[6] &= 0x0f;
+ guid_bytes[6] |= 0x30;
+
+ // "Set the two most significant bits (bits 6 and 7) of the
+ // clock_seq_hi_and_reserved to zero and one, respectively."
+ guid_bytes[8] &= 0x3f;
+ guid_bytes[8] |= static_cast<unsigned char>(0x80);
+}
+
+bool ConvertStringToSerializedGUID(const char *s, unsigned char *g) {
+ GUID namespace_guid;
+ wchar_t namespace_guid_wide[38 + 1];
+
+ if (strlen(s) > 38) {
+ return false;
+ }
+ if (strlen(s) == 38) {
+ mbstowcs(namespace_guid_wide, s, INT_MAX);
+ }
+
+ // Undocumented feature: accept GUIDs that are missing braces.
+ if (strlen(s) == 36 && s[0] != '{') {
+ namespace_guid_wide[0] = L'{';
+ mbstowcs(namespace_guid_wide + 1, s, INT_MAX);
+ wcscat(namespace_guid_wide, L"}");
+ }
+ if (FAILED(CLSIDFromString(namespace_guid_wide, &namespace_guid))) {
+ return false;
+ }
+
+ int ngi = 0;
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data1 >> 24);
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data1 >> 16);
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data1 >> 8);
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data1);
+
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data2 >> 8);
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data2);
+
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data3 >> 8);
+ g[ngi++] = static_cast<unsigned char>(namespace_guid.Data3);
+
+ memcpy(&g[ngi], namespace_guid.Data4, sizeof(namespace_guid.Data4));
+
+ return true;
+}
+
+// Permanent unit test
+//
+// Unfortunately, the single concrete example of such a GUID in the RFC is
+// incorrect. Authorities on the web suggest that the correct output for
+// (6ba7b810-9dad-11d1-80b4-00c04fd430c8, "www.widgets.com") is
+// 3d813cbb-47fb-32ba-91df-831e1593ac29, and this program passes that test.
+static bool run_unit_test() {
+ unsigned char hash[16] = { 0 };
+ const unsigned char known_hash[16] = { 0x3d, 0x81, 0x3c, 0xbb,
+ 0x47, 0xfb,
+ 0x32, 0xba,
+ 0x91, 0xdf, 0x83, 0x1e, 0x15, 0x93, 0xac, 0x29 };
+ const unsigned char namespace_DNS_GUID[16] = {0x6b, 0xa7, 0xb8, 0x10,
+ 0x9d, 0xad,
+ 0x11, 0xd1,
+ 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8};
+ GenerateNameBasedGUID(namespace_DNS_GUID, "www.widgets.com", hash);
+
+ return (0 == memcmp(hash, known_hash, 16));
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ fprintf(stderr, "This tool generates name-based GUIDs as described in "
+ "RFC 4122.\r\nUsage: gguidgen namespace-guid name\r\n");
+ return 1;
+ }
+
+ if (!run_unit_test()) {
+ fprintf(stderr, "This program is broken.\r\n");
+ return 1;
+ }
+
+ unsigned char namespace_guid_as_bytes[16] = { 0 };
+ if (!ConvertStringToSerializedGUID(argv[1], namespace_guid_as_bytes)) {
+ fprintf(stderr, "Namespace must be a GUID of the form "
+ "{00000000-0000-0000-0000-000000000000}.\r\n");
+ return 1;
+ }
+
+ unsigned char hash[16] = { 0 };
+ GenerateNameBasedGUID(namespace_guid_as_bytes, argv[2], hash);
+
+ printf(
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ hash[0], hash[1], hash[2], hash[3],
+ hash[4], hash[5],
+ hash[6], hash[7],
+ hash[8], hash[9],
+ hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
+
+ return 0;
+}
diff --git a/o3d/nbguidgen/win/nbguidgen.exe b/o3d/nbguidgen/win/nbguidgen.exe
new file mode 100644
index 0000000..cf3d75f
--- /dev/null
+++ b/o3d/nbguidgen/win/nbguidgen.exe
Binary files differ