aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-11-02 15:03:32 +0200
committerEli Zaretskii2013-11-02 15:03:32 +0200
commit1fd201bb1d720d0c5ab727a3972363778eef834f (patch)
tree508abf22dbb91d24309869bc42a93e814f9fbcd6 /src
parent5c4a19a90f803ed46629c2bdc1ac3d3563caa738 (diff)
downloademacs-1fd201bb1d720d0c5ab727a3972363778eef834f.tar.gz
emacs-1fd201bb1d720d0c5ab727a3972363778eef834f.zip
Adapted dostounix_filename. w32-short/long-filename work with wide APIs.
Diffstat (limited to 'src')
-rw-r--r--src/emacs.c19
-rw-r--r--src/fileio.c20
-rw-r--r--src/filelock.c2
-rw-r--r--src/msdos.c6
-rw-r--r--src/msdos.h2
-rw-r--r--src/termcap.c2
-rw-r--r--src/unexw32.c10
-rw-r--r--src/w32.c202
-rw-r--r--src/w32.h7
-rw-r--r--src/w32fns.c4
-rw-r--r--src/w32proc.c14
11 files changed, 131 insertions, 157 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 06b8d290cae..a58829e8918 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2153,9 +2153,15 @@ decode_env_path (const char *evarname, const char *defalt)
2153 Lisp_Object lpath, element, tem; 2153 Lisp_Object lpath, element, tem;
2154#ifdef WINDOWSNT 2154#ifdef WINDOWSNT
2155 bool defaulted = 0; 2155 bool defaulted = 0;
2156 const char *emacs_dir = egetenv ("emacs_dir");
2157 static const char *emacs_dir_env = "%emacs_dir%/"; 2156 static const char *emacs_dir_env = "%emacs_dir%/";
2158 const size_t emacs_dir_len = strlen (emacs_dir_env); 2157 const size_t emacs_dir_len = strlen (emacs_dir_env);
2158 const char *edir = egetenv ("emacs_dir");
2159 char emacs_dir[MAX_UTF8_PATH];
2160
2161 /* egetenv looks in process-environment, which holds the variables
2162 in their original system-locale encoding. We need emacs_dir to
2163 be in UTF-8. */
2164 filename_from_ansi (edir, emacs_dir);
2159#endif 2165#endif
2160 2166
2161 /* It's okay to use getenv here, because this function is only used 2167 /* It's okay to use getenv here, because this function is only used
@@ -2176,9 +2182,16 @@ decode_env_path (const char *evarname, const char *defalt)
2176 /* Ensure values from the environment use the proper directory separator. */ 2182 /* Ensure values from the environment use the proper directory separator. */
2177 if (path) 2183 if (path)
2178 { 2184 {
2179 char *path_copy = alloca (strlen (path) + 1); 2185 char *path_copy;
2186
2187#ifdef WINDOWSNT
2188 path_copy = alloca (MAX_UTF8_PATH);
2189 filename_from_ansi (path, path_copy);
2190#else /* MSDOS */
2191 path_copy = alloca (strlen (path) + 1);
2180 strcpy (path_copy, path); 2192 strcpy (path_copy, path);
2181 dostounix_filename (path_copy, 0); 2193#endif
2194 dostounix_filename (path_copy);
2182 path = path_copy; 2195 path = path_copy;
2183 } 2196 }
2184#endif 2197#endif
diff --git a/src/fileio.c b/src/fileio.c
index dc6d80932c4..eeaa736290c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -459,7 +459,8 @@ Given a Unix syntax file name, returns a string ending in slash. */)
459 strcat (res, "/"); 459 strcat (res, "/");
460 beg = res; 460 beg = res;
461 p = beg + strlen (beg); 461 p = beg + strlen (beg);
462 dostounix_filename (beg, 0); 462 dostounix_filename (beg);
463 /* FIXME: Figure out the multibyte vs unibyte stuff here. */
463 tem_fn = make_specified_string (beg, -1, p - beg, 464 tem_fn = make_specified_string (beg, -1, p - beg,
464 STRING_MULTIBYTE (filename)); 465 STRING_MULTIBYTE (filename));
465 } 466 }
@@ -470,7 +471,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
470 else if (STRING_MULTIBYTE (filename)) 471 else if (STRING_MULTIBYTE (filename))
471 { 472 {
472 tem_fn = make_specified_string (beg, -1, p - beg, 1); 473 tem_fn = make_specified_string (beg, -1, p - beg, 1);
473 dostounix_filename (SSDATA (tem_fn), 1); 474 dostounix_filename (SSDATA (tem_fn));
474#ifdef WINDOWSNT 475#ifdef WINDOWSNT
475 if (!NILP (Vw32_downcase_file_names)) 476 if (!NILP (Vw32_downcase_file_names))
476 tem_fn = Fdowncase (tem_fn); 477 tem_fn = Fdowncase (tem_fn);
@@ -478,7 +479,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
478 } 479 }
479 else 480 else
480 { 481 {
481 dostounix_filename (beg, 0); 482 dostounix_filename (beg);
482 tem_fn = make_specified_string (beg, -1, p - beg, 0); 483 tem_fn = make_specified_string (beg, -1, p - beg, 0);
483 } 484 }
484 return tem_fn; 485 return tem_fn;
@@ -582,7 +583,7 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen,
582 dst[srclen++] = DIRECTORY_SEP; 583 dst[srclen++] = DIRECTORY_SEP;
583 dst[srclen] = 0; 584 dst[srclen] = 0;
584#ifdef DOS_NT 585#ifdef DOS_NT
585 dostounix_filename (dst, multibyte); 586 dostounix_filename (dst);
586#endif 587#endif
587 return srclen; 588 return srclen;
588} 589}
@@ -651,7 +652,7 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
651 memcpy (dst, src, srclen); 652 memcpy (dst, src, srclen);
652 dst[srclen] = 0; 653 dst[srclen] = 0;
653#ifdef DOS_NT 654#ifdef DOS_NT
654 dostounix_filename (dst, multibyte); 655 dostounix_filename (dst);
655#endif 656#endif
656 return srclen; 657 return srclen;
657} 658}
@@ -1082,7 +1083,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1082#ifdef DOS_NT 1083#ifdef DOS_NT
1083 /* Make sure directories are all separated with /, but 1084 /* Make sure directories are all separated with /, but
1084 avoid allocation of a new string when not required. */ 1085 avoid allocation of a new string when not required. */
1085 dostounix_filename (nm, multibyte); 1086 /* FIXME: Figure out multibyte and downcase here. */
1087 dostounix_filename (nm);
1086#ifdef WINDOWSNT 1088#ifdef WINDOWSNT
1087 if (IS_DIRECTORY_SEP (nm[1])) 1089 if (IS_DIRECTORY_SEP (nm[1]))
1088 { 1090 {
@@ -1465,7 +1467,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1465 target[1] = ':'; 1467 target[1] = ':';
1466 } 1468 }
1467 result = make_specified_string (target, -1, o - target, multibyte); 1469 result = make_specified_string (target, -1, o - target, multibyte);
1468 dostounix_filename (SSDATA (result), multibyte); 1470 /* FIXME: Figure out the multibyte and downcase here. */
1471 dostounix_filename (SSDATA (result));
1469#ifdef WINDOWSNT 1472#ifdef WINDOWSNT
1470 if (!NILP (Vw32_downcase_file_names)) 1473 if (!NILP (Vw32_downcase_file_names))
1471 result = Fdowncase (result); 1474 result = Fdowncase (result);
@@ -1749,7 +1752,8 @@ those `/' is discarded. */)
1749 nm = xlispstrdupa (filename); 1752 nm = xlispstrdupa (filename);
1750 1753
1751#ifdef DOS_NT 1754#ifdef DOS_NT
1752 dostounix_filename (nm, multibyte); 1755 /* FIXME: Figure out multibyte and downcase. */
1756 dostounix_filename (nm);
1753 substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); 1757 substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0);
1754#endif 1758#endif
1755 endp = nm + SBYTES (filename); 1759 endp = nm + SBYTES (filename);
diff --git a/src/filelock.c b/src/filelock.c
index 2f53047f526..82ffd5d172b 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -689,7 +689,7 @@ lock_file (Lisp_Object fn)
689 /* Ensure we have only '/' separators, to avoid problems with 689 /* Ensure we have only '/' separators, to avoid problems with
690 looking (inside fill_in_lock_file_name) for backslashes in file 690 looking (inside fill_in_lock_file_name) for backslashes in file
691 names encoded by some DBCS codepage. */ 691 names encoded by some DBCS codepage. */
692 dostounix_filename (SSDATA (fn), 1); 692 dostounix_filename (SSDATA (fn));
693#endif 693#endif
694 encoded_fn = ENCODE_FILE (fn); 694 encoded_fn = ENCODE_FILE (fn);
695 695
diff --git a/src/msdos.c b/src/msdos.c
index 2ba7a16a443..cb4f8c3df89 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -3295,7 +3295,7 @@ void msdos_downcase_filename (unsigned char *);
3295/* Destructively turn backslashes into slashes. */ 3295/* Destructively turn backslashes into slashes. */
3296 3296
3297void 3297void
3298dostounix_filename (char *p, int ignore) 3298dostounix_filename (char *p)
3299{ 3299{
3300 msdos_downcase_filename (p); 3300 msdos_downcase_filename (p);
3301 3301
@@ -3559,7 +3559,7 @@ init_environment (int argc, char **argv, int skip_args)
3559 if (!s) s = "c:/command.com"; 3559 if (!s) s = "c:/command.com";
3560 t = alloca (strlen (s) + 1); 3560 t = alloca (strlen (s) + 1);
3561 strcpy (t, s); 3561 strcpy (t, s);
3562 dostounix_filename (t, 0); 3562 dostounix_filename (t);
3563 setenv ("SHELL", t, 0); 3563 setenv ("SHELL", t, 0);
3564 3564
3565 /* PATH is also downcased and backslashes mirrored. */ 3565 /* PATH is also downcased and backslashes mirrored. */
@@ -3569,7 +3569,7 @@ init_environment (int argc, char **argv, int skip_args)
3569 /* Current directory is always considered part of MsDos's path but it is 3569 /* Current directory is always considered part of MsDos's path but it is
3570 not normally mentioned. Now it is. */ 3570 not normally mentioned. Now it is. */
3571 strcat (strcpy (t, ".;"), s); 3571 strcat (strcpy (t, ".;"), s);
3572 dostounix_filename (t, 0); /* Not a single file name, but this should work. */ 3572 dostounix_filename (t); /* Not a single file name, but this should work. */
3573 setenv ("PATH", t, 1); 3573 setenv ("PATH", t, 1);
3574 3574
3575 /* In some sense all dos users have root privileges, so... */ 3575 /* In some sense all dos users have root privileges, so... */
diff --git a/src/msdos.h b/src/msdos.h
index 27090324b44..11d7eb5c3e1 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -29,7 +29,7 @@ void dos_set_window_size (int *, int *);
29 29
30int getdefdir (int, char*); 30int getdefdir (int, char*);
31void unixtodos_filename (char *); 31void unixtodos_filename (char *);
32void dostounix_filename (char *, int); 32void dostounix_filename (char *);
33char *rootrelativepath (char *); 33char *rootrelativepath (char *);
34void init_environment (int, char **, int); 34void init_environment (int, char **, int);
35void internal_terminal_init (void); 35void internal_terminal_init (void);
diff --git a/src/termcap.c b/src/termcap.c
index aa225d9b3b1..f0819266318 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -393,7 +393,7 @@ tgetent (char *bp, const char *name)
393 if (termcap_name && (*termcap_name == '\\' 393 if (termcap_name && (*termcap_name == '\\'
394 || *termcap_name == '/' 394 || *termcap_name == '/'
395 || termcap_name[1] == ':')) 395 || termcap_name[1] == ':'))
396 dostounix_filename (termcap_name, 0); 396 dostounix_filename (termcap_name);
397#endif 397#endif
398 398
399 filep = termcap_name && valid_filename_p (termcap_name); 399 filep = termcap_name && valid_filename_p (termcap_name);
diff --git a/src/unexw32.c b/src/unexw32.c
index a01ac799592..5320ec1e371 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -728,9 +728,15 @@ unexec (const char *new_name, const char *old_name)
728 char *q; 728 char *q;
729 729
730 /* Ignore old_name, and get our actual location from the OS. */ 730 /* Ignore old_name, and get our actual location from the OS. */
731 if (!GetModuleFileName (NULL, in_filename, MAX_PATH)) 731 if (!GetModuleFileNameA (NULL, in_filename, MAX_PATH))
732 abort (); 732 abort ();
733 dostounix_filename (in_filename, 0); 733
734 /* Can't use dostounix_filename here, since that needs its file name
735 argument encoded in UTF-8. */
736 for (p = in_filename; *p; p = CharNextA (p))
737 if (*p == '\\')
738 *p = '/';
739
734 strcpy (out_filename, in_filename); 740 strcpy (out_filename, in_filename);
735 741
736 /* Change the base of the output filename to match the requested name. */ 742 /* Change the base of the output filename to match the requested name. */
diff --git a/src/w32.c b/src/w32.c
index 09d78141e14..396a8cdd08b 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1336,7 +1336,7 @@ filename_to_ansi (const char *fn_in, char *fn_out)
1336 return -1; 1336 return -1;
1337} 1337}
1338 1338
1339static int 1339int
1340filename_from_ansi (const char *fn_in, char *fn_out) 1340filename_from_ansi (const char *fn_in, char *fn_out)
1341{ 1341{
1342 wchar_t fn_utf16[MAXPATHLEN]; 1342 wchar_t fn_utf16[MAXPATHLEN];
@@ -1799,31 +1799,20 @@ max_filename_mbslen (void)
1799 return cp_info.MaxCharSize; 1799 return cp_info.MaxCharSize;
1800} 1800}
1801 1801
1802/* Normalize filename by converting all path separators to 1802/* Normalize filename by converting in-place all of its path
1803 the specified separator. Also conditionally convert upper 1803 separators to the separator specified by PATH_SEP. */
1804 case path name components to lower case. */
1805 1804
1806static void 1805static void
1807normalize_filename (register char *fp, char path_sep, int multibyte) 1806normalize_filename (register char *fp, char path_sep)
1808{ 1807{
1809 char sep; 1808 char *p2;
1810 char *elem, *p2;
1811 int dbcs_p = max_filename_mbslen () > 1;
1812
1813 /* Multibyte file names are in the Emacs internal representation, so
1814 we can traverse them by bytes with no problems. */
1815 if (multibyte)
1816 dbcs_p = 0;
1817 1809
1818 /* Always lower-case drive letters a-z, even if the filesystem 1810 /* Always lower-case drive letters a-z, even if the filesystem
1819 preserves case in filenames. 1811 preserves case in filenames.
1820 This is so filenames can be compared by string comparison 1812 This is so filenames can be compared by string comparison
1821 functions that are case-sensitive. Even case-preserving filesystems 1813 functions that are case-sensitive. Even case-preserving filesystems
1822 do not distinguish case in drive letters. */ 1814 do not distinguish case in drive letters. */
1823 if (dbcs_p) 1815 p2 = fp + 1;
1824 p2 = CharNextExA (file_name_codepage, fp, 0);
1825 else
1826 p2 = fp + 1;
1827 1816
1828 if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z') 1817 if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z')
1829 { 1818 {
@@ -1831,68 +1820,26 @@ normalize_filename (register char *fp, char path_sep, int multibyte)
1831 fp += 2; 1820 fp += 2;
1832 } 1821 }
1833 1822
1834 if (multibyte || NILP (Vw32_downcase_file_names)) 1823 while (*fp)
1835 { 1824 {
1836 while (*fp) 1825 if (*fp == '/' || *fp == '\\')
1837 { 1826 *fp = path_sep;
1838 if (*fp == '/' || *fp == '\\') 1827 fp++;
1839 *fp = path_sep;
1840 if (!dbcs_p)
1841 fp++;
1842 else
1843 fp = CharNextExA (file_name_codepage, fp, 0);
1844 }
1845 return;
1846 } 1828 }
1847
1848 sep = path_sep; /* convert to this path separator */
1849 elem = fp; /* start of current path element */
1850
1851 do {
1852 if (*fp >= 'a' && *fp <= 'z')
1853 elem = 0; /* don't convert this element */
1854
1855 if (*fp == 0 || *fp == ':')
1856 {
1857 sep = *fp; /* restore current separator (or 0) */
1858 *fp = '/'; /* after conversion of this element */
1859 }
1860
1861 if (*fp == '/' || *fp == '\\')
1862 {
1863 if (elem && elem != fp)
1864 {
1865 *fp = 0; /* temporary end of string */
1866 _mbslwr (elem); /* while we convert to lower case */
1867 }
1868 *fp = sep; /* convert (or restore) path separator */
1869 elem = fp + 1; /* next element starts after separator */
1870 sep = path_sep;
1871 }
1872 if (*fp)
1873 {
1874 if (!dbcs_p)
1875 fp++;
1876 else
1877 fp = CharNextExA (file_name_codepage, fp, 0);
1878 }
1879 } while (*fp);
1880} 1829}
1881 1830
1882/* Destructively turn backslashes into slashes. MULTIBYTE non-zero 1831/* Destructively turn backslashes into slashes. */
1883 means the file name is a multibyte string in Emacs's internal
1884 representation. */
1885void 1832void
1886dostounix_filename (register char *p, int multibyte) 1833dostounix_filename (register char *p)
1887{ 1834{
1888 normalize_filename (p, '/', multibyte); 1835 normalize_filename (p, '/');
1889} 1836}
1890 1837
1891/* Destructively turn slashes into backslashes. */ 1838/* Destructively turn slashes into backslashes. */
1892void 1839void
1893unixtodos_filename (register char *p) 1840unixtodos_filename (register char *p)
1894{ 1841{
1895 normalize_filename (p, '\\', 0); 1842 normalize_filename (p, '\\');
1896} 1843}
1897 1844
1898/* Remove all CR's that are followed by a LF. 1845/* Remove all CR's that are followed by a LF.
@@ -1943,17 +1890,13 @@ parse_root (char * name, char ** pPath)
1943 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) 1890 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
1944 { 1891 {
1945 int slashes = 2; 1892 int slashes = 2;
1946 int dbcs_p = max_filename_mbslen () > 1;
1947 1893
1948 name += 2; 1894 name += 2;
1949 do 1895 do
1950 { 1896 {
1951 if (IS_DIRECTORY_SEP (*name) && --slashes == 0) 1897 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
1952 break; 1898 break;
1953 if (dbcs_p) 1899 name++;
1954 name = CharNextExA (file_name_codepage, name, 0);
1955 else
1956 name++;
1957 } 1900 }
1958 while ( *name ); 1901 while ( *name );
1959 if (IS_DIRECTORY_SEP (name[0])) 1902 if (IS_DIRECTORY_SEP (name[0]))
@@ -1970,23 +1913,44 @@ parse_root (char * name, char ** pPath)
1970static int 1913static int
1971get_long_basename (char * name, char * buf, int size) 1914get_long_basename (char * name, char * buf, int size)
1972{ 1915{
1973 WIN32_FIND_DATA find_data;
1974 HANDLE dir_handle; 1916 HANDLE dir_handle;
1917 char fname_utf8[MAX_UTF8_PATH];
1975 int len = 0; 1918 int len = 0;
1919 int cstatus;
1976 1920
1977 /* must be valid filename, no wild cards or other invalid characters */ 1921 /* Must be valid filename, no wild cards or other invalid characters. */
1978 if (_mbspbrk (name, "*?|<>\"")) 1922 if (strpbrk (name, "*?|<>\""))
1979 return 0; 1923 return 0;
1980 1924
1981 dir_handle = FindFirstFile (name, &find_data); 1925 if (w32_unicode_filenames)
1982 if (dir_handle != INVALID_HANDLE_VALUE)
1983 { 1926 {
1984 if ((len = strlen (find_data.cFileName)) < size) 1927 wchar_t fname_utf16[MAX_PATH];
1985 memcpy (buf, find_data.cFileName, len + 1); 1928 WIN32_FIND_DATAW find_data_wide;
1986 else 1929
1987 len = 0; 1930 filename_to_utf16 (name, fname_utf16);
1988 FindClose (dir_handle); 1931 dir_handle = FindFirstFileW (fname_utf16, &find_data_wide);
1932 if (dir_handle != INVALID_HANDLE_VALUE)
1933 cstatus = filename_from_utf16 (find_data_wide.cFileName, fname_utf8);
1934 }
1935 else
1936 {
1937 char fname_ansi[MAX_PATH];
1938 WIN32_FIND_DATAA find_data_ansi;
1939
1940 filename_to_ansi (name, fname_ansi);
1941 dir_handle = FindFirstFileA (fname_ansi, &find_data_ansi);
1942 if (dir_handle != INVALID_HANDLE_VALUE)
1943 cstatus = filename_from_ansi (find_data_ansi.cFileName, fname_utf8);
1989 } 1944 }
1945
1946 if (cstatus == 0 && (len = strlen (fname_utf8)) < size)
1947 memcpy (buf, fname_utf8, len + 1);
1948 else
1949 len = 0;
1950
1951 if (dir_handle != INVALID_HANDLE_VALUE)
1952 FindClose (dir_handle);
1953
1990 return len; 1954 return len;
1991} 1955}
1992 1956
@@ -1997,11 +1961,11 @@ w32_get_long_filename (char * name, char * buf, int size)
1997 char * o = buf; 1961 char * o = buf;
1998 char * p; 1962 char * p;
1999 char * q; 1963 char * q;
2000 char full[ MAX_PATH ]; 1964 char full[ MAX_UTF8_PATH ];
2001 int len; 1965 int len;
2002 1966
2003 len = strlen (name); 1967 len = strlen (name);
2004 if (len >= MAX_PATH) 1968 if (len >= MAX_UTF8_PATH)
2005 return FALSE; 1969 return FALSE;
2006 1970
2007 /* Use local copy for destructive modification. */ 1971 /* Use local copy for destructive modification. */
@@ -2018,7 +1982,7 @@ w32_get_long_filename (char * name, char * buf, int size)
2018 while (p != NULL && *p) 1982 while (p != NULL && *p)
2019 { 1983 {
2020 q = p; 1984 q = p;
2021 p = _mbschr (q, '\\'); 1985 p = strchr (q, '\\');
2022 if (p) *p = '\0'; 1986 if (p) *p = '\0';
2023 len = get_long_basename (full, o, size); 1987 len = get_long_basename (full, o, size);
2024 if (len > 0) 1988 if (len > 0)
@@ -2042,6 +2006,29 @@ w32_get_long_filename (char * name, char * buf, int size)
2042 return TRUE; 2006 return TRUE;
2043} 2007}
2044 2008
2009unsigned int
2010w32_get_short_filename (char * name, char * buf, int size)
2011{
2012 if (w32_unicode_filenames)
2013 {
2014 wchar_t name_utf16[MAX_PATH], short_name[MAX_PATH];
2015 unsigned int retval;
2016
2017 filename_to_utf16 (name, name_utf16);
2018 retval = GetShortPathNameW (name_utf16, short_name, size);
2019 if (retval && retval < size)
2020 filename_from_utf16 (short_name, buf);
2021 return retval;
2022 }
2023 else
2024 {
2025 char name_ansi[MAX_PATH];
2026
2027 filename_to_ansi (name, name_ansi);
2028 return GetShortPathNameA (name_ansi, buf, size);
2029 }
2030}
2031
2045static int 2032static int
2046is_unc_volume (const char *filename) 2033is_unc_volume (const char *filename)
2047{ 2034{
@@ -2506,7 +2493,7 @@ emacs_root_dir (void)
2506 emacs_abort (); 2493 emacs_abort ();
2507 strcpy (root_dir, p); 2494 strcpy (root_dir, p);
2508 root_dir[parse_root (root_dir, NULL)] = '\0'; 2495 root_dir[parse_root (root_dir, NULL)] = '\0';
2509 dostounix_filename (root_dir, 0); 2496 dostounix_filename (root_dir);
2510 return root_dir; 2497 return root_dir;
2511} 2498}
2512 2499
@@ -3937,49 +3924,6 @@ convert_from_time_t (time_t time, FILETIME * pft)
3937 pft->dwLowDateTime = tmp.LowPart; 3924 pft->dwLowDateTime = tmp.LowPart;
3938} 3925}
3939 3926
3940#if 0
3941/* No reason to keep this; faking inode values either by hashing or even
3942 using the file index from GetInformationByHandle, is not perfect and
3943 so by default Emacs doesn't use the inode values on Windows.
3944 Instead, we now determine file-truename correctly (except for
3945 possible drive aliasing etc). */
3946
3947/* Modified version of "PJW" algorithm (see the "Dragon" compiler book). */
3948static unsigned
3949hashval (const unsigned char * str)
3950{
3951 unsigned h = 0;
3952 while (*str)
3953 {
3954 h = (h << 4) + *str++;
3955 h ^= (h >> 28);
3956 }
3957 return h;
3958}
3959
3960/* Return the hash value of the canonical pathname, excluding the
3961 drive/UNC header, to get a hopefully unique inode number. */
3962static DWORD
3963generate_inode_val (const char * name)
3964{
3965 char fullname[ MAX_PATH ];
3966 char * p;
3967 unsigned hash;
3968
3969 /* Get the truly canonical filename, if it exists. (Note: this
3970 doesn't resolve aliasing due to subst commands, or recognize hard
3971 links. */
3972 if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
3973 emacs_abort ();
3974
3975 parse_root (fullname, &p);
3976 /* Normal W32 filesystems are still case insensitive. */
3977 _strlwr (p);
3978 return hashval (p);
3979}
3980
3981#endif
3982
3983static PSECURITY_DESCRIPTOR 3927static PSECURITY_DESCRIPTOR
3984get_file_security_desc_by_handle (HANDLE h) 3928get_file_security_desc_by_handle (HANDLE h)
3985{ 3929{
diff --git a/src/w32.h b/src/w32.h
index c836937bd66..80756e8e4ff 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -152,6 +152,9 @@ extern int w32_valid_pointer_p (void *, int);
152/* Get long (aka "true") form of file name, if it exists. */ 152/* Get long (aka "true") form of file name, if it exists. */
153extern BOOL w32_get_long_filename (char * name, char * buf, int size); 153extern BOOL w32_get_long_filename (char * name, char * buf, int size);
154 154
155/* Get the short (a.k.a. "8+3") form of a file name. */
156extern unsigned int w32_get_short_filename (char *, char *, int);
157
155/* Prepare our standard handles for proper inheritance by child processes. */ 158/* Prepare our standard handles for proper inheritance by child processes. */
156extern void prepare_standard_handles (int in, int out, 159extern void prepare_standard_handles (int in, int out,
157 int err, HANDLE handles[4]); 160 int err, HANDLE handles[4]);
@@ -181,8 +184,10 @@ extern void init_environment (char **);
181extern void check_windows_init_file (void); 184extern void check_windows_init_file (void);
182extern void syms_of_ntproc (void); 185extern void syms_of_ntproc (void);
183extern void syms_of_ntterm (void); 186extern void syms_of_ntterm (void);
184extern void dostounix_filename (register char *, int); 187extern void dostounix_filename (register char *);
185extern void unixtodos_filename (register char *); 188extern void unixtodos_filename (register char *);
189extern int filename_from_ansi (const char *, char *);
190
186extern BOOL init_winsock (int load_now); 191extern BOOL init_winsock (int load_now);
187extern void srandom (int); 192extern void srandom (int);
188extern int random (void); 193extern int random (void);
diff --git a/src/w32fns.c b/src/w32fns.c
index c98c84c8542..3e60d68023b 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6466,8 +6466,8 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
6466#ifdef NTGUI_UNICODE 6466#ifdef NTGUI_UNICODE
6467 filename = from_unicode_buffer (filename_buf); 6467 filename = from_unicode_buffer (filename_buf);
6468#else /* !NTGUI_UNICODE */ 6468#else /* !NTGUI_UNICODE */
6469 dostounix_filename (filename_buf, 0); 6469 filename = DECODE_FILE (build_unibyte_string (filename_buf));
6470 filename = DECODE_FILE (build_string (filename_buf)); 6470 dostounix_filename (SSDATA (filename));
6471#endif /* NTGUI_UNICODE */ 6471#endif /* NTGUI_UNICODE */
6472 6472
6473#ifdef CYGWIN 6473#ifdef CYGWIN
diff --git a/src/w32proc.c b/src/w32proc.c
index ea16f26a0ee..89748267bc6 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -2647,10 +2647,11 @@ All path elements in FILENAME are converted to their short names. */)
2647 filename = Fexpand_file_name (filename, Qnil); 2647 filename = Fexpand_file_name (filename, Qnil);
2648 2648
2649 /* luckily, this returns the short version of each element in the path. */ 2649 /* luckily, this returns the short version of each element in the path. */
2650 if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0) 2650 if (w32_get_short_filename (SDATA (ENCODE_FILE (filename)),
2651 shortname, MAX_PATH) == 0)
2651 return Qnil; 2652 return Qnil;
2652 2653
2653 dostounix_filename (shortname, 0); 2654 dostounix_filename (shortname);
2654 2655
2655 /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ 2656 /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */
2656 return build_string (shortname); 2657 return build_string (shortname);
@@ -2664,7 +2665,7 @@ If FILENAME does not exist, return nil.
2664All path elements in FILENAME are converted to their long names. */) 2665All path elements in FILENAME are converted to their long names. */)
2665 (Lisp_Object filename) 2666 (Lisp_Object filename)
2666{ 2667{
2667 char longname[ MAX_PATH ]; 2668 char longname[ MAX_UTF8_PATH ];
2668 int drive_only = 0; 2669 int drive_only = 0;
2669 2670
2670 CHECK_STRING (filename); 2671 CHECK_STRING (filename);
@@ -2676,10 +2677,11 @@ All path elements in FILENAME are converted to their long names. */)
2676 /* first expand it. */ 2677 /* first expand it. */
2677 filename = Fexpand_file_name (filename, Qnil); 2678 filename = Fexpand_file_name (filename, Qnil);
2678 2679
2679 if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH)) 2680 if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname,
2681 MAX_UTF8_PATH))
2680 return Qnil; 2682 return Qnil;
2681 2683
2682 dostounix_filename (longname, 0); 2684 dostounix_filename (longname);
2683 2685
2684 /* If we were passed only a drive, make sure that a slash is not appended 2686 /* If we were passed only a drive, make sure that a slash is not appended
2685 for consistency with directories. Allow for drive mapping via SUBST 2687 for consistency with directories. Allow for drive mapping via SUBST
@@ -2687,7 +2689,7 @@ All path elements in FILENAME are converted to their long names. */)
2687 if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3]) 2689 if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3])
2688 longname[2] = '\0'; 2690 longname[2] = '\0';
2689 2691
2690 return DECODE_FILE (build_string (longname)); 2692 return DECODE_FILE (build_unibyte_string (longname));
2691} 2693}
2692 2694
2693DEFUN ("w32-set-process-priority", Fw32_set_process_priority, 2695DEFUN ("w32-set-process-priority", Fw32_set_process_priority,