gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r24068 - gnunet/src/util


From: gnunet
Subject: [GNUnet-SVN] r24068 - gnunet/src/util
Date: Fri, 28 Sep 2012 11:12:05 +0200

Author: grothoff
Date: 2012-09-28 11:12:05 +0200 (Fri, 28 Sep 2012)
New Revision: 24068

Modified:
   gnunet/src/util/crypto_crc.c
   gnunet/src/util/win.c
Log:
-dos2unix

Modified: gnunet/src/util/crypto_crc.c
===================================================================
--- gnunet/src/util/crypto_crc.c        2012-09-28 07:53:28 UTC (rev 24067)
+++ gnunet/src/util/crypto_crc.c        2012-09-28 09:12:05 UTC (rev 24068)
@@ -27,7 +27,6 @@
  * @brief implementation of CRC16 and CRC32
  * @author Christian Grothoff
  */
-
 #include "platform.h"
 #include "gnunet_common.h"
 #include "gnunet_crypto_lib.h"

Modified: gnunet/src/util/win.c
===================================================================
--- gnunet/src/util/win.c       2012-09-28 07:53:28 UTC (rev 24067)
+++ gnunet/src/util/win.c       2012-09-28 09:12:05 UTC (rev 24068)
@@ -1,1263 +1,1263 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/win.c
- * @brief Helper functions for MS Windows in C++
- * @author Nils Durner
- */
-
-#ifndef _WIN_C
-#define _WIN_C
-
-#include "winproc.h"
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_connection_lib.h"
-
-#include <ntdef.h>
-
-#ifndef INHERITED_ACE
-#define INHERITED_ACE 0x10
-#endif
-
-int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
-
-#define _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
-  union { \
-    struct { \
-      ULONG Length; \
-      DWORD Flags; \
-    }; \
-  }; \
-
-#define _IP_ADAPTER_UNICAST_ADDRESS_BASE \
-  SOCKET_ADDRESS                     Address; \
-  IP_PREFIX_ORIGIN                   PrefixOrigin; \
-  IP_SUFFIX_ORIGIN                   SuffixOrigin; \
-  IP_DAD_STATE                       DadState; \
-  ULONG                              ValidLifetime; \
-  ULONG                              PreferredLifetime; \
-  ULONG                              LeaseLifetime;
-
-#define _IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA \
-  UINT8                              OnLinkPrefixLength;
-
-
-#define _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(suffix,addition) \
-typedef struct _IP_ADAPTER_UNICAST_ADDRESS##suffix { \
-  _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
-  struct _IP_ADAPTER_UNICAST_ADDRESS##suffix *Next; \
-  _IP_ADAPTER_UNICAST_ADDRESS_BASE \
-  addition \
-} IP_ADAPTER_UNICAST_ADDRESS##suffix, *PIP_ADAPTER_UNICAST_ADDRESS##suffix;
-
-/* _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(,) defined in w32api headers */
-_IP_ADAPTER_UNICAST_ADDRESS_DEFINE(_VISTA,_IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA)
-
-
-typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS {
-  union {
-    ULONGLONG Alignment;
-    struct {
-      ULONG Length;
-      DWORD Reserved;
-    };
-  };
-  struct _IP_ADAPTER_WINS_SERVER_ADDRESS  *Next;
-  SOCKET_ADDRESS                         Address;
-} IP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS, 
*PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
-
-typedef struct _IP_ADAPTER_GATEWAY_ADDRESS {
-  union {
-    ULONGLONG Alignment;
-    struct {
-      ULONG Length;
-      DWORD Reserved;
-    };
-  };
-  struct _IP_ADAPTER_GATEWAY_ADDRESS  *Next;
-  SOCKET_ADDRESS                     Address;
-} IP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS, 
*PIP_ADAPTER_GATEWAY_ADDRESS_LH;
-
-typedef UINT32 NET_IF_COMPARTMENT_ID;
-typedef GUID NET_IF_NETWORK_GUID;
-
-typedef enum _NET_IF_CONNECTION_TYPE {
-  NET_IF_CONNECTION_DEDICATED   = 1,
-  NET_IF_CONNECTION_PASSIVE,
-  NET_IF_CONNECTION_DEMAND,
-  NET_IF_CONNECTION_MAXIMUM 
-} NET_IF_CONNECTION_TYPE, *PNET_IF_CONNECTION_TYPE;
-
-typedef enum  {
-  TUNNEL_TYPE_NONE      = 0,
-  TUNNEL_TYPE_OTHER,
-  TUNNEL_TYPE_DIRECT,
-  TUNNEL_TYPE_6TO4,
-  TUNNEL_TYPE_ISATAP,
-  TUNNEL_TYPE_TEREDO,
-  TUNNEL_TYPE_IPHTTPS 
-} TUNNEL_TYPE, *PTUNNEL_TYPE;
-
-/*
-A DUID consists of a two-octet type code represented in network byte
-   order, followed by a variable number of octets that make up the
-   actual identifier.  A DUID can be no more than 128 octets long (not
-   including the type code).
-*/
-#define MAX_DHCPV6_DUID_LENGTH 130
-
-typedef union _NET_LUID {
-  ULONG64 Value;
-  struct {
-    ULONG64 Reserved  :24;
-    ULONG64 NetLuidIndex  :24;
-    ULONG64 IfType  :16;
-  } Info;
-} NET_LUID, *PNET_LUID, IF_LUID;
-
-#define MAX_DNS_SUFFIX_STRING_LENGTH 246
-
-typedef struct _IP_ADAPTER_DNS_SUFFIX {
-  struct _IP_ADAPTER_DNS_SUFFIX  *Next;
-  WCHAR                         String[MAX_DNS_SUFFIX_STRING_LENGTH];
-} IP_ADAPTER_DNS_SUFFIX, *PIP_ADAPTER_DNS_SUFFIX;
-
-
-
-#define _IP_ADAPTER_ADDRESSES_HEAD \
-  union { \
-    ULONGLONG Alignment; \
-    struct { \
-      ULONG Length; \
-      DWORD IfIndex; \
-    }; \
-  };
-
-#define _IP_ADAPTER_ADDRESSES_BASE \
-  PCHAR                              AdapterName; \
-  PIP_ADAPTER_UNICAST_ADDRESS        FirstUnicastAddress; \
-  PIP_ADAPTER_ANYCAST_ADDRESS        FirstAnycastAddress; \
-  PIP_ADAPTER_MULTICAST_ADDRESS      FirstMulticastAddress; \
-  PIP_ADAPTER_DNS_SERVER_ADDRESS     FirstDnsServerAddress; \
-  PWCHAR                             DnsSuffix; \
-  PWCHAR                             Description; \
-  PWCHAR                             FriendlyName; \
-  BYTE                               
PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; \
-  DWORD                              PhysicalAddressLength; \
-  DWORD                              Flags; \
-  DWORD                              Mtu; \
-  DWORD                              IfType; \
-  IF_OPER_STATUS                     OperStatus;
-
-#define _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
-  DWORD                              Ipv6IfIndex; \
-  DWORD                              ZoneIndices[16]; \
-  PIP_ADAPTER_PREFIX                 FirstPrefix; \
-
-
-#define _IP_ADAPTER_ADDRESSES_ADD_VISTA \
-  _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
-  ULONG64                            TransmitLinkSpeed; \
-  ULONG64                            ReceiveLinkSpeed; \
-  PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; \
-  PIP_ADAPTER_GATEWAY_ADDRESS_LH     FirstGatewayAddress; \
-  ULONG                              Ipv4Metric; \
-  ULONG                              Ipv6Metric; \
-  IF_LUID                            Luid; \
-  SOCKET_ADDRESS                     Dhcpv4Server; \
-  NET_IF_COMPARTMENT_ID              CompartmentId; \
-  NET_IF_NETWORK_GUID                NetworkGuid; \
-  NET_IF_CONNECTION_TYPE             ConnectionType; \
-  TUNNEL_TYPE                        TunnelType; \
-  SOCKET_ADDRESS                     Dhcpv6Server; \
-  BYTE                               Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; 
\
-  ULONG                              Dhcpv6ClientDuidLength; \
-  ULONG                              Dhcpv6Iaid;
-
-#define _IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1 \
-  _IP_ADAPTER_ADDRESSES_ADD_VISTA \
-  PIP_ADAPTER_DNS_SUFFIX             FirstDnsSuffix;
-
-#define _IP_ADAPTER_ADDRESSES_DEFINE(suffix,addition) \
-typedef struct _IP_ADAPTER_ADDRESSES##suffix { \
-  _IP_ADAPTER_ADDRESSES_HEAD \
-  struct _IP_ADAPTER_ADDRESSES##suffix *Next; \
-  _IP_ADAPTER_ADDRESSES_BASE \
-  addition \
-} IP_ADAPTER_ADDRESSES##suffix, *PIP_ADAPTER_ADDRESSES##suffix;
-  
-
-/* _IP_ADAPTER_ADDRESSES_DEFINE(,) defined in w32api headers */
-_IP_ADAPTER_ADDRESSES_DEFINE(_XPSP1,_IP_ADAPTER_ADDRESSES_ADD_XPSP1)
-_IP_ADAPTER_ADDRESSES_DEFINE(_VISTA,_IP_ADAPTER_ADDRESSES_ADD_VISTA)
-_IP_ADAPTER_ADDRESSES_DEFINE(_2008_OR_VISTASP1,_IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1)
-
-static int
-EnumNICs_IPv6_get_ifs_count (SOCKET s)
-{
-  DWORD dwret = 0, err;
-  int iret;
-  iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0,
-      &dwret, NULL, NULL);
-  err = GetLastError ();
-  if (iret == SOCKET_ERROR && err == WSAEFAULT)
-    return dwret;
-  else if (iret == 0)
-    return 0;
-  return GNUNET_SYSERR;
-}
-
-static int
-EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size)
-{
-  int iret;
-  DWORD dwret = 0;
-  iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, inf, size,
-      &dwret, NULL, NULL);
-
-  if (iret != 0 || dwret != size)
-  {
-    /* It's supposed to succeed! And size should be the same */
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-#undef GNUNET_malloc
-#define GNUNET_malloc(a) HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY | \
-    HEAP_GENERATE_EXCEPTIONS, a)
-
-#undef GNUNET_free
-#define GNUNET_free(a) HeapFree(GetProcessHeap (), 0, a)
-
-#undef GNUNET_free_non_null
-#define GNUNET_free_non_null(a) do { if ((a) != NULL) GNUNET_free(a); } while 
(0)
-
-static int
-EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size)
-{
-  int iret;
-  DWORD dwret = 0;
-  DWORD error;
-  INTERFACE_INFO *ii = NULL;
-  DWORD ii_size = sizeof (INTERFACE_INFO) * 15;
-  while (TRUE)
-  {
-    if (ii_size >= sizeof (INTERFACE_INFO) * 1000)
-      return GNUNET_SYSERR;
-    ii = (INTERFACE_INFO *) GNUNET_malloc (ii_size);
-    dwret = 0;
-    iret = WSAIoctl (s, SIO_GET_INTERFACE_LIST, NULL, 0, ii, ii_size,
-        &dwret, NULL, NULL);
-    error = GetLastError ();
-    if (iret == SOCKET_ERROR)
-    {
-      if (error == WSAEFAULT)
-      {
-        GNUNET_free (ii);
-        ii_size *= 2;
-        continue;
-      }
-      GNUNET_free (ii);
-      return GNUNET_SYSERR;
-    }
-    else
-    {
-      *inf = ii;
-      *size = dwret;
-      return GNUNET_OK;
-    }
-  }
-  return GNUNET_SYSERR;
-}
-
-int
-EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6)
-{
-  int result = 0;
-  SOCKET s4 = INVALID_SOCKET, s6 = INVALID_SOCKET;
-  DWORD dwret1 = 0, dwret2;
-  DWORD err1, err2;
-  int ifs4len = 0, ifs6len = 0;
-  INTERFACE_INFO *interfaces4 = NULL;
-  SOCKET_ADDRESS_LIST *interfaces6 = NULL;
-  SetLastError (0);
-  s4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-  err1 = GetLastError ();
-  SetLastError (0);
-  s6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
-  err2 = GetLastError ();
-  if (s6 != INVALID_SOCKET)
-  {
-    ifs6len = EnumNICs_IPv6_get_ifs_count (s6);
-    if (ifs6len > 0)
-    {
-      interfaces6 = (SOCKET_ADDRESS_LIST *) GNUNET_malloc (ifs6len);
-      result = EnumNICs_IPv6_get_ifs (s6, interfaces6, ifs6len) || result;
-    }
-    closesocket (s6);
-    s6 = INVALID_SOCKET;
-  }
-
-  if (s4 != INVALID_SOCKET)
-  {
-    result = EnumNICs_IPv4_get_ifs (s4, &interfaces4, &ifs4len) || result;
-    closesocket (s4);
-    s4 = INVALID_SOCKET;
-  }
-  if (ifs6len + ifs4len == 0)
-    goto error;
-
-  if (!result)
-  {
-    *ifs4 = interfaces4;
-    *ifs4_len = ifs4len;
-    *ifs6 = interfaces6;
-    return GNUNET_OK;
-  }
-error:
-  if (interfaces4 != NULL)
-    GNUNET_free (interfaces4);
-  if (interfaces6 != NULL)
-    GNUNET_free (interfaces6);
-  if (s4 != INVALID_SOCKET)
-    closesocket (s4);
-  if (s6 != INVALID_SOCKET)
-    closesocket (s6);
-  return GNUNET_SYSERR;
-}
-
-/**
- * Returns GNUNET_OK on OK, GNUNET_SYSERR on error
- */
-int
-EnumNICs3 (struct EnumNICs3_results **results, int *results_count)
-{
-  DWORD dwRetVal = 0;
-  int count = 0;
-  ULONG flags = /*GAA_FLAG_INCLUDE_PREFIX |*/ GAA_FLAG_SKIP_ANYCAST |
-      GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
-  struct sockaddr_in6 examplecom6;
-  IPAddr examplecom;
-  DWORD best_interface = 0;
-  DWORD best_interface6 = 0;
-
-  int use_enum2 = 0;
-  INTERFACE_INFO *interfaces4 = NULL;
-  int interfaces4_len = 0;
-  SOCKET_ADDRESS_LIST *interfaces6 = NULL;
-
-  unsigned long outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
-  IP_ADAPTER_ADDRESSES *pCurrentAddress = NULL;
-  IP_ADAPTER_ADDRESSES *pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc 
(outBufLen);
-
-  if (GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen)
-      == ERROR_BUFFER_OVERFLOW)
-  {
-    GNUNET_free (pAddresses);
-    pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen);
-  }
-
-  dwRetVal = GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, 
&outBufLen);
-
-  if (dwRetVal != NO_ERROR)
-  {
-    GNUNET_free (pAddresses);
-    return GNUNET_SYSERR;
-  }
-
-  if (pAddresses->Length < sizeof (IP_ADAPTER_ADDRESSES_VISTA))
-  {
-    use_enum2 = 1;
-
-    /* Enumerate NICs using WSAIoctl() */
-    if (GNUNET_OK != EnumNICs2 (&interfaces4, &interfaces4_len, &interfaces6))
-    {
-      GNUNET_free (pAddresses);
-      return GNUNET_SYSERR;
-    }
-  }
-
-  examplecom = inet_addr("192.0.34.166"); /* www.example.com */
-  if (GetBestInterface (examplecom, &best_interface) != NO_ERROR)
-    best_interface = 0;
-
-  if (GNGetBestInterfaceEx != NULL)
-  {
-    examplecom6.sin6_family = AF_INET6;
-    examplecom6.sin6_port = 0;
-    examplecom6.sin6_flowinfo = 0;
-    examplecom6.sin6_scope_id = 0;
-    inet_pton (AF_INET6, "2001:500:88:200:0:0:0:10",
-        (struct sockaddr *) &examplecom6.sin6_addr);
-    dwRetVal = GNGetBestInterfaceEx ((struct sockaddr *) &examplecom6,
-        &best_interface6);
-    if (dwRetVal != NO_ERROR)
-      best_interface6 = 0;
-  }
-
-  /* Give IPv6 a priority */
-  if (best_interface6 != 0)
-    best_interface = best_interface6;
-
-  count = 0;
-  for (pCurrentAddress = pAddresses;
-      pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
-  {
-    if (pCurrentAddress->OperStatus == IfOperStatusUp)
-    {
-      IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
-      for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
-          unicast = unicast->Next)
-      {
-        if ((unicast->Address.lpSockaddr->sa_family == AF_INET ||
-            unicast->Address.lpSockaddr->sa_family == AF_INET6) &&
-            (unicast->DadState == IpDadStateDeprecated ||
-            unicast->DadState == IpDadStatePreferred))
-          count += 1;
-      }
-    }
-  }
-
-  if (count == 0)
-  {
-    *results = NULL;
-    *results_count = 0;
-    GNUNET_free (pAddresses);
-    GNUNET_free_non_null (interfaces4);
-    GNUNET_free_non_null (interfaces6);
-    return GNUNET_OK;
-  }
-
-  *results = (struct EnumNICs3_results *) GNUNET_malloc (
-      sizeof (struct EnumNICs3_results) * count);
-  *results_count = count;
-
-  count = 0;
-  for (pCurrentAddress = pAddresses;
-      pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
-  {
-    struct EnumNICs3_results *r;
-    IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
-    if (pCurrentAddress->OperStatus != IfOperStatusUp)
-      continue;
-    for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
-        unicast = unicast->Next)
-    {
-      int i, j;
-      int mask_length = -1;
-      char dst[INET6_ADDRSTRLEN + 1];
-
-      if ((unicast->Address.lpSockaddr->sa_family != AF_INET &&
-          unicast->Address.lpSockaddr->sa_family != AF_INET6) ||
-          (unicast->DadState != IpDadStateDeprecated &&
-          unicast->DadState != IpDadStatePreferred))
-        continue;
-
-      r = &(*results)[count];
-      r->flags = 0;
-      if (pCurrentAddress->IfIndex > 0 &&
-          pCurrentAddress->IfIndex == best_interface &&
-          unicast->Address.lpSockaddr->sa_family == AF_INET)
-        r->is_default = 1;
-      else if (pCurrentAddress->Ipv6IfIndex > 0 &&
-          pCurrentAddress->Ipv6IfIndex == best_interface6 &&
-          unicast->Address.lpSockaddr->sa_family == AF_INET6)
-        r->is_default = 1;
-      else
-        r->is_default = 0;
-
-      /* Don't choose default interface twice */
-      if (r->is_default)
-        best_interface = best_interface6 = 0;
-
-      if (!use_enum2)
-      {
-        memcpy (&r->address, unicast->Address.lpSockaddr,
-            unicast->Address.iSockaddrLength);
-        memset (&r->mask, 0, sizeof (struct sockaddr));
-        mask_length = ((IP_ADAPTER_UNICAST_ADDRESS_VISTA *) unicast)->
-              OnLinkPrefixLength;
-        /* OnLinkPrefixLength is the number of leading 1s in the mask.
-         * OnLinkPrefixLength is available on Vista and later (hence 
use_enum2).
-         */
-        if (unicast->Address.lpSockaddr->sa_family == AF_INET)
-        {
-          struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
-          for (i = 0; i < mask_length; i++)
-              ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
-        }
-        else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
-        {
-          struct sockaddr_in6 *m = (struct sockaddr_in6 *) &r->mask;
-          struct sockaddr_in6 *b = (struct sockaddr_in6 *) &r->broadcast;
-          for (i = 0; i < mask_length; i++)
-            ((unsigned char *) &m->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
-          memcpy (&r->broadcast, &r->address, 
unicast->Address.iSockaddrLength);
-          for (i = mask_length; i < 128; i++)
-            ((unsigned char *) &b->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
-        }
-        r->flags |= ENUMNICS3_MASK_OK;
-      }
-      else
-      {
-        int found = 0;
-        if (unicast->Address.lpSockaddr->sa_family == AF_INET)
-        {
-          for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); 
i++)
-          {
-            struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
-            if (memcpy (&interfaces4[i].iiAddress.Address,
-                unicast->Address.lpSockaddr,
-                unicast->Address.iSockaddrLength) != 0)
-              continue;
-            found = 1;
-            memcpy (&r->address, &interfaces4[i].iiAddress.Address,
-                sizeof (struct sockaddr_in));
-            memcpy (&r->mask, &interfaces4[i].iiNetmask.Address,
-                sizeof (struct sockaddr_in));
-            for (mask_length = 0;
-                ((unsigned char *) &m->sin_addr)[mask_length / 8] &
-                0x80 >> (mask_length % 8); mask_length++)
-            {
-            }
-            r->flags |= ENUMNICS3_MASK_OK;
-          }
-        }
-        else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
-        {
-          for (i = 0;
-              interfaces6 != NULL && !found && i < interfaces6->iAddressCount;
-              i++)
-          {
-            if (memcpy (interfaces6->Address[i].lpSockaddr,
-                unicast->Address.lpSockaddr,
-                unicast->Address.iSockaddrLength) != 0)
-              continue;
-            found = 1;
-            memcpy (&r->address, interfaces6->Address[i].lpSockaddr,
-                sizeof (struct sockaddr_in6));
-            /* TODO: Find a way to reliably get network mask for IPv6 on XP */
-            memset (&r->mask, 0, sizeof (struct sockaddr));
-            r->flags &= ~ENUMNICS3_MASK_OK;
-          }
-        }
-        if (!found)
-        {
-          DebugBreak ();
-        }
-      }
-      if (unicast->Address.lpSockaddr->sa_family == AF_INET)
-      {
-        struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
-        struct sockaddr_in *a = (struct sockaddr_in *) &r->address;
-        /* copy address to broadcast, then flip all the trailing bits not
-         * falling under netmask to 1,
-         * so we get, 192.168.0.255 from, say, 192.168.0.43 with mask == 24.
-         */
-        memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength);
-        for (i = mask_length; i < 32; i++)
-          ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
-        r->flags |= ENUMNICS3_BCAST_OK;
-        r->addr_size = sizeof (struct sockaddr_in);
-        inet_ntop (AF_INET, &a->sin_addr, dst, INET_ADDRSTRLEN);
-      }
-      else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
-      {
-        struct sockaddr_in6 *a = (struct sockaddr_in6 *) &r->address;
-        /* for IPv6 broadcast is not defined, zero it down */
-        memset (&r->broadcast, 0, sizeof (struct sockaddr));
-        r->flags &= ~ENUMNICS3_BCAST_OK;
-        r->addr_size = sizeof (struct sockaddr_in6);
-        inet_ntop (AF_INET6, &a->sin6_addr, dst, INET6_ADDRSTRLEN);
-      }
-
-      i = 0;
-      i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
-          "%S (%s", pCurrentAddress->FriendlyName, dst);
-      for (j = 0; j < pCurrentAddress->PhysicalAddressLength; j++)
-        i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
-            "%s%02X",j > 0 ? ":" : " - ", pCurrentAddress->PhysicalAddress[j]);
-      i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, ")");
-      r->pretty_name[1000] = '\0';
-      count += 1;
-    }
-  }
-
-  if (use_enum2)
-  {
-    GNUNET_free_non_null (interfaces4);
-    GNUNET_free_non_null (interfaces6);
-  }
-
-  GNUNET_free (pAddresses);
-  return GNUNET_OK;
-}
-
-void
-EnumNICs3_free (struct EnumNICs3_results *r)
-{
-  GNUNET_free_non_null (r);
-}
-
-
-/**
- * Lists all network interfaces in a combo box
- * Used by the basic GTK configurator
- *
- * @param callback function to call for each NIC
- * @param callback_cls closure for callback
- */
-int
-ListNICs (void (*callback) (void *, const char *, int), void * callback_cls)
-{
-  int r;
-  int i;
-  struct EnumNICs3_results *results = NULL;
-  int results_count;
-
-  r = EnumNICs3 (&results, &results_count);
-  if (r != GNUNET_OK)
-    return GNUNET_NO;
-
-  for (i = 0; i < results_count; i++)
-    callback (callback_cls, results[i].pretty_name, results[i].is_default);
-  GNUNET_free_non_null (results);
-  return GNUNET_YES;
-}
-
-/**
- * @brief Installs the Windows service
- * @param servicename name of the service as diplayed by the SCM
- * @param application path to the application binary
- * @param username the name of the service's user account
- * @returns 0 on success
- *          1 if the Windows version doesn't support services
- *          2 if the SCM could not be opened
- *          3 if the service could not be created
- */
-int InstallAsService(char *servicename, char *application, char *username)
-{
-  SC_HANDLE hManager, hService;
-  char szEXE[_MAX_PATH + 17] = "\"";
-  char *user = NULL;
-
-  if (! GNOpenSCManager)
-    return 1;
-
-  plibc_conv_to_win_path(application, szEXE + 1);
-  strcat(szEXE, "\" --win-service");
-  hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
-  if (! hManager)
-    return 2;
-
-  if (username)
-  {
-       user = (char *) malloc(strlen(username) + 3);
-       sprintf(user, ".\\%s", username);
-  }
-
-  hService = GNCreateService(hManager, (LPCTSTR) servicename, (LPCTSTR) 
servicename, 0,
-    SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, 
(LPCTSTR) szEXE,
-    NULL, NULL, NULL, (LPCTSTR) user, (LPCTSTR) username);
-
-  if (user)
-    free(user);
-
-  if (! hService)
-    return 3;
-
-  GNCloseServiceHandle(hService);
-
-  return 0;
-}
-
-/**
- * @brief Uninstall Windows service
- * @param servicename name of the service to delete
- * @returns 0 on success
- *          1 if the Windows version doesn't support services
- *          2 if the SCM could not be openend
- *          3 if the service cannot be accessed
- *          4 if the service cannot be deleted
- */
-int UninstallService(char *servicename)
-{
-  SC_HANDLE hManager, hService;
-
-  if (! GNOpenSCManager)
-    return 1;
-
-  hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
-  if (! hManager)
-    return 2;
-
-  if (! (hService = GNOpenService(hManager, (LPCTSTR) servicename, DELETE)))
-    if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
-      return 3;
-     else
-       goto closeSCM;
-
-  if (! GNDeleteService(hService))
-    if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE)
-      return 4;
-
-closeSCM:
-  GNCloseServiceHandle(hService);
-
-  return 0;
-}
-
-/**
- * @author Scott Field, Microsoft
- * @see http://support.microsoft.com/?scid=kb;en-us;132958
- * @date 12-Jul-95
- */
-void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
-{
-  DWORD StringLength;
-
-  if(String == NULL)
-  {
-    LsaString->Buffer = NULL;
-    LsaString->Length = 0;
-    LsaString->MaximumLength = 0;
-    return;
-  }
-
-  StringLength = wcslen(String);
-  LsaString->Buffer = String;
-  LsaString->Length = (USHORT) StringLength *sizeof(WCHAR);
-  LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR);
-}
-
-
-/**
- * @author Scott Field, Microsoft
- * @see http://support.microsoft.com/?scid=kb;en-us;132958
- * @date 12-Jul-95
- */
-NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE 
PolicyHandle)
-{
-  LSA_OBJECT_ATTRIBUTES ObjectAttributes;
-  LSA_UNICODE_STRING ServerString;
-  PLSA_UNICODE_STRING Server = NULL;
-
-  /* Always initialize the object attributes to all zeroes. */
-  ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
-
-  if(ServerName != NULL)
-  {
-    /* Make a LSA_UNICODE_STRING out of the LPWSTR passed in */
-    _InitLsaString(&ServerString, ServerName);
-    Server = &ServerString;
-  }
-
-  /* Attempt to open the policy. */
-  return GNLsaOpenPolicy(Server,
-                       &ObjectAttributes, DesiredAccess, PolicyHandle);
-}
-
-/**
- * @brief Obtain a SID representing the supplied account on the supplied system
- * @return TRUE on success, FALSE on failure
- * @author Scott Field, Microsoft
- * @date 12-Jul-95
- * @remarks A buffer is allocated which contains the SID representing the
- *          supplied account. This buffer should be freed when it is no longer
- *          needed by calling\n
- *            HeapFree(GetProcessHeap(), 0, buffer)
- * @remarks Call GetLastError() to obtain extended error information.
- * @see http://support.microsoft.com/?scid=kb;en-us;132958
- */
-BOOL _GetAccountSid(LPCTSTR SystemName, LPCTSTR AccountName, PSID * Sid)
-{
-  LPTSTR ReferencedDomain = NULL;
-  DWORD cbSid = 128;                                                   /* 
initial allocation attempt */
-  DWORD cchReferencedDomain = 16;      /* initial allocation size */
-  SID_NAME_USE peUse;
-  BOOL bSuccess = FALSE;                                       /* assume this 
function will fail */
-
-  /* initial memory allocations */
-  if ((*Sid = HeapAlloc (GetProcessHeap (), 0, cbSid)) == NULL)
-       return FALSE;
-
-  if ((ReferencedDomain = (LPTSTR) HeapAlloc (GetProcessHeap (),
-                                   0,
-                                   cchReferencedDomain *
-                                   sizeof (TCHAR))) == NULL)
-       return FALSE;
-
-    /* Obtain the SID of the specified account on the specified system. */
-       while (!GNLookupAccountName(SystemName, /* machine to lookup account on 
*/
-                  AccountName,                                                 
                                        /* account to lookup */
-                  *Sid,                                                        
                                                                /* SID of 
interest */
-                  &cbSid,                                                      
                                                        /* size of SID */
-                  ReferencedDomain,                                            
                        /* domain account was found on */
-                  &cchReferencedDomain, &peUse))
-       {
-               if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-               {
-                       /* reallocate memory */
-                       if ((*Sid = HeapReAlloc (GetProcessHeap (), 0, *Sid, 
cbSid)) == NULL)
-                               return FALSE;
-
-                       if ((ReferencedDomain = (LPTSTR) HeapReAlloc 
(GetProcessHeap (),
-                                             0,
-                                             ReferencedDomain,
-                                             cchReferencedDomain
-                                             * sizeof (TCHAR))) == NULL)
-                               return FALSE;
-      }
-      else
-        goto end;
-  }
-
-  /* Indicate success. */
-  bSuccess = TRUE;
-
-end:
-  /* Cleanup and indicate failure, if appropriate. */
-  HeapFree (GetProcessHeap (), 0, ReferencedDomain);
-
-  if (!bSuccess)
-  {
-    if (*Sid != NULL)
-    {
-               HeapFree (GetProcessHeap (), 0, *Sid);
-               *Sid = NULL;
-    }
-  }
-
-  return bSuccess;
-}
-
-/**
- * @author Scott Field, Microsoft
- * @see http://support.microsoft.com/?scid=kb;en-us;132958
- * @date 12-Jul-95
- */
-NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle 
*/
-                               PSID AccountSid,                        /* SID 
to grant privilege to */
-                               LPWSTR PrivilegeName,   /* privilege to grant 
(Unicode) */
-                               BOOL bEnable                                    
        /* enable or disable */
-  )
-{
-  LSA_UNICODE_STRING PrivilegeString;
-
-  /* Create a LSA_UNICODE_STRING for the privilege name. */
-  _InitLsaString(&PrivilegeString, PrivilegeName);
-
-  /* grant or revoke the privilege, accordingly */
-  if(bEnable)
-  {
-    NTSTATUS i;
-
-    i = GNLsaAddAccountRights(PolicyHandle,                            /* open 
policy handle */
-                               AccountSid,                             /* 
target SID */
-                               &PrivilegeString,        /* privileges */
-                               1                                               
                                        /* privilege count */
-      );
-  }
-  else
-  {
-    return GNLsaRemoveAccountRights(PolicyHandle,                      /* open 
policy handle */
-                                  AccountSid,                          /* 
target SID */
-                                  FALSE,                                       
                /* do not disable all rights */
-                                  &PrivilegeString,            /* privileges */
-                                  1                                            
                                /* privilege count */
-      );
-  }
-}
-
-/**
- * @brief Create a Windows service account
- * @return 0 on success, > 0 otherwise
- * @param pszName the name of the account
- * @param pszDesc description of the account
- */
-int CreateServiceAccount(const char *pszName, const char *pszDesc)
-{
-  USER_INFO_1 ui;
-  USER_INFO_1008 ui2;
-  NET_API_STATUS nStatus;
-  wchar_t wszName[MAX_NAME_LENGTH], wszDesc[MAX_NAME_LENGTH];
-  DWORD dwErr;
-  LSA_HANDLE hPolicy;
-  PSID pSID;
-
-  if (! GNNetUserAdd)
-       return 1;
-  mbstowcs(wszName, pszName, strlen(pszName) + 1);
-  mbstowcs(wszDesc, pszDesc, strlen(pszDesc) + 1);
-
-  memset(&ui, 0, sizeof(ui));
-  ui.usri1_name = wszName;
-  ui.usri1_password = wszName; /* account is locked anyway */
-  ui.usri1_priv = USER_PRIV_USER;
-  ui.usri1_comment = wszDesc;
-  ui.usri1_flags = UF_SCRIPT;
-
-  nStatus = GNNetUserAdd(NULL, 1, (LPBYTE)&ui, NULL);
-
-  if (nStatus != NERR_Success && nStatus != NERR_UserExists)
-       return 2;
-
-  ui2.usri1008_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
-  GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL);
-
-  if (_OpenPolicy(NULL, POLICY_ALL_ACCESS, &hPolicy) !=
-                                                                               
STATUS_SUCCESS)
-       return 3;
-
-  _GetAccountSid(NULL, (LPCTSTR) pszName, &pSID);
-
-  if (_SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeServiceLogonRight", 
TRUE) != STATUS_SUCCESS)
-       return 4;
-
-  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) 
L"SeDenyInteractiveLogonRight", TRUE);
-  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyBatchLogonRight", 
TRUE);
-  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyNetworkLogonRight", 
TRUE);
-
-  GNLsaClose(hPolicy);
-
-  return 0;
-}
-
-/**
- * @brief Grant permission to a file
- * @param lpszFileName the name of the file or directory
- * @param lpszAccountName the user account
- * @param dwAccessMask the desired access (e.g. GENERIC_ALL)
- * @return TRUE on success
- * @remark based on 
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102&;
- */
-BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
-      DWORD dwAccessMask)
-{
-  /* SID variables. */
-  SID_NAME_USE   snuType;
-  TCHAR *        szDomain       = NULL;
-  DWORD          cbDomain       = 0;
-  LPVOID         pUserSID       = NULL;
-  DWORD          cbUserSID      = 0;
-
-  /* File SD variables. */
-  PSECURITY_DESCRIPTOR pFileSD  = NULL;
-  DWORD          cbFileSD       = 0;
-
-  /* New SD variables. */
-  SECURITY_DESCRIPTOR  newSD;
-
-  /* ACL variables. */
-  PACL           pACL           = NULL;
-  BOOL           fDaclPresent;
-  BOOL           fDaclDefaulted;
-  ACL_SIZE_INFORMATION AclInfo;
-
-  /* New ACL variables. */
-  PACL           pNewACL        = NULL;
-  DWORD          cbNewACL       = 0;
-
-  /* Temporary ACE. */
-  LPVOID         pTempAce       = NULL;
-  UINT           CurrentAceIndex = 0;
-
-  UINT           newAceIndex = 0;
-
-  /* Assume function will fail. */
-  BOOL           fResult        = FALSE;
-  BOOL           fAPISuccess;
-
-  SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
-
-  /**
-   * STEP 1: Get SID of the account name specified.
-   */
-  fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
-        pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
-
-  /* API should have failed with insufficient buffer. */
-  if (fAPISuccess)
-     goto end;
-  else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-     goto end;
-  }
-
-  pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID);
-  if (!pUserSID) {
-     goto end;
-  }
-
-  szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDomain 
* sizeof(TCHAR));
-  if (!szDomain) {
-     goto end;
-  }
-
-  fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
-        pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
-  if (!fAPISuccess) {
-     goto end;
-  }
-
-  /**
-   *  STEP 2: Get security descriptor (SD) of the file specified.
-   */
-  fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
-        secInfo, pFileSD, 0, &cbFileSD);
-
-  /* API should have failed with insufficient buffer. */
-  if (fAPISuccess)
-     goto end;
-  else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-     goto end;
-  }
-
-  pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), 
HEAP_ZERO_MEMORY,
-       cbFileSD);
-  if (!pFileSD) {
-     goto end;
-  }
-
-  fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
-        secInfo, pFileSD, cbFileSD, &cbFileSD);
-  if (!fAPISuccess) {
-     goto end;
-  }
-
-  /**
-   * STEP 3: Initialize new SD.
-   */
-  if (!GNInitializeSecurityDescriptor(&newSD,
-        SECURITY_DESCRIPTOR_REVISION)) {
-     goto end;
-  }
-
-  /**
-   * STEP 4: Get DACL from the old SD.
-   */
-  if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
-        &fDaclDefaulted)) {
-     goto end;
-  }
-
-  /**
-   * STEP 5: Get size information for DACL.
-   */
-  AclInfo.AceCount = 0; // Assume NULL DACL.
-  AclInfo.AclBytesFree = 0;
-  AclInfo.AclBytesInUse = sizeof(ACL);
-
-  if (pACL == NULL)
-     fDaclPresent = FALSE;
-
-  /* If not NULL DACL, gather size information from DACL. */
-  if (fDaclPresent) {
-
-     if (!GNGetAclInformation(pACL, &AclInfo,
-           sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
-        goto end;
-     }
-  }
-
-  /**
-   * STEP 6: Compute size needed for the new ACL.
-   */
-  cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
-        + GetLengthSid(pUserSID) - sizeof(DWORD);
-
-  /**
-   * STEP 7: Allocate memory for new ACL.
-   */
-  pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL);
-  if (!pNewACL) {
-     goto end;
-  }
-
-  /**
-   * STEP 8: Initialize the new ACL.
-   */
-  if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
-     goto end;
-  }
-
-  /**
-   * STEP 9 If DACL is present, copy all the ACEs from the old DACL
-   * to the new DACL.
-   *
-   * The following code assumes that the old DACL is
-   * already in Windows 2000 preferred order.  To conform
-   * to the new Windows 2000 preferred order, first we will
-   * copy all non-inherited ACEs from the old DACL to the
-   * new DACL, irrespective of the ACE type.
-   */
-
-  newAceIndex = 0;
-
-  if (fDaclPresent && AclInfo.AceCount) {
-
-     for (CurrentAceIndex = 0;
-           CurrentAceIndex < AclInfo.AceCount;
-           CurrentAceIndex++) {
-
-        /**
-         * TEP 10: Get an ACE.
-         */
-        if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
-           goto end;
-        }
-
-        /**
-         * STEP 11: Check if it is a non-inherited ACE.
-         * If it is an inherited ACE, break from the loop so
-         * that the new access allowed non-inherited ACE can
-         * be added in the correct position, immediately after
-         * all non-inherited ACEs.
-         */
-        if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
-           & INHERITED_ACE)
-           break;
-
-        /**
-         * STEP 12: Skip adding the ACE, if the SID matches
-         * with the account specified, as we are going to
-         * add an access allowed ACE with a different access
-         * mask.
-         */
-        if (GNEqualSid(pUserSID,
-           &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
-           continue;
-
-        /**
-         * STEP 13: Add the ACE to the new ACL.
-         */
-        if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
-              ((PACE_HEADER) pTempAce)->AceSize)) {
-           goto end;
-        }
-
-        newAceIndex++;
-     }
-  }
-
-  /**
-   * STEP 14: Add the access-allowed ACE to the new DACL.
-   * The new ACE added here will be in the correct position,
-   * immediately after all existing non-inherited ACEs.
-   */
-  if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
-        pUserSID)) {
-     goto end;
-  }
-
-  /**
-   * STEP 14.5: Make new ACE inheritable
-   */
-  if (!GetAce(pNewACL, newAceIndex, &pTempAce))
-    goto end;
-  ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |=
-    (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
-
-  /**
-   * STEP 15: To conform to the new Windows 2000 preferred order,
-   * we will now copy the rest of inherited ACEs from the
-   * old DACL to the new DACL.
-   */
-  if (fDaclPresent && AclInfo.AceCount) {
-
-     for (;
-          CurrentAceIndex < AclInfo.AceCount;
-          CurrentAceIndex++) {
-
-        /**
-         * STEP 16: Get an ACE.
-         */
-        if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
-           goto end;
-        }
-
-        /**
-         * STEP 17: Add the ACE to the new ACL.
-         */
-        if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
-              ((PACE_HEADER) pTempAce)->AceSize)) {
-           goto end;
-        }
-     }
-  }
-
-  /**
-   * STEP 18: Set permissions
-   */
-  if (GNSetNamedSecurityInfo((LPTSTR) lpszFileName, SE_FILE_OBJECT,
-    DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) {
-       goto end;
-  }
-
-  fResult = TRUE;
-
-end:
-
-  /**
-   * STEP 19: Free allocated memory
-   */
-  if (pUserSID)
-     HeapFree(GetProcessHeap(), 0, pUserSID);
-
-  if (szDomain)
-     HeapFree(GetProcessHeap(), 0, szDomain);
-
-  if (pFileSD)
-     HeapFree(GetProcessHeap(), 0, pFileSD);
-
-  if (pNewACL)
-     HeapFree(GetProcessHeap(), 0, pNewACL);
-
-  return fResult;
-}
-
-char *winErrorStr(const char *prefix, int dwErr)
-{
-  char *err, *ret;
-  int mem;
-
-  if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM,
-    NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) 
&err,
-    0, NULL ))
-  {
-    err = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, 1);
-  }
-
-  mem = strlen(err) + strlen(prefix) + 20;
-  ret = (char *) malloc(mem);
-
-  snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
-
-  LocalFree(err);
-
-  return ret;
-}
-
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
 /**
+ * @file util/win.c
+ * @brief Helper functions for MS Windows in C++
+ * @author Nils Durner
+ */
+
+#ifndef _WIN_C
+#define _WIN_C
+
+#include "winproc.h"
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_connection_lib.h"
+
+#include <ntdef.h>
+
+#ifndef INHERITED_ACE
+#define INHERITED_ACE 0x10
+#endif
+
+int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
+
+#define _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
+  union { \
+    struct { \
+      ULONG Length; \
+      DWORD Flags; \
+    }; \
+  }; \
+
+#define _IP_ADAPTER_UNICAST_ADDRESS_BASE \
+  SOCKET_ADDRESS                     Address; \
+  IP_PREFIX_ORIGIN                   PrefixOrigin; \
+  IP_SUFFIX_ORIGIN                   SuffixOrigin; \
+  IP_DAD_STATE                       DadState; \
+  ULONG                              ValidLifetime; \
+  ULONG                              PreferredLifetime; \
+  ULONG                              LeaseLifetime;
+
+#define _IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA \
+  UINT8                              OnLinkPrefixLength;
+
+
+#define _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(suffix,addition) \
+typedef struct _IP_ADAPTER_UNICAST_ADDRESS##suffix { \
+  _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
+  struct _IP_ADAPTER_UNICAST_ADDRESS##suffix *Next; \
+  _IP_ADAPTER_UNICAST_ADDRESS_BASE \
+  addition \
+} IP_ADAPTER_UNICAST_ADDRESS##suffix, *PIP_ADAPTER_UNICAST_ADDRESS##suffix;
+
+/* _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(,) defined in w32api headers */
+_IP_ADAPTER_UNICAST_ADDRESS_DEFINE(_VISTA,_IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA)
+
+
+typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS {
+  union {
+    ULONGLONG Alignment;
+    struct {
+      ULONG Length;
+      DWORD Reserved;
+    };
+  };
+  struct _IP_ADAPTER_WINS_SERVER_ADDRESS  *Next;
+  SOCKET_ADDRESS                         Address;
+} IP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS, 
*PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
+
+typedef struct _IP_ADAPTER_GATEWAY_ADDRESS {
+  union {
+    ULONGLONG Alignment;
+    struct {
+      ULONG Length;
+      DWORD Reserved;
+    };
+  };
+  struct _IP_ADAPTER_GATEWAY_ADDRESS  *Next;
+  SOCKET_ADDRESS                     Address;
+} IP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS, 
*PIP_ADAPTER_GATEWAY_ADDRESS_LH;
+
+typedef UINT32 NET_IF_COMPARTMENT_ID;
+typedef GUID NET_IF_NETWORK_GUID;
+
+typedef enum _NET_IF_CONNECTION_TYPE {
+  NET_IF_CONNECTION_DEDICATED   = 1,
+  NET_IF_CONNECTION_PASSIVE,
+  NET_IF_CONNECTION_DEMAND,
+  NET_IF_CONNECTION_MAXIMUM 
+} NET_IF_CONNECTION_TYPE, *PNET_IF_CONNECTION_TYPE;
+
+typedef enum  {
+  TUNNEL_TYPE_NONE      = 0,
+  TUNNEL_TYPE_OTHER,
+  TUNNEL_TYPE_DIRECT,
+  TUNNEL_TYPE_6TO4,
+  TUNNEL_TYPE_ISATAP,
+  TUNNEL_TYPE_TEREDO,
+  TUNNEL_TYPE_IPHTTPS 
+} TUNNEL_TYPE, *PTUNNEL_TYPE;
+
+/*
+A DUID consists of a two-octet type code represented in network byte
+   order, followed by a variable number of octets that make up the
+   actual identifier.  A DUID can be no more than 128 octets long (not
+   including the type code).
+*/
+#define MAX_DHCPV6_DUID_LENGTH 130
+
+typedef union _NET_LUID {
+  ULONG64 Value;
+  struct {
+    ULONG64 Reserved  :24;
+    ULONG64 NetLuidIndex  :24;
+    ULONG64 IfType  :16;
+  } Info;
+} NET_LUID, *PNET_LUID, IF_LUID;
+
+#define MAX_DNS_SUFFIX_STRING_LENGTH 246
+
+typedef struct _IP_ADAPTER_DNS_SUFFIX {
+  struct _IP_ADAPTER_DNS_SUFFIX  *Next;
+  WCHAR                         String[MAX_DNS_SUFFIX_STRING_LENGTH];
+} IP_ADAPTER_DNS_SUFFIX, *PIP_ADAPTER_DNS_SUFFIX;
+
+
+
+#define _IP_ADAPTER_ADDRESSES_HEAD \
+  union { \
+    ULONGLONG Alignment; \
+    struct { \
+      ULONG Length; \
+      DWORD IfIndex; \
+    }; \
+  };
+
+#define _IP_ADAPTER_ADDRESSES_BASE \
+  PCHAR                              AdapterName; \
+  PIP_ADAPTER_UNICAST_ADDRESS        FirstUnicastAddress; \
+  PIP_ADAPTER_ANYCAST_ADDRESS        FirstAnycastAddress; \
+  PIP_ADAPTER_MULTICAST_ADDRESS      FirstMulticastAddress; \
+  PIP_ADAPTER_DNS_SERVER_ADDRESS     FirstDnsServerAddress; \
+  PWCHAR                             DnsSuffix; \
+  PWCHAR                             Description; \
+  PWCHAR                             FriendlyName; \
+  BYTE                               
PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; \
+  DWORD                              PhysicalAddressLength; \
+  DWORD                              Flags; \
+  DWORD                              Mtu; \
+  DWORD                              IfType; \
+  IF_OPER_STATUS                     OperStatus;
+
+#define _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
+  DWORD                              Ipv6IfIndex; \
+  DWORD                              ZoneIndices[16]; \
+  PIP_ADAPTER_PREFIX                 FirstPrefix; \
+
+
+#define _IP_ADAPTER_ADDRESSES_ADD_VISTA \
+  _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
+  ULONG64                            TransmitLinkSpeed; \
+  ULONG64                            ReceiveLinkSpeed; \
+  PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; \
+  PIP_ADAPTER_GATEWAY_ADDRESS_LH     FirstGatewayAddress; \
+  ULONG                              Ipv4Metric; \
+  ULONG                              Ipv6Metric; \
+  IF_LUID                            Luid; \
+  SOCKET_ADDRESS                     Dhcpv4Server; \
+  NET_IF_COMPARTMENT_ID              CompartmentId; \
+  NET_IF_NETWORK_GUID                NetworkGuid; \
+  NET_IF_CONNECTION_TYPE             ConnectionType; \
+  TUNNEL_TYPE                        TunnelType; \
+  SOCKET_ADDRESS                     Dhcpv6Server; \
+  BYTE                               Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; 
\
+  ULONG                              Dhcpv6ClientDuidLength; \
+  ULONG                              Dhcpv6Iaid;
+
+#define _IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1 \
+  _IP_ADAPTER_ADDRESSES_ADD_VISTA \
+  PIP_ADAPTER_DNS_SUFFIX             FirstDnsSuffix;
+
+#define _IP_ADAPTER_ADDRESSES_DEFINE(suffix,addition) \
+typedef struct _IP_ADAPTER_ADDRESSES##suffix { \
+  _IP_ADAPTER_ADDRESSES_HEAD \
+  struct _IP_ADAPTER_ADDRESSES##suffix *Next; \
+  _IP_ADAPTER_ADDRESSES_BASE \
+  addition \
+} IP_ADAPTER_ADDRESSES##suffix, *PIP_ADAPTER_ADDRESSES##suffix;
+  
+
+/* _IP_ADAPTER_ADDRESSES_DEFINE(,) defined in w32api headers */
+_IP_ADAPTER_ADDRESSES_DEFINE(_XPSP1,_IP_ADAPTER_ADDRESSES_ADD_XPSP1)
+_IP_ADAPTER_ADDRESSES_DEFINE(_VISTA,_IP_ADAPTER_ADDRESSES_ADD_VISTA)
+_IP_ADAPTER_ADDRESSES_DEFINE(_2008_OR_VISTASP1,_IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1)
+
+static int
+EnumNICs_IPv6_get_ifs_count (SOCKET s)
+{
+  DWORD dwret = 0, err;
+  int iret;
+  iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0,
+      &dwret, NULL, NULL);
+  err = GetLastError ();
+  if (iret == SOCKET_ERROR && err == WSAEFAULT)
+    return dwret;
+  else if (iret == 0)
+    return 0;
+  return GNUNET_SYSERR;
+}
+
+static int
+EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size)
+{
+  int iret;
+  DWORD dwret = 0;
+  iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, inf, size,
+      &dwret, NULL, NULL);
+
+  if (iret != 0 || dwret != size)
+  {
+    /* It's supposed to succeed! And size should be the same */
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+#undef GNUNET_malloc
+#define GNUNET_malloc(a) HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY | \
+    HEAP_GENERATE_EXCEPTIONS, a)
+
+#undef GNUNET_free
+#define GNUNET_free(a) HeapFree(GetProcessHeap (), 0, a)
+
+#undef GNUNET_free_non_null
+#define GNUNET_free_non_null(a) do { if ((a) != NULL) GNUNET_free(a); } while 
(0)
+
+static int
+EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size)
+{
+  int iret;
+  DWORD dwret = 0;
+  DWORD error;
+  INTERFACE_INFO *ii = NULL;
+  DWORD ii_size = sizeof (INTERFACE_INFO) * 15;
+  while (TRUE)
+  {
+    if (ii_size >= sizeof (INTERFACE_INFO) * 1000)
+      return GNUNET_SYSERR;
+    ii = (INTERFACE_INFO *) GNUNET_malloc (ii_size);
+    dwret = 0;
+    iret = WSAIoctl (s, SIO_GET_INTERFACE_LIST, NULL, 0, ii, ii_size,
+        &dwret, NULL, NULL);
+    error = GetLastError ();
+    if (iret == SOCKET_ERROR)
+    {
+      if (error == WSAEFAULT)
+      {
+        GNUNET_free (ii);
+        ii_size *= 2;
+        continue;
+      }
+      GNUNET_free (ii);
+      return GNUNET_SYSERR;
+    }
+    else
+    {
+      *inf = ii;
+      *size = dwret;
+      return GNUNET_OK;
+    }
+  }
+  return GNUNET_SYSERR;
+}
+
+int
+EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6)
+{
+  int result = 0;
+  SOCKET s4 = INVALID_SOCKET, s6 = INVALID_SOCKET;
+  DWORD dwret1 = 0, dwret2;
+  DWORD err1, err2;
+  int ifs4len = 0, ifs6len = 0;
+  INTERFACE_INFO *interfaces4 = NULL;
+  SOCKET_ADDRESS_LIST *interfaces6 = NULL;
+  SetLastError (0);
+  s4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  err1 = GetLastError ();
+  SetLastError (0);
+  s6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+  err2 = GetLastError ();
+  if (s6 != INVALID_SOCKET)
+  {
+    ifs6len = EnumNICs_IPv6_get_ifs_count (s6);
+    if (ifs6len > 0)
+    {
+      interfaces6 = (SOCKET_ADDRESS_LIST *) GNUNET_malloc (ifs6len);
+      result = EnumNICs_IPv6_get_ifs (s6, interfaces6, ifs6len) || result;
+    }
+    closesocket (s6);
+    s6 = INVALID_SOCKET;
+  }
+
+  if (s4 != INVALID_SOCKET)
+  {
+    result = EnumNICs_IPv4_get_ifs (s4, &interfaces4, &ifs4len) || result;
+    closesocket (s4);
+    s4 = INVALID_SOCKET;
+  }
+  if (ifs6len + ifs4len == 0)
+    goto error;
+
+  if (!result)
+  {
+    *ifs4 = interfaces4;
+    *ifs4_len = ifs4len;
+    *ifs6 = interfaces6;
+    return GNUNET_OK;
+  }
+error:
+  if (interfaces4 != NULL)
+    GNUNET_free (interfaces4);
+  if (interfaces6 != NULL)
+    GNUNET_free (interfaces6);
+  if (s4 != INVALID_SOCKET)
+    closesocket (s4);
+  if (s6 != INVALID_SOCKET)
+    closesocket (s6);
+  return GNUNET_SYSERR;
+}
+
+/**
+ * Returns GNUNET_OK on OK, GNUNET_SYSERR on error
+ */
+int
+EnumNICs3 (struct EnumNICs3_results **results, int *results_count)
+{
+  DWORD dwRetVal = 0;
+  int count = 0;
+  ULONG flags = /*GAA_FLAG_INCLUDE_PREFIX |*/ GAA_FLAG_SKIP_ANYCAST |
+      GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
+  struct sockaddr_in6 examplecom6;
+  IPAddr examplecom;
+  DWORD best_interface = 0;
+  DWORD best_interface6 = 0;
+
+  int use_enum2 = 0;
+  INTERFACE_INFO *interfaces4 = NULL;
+  int interfaces4_len = 0;
+  SOCKET_ADDRESS_LIST *interfaces6 = NULL;
+
+  unsigned long outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
+  IP_ADAPTER_ADDRESSES *pCurrentAddress = NULL;
+  IP_ADAPTER_ADDRESSES *pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc 
(outBufLen);
+
+  if (GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen)
+      == ERROR_BUFFER_OVERFLOW)
+  {
+    GNUNET_free (pAddresses);
+    pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen);
+  }
+
+  dwRetVal = GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, 
&outBufLen);
+
+  if (dwRetVal != NO_ERROR)
+  {
+    GNUNET_free (pAddresses);
+    return GNUNET_SYSERR;
+  }
+
+  if (pAddresses->Length < sizeof (IP_ADAPTER_ADDRESSES_VISTA))
+  {
+    use_enum2 = 1;
+
+    /* Enumerate NICs using WSAIoctl() */
+    if (GNUNET_OK != EnumNICs2 (&interfaces4, &interfaces4_len, &interfaces6))
+    {
+      GNUNET_free (pAddresses);
+      return GNUNET_SYSERR;
+    }
+  }
+
+  examplecom = inet_addr("192.0.34.166"); /* www.example.com */
+  if (GetBestInterface (examplecom, &best_interface) != NO_ERROR)
+    best_interface = 0;
+
+  if (GNGetBestInterfaceEx != NULL)
+  {
+    examplecom6.sin6_family = AF_INET6;
+    examplecom6.sin6_port = 0;
+    examplecom6.sin6_flowinfo = 0;
+    examplecom6.sin6_scope_id = 0;
+    inet_pton (AF_INET6, "2001:500:88:200:0:0:0:10",
+        (struct sockaddr *) &examplecom6.sin6_addr);
+    dwRetVal = GNGetBestInterfaceEx ((struct sockaddr *) &examplecom6,
+        &best_interface6);
+    if (dwRetVal != NO_ERROR)
+      best_interface6 = 0;
+  }
+
+  /* Give IPv6 a priority */
+  if (best_interface6 != 0)
+    best_interface = best_interface6;
+
+  count = 0;
+  for (pCurrentAddress = pAddresses;
+      pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
+  {
+    if (pCurrentAddress->OperStatus == IfOperStatusUp)
+    {
+      IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
+      for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
+          unicast = unicast->Next)
+      {
+        if ((unicast->Address.lpSockaddr->sa_family == AF_INET ||
+            unicast->Address.lpSockaddr->sa_family == AF_INET6) &&
+            (unicast->DadState == IpDadStateDeprecated ||
+            unicast->DadState == IpDadStatePreferred))
+          count += 1;
+      }
+    }
+  }
+
+  if (count == 0)
+  {
+    *results = NULL;
+    *results_count = 0;
+    GNUNET_free (pAddresses);
+    GNUNET_free_non_null (interfaces4);
+    GNUNET_free_non_null (interfaces6);
+    return GNUNET_OK;
+  }
+
+  *results = (struct EnumNICs3_results *) GNUNET_malloc (
+      sizeof (struct EnumNICs3_results) * count);
+  *results_count = count;
+
+  count = 0;
+  for (pCurrentAddress = pAddresses;
+      pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
+  {
+    struct EnumNICs3_results *r;
+    IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
+    if (pCurrentAddress->OperStatus != IfOperStatusUp)
+      continue;
+    for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
+        unicast = unicast->Next)
+    {
+      int i, j;
+      int mask_length = -1;
+      char dst[INET6_ADDRSTRLEN + 1];
+
+      if ((unicast->Address.lpSockaddr->sa_family != AF_INET &&
+          unicast->Address.lpSockaddr->sa_family != AF_INET6) ||
+          (unicast->DadState != IpDadStateDeprecated &&
+          unicast->DadState != IpDadStatePreferred))
+        continue;
+
+      r = &(*results)[count];
+      r->flags = 0;
+      if (pCurrentAddress->IfIndex > 0 &&
+          pCurrentAddress->IfIndex == best_interface &&
+          unicast->Address.lpSockaddr->sa_family == AF_INET)
+        r->is_default = 1;
+      else if (pCurrentAddress->Ipv6IfIndex > 0 &&
+          pCurrentAddress->Ipv6IfIndex == best_interface6 &&
+          unicast->Address.lpSockaddr->sa_family == AF_INET6)
+        r->is_default = 1;
+      else
+        r->is_default = 0;
+
+      /* Don't choose default interface twice */
+      if (r->is_default)
+        best_interface = best_interface6 = 0;
+
+      if (!use_enum2)
+      {
+        memcpy (&r->address, unicast->Address.lpSockaddr,
+            unicast->Address.iSockaddrLength);
+        memset (&r->mask, 0, sizeof (struct sockaddr));
+        mask_length = ((IP_ADAPTER_UNICAST_ADDRESS_VISTA *) unicast)->
+              OnLinkPrefixLength;
+        /* OnLinkPrefixLength is the number of leading 1s in the mask.
+         * OnLinkPrefixLength is available on Vista and later (hence 
use_enum2).
+         */
+        if (unicast->Address.lpSockaddr->sa_family == AF_INET)
+        {
+          struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
+          for (i = 0; i < mask_length; i++)
+              ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
+        }
+        else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
+        {
+          struct sockaddr_in6 *m = (struct sockaddr_in6 *) &r->mask;
+          struct sockaddr_in6 *b = (struct sockaddr_in6 *) &r->broadcast;
+          for (i = 0; i < mask_length; i++)
+            ((unsigned char *) &m->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
+          memcpy (&r->broadcast, &r->address, 
unicast->Address.iSockaddrLength);
+          for (i = mask_length; i < 128; i++)
+            ((unsigned char *) &b->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
+        }
+        r->flags |= ENUMNICS3_MASK_OK;
+      }
+      else
+      {
+        int found = 0;
+        if (unicast->Address.lpSockaddr->sa_family == AF_INET)
+        {
+          for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); 
i++)
+          {
+            struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
+            if (memcpy (&interfaces4[i].iiAddress.Address,
+                unicast->Address.lpSockaddr,
+                unicast->Address.iSockaddrLength) != 0)
+              continue;
+            found = 1;
+            memcpy (&r->address, &interfaces4[i].iiAddress.Address,
+                sizeof (struct sockaddr_in));
+            memcpy (&r->mask, &interfaces4[i].iiNetmask.Address,
+                sizeof (struct sockaddr_in));
+            for (mask_length = 0;
+                ((unsigned char *) &m->sin_addr)[mask_length / 8] &
+                0x80 >> (mask_length % 8); mask_length++)
+            {
+            }
+            r->flags |= ENUMNICS3_MASK_OK;
+          }
+        }
+        else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
+        {
+          for (i = 0;
+              interfaces6 != NULL && !found && i < interfaces6->iAddressCount;
+              i++)
+          {
+            if (memcpy (interfaces6->Address[i].lpSockaddr,
+                unicast->Address.lpSockaddr,
+                unicast->Address.iSockaddrLength) != 0)
+              continue;
+            found = 1;
+            memcpy (&r->address, interfaces6->Address[i].lpSockaddr,
+                sizeof (struct sockaddr_in6));
+            /* TODO: Find a way to reliably get network mask for IPv6 on XP */
+            memset (&r->mask, 0, sizeof (struct sockaddr));
+            r->flags &= ~ENUMNICS3_MASK_OK;
+          }
+        }
+        if (!found)
+        {
+          DebugBreak ();
+        }
+      }
+      if (unicast->Address.lpSockaddr->sa_family == AF_INET)
+      {
+        struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
+        struct sockaddr_in *a = (struct sockaddr_in *) &r->address;
+        /* copy address to broadcast, then flip all the trailing bits not
+         * falling under netmask to 1,
+         * so we get, 192.168.0.255 from, say, 192.168.0.43 with mask == 24.
+         */
+        memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength);
+        for (i = mask_length; i < 32; i++)
+          ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
+        r->flags |= ENUMNICS3_BCAST_OK;
+        r->addr_size = sizeof (struct sockaddr_in);
+        inet_ntop (AF_INET, &a->sin_addr, dst, INET_ADDRSTRLEN);
+      }
+      else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
+      {
+        struct sockaddr_in6 *a = (struct sockaddr_in6 *) &r->address;
+        /* for IPv6 broadcast is not defined, zero it down */
+        memset (&r->broadcast, 0, sizeof (struct sockaddr));
+        r->flags &= ~ENUMNICS3_BCAST_OK;
+        r->addr_size = sizeof (struct sockaddr_in6);
+        inet_ntop (AF_INET6, &a->sin6_addr, dst, INET6_ADDRSTRLEN);
+      }
+
+      i = 0;
+      i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
+          "%S (%s", pCurrentAddress->FriendlyName, dst);
+      for (j = 0; j < pCurrentAddress->PhysicalAddressLength; j++)
+        i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
+            "%s%02X",j > 0 ? ":" : " - ", pCurrentAddress->PhysicalAddress[j]);
+      i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, ")");
+      r->pretty_name[1000] = '\0';
+      count += 1;
+    }
+  }
+
+  if (use_enum2)
+  {
+    GNUNET_free_non_null (interfaces4);
+    GNUNET_free_non_null (interfaces6);
+  }
+
+  GNUNET_free (pAddresses);
+  return GNUNET_OK;
+}
+
+void
+EnumNICs3_free (struct EnumNICs3_results *r)
+{
+  GNUNET_free_non_null (r);
+}
+
+
+/**
+ * Lists all network interfaces in a combo box
+ * Used by the basic GTK configurator
+ *
+ * @param callback function to call for each NIC
+ * @param callback_cls closure for callback
+ */
+int
+ListNICs (void (*callback) (void *, const char *, int), void * callback_cls)
+{
+  int r;
+  int i;
+  struct EnumNICs3_results *results = NULL;
+  int results_count;
+
+  r = EnumNICs3 (&results, &results_count);
+  if (r != GNUNET_OK)
+    return GNUNET_NO;
+
+  for (i = 0; i < results_count; i++)
+    callback (callback_cls, results[i].pretty_name, results[i].is_default);
+  GNUNET_free_non_null (results);
+  return GNUNET_YES;
+}
+
+/**
+ * @brief Installs the Windows service
+ * @param servicename name of the service as diplayed by the SCM
+ * @param application path to the application binary
+ * @param username the name of the service's user account
+ * @returns 0 on success
+ *          1 if the Windows version doesn't support services
+ *          2 if the SCM could not be opened
+ *          3 if the service could not be created
+ */
+int InstallAsService(char *servicename, char *application, char *username)
+{
+  SC_HANDLE hManager, hService;
+  char szEXE[_MAX_PATH + 17] = "\"";
+  char *user = NULL;
+
+  if (! GNOpenSCManager)
+    return 1;
+
+  plibc_conv_to_win_path(application, szEXE + 1);
+  strcat(szEXE, "\" --win-service");
+  hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+  if (! hManager)
+    return 2;
+
+  if (username)
+  {
+       user = (char *) malloc(strlen(username) + 3);
+       sprintf(user, ".\\%s", username);
+  }
+
+  hService = GNCreateService(hManager, (LPCTSTR) servicename, (LPCTSTR) 
servicename, 0,
+    SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, 
(LPCTSTR) szEXE,
+    NULL, NULL, NULL, (LPCTSTR) user, (LPCTSTR) username);
+
+  if (user)
+    free(user);
+
+  if (! hService)
+    return 3;
+
+  GNCloseServiceHandle(hService);
+
+  return 0;
+}
+
+/**
+ * @brief Uninstall Windows service
+ * @param servicename name of the service to delete
+ * @returns 0 on success
+ *          1 if the Windows version doesn't support services
+ *          2 if the SCM could not be openend
+ *          3 if the service cannot be accessed
+ *          4 if the service cannot be deleted
+ */
+int UninstallService(char *servicename)
+{
+  SC_HANDLE hManager, hService;
+
+  if (! GNOpenSCManager)
+    return 1;
+
+  hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+  if (! hManager)
+    return 2;
+
+  if (! (hService = GNOpenService(hManager, (LPCTSTR) servicename, DELETE)))
+    if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
+      return 3;
+     else
+       goto closeSCM;
+
+  if (! GNDeleteService(hService))
+    if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE)
+      return 4;
+
+closeSCM:
+  GNCloseServiceHandle(hService);
+
+  return 0;
+}
+
+/**
+ * @author Scott Field, Microsoft
+ * @see http://support.microsoft.com/?scid=kb;en-us;132958
+ * @date 12-Jul-95
+ */
+void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
+{
+  DWORD StringLength;
+
+  if(String == NULL)
+  {
+    LsaString->Buffer = NULL;
+    LsaString->Length = 0;
+    LsaString->MaximumLength = 0;
+    return;
+  }
+
+  StringLength = wcslen(String);
+  LsaString->Buffer = String;
+  LsaString->Length = (USHORT) StringLength *sizeof(WCHAR);
+  LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR);
+}
+
+
+/**
+ * @author Scott Field, Microsoft
+ * @see http://support.microsoft.com/?scid=kb;en-us;132958
+ * @date 12-Jul-95
+ */
+NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE 
PolicyHandle)
+{
+  LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+  LSA_UNICODE_STRING ServerString;
+  PLSA_UNICODE_STRING Server = NULL;
+
+  /* Always initialize the object attributes to all zeroes. */
+  ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
+
+  if(ServerName != NULL)
+  {
+    /* Make a LSA_UNICODE_STRING out of the LPWSTR passed in */
+    _InitLsaString(&ServerString, ServerName);
+    Server = &ServerString;
+  }
+
+  /* Attempt to open the policy. */
+  return GNLsaOpenPolicy(Server,
+                       &ObjectAttributes, DesiredAccess, PolicyHandle);
+}
+
+/**
+ * @brief Obtain a SID representing the supplied account on the supplied system
+ * @return TRUE on success, FALSE on failure
+ * @author Scott Field, Microsoft
+ * @date 12-Jul-95
+ * @remarks A buffer is allocated which contains the SID representing the
+ *          supplied account. This buffer should be freed when it is no longer
+ *          needed by calling\n
+ *            HeapFree(GetProcessHeap(), 0, buffer)
+ * @remarks Call GetLastError() to obtain extended error information.
+ * @see http://support.microsoft.com/?scid=kb;en-us;132958
+ */
+BOOL _GetAccountSid(LPCTSTR SystemName, LPCTSTR AccountName, PSID * Sid)
+{
+  LPTSTR ReferencedDomain = NULL;
+  DWORD cbSid = 128;                                                   /* 
initial allocation attempt */
+  DWORD cchReferencedDomain = 16;      /* initial allocation size */
+  SID_NAME_USE peUse;
+  BOOL bSuccess = FALSE;                                       /* assume this 
function will fail */
+
+  /* initial memory allocations */
+  if ((*Sid = HeapAlloc (GetProcessHeap (), 0, cbSid)) == NULL)
+       return FALSE;
+
+  if ((ReferencedDomain = (LPTSTR) HeapAlloc (GetProcessHeap (),
+                                   0,
+                                   cchReferencedDomain *
+                                   sizeof (TCHAR))) == NULL)
+       return FALSE;
+
+    /* Obtain the SID of the specified account on the specified system. */
+       while (!GNLookupAccountName(SystemName, /* machine to lookup account on 
*/
+                  AccountName,                                                 
                                        /* account to lookup */
+                  *Sid,                                                        
                                                                /* SID of 
interest */
+                  &cbSid,                                                      
                                                        /* size of SID */
+                  ReferencedDomain,                                            
                        /* domain account was found on */
+                  &cchReferencedDomain, &peUse))
+       {
+               if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+               {
+                       /* reallocate memory */
+                       if ((*Sid = HeapReAlloc (GetProcessHeap (), 0, *Sid, 
cbSid)) == NULL)
+                               return FALSE;
+
+                       if ((ReferencedDomain = (LPTSTR) HeapReAlloc 
(GetProcessHeap (),
+                                             0,
+                                             ReferencedDomain,
+                                             cchReferencedDomain
+                                             * sizeof (TCHAR))) == NULL)
+                               return FALSE;
+      }
+      else
+        goto end;
+  }
+
+  /* Indicate success. */
+  bSuccess = TRUE;
+
+end:
+  /* Cleanup and indicate failure, if appropriate. */
+  HeapFree (GetProcessHeap (), 0, ReferencedDomain);
+
+  if (!bSuccess)
+  {
+    if (*Sid != NULL)
+    {
+               HeapFree (GetProcessHeap (), 0, *Sid);
+               *Sid = NULL;
+    }
+  }
+
+  return bSuccess;
+}
+
+/**
+ * @author Scott Field, Microsoft
+ * @see http://support.microsoft.com/?scid=kb;en-us;132958
+ * @date 12-Jul-95
+ */
+NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle 
*/
+                               PSID AccountSid,                        /* SID 
to grant privilege to */
+                               LPWSTR PrivilegeName,   /* privilege to grant 
(Unicode) */
+                               BOOL bEnable                                    
        /* enable or disable */
+  )
+{
+  LSA_UNICODE_STRING PrivilegeString;
+
+  /* Create a LSA_UNICODE_STRING for the privilege name. */
+  _InitLsaString(&PrivilegeString, PrivilegeName);
+
+  /* grant or revoke the privilege, accordingly */
+  if(bEnable)
+  {
+    NTSTATUS i;
+
+    i = GNLsaAddAccountRights(PolicyHandle,                            /* open 
policy handle */
+                               AccountSid,                             /* 
target SID */
+                               &PrivilegeString,        /* privileges */
+                               1                                               
                                        /* privilege count */
+      );
+  }
+  else
+  {
+    return GNLsaRemoveAccountRights(PolicyHandle,                      /* open 
policy handle */
+                                  AccountSid,                          /* 
target SID */
+                                  FALSE,                                       
                /* do not disable all rights */
+                                  &PrivilegeString,            /* privileges */
+                                  1                                            
                                /* privilege count */
+      );
+  }
+}
+
+/**
+ * @brief Create a Windows service account
+ * @return 0 on success, > 0 otherwise
+ * @param pszName the name of the account
+ * @param pszDesc description of the account
+ */
+int CreateServiceAccount(const char *pszName, const char *pszDesc)
+{
+  USER_INFO_1 ui;
+  USER_INFO_1008 ui2;
+  NET_API_STATUS nStatus;
+  wchar_t wszName[MAX_NAME_LENGTH], wszDesc[MAX_NAME_LENGTH];
+  DWORD dwErr;
+  LSA_HANDLE hPolicy;
+  PSID pSID;
+
+  if (! GNNetUserAdd)
+       return 1;
+  mbstowcs(wszName, pszName, strlen(pszName) + 1);
+  mbstowcs(wszDesc, pszDesc, strlen(pszDesc) + 1);
+
+  memset(&ui, 0, sizeof(ui));
+  ui.usri1_name = wszName;
+  ui.usri1_password = wszName; /* account is locked anyway */
+  ui.usri1_priv = USER_PRIV_USER;
+  ui.usri1_comment = wszDesc;
+  ui.usri1_flags = UF_SCRIPT;
+
+  nStatus = GNNetUserAdd(NULL, 1, (LPBYTE)&ui, NULL);
+
+  if (nStatus != NERR_Success && nStatus != NERR_UserExists)
+       return 2;
+
+  ui2.usri1008_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
+  GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL);
+
+  if (_OpenPolicy(NULL, POLICY_ALL_ACCESS, &hPolicy) !=
+                                                                               
STATUS_SUCCESS)
+       return 3;
+
+  _GetAccountSid(NULL, (LPCTSTR) pszName, &pSID);
+
+  if (_SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeServiceLogonRight", 
TRUE) != STATUS_SUCCESS)
+       return 4;
+
+  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) 
L"SeDenyInteractiveLogonRight", TRUE);
+  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyBatchLogonRight", 
TRUE);
+  _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyNetworkLogonRight", 
TRUE);
+
+  GNLsaClose(hPolicy);
+
+  return 0;
+}
+
+/**
+ * @brief Grant permission to a file
+ * @param lpszFileName the name of the file or directory
+ * @param lpszAccountName the user account
+ * @param dwAccessMask the desired access (e.g. GENERIC_ALL)
+ * @return TRUE on success
+ * @remark based on 
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102&;
+ */
+BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
+      DWORD dwAccessMask)
+{
+  /* SID variables. */
+  SID_NAME_USE   snuType;
+  TCHAR *        szDomain       = NULL;
+  DWORD          cbDomain       = 0;
+  LPVOID         pUserSID       = NULL;
+  DWORD          cbUserSID      = 0;
+
+  /* File SD variables. */
+  PSECURITY_DESCRIPTOR pFileSD  = NULL;
+  DWORD          cbFileSD       = 0;
+
+  /* New SD variables. */
+  SECURITY_DESCRIPTOR  newSD;
+
+  /* ACL variables. */
+  PACL           pACL           = NULL;
+  BOOL           fDaclPresent;
+  BOOL           fDaclDefaulted;
+  ACL_SIZE_INFORMATION AclInfo;
+
+  /* New ACL variables. */
+  PACL           pNewACL        = NULL;
+  DWORD          cbNewACL       = 0;
+
+  /* Temporary ACE. */
+  LPVOID         pTempAce       = NULL;
+  UINT           CurrentAceIndex = 0;
+
+  UINT           newAceIndex = 0;
+
+  /* Assume function will fail. */
+  BOOL           fResult        = FALSE;
+  BOOL           fAPISuccess;
+
+  SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
+
+  /**
+   * STEP 1: Get SID of the account name specified.
+   */
+  fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
+        pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
+
+  /* API should have failed with insufficient buffer. */
+  if (fAPISuccess)
+     goto end;
+  else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+     goto end;
+  }
+
+  pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID);
+  if (!pUserSID) {
+     goto end;
+  }
+
+  szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDomain 
* sizeof(TCHAR));
+  if (!szDomain) {
+     goto end;
+  }
+
+  fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
+        pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
+  if (!fAPISuccess) {
+     goto end;
+  }
+
+  /**
+   *  STEP 2: Get security descriptor (SD) of the file specified.
+   */
+  fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
+        secInfo, pFileSD, 0, &cbFileSD);
+
+  /* API should have failed with insufficient buffer. */
+  if (fAPISuccess)
+     goto end;
+  else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+     goto end;
+  }
+
+  pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), 
HEAP_ZERO_MEMORY,
+       cbFileSD);
+  if (!pFileSD) {
+     goto end;
+  }
+
+  fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
+        secInfo, pFileSD, cbFileSD, &cbFileSD);
+  if (!fAPISuccess) {
+     goto end;
+  }
+
+  /**
+   * STEP 3: Initialize new SD.
+   */
+  if (!GNInitializeSecurityDescriptor(&newSD,
+        SECURITY_DESCRIPTOR_REVISION)) {
+     goto end;
+  }
+
+  /**
+   * STEP 4: Get DACL from the old SD.
+   */
+  if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
+        &fDaclDefaulted)) {
+     goto end;
+  }
+
+  /**
+   * STEP 5: Get size information for DACL.
+   */
+  AclInfo.AceCount = 0; // Assume NULL DACL.
+  AclInfo.AclBytesFree = 0;
+  AclInfo.AclBytesInUse = sizeof(ACL);
+
+  if (pACL == NULL)
+     fDaclPresent = FALSE;
+
+  /* If not NULL DACL, gather size information from DACL. */
+  if (fDaclPresent) {
+
+     if (!GNGetAclInformation(pACL, &AclInfo,
+           sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
+        goto end;
+     }
+  }
+
+  /**
+   * STEP 6: Compute size needed for the new ACL.
+   */
+  cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
+        + GetLengthSid(pUserSID) - sizeof(DWORD);
+
+  /**
+   * STEP 7: Allocate memory for new ACL.
+   */
+  pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL);
+  if (!pNewACL) {
+     goto end;
+  }
+
+  /**
+   * STEP 8: Initialize the new ACL.
+   */
+  if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
+     goto end;
+  }
+
+  /**
+   * STEP 9 If DACL is present, copy all the ACEs from the old DACL
+   * to the new DACL.
+   *
+   * The following code assumes that the old DACL is
+   * already in Windows 2000 preferred order.  To conform
+   * to the new Windows 2000 preferred order, first we will
+   * copy all non-inherited ACEs from the old DACL to the
+   * new DACL, irrespective of the ACE type.
+   */
+
+  newAceIndex = 0;
+
+  if (fDaclPresent && AclInfo.AceCount) {
+
+     for (CurrentAceIndex = 0;
+           CurrentAceIndex < AclInfo.AceCount;
+           CurrentAceIndex++) {
+
+        /**
+         * TEP 10: Get an ACE.
+         */
+        if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
+           goto end;
+        }
+
+        /**
+         * STEP 11: Check if it is a non-inherited ACE.
+         * If it is an inherited ACE, break from the loop so
+         * that the new access allowed non-inherited ACE can
+         * be added in the correct position, immediately after
+         * all non-inherited ACEs.
+         */
+        if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
+           & INHERITED_ACE)
+           break;
+
+        /**
+         * STEP 12: Skip adding the ACE, if the SID matches
+         * with the account specified, as we are going to
+         * add an access allowed ACE with a different access
+         * mask.
+         */
+        if (GNEqualSid(pUserSID,
+           &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
+           continue;
+
+        /**
+         * STEP 13: Add the ACE to the new ACL.
+         */
+        if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
+              ((PACE_HEADER) pTempAce)->AceSize)) {
+           goto end;
+        }
+
+        newAceIndex++;
+     }
+  }
+
+  /**
+   * STEP 14: Add the access-allowed ACE to the new DACL.
+   * The new ACE added here will be in the correct position,
+   * immediately after all existing non-inherited ACEs.
+   */
+  if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
+        pUserSID)) {
+     goto end;
+  }
+
+  /**
+   * STEP 14.5: Make new ACE inheritable
+   */
+  if (!GetAce(pNewACL, newAceIndex, &pTempAce))
+    goto end;
+  ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |=
+    (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
+
+  /**
+   * STEP 15: To conform to the new Windows 2000 preferred order,
+   * we will now copy the rest of inherited ACEs from the
+   * old DACL to the new DACL.
+   */
+  if (fDaclPresent && AclInfo.AceCount) {
+
+     for (;
+          CurrentAceIndex < AclInfo.AceCount;
+          CurrentAceIndex++) {
+
+        /**
+         * STEP 16: Get an ACE.
+         */
+        if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
+           goto end;
+        }
+
+        /**
+         * STEP 17: Add the ACE to the new ACL.
+         */
+        if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
+              ((PACE_HEADER) pTempAce)->AceSize)) {
+           goto end;
+        }
+     }
+  }
+
+  /**
+   * STEP 18: Set permissions
+   */
+  if (GNSetNamedSecurityInfo((LPTSTR) lpszFileName, SE_FILE_OBJECT,
+    DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) {
+       goto end;
+  }
+
+  fResult = TRUE;
+
+end:
+
+  /**
+   * STEP 19: Free allocated memory
+   */
+  if (pUserSID)
+     HeapFree(GetProcessHeap(), 0, pUserSID);
+
+  if (szDomain)
+     HeapFree(GetProcessHeap(), 0, szDomain);
+
+  if (pFileSD)
+     HeapFree(GetProcessHeap(), 0, pFileSD);
+
+  if (pNewACL)
+     HeapFree(GetProcessHeap(), 0, pNewACL);
+
+  return fResult;
+}
+
+char *winErrorStr(const char *prefix, int dwErr)
+{
+  char *err, *ret;
+  int mem;
+
+  if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM,
+    NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) 
&err,
+    0, NULL ))
+  {
+    err = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, 1);
+  }
+
+  mem = strlen(err) + strlen(prefix) + 20;
+  ret = (char *) malloc(mem);
+
+  snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
+
+  LocalFree(err);
+
+  return ret;
+}
+
+/**
  * Terminate a process by creating a remote thread within it,
  * which proceeds to call ExitProcess() inside that process.
  * Safer than TerminateProcess ().
@@ -1269,61 +1269,61 @@
  * @param dwTimeout number of ms to wait for the process to terminate
  * @return TRUE on success, FALSE on failure (check last error for the code)
  */
-BOOL
-SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout)
-{
-  DWORD dwTID, dwCode, dwErr = 0;
-  HANDLE hProcessDup = INVALID_HANDLE_VALUE;
-  HANDLE hRT = NULL;
-  HINSTANCE hKernel = GetModuleHandle ("Kernel32");
-  BOOL bSuccess = FALSE;
-
-  BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess,
-      GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS,
-      FALSE, 0);
-
-  /* Detect the special case where the process is
-   * already dead...
-   */
-  if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) &&
-      (STILL_ACTIVE ==  dwCode))
-  {
-    FARPROC pfnExitProc;
-
-    pfnExitProc = GetProcAddress (hKernel, "ExitProcess");
-
-    hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0,
-        (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID);
-
-    dwErr = GetLastError ();
-  }
-  else
-  {
-    dwErr = ERROR_PROCESS_ABORTED;
-  }
-
-  if (hRT)
-  {
-    /* Must wait process to terminate to
-     * guarantee that it has exited...
-     */
-    DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess,
-        dwTimeout);
-    if (dwWaitResult == WAIT_TIMEOUT)
-      dwErr = WAIT_TIMEOUT;
-    else
-      dwErr = GetLastError ();
-
-    CloseHandle (hRT);
-    bSuccess = dwErr == NO_ERROR;
-  }
-
-  if (bDup)
-    CloseHandle (hProcessDup);
-
-  SetLastError (dwErr);
-
-  return bSuccess;
+BOOL
+SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout)
+{
+  DWORD dwTID, dwCode, dwErr = 0;
+  HANDLE hProcessDup = INVALID_HANDLE_VALUE;
+  HANDLE hRT = NULL;
+  HINSTANCE hKernel = GetModuleHandle ("Kernel32");
+  BOOL bSuccess = FALSE;
+
+  BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess,
+      GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS,
+      FALSE, 0);
+
+  /* Detect the special case where the process is
+   * already dead...
+   */
+  if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) &&
+      (STILL_ACTIVE ==  dwCode))
+  {
+    FARPROC pfnExitProc;
+
+    pfnExitProc = GetProcAddress (hKernel, "ExitProcess");
+
+    hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0,
+        (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID);
+
+    dwErr = GetLastError ();
+  }
+  else
+  {
+    dwErr = ERROR_PROCESS_ABORTED;
+  }
+
+  if (hRT)
+  {
+    /* Must wait process to terminate to
+     * guarantee that it has exited...
+     */
+    DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess,
+        dwTimeout);
+    if (dwWaitResult == WAIT_TIMEOUT)
+      dwErr = WAIT_TIMEOUT;
+    else
+      dwErr = GetLastError ();
+
+    CloseHandle (hRT);
+    bSuccess = dwErr == NO_ERROR;
+  }
+
+  if (bDup)
+    CloseHandle (hProcessDup);
+
+  SetLastError (dwErr);
+
+  return bSuccess;
 }
-
-#endif
+
+#endif




reply via email to

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