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