Don't shadow the system() function
[oweals/gnunet.git] / src / util / winproc.c
index 469e1fb416c0be8e63b2bb6d35d6f5eb650f346c..7f020c6dc79c579cd66b75fd1472b25f6f2ce6fb 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 */
 
 /**
 */
 
 /**
- * @file util/win/winproc.c
+ * @file util/winproc.c
  * @brief Functions for MS Windows
  * @author Nils Durner
  */
 
 #include "platform.h"
  * @brief Functions for MS Windows
  * @author Nils Durner
  */
 
 #include "platform.h"
+#include "gnunet_crypto_lib.h"
 #include "gnunet_common.h"
 
 #include "gnunet_common.h"
 
-#define DEBUG_WINPROC 0
 
 #ifdef MINGW
 
 static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi;
 
 #ifdef MINGW
 
 static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi;
+#ifdef W32_VEH
+static void *GNWinVEH_handle = NULL;
+#endif
 
 TNtQuerySystemInformation GNNtQuerySystemInformation;
 TGetIfEntry GNGetIfEntry;
 
 TNtQuerySystemInformation GNNtQuerySystemInformation;
 TGetIfEntry GNGetIfEntry;
@@ -46,8 +49,8 @@ TSetServiceStatus GNSetServiceStatus;
 TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
 TControlService GNControlService;
 TOpenService GNOpenService;
 TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
 TControlService GNControlService;
 TOpenService GNOpenService;
-TGetBestInterface GNGetBestInterface;
-TGetAdaptersInfo GGetAdaptersInfo;
+TGetBestInterfaceEx GNGetBestInterfaceEx;
+TGetAdaptersInfo GNGetAdaptersInfo;
 TNetUserAdd GNNetUserAdd;
 TNetUserSetInfo GNNetUserSetInfo;
 TLsaOpenPolicy GNLsaOpenPolicy;
 TNetUserAdd GNNetUserAdd;
 TNetUserSetInfo GNNetUserSetInfo;
 TLsaOpenPolicy GNLsaOpenPolicy;
@@ -66,163 +69,237 @@ TAddAce GNAddAce;
 TAddAccessAllowedAce GNAddAccessAllowedAce;
 TSetNamedSecurityInfo GNSetNamedSecurityInfo;
 
 TAddAccessAllowedAce GNAddAccessAllowedAce;
 TSetNamedSecurityInfo GNSetNamedSecurityInfo;
 
+#define LOG(kind,...) GNUNET_log_from (kind, "winproc", __VA_ARGS__)
 /**
  * Log (panic) messages from PlibC
  */
 void
 plibc_panic (int err, char *msg)
 {
 /**
  * Log (panic) messages from PlibC
  */
 void
 plibc_panic (int err, char *msg)
 {
-  GNUNET_log (((err ==
-                   INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
-                 "%s", msg);
+  LOG (((err == INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
+       "%s", msg);
 }
 
 }
 
+#ifdef W32_VEH
+/**
+ * Handles exceptions (useful for debugging).
+ * Issues a DebugBreak() call if the process is being debugged (not really
+ * useful - if the process is being debugged, this handler won't be invoked
+ * anyway). If it is not, runs a debugger from GNUNET_DEBUGGER env var,
+ * substituting first %u in it for PID, and the second one for the event,
+ * that should be set once the debugger attaches itself (otherwise the
+ * only way out of WaitForSingleObject() is to time out after 1 minute).
+ */
+LONG __stdcall
+GNWinVEH (PEXCEPTION_POINTERS ExceptionInfo)
+{
+  char debugger[MAX_PATH + 1];
+  char *debugger_env = NULL;
+  if (IsDebuggerPresent ())
+  {
+    DebugBreak ();
+    return EXCEPTION_CONTINUE_EXECUTION;
+  }
+  debugger_env = getenv ("GNUNET_DEBUGGER");
+  if (debugger_env != NULL)
+  {
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    HANDLE event;
+    SECURITY_ATTRIBUTES sa;
+    memset (&si, 0, sizeof (si));
+    si.cb = sizeof (si);
+    memset (&pi, 0, sizeof (pi));
+    memset (&sa, 0, sizeof (sa));
+    sa.nLength = sizeof (sa);
+    sa.bInheritHandle = TRUE;
+    event = CreateEvent (&sa, FALSE, FALSE, NULL);
+    snprintf (debugger, MAX_PATH + 1, debugger_env, GetCurrentProcessId (), (uintptr_t) event);
+    debugger[MAX_PATH] = '\0';
+    if (0 != CreateProcessA (NULL, debugger, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
+    {
+      CloseHandle (pi.hProcess);
+      CloseHandle (pi.hThread);
+      WaitForSingleObject (event, 60000);
+      CloseHandle (event);
+      if (IsDebuggerPresent ())
+      {
+        return EXCEPTION_CONTINUE_EXECUTION;
+      }
+    }
+    else
+      CloseHandle (event);
+  }
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
 /**
  * @brief Initialize PlibC and set up Windows environment
  * @param logging context, NULL means stderr
  * @return Error code from winerror.h, ERROR_SUCCESS on success
 */
 int
 /**
  * @brief Initialize PlibC and set up Windows environment
  * @param logging context, NULL means stderr
  * @return Error code from winerror.h, ERROR_SUCCESS on success
 */
 int
-InitWinEnv ()
+GNInitWinEnv ()
 {
   int ret;
 
   plibc_initialized ();
   plibc_set_panic_proc (plibc_panic);
 {
   int ret;
 
   plibc_initialized ();
   plibc_set_panic_proc (plibc_panic);
-  ret = plibc_init ("GNU", PACKAGE);
-
+  ret = plibc_init_utf8 ("GNU", PACKAGE, 1);
+  plibc_set_stat_size_size (sizeof (((struct stat *) 0)->st_size));
+  plibc_set_stat_time_size (sizeof (((struct stat *) 0)->st_mtime));
   /* don't load other DLLs twice */
   if (hNTDLL)
     return ret;
 
   /* don't load other DLLs twice */
   if (hNTDLL)
     return ret;
 
+#ifdef W32_VEH
+  if (GNWinVEH_handle == NULL)
+  {
+    GNWinVEH_handle = AddVectoredExceptionHandler (1, &GNWinVEH);
+    if (GNWinVEH_handle == NULL)
+    {
+      /* This is bad, but what can we do? */
+      printf ("Failed to set up an exception handler!\n");
+    }
+  }
+#endif
+
   hNTDLL = LoadLibrary ("ntdll.dll");
 
   /* Function to get CPU usage under Win NT */
   if (hNTDLL)
   hNTDLL = LoadLibrary ("ntdll.dll");
 
   /* Function to get CPU usage under Win NT */
   if (hNTDLL)
-    {
-      GNNtQuerySystemInformation = (TNtQuerySystemInformation)
-        GetProcAddress (hNTDLL, "NtQuerySystemInformation");
-    }
+  {
+    GNNtQuerySystemInformation =
+        (TNtQuerySystemInformation) GetProcAddress (hNTDLL,
+                                                    "NtQuerySystemInformation");
+  }
   else
   else
-    {
-      GNNtQuerySystemInformation = NULL;
-    }
+  {
+    GNNtQuerySystemInformation = NULL;
+  }
 
   /* Functions to get information about a network adapter */
   hIphlpapi = LoadLibrary ("iphlpapi.dll");
   if (hIphlpapi)
 
   /* Functions to get information about a network adapter */
   hIphlpapi = LoadLibrary ("iphlpapi.dll");
   if (hIphlpapi)
-    {
-      GNGetIfEntry = (TGetIfEntry) GetProcAddress (hIphlpapi, "GetIfEntry");
-      GNGetIpAddrTable = (TGetIpAddrTable) GetProcAddress (hIphlpapi,
-                                                           "GetIpAddrTable");
-      GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable");
-      GNGetBestInterface = (TGetBestInterface) GetProcAddress (hIphlpapi,
-                                                               "GetBestInterface");
-      GGetAdaptersInfo = (TGetAdaptersInfo) GetProcAddress (hIphlpapi,
-                                                            "GetAdaptersInfo");
-    }
+  {
+    GNGetIfEntry = (TGetIfEntry) GetProcAddress (hIphlpapi, "GetIfEntry");
+    GNGetIpAddrTable =
+        (TGetIpAddrTable) GetProcAddress (hIphlpapi, "GetIpAddrTable");
+    GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable");
+    GNGetBestInterfaceEx =
+        (TGetBestInterfaceEx) GetProcAddress (hIphlpapi, "GetBestInterfaceEx");
+    GNGetAdaptersInfo =
+        (TGetAdaptersInfo) GetProcAddress (hIphlpapi, "GetAdaptersInfo");
+  }
   else
   else
-    {
-      GNGetIfEntry = NULL;
-      GNGetIpAddrTable = NULL;
-      GNGetIfTable = NULL;
-      GNGetBestInterface = NULL;
-      GGetAdaptersInfo = NULL;
-    }
+  {
+    GNGetIfEntry = NULL;
+    GNGetIpAddrTable = NULL;
+    GNGetIfTable = NULL;
+    GNGetBestInterfaceEx = NULL;
+    GNGetAdaptersInfo = NULL;
+  }
 
   /* Service & Account functions */
   hAdvapi = LoadLibrary ("advapi32.dll");
   if (hAdvapi)
 
   /* Service & Account functions */
   hAdvapi = LoadLibrary ("advapi32.dll");
   if (hAdvapi)
-    {
-      GNOpenSCManager = (TOpenSCManager)
-        GetProcAddress (hAdvapi, "OpenSCManagerA");
-      GNCreateService = (TCreateService)
-        GetProcAddress (hAdvapi, "CreateServiceA");
-      GNCloseServiceHandle = (TCloseServiceHandle)
-        GetProcAddress (hAdvapi, "CloseServiceHandle");
-      GNDeleteService = (TDeleteService)
-        GetProcAddress (hAdvapi, "DeleteService");
-      GNRegisterServiceCtrlHandler = (TRegisterServiceCtrlHandler)
-        GetProcAddress (hAdvapi, "RegisterServiceCtrlHandlerA");
-      GNSetServiceStatus = (TSetServiceStatus)
-        GetProcAddress (hAdvapi, "SetServiceStatus");
-      GNStartServiceCtrlDispatcher = (TStartServiceCtrlDispatcher)
-        GetProcAddress (hAdvapi, "StartServiceCtrlDispatcherA");
-      GNControlService = (TControlService)
-        GetProcAddress (hAdvapi, "ControlService");
-      GNOpenService = (TOpenService) GetProcAddress (hAdvapi, "OpenServiceA");
-
-      GNLsaOpenPolicy = (TLsaOpenPolicy)
-        GetProcAddress (hAdvapi, "LsaOpenPolicy");
-      GNLsaAddAccountRights = (TLsaAddAccountRights)
-        GetProcAddress (hAdvapi, "LsaAddAccountRights");
-      GNLsaRemoveAccountRights = (TLsaRemoveAccountRights)
-        GetProcAddress (hAdvapi, "LsaRemoveAccountRights");
-      GNLsaClose = (TLsaClose) GetProcAddress (hAdvapi, "LsaClose");
-      GNLookupAccountName = (TLookupAccountName)
-        GetProcAddress (hAdvapi, "LookupAccountNameA");
-
-      GNGetFileSecurity = (TGetFileSecurity)
-        GetProcAddress (hAdvapi, "GetFileSecurityA");
-      GNInitializeSecurityDescriptor = (TInitializeSecurityDescriptor)
-        GetProcAddress (hAdvapi, "InitializeSecurityDescriptor");
-      GNGetSecurityDescriptorDacl = (TGetSecurityDescriptorDacl)
-        GetProcAddress (hAdvapi, "GetSecurityDescriptorDacl");
-      GNGetAclInformation = (TGetAclInformation)
-        GetProcAddress (hAdvapi, "GetAclInformation");
-      GNInitializeAcl = (TInitializeAcl)
-        GetProcAddress (hAdvapi, "InitializeAcl");
-      GNGetAce = (TGetAce) GetProcAddress (hAdvapi, "GetAce");
-      GNEqualSid = (TEqualSid) GetProcAddress (hAdvapi, "EqualSid");
-      GNAddAce = (TAddAce) GetProcAddress (hAdvapi, "AddAce");
-      GNAddAccessAllowedAce = (TAddAccessAllowedAce)
-        GetProcAddress (hAdvapi, "AddAccessAllowedAce");
-      GNSetNamedSecurityInfo = (TSetNamedSecurityInfo)
-        GetProcAddress (hAdvapi, "SetNamedSecurityInfoA");
-    }
+  {
+    GNOpenSCManager =
+        (TOpenSCManager) GetProcAddress (hAdvapi, "OpenSCManagerA");
+    GNCreateService =
+        (TCreateService) GetProcAddress (hAdvapi, "CreateServiceA");
+    GNCloseServiceHandle =
+        (TCloseServiceHandle) GetProcAddress (hAdvapi, "CloseServiceHandle");
+    GNDeleteService =
+        (TDeleteService) GetProcAddress (hAdvapi, "DeleteService");
+    GNRegisterServiceCtrlHandler =
+        (TRegisterServiceCtrlHandler) GetProcAddress (hAdvapi,
+                                                      "RegisterServiceCtrlHandlerA");
+    GNSetServiceStatus =
+        (TSetServiceStatus) GetProcAddress (hAdvapi, "SetServiceStatus");
+    GNStartServiceCtrlDispatcher =
+        (TStartServiceCtrlDispatcher) GetProcAddress (hAdvapi,
+                                                      "StartServiceCtrlDispatcherA");
+    GNControlService =
+        (TControlService) GetProcAddress (hAdvapi, "ControlService");
+    GNOpenService = (TOpenService) GetProcAddress (hAdvapi, "OpenServiceA");
+
+    GNLsaOpenPolicy =
+        (TLsaOpenPolicy) GetProcAddress (hAdvapi, "LsaOpenPolicy");
+    GNLsaAddAccountRights =
+        (TLsaAddAccountRights) GetProcAddress (hAdvapi, "LsaAddAccountRights");
+    GNLsaRemoveAccountRights =
+        (TLsaRemoveAccountRights) GetProcAddress (hAdvapi,
+                                                  "LsaRemoveAccountRights");
+    GNLsaClose = (TLsaClose) GetProcAddress (hAdvapi, "LsaClose");
+    GNLookupAccountName =
+        (TLookupAccountName) GetProcAddress (hAdvapi, "LookupAccountNameA");
+
+    GNGetFileSecurity =
+        (TGetFileSecurity) GetProcAddress (hAdvapi, "GetFileSecurityA");
+    GNInitializeSecurityDescriptor =
+        (TInitializeSecurityDescriptor) GetProcAddress (hAdvapi,
+                                                        "InitializeSecurityDescriptor");
+    GNGetSecurityDescriptorDacl =
+        (TGetSecurityDescriptorDacl) GetProcAddress (hAdvapi,
+                                                     "GetSecurityDescriptorDacl");
+    GNGetAclInformation =
+        (TGetAclInformation) GetProcAddress (hAdvapi, "GetAclInformation");
+    GNInitializeAcl =
+        (TInitializeAcl) GetProcAddress (hAdvapi, "InitializeAcl");
+    GNGetAce = (TGetAce) GetProcAddress (hAdvapi, "GetAce");
+    GNEqualSid = (TEqualSid) GetProcAddress (hAdvapi, "EqualSid");
+    GNAddAce = (TAddAce) GetProcAddress (hAdvapi, "AddAce");
+    GNAddAccessAllowedAce =
+        (TAddAccessAllowedAce) GetProcAddress (hAdvapi, "AddAccessAllowedAce");
+    GNSetNamedSecurityInfo =
+        (TSetNamedSecurityInfo) GetProcAddress (hAdvapi,
+                                                "SetNamedSecurityInfoA");
+  }
   else
   else
-    {
-      GNOpenSCManager = NULL;
-      GNCreateService = NULL;
-      GNCloseServiceHandle = NULL;
-      GNDeleteService = NULL;
-      GNRegisterServiceCtrlHandler = NULL;
-      GNSetServiceStatus = NULL;
-      GNStartServiceCtrlDispatcher = NULL;
-      GNControlService = NULL;
-      GNOpenService = NULL;
-
-      GNLsaOpenPolicy = NULL;
-      GNLsaAddAccountRights = NULL;
-      GNLsaRemoveAccountRights = NULL;
-      GNLsaClose = NULL;
-      GNLookupAccountName = NULL;
-
-      GNGetFileSecurity = NULL;
-      GNInitializeSecurityDescriptor = NULL;
-      GNGetSecurityDescriptorDacl = NULL;
-      GNGetAclInformation = NULL;
-      GNInitializeAcl = NULL;
-      GNGetAce = NULL;
-      GNEqualSid = NULL;
-      GNAddAce = NULL;
-      GNAddAccessAllowedAce = NULL;
-      GNSetNamedSecurityInfo = NULL;
-    }
+  {
+    GNOpenSCManager = NULL;
+    GNCreateService = NULL;
+    GNCloseServiceHandle = NULL;
+    GNDeleteService = NULL;
+    GNRegisterServiceCtrlHandler = NULL;
+    GNSetServiceStatus = NULL;
+    GNStartServiceCtrlDispatcher = NULL;
+    GNControlService = NULL;
+    GNOpenService = NULL;
+
+    GNLsaOpenPolicy = NULL;
+    GNLsaAddAccountRights = NULL;
+    GNLsaRemoveAccountRights = NULL;
+    GNLsaClose = NULL;
+    GNLookupAccountName = NULL;
+
+    GNGetFileSecurity = NULL;
+    GNInitializeSecurityDescriptor = NULL;
+    GNGetSecurityDescriptorDacl = NULL;
+    GNGetAclInformation = NULL;
+    GNInitializeAcl = NULL;
+    GNGetAce = NULL;
+    GNEqualSid = NULL;
+    GNAddAce = NULL;
+    GNAddAccessAllowedAce = NULL;
+    GNSetNamedSecurityInfo = NULL;
+  }
 
   /* Account function */
   hNetapi = LoadLibrary ("netapi32.dll");
   if (hNetapi)
 
   /* Account function */
   hNetapi = LoadLibrary ("netapi32.dll");
   if (hNetapi)
-    {
-      GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
-      GNNetUserSetInfo = (TNetUserSetInfo)
-        GetProcAddress (hNetapi, "NetUserSetInfo");
-    }
+  {
+    GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
+    GNNetUserSetInfo =
+        (TNetUserSetInfo) GetProcAddress (hNetapi, "NetUserSetInfo");
+  }
   else
   else
-    {
-      GNNetUserAdd = NULL;
-      GNNetUserSetInfo = NULL;
-    }
+  {
+    GNNetUserAdd = NULL;
+    GNNetUserSetInfo = NULL;
+  }
 
   return ret;
 }
 
   return ret;
 }
@@ -231,10 +308,18 @@ InitWinEnv ()
  * Clean up Windows environment
  */
 void
  * Clean up Windows environment
  */
 void
-ShutdownWinEnv ()
+GNShutdownWinEnv ()
 {
   plibc_shutdown ();
 
 {
   plibc_shutdown ();
 
+#ifdef W32_VEH
+  if (GNWinVEH_handle != NULL)
+  {
+    RemoveVectoredExceptionHandler (GNWinVEH_handle);
+    GNWinVEH_handle = NULL;
+  }
+#endif
+
   FreeLibrary (hNTDLL);
   FreeLibrary (hIphlpapi);
   FreeLibrary (hAdvapi);
   FreeLibrary (hNTDLL);
   FreeLibrary (hIphlpapi);
   FreeLibrary (hAdvapi);