/libgnome-2.32.1/libgnome/dllmain.c

# · C · 196 lines · 114 code · 25 blank · 57 comment · 25 complexity · 5f207cff1042d478003ab4a77eed15f1 MD5 · raw file

  1. /* -*- Mode: C; tab-width: 8; c-basic-offset: 8; indent-tabs-mode: nil -*- */
  2. /* dllmain.c: DLL entry point for libgnome on Win32
  3. * Copyright (C) 2005 Novell, Inc
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public
  16. * License along with this library; if not, write to the
  17. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18. * Boston, MA 02110-1301, USA.
  19. */
  20. #include <config.h>
  21. #include <windows.h>
  22. #include <string.h>
  23. #include <mbstring.h>
  24. #include <glib.h>
  25. #include "gnome-init.h"
  26. /* localedir uses system codepage as it is passed to the non-UTF8ified
  27. * gettext library
  28. */
  29. static const char *localedir = NULL;
  30. /* The others are in UTF-8 */
  31. static char *prefix;
  32. static const char *libdir;
  33. static const char *datadir;
  34. static const char *localstatedir;
  35. static const char *sysconfdir;
  36. static HMODULE hmodule;
  37. G_LOCK_DEFINE_STATIC (mutex);
  38. /* Silence gcc with prototype. Yes, this is silly. */
  39. BOOL WINAPI DllMain (HINSTANCE hinstDLL,
  40. DWORD fdwReason,
  41. LPVOID lpvReserved);
  42. /* DllMain used to tuck away the libgnome DLL's HMODULE */
  43. BOOL WINAPI
  44. DllMain (HINSTANCE hinstDLL,
  45. DWORD fdwReason,
  46. LPVOID lpvReserved)
  47. {
  48. switch (fdwReason) {
  49. case DLL_PROCESS_ATTACH:
  50. hmodule = hinstDLL;
  51. break;
  52. }
  53. return TRUE;
  54. }
  55. static char *
  56. replace_prefix (const char *runtime_prefix,
  57. const char *configure_time_path)
  58. {
  59. if (runtime_prefix &&
  60. strncmp (configure_time_path, LIBGNOME_PREFIX "/",
  61. strlen (LIBGNOME_PREFIX) + 1) == 0)
  62. return g_strconcat (runtime_prefix,
  63. configure_time_path + strlen (LIBGNOME_PREFIX),
  64. NULL);
  65. else
  66. return g_strdup (configure_time_path);
  67. }
  68. /**
  69. * gnome_win32_get_prefixes:
  70. * @hmodule: The handle to a DLL (a HMODULE).
  71. * @full_prefix: Where the full UTF-8 path to the DLL's installation folder
  72. * will be returned.
  73. * @cp_prefix: Where a system codepage version of
  74. * the installation folder will be returned.
  75. *
  76. * This function looks up the installation prefix of the DLL (or EXE)
  77. * with handle @hmodule. The prefix using long filenames and in UTF-8
  78. * form is returned in @full_prefix. The prefix using short file names
  79. * (if present in the file system) and in the system codepage is
  80. * returned in @cp_prefix. To determine the installation prefix, the
  81. * full path to the DLL or EXE is first fetched. If the last folder
  82. * component in that path is called "bin", its parent folder is used,
  83. * otherwise the folder itself.
  84. *
  85. * If either can't be obtained, %NULL is stored. The caller should be
  86. * prepared to handle that.
  87. *
  88. * The returned character pointers are newly allocated and should be
  89. * freed with g_free when not longer needed.
  90. */
  91. void
  92. gnome_win32_get_prefixes (gpointer hmodule,
  93. char **full_prefix,
  94. char **cp_prefix)
  95. {
  96. wchar_t wcbfr[1000];
  97. char cpbfr[1000];
  98. g_return_if_fail (full_prefix != NULL);
  99. g_return_if_fail (cp_prefix != NULL);
  100. *full_prefix = NULL;
  101. *cp_prefix = NULL;
  102. if (GetModuleFileNameW ((HMODULE) hmodule, wcbfr, G_N_ELEMENTS (wcbfr))) {
  103. *full_prefix = g_utf16_to_utf8 (wcbfr, -1,
  104. NULL, NULL, NULL);
  105. if (GetShortPathNameW (wcbfr, wcbfr, G_N_ELEMENTS (wcbfr)) &&
  106. /* Short pathnames always contain only
  107. * ASCII, I think, but just in case, be
  108. * prepared.
  109. */
  110. WideCharToMultiByte (CP_ACP, 0, wcbfr, -1,
  111. cpbfr, G_N_ELEMENTS (cpbfr),
  112. NULL, NULL))
  113. *cp_prefix = g_strdup (cpbfr);
  114. else if (*full_prefix)
  115. *cp_prefix = g_locale_from_utf8 (*full_prefix, -1,
  116. NULL, NULL, NULL);
  117. }
  118. if (*full_prefix != NULL) {
  119. gchar *p = strrchr (*full_prefix, '\\');
  120. if (p != NULL)
  121. *p = '\0';
  122. p = strrchr (*full_prefix, '\\');
  123. if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0))
  124. *p = '\0';
  125. }
  126. /* cp_prefix is in system codepage */
  127. if (*cp_prefix != NULL) {
  128. gchar *p = _mbsrchr (*cp_prefix, '\\');
  129. if (p != NULL)
  130. *p = '\0';
  131. p = _mbsrchr (*cp_prefix, '\\');
  132. if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0))
  133. *p = '\0';
  134. }
  135. }
  136. static void
  137. setup (void)
  138. {
  139. char *cp_prefix;
  140. G_LOCK (mutex);
  141. if (localedir != NULL) {
  142. G_UNLOCK (mutex);
  143. return;
  144. }
  145. gnome_win32_get_prefixes (hmodule, &prefix, &cp_prefix);
  146. localedir = replace_prefix (cp_prefix, LIBGNOME_LOCALEDIR);
  147. g_free (cp_prefix);
  148. libdir = replace_prefix (prefix, LIBGNOME_LIBDIR);
  149. datadir = replace_prefix (prefix, LIBGNOME_DATADIR);
  150. localstatedir = replace_prefix (prefix, LIBGNOME_LOCALSTATEDIR);
  151. sysconfdir = replace_prefix (prefix, LIBGNOME_SYSCONFDIR);
  152. G_UNLOCK (mutex);
  153. }
  154. /* Include libgnome-private.h now to get prototypes for the getter
  155. * functions, to silence gcc. Can't include earlier as we need the
  156. * definitions of the LIBGNOME_*DIR macros from the Makefile above.
  157. */
  158. #include "libgnome-private.h"
  159. #define GETTER(varbl) \
  160. const char * \
  161. _gnome_get_##varbl (void) \
  162. { \
  163. setup (); \
  164. return varbl; \
  165. }
  166. GETTER (prefix)
  167. GETTER (localedir)
  168. GETTER (libdir)
  169. GETTER (datadir)
  170. GETTER (localstatedir)
  171. GETTER (sysconfdir)