cc6da5f9935faeeae7bb9a557606006ae7e04bb7
[platform/upstream/glib.git] / glib / gwin32.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-1999  Tor Lillqvist
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 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  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
21  * file for a list of people on the GLib Team.  See the ChangeLog
22  * files for a list of changes.  These files are distributed with
23  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
24  */
25
26 /* 
27  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
28  */
29
30 #include "config.h"
31
32 #include "glibconfig.h"
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <wchar.h>
38 #include <errno.h>
39
40 #define STRICT                  /* Strict typing, please */
41 #include <windows.h>
42 #undef STRICT
43 #ifndef G_WITH_CYGWIN
44 #include <direct.h>
45 #endif
46 #include <errno.h>
47 #include <ctype.h>
48 #if defined(_MSC_VER) || defined(__DMC__)
49 #  include <io.h>
50 #endif /* _MSC_VER || __DMC__ */
51
52 #define MODERN_API_FAMILY 2
53
54 #if WINAPI_FAMILY == MODERN_API_FAMILY
55 /* This is for modern UI Builds, where we can't use LoadLibraryW()/GetProcAddress() */
56 /* ntddk.h is found in the WDK, and MinGW */
57 #include <ntddk.h>
58
59 #ifdef _MSC_VER
60 #pragma comment (lib, "ntoskrnl.lib")
61 #endif
62 #elif defined (__MINGW32__)
63 /* mingw-w64, not MinGW, has winternl.h */
64 #include <ntdef.h>
65 #else
66 #include <winternl.h>
67 #endif
68
69 #include "glib.h"
70 #include "gthreadprivate.h"
71
72 #ifdef G_WITH_CYGWIN
73 #include <sys/cygwin.h>
74 #endif
75
76 #ifndef G_WITH_CYGWIN
77
78 gint
79 g_win32_ftruncate (gint  fd,
80                    guint size)
81 {
82   return _chsize (fd, size);
83 }
84
85 #endif
86
87 /**
88  * g_win32_getlocale:
89  *
90  * The setlocale() function in the Microsoft C library uses locale
91  * names of the form "English_United States.1252" etc. We want the
92  * UNIXish standard form "en_US", "zh_TW" etc. This function gets the
93  * current thread locale from Windows - without any encoding info -
94  * and returns it as a string of the above form for use in forming
95  * file names etc. The returned string should be deallocated with
96  * g_free().
97  *
98  * Returns: newly-allocated locale name.
99  **/
100
101 #ifndef SUBLANG_SERBIAN_LATIN_BA
102 #define SUBLANG_SERBIAN_LATIN_BA 0x06
103 #endif
104
105 gchar *
106 g_win32_getlocale (void)
107 {
108   LCID lcid;
109   LANGID langid;
110   gchar *ev;
111   gint primary, sub;
112   char iso639[10];
113   char iso3166[10];
114   const gchar *script = NULL;
115
116   /* Let the user override the system settings through environment
117    * variables, as on POSIX systems. Note that in GTK+ applications
118    * since GTK+ 2.10.7 setting either LC_ALL or LANG also sets the
119    * Win32 locale and C library locale through code in gtkmain.c.
120    */
121   if (((ev = getenv ("LC_ALL")) != NULL && ev[0] != '\0')
122       || ((ev = getenv ("LC_MESSAGES")) != NULL && ev[0] != '\0')
123       || ((ev = getenv ("LANG")) != NULL && ev[0] != '\0'))
124     return g_strdup (ev);
125
126   lcid = GetThreadLocale ();
127
128   if (!GetLocaleInfo (lcid, LOCALE_SISO639LANGNAME, iso639, sizeof (iso639)) ||
129       !GetLocaleInfo (lcid, LOCALE_SISO3166CTRYNAME, iso3166, sizeof (iso3166)))
130     return g_strdup ("C");
131   
132   /* Strip off the sorting rules, keep only the language part.  */
133   langid = LANGIDFROMLCID (lcid);
134
135   /* Split into language and territory part.  */
136   primary = PRIMARYLANGID (langid);
137   sub = SUBLANGID (langid);
138
139   /* Handle special cases */
140   switch (primary)
141     {
142     case LANG_AZERI:
143       switch (sub)
144         {
145         case SUBLANG_AZERI_LATIN:
146           script = "@Latn";
147           break;
148         case SUBLANG_AZERI_CYRILLIC:
149           script = "@Cyrl";
150           break;
151         }
152       break;
153     case LANG_SERBIAN:          /* LANG_CROATIAN == LANG_SERBIAN */
154       switch (sub)
155         {
156         case SUBLANG_SERBIAN_LATIN:
157         case 0x06: /* Serbian (Latin) - Bosnia and Herzegovina */
158           script = "@Latn";
159           break;
160         }
161       break;
162     case LANG_UZBEK:
163       switch (sub)
164         {
165         case SUBLANG_UZBEK_LATIN:
166           script = "@Latn";
167           break;
168         case SUBLANG_UZBEK_CYRILLIC:
169           script = "@Cyrl";
170           break;
171         }
172       break;
173     }
174   return g_strconcat (iso639, "_", iso3166, script, NULL);
175 }
176
177 /**
178  * g_win32_error_message:
179  * @error: error code.
180  *
181  * Translate a Win32 error code (as returned by GetLastError() or
182  * WSAGetLastError()) into the corresponding message. The message is
183  * either language neutral, or in the thread's language, or the user's
184  * language, the system's language, or US English (see docs for
185  * FormatMessage()). The returned string is in UTF-8. It should be
186  * deallocated with g_free().
187  *
188  * Returns: newly-allocated error message
189  **/
190 gchar *
191 g_win32_error_message (gint error)
192 {
193   gchar *retval;
194   wchar_t *msg = NULL;
195   size_t nchars;
196
197   FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
198                   |FORMAT_MESSAGE_IGNORE_INSERTS
199                   |FORMAT_MESSAGE_FROM_SYSTEM,
200                   NULL, error, 0,
201                   (LPWSTR) &msg, 0, NULL);
202   if (msg != NULL)
203     {
204       nchars = wcslen (msg);
205
206       if (nchars >= 2 && msg[nchars-1] == L'\n' && msg[nchars-2] == L'\r')
207         msg[nchars-2] = L'\0';
208
209       retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL);
210
211       LocalFree (msg);
212     }
213   else
214     retval = g_strdup ("");
215
216   return retval;
217 }
218
219 /**
220  * g_win32_get_package_installation_directory_of_module:
221  * @hmodule: (nullable): The Win32 handle for a DLL loaded into the current process, or %NULL
222  *
223  * This function tries to determine the installation directory of a
224  * software package based on the location of a DLL of the software
225  * package.
226  *
227  * @hmodule should be the handle of a loaded DLL or %NULL. The
228  * function looks up the directory that DLL was loaded from. If
229  * @hmodule is NULL, the directory the main executable of the current
230  * process is looked up. If that directory's last component is "bin"
231  * or "lib", its parent directory is returned, otherwise the directory
232  * itself.
233  *
234  * It thus makes sense to pass only the handle to a "public" DLL of a
235  * software package to this function, as such DLLs typically are known
236  * to be installed in a "bin" or occasionally "lib" subfolder of the
237  * installation folder. DLLs that are of the dynamically loaded module
238  * or plugin variety are often located in more private locations
239  * deeper down in the tree, from which it is impossible for GLib to
240  * deduce the root of the package installation.
241  *
242  * The typical use case for this function is to have a DllMain() that
243  * saves the handle for the DLL. Then when code in the DLL needs to
244  * construct names of files in the installation tree it calls this
245  * function passing the DLL handle.
246  *
247  * Returns: a string containing the guessed installation directory for
248  * the software package @hmodule is from. The string is in the GLib
249  * file name encoding, i.e. UTF-8. The return value should be freed
250  * with g_free() when not needed any longer. If the function fails
251  * %NULL is returned.
252  *
253  * Since: 2.16
254  */
255 gchar *
256 g_win32_get_package_installation_directory_of_module (gpointer hmodule)
257 {
258   gchar *filename;
259   gchar *retval;
260   gchar *p;
261   wchar_t wc_fn[MAX_PATH];
262
263   /* NOTE: it relies that GetModuleFileNameW returns only canonical paths */
264   if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH))
265     return NULL;
266
267   filename = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL);
268
269   if ((p = strrchr (filename, G_DIR_SEPARATOR)) != NULL)
270     *p = '\0';
271
272   retval = g_strdup (filename);
273
274   do
275     {
276       p = strrchr (retval, G_DIR_SEPARATOR);
277       if (p == NULL)
278         break;
279
280       *p = '\0';
281
282       if (g_ascii_strcasecmp (p + 1, "bin") == 0 ||
283           g_ascii_strcasecmp (p + 1, "lib") == 0)
284         break;
285     }
286   while (p != NULL);
287
288   if (p == NULL)
289     {
290       g_free (retval);
291       retval = filename;
292     }
293   else
294     g_free (filename);
295
296 #ifdef G_WITH_CYGWIN
297   /* In Cygwin we need to have POSIX paths */
298   {
299     gchar tmp[MAX_PATH];
300
301     cygwin_conv_to_posix_path (retval, tmp);
302     g_free (retval);
303     retval = g_strdup (tmp);
304   }
305 #endif
306
307   return retval;
308 }
309
310 static gchar *
311 get_package_directory_from_module (const gchar *module_name)
312 {
313   static GHashTable *module_dirs = NULL;
314   G_LOCK_DEFINE_STATIC (module_dirs);
315   HMODULE hmodule = NULL;
316   gchar *fn;
317
318   G_LOCK (module_dirs);
319
320   if (module_dirs == NULL)
321     module_dirs = g_hash_table_new (g_str_hash, g_str_equal);
322   
323   fn = g_hash_table_lookup (module_dirs, module_name ? module_name : "");
324       
325   if (fn)
326     {
327       G_UNLOCK (module_dirs);
328       return g_strdup (fn);
329     }
330
331   if (module_name)
332     {
333       wchar_t *wc_module_name = g_utf8_to_utf16 (module_name, -1, NULL, NULL, NULL);
334       hmodule = GetModuleHandleW (wc_module_name);
335       g_free (wc_module_name);
336
337       if (!hmodule)
338         {
339           G_UNLOCK (module_dirs);
340           return NULL;
341         }
342     }
343
344   fn = g_win32_get_package_installation_directory_of_module (hmodule);
345
346   if (fn == NULL)
347     {
348       G_UNLOCK (module_dirs);
349       return NULL;
350     }
351   
352   g_hash_table_insert (module_dirs, module_name ? g_strdup (module_name) : "", fn);
353
354   G_UNLOCK (module_dirs);
355
356   return g_strdup (fn);
357 }
358
359 /**
360  * g_win32_get_package_installation_directory:
361  * @package: (nullable): You should pass %NULL for this.
362  * @dll_name: (nullable): The name of a DLL that a package provides in UTF-8, or %NULL.
363  *
364  * Try to determine the installation directory for a software package.
365  *
366  * This function is deprecated. Use
367  * g_win32_get_package_installation_directory_of_module() instead.
368  *
369  * The use of @package is deprecated. You should always pass %NULL. A
370  * warning is printed if non-NULL is passed as @package.
371  *
372  * The original intended use of @package was for a short identifier of
373  * the package, typically the same identifier as used for
374  * `GETTEXT_PACKAGE` in software configured using GNU
375  * autotools. The function first looks in the Windows Registry for the
376  * value `#InstallationDirectory` in the key
377  * `#HKLM\Software\@package`, and if that value
378  * exists and is a string, returns that.
379  *
380  * It is strongly recommended that packagers of GLib-using libraries
381  * for Windows do not store installation paths in the Registry to be
382  * used by this function as that interfers with having several
383  * parallel installations of the library. Enabling multiple
384  * installations of different versions of some GLib-using library, or
385  * GLib itself, is desirable for various reasons.
386  *
387  * For this reason it is recommeded to always pass %NULL as
388  * @package to this function, to avoid the temptation to use the
389  * Registry. In version 2.20 of GLib the @package parameter
390  * will be ignored and this function won't look in the Registry at all.
391  *
392  * If @package is %NULL, or the above value isn't found in the
393  * Registry, but @dll_name is non-%NULL, it should name a DLL loaded
394  * into the current process. Typically that would be the name of the
395  * DLL calling this function, looking for its installation
396  * directory. The function then asks Windows what directory that DLL
397  * was loaded from. If that directory's last component is "bin" or
398  * "lib", the parent directory is returned, otherwise the directory
399  * itself. If that DLL isn't loaded, the function proceeds as if
400  * @dll_name was %NULL.
401  *
402  * If both @package and @dll_name are %NULL, the directory from where
403  * the main executable of the process was loaded is used instead in
404  * the same way as above.
405  *
406  * Returns: a string containing the installation directory for
407  * @package. The string is in the GLib file name encoding,
408  * i.e. UTF-8. The return value should be freed with g_free() when not
409  * needed any longer. If the function fails %NULL is returned.
410  *
411  * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to
412  * g_win32_get_package_installation_directory_of_module() instead.
413  **/
414
415 gchar *
416 g_win32_get_package_installation_directory (const gchar *package,
417                                             const gchar *dll_name)
418 {
419   gchar *result = NULL;
420
421   if (package != NULL)
422       g_warning ("Passing a non-NULL package to g_win32_get_package_installation_directory() is deprecated and it is ignored.");
423
424   if (dll_name != NULL)
425     result = get_package_directory_from_module (dll_name);
426
427   if (result == NULL)
428     result = get_package_directory_from_module (NULL);
429
430   return result;
431 }
432
433 /**
434  * g_win32_get_package_installation_subdirectory:
435  * @package: (nullable): You should pass %NULL for this.
436  * @dll_name: (nullable): The name of a DLL that a package provides, in UTF-8, or %NULL.
437  * @subdir: A subdirectory of the package installation directory, also in UTF-8
438  *
439  * This function is deprecated. Use
440  * g_win32_get_package_installation_directory_of_module() and
441  * g_build_filename() instead.
442  *
443  * Returns a newly-allocated string containing the path of the
444  * subdirectory @subdir in the return value from calling
445  * g_win32_get_package_installation_directory() with the @package and
446  * @dll_name parameters. See the documentation for
447  * g_win32_get_package_installation_directory() for more details. In
448  * particular, note that it is deprecated to pass anything except NULL
449  * as @package.
450  *
451  * Returns: a string containing the complete path to @subdir inside
452  * the installation directory of @package. The returned string is in
453  * the GLib file name encoding, i.e. UTF-8. The return value should be
454  * freed with g_free() when no longer needed. If something goes wrong,
455  * %NULL is returned.
456  *
457  * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to
458  * g_win32_get_package_installation_directory_of_module() instead, and
459  * then construct a subdirectory pathname with g_build_filename().
460  **/
461
462 gchar *
463 g_win32_get_package_installation_subdirectory (const gchar *package,
464                                                const gchar *dll_name,
465                                                const gchar *subdir)
466 {
467   gchar *prefix;
468   gchar *dirname;
469
470 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
471   prefix = g_win32_get_package_installation_directory (package, dll_name);
472 G_GNUC_END_IGNORE_DEPRECATIONS
473
474   dirname = g_build_filename (prefix, subdir, NULL);
475   g_free (prefix);
476
477   return dirname;
478 }
479
480 /**
481  * g_win32_check_windows_version:
482  * @major: major version of Windows
483  * @minor: minor version of Windows
484  * @spver: Windows Service Pack Level, 0 if none
485  * @os_type: Type of Windows OS
486  *
487  * Returns whether the version of the Windows operating system the
488  * code is running on is at least the specified major, minor and
489  * service pack versions.  See MSDN documentation for the Operating
490  * System Version.  Software that needs even more detailed version and
491  * feature information should use the Win32 API VerifyVersionInfo()
492  * directly.
493  *
494  * Successive calls of this function can be used for enabling or
495  * disabling features at run-time for a range of Windows versions,
496  * as per the VerifyVersionInfo() API documentation.
497  *
498  * Returns: %TRUE if the Windows Version is the same or greater than
499  *          the specified major, minor and service pack versions, and
500  *          whether the running Windows is a workstation or server edition
501  *          of Windows, if specifically specified.
502  *
503  * Since: 2.44
504  **/
505 gboolean
506 g_win32_check_windows_version (const gint major,
507                                const gint minor,
508                                const gint spver,
509                                const GWin32OSType os_type)
510 {
511   OSVERSIONINFOEXW osverinfo;
512   gboolean is_ver_checked = FALSE;
513   gboolean is_type_checked = FALSE;
514
515 #if WINAPI_FAMILY != MODERN_API_FAMILY
516   /* For non-modern UI Apps, use the LoadLibraryW()/GetProcAddress() thing */
517   typedef NTSTATUS (WINAPI fRtlGetVersion) (PRTL_OSVERSIONINFOEXW);
518
519   fRtlGetVersion *RtlGetVersion;
520   HMODULE hmodule;
521 #endif
522   /* We Only Support Checking for XP or later */
523   g_return_val_if_fail (major >= 5 && (major <=6 || major == 10), FALSE);
524   g_return_val_if_fail ((major >= 5 && minor >= 1) || major >= 6, FALSE);
525
526   /* Check for Service Pack Version >= 0 */
527   g_return_val_if_fail (spver >= 0, FALSE);
528
529 #if WINAPI_FAMILY != MODERN_API_FAMILY
530   hmodule = LoadLibraryW (L"ntdll.dll");
531   g_return_val_if_fail (hmodule != NULL, FALSE);
532
533   RtlGetVersion = (fRtlGetVersion *) GetProcAddress (hmodule, "RtlGetVersion");
534   g_return_val_if_fail (RtlGetVersion != NULL, FALSE);
535 #endif
536
537   memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW));
538   osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
539   RtlGetVersion (&osverinfo);
540
541   /* check the OS and Service Pack Versions */
542   if (osverinfo.dwMajorVersion > major)
543     is_ver_checked = TRUE;
544   else if (osverinfo.dwMajorVersion == major)
545     {
546       if (osverinfo.dwMinorVersion > minor)
547         is_ver_checked = TRUE;
548       else if (osverinfo.dwMinorVersion == minor)
549         if (osverinfo.wServicePackMajor >= spver)
550           is_ver_checked = TRUE;
551     }
552
553   /* Check OS Type */
554   if (is_ver_checked)
555     {
556       switch (os_type)
557         {
558           case G_WIN32_OS_ANY:
559             is_type_checked = TRUE;
560             break;
561           case G_WIN32_OS_WORKSTATION:
562             if (osverinfo.wProductType == VER_NT_WORKSTATION)
563               is_type_checked = TRUE;
564             break;
565           case G_WIN32_OS_SERVER:
566             if (osverinfo.wProductType == VER_NT_SERVER ||
567                 osverinfo.wProductType == VER_NT_DOMAIN_CONTROLLER)
568               is_type_checked = TRUE;
569             break;
570           default:
571             /* shouldn't get here normally */
572             g_warning ("Invalid os_type specified");
573             break;
574         }
575     }
576
577 #if WINAPI_FAMILY != MODERN_API_FAMILY
578   FreeLibrary (hmodule);
579 #endif
580
581   return is_ver_checked && is_type_checked;
582 }
583
584 /**
585  * g_win32_get_windows_version:
586  *
587  * This function is deprecated. Use
588  * g_win32_check_windows_version() instead.
589  *
590  * Returns version information for the Windows operating system the
591  * code is running on. See MSDN documentation for the GetVersion()
592  * function. To summarize, the most significant bit is one on Win9x,
593  * and zero on NT-based systems. Since version 2.14, GLib works only
594  * on NT-based systems, so checking whether your are running on Win9x
595  * in your own software is moot. The least significant byte is 4 on
596  * Windows NT 4, and 5 on Windows XP. Software that needs really
597  * detailed version and feature information should use Win32 API like
598  * GetVersionEx() and VerifyVersionInfo().
599  *
600  * Returns: The version information.
601  *
602  * Deprecated: 2.44: Be aware that for Windows 8.1 and Windows Server
603  * 2012 R2 and later, this will return 62 unless the application is
604  * manifested for Windows 8.1/Windows Server 2012 R2, for example.
605  * MSDN stated that GetVersion(), which is used here, is subject to
606  * further change or removal after Windows 8.1.
607  **/
608 guint
609 g_win32_get_windows_version (void)
610 {
611   static gsize windows_version;
612
613   if (g_once_init_enter (&windows_version))
614     g_once_init_leave (&windows_version, GetVersion ());
615
616   return windows_version;
617 }
618
619 /*
620  * Doesn't use gettext (and gconv), preventing recursive calls when
621  * g_win32_locale_filename_from_utf8() is called during
622  * gettext initialization.
623  */
624 static gchar *
625 special_wchar_to_locale_enoding (wchar_t *wstring)
626 {
627   int sizeof_output;
628   int wctmb_result;
629   char *result;
630   BOOL not_representable = FALSE;
631
632   sizeof_output = WideCharToMultiByte (CP_ACP,
633                                        WC_NO_BEST_FIT_CHARS,
634                                        wstring, -1,
635                                        NULL, 0,
636                                        NULL,
637                                        &not_representable);
638
639   if (not_representable ||
640       sizeof_output == 0 ||
641       sizeof_output > MAX_PATH)
642     return NULL;
643
644   result = g_malloc0 (sizeof_output + 1);
645
646   wctmb_result = WideCharToMultiByte (CP_ACP,
647                                       WC_NO_BEST_FIT_CHARS,
648                                       wstring, -1,
649                                       result, sizeof_output + 1,
650                                       NULL,
651                                       &not_representable);
652
653   if (wctmb_result == sizeof_output &&
654       not_representable == FALSE)
655     return result;
656
657   g_free (result);
658
659   return NULL;
660 }
661
662 /**
663  * g_win32_locale_filename_from_utf8:
664  * @utf8filename: a UTF-8 encoded filename.
665  *
666  * Converts a filename from UTF-8 to the system codepage.
667  *
668  * On NT-based Windows, on NTFS file systems, file names are in
669  * Unicode. It is quite possible that Unicode file names contain
670  * characters not representable in the system codepage. (For instance,
671  * Greek or Cyrillic characters on Western European or US Windows
672  * installations, or various less common CJK characters on CJK Windows
673  * installations.)
674  *
675  * In such a case, and if the filename refers to an existing file, and
676  * the file system stores alternate short (8.3) names for directory
677  * entries, the short form of the filename is returned. Note that the
678  * "short" name might in fact be longer than the Unicode name if the
679  * Unicode name has very short pathname components containing
680  * non-ASCII characters. If no system codepage name for the file is
681  * possible, %NULL is returned.
682  *
683  * The return value is dynamically allocated and should be freed with
684  * g_free() when no longer needed.
685  *
686  * Returns: The converted filename, or %NULL on conversion
687  * failure and lack of short names.
688  *
689  * Since: 2.8
690  */
691 gchar *
692 g_win32_locale_filename_from_utf8 (const gchar *utf8filename)
693 {
694   gchar *retval;
695   wchar_t *wname;
696
697   wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL);
698
699   if (wname == NULL)
700     return NULL;
701
702   retval = special_wchar_to_locale_enoding (wname);
703
704   if (retval == NULL)
705     {
706       /* Conversion failed, so check if there is a 8.3 version, and use that. */
707       wchar_t wshortname[MAX_PATH + 1];
708
709       if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname)))
710         retval = special_wchar_to_locale_enoding (wshortname);
711     }
712
713   g_free (wname);
714
715   return retval;
716 }
717
718 /**
719  * g_win32_get_command_line:
720  *
721  * Gets the command line arguments, on Windows, in the GLib filename
722  * encoding (ie: UTF-8).
723  *
724  * Normally, on Windows, the command line arguments are passed to main()
725  * in the system codepage encoding.  This prevents passing filenames as
726  * arguments if the filenames contain characters that fall outside of
727  * this codepage.  If such filenames are passed, then substitutions
728  * will occur (such as replacing some characters with '?').
729  *
730  * GLib's policy of using UTF-8 as a filename encoding on Windows was
731  * designed to localise the pain of dealing with filenames outside of
732  * the system codepage to one area: dealing with commandline arguments
733  * in main().
734  *
735  * As such, most GLib programs should ignore the value of argv passed to
736  * their main() function and call g_win32_get_command_line() instead.
737  * This will get the "full Unicode" commandline arguments using
738  * GetCommandLineW() and convert it to the GLib filename encoding (which
739  * is UTF-8 on Windows).
740  *
741  * The strings returned by this function are suitable for use with
742  * functions such as g_open() and g_file_new_for_commandline_arg() but
743  * are not suitable for use with g_option_context_parse(), which assumes
744  * that its input will be in the system codepage.  The return value is
745  * suitable for use with g_option_context_parse_strv(), however, which
746  * is a better match anyway because it won't leak memory.
747  *
748  * Unlike argv, the returned value is a normal strv and can (and should)
749  * be freed with g_strfreev() when no longer needed.
750  *
751  * Returns: (transfer full): the commandline arguments in the GLib
752  *   filename encoding (ie: UTF-8)
753  *
754  * Since: 2.40
755  **/
756 gchar **
757 g_win32_get_command_line (void)
758 {
759   gchar **result;
760   LPWSTR *args;
761   gint i, n;
762
763   args = CommandLineToArgvW (GetCommandLineW(), &n);
764
765   result = g_new (gchar *, n + 1);
766   for (i = 0; i < n; i++)
767     result[i] = g_utf16_to_utf8 (args[i], -1, NULL, NULL, NULL);
768   result[i] = NULL;
769
770   LocalFree (args);
771   return result;
772 }
773
774 #ifdef G_OS_WIN32
775
776 /* Binary compatibility versions. Not for newly compiled code. */
777
778 _GLIB_EXTERN gchar *g_win32_get_package_installation_directory_utf8    (const gchar *package,
779                                                                         const gchar *dll_name);
780
781 _GLIB_EXTERN gchar *g_win32_get_package_installation_subdirectory_utf8 (const gchar *package,
782                                                                         const gchar *dll_name,
783                                                                         const gchar *subdir);
784
785 gchar *
786 g_win32_get_package_installation_directory_utf8 (const gchar *package,
787                                                  const gchar *dll_name)
788 {
789 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
790   return g_win32_get_package_installation_directory (package, dll_name);
791 G_GNUC_END_IGNORE_DEPRECATIONS
792 }
793
794 gchar *
795 g_win32_get_package_installation_subdirectory_utf8 (const gchar *package,
796                                                     const gchar *dll_name,
797                                                     const gchar *subdir)
798 {
799 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
800   return g_win32_get_package_installation_subdirectory (package,
801                                                         dll_name,
802                                                         subdir);
803 G_GNUC_END_IGNORE_DEPRECATIONS
804 }
805
806 #endif