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