[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r24619 - gnunet/src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r24619 - gnunet/src/util |
Date: |
Tue, 30 Oct 2012 22:08:47 +0100 |
Author: LRN
Date: 2012-10-30 22:08:47 +0100 (Tue, 30 Oct 2012)
New Revision: 24619
Modified:
gnunet/src/util/os_installation.c
Log:
W32: Fix get_path_from_module_filename()
Modified: gnunet/src/util/os_installation.c
===================================================================
--- gnunet/src/util/os_installation.c 2012-10-30 21:08:43 UTC (rev 24618)
+++ gnunet/src/util/os_installation.c 2012-10-30 21:08:47 UTC (rev 24619)
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <unistr.h> /* for u16_to_u8 */
#include "platform.h"
#include "gnunet_common.h"
@@ -111,6 +112,32 @@
#endif
#if WINDOWS
+
+static HINSTANCE dll_instance;
+
+
+/* GNUNET_util_cl_init() in common_logging.c is preferred.
+ * This function is only for thread-local storage (not used in GNUnet)
+ * and hInstance saving.
+ */
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ dll_instance = hinstDLL;
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
/**
* Try to determine path with win32-specific function
*
@@ -119,19 +146,78 @@
static char *
get_path_from_module_filename ()
{
- wchar_t path[4097];
- char upath[4097];
+ size_t pathlen = 512;
+ DWORD real_pathlen;
wchar_t *idx;
+ wchar_t *modulepath = NULL;
+ char *upath;
+ uint8_t *u8_string;
+ size_t u8_string_length;
- GetModuleFileNameW (NULL, path, sizeof (path) - 1);
- idx = path + wcslen (path);
- while ((idx > path) && (*idx != L'\\') && (*idx != L'/'))
+ /* This braindead function won't tell us how much space it needs, so
+ * we start at 1024 and double the space up if it doesn't fit, until
+ * it fits, or we exceed the threshold.
+ */
+ do
+ {
+ pathlen = pathlen * 2;
+ modulepath = GNUNET_realloc (modulepath, pathlen * sizeof (wchar_t));
+ SetLastError (0);
+ real_pathlen = GetModuleFileNameW (dll_instance, modulepath, pathlen *
sizeof (wchar_t));
+ } while (real_pathlen >= pathlen && pathlen < 16*1024);
+ if (real_pathlen >= pathlen)
+ GNUNET_abort ();
+ /* To be safe */
+ modulepath[real_pathlen] = '\0';
+
+ idx = modulepath + real_pathlen;
+ while ((idx > modulepath) && (*idx != L'\\') && (*idx != L'/'))
idx--;
*idx = L'\0';
- upath[0] = '\0';
- WideCharToMultiByte (CP_UTF8, 0, path, -1, upath, 4097, NULL, NULL);
- return GNUNET_strdup (upath);
+ /* Now modulepath holds full path to the directory where libgnunetutil is.
+ * This directory should look like <GNUNET_PREFIX>/bin or <GNUNET_PREFIX>.
+ */
+ if (wcschr (modulepath, L'/') || wcschr (modulepath, L'\\'))
+ {
+ /* At least one directory component (i.e. we're not in a root directory) */
+ wchar_t *dirname = idx;
+ while ((dirname > modulepath) && (*dirname != L'\\') && (*dirname != L'/'))
+ dirname--;
+ *dirname = L'\0';
+ if (dirname > modulepath)
+ {
+ dirname++;
+ /* Now modulepath holds full path to the parent directory of the
directory
+ * where libgnunetutil is.
+ * dirname holds the name of the directory where libgnunetutil is.
+ */
+ if (wcsicmp (dirname, L"bin") == 0)
+ {
+ /* pass */
+ }
+ else
+ {
+ /* Roll back our changes to modulepath */
+ dirname--;
+ *dirname = L'/';
+ }
+ }
+ }
+
+ /* modulepath is GNUNET_PREFIX */
+ u8_string = u16_to_u8 (modulepath, wcslen (modulepath), NULL,
&u8_string_length);
+ if (NULL == u8_string)
+ GNUNET_abort ();
+
+ upath = GNUNET_malloc (u8_string_length + 1);
+ memcpy (upath, u8_string, u8_string_length);
+ upath[u8_string_length] = '\0';
+
+ free (u8_string);
+ GNUNET_free (modulepath);
+
+ return upath;
}
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r24619 - gnunet/src/util,
gnunet <=