@@ -1761,9 +1761,13 @@ mch_resolve_shortcut(char_u *fname)
17611761 IPersistFile * ppf = NULL ;
17621762 OLECHAR wsz [MAX_PATH ];
17631763 WIN32_FIND_DATA ffd ; // we get those free of charge
1764- TCHAR buf [MAX_PATH ]; // could have simply reused 'wsz'...
1764+ CHAR buf [MAX_PATH ]; // could have simply reused 'wsz'...
17651765 char_u * rfname = NULL ;
17661766 int len ;
1767+ # ifdef FEAT_MBYTE
1768+ IShellLinkW * pslw = NULL ;
1769+ WIN32_FIND_DATAW ffdw ; // we get those free of charge
1770+ # endif
17671771
17681772 /* Check if the file name ends in ".lnk". Avoid calling
17691773 * CoCreateInstance(), it's quite slow. */
@@ -1775,44 +1779,92 @@ mch_resolve_shortcut(char_u *fname)
17751779
17761780 CoInitialize (NULL );
17771781
1782+ # ifdef FEAT_MBYTE
1783+ if (enc_codepage >= 0 && (int )GetACP () != enc_codepage )
1784+ {
1785+ // create a link manager object and request its interface
1786+ hr = CoCreateInstance (
1787+ & CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,
1788+ & IID_IShellLinkW , (void * * )& pslw );
1789+ if (hr == S_OK )
1790+ {
1791+ WCHAR * p = enc_to_utf16 (fname , NULL );
1792+
1793+ if (p != NULL )
1794+ {
1795+ // Get a pointer to the IPersistFile interface.
1796+ hr = pslw -> lpVtbl -> QueryInterface (
1797+ pslw , & IID_IPersistFile , (void * * )& ppf );
1798+ if (hr != S_OK )
1799+ goto shortcut_errorw ;
1800+
1801+ // "load" the name and resolve the link
1802+ hr = ppf -> lpVtbl -> Load (ppf , p , STGM_READ );
1803+ if (hr != S_OK )
1804+ goto shortcut_errorw ;
1805+ # if 0 // This makes Vim wait a long time if the target does not exist.
1806+ hr = pslw -> lpVtbl -> Resolve (pslw , NULL , SLR_NO_UI );
1807+ if (hr != S_OK )
1808+ goto shortcut_errorw ;
1809+ # endif
1810+
1811+ // Get the path to the link target.
1812+ ZeroMemory (wsz , MAX_PATH * sizeof (WCHAR ));
1813+ hr = pslw -> lpVtbl -> GetPath (pslw , wsz , MAX_PATH , & ffdw , 0 );
1814+ if (hr == S_OK && wsz [0 ] != NUL )
1815+ rfname = utf16_to_enc (wsz , NULL );
1816+
1817+ shortcut_errorw :
1818+ vim_free (p );
1819+ if (hr == S_OK )
1820+ goto shortcut_end ;
1821+ }
1822+ }
1823+ /* Retry with non-wide function (for Windows 98). */
1824+ }
1825+ # endif
17781826 // create a link manager object and request its interface
17791827 hr = CoCreateInstance (
17801828 & CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,
17811829 & IID_IShellLink , (void * * )& psl );
17821830 if (hr != S_OK )
1783- goto shortcut_error ;
1831+ goto shortcut_end ;
17841832
17851833 // Get a pointer to the IPersistFile interface.
17861834 hr = psl -> lpVtbl -> QueryInterface (
17871835 psl , & IID_IPersistFile , (void * * )& ppf );
17881836 if (hr != S_OK )
1789- goto shortcut_error ;
1837+ goto shortcut_end ;
17901838
17911839 // full path string must be in Unicode.
17921840 MultiByteToWideChar (CP_ACP , 0 , fname , -1 , wsz , MAX_PATH );
17931841
17941842 // "load" the name and resolve the link
17951843 hr = ppf -> lpVtbl -> Load (ppf , wsz , STGM_READ );
17961844 if (hr != S_OK )
1797- goto shortcut_error ;
1798- #if 0 // This makes Vim wait a long time if the target doesn't exist.
1845+ goto shortcut_end ;
1846+ # if 0 // This makes Vim wait a long time if the target doesn't exist.
17991847 hr = psl -> lpVtbl -> Resolve (psl , NULL , SLR_NO_UI );
18001848 if (hr != S_OK )
1801- goto shortcut_error ;
1802- #endif
1849+ goto shortcut_end ;
1850+ # endif
18031851
18041852 // Get the path to the link target.
18051853 ZeroMemory (buf , MAX_PATH );
18061854 hr = psl -> lpVtbl -> GetPath (psl , buf , MAX_PATH , & ffd , 0 );
18071855 if (hr == S_OK && buf [0 ] != NUL )
18081856 rfname = vim_strsave (buf );
18091857
1810- shortcut_error :
1858+ shortcut_end :
18111859 // Release all interface pointers (both belong to the same object)
18121860 if (ppf != NULL )
18131861 ppf -> lpVtbl -> Release (ppf );
18141862 if (psl != NULL )
18151863 psl -> lpVtbl -> Release (psl );
1864+ # ifdef FEAT_MBYTE
1865+ if (pslw != NULL )
1866+ pslw -> lpVtbl -> Release (pslw );
1867+ # endif
18161868
18171869 CoUninitialize ();
18181870 return rfname ;
0 commit comments