X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgwin32.c;h=ffc5fe2e63f79fd86d45ec37ce8e738edc67cf98;hb=037bdb1b7ec89f9ddc0d40cabc78bb194b52fafb;hp=d722a874a99388df1ffc4349c2a9b2ff23d59710;hpb=f5b5154a8817e0964c96f7be960d4fae143136b2;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gwin32.c b/glib/gwin32.c index d722a87..ffc5fe2 100644 --- a/glib/gwin32.c +++ b/glib/gwin32.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* @@ -52,7 +50,7 @@ #endif /* _MSC_VER || __DMC__ */ #include "glib.h" -#include "galias.h" +#include "gthreadprivate.h" #ifdef G_WITH_CYGWIN #include @@ -163,12 +161,12 @@ g_win32_getlocale (void) * 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 - * language, or US English (see docs for FormatMessage()). The - * returned string is in UTF-8. It should be deallocated with - * g_free(). + * Translate a Win32 error code (as returned by GetLastError() or + * WSAGetLastError()) into the corresponding message. The message is + * either language neutral, or in the thread's language, or the user's + * language, the system's language, or US English (see docs for + * FormatMessage()). The returned string is in UTF-8. It should be + * deallocated with g_free(). * * Returns: newly-allocated error message **/ @@ -203,7 +201,7 @@ g_win32_error_message (gint error) /** * g_win32_get_package_installation_directory_of_module: - * @hmodule: The Win32 handle for a DLL loaded into the current process, or %NULL + * @hmodule: (allow-none): 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 @@ -240,22 +238,43 @@ g_win32_error_message (gint error) gchar * g_win32_get_package_installation_directory_of_module (gpointer hmodule) { + gchar *filename; gchar *retval; gchar *p; wchar_t wc_fn[MAX_PATH]; + /* NOTE: it relies that GetModuleFileNameW returns only canonical paths */ if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH)) return NULL; - retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); + filename = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); - if ((p = strrchr (retval, G_DIR_SEPARATOR)) != NULL) + if ((p = strrchr (filename, 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'; + retval = g_strdup (filename); + + do + { + p = strrchr (retval, G_DIR_SEPARATOR); + if (p == NULL) + break; + + *p = '\0'; + + if (g_ascii_strcasecmp (p + 1, "bin") == 0 || + g_ascii_strcasecmp (p + 1, "lib") == 0) + break; + } + while (p != NULL); + + if (p == NULL) + { + g_free (retval); + retval = filename; + } + else + g_free (filename); #ifdef G_WITH_CYGWIN /* In Cygwin we need to have POSIX paths */ @@ -322,8 +341,8 @@ get_package_directory_from_module (const gchar *module_name) /** * g_win32_get_package_installation_directory: - * @package: You should pass %NULL for this. - * @dll_name: The name of a DLL that a package provides in UTF-8, or %NULL. + * @package: (allow-none): You should pass %NULL for this. + * @dll_name: (allow-none): The name of a DLL that a package provides in UTF-8, or %NULL. * * Try to determine the installation directory for a software package. * @@ -335,10 +354,10 @@ get_package_directory_from_module (const gchar *module_name) * * 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 + * `GETTEXT_PACKAGE` in software configured using GNU * autotools. The function first looks in the Windows Registry for the - * value #InstallationDirectory in the key - * #HKLM\Software\@package, and if that value + * value `#InstallationDirectory` in the key + * `#HKLM\Software\@package`, and if that value * exists and is a string, returns that. * * It is strongly recommended that packagers of GLib-using libraries @@ -372,7 +391,7 @@ get_package_directory_from_module (const gchar *module_name) * 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. * - * @Deprecated:2.18: Pass the HMODULE of a DLL or EXE to + * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to * g_win32_get_package_installation_directory_of_module() instead. **/ @@ -380,75 +399,11 @@ get_package_directory_from_module (const gchar *module_name) g_win32_get_package_installation_directory_utf8 (const gchar *package, const gchar *dll_name) { - static GHashTable *package_dirs = NULL; - G_LOCK_DEFINE_STATIC (package_dirs); gchar *result = NULL; - gchar *key; - wchar_t *wc_key; - HKEY reg_key = NULL; - DWORD type; - DWORD nbytes; -#if GLIB_CHECK_VERSION (2, 19, 0) if (package != NULL) g_warning ("Passing a non-NULL package to g_win32_get_package_installation_directory() is deprecated and it is ignored."); -#else - if (package != NULL) - { - g_warning ("Passing a non-NULL package to g_win32_get_package_installation_directory() is deprecated and will not work in GLib after 2.18."); - G_LOCK (package_dirs); - - 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]) - { - G_UNLOCK (package_dirs); - return g_strdup (result); - } - - key = g_strconcat ("Software\\", package, NULL); - - nbytes = 0; - - wc_key = g_utf8_to_utf16 (key, -1, NULL, NULL, NULL); - if (((RegOpenKeyExW (HKEY_CURRENT_USER, wc_key, 0, - KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS - && RegQueryValueExW (reg_key, L"InstallationDirectory", 0, - &type, NULL, &nbytes) == ERROR_SUCCESS) - || - (RegOpenKeyExW (HKEY_LOCAL_MACHINE, wc_key, 0, - KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS - && RegQueryValueExW (reg_key, L"InstallationDirectory", 0, - &type, NULL, &nbytes) == ERROR_SUCCESS)) - && type == REG_SZ) - { - wchar_t *wc_temp = g_new (wchar_t, (nbytes+1)/2 + 1); - RegQueryValueExW (reg_key, L"InstallationDirectory", 0, - &type, (LPBYTE) wc_temp, &nbytes); - wc_temp[nbytes/2] = '\0'; - result = g_utf16_to_utf8 (wc_temp, -1, NULL, NULL, NULL); - g_free (wc_temp); - } - g_free (wc_key); - - if (reg_key != NULL) - RegCloseKey (reg_key); - - g_free (key); - - if (result) - { - g_hash_table_insert (package_dirs, g_strdup (package), result); - G_UNLOCK (package_dirs); - return g_strdup (result); - } - G_UNLOCK (package_dirs); - } -#endif if (dll_name != NULL) result = get_package_directory_from_module (dll_name); @@ -492,8 +447,8 @@ g_win32_get_package_installation_directory (const gchar *package, /** * g_win32_get_package_installation_subdirectory: - * @package: You should pass %NULL for this. - * @dll_name: The name of a DLL that a package provides, in UTF-8, or %NULL. + * @package: (allow-none): You should pass %NULL for this. + * @dll_name: (allow-none): 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 is deprecated. Use @@ -514,7 +469,7 @@ g_win32_get_package_installation_directory (const gchar *package, * freed with g_free() when no longer needed. If something goes wrong, * %NULL is returned. * - * @Deprecated:2.18: Pass the HMODULE of a DLL or EXE to + * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to * g_win32_get_package_installation_directory_of_module() instead, and * then construct a subdirectory pathname with g_build_filename(). **/ @@ -527,7 +482,9 @@ g_win32_get_package_installation_subdirectory_utf8 (const gchar *package, gchar *prefix; gchar *dirname; +G_GNUC_BEGIN_IGNORE_DEPRECATIONS prefix = g_win32_get_package_installation_directory_utf8 (package, dll_name); +G_GNUC_END_IGNORE_DEPRECATIONS dirname = g_build_filename (prefix, subdir, NULL); g_free (prefix); @@ -547,7 +504,9 @@ g_win32_get_package_installation_subdirectory (const gchar *package, gchar *prefix; gchar *dirname; + G_GNUC_BEGIN_IGNORE_DEPRECATIONS prefix = g_win32_get_package_installation_directory (package, dll_name); + G_GNUC_END_IGNORE_DEPRECATIONS dirname = g_build_filename (prefix, subdir, NULL); g_free (prefix); @@ -557,29 +516,6 @@ g_win32_get_package_installation_subdirectory (const gchar *package, #endif -static guint windows_version; - -static void -g_win32_windows_version_init (void) -{ - static gboolean beenhere = FALSE; - - if (!beenhere) - { - beenhere = TRUE; - windows_version = GetVersion (); - - if (windows_version & 0x80000000) - g_error ("This version of GLib requires NT-based Windows."); - } -} - -void -_g_win32_thread_init (void) -{ - g_win32_windows_version_init (); -} - /** * g_win32_get_windows_version: * @@ -590,7 +526,7 @@ _g_win32_thread_init (void) * on NT-based systems, so checking whether your are running on Win9x * in your own software is moot. The least significant byte is 4 on * Windows NT 4, and 5 on Windows XP. Software that needs really - * detailled version and feature information should use Win32 API like + * detailed version and feature information should use Win32 API like * GetVersionEx() and VerifyVersionInfo(). * * Returns: The version information. @@ -600,8 +536,11 @@ _g_win32_thread_init (void) guint g_win32_get_windows_version (void) { - g_win32_windows_version_init (); - + static gsize windows_version; + + if (g_once_init_enter (&windows_version)) + g_once_init_leave (&windows_version, GetVersion ()); + return windows_version; } @@ -629,7 +568,7 @@ g_win32_get_windows_version (void) * The return value is dynamically allocated and should be freed with * g_free() when no longer needed. * - * Return value: The converted filename, or %NULL on conversion + * Returns: The converted filename, or %NULL on conversion * failure and lack of short names. * * Since: 2.8 @@ -660,5 +599,57 @@ g_win32_locale_filename_from_utf8 (const gchar *utf8filename) return retval; } -#define __G_WIN32_C__ -#include "galiasdef.c" +/** + * g_win32_get_command_line: + * + * Gets the command line arguments, on Windows, in the GLib filename + * encoding (ie: UTF-8). + * + * Normally, on Windows, the command line arguments are passed to main() + * in the system codepage encoding. This prevents passing filenames as + * arguments if the filenames contain characters that fall outside of + * this codepage. If such filenames are passed, then substitutions + * will occur (such as replacing some characters with '?'). + * + * GLib's policy of using UTF-8 as a filename encoding on Windows was + * designed to localise the pain of dealing with filenames outside of + * the system codepage to one area: dealing with commandline arguments + * in main(). + * + * As such, most GLib programs should ignore the value of argv passed to + * their main() function and call g_win32_get_command_line() instead. + * This will get the "full Unicode" commandline arguments using + * GetCommandLineW() and convert it to the GLib filename encoding (which + * is UTF-8 on Windows). + * + * The strings returned by this function are suitable for use with + * functions such as g_open() and g_file_new_for_commandline_arg() but + * are not suitable for use with g_option_context_parse(), which assumes + * that its input will be in the system codepage. The return value is + * suitable for use with g_option_context_parse_strv(), however, which + * is a better match anyway because it won't leak memory. + * + * Unlike argv, the returned value is a normal strv and can (and should) + * be freed with g_strfreev() when no longer needed. + * + * Returns: (transfer full): the commandline arguments in the GLib + * filename encoding (ie: UTF-8) + * + * Since: 2.40 + **/ +gchar ** +g_win32_get_command_line (void) +{ + gchar **result; + LPWSTR *args; + gint i, n; + + args = CommandLineToArgvW (GetCommandLineW(), &n); + + result = g_new (gchar *, n + 1); + for (i = 0; i < n; i++) + result[i] = g_utf16_to_utf8 (args[i], -1, NULL, NULL, NULL); + result[i] = NULL; + + return result; +}