@@ -456,15 +456,22 @@ mch_FullName(
456456 int
457457mch_isFullName (char_u * fname )
458458{
459+ #ifdef FEAT_MBYTE
460+ /* WinNT and later can use _MAX_PATH wide characters for a pathname, which
461+ * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is
462+ * UTF-8. */
463+ char szName [_MAX_PATH * 3 + 1 ];
464+ #else
459465 char szName [_MAX_PATH + 1 ];
466+ #endif
460467
461468 /* A name like "d:/foo" and "//server/share" is absolute */
462469 if ((fname [0 ] && fname [1 ] == ':' && (fname [2 ] == '/' || fname [2 ] == '\\' ))
463470 || (fname [0 ] == fname [1 ] && (fname [0 ] == '/' || fname [0 ] == '\\' )))
464471 return TRUE;
465472
466473 /* A name that can't be made absolute probably isn't absolute. */
467- if (mch_FullName (fname , szName , _MAX_PATH , FALSE) == FAIL )
474+ if (mch_FullName (fname , szName , sizeof ( szName ) - 1 , FALSE) == FAIL )
468475 return FALSE;
469476
470477 return pathcmp (fname , szName , -1 ) == 0 ;
@@ -498,10 +505,17 @@ slash_adjust(p)
498505 int
499506vim_stat (const char * name , struct stat * stp )
500507{
508+ #ifdef FEAT_MBYTE
509+ /* WinNT and later can use _MAX_PATH wide characters for a pathname, which
510+ * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is
511+ * UTF-8. */
512+ char buf [_MAX_PATH * 3 + 1 ];
513+ #else
501514 char buf [_MAX_PATH + 1 ];
515+ #endif
502516 char * p ;
503517
504- vim_strncpy ((char_u * )buf , (char_u * )name , _MAX_PATH );
518+ vim_strncpy ((char_u * )buf , (char_u * )name , sizeof ( buf ) - 1 );
505519 p = buf + strlen (buf );
506520 if (p > buf )
507521 mb_ptr_back (buf , p );
@@ -1761,9 +1775,13 @@ mch_resolve_shortcut(char_u *fname)
17611775 IPersistFile * ppf = NULL ;
17621776 OLECHAR wsz [MAX_PATH ];
17631777 WIN32_FIND_DATA ffd ; // we get those free of charge
1764- TCHAR buf [MAX_PATH ]; // could have simply reused 'wsz'...
1778+ CHAR buf [MAX_PATH ]; // could have simply reused 'wsz'...
17651779 char_u * rfname = NULL ;
17661780 int len ;
1781+ # ifdef FEAT_MBYTE
1782+ IShellLinkW * pslw = NULL ;
1783+ WIN32_FIND_DATAW ffdw ; // we get those free of charge
1784+ # endif
17671785
17681786 /* Check if the file name ends in ".lnk". Avoid calling
17691787 * CoCreateInstance(), it's quite slow. */
@@ -1775,44 +1793,92 @@ mch_resolve_shortcut(char_u *fname)
17751793
17761794 CoInitialize (NULL );
17771795
1796+ # ifdef FEAT_MBYTE
1797+ if (enc_codepage >= 0 && (int )GetACP () != enc_codepage )
1798+ {
1799+ // create a link manager object and request its interface
1800+ hr = CoCreateInstance (
1801+ & CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,
1802+ & IID_IShellLinkW , (void * * )& pslw );
1803+ if (hr == S_OK )
1804+ {
1805+ WCHAR * p = enc_to_utf16 (fname , NULL );
1806+
1807+ if (p != NULL )
1808+ {
1809+ // Get a pointer to the IPersistFile interface.
1810+ hr = pslw -> lpVtbl -> QueryInterface (
1811+ pslw , & IID_IPersistFile , (void * * )& ppf );
1812+ if (hr != S_OK )
1813+ goto shortcut_errorw ;
1814+
1815+ // "load" the name and resolve the link
1816+ hr = ppf -> lpVtbl -> Load (ppf , p , STGM_READ );
1817+ if (hr != S_OK )
1818+ goto shortcut_errorw ;
1819+ # if 0 // This makes Vim wait a long time if the target does not exist.
1820+ hr = pslw -> lpVtbl -> Resolve (pslw , NULL , SLR_NO_UI );
1821+ if (hr != S_OK )
1822+ goto shortcut_errorw ;
1823+ # endif
1824+
1825+ // Get the path to the link target.
1826+ ZeroMemory (wsz , MAX_PATH * sizeof (WCHAR ));
1827+ hr = pslw -> lpVtbl -> GetPath (pslw , wsz , MAX_PATH , & ffdw , 0 );
1828+ if (hr == S_OK && wsz [0 ] != NUL )
1829+ rfname = utf16_to_enc (wsz , NULL );
1830+
1831+ shortcut_errorw :
1832+ vim_free (p );
1833+ if (hr == S_OK )
1834+ goto shortcut_end ;
1835+ }
1836+ }
1837+ /* Retry with non-wide function (for Windows 98). */
1838+ }
1839+ # endif
17781840 // create a link manager object and request its interface
17791841 hr = CoCreateInstance (
17801842 & CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,
17811843 & IID_IShellLink , (void * * )& psl );
17821844 if (hr != S_OK )
1783- goto shortcut_error ;
1845+ goto shortcut_end ;
17841846
17851847 // Get a pointer to the IPersistFile interface.
17861848 hr = psl -> lpVtbl -> QueryInterface (
17871849 psl , & IID_IPersistFile , (void * * )& ppf );
17881850 if (hr != S_OK )
1789- goto shortcut_error ;
1851+ goto shortcut_end ;
17901852
17911853 // full path string must be in Unicode.
17921854 MultiByteToWideChar (CP_ACP , 0 , fname , -1 , wsz , MAX_PATH );
17931855
17941856 // "load" the name and resolve the link
17951857 hr = ppf -> lpVtbl -> Load (ppf , wsz , STGM_READ );
17961858 if (hr != S_OK )
1797- goto shortcut_error ;
1798- #if 0 // This makes Vim wait a long time if the target doesn't exist.
1859+ goto shortcut_end ;
1860+ # if 0 // This makes Vim wait a long time if the target doesn't exist.
17991861 hr = psl -> lpVtbl -> Resolve (psl , NULL , SLR_NO_UI );
18001862 if (hr != S_OK )
1801- goto shortcut_error ;
1802- #endif
1863+ goto shortcut_end ;
1864+ # endif
18031865
18041866 // Get the path to the link target.
18051867 ZeroMemory (buf , MAX_PATH );
18061868 hr = psl -> lpVtbl -> GetPath (psl , buf , MAX_PATH , & ffd , 0 );
18071869 if (hr == S_OK && buf [0 ] != NUL )
18081870 rfname = vim_strsave (buf );
18091871
1810- shortcut_error :
1872+ shortcut_end :
18111873 // Release all interface pointers (both belong to the same object)
18121874 if (ppf != NULL )
18131875 ppf -> lpVtbl -> Release (ppf );
18141876 if (psl != NULL )
18151877 psl -> lpVtbl -> Release (psl );
1878+ # ifdef FEAT_MBYTE
1879+ if (pslw != NULL )
1880+ pslw -> lpVtbl -> Release (pslw );
1881+ # endif
18161882
18171883 CoUninitialize ();
18181884 return rfname ;
0 commit comments