X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fwinproc.c;h=7f020c6dc79c579cd66b75fd1472b25f6f2ce6fb;hb=34f34474b6137233d6700d4599f42257e8208af2;hp=9594c5d6f78181890cf416e0551320e359f8aff2;hpb=5746309cb4be2073d550ad7a6885e918631dbc38;p=oweals%2Fgnunet.git diff --git a/src/util/winproc.c b/src/util/winproc.c index 9594c5d6f..7f020c6dc 100644 --- a/src/util/winproc.c +++ b/src/util/winproc.c @@ -1,10 +1,10 @@ /* 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 - 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 @@ -25,13 +25,16 @@ */ #include "platform.h" +#include "gnunet_crypto_lib.h" #include "gnunet_common.h" -#define DEBUG_WINPROC 0 #ifdef MINGW static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi; +#ifdef W32_VEH +static void *GNWinVEH_handle = NULL; +#endif TNtQuerySystemInformation GNNtQuerySystemInformation; TGetIfEntry GNGetIfEntry; @@ -46,8 +49,8 @@ TSetServiceStatus GNSetServiceStatus; TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; TControlService GNControlService; TOpenService GNOpenService; -TGetBestInterface GNGetBestInterface; -TGetAdaptersInfo GGetAdaptersInfo; +TGetBestInterfaceEx GNGetBestInterfaceEx; +TGetAdaptersInfo GNGetAdaptersInfo; TNetUserAdd GNNetUserAdd; TNetUserSetInfo GNNetUserSetInfo; TLsaOpenPolicy GNLsaOpenPolicy; @@ -66,16 +69,70 @@ TAddAce GNAddAce; 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) { - 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 @@ -89,12 +146,25 @@ GNInitWinEnv () 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; +#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 */ @@ -117,9 +187,9 @@ GNInitWinEnv () GNGetIpAddrTable = (TGetIpAddrTable) GetProcAddress (hIphlpapi, "GetIpAddrTable"); GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable"); - GNGetBestInterface = - (TGetBestInterface) GetProcAddress (hIphlpapi, "GetBestInterface"); - GGetAdaptersInfo = + GNGetBestInterfaceEx = + (TGetBestInterfaceEx) GetProcAddress (hIphlpapi, "GetBestInterfaceEx"); + GNGetAdaptersInfo = (TGetAdaptersInfo) GetProcAddress (hIphlpapi, "GetAdaptersInfo"); } else @@ -127,8 +197,8 @@ GNInitWinEnv () GNGetIfEntry = NULL; GNGetIpAddrTable = NULL; GNGetIfTable = NULL; - GNGetBestInterface = NULL; - GGetAdaptersInfo = NULL; + GNGetBestInterfaceEx = NULL; + GNGetAdaptersInfo = NULL; } /* Service & Account functions */ @@ -242,6 +312,14 @@ GNShutdownWinEnv () { plibc_shutdown (); +#ifdef W32_VEH + if (GNWinVEH_handle != NULL) + { + RemoveVectoredExceptionHandler (GNWinVEH_handle); + GNWinVEH_handle = NULL; + } +#endif + FreeLibrary (hNTDLL); FreeLibrary (hIphlpapi); FreeLibrary (hAdvapi);