add crc8
[oweals/gnunet.git] / src / util / winproc.c
index 4fa3ab4848f5e3c343c69de7e20f8a9a2e36af56..5c445707ec906a2c73327a4547a3658876ada06a 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
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
 */
 
 /**
  */
 
 #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;
@@ -66,17 +69,71 @@ 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
 /**
  * @brief Initialize PlibC and set up Windows environment
  * @param logging context, NULL means stderr
@@ -89,19 +146,33 @@ 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);
+  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
   {
@@ -113,72 +184,78 @@ GNInitWinEnv ()
   if (hIphlpapi)
   {
     GNGetIfEntry = (TGetIfEntry) GetProcAddress (hIphlpapi, "GetIfEntry");
   if (hIphlpapi)
   {
     GNGetIfEntry = (TGetIfEntry) GetProcAddress (hIphlpapi, "GetIfEntry");
-    GNGetIpAddrTable = (TGetIpAddrTable) GetProcAddress (hIphlpapi,
-                                                         "GetIpAddrTable");
+    GNGetIpAddrTable =
+        (TGetIpAddrTable) GetProcAddress (hIphlpapi, "GetIpAddrTable");
     GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable");
     GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable");
-    GNGetBestInterface = (TGetBestInterface) GetProcAddress (hIphlpapi,
-                                                             "GetBestInterface");
-    GGetAdaptersInfo = (TGetAdaptersInfo) GetProcAddress (hIphlpapi,
-                                                          "GetAdaptersInfo");
+    GNGetBestInterfaceEx =
+        (TGetBestInterfaceEx) GetProcAddress (hIphlpapi, "GetBestInterfaceEx");
+    GNGetAdaptersInfo =
+        (TGetAdaptersInfo) GetProcAddress (hIphlpapi, "GetAdaptersInfo");
   }
   else
   {
     GNGetIfEntry = NULL;
     GNGetIpAddrTable = NULL;
     GNGetIfTable = NULL;
   }
   else
   {
     GNGetIfEntry = NULL;
     GNGetIpAddrTable = NULL;
     GNGetIfTable = NULL;
-    GNGetBestInterface = NULL;
-    GGetAdaptersInfo = 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");
+    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");
 
     GNOpenService = (TOpenService) GetProcAddress (hAdvapi, "OpenServiceA");
 
-    GNLsaOpenPolicy = (TLsaOpenPolicy)
-        GetProcAddress (hAdvapi, "LsaOpenPolicy");
-    GNLsaAddAccountRights = (TLsaAddAccountRights)
-        GetProcAddress (hAdvapi, "LsaAddAccountRights");
-    GNLsaRemoveAccountRights = (TLsaRemoveAccountRights)
-        GetProcAddress (hAdvapi, "LsaRemoveAccountRights");
+    GNLsaOpenPolicy =
+        (TLsaOpenPolicy) GetProcAddress (hAdvapi, "LsaOpenPolicy");
+    GNLsaAddAccountRights =
+        (TLsaAddAccountRights) GetProcAddress (hAdvapi, "LsaAddAccountRights");
+    GNLsaRemoveAccountRights =
+        (TLsaRemoveAccountRights) GetProcAddress (hAdvapi,
+                                                  "LsaRemoveAccountRights");
     GNLsaClose = (TLsaClose) GetProcAddress (hAdvapi, "LsaClose");
     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");
+    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");
     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");
+    GNAddAccessAllowedAce =
+        (TAddAccessAllowedAce) GetProcAddress (hAdvapi, "AddAccessAllowedAce");
+    GNSetNamedSecurityInfo =
+        (TSetNamedSecurityInfo) GetProcAddress (hAdvapi,
+                                                "SetNamedSecurityInfoA");
   }
   else
   {
   }
   else
   {
@@ -215,8 +292,8 @@ GNInitWinEnv ()
   if (hNetapi)
   {
     GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
   if (hNetapi)
   {
     GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
-    GNNetUserSetInfo = (TNetUserSetInfo)
-        GetProcAddress (hNetapi, "NetUserSetInfo");
+    GNNetUserSetInfo =
+        (TNetUserSetInfo) GetProcAddress (hNetapi, "NetUserSetInfo");
   }
   else
   {
   }
   else
   {
@@ -235,6 +312,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);