plibc: win32 related, socket
[oweals/gnunet.git] / src / util / winproc.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
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/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file util/winproc.c
23  * @brief Functions for MS Windows
24  * @author Nils Durner
25  */
26
27 #include "platform.h"
28 #include "gnunet_crypto_lib.h"
29 #include "gnunet_common.h"
30
31
32 #ifdef MINGW
33
34 static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi;
35 #ifdef W32_VEH
36 static void *GNWinVEH_handle = NULL;
37 #endif
38
39 TNtQuerySystemInformation GNNtQuerySystemInformation;
40 TGetIfEntry GNGetIfEntry;
41 TGetIpAddrTable GNGetIpAddrTable;
42 TGetIfTable GNGetIfTable;
43 TOpenSCManager GNOpenSCManager;
44 TCreateService GNCreateService;
45 TCloseServiceHandle GNCloseServiceHandle;
46 TDeleteService GNDeleteService;
47 TRegisterServiceCtrlHandler GNRegisterServiceCtrlHandler;
48 TSetServiceStatus GNSetServiceStatus;
49 TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
50 TControlService GNControlService;
51 TOpenService GNOpenService;
52 TGetBestInterfaceEx GNGetBestInterfaceEx;
53 TGetAdaptersInfo GNGetAdaptersInfo;
54 TNetUserAdd GNNetUserAdd;
55 TNetUserSetInfo GNNetUserSetInfo;
56 TLsaOpenPolicy GNLsaOpenPolicy;
57 TLsaAddAccountRights GNLsaAddAccountRights;
58 TLsaRemoveAccountRights GNLsaRemoveAccountRights;
59 TLsaClose GNLsaClose;
60 TLookupAccountName GNLookupAccountName;
61 TGetFileSecurity GNGetFileSecurity;
62 TInitializeSecurityDescriptor GNInitializeSecurityDescriptor;
63 TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl;
64 TGetAclInformation GNGetAclInformation;
65 TInitializeAcl GNInitializeAcl;
66 TGetAce GNGetAce;
67 TEqualSid GNEqualSid;
68 TAddAce GNAddAce;
69 TAddAccessAllowedAce GNAddAccessAllowedAce;
70 TSetNamedSecurityInfo GNSetNamedSecurityInfo;
71
72 #define LOG(kind, ...) GNUNET_log_from(kind, "util-winproc", __VA_ARGS__)
73 /**
74  * Log (panic) messages from PlibC
75  */
76 void
77 plibc_panic(int err, char *msg)
78 {
79   LOG(((err == INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
80       "%s", msg);
81 }
82
83 #ifdef W32_VEH
84 /**
85  * Handles exceptions (useful for debugging).
86  * Issues a DebugBreak() call if the process is being debugged (not really
87  * useful - if the process is being debugged, this handler won't be invoked
88  * anyway). If it is not, runs a debugger from GNUNET_DEBUGGER env var,
89  * substituting first %u in it for PID, and the second one for the event,
90  * that should be set once the debugger attaches itself (otherwise the
91  * only way out of WaitForSingleObject() is to time out after 1 minute).
92  */
93 LONG __stdcall
94 GNWinVEH(PEXCEPTION_POINTERS ExceptionInfo)
95 {
96   char debugger[MAX_PATH + 1];
97   char *debugger_env = NULL;
98
99   if (IsDebuggerPresent())
100     {
101       DebugBreak();
102       return EXCEPTION_CONTINUE_EXECUTION;
103     }
104   debugger_env = getenv("GNUNET_DEBUGGER");
105   if (debugger_env != NULL)
106     {
107       STARTUPINFO si;
108       PROCESS_INFORMATION pi;
109       HANDLE event;
110       SECURITY_ATTRIBUTES sa;
111       memset(&si, 0, sizeof(si));
112       si.cb = sizeof(si);
113       memset(&pi, 0, sizeof(pi));
114       memset(&sa, 0, sizeof(sa));
115       sa.nLength = sizeof(sa);
116       sa.bInheritHandle = TRUE;
117       event = CreateEvent(&sa, FALSE, FALSE, NULL);
118       snprintf(debugger, MAX_PATH + 1, debugger_env, GetCurrentProcessId(), (uintptr_t)event);
119       debugger[MAX_PATH] = '\0';
120       if (0 != CreateProcessA(NULL, debugger, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
121         {
122           CloseHandle(pi.hProcess);
123           CloseHandle(pi.hThread);
124           WaitForSingleObject(event, 60000);
125           CloseHandle(event);
126           if (IsDebuggerPresent())
127             {
128               return EXCEPTION_CONTINUE_EXECUTION;
129             }
130         }
131       else
132         CloseHandle(event);
133     }
134   return EXCEPTION_CONTINUE_SEARCH;
135 }
136 #endif
137
138 /**
139  * @brief Initialize PlibC and set up Windows environment
140  * @param logging context, NULL means stderr
141  * @return Error code from winerror.h, ERROR_SUCCESS on success
142  */
143 int
144 GNInitWinEnv()
145 {
146   int ret;
147
148   plibc_initialized();
149   plibc_set_panic_proc(plibc_panic);
150   ret = plibc_init_utf8("GNU", PACKAGE, 1);
151   plibc_set_stat_size_size(sizeof(((struct stat *)0)->st_size));
152   plibc_set_stat_time_size(sizeof(((struct stat *)0)->st_mtime));
153   /* don't load other DLLs twice */
154   if (hNTDLL)
155     return ret;
156
157 #ifdef W32_VEH
158   if (GNWinVEH_handle == NULL)
159     {
160       GNWinVEH_handle = AddVectoredExceptionHandler(1, &GNWinVEH);
161       if (GNWinVEH_handle == NULL)
162         {
163           /* This is bad, but what can we do? */
164           printf("Failed to set up an exception handler!\n");
165         }
166     }
167 #endif
168
169   hNTDLL = LoadLibrary("ntdll.dll");
170
171   /* Function to get CPU usage under Win NT */
172   if (hNTDLL)
173     {
174       GNNtQuerySystemInformation =
175         (TNtQuerySystemInformation)GetProcAddress(hNTDLL,
176                                                   "NtQuerySystemInformation");
177     }
178   else
179     {
180       GNNtQuerySystemInformation = NULL;
181     }
182
183   /* Functions to get information about a network adapter */
184   hIphlpapi = LoadLibrary("iphlpapi.dll");
185   if (hIphlpapi)
186     {
187       GNGetIfEntry = (TGetIfEntry)GetProcAddress(hIphlpapi, "GetIfEntry");
188       GNGetIpAddrTable =
189         (TGetIpAddrTable)GetProcAddress(hIphlpapi, "GetIpAddrTable");
190       GNGetIfTable = (TGetIfTable)GetProcAddress(hIphlpapi, "GetIfTable");
191       GNGetBestInterfaceEx =
192         (TGetBestInterfaceEx)GetProcAddress(hIphlpapi, "GetBestInterfaceEx");
193       GNGetAdaptersInfo =
194         (TGetAdaptersInfo)GetProcAddress(hIphlpapi, "GetAdaptersInfo");
195     }
196   else
197     {
198       GNGetIfEntry = NULL;
199       GNGetIpAddrTable = NULL;
200       GNGetIfTable = NULL;
201       GNGetBestInterfaceEx = NULL;
202       GNGetAdaptersInfo = NULL;
203     }
204
205   /* Service & Account functions */
206   hAdvapi = LoadLibrary("advapi32.dll");
207   if (hAdvapi)
208     {
209       GNOpenSCManager =
210         (TOpenSCManager)GetProcAddress(hAdvapi, "OpenSCManagerA");
211       GNCreateService =
212         (TCreateService)GetProcAddress(hAdvapi, "CreateServiceA");
213       GNCloseServiceHandle =
214         (TCloseServiceHandle)GetProcAddress(hAdvapi, "CloseServiceHandle");
215       GNDeleteService =
216         (TDeleteService)GetProcAddress(hAdvapi, "DeleteService");
217       GNRegisterServiceCtrlHandler =
218         (TRegisterServiceCtrlHandler)GetProcAddress(hAdvapi,
219                                                     "RegisterServiceCtrlHandlerA");
220       GNSetServiceStatus =
221         (TSetServiceStatus)GetProcAddress(hAdvapi, "SetServiceStatus");
222       GNStartServiceCtrlDispatcher =
223         (TStartServiceCtrlDispatcher)GetProcAddress(hAdvapi,
224                                                     "StartServiceCtrlDispatcherA");
225       GNControlService =
226         (TControlService)GetProcAddress(hAdvapi, "ControlService");
227       GNOpenService = (TOpenService)GetProcAddress(hAdvapi, "OpenServiceA");
228
229       GNLsaOpenPolicy =
230         (TLsaOpenPolicy)GetProcAddress(hAdvapi, "LsaOpenPolicy");
231       GNLsaAddAccountRights =
232         (TLsaAddAccountRights)GetProcAddress(hAdvapi, "LsaAddAccountRights");
233       GNLsaRemoveAccountRights =
234         (TLsaRemoveAccountRights)GetProcAddress(hAdvapi,
235                                                 "LsaRemoveAccountRights");
236       GNLsaClose = (TLsaClose)GetProcAddress(hAdvapi, "LsaClose");
237       GNLookupAccountName =
238         (TLookupAccountName)GetProcAddress(hAdvapi, "LookupAccountNameA");
239
240       GNGetFileSecurity =
241         (TGetFileSecurity)GetProcAddress(hAdvapi, "GetFileSecurityA");
242       GNInitializeSecurityDescriptor =
243         (TInitializeSecurityDescriptor)GetProcAddress(hAdvapi,
244                                                       "InitializeSecurityDescriptor");
245       GNGetSecurityDescriptorDacl =
246         (TGetSecurityDescriptorDacl)GetProcAddress(hAdvapi,
247                                                    "GetSecurityDescriptorDacl");
248       GNGetAclInformation =
249         (TGetAclInformation)GetProcAddress(hAdvapi, "GetAclInformation");
250       GNInitializeAcl =
251         (TInitializeAcl)GetProcAddress(hAdvapi, "InitializeAcl");
252       GNGetAce = (TGetAce)GetProcAddress(hAdvapi, "GetAce");
253       GNEqualSid = (TEqualSid)GetProcAddress(hAdvapi, "EqualSid");
254       GNAddAce = (TAddAce)GetProcAddress(hAdvapi, "AddAce");
255       GNAddAccessAllowedAce =
256         (TAddAccessAllowedAce)GetProcAddress(hAdvapi, "AddAccessAllowedAce");
257       GNSetNamedSecurityInfo =
258         (TSetNamedSecurityInfo)GetProcAddress(hAdvapi,
259                                               "SetNamedSecurityInfoA");
260     }
261   else
262     {
263       GNOpenSCManager = NULL;
264       GNCreateService = NULL;
265       GNCloseServiceHandle = NULL;
266       GNDeleteService = NULL;
267       GNRegisterServiceCtrlHandler = NULL;
268       GNSetServiceStatus = NULL;
269       GNStartServiceCtrlDispatcher = NULL;
270       GNControlService = NULL;
271       GNOpenService = NULL;
272
273       GNLsaOpenPolicy = NULL;
274       GNLsaAddAccountRights = NULL;
275       GNLsaRemoveAccountRights = NULL;
276       GNLsaClose = NULL;
277       GNLookupAccountName = NULL;
278
279       GNGetFileSecurity = NULL;
280       GNInitializeSecurityDescriptor = NULL;
281       GNGetSecurityDescriptorDacl = NULL;
282       GNGetAclInformation = NULL;
283       GNInitializeAcl = NULL;
284       GNGetAce = NULL;
285       GNEqualSid = NULL;
286       GNAddAce = NULL;
287       GNAddAccessAllowedAce = NULL;
288       GNSetNamedSecurityInfo = NULL;
289     }
290
291   /* Account function */
292   hNetapi = LoadLibrary("netapi32.dll");
293   if (hNetapi)
294     {
295       GNNetUserAdd = (TNetUserAdd)GetProcAddress(hNetapi, "NetUserAdd");
296       GNNetUserSetInfo =
297         (TNetUserSetInfo)GetProcAddress(hNetapi, "NetUserSetInfo");
298     }
299   else
300     {
301       GNNetUserAdd = NULL;
302       GNNetUserSetInfo = NULL;
303     }
304
305   return ret;
306 }
307
308 /**
309  * Clean up Windows environment
310  */
311 void
312 GNShutdownWinEnv()
313 {
314   plibc_shutdown();
315
316 #ifdef W32_VEH
317   if (GNWinVEH_handle != NULL)
318     {
319       RemoveVectoredExceptionHandler(GNWinVEH_handle);
320       GNWinVEH_handle = NULL;
321     }
322 #endif
323
324   FreeLibrary(hNTDLL);
325   FreeLibrary(hIphlpapi);
326   FreeLibrary(hAdvapi);
327   FreeLibrary(hNetapi);
328
329   CoUninitialize();
330 }
331
332 #endif /* MINGW */
333
334 #if !HAVE_ATOLL
335 long long
336 atoll(const char *nptr)
337 {
338   return atol(nptr);
339 }
340 #endif