bug-wget
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-wget] [patch] uuid generation in warc.c


From: Eli Zaretskii
Subject: Re: [Bug-wget] [patch] uuid generation in warc.c
Date: Sat, 14 Feb 2015 13:10:07 +0200

> Date: Wed, 11 Feb 2015 00:15:32 +0100
> From: Gisle Vanem <address@hidden>
> 
>  > Do we still want to support the older Windows NT4 and 9X versions?  If
> > so, we should try loading Rpcrt4.dll dynamically, with LoadLibrary,
> > and if that fails, fall back on the current code.
> 
> Seems this issue is dangling in loose air. It should be fixed
> IMHO.
> 
> Eli, do have any code for a dynamic load of "Rpcrt4.dll"?

The patch I suggest is below.  It uses the fallback method if
Rpcrt4.dll cannot be loaded, or if the functions from that DLL fail
for some reason.

2015-02-14  Eli Zaretskii  <address@hidden>
            Gisle Vanem  <address@hidden>

        * 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.

--- src/warc.c~2        2015-02-14 11:57:50.242875000 +0200
+++ src/warc.c  2015-02-14 12:52:32.656250000 +0200
@@ -60,6 +60,7 @@ as that of the covered work.  */
 #ifdef WINDOWS
 /* we need this on Windows to have O_TEMPORARY defined */
 # include <fcntl.h>
+# include <rpc.h>
 #endif
 
 #include "warc.h"
@@ -623,6 +624,59 @@ warc_uuid_str (char *urn_str)
   sprintf (urn_str, "<urn:uuid:%s>", 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;
+       }
+    }
+
+  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.)
@@ -638,6 +692,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);
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]