From 69dbd6eb03a0abe5d0f889c670a467e74e256ef7 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 17 Jan 2001 21:37:32 +0000 Subject: [PATCH] Add doc comments. (g_win32_get_package_installation_directory): Add one 2001-01-17 Tor Lillqvist * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc comments. (g_win32_get_package_installation_directory): Add one parameter, the name of a DLL in the package. Add possibility to use that to deduce the installation directory if not entered into the Registry. Make the return value dynamically allocated. (g_win32_get_package_installation_subdirectory): New convenience function. * gutils.c (GLIB_LOCALE_DIR) * gwin32.h: Adapt accordingly. * testglib.c (main): Adapt tests accordingly. --- ChangeLog | 16 +++++ ChangeLog.pre-2-0 | 16 +++++ ChangeLog.pre-2-10 | 16 +++++ ChangeLog.pre-2-12 | 16 +++++ ChangeLog.pre-2-2 | 16 +++++ ChangeLog.pre-2-4 | 16 +++++ ChangeLog.pre-2-6 | 16 +++++ ChangeLog.pre-2-8 | 16 +++++ glib.def | 1 + glib/glib.def | 1 + glib/gutils.c | 11 +-- glib/gwin32.c | 197 ++++++++++++++++++++++++++++++++++++++++++++--------- glib/gwin32.h | 7 +- gutils.c | 11 +-- gwin32.c | 197 ++++++++++++++++++++++++++++++++++++++++++++--------- gwin32.h | 7 +- testglib.c | 18 ++++- tests/testglib.c | 18 ++++- 18 files changed, 510 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9798c5e..e22b4e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9798c5e..e22b4e2 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,19 @@ +2001-01-17 Tor Lillqvist + + * gwin32.c (g_win32_getlocale, g_win32_error_message): Add doc + comments. + (g_win32_get_package_installation_directory): Add one parameter, + the name of a DLL in the package. Add possibility to use that to + deduce the installation directory if not entered into the + Registry. Make the return value dynamically allocated. + (g_win32_get_package_installation_subdirectory): New convenience + function. + + * gutils.c (GLIB_LOCALE_DIR) + * gwin32.h: Adapt accordingly. + + * testglib.c (main): Adapt tests accordingly. + Tue Jan 16 23:20:38 2001 Owen Taylor * gutils.c glibintl.h: Optimize for size rather than speed by diff --git a/glib.def b/glib.def index b56d2d3..e414e35 100644 --- a/glib.def +++ b/glib.def @@ -586,6 +586,7 @@ EXPORTS g_win32_error_message g_win32_ftruncate g_win32_get_package_installation_directory + g_win32_get_package_installation_subdirectory g_win32_getlocale g_win32_opendir g_win32_readdir diff --git a/glib/glib.def b/glib/glib.def index b56d2d3..e414e35 100644 --- a/glib/glib.def +++ b/glib/glib.def @@ -586,6 +586,7 @@ EXPORTS g_win32_error_message g_win32_ftruncate g_win32_get_package_installation_directory + g_win32_get_package_installation_subdirectory g_win32_getlocale g_win32_opendir g_win32_readdir diff --git a/glib/gutils.c b/glib/gutils.c index 221cc19..c48fb2d 100644 --- a/glib/gutils.c +++ b/glib/gutils.c @@ -1009,11 +1009,12 @@ g_get_codeset (void) #ifdef G_OS_WIN32 -#define GLIB_LOCALE_DIR \ - g_strconcat (g_win32_get_package_installation_directory (GETTEXT_PACKAGE), \ - G_DIR_SEPARATOR_S, \ - "locale", \ - NULL) +#define GLIB_LOCALE_DIR \ + g_win32_get_package_installation_subdirectory \ + (GETTEXT_PACKAGE, g_strdup_printf ("glib-%d.%d.dll", \ + GLIB_MAJOR_VERSION, \ + GLIB_MINOR_VERSION), \ + "locale") #endif /* G_OS_WIN32 */ diff --git a/glib/gwin32.c b/glib/gwin32.c index 7126b5d..a3577e3 100644 --- a/glib/gwin32.c +++ b/glib/gwin32.c @@ -526,6 +526,17 @@ g_win32_closedir (DIR *dir) #define SUBLANG_UZBEK_CYRILLIC 0x02 #endif +/** + * g_win32_getlocale: + * + * The setlocale in the Microsoft C library uses locale names of the + * form "English_United States.1252" etc. We want the Unixish standard + * form "en", "zh_TW" etc. This function gets the current thread + * locale from Windows and returns it as a string of the above form + * for use in forming file names etc. The returned string should be + * deallocated with g_free(). + */ + gchar * g_win32_getlocale (void) { @@ -798,6 +809,16 @@ g_win32_getlocale (void) return g_strdup (bfr); } +/** + * g_win32_error_message: + * @error: error code + * + * Translate a Win32 error code (as returned by GetLastError()) into + * the corresponding message. The message is either language neutral, + * or in the thread's language, or the user's language, the system's + * langauge, or US English (see docs for FormatMessage). The returned + * string should be deallocated with g_free(). + */ gchar * g_win32_error_message (gint error) { @@ -823,54 +844,162 @@ g_win32_error_message (gint error) return retval; } -gchar * -g_win32_get_package_installation_directory (gchar *package) +static gchar * +get_package_directory_from_module (gchar *module_name) { - static GHashTable *installation_dirs = NULL; + static GHashTable *module_dirs = NULL; + HMODULE hmodule = NULL; + gchar fn[MAX_PATH]; + gchar *p; gchar *result; + + 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 : ""); + + if (result) + return g_strdup (result); + + if (module_name) + { + hmodule = GetModuleHandle (module_name); + if (!hmodule) + return NULL; + } + + if (!GetModuleFileName (hmodule, fn, sizeof (fn))) + return NULL; + + if ((p = strrchr (fn, '\\')) != NULL) + *p = '\0'; + + if (module_name) + { + p = strrchr (fn, '\\'); + if (p && (g_strcasecmp (p + 1, "bin") == 0 || + g_strcasecmp (p + 1, "lib") == 0)) + *p = '\0'; + } + + g_hash_table_insert (module_dirs, module_name ? module_name : "", fn); + + return g_strdup (fn); +} + +/** + * g_win32_get_package_installation_directory: + * @package: An identifier for a software package, or NULL + * @dll_name: The name of a DLL that a package provides, or NULL + * + * Try to determine the installation directory for a software package. + * Typically used by GNU software packages. + * + * @package should be a short identifier for the package. Typically it + * is the same identifier as used for GETTEXT_PACKAGE in software + * configured accoring to GNU standards. The function first looks in + * the Windows Registry for the value #InstallationDirectory in the + * key #HKLM\Software\@package, and if that value exists and is a + * string, returns that. + * + * If @package is NULL, or the above value isn't found in the + * Registry, but @dll_name is non-NULL, it should name a DLL loaded + * into the current process. Typically that would be the name of the + * DLL calling this function, looking for its installation + * directory. The function then asks Windows what directory that DLL + * was loaded from. If that directory's last component is "bin" or + * "lib", the parent directory is returned, otherwise the directory + * itself. If that DLL isn't loaded, the function proceeds as if + * @dll_name was NULL. + * + * If both @package and @dll_name are NULL, the directory from where + * the main executable of the process was loaded is uses instead in + * the same way as above. + * + * The return value should be freed with g_free() when not needed any longer. */ + +gchar * +g_win32_get_package_installation_directory (gchar *package, + gchar *dll_name) +{ + static GHashTable *package_dirs = NULL; + gchar *result = NULL; gchar *key; char win_dir[MAX_PATH]; - gchar *sep; HKEY reg_key = NULL; DWORD type; DWORD nbytes; - if (installation_dirs == NULL) - installation_dirs = g_hash_table_new (g_str_hash, g_str_equal); - - result = g_hash_table_lookup (installation_dirs, package); - - if (result && result[0]) - return result; - - key = g_strconcat ("Software\\", package, NULL); - - nbytes = 0; - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, - KEY_QUERY_VALUE, ®_key) != ERROR_SUCCESS - || RegQueryValueEx (reg_key, "InstallationDirectory", 0, - &type, NULL, &nbytes) != ERROR_SUCCESS - || type != REG_SZ) + if (package != NULL) { - /* Uh oh. Use a default %WinDir%\package value */ - if (GetWindowsDirectory (win_dir, sizeof (win_dir)) == 0) - strcpy (win_dir, (GetVersion () >= 0x80000000 ? "C:\\windows" : "C:\\winnt")); - sep = (win_dir[strlen (win_dir) - 1] == '\\' ? "" : "\\"); - result = g_strconcat (win_dir, sep, package, NULL); + if (package_dirs == NULL) + package_dirs = g_hash_table_new (g_str_hash, g_str_equal); + + result = g_hash_table_lookup (package_dirs, package); + + if (result && result[0]) + return g_strdup (result); + + key = g_strconcat ("Software\\", package, NULL); + + nbytes = 0; + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, + KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS + && RegQueryValueEx (reg_key, "InstallationDirectory", 0, + &type, NULL, &nbytes) == ERROR_SUCCESS + && type == REG_SZ) + { + result = g_malloc (nbytes + 1); + RegQueryValueEx (reg_key, "InstallationDirectory", 0, + &type, result, &nbytes); + result[nbytes] = '\0'; + } + + if (reg_key != NULL) + RegCloseKey (reg_key); + + g_free (key); + } - else + if (result) { - result = g_malloc (nbytes + 1); - RegQueryValueEx (reg_key, "InstallationDirectory", 0, - &type, result, &nbytes); - result[nbytes] = '\0'; + g_hash_table_insert (package_dirs, package, result); + return g_strdup (result); } - g_hash_table_insert (installation_dirs, package, result); - if (reg_key != NULL) - RegCloseKey (reg_key); + if (dll_name != NULL) + result = get_package_directory_from_module (dll_name); - g_free (key); + if (result == NULL) + result = get_package_directory_from_module (NULL); return result; } + +/** + * g_win32_get_package_installation_subdirectory: + * @package: An identifier for a software package, or NULL + * @dll_name: The name of a DLL that a package provides, or NULL + * @subdir: A subdirectory of the package installation directory. + * + * Returns a string containg the path of the subdirectory @subdir in + * the return value from calling + * g_win32_get_package_installation_directory() with the @package and + * @dll_name parameters. The return value should be freed with + * g_free() when no longer needed. + */ + +gchar * +g_win32_get_package_installation_subdirectory (gchar *package, + gchar *dll_name, + gchar *subdir) +{ + gchar *prefix; + gchar *sep; + + prefix = g_win32_get_package_installation_directory (package, dll_name); + + sep = (prefix[strlen (prefix) - 1] == '\\' ? "" : "\\"); + + return g_strconcat (prefix, sep, subdir, NULL); +} diff --git a/glib/gwin32.h b/glib/gwin32.h index faa81c7..b30ab15 100644 --- a/glib/gwin32.h +++ b/glib/gwin32.h @@ -110,7 +110,12 @@ gchar * g_win32_getlocale (void); */ gchar * g_win32_error_message (gint error); -gchar * g_win32_get_package_installation_directory (gchar *package); +gchar * g_win32_get_package_installation_directory (gchar *package, + gchar *dll_name); + +gchar * g_win32_get_package_installation_subdirectory (gchar *package, + gchar *dll_name, + gchar *subdir); G_END_DECLS diff --git a/gutils.c b/gutils.c index 221cc19..c48fb2d 100644 --- a/gutils.c +++ b/gutils.c @@ -1009,11 +1009,12 @@ g_get_codeset (void) #ifdef G_OS_WIN32 -#define GLIB_LOCALE_DIR \ - g_strconcat (g_win32_get_package_installation_directory (GETTEXT_PACKAGE), \ - G_DIR_SEPARATOR_S, \ - "locale", \ - NULL) +#define GLIB_LOCALE_DIR \ + g_win32_get_package_installation_subdirectory \ + (GETTEXT_PACKAGE, g_strdup_printf ("glib-%d.%d.dll", \ + GLIB_MAJOR_VERSION, \ + GLIB_MINOR_VERSION), \ + "locale") #endif /* G_OS_WIN32 */ diff --git a/gwin32.c b/gwin32.c index 7126b5d..a3577e3 100644 --- a/gwin32.c +++ b/gwin32.c @@ -526,6 +526,17 @@ g_win32_closedir (DIR *dir) #define SUBLANG_UZBEK_CYRILLIC 0x02 #endif +/** + * g_win32_getlocale: + * + * The setlocale in the Microsoft C library uses locale names of the + * form "English_United States.1252" etc. We want the Unixish standard + * form "en", "zh_TW" etc. This function gets the current thread + * locale from Windows and returns it as a string of the above form + * for use in forming file names etc. The returned string should be + * deallocated with g_free(). + */ + gchar * g_win32_getlocale (void) { @@ -798,6 +809,16 @@ g_win32_getlocale (void) return g_strdup (bfr); } +/** + * g_win32_error_message: + * @error: error code + * + * Translate a Win32 error code (as returned by GetLastError()) into + * the corresponding message. The message is either language neutral, + * or in the thread's language, or the user's language, the system's + * langauge, or US English (see docs for FormatMessage). The returned + * string should be deallocated with g_free(). + */ gchar * g_win32_error_message (gint error) { @@ -823,54 +844,162 @@ g_win32_error_message (gint error) return retval; } -gchar * -g_win32_get_package_installation_directory (gchar *package) +static gchar * +get_package_directory_from_module (gchar *module_name) { - static GHashTable *installation_dirs = NULL; + static GHashTable *module_dirs = NULL; + HMODULE hmodule = NULL; + gchar fn[MAX_PATH]; + gchar *p; gchar *result; + + 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 : ""); + + if (result) + return g_strdup (result); + + if (module_name) + { + hmodule = GetModuleHandle (module_name); + if (!hmodule) + return NULL; + } + + if (!GetModuleFileName (hmodule, fn, sizeof (fn))) + return NULL; + + if ((p = strrchr (fn, '\\')) != NULL) + *p = '\0'; + + if (module_name) + { + p = strrchr (fn, '\\'); + if (p && (g_strcasecmp (p + 1, "bin") == 0 || + g_strcasecmp (p + 1, "lib") == 0)) + *p = '\0'; + } + + g_hash_table_insert (module_dirs, module_name ? module_name : "", fn); + + return g_strdup (fn); +} + +/** + * g_win32_get_package_installation_directory: + * @package: An identifier for a software package, or NULL + * @dll_name: The name of a DLL that a package provides, or NULL + * + * Try to determine the installation directory for a software package. + * Typically used by GNU software packages. + * + * @package should be a short identifier for the package. Typically it + * is the same identifier as used for GETTEXT_PACKAGE in software + * configured accoring to GNU standards. The function first looks in + * the Windows Registry for the value #InstallationDirectory in the + * key #HKLM\Software\@package, and if that value exists and is a + * string, returns that. + * + * If @package is NULL, or the above value isn't found in the + * Registry, but @dll_name is non-NULL, it should name a DLL loaded + * into the current process. Typically that would be the name of the + * DLL calling this function, looking for its installation + * directory. The function then asks Windows what directory that DLL + * was loaded from. If that directory's last component is "bin" or + * "lib", the parent directory is returned, otherwise the directory + * itself. If that DLL isn't loaded, the function proceeds as if + * @dll_name was NULL. + * + * If both @package and @dll_name are NULL, the directory from where + * the main executable of the process was loaded is uses instead in + * the same way as above. + * + * The return value should be freed with g_free() when not needed any longer. */ + +gchar * +g_win32_get_package_installation_directory (gchar *package, + gchar *dll_name) +{ + static GHashTable *package_dirs = NULL; + gchar *result = NULL; gchar *key; char win_dir[MAX_PATH]; - gchar *sep; HKEY reg_key = NULL; DWORD type; DWORD nbytes; - if (installation_dirs == NULL) - installation_dirs = g_hash_table_new (g_str_hash, g_str_equal); - - result = g_hash_table_lookup (installation_dirs, package); - - if (result && result[0]) - return result; - - key = g_strconcat ("Software\\", package, NULL); - - nbytes = 0; - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, - KEY_QUERY_VALUE, ®_key) != ERROR_SUCCESS - || RegQueryValueEx (reg_key, "InstallationDirectory", 0, - &type, NULL, &nbytes) != ERROR_SUCCESS - || type != REG_SZ) + if (package != NULL) { - /* Uh oh. Use a default %WinDir%\package value */ - if (GetWindowsDirectory (win_dir, sizeof (win_dir)) == 0) - strcpy (win_dir, (GetVersion () >= 0x80000000 ? "C:\\windows" : "C:\\winnt")); - sep = (win_dir[strlen (win_dir) - 1] == '\\' ? "" : "\\"); - result = g_strconcat (win_dir, sep, package, NULL); + if (package_dirs == NULL) + package_dirs = g_hash_table_new (g_str_hash, g_str_equal); + + result = g_hash_table_lookup (package_dirs, package); + + if (result && result[0]) + return g_strdup (result); + + key = g_strconcat ("Software\\", package, NULL); + + nbytes = 0; + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, + KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS + && RegQueryValueEx (reg_key, "InstallationDirectory", 0, + &type, NULL, &nbytes) == ERROR_SUCCESS + && type == REG_SZ) + { + result = g_malloc (nbytes + 1); + RegQueryValueEx (reg_key, "InstallationDirectory", 0, + &type, result, &nbytes); + result[nbytes] = '\0'; + } + + if (reg_key != NULL) + RegCloseKey (reg_key); + + g_free (key); + } - else + if (result) { - result = g_malloc (nbytes + 1); - RegQueryValueEx (reg_key, "InstallationDirectory", 0, - &type, result, &nbytes); - result[nbytes] = '\0'; + g_hash_table_insert (package_dirs, package, result); + return g_strdup (result); } - g_hash_table_insert (installation_dirs, package, result); - if (reg_key != NULL) - RegCloseKey (reg_key); + if (dll_name != NULL) + result = get_package_directory_from_module (dll_name); - g_free (key); + if (result == NULL) + result = get_package_directory_from_module (NULL); return result; } + +/** + * g_win32_get_package_installation_subdirectory: + * @package: An identifier for a software package, or NULL + * @dll_name: The name of a DLL that a package provides, or NULL + * @subdir: A subdirectory of the package installation directory. + * + * Returns a string containg the path of the subdirectory @subdir in + * the return value from calling + * g_win32_get_package_installation_directory() with the @package and + * @dll_name parameters. The return value should be freed with + * g_free() when no longer needed. + */ + +gchar * +g_win32_get_package_installation_subdirectory (gchar *package, + gchar *dll_name, + gchar *subdir) +{ + gchar *prefix; + gchar *sep; + + prefix = g_win32_get_package_installation_directory (package, dll_name); + + sep = (prefix[strlen (prefix) - 1] == '\\' ? "" : "\\"); + + return g_strconcat (prefix, sep, subdir, NULL); +} diff --git a/gwin32.h b/gwin32.h index faa81c7..b30ab15 100644 --- a/gwin32.h +++ b/gwin32.h @@ -110,7 +110,12 @@ gchar * g_win32_getlocale (void); */ gchar * g_win32_error_message (gint error); -gchar * g_win32_get_package_installation_directory (gchar *package); +gchar * g_win32_get_package_installation_directory (gchar *package, + gchar *dll_name); + +gchar * g_win32_get_package_installation_subdirectory (gchar *package, + gchar *dll_name, + gchar *subdir); G_END_DECLS diff --git a/testglib.c b/testglib.c index 05dd7d5..7cbd939 100644 --- a/testglib.c +++ b/testglib.c @@ -388,6 +388,11 @@ main (int argc, GError *error; char *name_used; gchar *p; +#ifdef G_OS_WIN32 + gchar *glib_dll = g_strdup_printf ("glib-%d.%d.dll", + GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION); +#endif g_print ("TestGLib v%u.%u.%u (i:%u b:%u)\n", glib_major_version, @@ -1145,10 +1150,17 @@ main (int argc, #ifdef G_OS_WIN32 g_print ("current locale: %s\n", g_win32_getlocale ()); - g_print ("GLib installation directory (used for message catalogs): %s\n", - g_win32_get_package_installation_directory (GETTEXT_PACKAGE)); + g_print ("GLib installation directory, from Registry entry for %s if available: %s\n", + GETTEXT_PACKAGE, + g_win32_get_package_installation_directory (GETTEXT_PACKAGE, NULL)); + g_print ("Ditto, or from GLib DLL name: %s\n", + g_win32_get_package_installation_directory (GETTEXT_PACKAGE, glib_dll)); + g_print ("Ditto, only from GLib DLL name: %s\n", + g_win32_get_package_installation_directory (NULL, glib_dll)); + g_print ("locale subdirectory of GLib installation directory: %s\n", + g_win32_get_package_installation_subdirectory (NULL, glib_dll, "locale")); g_print ("GTK+ 2.0 installation directory, if available: %s\n", - g_win32_get_package_installation_directory ("gtk20")); + g_win32_get_package_installation_directory ("gtk20", NULL)); #endif g_print ("checking file functions...\n"); diff --git a/tests/testglib.c b/tests/testglib.c index 05dd7d5..7cbd939 100644 --- a/tests/testglib.c +++ b/tests/testglib.c @@ -388,6 +388,11 @@ main (int argc, GError *error; char *name_used; gchar *p; +#ifdef G_OS_WIN32 + gchar *glib_dll = g_strdup_printf ("glib-%d.%d.dll", + GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION); +#endif g_print ("TestGLib v%u.%u.%u (i:%u b:%u)\n", glib_major_version, @@ -1145,10 +1150,17 @@ main (int argc, #ifdef G_OS_WIN32 g_print ("current locale: %s\n", g_win32_getlocale ()); - g_print ("GLib installation directory (used for message catalogs): %s\n", - g_win32_get_package_installation_directory (GETTEXT_PACKAGE)); + g_print ("GLib installation directory, from Registry entry for %s if available: %s\n", + GETTEXT_PACKAGE, + g_win32_get_package_installation_directory (GETTEXT_PACKAGE, NULL)); + g_print ("Ditto, or from GLib DLL name: %s\n", + g_win32_get_package_installation_directory (GETTEXT_PACKAGE, glib_dll)); + g_print ("Ditto, only from GLib DLL name: %s\n", + g_win32_get_package_installation_directory (NULL, glib_dll)); + g_print ("locale subdirectory of GLib installation directory: %s\n", + g_win32_get_package_installation_subdirectory (NULL, glib_dll, "locale")); g_print ("GTK+ 2.0 installation directory, if available: %s\n", - g_win32_get_package_installation_directory ("gtk20")); + g_win32_get_package_installation_directory ("gtk20", NULL)); #endif g_print ("checking file functions...\n"); -- 2.7.4