#include "platform.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;
TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
TControlService GNControlService;
TOpenService GNOpenService;
-TGetBestInterface GNGetBestInterface;
-TGetAdaptersInfo GGetAdaptersInfo;
+TGetBestInterfaceEx GNGetBestInterfaceEx;
+TGetAdaptersInfo GNGetAdaptersInfo;
TNetUserAdd GNNetUserAdd;
TNetUserSetInfo GNNetUserSetInfo;
TLsaOpenPolicy GNLsaOpenPolicy;
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
* @param logging context, NULL means stderr
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;
+#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 */
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
GNGetIfEntry = NULL;
GNGetIpAddrTable = NULL;
GNGetIfTable = NULL;
- GNGetBestInterface = NULL;
- GGetAdaptersInfo = NULL;
+ GNGetBestInterfaceEx = NULL;
+ GNGetAdaptersInfo = NULL;
}
/* Service & Account functions */
{
plibc_shutdown ();
+#ifdef W32_VEH
+ if (GNWinVEH_handle != NULL)
+ {
+ RemoveVectoredExceptionHandler (GNWinVEH_handle);
+ GNWinVEH_handle = NULL;
+ }
+#endif
+
FreeLibrary (hNTDLL);
FreeLibrary (hIphlpapi);
FreeLibrary (hAdvapi);