diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-09-28 09:12:05 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-09-28 09:12:05 +0000 |
commit | 5c70099f12dca398e9e6aaab13610207982f666f (patch) | |
tree | b91e50b26b735f1f9cf644d132228d093c15223f /src/util | |
parent | 23e7a5c1060d37c45a955e4bed961661af8cafb9 (diff) | |
download | gnunet-5c70099f12dca398e9e6aaab13610207982f666f.tar.gz gnunet-5c70099f12dca398e9e6aaab13610207982f666f.zip |
-dos2unix
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/crypto_crc.c | 1 | ||||
-rw-r--r-- | src/util/win.c | 2632 |
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 | ||
41 | int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); | 41 | int 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) \ |
65 | typedef 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 | typedef struct _IP_ADAPTER_WINS_SERVER_ADDRESS { | 76 | typedef 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 | ||
88 | typedef struct _IP_ADAPTER_GATEWAY_ADDRESS { | 88 | typedef 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 | ||
100 | typedef UINT32 NET_IF_COMPARTMENT_ID; | 100 | typedef UINT32 NET_IF_COMPARTMENT_ID; |
101 | typedef GUID NET_IF_NETWORK_GUID; | 101 | typedef GUID NET_IF_NETWORK_GUID; |
102 | 102 | ||
103 | typedef enum _NET_IF_CONNECTION_TYPE { | 103 | typedef 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 | ||
110 | typedef enum { | 110 | typedef 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 | /* |
121 | A DUID consists of a two-octet type code represented in network byte | 121 | A 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 | ||
128 | typedef union _NET_LUID { | 128 | typedef 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 | ||
139 | typedef struct _IP_ADAPTER_DNS_SUFFIX { | 139 | typedef 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) \ |
201 | typedef struct _IP_ADAPTER_ADDRESSES##suffix { \ | 201 | typedef 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 | ||
214 | static int | 214 | static int |
215 | EnumNICs_IPv6_get_ifs_count (SOCKET s) | 215 | EnumNICs_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 | ||
229 | static int | 229 | static int |
230 | EnumNICs_IPv6_get_ifs (SOCKET s, SOCKET_ADDRESS_LIST *inf, int size) | 230 | EnumNICs_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 | ||
255 | static int | 255 | static int |
256 | EnumNICs_IPv4_get_ifs (SOCKET s, INTERFACE_INFO **inf, int *size) | 256 | EnumNICs_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 | ||
293 | int | 293 | int |
294 | EnumNICs2 (INTERFACE_INFO **ifs4, int *ifs4_len, SOCKET_ADDRESS_LIST **ifs6) | 294 | EnumNICs2 (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 | } |
337 | error: | 337 | error: |
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 | */ |
352 | int | 352 | int |
353 | EnumNICs3 (struct EnumNICs3_results **results, int *results_count) | 353 | EnumNICs3 (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 | ||
616 | void | 616 | void |
617 | EnumNICs3_free (struct EnumNICs3_results *r) | 617 | EnumNICs3_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 | */ |
630 | int | 630 | int |
631 | ListNICs (void (*callback) (void *, const char *, int), void * callback_cls) | 631 | ListNICs (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 | */ |
658 | int InstallAsService(char *servicename, char *application, char *username) | 658 | int 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 | */ |
703 | int UninstallService(char *servicename) | 703 | int 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 | ||
724 | closeSCM: | 724 | closeSCM: |
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 | */ |
735 | void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String) | 735 | void _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 | */ |
759 | NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle) | 759 | NTSTATUS _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 | */ |
792 | BOOL _GetAccountSid(LPCTSTR SystemName, LPCTSTR AccountName, PSID * Sid) | 792 | BOOL _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 | ||
838 | end: | 838 | end: |
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 | */ |
859 | NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle */ | 859 | NTSTATUS _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 | */ |
898 | int CreateServiceAccount(const char *pszName, const char *pszDesc) | 898 | int 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 | */ |
954 | BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName, | 954 | BOOL 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 | ||
1218 | end: | 1218 | end: |
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 | ||
1238 | char *winErrorStr(const char *prefix, int dwErr) | 1238 | char *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 | */ |
1272 | BOOL | 1272 | BOOL |
1273 | SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout) | 1273 | SafeTerminateProcess (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 |