working again
[oweals/gnunet.git] / src / util / winproc.c
index aa4757f4a949dec828a62aabf7199eb1f12b2826..18fa368a9572d5586e3f46728ef5351a644f748a 100644 (file)
@@ -4,7 +4,7 @@
 
      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
  */
 
 #include "platform.h"
  */
 
 #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;
@@ -73,11 +76,64 @@ TSetNamedSecurityInfo GNSetNamedSecurityInfo;
 void
 plibc_panic (int err, char *msg)
 {
 void
 plibc_panic (int err, char *msg)
 {
-  LOG (((err ==
-        INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
+  LOG (((err == INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
        "%s", msg);
 }
 
        "%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
 /**
  * @brief Initialize PlibC and set up Windows environment
  * @param logging context, NULL means stderr
@@ -90,149 +146,159 @@ GNInitWinEnv ()
 
   plibc_initialized ();
   plibc_set_panic_proc (plibc_panic);
 
   plibc_initialized ();
   plibc_set_panic_proc (plibc_panic);
-  ret = plibc_init ("GNU", PACKAGE);
+  ret = plibc_init_utf8 ("GNU", PACKAGE, 1);
 
   /* 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");
+  {
+    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");
+    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");
-    }
+    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;
+  {
+    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;
+    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;
-    }
+    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;
 }
@@ -245,6 +311,14 @@ 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);