warc.c: native uuid generation on Windows

* warc.c (windows_uuid_str) [WINDOWS]: New function specific to
MS-Windows.
(warc_uuid_str) [WINDOWS]: If windows_uuid_str succeeds, use its
result; otherwise use the fallback method.
This commit is contained in:
Eli Zaretskii 2015-02-23 23:32:33 +01:00 committed by Giuseppe Scrivano
parent 9df2250f4c
commit 33c5d979ce
1 changed files with 65 additions and 1 deletions

View File

@ -60,7 +60,8 @@ as that of the covered work. */
#ifdef WINDOWS
/* we need this on Windows to have O_TEMPORARY defined */
#include <fcntl.h>
# include <fcntl.h>
# include <rpc.h>
#endif
#ifndef O_TEMPORARY
@ -632,6 +633,61 @@ warc_uuid_str (char *urn_str)
xfree (uuid_str);
}
#else
# ifdef WINDOWS
typedef RPC_STATUS (RPC_ENTRY * UuidCreate_proc) (UUID *);
typedef RPC_STATUS (RPC_ENTRY * UuidToString_proc) (UUID *, unsigned char **);
typedef RPC_STATUS (RPC_ENTRY * RpcStringFree_proc) (unsigned char **);
static int
windows_uuid_str (char *urn_str)
{
static UuidCreate_proc pfn_UuidCreate = NULL;
static UuidToString_proc pfn_UuidToString = NULL;
static RpcStringFree_proc pfn_RpcStringFree = NULL;
static int rpc_uuid_avail = -1;
/* Rpcrt4.dll is not available on older versions of Windows, so we
need to test its availability at run time. */
if (rpc_uuid_avail == -1)
{
HMODULE hm_rpcrt4 = LoadLibrary ("Rpcrt4.dll");
if (hm_rpcrt4)
{
pfn_UuidCreate =
(UuidCreate_proc) GetProcAddress (hm_rpcrt4, "UuidCreate");
pfn_UuidToString =
(UuidToString_proc) GetProcAddress (hm_rpcrt4, "UuidToStringA");
pfn_RpcStringFree =
(RpcStringFree_proc) GetProcAddress (hm_rpcrt4, "RpcStringFreeA");
if (pfn_UuidCreate && pfn_UuidToString && pfn_RpcStringFree)
rpc_uuid_avail = 1;
else
rpc_uuid_avail = 0;
}
else
rpc_uuid_avail = 0;
}
if (rpc_uuid_avail)
{
BYTE *uuid_str;
UUID uuid;
if (pfn_UuidCreate (&uuid) == RPC_S_OK)
{
if (pfn_UuidToString (&uuid, &uuid_str) == RPC_S_OK)
{
sprintf (urn_str, "<urn:uuid:%s>", uuid_str);
pfn_RpcStringFree (&uuid_str);
return 1;
}
}
}
return 0;
}
#endif
/* Fills urn_str with a UUID based on random numbers in the format
required for the WARC-Record-Id header.
(See RFC 4122, UUID version 4.)
@ -647,6 +703,14 @@ warc_uuid_str (char *urn_str)
unsigned char uuid_data[16];
int i;
#ifdef WINDOWS
/* If the native method fails (expected on older Windows versions),
use the fallback below. */
if (windows_uuid_str (urn_str))
return;
#endif
for (i=0; i<16; i++)
uuid_data[i] = random_number (255);