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
*/
/**
- * @file util/win/winproc.c
+ * @file util/winproc.c
* @brief Functions for MS Windows
* @author Nils Durner
*/
#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;
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
* @return Error code from winerror.h, ERROR_SUCCESS on success
*/
int
-InitWinEnv ()
+GNInitWinEnv ()
{
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;
+#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)
- {
- GNNtQuerySystemInformation = (TNtQuerySystemInformation)
- GetProcAddress (hNTDLL, "NtQuerySystemInformation");
- }
+ {
+ GNNtQuerySystemInformation =
+ (TNtQuerySystemInformation) GetProcAddress (hNTDLL,
+ "NtQuerySystemInformation");
+ }
else
- {
- GNNtQuerySystemInformation = NULL;
- }
+ {
+ GNNtQuerySystemInformation = NULL;
+ }
/* 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
- {
- 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)
- {
- 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
- {
- 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)
- {
- GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
- GNNetUserSetInfo = (TNetUserSetInfo)
- GetProcAddress (hNetapi, "NetUserSetInfo");
- }
+ {
+ GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
+ GNNetUserSetInfo =
+ (TNetUserSetInfo) GetProcAddress (hNetapi, "NetUserSetInfo");
+ }
else
- {
- GNNetUserAdd = NULL;
- GNNetUserSetInfo = NULL;
- }
+ {
+ GNNetUserAdd = NULL;
+ GNNetUserSetInfo = NULL;
+ }
return ret;
}
* Clean up Windows environment
*/
void
-ShutdownWinEnv ()
+GNShutdownWinEnv ()
{
plibc_shutdown ();
+#ifdef W32_VEH
+ if (GNWinVEH_handle != NULL)
+ {
+ RemoveVectoredExceptionHandler (GNWinVEH_handle);
+ GNWinVEH_handle = NULL;
+ }
+#endif
+
FreeLibrary (hNTDLL);
FreeLibrary (hIphlpapi);
FreeLibrary (hAdvapi);