From: Tor Lillqvist Date: Sun, 24 Feb 2008 00:38:01 +0000 (+0000) Subject: New function. Supersedes g_win32_get_package_installation_directory() and X-Git-Tag: GLIB_2_15_6~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3af00194ea510ced8eb2fd08c29b59561f387fab;p=platform%2Fupstream%2Fglib.git New function. Supersedes g_win32_get_package_installation_directory() and 2008-02-24 Tor Lillqvist * glib/gwin32.c (g_win32_get_package_installation_directory_of_module): New function. Supersedes g_win32_get_package_installation_directory() and g_win32_get_package_installation_directory(). It makes more sense to have the function for this functionality take a HMODULE as parameter instead of DLL name. The typical use scenario has been to have a DllMain() function that retrieves the full pathname for the DLL in question, and saves just the basename of that. Then later code passes that saved dll basename to g_win32_get_package_installation_directory(), which retrieves the corresponding DLL handle, and then retrieves up its full pathname. (Which DLlMain() already had.) It is less convoluted to have a DllMain() that just saves the DLL handle, and then when needed call this function to get the corresponding installation folder. (get_package_directory_from_module): Use g_win32_get_package_installation_directory_of_module(). (g_win32_get_package_installation_directory) (g_win32_get_package_installation_subdirectory): Mention these functions will be deprecated and recommend using g_win32_get_package_installation_directory_of_module() instead. * glib/gwin32.h: Declare g_win32_get_package_installation_directory_of_module(). * glib/glib.symbols: Add it. svn path=/trunk/; revision=6569 --- diff --git a/ChangeLog b/ChangeLog index 3e1c816..f3660f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2008-02-24 Tor Lillqvist + + * glib/gwin32.c + (g_win32_get_package_installation_directory_of_module): New + function. Supersedes g_win32_get_package_installation_directory() + and g_win32_get_package_installation_directory(). + + It makes more sense to have the function for this functionality + take a HMODULE as parameter instead of DLL name. The typical use + scenario has been to have a DllMain() function that retrieves the + full pathname for the DLL in question, and saves just the basename + of that. Then later code passes that saved dll basename to + g_win32_get_package_installation_directory(), which retrieves the + corresponding DLL handle, and then retrieves up its full + pathname. (Which DLlMain() already had.) It is less convoluted to + have a DllMain() that just saves the DLL handle, and then when + needed call this function to get the corresponding installation + folder. + + (get_package_directory_from_module): Use + g_win32_get_package_installation_directory_of_module(). + + (g_win32_get_package_installation_directory) + (g_win32_get_package_installation_subdirectory): Mention these + functions will be deprecated and recommend using + g_win32_get_package_installation_directory_of_module() instead. + + * glib/gwin32.h: Declare + g_win32_get_package_installation_directory_of_module(). + + * glib/glib.symbols: Add it. + 2008-02-23 Matthias Clasen * NEWS: Updates diff --git a/glib/glib.symbols b/glib/glib.symbols index 9e8f761..38197a2 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -1571,6 +1571,7 @@ g_match_info_fetch_all #ifdef G_OS_WIN32 g_win32_error_message g_win32_ftruncate +g_win32_get_package_installation_directory_of_module g_win32_get_package_installation_directory PRIVATE g_win32_get_package_installation_directory_utf8 g_win32_get_package_installation_subdirectory PRIVATE diff --git a/glib/gwin32.c b/glib/gwin32.c index 086aae0..21bca3c 100644 --- a/glib/gwin32.c +++ b/glib/gwin32.c @@ -201,6 +201,74 @@ g_win32_error_message (gint error) return retval; } +/** + * g_win32_get_package_installation_directory_of_module: + * @hmodule: The Win32 handle for a DLL loaded into the current process, or %NULL + * + * This function tries to determine the installation directory of a + * software package based on the location of a DLL of the software + * package. + * + * @hmodule should be the handle of a loaded DLL or %NULL. The + * function looks up the directory that DLL was loaded from. If + * @hmodule is NULL, the directory the main executable of the current + * process is looked up. If that directory's last component is "bin" + * or "lib", its parent directory is returned, otherwise the directory + * itself. + * + * It thus makes sense to pass only the handle to a "public" DLL of a + * software package to this function, as such DLLs typically are known + * to be installed in a "bin" or occasionally "lib" subfolder of the + * installation folder. DLLs that are of the dynamically loaded module + * or plugin variety are often located in more private locations + * deeper down in the tree, from which it is impossible for GLib to + * deduce the root of the package installation. + * + * The typical use case for this function is to have a DllMain() that + * saves the handle for the DLL. Then when code in the DLL needs to + * construct names of files in the installation tree it calls this + * function passing the DLL handle. + * + * Returns: a string containing the guessed installation directory for + * the software package @hmodule is from. The string is in the GLib + * file name encoding, i.e. UTF-8. The return value should be freed + * with g_free() when not needed any longer. If the function fails + * %NULL is returned. + */ +gchar * +g_win32_get_package_installation_directory_of_module (gpointer hmodule) +{ + gchar *retval; + gchar *p; + wchar_t wc_fn[MAX_PATH]; + + if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH)) + return NULL; + + retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); + + if ((p = strrchr (retval, G_DIR_SEPARATOR)) != NULL) + *p = '\0'; + + p = strrchr (retval, G_DIR_SEPARATOR); + if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0 || + g_ascii_strcasecmp (p + 1, "lib") == 0)) + *p = '\0'; + +#ifdef G_WITH_CYGWIN + /* In Cygwin we need to have POSIX paths */ + { + gchar tmp[MAX_PATH]; + + cygwin_conv_to_posix_path(fn, tmp); + g_free(fn); + fn = g_strdup(tmp); + } +#endif + + return retval; +} + static gchar * get_package_directory_from_module (const gchar *module_name) { @@ -208,21 +276,18 @@ get_package_directory_from_module (const gchar *module_name) G_LOCK_DEFINE_STATIC (module_dirs); HMODULE hmodule = NULL; gchar *fn; - gchar *p; - gchar *result; - wchar_t wc_fn[MAX_PATH]; G_LOCK (module_dirs); if (module_dirs == NULL) module_dirs = g_hash_table_new (g_str_hash, g_str_equal); - result = g_hash_table_lookup (module_dirs, module_name ? module_name : ""); + fn = g_hash_table_lookup (module_dirs, module_name ? module_name : ""); - if (result) + if (fn) { G_UNLOCK (module_dirs); - return g_strdup (result); + return g_strdup (fn); } if (module_name) @@ -235,32 +300,11 @@ get_package_directory_from_module (const gchar *module_name) return NULL; } - if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH)) - { - G_UNLOCK (module_dirs); - return NULL; - } - fn = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); - - if ((p = strrchr (fn, G_DIR_SEPARATOR)) != NULL) - *p = '\0'; - - p = strrchr (fn, G_DIR_SEPARATOR); - if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0 || - g_ascii_strcasecmp (p + 1, "lib") == 0)) - *p = '\0'; - -#ifdef G_WITH_CYGWIN - /* In Cygwin we need to have POSIX paths */ - { - gchar tmp[MAX_PATH]; - - cygwin_conv_to_posix_path(fn, tmp); - g_free(fn); - fn = g_strdup(tmp); - } -#endif + fn = g_win32_get_package_installation_directory_of_module (hmodule); + if (fn == NULL) + return NULL; + g_hash_table_insert (module_dirs, module_name ? g_strdup (module_name) : "", fn); G_UNLOCK (module_dirs); @@ -275,9 +319,12 @@ get_package_directory_from_module (const gchar *module_name) * * Try to determine the installation directory for a software package. * + * This function will be deprecated in the future. Use + * g_win32_get_package_installation_directory_of_module() instead. + * * The use of @package is deprecated. You should always pass %NULL. * - * Its original intended use was for a short identifier for + * The original intended use of @package was for a short identifier of * the package, typically the same identifier as used for * GETTEXT_PACKAGE in software configured using GNU * autotools. The function first looks in the Windows Registry for the @@ -312,9 +359,9 @@ get_package_directory_from_module (const gchar *module_name) * the same way as above. * * Returns: a string containing the installation directory for - * @package. The string is in the GLib file name encoding, i.e. UTF-8 - * on Windows. The return value should be freed with g_free() when not - * needed any longer. + * @package. The string is in the GLib file name encoding, + * i.e. UTF-8. The return value should be freed with g_free() when not + * needed any longer. If the function fails %NULL is returned. **/ gchar * @@ -429,6 +476,9 @@ g_win32_get_package_installation_directory (const gchar *package, * @dll_name: The name of a DLL that a package provides, in UTF-8, or %NULL. * @subdir: A subdirectory of the package installation directory, also in UTF-8 * + * This function will be deprecated in the future. Use + * g_win32_get_package_installation_directory_of_module() instead. + * * Returns a newly-allocated string containing the path of the * subdirectory @subdir in the return value from calling * g_win32_get_package_installation_directory() with the @package and @@ -439,8 +489,9 @@ g_win32_get_package_installation_directory (const gchar *package, * * Returns: a string containing the complete path to @subdir inside * the installation directory of @package. The returned string is in - * the GLib file name encoding, i.e. UTF-8 on Windows. The return - * value should be freed with g_free() when no longer needed. + * the GLib file name encoding, i.e. UTF-8. The return value should be + * freed with g_free() when no longer needed. If something goes wrong, + * %NULL is returned. **/ gchar * diff --git a/glib/gwin32.h b/glib/gwin32.h index 431b198..7b6aa14 100644 --- a/glib/gwin32.h +++ b/glib/gwin32.h @@ -89,6 +89,8 @@ gchar* g_win32_get_package_installation_subdirectory (const gchar *pack const gchar *dll_name, const gchar *subdir); +gchar* g_win32_get_package_installation_directory_of_module (gpointer hmodule); + guint g_win32_get_windows_version (void); gchar* g_win32_locale_filename_from_utf8 (const gchar *utf8filename);