aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-09-28 09:12:05 +0000
committerChristian Grothoff <christian@grothoff.org>2012-09-28 09:12:05 +0000
commit5c70099f12dca398e9e6aaab13610207982f666f (patch)
treeb91e50b26b735f1f9cf644d132228d093c15223f /src/util
parent23e7a5c1060d37c45a955e4bed961661af8cafb9 (diff)
downloadgnunet-5c70099f12dca398e9e6aaab13610207982f666f.tar.gz
gnunet-5c70099f12dca398e9e6aaab13610207982f666f.zip
-dos2unix
Diffstat (limited to 'src/util')
-rw-r--r--src/util/crypto_crc.c1
-rw-r--r--src/util/win.c2632
2 files changed, 1316 insertions, 1317 deletions
diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c
index 3f4991353..ea50b636c 100644
--- a/src/util/crypto_crc.c
+++ b/src/util/crypto_crc.c
@@ -27,7 +27,6 @@
27 * @brief implementation of CRC16 and CRC32 27 * @brief implementation of CRC16 and CRC32
28 * @author Christian Grothoff 28 * @author Christian Grothoff
29 */ 29 */
30
31#include "platform.h" 30#include "platform.h"
32#include "gnunet_common.h" 31#include "gnunet_common.h"
33#include "gnunet_crypto_lib.h" 32#include "gnunet_crypto_lib.h"
diff --git a/src/util/win.c b/src/util/win.c
index 18e3e80c0..6a2da9339 100644
--- a/src/util/win.c
+++ b/src/util/win.c
@@ -1,1262 +1,1262 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your 7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/** 21/**
22 * @file util/win.c 22 * @file util/win.c
23 * @brief Helper functions for MS Windows in C++ 23 * @brief Helper functions for MS Windows in C++
24 * @author Nils Durner 24 * @author Nils Durner
25 */ 25 */
26 26
27#ifndef _WIN_C 27#ifndef _WIN_C
28#define _WIN_C 28#define _WIN_C
29 29
30#include "winproc.h" 30#include "winproc.h"
31#include "platform.h" 31#include "platform.h"
32#include "gnunet_common.h" 32#include "gnunet_common.h"
33#include "gnunet_connection_lib.h" 33#include "gnunet_connection_lib.h"
34 34
35#include <ntdef.h> 35#include <ntdef.h>
36 36
37#ifndef INHERITED_ACE 37#ifndef INHERITED_ACE
38#define INHERITED_ACE 0x10 38#define INHERITED_ACE 0x10
39#endif 39#endif
40 40
41int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); 41int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
42 42
43#define _IP_ADAPTER_UNICAST_ADDRESS_HEAD \ 43#define _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
44 union { \ 44 union { \
45 struct { \ 45 struct { \
46 ULONG Length; \ 46 ULONG Length; \
47 DWORD Flags; \ 47 DWORD Flags; \
48 }; \ 48 }; \
49 }; \ 49 }; \
50 50
51#define _IP_ADAPTER_UNICAST_ADDRESS_BASE \ 51#define _IP_ADAPTER_UNICAST_ADDRESS_BASE \
52 SOCKET_ADDRESS Address; \ 52 SOCKET_ADDRESS Address; \
53 IP_PREFIX_ORIGIN PrefixOrigin; \ 53 IP_PREFIX_ORIGIN PrefixOrigin; \
54 IP_SUFFIX_ORIGIN SuffixOrigin; \ 54 IP_SUFFIX_ORIGIN SuffixOrigin; \
55 IP_DAD_STATE DadState; \ 55 IP_DAD_STATE DadState; \
56 ULONG ValidLifetime; \ 56 ULONG ValidLifetime; \
57 ULONG PreferredLifetime; \ 57 ULONG PreferredLifetime; \
58 ULONG LeaseLifetime; 58 ULONG LeaseLifetime;
59 59
60#define _IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA \ 60#define _IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA \
61 UINT8 OnLinkPrefixLength; 61 UINT8 OnLinkPrefixLength;
62 62
63 63
64#define _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(suffix,addition) \ 64#define _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(suffix,addition) \
65typedef struct _IP_ADAPTER_UNICAST_ADDRESS##suffix { \ 65typedef struct _IP_ADAPTER_UNICAST_ADDRESS##suffix { \
66 _IP_ADAPTER_UNICAST_ADDRESS_HEAD \ 66 _IP_ADAPTER_UNICAST_ADDRESS_HEAD \
67 struct _IP_ADAPTER_UNICAST_ADDRESS##suffix *Next; \ 67 struct _IP_ADAPTER_UNICAST_ADDRESS##suffix *Next; \
68 _IP_ADAPTER_UNICAST_ADDRESS_BASE \ 68 _IP_ADAPTER_UNICAST_ADDRESS_BASE \
69 addition \ 69 addition \
70} IP_ADAPTER_UNICAST_ADDRESS##suffix, *PIP_ADAPTER_UNICAST_ADDRESS##suffix; 70} IP_ADAPTER_UNICAST_ADDRESS##suffix, *PIP_ADAPTER_UNICAST_ADDRESS##suffix;
71 71
72/* _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(,) defined in w32api headers */ 72/* _IP_ADAPTER_UNICAST_ADDRESS_DEFINE(,) defined in w32api headers */
73_IP_ADAPTER_UNICAST_ADDRESS_DEFINE(_VISTA,_IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA) 73_IP_ADAPTER_UNICAST_ADDRESS_DEFINE(_VISTA,_IP_ADAPTER_UNICAST_ADDRESS_ADD_VISTA)
74 74
75 75
76typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS { 76typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS {
77 union { 77 union {
78 ULONGLONG Alignment; 78 ULONGLONG Alignment;
79 struct { 79 struct {
80 ULONG Length; 80 ULONG Length;
81 DWORD Reserved; 81 DWORD Reserved;
82 }; 82 };
83 }; 83 };
84 struct _IP_ADAPTER_WINS_SERVER_ADDRESS *Next; 84 struct _IP_ADAPTER_WINS_SERVER_ADDRESS *Next;
85 SOCKET_ADDRESS Address; 85 SOCKET_ADDRESS Address;
86} IP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; 86} IP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS, *PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
87 87
88typedef struct _IP_ADAPTER_GATEWAY_ADDRESS { 88typedef struct _IP_ADAPTER_GATEWAY_ADDRESS {
89 union { 89 union {
90 ULONGLONG Alignment; 90 ULONGLONG Alignment;
91 struct { 91 struct {
92 ULONG Length; 92 ULONG Length;
93 DWORD Reserved; 93 DWORD Reserved;
94 }; 94 };
95 }; 95 };
96 struct _IP_ADAPTER_GATEWAY_ADDRESS *Next; 96 struct _IP_ADAPTER_GATEWAY_ADDRESS *Next;
97 SOCKET_ADDRESS Address; 97 SOCKET_ADDRESS Address;
98} IP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS_LH; 98} IP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS, *PIP_ADAPTER_GATEWAY_ADDRESS_LH;
99 99
100typedef UINT32 NET_IF_COMPARTMENT_ID; 100typedef UINT32 NET_IF_COMPARTMENT_ID;
101typedef GUID NET_IF_NETWORK_GUID; 101typedef GUID NET_IF_NETWORK_GUID;
102 102
103typedef enum _NET_IF_CONNECTION_TYPE { 103typedef enum _NET_IF_CONNECTION_TYPE {
104 NET_IF_CONNECTION_DEDICATED = 1, 104 NET_IF_CONNECTION_DEDICATED = 1,
105 NET_IF_CONNECTION_PASSIVE, 105 NET_IF_CONNECTION_PASSIVE,
106 NET_IF_CONNECTION_DEMAND, 106 NET_IF_CONNECTION_DEMAND,
107 NET_IF_CONNECTION_MAXIMUM 107 NET_IF_CONNECTION_MAXIMUM
108} NET_IF_CONNECTION_TYPE, *PNET_IF_CONNECTION_TYPE; 108} NET_IF_CONNECTION_TYPE, *PNET_IF_CONNECTION_TYPE;
109 109
110typedef enum { 110typedef enum {
111 TUNNEL_TYPE_NONE = 0, 111 TUNNEL_TYPE_NONE = 0,
112 TUNNEL_TYPE_OTHER, 112 TUNNEL_TYPE_OTHER,
113 TUNNEL_TYPE_DIRECT, 113 TUNNEL_TYPE_DIRECT,
114 TUNNEL_TYPE_6TO4, 114 TUNNEL_TYPE_6TO4,
115 TUNNEL_TYPE_ISATAP, 115 TUNNEL_TYPE_ISATAP,
116 TUNNEL_TYPE_TEREDO, 116 TUNNEL_TYPE_TEREDO,
117 TUNNEL_TYPE_IPHTTPS 117 TUNNEL_TYPE_IPHTTPS
118} TUNNEL_TYPE, *PTUNNEL_TYPE; 118} TUNNEL_TYPE, *PTUNNEL_TYPE;
119 119
120/* 120/*
121A DUID consists of a two-octet type code represented in network byte 121A DUID consists of a two-octet type code represented in network byte
122 order, followed by a variable number of octets that make up the 122 order, followed by a variable number of octets that make up the
123 actual identifier. A DUID can be no more than 128 octets long (not 123 actual identifier. A DUID can be no more than 128 octets long (not
124 including the type code). 124 including the type code).
125*/ 125*/
126#define MAX_DHCPV6_DUID_LENGTH 130 126#define MAX_DHCPV6_DUID_LENGTH 130
127 127
128typedef union _NET_LUID { 128typedef union _NET_LUID {
129 ULONG64 Value; 129 ULONG64 Value;
130 struct { 130 struct {
131 ULONG64 Reserved :24; 131 ULONG64 Reserved :24;
132 ULONG64 NetLuidIndex :24; 132 ULONG64 NetLuidIndex :24;
133 ULONG64 IfType :16; 133 ULONG64 IfType :16;
134 } Info; 134 } Info;
135} NET_LUID, *PNET_LUID, IF_LUID; 135} NET_LUID, *PNET_LUID, IF_LUID;
136 136
137#define MAX_DNS_SUFFIX_STRING_LENGTH 246 137#define MAX_DNS_SUFFIX_STRING_LENGTH 246
138 138
139typedef struct _IP_ADAPTER_DNS_SUFFIX { 139typedef struct _IP_ADAPTER_DNS_SUFFIX {
140 struct _IP_ADAPTER_DNS_SUFFIX *Next; 140 struct _IP_ADAPTER_DNS_SUFFIX *Next;
141 WCHAR String[MAX_DNS_SUFFIX_STRING_LENGTH]; 141 WCHAR String[MAX_DNS_SUFFIX_STRING_LENGTH];
142} IP_ADAPTER_DNS_SUFFIX, *PIP_ADAPTER_DNS_SUFFIX; 142} IP_ADAPTER_DNS_SUFFIX, *PIP_ADAPTER_DNS_SUFFIX;
143 143
144 144
145 145
146#define _IP_ADAPTER_ADDRESSES_HEAD \ 146#define _IP_ADAPTER_ADDRESSES_HEAD \
147 union { \ 147 union { \
148 ULONGLONG Alignment; \ 148 ULONGLONG Alignment; \
149 struct { \ 149 struct { \
150 ULONG Length; \ 150 ULONG Length; \
151 DWORD IfIndex; \ 151 DWORD IfIndex; \
152 }; \ 152 }; \
153 }; 153 };
154 154
155#define _IP_ADAPTER_ADDRESSES_BASE \ 155#define _IP_ADAPTER_ADDRESSES_BASE \
156 PCHAR AdapterName; \ 156 PCHAR AdapterName; \
157 PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; \ 157 PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; \
158 PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; \ 158 PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; \
159 PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; \ 159 PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; \
160 PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; \ 160 PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; \
161 PWCHAR DnsSuffix; \ 161 PWCHAR DnsSuffix; \
162 PWCHAR Description; \ 162 PWCHAR Description; \
163 PWCHAR FriendlyName; \ 163 PWCHAR FriendlyName; \
164 BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; \ 164 BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; \
165 DWORD PhysicalAddressLength; \ 165 DWORD PhysicalAddressLength; \
166 DWORD Flags; \ 166 DWORD Flags; \
167 DWORD Mtu; \ 167 DWORD Mtu; \
168 DWORD IfType; \ 168 DWORD IfType; \
169 IF_OPER_STATUS OperStatus; 169 IF_OPER_STATUS OperStatus;
170 170
171#define _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \ 171#define _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
172 DWORD Ipv6IfIndex; \ 172 DWORD Ipv6IfIndex; \
173 DWORD ZoneIndices[16]; \ 173 DWORD ZoneIndices[16]; \
174 PIP_ADAPTER_PREFIX FirstPrefix; \ 174 PIP_ADAPTER_PREFIX FirstPrefix; \
175 175
176 176
177#define _IP_ADAPTER_ADDRESSES_ADD_VISTA \ 177#define _IP_ADAPTER_ADDRESSES_ADD_VISTA \
178 _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \ 178 _IP_ADAPTER_ADDRESSES_ADD_XPSP1 \
179 ULONG64 TransmitLinkSpeed; \ 179 ULONG64 TransmitLinkSpeed; \
180 ULONG64 ReceiveLinkSpeed; \ 180 ULONG64 ReceiveLinkSpeed; \
181 PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; \ 181 PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; \
182 PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress; \ 182 PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress; \
183 ULONG Ipv4Metric; \ 183 ULONG Ipv4Metric; \
184 ULONG Ipv6Metric; \ 184 ULONG Ipv6Metric; \
185 IF_LUID Luid; \ 185 IF_LUID Luid; \
186 SOCKET_ADDRESS Dhcpv4Server; \ 186 SOCKET_ADDRESS Dhcpv4Server; \
187 NET_IF_COMPARTMENT_ID CompartmentId; \ 187 NET_IF_COMPARTMENT_ID CompartmentId; \
188 NET_IF_NETWORK_GUID NetworkGuid; \ 188 NET_IF_NETWORK_GUID NetworkGuid; \
189 NET_IF_CONNECTION_TYPE ConnectionType; \ 189 NET_IF_CONNECTION_TYPE ConnectionType; \
190 TUNNEL_TYPE TunnelType; \ 190 TUNNEL_TYPE TunnelType; \
191 SOCKET_ADDRESS Dhcpv6Server; \ 191 SOCKET_ADDRESS Dhcpv6Server; \
192 BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; \ 192 BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; \
193 ULONG Dhcpv6ClientDuidLength; \ 193 ULONG Dhcpv6ClientDuidLength; \
194 ULONG Dhcpv6Iaid; 194 ULONG Dhcpv6Iaid;
195 195
196#define _IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1 \ 196#define _IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1 \
197 _IP_ADAPTER_ADDRESSES_ADD_VISTA \ 197 _IP_ADAPTER_ADDRESSES_ADD_VISTA \
198 PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix; 198 PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix;
199 199
200#define _IP_ADAPTER_ADDRESSES_DEFINE(suffix,addition) \ 200#define _IP_ADAPTER_ADDRESSES_DEFINE(suffix,addition) \
201typedef struct _IP_ADAPTER_ADDRESSES##suffix { \ 201typedef struct _IP_ADAPTER_ADDRESSES##suffix { \
202 _IP_ADAPTER_ADDRESSES_HEAD \ 202 _IP_ADAPTER_ADDRESSES_HEAD \
203 struct _IP_ADAPTER_ADDRESSES##suffix *Next; \ 203 struct _IP_ADAPTER_ADDRESSES##suffix *Next; \
204 _IP_ADAPTER_ADDRESSES_BASE \ 204 _IP_ADAPTER_ADDRESSES_BASE \
205 addition \ 205 addition \
206} IP_ADAPTER_ADDRESSES##suffix, *PIP_ADAPTER_ADDRESSES##suffix; 206} IP_ADAPTER_ADDRESSES##suffix, *PIP_ADAPTER_ADDRESSES##suffix;
207 207
208 208
209/* _IP_ADAPTER_ADDRESSES_DEFINE(,) defined in w32api headers */ 209/* _IP_ADAPTER_ADDRESSES_DEFINE(,) defined in w32api headers */
210_IP_ADAPTER_ADDRESSES_DEFINE(_XPSP1,_IP_ADAPTER_ADDRESSES_ADD_XPSP1) 210_IP_ADAPTER_ADDRESSES_DEFINE(_XPSP1,_IP_ADAPTER_ADDRESSES_ADD_XPSP1)
211_IP_ADAPTER_ADDRESSES_DEFINE(_VISTA,_IP_ADAPTER_ADDRESSES_ADD_VISTA) 211_IP_ADAPTER_ADDRESSES_DEFINE(_VISTA,_IP_ADAPTER_ADDRESSES_ADD_VISTA)
212_IP_ADAPTER_ADDRESSES_DEFINE(_2008_OR_VISTASP1,_IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1) 212_IP_ADAPTER_ADDRESSES_DEFINE(_2008_OR_VISTASP1,_IP_ADAPTER_ADDRESSES_ADD_2008_OR_VISTASP1)
213 213
214static int 214static int
215EnumNICs_IPv6_get_ifs_count (SOCKET s) 215EnumNICs_IPv6_get_ifs_count (SOCKET s)
216{ 216{
217 DWORD dwret = 0, err; 217 DWORD dwret = 0, err;
218 int iret; 218 int iret;
219 iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, 219 iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0,
220 &dwret, NULL, NULL); 220 &dwret, NULL, NULL);
221 err = GetLastError (); 221 err = GetLastError ();
222 if (iret == SOCKET_ERROR && err == WSAEFAULT) 222 if (iret == SOCKET_ERROR && err == WSAEFAULT)
223 return dwret; 223 return dwret;
224 else if (iret == 0) 224 else if (iret == 0)
225 return 0; 225 return 0;
226 return GNUNET_SYSERR; 226 return GNUNET_SYSERR;
227} 227}
228 228
229static int 229static int
230EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size) 230EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size)
231{ 231{
232 int iret; 232 int iret;
233 DWORD dwret = 0; 233 DWORD dwret = 0;
234 iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, inf, size, 234 iret = WSAIoctl (s, SIO_ADDRESS_LIST_QUERY, NULL, 0, inf, size,
235 &dwret, NULL, NULL); 235 &dwret, NULL, NULL);
236 236
237 if (iret != 0 || dwret != size) 237 if (iret != 0 || dwret != size)
238 { 238 {
239 /* It's supposed to succeed! And size should be the same */ 239 /* It's supposed to succeed! And size should be the same */
240 return GNUNET_SYSERR; 240 return GNUNET_SYSERR;
241 } 241 }
242 return GNUNET_OK; 242 return GNUNET_OK;
243} 243}
244 244
245#undef GNUNET_malloc 245#undef GNUNET_malloc
246#define GNUNET_malloc(a) HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY | \ 246#define GNUNET_malloc(a) HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY | \
247 HEAP_GENERATE_EXCEPTIONS, a) 247 HEAP_GENERATE_EXCEPTIONS, a)
248 248
249#undef GNUNET_free 249#undef GNUNET_free
250#define GNUNET_free(a) HeapFree(GetProcessHeap (), 0, a) 250#define GNUNET_free(a) HeapFree(GetProcessHeap (), 0, a)
251 251
252#undef GNUNET_free_non_null 252#undef GNUNET_free_non_null
253#define GNUNET_free_non_null(a) do { if ((a) != NULL) GNUNET_free(a); } while (0) 253#define GNUNET_free_non_null(a) do { if ((a) != NULL) GNUNET_free(a); } while (0)
254 254
255static int 255static int
256EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size) 256EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size)
257{ 257{
258 int iret; 258 int iret;
259 DWORD dwret = 0; 259 DWORD dwret = 0;
260 DWORD error; 260 DWORD error;
261 INTERFACE_INFO *ii = NULL; 261 INTERFACE_INFO *ii = NULL;
262 DWORD ii_size = sizeof (INTERFACE_INFO) * 15; 262 DWORD ii_size = sizeof (INTERFACE_INFO) * 15;
263 while (TRUE) 263 while (TRUE)
264 { 264 {
265 if (ii_size >= sizeof (INTERFACE_INFO) * 1000) 265 if (ii_size >= sizeof (INTERFACE_INFO) * 1000)
266 return GNUNET_SYSERR; 266 return GNUNET_SYSERR;
267 ii = (INTERFACE_INFO *) GNUNET_malloc (ii_size); 267 ii = (INTERFACE_INFO *) GNUNET_malloc (ii_size);
268 dwret = 0; 268 dwret = 0;
269 iret = WSAIoctl (s, SIO_GET_INTERFACE_LIST, NULL, 0, ii, ii_size, 269 iret = WSAIoctl (s, SIO_GET_INTERFACE_LIST, NULL, 0, ii, ii_size,
270 &dwret, NULL, NULL); 270 &dwret, NULL, NULL);
271 error = GetLastError (); 271 error = GetLastError ();
272 if (iret == SOCKET_ERROR) 272 if (iret == SOCKET_ERROR)
273 { 273 {
274 if (error == WSAEFAULT) 274 if (error == WSAEFAULT)
275 { 275 {
276 GNUNET_free (ii); 276 GNUNET_free (ii);
277 ii_size *= 2; 277 ii_size *= 2;
278 continue; 278 continue;
279 } 279 }
280 GNUNET_free (ii); 280 GNUNET_free (ii);
281 return GNUNET_SYSERR; 281 return GNUNET_SYSERR;
282 } 282 }
283 else 283 else
284 { 284 {
285 *inf = ii; 285 *inf = ii;
286 *size = dwret; 286 *size = dwret;
287 return GNUNET_OK; 287 return GNUNET_OK;
288 } 288 }
289 } 289 }
290 return GNUNET_SYSERR; 290 return GNUNET_SYSERR;
291} 291}
292 292
293int 293int
294EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6) 294EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6)
295{ 295{
296 int result = 0; 296 int result = 0;
297 SOCKET s4 = INVALID_SOCKET, s6 = INVALID_SOCKET; 297 SOCKET s4 = INVALID_SOCKET, s6 = INVALID_SOCKET;
298 DWORD dwret1 = 0, dwret2; 298 DWORD dwret1 = 0, dwret2;
299 DWORD err1, err2; 299 DWORD err1, err2;
300 int ifs4len = 0, ifs6len = 0; 300 int ifs4len = 0, ifs6len = 0;
301 INTERFACE_INFO *interfaces4 = NULL; 301 INTERFACE_INFO *interfaces4 = NULL;
302 SOCKET_ADDRESS_LIST *interfaces6 = NULL; 302 SOCKET_ADDRESS_LIST *interfaces6 = NULL;
303 SetLastError (0); 303 SetLastError (0);
304 s4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 304 s4 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
305 err1 = GetLastError (); 305 err1 = GetLastError ();
306 SetLastError (0); 306 SetLastError (0);
307 s6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP); 307 s6 = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
308 err2 = GetLastError (); 308 err2 = GetLastError ();
309 if (s6 != INVALID_SOCKET) 309 if (s6 != INVALID_SOCKET)
310 { 310 {
311 ifs6len = EnumNICs_IPv6_get_ifs_count (s6); 311 ifs6len = EnumNICs_IPv6_get_ifs_count (s6);
312 if (ifs6len > 0) 312 if (ifs6len > 0)
313 { 313 {
314 interfaces6 = (SOCKET_ADDRESS_LIST *) GNUNET_malloc (ifs6len); 314 interfaces6 = (SOCKET_ADDRESS_LIST *) GNUNET_malloc (ifs6len);
315 result = EnumNICs_IPv6_get_ifs (s6, interfaces6, ifs6len) || result; 315 result = EnumNICs_IPv6_get_ifs (s6, interfaces6, ifs6len) || result;
316 } 316 }
317 closesocket (s6); 317 closesocket (s6);
318 s6 = INVALID_SOCKET; 318 s6 = INVALID_SOCKET;
319 } 319 }
320 320
321 if (s4 != INVALID_SOCKET) 321 if (s4 != INVALID_SOCKET)
322 { 322 {
323 result = EnumNICs_IPv4_get_ifs (s4, &interfaces4, &ifs4len) || result; 323 result = EnumNICs_IPv4_get_ifs (s4, &interfaces4, &ifs4len) || result;
324 closesocket (s4); 324 closesocket (s4);
325 s4 = INVALID_SOCKET; 325 s4 = INVALID_SOCKET;
326 } 326 }
327 if (ifs6len + ifs4len == 0) 327 if (ifs6len + ifs4len == 0)
328 goto error; 328 goto error;
329 329
330 if (!result) 330 if (!result)
331 { 331 {
332 *ifs4 = interfaces4; 332 *ifs4 = interfaces4;
333 *ifs4_len = ifs4len; 333 *ifs4_len = ifs4len;
334 *ifs6 = interfaces6; 334 *ifs6 = interfaces6;
335 return GNUNET_OK; 335 return GNUNET_OK;
336 } 336 }
337error: 337error:
338 if (interfaces4 != NULL) 338 if (interfaces4 != NULL)
339 GNUNET_free (interfaces4); 339 GNUNET_free (interfaces4);
340 if (interfaces6 != NULL) 340 if (interfaces6 != NULL)
341 GNUNET_free (interfaces6); 341 GNUNET_free (interfaces6);
342 if (s4 != INVALID_SOCKET) 342 if (s4 != INVALID_SOCKET)
343 closesocket (s4); 343 closesocket (s4);
344 if (s6 != INVALID_SOCKET) 344 if (s6 != INVALID_SOCKET)
345 closesocket (s6); 345 closesocket (s6);
346 return GNUNET_SYSERR; 346 return GNUNET_SYSERR;
347} 347}
348 348
349/** 349/**
350 * Returns GNUNET_OK on OK, GNUNET_SYSERR on error 350 * Returns GNUNET_OK on OK, GNUNET_SYSERR on error
351 */ 351 */
352int 352int
353EnumNICs3 (struct EnumNICs3_results **results, int *results_count) 353EnumNICs3 (struct EnumNICs3_results **results, int *results_count)
354{ 354{
355 DWORD dwRetVal = 0; 355 DWORD dwRetVal = 0;
356 int count = 0; 356 int count = 0;
357 ULONG flags = /*GAA_FLAG_INCLUDE_PREFIX |*/ GAA_FLAG_SKIP_ANYCAST | 357 ULONG flags = /*GAA_FLAG_INCLUDE_PREFIX |*/ GAA_FLAG_SKIP_ANYCAST |
358 GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; 358 GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
359 struct sockaddr_in6 examplecom6; 359 struct sockaddr_in6 examplecom6;
360 IPAddr examplecom; 360 IPAddr examplecom;
361 DWORD best_interface = 0; 361 DWORD best_interface = 0;
362 DWORD best_interface6 = 0; 362 DWORD best_interface6 = 0;
363 363
364 int use_enum2 = 0; 364 int use_enum2 = 0;
365 INTERFACE_INFO *interfaces4 = NULL; 365 INTERFACE_INFO *interfaces4 = NULL;
366 int interfaces4_len = 0; 366 int interfaces4_len = 0;
367 SOCKET_ADDRESS_LIST *interfaces6 = NULL; 367 SOCKET_ADDRESS_LIST *interfaces6 = NULL;
368 368
369 unsigned long outBufLen = sizeof (IP_ADAPTER_ADDRESSES); 369 unsigned long outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
370 IP_ADAPTER_ADDRESSES *pCurrentAddress = NULL; 370 IP_ADAPTER_ADDRESSES *pCurrentAddress = NULL;
371 IP_ADAPTER_ADDRESSES *pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen); 371 IP_ADAPTER_ADDRESSES *pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen);
372 372
373 if (GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen) 373 if (GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen)
374 == ERROR_BUFFER_OVERFLOW) 374 == ERROR_BUFFER_OVERFLOW)
375 { 375 {
376 GNUNET_free (pAddresses); 376 GNUNET_free (pAddresses);
377 pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen); 377 pAddresses = (IP_ADAPTER_ADDRESSES *) GNUNET_malloc (outBufLen);
378 } 378 }
379 379
380 dwRetVal = GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); 380 dwRetVal = GetAdaptersAddresses (AF_UNSPEC, flags, NULL, pAddresses, &outBufLen);
381 381
382 if (dwRetVal != NO_ERROR) 382 if (dwRetVal != NO_ERROR)
383 { 383 {
384 GNUNET_free (pAddresses); 384 GNUNET_free (pAddresses);
385 return GNUNET_SYSERR; 385 return GNUNET_SYSERR;
386 } 386 }
387 387
388 if (pAddresses->Length < sizeof (IP_ADAPTER_ADDRESSES_VISTA)) 388 if (pAddresses->Length < sizeof (IP_ADAPTER_ADDRESSES_VISTA))
389 { 389 {
390 use_enum2 = 1; 390 use_enum2 = 1;
391 391
392 /* Enumerate NICs using WSAIoctl() */ 392 /* Enumerate NICs using WSAIoctl() */
393 if (GNUNET_OK != EnumNICs2 (&interfaces4, &interfaces4_len, &interfaces6)) 393 if (GNUNET_OK != EnumNICs2 (&interfaces4, &interfaces4_len, &interfaces6))
394 { 394 {
395 GNUNET_free (pAddresses); 395 GNUNET_free (pAddresses);
396 return GNUNET_SYSERR; 396 return GNUNET_SYSERR;
397 } 397 }
398 } 398 }
399 399
400 examplecom = inet_addr("192.0.34.166"); /* www.example.com */ 400 examplecom = inet_addr("192.0.34.166"); /* www.example.com */
401 if (GetBestInterface (examplecom, &best_interface) != NO_ERROR) 401 if (GetBestInterface (examplecom, &best_interface) != NO_ERROR)
402 best_interface = 0; 402 best_interface = 0;
403 403
404 if (GNGetBestInterfaceEx != NULL) 404 if (GNGetBestInterfaceEx != NULL)
405 { 405 {
406 examplecom6.sin6_family = AF_INET6; 406 examplecom6.sin6_family = AF_INET6;
407 examplecom6.sin6_port = 0; 407 examplecom6.sin6_port = 0;
408 examplecom6.sin6_flowinfo = 0; 408 examplecom6.sin6_flowinfo = 0;
409 examplecom6.sin6_scope_id = 0; 409 examplecom6.sin6_scope_id = 0;
410 inet_pton (AF_INET6, "2001:500:88:200:0:0:0:10", 410 inet_pton (AF_INET6, "2001:500:88:200:0:0:0:10",
411 (struct sockaddr *) &examplecom6.sin6_addr); 411 (struct sockaddr *) &examplecom6.sin6_addr);
412 dwRetVal = GNGetBestInterfaceEx ((struct sockaddr *) &examplecom6, 412 dwRetVal = GNGetBestInterfaceEx ((struct sockaddr *) &examplecom6,
413 &best_interface6); 413 &best_interface6);
414 if (dwRetVal != NO_ERROR) 414 if (dwRetVal != NO_ERROR)
415 best_interface6 = 0; 415 best_interface6 = 0;
416 } 416 }
417 417
418 /* Give IPv6 a priority */ 418 /* Give IPv6 a priority */
419 if (best_interface6 != 0) 419 if (best_interface6 != 0)
420 best_interface = best_interface6; 420 best_interface = best_interface6;
421 421
422 count = 0; 422 count = 0;
423 for (pCurrentAddress = pAddresses; 423 for (pCurrentAddress = pAddresses;
424 pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next) 424 pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
425 { 425 {
426 if (pCurrentAddress->OperStatus == IfOperStatusUp) 426 if (pCurrentAddress->OperStatus == IfOperStatusUp)
427 { 427 {
428 IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL; 428 IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
429 for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL; 429 for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
430 unicast = unicast->Next) 430 unicast = unicast->Next)
431 { 431 {
432 if ((unicast->Address.lpSockaddr->sa_family == AF_INET || 432 if ((unicast->Address.lpSockaddr->sa_family == AF_INET ||
433 unicast->Address.lpSockaddr->sa_family == AF_INET6) && 433 unicast->Address.lpSockaddr->sa_family == AF_INET6) &&
434 (unicast->DadState == IpDadStateDeprecated || 434 (unicast->DadState == IpDadStateDeprecated ||
435 unicast->DadState == IpDadStatePreferred)) 435 unicast->DadState == IpDadStatePreferred))
436 count += 1; 436 count += 1;
437 } 437 }
438 } 438 }
439 } 439 }
440 440
441 if (count == 0) 441 if (count == 0)
442 { 442 {
443 *results = NULL; 443 *results = NULL;
444 *results_count = 0; 444 *results_count = 0;
445 GNUNET_free (pAddresses); 445 GNUNET_free (pAddresses);
446 GNUNET_free_non_null (interfaces4); 446 GNUNET_free_non_null (interfaces4);
447 GNUNET_free_non_null (interfaces6); 447 GNUNET_free_non_null (interfaces6);
448 return GNUNET_OK; 448 return GNUNET_OK;
449 } 449 }
450 450
451 *results = (struct EnumNICs3_results *) GNUNET_malloc ( 451 *results = (struct EnumNICs3_results *) GNUNET_malloc (
452 sizeof (struct EnumNICs3_results) * count); 452 sizeof (struct EnumNICs3_results) * count);
453 *results_count = count; 453 *results_count = count;
454 454
455 count = 0; 455 count = 0;
456 for (pCurrentAddress = pAddresses; 456 for (pCurrentAddress = pAddresses;
457 pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next) 457 pCurrentAddress != NULL; pCurrentAddress = pCurrentAddress->Next)
458 { 458 {
459 struct EnumNICs3_results *r; 459 struct EnumNICs3_results *r;
460 IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL; 460 IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL;
461 if (pCurrentAddress->OperStatus != IfOperStatusUp) 461 if (pCurrentAddress->OperStatus != IfOperStatusUp)
462 continue; 462 continue;
463 for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL; 463 for (unicast = pCurrentAddress->FirstUnicastAddress; unicast != NULL;
464 unicast = unicast->Next) 464 unicast = unicast->Next)
465 { 465 {
466 int i, j; 466 int i, j;
467 int mask_length = -1; 467 int mask_length = -1;
468 char dst[INET6_ADDRSTRLEN + 1]; 468 char dst[INET6_ADDRSTRLEN + 1];
469 469
470 if ((unicast->Address.lpSockaddr->sa_family != AF_INET && 470 if ((unicast->Address.lpSockaddr->sa_family != AF_INET &&
471 unicast->Address.lpSockaddr->sa_family != AF_INET6) || 471 unicast->Address.lpSockaddr->sa_family != AF_INET6) ||
472 (unicast->DadState != IpDadStateDeprecated && 472 (unicast->DadState != IpDadStateDeprecated &&
473 unicast->DadState != IpDadStatePreferred)) 473 unicast->DadState != IpDadStatePreferred))
474 continue; 474 continue;
475 475
476 r = &(*results)[count]; 476 r = &(*results)[count];
477 r->flags = 0; 477 r->flags = 0;
478 if (pCurrentAddress->IfIndex > 0 && 478 if (pCurrentAddress->IfIndex > 0 &&
479 pCurrentAddress->IfIndex == best_interface && 479 pCurrentAddress->IfIndex == best_interface &&
480 unicast->Address.lpSockaddr->sa_family == AF_INET) 480 unicast->Address.lpSockaddr->sa_family == AF_INET)
481 r->is_default = 1; 481 r->is_default = 1;
482 else if (pCurrentAddress->Ipv6IfIndex > 0 && 482 else if (pCurrentAddress->Ipv6IfIndex > 0 &&
483 pCurrentAddress->Ipv6IfIndex == best_interface6 && 483 pCurrentAddress->Ipv6IfIndex == best_interface6 &&
484 unicast->Address.lpSockaddr->sa_family == AF_INET6) 484 unicast->Address.lpSockaddr->sa_family == AF_INET6)
485 r->is_default = 1; 485 r->is_default = 1;
486 else 486 else
487 r->is_default = 0; 487 r->is_default = 0;
488 488
489 /* Don't choose default interface twice */ 489 /* Don't choose default interface twice */
490 if (r->is_default) 490 if (r->is_default)
491 best_interface = best_interface6 = 0; 491 best_interface = best_interface6 = 0;
492 492
493 if (!use_enum2) 493 if (!use_enum2)
494 { 494 {
495 memcpy (&r->address, unicast->Address.lpSockaddr, 495 memcpy (&r->address, unicast->Address.lpSockaddr,
496 unicast->Address.iSockaddrLength); 496 unicast->Address.iSockaddrLength);
497 memset (&r->mask, 0, sizeof (struct sockaddr)); 497 memset (&r->mask, 0, sizeof (struct sockaddr));
498 mask_length = ((IP_ADAPTER_UNICAST_ADDRESS_VISTA *) unicast)-> 498 mask_length = ((IP_ADAPTER_UNICAST_ADDRESS_VISTA *) unicast)->
499 OnLinkPrefixLength; 499 OnLinkPrefixLength;
500 /* OnLinkPrefixLength is the number of leading 1s in the mask. 500 /* OnLinkPrefixLength is the number of leading 1s in the mask.
501 * OnLinkPrefixLength is available on Vista and later (hence use_enum2). 501 * OnLinkPrefixLength is available on Vista and later (hence use_enum2).
502 */ 502 */
503 if (unicast->Address.lpSockaddr->sa_family == AF_INET) 503 if (unicast->Address.lpSockaddr->sa_family == AF_INET)
504 { 504 {
505 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; 505 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
506 for (i = 0; i < mask_length; i++) 506 for (i = 0; i < mask_length; i++)
507 ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8); 507 ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
508 } 508 }
509 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) 509 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
510 { 510 {
511 struct sockaddr_in6 *m = (struct sockaddr_in6 *) &r->mask; 511 struct sockaddr_in6 *m = (struct sockaddr_in6 *) &r->mask;
512 struct sockaddr_in6 *b = (struct sockaddr_in6 *) &r->broadcast; 512 struct sockaddr_in6 *b = (struct sockaddr_in6 *) &r->broadcast;
513 for (i = 0; i < mask_length; i++) 513 for (i = 0; i < mask_length; i++)
514 ((unsigned char *) &m->sin6_addr)[i / 8] |= 0x80 >> (i % 8); 514 ((unsigned char *) &m->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
515 memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength); 515 memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength);
516 for (i = mask_length; i < 128; i++) 516 for (i = mask_length; i < 128; i++)
517 ((unsigned char *) &b->sin6_addr)[i / 8] |= 0x80 >> (i % 8); 517 ((unsigned char *) &b->sin6_addr)[i / 8] |= 0x80 >> (i % 8);
518 } 518 }
519 r->flags |= ENUMNICS3_MASK_OK; 519 r->flags |= ENUMNICS3_MASK_OK;
520 } 520 }
521 else 521 else
522 { 522 {
523 int found = 0; 523 int found = 0;
524 if (unicast->Address.lpSockaddr->sa_family == AF_INET) 524 if (unicast->Address.lpSockaddr->sa_family == AF_INET)
525 { 525 {
526 for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); i++) 526 for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); i++)
527 { 527 {
528 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; 528 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
529 if (memcpy (&interfaces4[i].iiAddress.Address, 529 if (memcpy (&interfaces4[i].iiAddress.Address,
530 unicast->Address.lpSockaddr, 530 unicast->Address.lpSockaddr,
531 unicast->Address.iSockaddrLength) != 0) 531 unicast->Address.iSockaddrLength) != 0)
532 continue; 532 continue;
533 found = 1; 533 found = 1;
534 memcpy (&r->address, &interfaces4[i].iiAddress.Address, 534 memcpy (&r->address, &interfaces4[i].iiAddress.Address,
535 sizeof (struct sockaddr_in)); 535 sizeof (struct sockaddr_in));
536 memcpy (&r->mask, &interfaces4[i].iiNetmask.Address, 536 memcpy (&r->mask, &interfaces4[i].iiNetmask.Address,
537 sizeof (struct sockaddr_in)); 537 sizeof (struct sockaddr_in));
538 for (mask_length = 0; 538 for (mask_length = 0;
539 ((unsigned char *) &m->sin_addr)[mask_length / 8] & 539 ((unsigned char *) &m->sin_addr)[mask_length / 8] &
540 0x80 >> (mask_length % 8); mask_length++) 540 0x80 >> (mask_length % 8); mask_length++)
541 { 541 {
542 } 542 }
543 r->flags |= ENUMNICS3_MASK_OK; 543 r->flags |= ENUMNICS3_MASK_OK;
544 } 544 }
545 } 545 }
546 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) 546 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
547 { 547 {
548 for (i = 0; 548 for (i = 0;
549 interfaces6 != NULL && !found && i < interfaces6->iAddressCount; 549 interfaces6 != NULL && !found && i < interfaces6->iAddressCount;
550 i++) 550 i++)
551 { 551 {
552 if (memcpy (interfaces6->Address[i].lpSockaddr, 552 if (memcpy (interfaces6->Address[i].lpSockaddr,
553 unicast->Address.lpSockaddr, 553 unicast->Address.lpSockaddr,
554 unicast->Address.iSockaddrLength) != 0) 554 unicast->Address.iSockaddrLength) != 0)
555 continue; 555 continue;
556 found = 1; 556 found = 1;
557 memcpy (&r->address, interfaces6->Address[i].lpSockaddr, 557 memcpy (&r->address, interfaces6->Address[i].lpSockaddr,
558 sizeof (struct sockaddr_in6)); 558 sizeof (struct sockaddr_in6));
559 /* TODO: Find a way to reliably get network mask for IPv6 on XP */ 559 /* TODO: Find a way to reliably get network mask for IPv6 on XP */
560 memset (&r->mask, 0, sizeof (struct sockaddr)); 560 memset (&r->mask, 0, sizeof (struct sockaddr));
561 r->flags &= ~ENUMNICS3_MASK_OK; 561 r->flags &= ~ENUMNICS3_MASK_OK;
562 } 562 }
563 } 563 }
564 if (!found) 564 if (!found)
565 { 565 {
566 DebugBreak (); 566 DebugBreak ();
567 } 567 }
568 } 568 }
569 if (unicast->Address.lpSockaddr->sa_family == AF_INET) 569 if (unicast->Address.lpSockaddr->sa_family == AF_INET)
570 { 570 {
571 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; 571 struct sockaddr_in *m = (struct sockaddr_in *) &r->mask;
572 struct sockaddr_in *a = (struct sockaddr_in *) &r->address; 572 struct sockaddr_in *a = (struct sockaddr_in *) &r->address;
573 /* copy address to broadcast, then flip all the trailing bits not 573 /* copy address to broadcast, then flip all the trailing bits not
574 * falling under netmask to 1, 574 * falling under netmask to 1,
575 * so we get, 192.168.0.255 from, say, 192.168.0.43 with mask == 24. 575 * so we get, 192.168.0.255 from, say, 192.168.0.43 with mask == 24.
576 */ 576 */
577 memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength); 577 memcpy (&r->broadcast, &r->address, unicast->Address.iSockaddrLength);
578 for (i = mask_length; i < 32; i++) 578 for (i = mask_length; i < 32; i++)
579 ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8); 579 ((unsigned char *) &m->sin_addr)[i / 8] |= 0x80 >> (i % 8);
580 r->flags |= ENUMNICS3_BCAST_OK; 580 r->flags |= ENUMNICS3_BCAST_OK;
581 r->addr_size = sizeof (struct sockaddr_in); 581 r->addr_size = sizeof (struct sockaddr_in);
582 inet_ntop (AF_INET, &a->sin_addr, dst, INET_ADDRSTRLEN); 582 inet_ntop (AF_INET, &a->sin_addr, dst, INET_ADDRSTRLEN);
583 } 583 }
584 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) 584 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
585 { 585 {
586 struct sockaddr_in6 *a = (struct sockaddr_in6 *) &r->address; 586 struct sockaddr_in6 *a = (struct sockaddr_in6 *) &r->address;
587 /* for IPv6 broadcast is not defined, zero it down */ 587 /* for IPv6 broadcast is not defined, zero it down */
588 memset (&r->broadcast, 0, sizeof (struct sockaddr)); 588 memset (&r->broadcast, 0, sizeof (struct sockaddr));
589 r->flags &= ~ENUMNICS3_BCAST_OK; 589 r->flags &= ~ENUMNICS3_BCAST_OK;
590 r->addr_size = sizeof (struct sockaddr_in6); 590 r->addr_size = sizeof (struct sockaddr_in6);
591 inet_ntop (AF_INET6, &a->sin6_addr, dst, INET6_ADDRSTRLEN); 591 inet_ntop (AF_INET6, &a->sin6_addr, dst, INET6_ADDRSTRLEN);
592 } 592 }
593 593
594 i = 0; 594 i = 0;
595 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, 595 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
596 "%S (%s", pCurrentAddress->FriendlyName, dst); 596 "%S (%s", pCurrentAddress->FriendlyName, dst);
597 for (j = 0; j < pCurrentAddress->PhysicalAddressLength; j++) 597 for (j = 0; j < pCurrentAddress->PhysicalAddressLength; j++)
598 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, 598 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0,
599 "%s%02X",j > 0 ? ":" : " - ", pCurrentAddress->PhysicalAddress[j]); 599 "%s%02X",j > 0 ? ":" : " - ", pCurrentAddress->PhysicalAddress[j]);
600 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, ")"); 600 i += snprintf (&r->pretty_name[i], 1000 - i > 0 ? 1000 - i : 0, ")");
601 r->pretty_name[1000] = '\0'; 601 r->pretty_name[1000] = '\0';
602 count += 1; 602 count += 1;
603 } 603 }
604 } 604 }
605 605
606 if (use_enum2) 606 if (use_enum2)
607 { 607 {
608 GNUNET_free_non_null (interfaces4); 608 GNUNET_free_non_null (interfaces4);
609 GNUNET_free_non_null (interfaces6); 609 GNUNET_free_non_null (interfaces6);
610 } 610 }
611 611
612 GNUNET_free (pAddresses); 612 GNUNET_free (pAddresses);
613 return GNUNET_OK; 613 return GNUNET_OK;
614} 614}
615 615
616void 616void
617EnumNICs3_free (struct EnumNICs3_results *r) 617EnumNICs3_free (struct EnumNICs3_results *r)
618{ 618{
619 GNUNET_free_non_null (r); 619 GNUNET_free_non_null (r);
620} 620}
621 621
622 622
623/** 623/**
624 * Lists all network interfaces in a combo box 624 * Lists all network interfaces in a combo box
625 * Used by the basic GTK configurator 625 * Used by the basic GTK configurator
626 * 626 *
627 * @param callback function to call for each NIC 627 * @param callback function to call for each NIC
628 * @param callback_cls closure for callback 628 * @param callback_cls closure for callback
629 */ 629 */
630int 630int
631ListNICs (void (*callback) (void *, const char *, int), void * callback_cls) 631ListNICs (void (*callback) (void *, const char *, int), void * callback_cls)
632{ 632{
633 int r; 633 int r;
634 int i; 634 int i;
635 struct EnumNICs3_results *results = NULL; 635 struct EnumNICs3_results *results = NULL;
636 int results_count; 636 int results_count;
637 637
638 r = EnumNICs3 (&results, &results_count); 638 r = EnumNICs3 (&results, &results_count);
639 if (r != GNUNET_OK) 639 if (r != GNUNET_OK)
640 return GNUNET_NO; 640 return GNUNET_NO;
641 641
642 for (i = 0; i < results_count; i++) 642 for (i = 0; i < results_count; i++)
643 callback (callback_cls, results[i].pretty_name, results[i].is_default); 643 callback (callback_cls, results[i].pretty_name, results[i].is_default);
644 GNUNET_free_non_null (results); 644 GNUNET_free_non_null (results);
645 return GNUNET_YES; 645 return GNUNET_YES;
646} 646}
647 647
648/** 648/**
649 * @brief Installs the Windows service 649 * @brief Installs the Windows service
650 * @param servicename name of the service as diplayed by the SCM 650 * @param servicename name of the service as diplayed by the SCM
651 * @param application path to the application binary 651 * @param application path to the application binary
652 * @param username the name of the service's user account 652 * @param username the name of the service's user account
653 * @returns 0 on success 653 * @returns 0 on success
654 * 1 if the Windows version doesn't support services 654 * 1 if the Windows version doesn't support services
655 * 2 if the SCM could not be opened 655 * 2 if the SCM could not be opened
656 * 3 if the service could not be created 656 * 3 if the service could not be created
657 */ 657 */
658int InstallAsService(char *servicename, char *application, char *username) 658int InstallAsService(char *servicename, char *application, char *username)
659{ 659{
660 SC_HANDLE hManager, hService; 660 SC_HANDLE hManager, hService;
661 char szEXE[_MAX_PATH + 17] = "\""; 661 char szEXE[_MAX_PATH + 17] = "\"";
662 char *user = NULL; 662 char *user = NULL;
663 663
664 if (! GNOpenSCManager) 664 if (! GNOpenSCManager)
665 return 1; 665 return 1;
666 666
667 plibc_conv_to_win_path(application, szEXE + 1); 667 plibc_conv_to_win_path(application, szEXE + 1);
668 strcat(szEXE, "\" --win-service"); 668 strcat(szEXE, "\" --win-service");
669 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 669 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
670 if (! hManager) 670 if (! hManager)
671 return 2; 671 return 2;
672 672
673 if (username) 673 if (username)
674 { 674 {
675 user = (char *) malloc(strlen(username) + 3); 675 user = (char *) malloc(strlen(username) + 3);
676 sprintf(user, ".\\%s", username); 676 sprintf(user, ".\\%s", username);
677 } 677 }
678 678
679 hService = GNCreateService(hManager, (LPCTSTR) servicename, (LPCTSTR) servicename, 0, 679 hService = GNCreateService(hManager, (LPCTSTR) servicename, (LPCTSTR) servicename, 0,
680 SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, (LPCTSTR) szEXE, 680 SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, (LPCTSTR) szEXE,
681 NULL, NULL, NULL, (LPCTSTR) user, (LPCTSTR) username); 681 NULL, NULL, NULL, (LPCTSTR) user, (LPCTSTR) username);
682 682
683 if (user) 683 if (user)
684 free(user); 684 free(user);
685 685
686 if (! hService) 686 if (! hService)
687 return 3; 687 return 3;
688 688
689 GNCloseServiceHandle(hService); 689 GNCloseServiceHandle(hService);
690 690
691 return 0; 691 return 0;
692} 692}
693 693
694/** 694/**
695 * @brief Uninstall Windows service 695 * @brief Uninstall Windows service
696 * @param servicename name of the service to delete 696 * @param servicename name of the service to delete
697 * @returns 0 on success 697 * @returns 0 on success
698 * 1 if the Windows version doesn't support services 698 * 1 if the Windows version doesn't support services
699 * 2 if the SCM could not be openend 699 * 2 if the SCM could not be openend
700 * 3 if the service cannot be accessed 700 * 3 if the service cannot be accessed
701 * 4 if the service cannot be deleted 701 * 4 if the service cannot be deleted
702 */ 702 */
703int UninstallService(char *servicename) 703int UninstallService(char *servicename)
704{ 704{
705 SC_HANDLE hManager, hService; 705 SC_HANDLE hManager, hService;
706 706
707 if (! GNOpenSCManager) 707 if (! GNOpenSCManager)
708 return 1; 708 return 1;
709 709
710 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); 710 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
711 if (! hManager) 711 if (! hManager)
712 return 2; 712 return 2;
713 713
714 if (! (hService = GNOpenService(hManager, (LPCTSTR) servicename, DELETE))) 714 if (! (hService = GNOpenService(hManager, (LPCTSTR) servicename, DELETE)))
715 if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) 715 if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
716 return 3; 716 return 3;
717 else 717 else
718 goto closeSCM; 718 goto closeSCM;
719 719
720 if (! GNDeleteService(hService)) 720 if (! GNDeleteService(hService))
721 if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) 721 if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE)
722 return 4; 722 return 4;
723 723
724closeSCM: 724closeSCM:
725 GNCloseServiceHandle(hService); 725 GNCloseServiceHandle(hService);
726 726
727 return 0; 727 return 0;
728} 728}
729 729
730/** 730/**
731 * @author Scott Field, Microsoft 731 * @author Scott Field, Microsoft
732 * @see http://support.microsoft.com/?scid=kb;en-us;132958 732 * @see http://support.microsoft.com/?scid=kb;en-us;132958
733 * @date 12-Jul-95 733 * @date 12-Jul-95
734 */ 734 */
735void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String) 735void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
736{ 736{
737 DWORD StringLength; 737 DWORD StringLength;
738 738
739 if(String == NULL) 739 if(String == NULL)
740 { 740 {
741 LsaString->Buffer = NULL; 741 LsaString->Buffer = NULL;
742 LsaString->Length = 0; 742 LsaString->Length = 0;
743 LsaString->MaximumLength = 0; 743 LsaString->MaximumLength = 0;
744 return; 744 return;
745 } 745 }
746 746
747 StringLength = wcslen(String); 747 StringLength = wcslen(String);
748 LsaString->Buffer = String; 748 LsaString->Buffer = String;
749 LsaString->Length = (USHORT) StringLength *sizeof(WCHAR); 749 LsaString->Length = (USHORT) StringLength *sizeof(WCHAR);
750 LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR); 750 LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR);
751} 751}
752 752
753 753
754/** 754/**
755 * @author Scott Field, Microsoft 755 * @author Scott Field, Microsoft
756 * @see http://support.microsoft.com/?scid=kb;en-us;132958 756 * @see http://support.microsoft.com/?scid=kb;en-us;132958
757 * @date 12-Jul-95 757 * @date 12-Jul-95
758 */ 758 */
759NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle) 759NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle)
760{ 760{
761 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 761 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
762 LSA_UNICODE_STRING ServerString; 762 LSA_UNICODE_STRING ServerString;
763 PLSA_UNICODE_STRING Server = NULL; 763 PLSA_UNICODE_STRING Server = NULL;
764 764
765 /* Always initialize the object attributes to all zeroes. */ 765 /* Always initialize the object attributes to all zeroes. */
766 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); 766 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
767 767
768 if(ServerName != NULL) 768 if(ServerName != NULL)
769 { 769 {
770 /* Make a LSA_UNICODE_STRING out of the LPWSTR passed in */ 770 /* Make a LSA_UNICODE_STRING out of the LPWSTR passed in */
771 _InitLsaString(&ServerString, ServerName); 771 _InitLsaString(&ServerString, ServerName);
772 Server = &ServerString; 772 Server = &ServerString;
773 } 773 }
774 774
775 /* Attempt to open the policy. */ 775 /* Attempt to open the policy. */
776 return GNLsaOpenPolicy(Server, 776 return GNLsaOpenPolicy(Server,
777 &ObjectAttributes, DesiredAccess, PolicyHandle); 777 &ObjectAttributes, DesiredAccess, PolicyHandle);
778} 778}
779 779
780/** 780/**
781 * @brief Obtain a SID representing the supplied account on the supplied system 781 * @brief Obtain a SID representing the supplied account on the supplied system
782 * @return TRUE on success, FALSE on failure 782 * @return TRUE on success, FALSE on failure
783 * @author Scott Field, Microsoft 783 * @author Scott Field, Microsoft
784 * @date 12-Jul-95 784 * @date 12-Jul-95
785 * @remarks A buffer is allocated which contains the SID representing the 785 * @remarks A buffer is allocated which contains the SID representing the
786 * supplied account. This buffer should be freed when it is no longer 786 * supplied account. This buffer should be freed when it is no longer
787 * needed by calling\n 787 * needed by calling\n
788 * HeapFree(GetProcessHeap(), 0, buffer) 788 * HeapFree(GetProcessHeap(), 0, buffer)
789 * @remarks Call GetLastError() to obtain extended error information. 789 * @remarks Call GetLastError() to obtain extended error information.
790 * @see http://support.microsoft.com/?scid=kb;en-us;132958 790 * @see http://support.microsoft.com/?scid=kb;en-us;132958
791 */ 791 */
792BOOL _GetAccountSid(LPCTSTR SystemName, LPCTSTR AccountName, PSID * Sid) 792BOOL _GetAccountSid(LPCTSTR SystemName, LPCTSTR AccountName, PSID * Sid)
793{ 793{
794 LPTSTR ReferencedDomain = NULL; 794 LPTSTR ReferencedDomain = NULL;
795 DWORD cbSid = 128; /* initial allocation attempt */ 795 DWORD cbSid = 128; /* initial allocation attempt */
796 DWORD cchReferencedDomain = 16; /* initial allocation size */ 796 DWORD cchReferencedDomain = 16; /* initial allocation size */
797 SID_NAME_USE peUse; 797 SID_NAME_USE peUse;
798 BOOL bSuccess = FALSE; /* assume this function will fail */ 798 BOOL bSuccess = FALSE; /* assume this function will fail */
799 799
800 /* initial memory allocations */ 800 /* initial memory allocations */
801 if ((*Sid = HeapAlloc (GetProcessHeap (), 0, cbSid)) == NULL) 801 if ((*Sid = HeapAlloc (GetProcessHeap (), 0, cbSid)) == NULL)
802 return FALSE; 802 return FALSE;
803 803
804 if ((ReferencedDomain = (LPTSTR) HeapAlloc (GetProcessHeap (), 804 if ((ReferencedDomain = (LPTSTR) HeapAlloc (GetProcessHeap (),
805 0, 805 0,
806 cchReferencedDomain * 806 cchReferencedDomain *
807 sizeof (TCHAR))) == NULL) 807 sizeof (TCHAR))) == NULL)
808 return FALSE; 808 return FALSE;
809 809
810 /* Obtain the SID of the specified account on the specified system. */ 810 /* Obtain the SID of the specified account on the specified system. */
811 while (!GNLookupAccountName(SystemName, /* machine to lookup account on */ 811 while (!GNLookupAccountName(SystemName, /* machine to lookup account on */
812 AccountName, /* account to lookup */ 812 AccountName, /* account to lookup */
813 *Sid, /* SID of interest */ 813 *Sid, /* SID of interest */
814 &cbSid, /* size of SID */ 814 &cbSid, /* size of SID */
815 ReferencedDomain, /* domain account was found on */ 815 ReferencedDomain, /* domain account was found on */
816 &cchReferencedDomain, &peUse)) 816 &cchReferencedDomain, &peUse))
817 { 817 {
818 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 818 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
819 { 819 {
820 /* reallocate memory */ 820 /* reallocate memory */
821 if ((*Sid = HeapReAlloc (GetProcessHeap (), 0, *Sid, cbSid)) == NULL) 821 if ((*Sid = HeapReAlloc (GetProcessHeap (), 0, *Sid, cbSid)) == NULL)
822 return FALSE; 822 return FALSE;
823 823
824 if ((ReferencedDomain = (LPTSTR) HeapReAlloc (GetProcessHeap (), 824 if ((ReferencedDomain = (LPTSTR) HeapReAlloc (GetProcessHeap (),
825 0, 825 0,
826 ReferencedDomain, 826 ReferencedDomain,
827 cchReferencedDomain 827 cchReferencedDomain
828 * sizeof (TCHAR))) == NULL) 828 * sizeof (TCHAR))) == NULL)
829 return FALSE; 829 return FALSE;
830 } 830 }
831 else 831 else
832 goto end; 832 goto end;
833 } 833 }
834 834
835 /* Indicate success. */ 835 /* Indicate success. */
836 bSuccess = TRUE; 836 bSuccess = TRUE;
837 837
838end: 838end:
839 /* Cleanup and indicate failure, if appropriate. */ 839 /* Cleanup and indicate failure, if appropriate. */
840 HeapFree (GetProcessHeap (), 0, ReferencedDomain); 840 HeapFree (GetProcessHeap (), 0, ReferencedDomain);
841 841
842 if (!bSuccess) 842 if (!bSuccess)
843 { 843 {
844 if (*Sid != NULL) 844 if (*Sid != NULL)
845 { 845 {
846 HeapFree (GetProcessHeap (), 0, *Sid); 846 HeapFree (GetProcessHeap (), 0, *Sid);
847 *Sid = NULL; 847 *Sid = NULL;
848 } 848 }
849 } 849 }
850 850
851 return bSuccess; 851 return bSuccess;
852} 852}
853 853
854/** 854/**
855 * @author Scott Field, Microsoft 855 * @author Scott Field, Microsoft
856 * @see http://support.microsoft.com/?scid=kb;en-us;132958 856 * @see http://support.microsoft.com/?scid=kb;en-us;132958
857 * @date 12-Jul-95 857 * @date 12-Jul-95
858 */ 858 */
859NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle */ 859NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle */
860 PSID AccountSid, /* SID to grant privilege to */ 860 PSID AccountSid, /* SID to grant privilege to */
861 LPWSTR PrivilegeName, /* privilege to grant (Unicode) */ 861 LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
862 BOOL bEnable /* enable or disable */ 862 BOOL bEnable /* enable or disable */
863 ) 863 )
864{ 864{
865 LSA_UNICODE_STRING PrivilegeString; 865 LSA_UNICODE_STRING PrivilegeString;
866 866
867 /* Create a LSA_UNICODE_STRING for the privilege name. */ 867 /* Create a LSA_UNICODE_STRING for the privilege name. */
868 _InitLsaString(&PrivilegeString, PrivilegeName); 868 _InitLsaString(&PrivilegeString, PrivilegeName);
869 869
870 /* grant or revoke the privilege, accordingly */ 870 /* grant or revoke the privilege, accordingly */
871 if(bEnable) 871 if(bEnable)
872 { 872 {
873 NTSTATUS i; 873 NTSTATUS i;
874 874
875 i = GNLsaAddAccountRights(PolicyHandle, /* open policy handle */ 875 i = GNLsaAddAccountRights(PolicyHandle, /* open policy handle */
876 AccountSid, /* target SID */ 876 AccountSid, /* target SID */
877 &PrivilegeString, /* privileges */ 877 &PrivilegeString, /* privileges */
878 1 /* privilege count */ 878 1 /* privilege count */
879 ); 879 );
880 } 880 }
881 else 881 else
882 { 882 {
883 return GNLsaRemoveAccountRights(PolicyHandle, /* open policy handle */ 883 return GNLsaRemoveAccountRights(PolicyHandle, /* open policy handle */
884 AccountSid, /* target SID */ 884 AccountSid, /* target SID */
885 FALSE, /* do not disable all rights */ 885 FALSE, /* do not disable all rights */
886 &PrivilegeString, /* privileges */ 886 &PrivilegeString, /* privileges */
887 1 /* privilege count */ 887 1 /* privilege count */
888 ); 888 );
889 } 889 }
890} 890}
891 891
892/** 892/**
893 * @brief Create a Windows service account 893 * @brief Create a Windows service account
894 * @return 0 on success, > 0 otherwise 894 * @return 0 on success, > 0 otherwise
895 * @param pszName the name of the account 895 * @param pszName the name of the account
896 * @param pszDesc description of the account 896 * @param pszDesc description of the account
897 */ 897 */
898int CreateServiceAccount(const char *pszName, const char *pszDesc) 898int CreateServiceAccount(const char *pszName, const char *pszDesc)
899{ 899{
900 USER_INFO_1 ui; 900 USER_INFO_1 ui;
901 USER_INFO_1008 ui2; 901 USER_INFO_1008 ui2;
902 NET_API_STATUS nStatus; 902 NET_API_STATUS nStatus;
903 wchar_t wszName[MAX_NAME_LENGTH], wszDesc[MAX_NAME_LENGTH]; 903 wchar_t wszName[MAX_NAME_LENGTH], wszDesc[MAX_NAME_LENGTH];
904 DWORD dwErr; 904 DWORD dwErr;
905 LSA_HANDLE hPolicy; 905 LSA_HANDLE hPolicy;
906 PSID pSID; 906 PSID pSID;
907 907
908 if (! GNNetUserAdd) 908 if (! GNNetUserAdd)
909 return 1; 909 return 1;
910 mbstowcs(wszName, pszName, strlen(pszName) + 1); 910 mbstowcs(wszName, pszName, strlen(pszName) + 1);
911 mbstowcs(wszDesc, pszDesc, strlen(pszDesc) + 1); 911 mbstowcs(wszDesc, pszDesc, strlen(pszDesc) + 1);
912 912
913 memset(&ui, 0, sizeof(ui)); 913 memset(&ui, 0, sizeof(ui));
914 ui.usri1_name = wszName; 914 ui.usri1_name = wszName;
915 ui.usri1_password = wszName; /* account is locked anyway */ 915 ui.usri1_password = wszName; /* account is locked anyway */
916 ui.usri1_priv = USER_PRIV_USER; 916 ui.usri1_priv = USER_PRIV_USER;
917 ui.usri1_comment = wszDesc; 917 ui.usri1_comment = wszDesc;
918 ui.usri1_flags = UF_SCRIPT; 918 ui.usri1_flags = UF_SCRIPT;
919 919
920 nStatus = GNNetUserAdd(NULL, 1, (LPBYTE)&ui, NULL); 920 nStatus = GNNetUserAdd(NULL, 1, (LPBYTE)&ui, NULL);
921 921
922 if (nStatus != NERR_Success && nStatus != NERR_UserExists) 922 if (nStatus != NERR_Success && nStatus != NERR_UserExists)
923 return 2; 923 return 2;
924 924
925 ui2.usri1008_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD; 925 ui2.usri1008_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
926 GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL); 926 GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL);
927 927
928 if (_OpenPolicy(NULL, POLICY_ALL_ACCESS, &hPolicy) != 928 if (_OpenPolicy(NULL, POLICY_ALL_ACCESS, &hPolicy) !=
929 STATUS_SUCCESS) 929 STATUS_SUCCESS)
930 return 3; 930 return 3;
931 931
932 _GetAccountSid(NULL, (LPCTSTR) pszName, &pSID); 932 _GetAccountSid(NULL, (LPCTSTR) pszName, &pSID);
933 933
934 if (_SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeServiceLogonRight", TRUE) != STATUS_SUCCESS) 934 if (_SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeServiceLogonRight", TRUE) != STATUS_SUCCESS)
935 return 4; 935 return 4;
936 936
937 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyInteractiveLogonRight", TRUE); 937 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyInteractiveLogonRight", TRUE);
938 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyBatchLogonRight", TRUE); 938 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyBatchLogonRight", TRUE);
939 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyNetworkLogonRight", TRUE); 939 _SetPrivilegeOnAccount(hPolicy, pSID, (LPWSTR) L"SeDenyNetworkLogonRight", TRUE);
940 940
941 GNLsaClose(hPolicy); 941 GNLsaClose(hPolicy);
942 942
943 return 0; 943 return 0;
944} 944}
945 945
946/** 946/**
947 * @brief Grant permission to a file 947 * @brief Grant permission to a file
948 * @param lpszFileName the name of the file or directory 948 * @param lpszFileName the name of the file or directory
949 * @param lpszAccountName the user account 949 * @param lpszAccountName the user account
950 * @param dwAccessMask the desired access (e.g. GENERIC_ALL) 950 * @param dwAccessMask the desired access (e.g. GENERIC_ALL)
951 * @return TRUE on success 951 * @return TRUE on success
952 * @remark based on http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102& 952 * @remark based on http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102&
953 */ 953 */
954BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName, 954BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
955 DWORD dwAccessMask) 955 DWORD dwAccessMask)
956{ 956{
957 /* SID variables. */ 957 /* SID variables. */
958 SID_NAME_USE snuType; 958 SID_NAME_USE snuType;
959 TCHAR * szDomain = NULL; 959 TCHAR * szDomain = NULL;
960 DWORD cbDomain = 0; 960 DWORD cbDomain = 0;
961 LPVOID pUserSID = NULL; 961 LPVOID pUserSID = NULL;
962 DWORD cbUserSID = 0; 962 DWORD cbUserSID = 0;
963 963
964 /* File SD variables. */ 964 /* File SD variables. */
965 PSECURITY_DESCRIPTOR pFileSD = NULL; 965 PSECURITY_DESCRIPTOR pFileSD = NULL;
966 DWORD cbFileSD = 0; 966 DWORD cbFileSD = 0;
967 967
968 /* New SD variables. */ 968 /* New SD variables. */
969 SECURITY_DESCRIPTOR newSD; 969 SECURITY_DESCRIPTOR newSD;
970 970
971 /* ACL variables. */ 971 /* ACL variables. */
972 PACL pACL = NULL; 972 PACL pACL = NULL;
973 BOOL fDaclPresent; 973 BOOL fDaclPresent;
974 BOOL fDaclDefaulted; 974 BOOL fDaclDefaulted;
975 ACL_SIZE_INFORMATION AclInfo; 975 ACL_SIZE_INFORMATION AclInfo;
976 976
977 /* New ACL variables. */ 977 /* New ACL variables. */
978 PACL pNewACL = NULL; 978 PACL pNewACL = NULL;
979 DWORD cbNewACL = 0; 979 DWORD cbNewACL = 0;
980 980
981 /* Temporary ACE. */ 981 /* Temporary ACE. */
982 LPVOID pTempAce = NULL; 982 LPVOID pTempAce = NULL;
983 UINT CurrentAceIndex = 0; 983 UINT CurrentAceIndex = 0;
984 984
985 UINT newAceIndex = 0; 985 UINT newAceIndex = 0;
986 986
987 /* Assume function will fail. */ 987 /* Assume function will fail. */
988 BOOL fResult = FALSE; 988 BOOL fResult = FALSE;
989 BOOL fAPISuccess; 989 BOOL fAPISuccess;
990 990
991 SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION; 991 SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
992 992
993 /** 993 /**
994 * STEP 1: Get SID of the account name specified. 994 * STEP 1: Get SID of the account name specified.
995 */ 995 */
996 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName, 996 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
997 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType); 997 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
998 998
999 /* API should have failed with insufficient buffer. */ 999 /* API should have failed with insufficient buffer. */
1000 if (fAPISuccess) 1000 if (fAPISuccess)
1001 goto end; 1001 goto end;
1002 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 1002 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1003 goto end; 1003 goto end;
1004 } 1004 }
1005 1005
1006 pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID); 1006 pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID);
1007 if (!pUserSID) { 1007 if (!pUserSID) {
1008 goto end; 1008 goto end;
1009 } 1009 }
1010 1010
1011 szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDomain * sizeof(TCHAR)); 1011 szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDomain * sizeof(TCHAR));
1012 if (!szDomain) { 1012 if (!szDomain) {
1013 goto end; 1013 goto end;
1014 } 1014 }
1015 1015
1016 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName, 1016 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
1017 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType); 1017 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
1018 if (!fAPISuccess) { 1018 if (!fAPISuccess) {
1019 goto end; 1019 goto end;
1020 } 1020 }
1021 1021
1022 /** 1022 /**
1023 * STEP 2: Get security descriptor (SD) of the file specified. 1023 * STEP 2: Get security descriptor (SD) of the file specified.
1024 */ 1024 */
1025 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName, 1025 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
1026 secInfo, pFileSD, 0, &cbFileSD); 1026 secInfo, pFileSD, 0, &cbFileSD);
1027 1027
1028 /* API should have failed with insufficient buffer. */ 1028 /* API should have failed with insufficient buffer. */
1029 if (fAPISuccess) 1029 if (fAPISuccess)
1030 goto end; 1030 goto end;
1031 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 1031 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1032 goto end; 1032 goto end;
1033 } 1033 }
1034 1034
1035 pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1035 pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1036 cbFileSD); 1036 cbFileSD);
1037 if (!pFileSD) { 1037 if (!pFileSD) {
1038 goto end; 1038 goto end;
1039 } 1039 }
1040 1040
1041 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName, 1041 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
1042 secInfo, pFileSD, cbFileSD, &cbFileSD); 1042 secInfo, pFileSD, cbFileSD, &cbFileSD);
1043 if (!fAPISuccess) { 1043 if (!fAPISuccess) {
1044 goto end; 1044 goto end;
1045 } 1045 }
1046 1046
1047 /** 1047 /**
1048 * STEP 3: Initialize new SD. 1048 * STEP 3: Initialize new SD.
1049 */ 1049 */
1050 if (!GNInitializeSecurityDescriptor(&newSD, 1050 if (!GNInitializeSecurityDescriptor(&newSD,
1051 SECURITY_DESCRIPTOR_REVISION)) { 1051 SECURITY_DESCRIPTOR_REVISION)) {
1052 goto end; 1052 goto end;
1053 } 1053 }
1054 1054
1055 /** 1055 /**
1056 * STEP 4: Get DACL from the old SD. 1056 * STEP 4: Get DACL from the old SD.
1057 */ 1057 */
1058 if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL, 1058 if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
1059 &fDaclDefaulted)) { 1059 &fDaclDefaulted)) {
1060 goto end; 1060 goto end;
1061 } 1061 }
1062 1062
1063 /** 1063 /**
1064 * STEP 5: Get size information for DACL. 1064 * STEP 5: Get size information for DACL.
1065 */ 1065 */
1066 AclInfo.AceCount = 0; // Assume NULL DACL. 1066 AclInfo.AceCount = 0; // Assume NULL DACL.
1067 AclInfo.AclBytesFree = 0; 1067 AclInfo.AclBytesFree = 0;
1068 AclInfo.AclBytesInUse = sizeof(ACL); 1068 AclInfo.AclBytesInUse = sizeof(ACL);
1069 1069
1070 if (pACL == NULL) 1070 if (pACL == NULL)
1071 fDaclPresent = FALSE; 1071 fDaclPresent = FALSE;
1072 1072
1073 /* If not NULL DACL, gather size information from DACL. */ 1073 /* If not NULL DACL, gather size information from DACL. */
1074 if (fDaclPresent) { 1074 if (fDaclPresent) {
1075 1075
1076 if (!GNGetAclInformation(pACL, &AclInfo, 1076 if (!GNGetAclInformation(pACL, &AclInfo,
1077 sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) { 1077 sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
1078 goto end; 1078 goto end;
1079 } 1079 }
1080 } 1080 }
1081 1081
1082 /** 1082 /**
1083 * STEP 6: Compute size needed for the new ACL. 1083 * STEP 6: Compute size needed for the new ACL.
1084 */ 1084 */
1085 cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) 1085 cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
1086 + GetLengthSid(pUserSID) - sizeof(DWORD); 1086 + GetLengthSid(pUserSID) - sizeof(DWORD);
1087 1087
1088 /** 1088 /**
1089 * STEP 7: Allocate memory for new ACL. 1089 * STEP 7: Allocate memory for new ACL.
1090 */ 1090 */
1091 pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL); 1091 pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL);
1092 if (!pNewACL) { 1092 if (!pNewACL) {
1093 goto end; 1093 goto end;
1094 } 1094 }
1095 1095
1096 /** 1096 /**
1097 * STEP 8: Initialize the new ACL. 1097 * STEP 8: Initialize the new ACL.
1098 */ 1098 */
1099 if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) { 1099 if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
1100 goto end; 1100 goto end;
1101 } 1101 }
1102 1102
1103 /** 1103 /**
1104 * STEP 9 If DACL is present, copy all the ACEs from the old DACL 1104 * STEP 9 If DACL is present, copy all the ACEs from the old DACL
1105 * to the new DACL. 1105 * to the new DACL.
1106 * 1106 *
1107 * The following code assumes that the old DACL is 1107 * The following code assumes that the old DACL is
1108 * already in Windows 2000 preferred order. To conform 1108 * already in Windows 2000 preferred order. To conform
1109 * to the new Windows 2000 preferred order, first we will 1109 * to the new Windows 2000 preferred order, first we will
1110 * copy all non-inherited ACEs from the old DACL to the 1110 * copy all non-inherited ACEs from the old DACL to the
1111 * new DACL, irrespective of the ACE type. 1111 * new DACL, irrespective of the ACE type.
1112 */ 1112 */
1113 1113
1114 newAceIndex = 0; 1114 newAceIndex = 0;
1115 1115
1116 if (fDaclPresent && AclInfo.AceCount) { 1116 if (fDaclPresent && AclInfo.AceCount) {
1117 1117
1118 for (CurrentAceIndex = 0; 1118 for (CurrentAceIndex = 0;
1119 CurrentAceIndex < AclInfo.AceCount; 1119 CurrentAceIndex < AclInfo.AceCount;
1120 CurrentAceIndex++) { 1120 CurrentAceIndex++) {
1121 1121
1122 /** 1122 /**
1123 * TEP 10: Get an ACE. 1123 * TEP 10: Get an ACE.
1124 */ 1124 */
1125 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) { 1125 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
1126 goto end; 1126 goto end;
1127 } 1127 }
1128 1128
1129 /** 1129 /**
1130 * STEP 11: Check if it is a non-inherited ACE. 1130 * STEP 11: Check if it is a non-inherited ACE.
1131 * If it is an inherited ACE, break from the loop so 1131 * If it is an inherited ACE, break from the loop so
1132 * that the new access allowed non-inherited ACE can 1132 * that the new access allowed non-inherited ACE can
1133 * be added in the correct position, immediately after 1133 * be added in the correct position, immediately after
1134 * all non-inherited ACEs. 1134 * all non-inherited ACEs.
1135 */ 1135 */
1136 if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags 1136 if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
1137 & INHERITED_ACE) 1137 & INHERITED_ACE)
1138 break; 1138 break;
1139 1139
1140 /** 1140 /**
1141 * STEP 12: Skip adding the ACE, if the SID matches 1141 * STEP 12: Skip adding the ACE, if the SID matches
1142 * with the account specified, as we are going to 1142 * with the account specified, as we are going to
1143 * add an access allowed ACE with a different access 1143 * add an access allowed ACE with a different access
1144 * mask. 1144 * mask.
1145 */ 1145 */
1146 if (GNEqualSid(pUserSID, 1146 if (GNEqualSid(pUserSID,
1147 &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart))) 1147 &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
1148 continue; 1148 continue;
1149 1149
1150 /** 1150 /**
1151 * STEP 13: Add the ACE to the new ACL. 1151 * STEP 13: Add the ACE to the new ACL.
1152 */ 1152 */
1153 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, 1153 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
1154 ((PACE_HEADER) pTempAce)->AceSize)) { 1154 ((PACE_HEADER) pTempAce)->AceSize)) {
1155 goto end; 1155 goto end;
1156 } 1156 }
1157 1157
1158 newAceIndex++; 1158 newAceIndex++;
1159 } 1159 }
1160 } 1160 }
1161 1161
1162 /** 1162 /**
1163 * STEP 14: Add the access-allowed ACE to the new DACL. 1163 * STEP 14: Add the access-allowed ACE to the new DACL.
1164 * The new ACE added here will be in the correct position, 1164 * The new ACE added here will be in the correct position,
1165 * immediately after all existing non-inherited ACEs. 1165 * immediately after all existing non-inherited ACEs.
1166 */ 1166 */
1167 if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask, 1167 if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
1168 pUserSID)) { 1168 pUserSID)) {
1169 goto end; 1169 goto end;
1170 } 1170 }
1171 1171
1172 /** 1172 /**
1173 * STEP 14.5: Make new ACE inheritable 1173 * STEP 14.5: Make new ACE inheritable
1174 */ 1174 */
1175 if (!GetAce(pNewACL, newAceIndex, &pTempAce)) 1175 if (!GetAce(pNewACL, newAceIndex, &pTempAce))
1176 goto end; 1176 goto end;
1177 ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |= 1177 ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |=
1178 (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); 1178 (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
1179 1179
1180 /** 1180 /**
1181 * STEP 15: To conform to the new Windows 2000 preferred order, 1181 * STEP 15: To conform to the new Windows 2000 preferred order,
1182 * we will now copy the rest of inherited ACEs from the 1182 * we will now copy the rest of inherited ACEs from the
1183 * old DACL to the new DACL. 1183 * old DACL to the new DACL.
1184 */ 1184 */
1185 if (fDaclPresent && AclInfo.AceCount) { 1185 if (fDaclPresent && AclInfo.AceCount) {
1186 1186
1187 for (; 1187 for (;
1188 CurrentAceIndex < AclInfo.AceCount; 1188 CurrentAceIndex < AclInfo.AceCount;
1189 CurrentAceIndex++) { 1189 CurrentAceIndex++) {
1190 1190
1191 /** 1191 /**
1192 * STEP 16: Get an ACE. 1192 * STEP 16: Get an ACE.
1193 */ 1193 */
1194 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) { 1194 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
1195 goto end; 1195 goto end;
1196 } 1196 }
1197 1197
1198 /** 1198 /**
1199 * STEP 17: Add the ACE to the new ACL. 1199 * STEP 17: Add the ACE to the new ACL.
1200 */ 1200 */
1201 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, 1201 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
1202 ((PACE_HEADER) pTempAce)->AceSize)) { 1202 ((PACE_HEADER) pTempAce)->AceSize)) {
1203 goto end; 1203 goto end;
1204 } 1204 }
1205 } 1205 }
1206 } 1206 }
1207 1207
1208 /** 1208 /**
1209 * STEP 18: Set permissions 1209 * STEP 18: Set permissions
1210 */ 1210 */
1211 if (GNSetNamedSecurityInfo((LPTSTR) lpszFileName, SE_FILE_OBJECT, 1211 if (GNSetNamedSecurityInfo((LPTSTR) lpszFileName, SE_FILE_OBJECT,
1212 DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) { 1212 DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) {
1213 goto end; 1213 goto end;
1214 } 1214 }
1215 1215
1216 fResult = TRUE; 1216 fResult = TRUE;
1217 1217
1218end: 1218end:
1219 1219
1220 /** 1220 /**
1221 * STEP 19: Free allocated memory 1221 * STEP 19: Free allocated memory
1222 */ 1222 */
1223 if (pUserSID) 1223 if (pUserSID)
1224 HeapFree(GetProcessHeap(), 0, pUserSID); 1224 HeapFree(GetProcessHeap(), 0, pUserSID);
1225 1225
1226 if (szDomain) 1226 if (szDomain)
1227 HeapFree(GetProcessHeap(), 0, szDomain); 1227 HeapFree(GetProcessHeap(), 0, szDomain);
1228 1228
1229 if (pFileSD) 1229 if (pFileSD)
1230 HeapFree(GetProcessHeap(), 0, pFileSD); 1230 HeapFree(GetProcessHeap(), 0, pFileSD);
1231 1231
1232 if (pNewACL) 1232 if (pNewACL)
1233 HeapFree(GetProcessHeap(), 0, pNewACL); 1233 HeapFree(GetProcessHeap(), 0, pNewACL);
1234 1234
1235 return fResult; 1235 return fResult;
1236} 1236}
1237 1237
1238char *winErrorStr(const char *prefix, int dwErr) 1238char *winErrorStr(const char *prefix, int dwErr)
1239{ 1239{
1240 char *err, *ret; 1240 char *err, *ret;
1241 int mem; 1241 int mem;
1242 1242
1243 if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 1243 if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
1244 NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err, 1244 NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err,
1245 0, NULL )) 1245 0, NULL ))
1246 { 1246 {
1247 err = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, 1); 1247 err = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, 1);
1248 } 1248 }
1249 1249
1250 mem = strlen(err) + strlen(prefix) + 20; 1250 mem = strlen(err) + strlen(prefix) + 20;
1251 ret = (char *) malloc(mem); 1251 ret = (char *) malloc(mem);
1252 1252
1253 snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr); 1253 snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
1254 1254
1255 LocalFree(err); 1255 LocalFree(err);
1256 1256
1257 return ret; 1257 return ret;
1258} 1258}
1259 1259
1260/** 1260/**
1261 * Terminate a process by creating a remote thread within it, 1261 * Terminate a process by creating a remote thread within it,
1262 * which proceeds to call ExitProcess() inside that process. 1262 * which proceeds to call ExitProcess() inside that process.
@@ -1269,61 +1269,61 @@ char *winErrorStr(const char *prefix, int dwErr)
1269 * @param dwTimeout number of ms to wait for the process to terminate 1269 * @param dwTimeout number of ms to wait for the process to terminate
1270 * @return TRUE on success, FALSE on failure (check last error for the code) 1270 * @return TRUE on success, FALSE on failure (check last error for the code)
1271 */ 1271 */
1272BOOL 1272BOOL
1273SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout) 1273SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout)
1274{ 1274{
1275 DWORD dwTID, dwCode, dwErr = 0; 1275 DWORD dwTID, dwCode, dwErr = 0;
1276 HANDLE hProcessDup = INVALID_HANDLE_VALUE; 1276 HANDLE hProcessDup = INVALID_HANDLE_VALUE;
1277 HANDLE hRT = NULL; 1277 HANDLE hRT = NULL;
1278 HINSTANCE hKernel = GetModuleHandle ("Kernel32"); 1278 HINSTANCE hKernel = GetModuleHandle ("Kernel32");
1279 BOOL bSuccess = FALSE; 1279 BOOL bSuccess = FALSE;
1280 1280
1281 BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess, 1281 BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess,
1282 GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS, 1282 GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS,
1283 FALSE, 0); 1283 FALSE, 0);
1284 1284
1285 /* Detect the special case where the process is 1285 /* Detect the special case where the process is
1286 * already dead... 1286 * already dead...
1287 */ 1287 */
1288 if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) && 1288 if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) &&
1289 (STILL_ACTIVE == dwCode)) 1289 (STILL_ACTIVE == dwCode))
1290 { 1290 {
1291 FARPROC pfnExitProc; 1291 FARPROC pfnExitProc;
1292 1292
1293 pfnExitProc = GetProcAddress (hKernel, "ExitProcess"); 1293 pfnExitProc = GetProcAddress (hKernel, "ExitProcess");
1294 1294
1295 hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0, 1295 hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0,
1296 (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID); 1296 (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID);
1297 1297
1298 dwErr = GetLastError (); 1298 dwErr = GetLastError ();
1299 } 1299 }
1300 else 1300 else
1301 { 1301 {
1302 dwErr = ERROR_PROCESS_ABORTED; 1302 dwErr = ERROR_PROCESS_ABORTED;
1303 } 1303 }
1304 1304
1305 if (hRT) 1305 if (hRT)
1306 { 1306 {
1307 /* Must wait process to terminate to 1307 /* Must wait process to terminate to
1308 * guarantee that it has exited... 1308 * guarantee that it has exited...
1309 */ 1309 */
1310 DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess, 1310 DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess,
1311 dwTimeout); 1311 dwTimeout);
1312 if (dwWaitResult == WAIT_TIMEOUT) 1312 if (dwWaitResult == WAIT_TIMEOUT)
1313 dwErr = WAIT_TIMEOUT; 1313 dwErr = WAIT_TIMEOUT;
1314 else 1314 else
1315 dwErr = GetLastError (); 1315 dwErr = GetLastError ();
1316 1316
1317 CloseHandle (hRT); 1317 CloseHandle (hRT);
1318 bSuccess = dwErr == NO_ERROR; 1318 bSuccess = dwErr == NO_ERROR;
1319 } 1319 }
1320 1320
1321 if (bDup) 1321 if (bDup)
1322 CloseHandle (hProcessDup); 1322 CloseHandle (hProcessDup);
1323 1323
1324 SetLastError (dwErr); 1324 SetLastError (dwErr);
1325 1325
1326 return bSuccess; 1326 return bSuccess;
1327} 1327}
1328 1328
1329#endif 1329#endif