Mercurial > vim
comparison src/os_mswin.c @ 5318:8e28c23e482c v7.4.012
updated for version 7.4.012
Problem: MS-Windows: resolving shortcut does not work properly with
multi-byte characters.
Solution: Use wide system functions. (Ken Takata)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Fri, 30 Aug 2013 16:44:19 +0200 |
parents | 1cf02fbe6281 |
children | 07737d3aa817 |
comparison
equal
deleted
inserted
replaced
5317:076f115ed30d | 5318:8e28c23e482c |
---|---|
1759 HRESULT hr; | 1759 HRESULT hr; |
1760 IShellLink *psl = NULL; | 1760 IShellLink *psl = NULL; |
1761 IPersistFile *ppf = NULL; | 1761 IPersistFile *ppf = NULL; |
1762 OLECHAR wsz[MAX_PATH]; | 1762 OLECHAR wsz[MAX_PATH]; |
1763 WIN32_FIND_DATA ffd; // we get those free of charge | 1763 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'... |
1765 char_u *rfname = NULL; | 1765 char_u *rfname = NULL; |
1766 int len; | 1766 int len; |
1767 # ifdef FEAT_MBYTE | |
1768 IShellLinkW *pslw = NULL; | |
1769 WIN32_FIND_DATAW ffdw; // we get those free of charge | |
1770 # endif | |
1767 | 1771 |
1768 /* Check if the file name ends in ".lnk". Avoid calling | 1772 /* Check if the file name ends in ".lnk". Avoid calling |
1769 * CoCreateInstance(), it's quite slow. */ | 1773 * CoCreateInstance(), it's quite slow. */ |
1770 if (fname == NULL) | 1774 if (fname == NULL) |
1771 return rfname; | 1775 return rfname; |
1773 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) | 1777 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) |
1774 return rfname; | 1778 return rfname; |
1775 | 1779 |
1776 CoInitialize(NULL); | 1780 CoInitialize(NULL); |
1777 | 1781 |
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 | |
1778 // create a link manager object and request its interface | 1826 // create a link manager object and request its interface |
1779 hr = CoCreateInstance( | 1827 hr = CoCreateInstance( |
1780 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, | 1828 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, |
1781 &IID_IShellLink, (void**)&psl); | 1829 &IID_IShellLink, (void**)&psl); |
1782 if (hr != S_OK) | 1830 if (hr != S_OK) |
1783 goto shortcut_error; | 1831 goto shortcut_end; |
1784 | 1832 |
1785 // Get a pointer to the IPersistFile interface. | 1833 // Get a pointer to the IPersistFile interface. |
1786 hr = psl->lpVtbl->QueryInterface( | 1834 hr = psl->lpVtbl->QueryInterface( |
1787 psl, &IID_IPersistFile, (void**)&ppf); | 1835 psl, &IID_IPersistFile, (void**)&ppf); |
1788 if (hr != S_OK) | 1836 if (hr != S_OK) |
1789 goto shortcut_error; | 1837 goto shortcut_end; |
1790 | 1838 |
1791 // full path string must be in Unicode. | 1839 // full path string must be in Unicode. |
1792 MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH); | 1840 MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH); |
1793 | 1841 |
1794 // "load" the name and resolve the link | 1842 // "load" the name and resolve the link |
1795 hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); | 1843 hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); |
1796 if (hr != S_OK) | 1844 if (hr != S_OK) |
1797 goto shortcut_error; | 1845 goto shortcut_end; |
1798 #if 0 // This makes Vim wait a long time if the target doesn't exist. | 1846 # if 0 // This makes Vim wait a long time if the target doesn't exist. |
1799 hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); | 1847 hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); |
1800 if (hr != S_OK) | 1848 if (hr != S_OK) |
1801 goto shortcut_error; | 1849 goto shortcut_end; |
1802 #endif | 1850 # endif |
1803 | 1851 |
1804 // Get the path to the link target. | 1852 // Get the path to the link target. |
1805 ZeroMemory(buf, MAX_PATH); | 1853 ZeroMemory(buf, MAX_PATH); |
1806 hr = psl->lpVtbl->GetPath(psl, buf, MAX_PATH, &ffd, 0); | 1854 hr = psl->lpVtbl->GetPath(psl, buf, MAX_PATH, &ffd, 0); |
1807 if (hr == S_OK && buf[0] != NUL) | 1855 if (hr == S_OK && buf[0] != NUL) |
1808 rfname = vim_strsave(buf); | 1856 rfname = vim_strsave(buf); |
1809 | 1857 |
1810 shortcut_error: | 1858 shortcut_end: |
1811 // Release all interface pointers (both belong to the same object) | 1859 // Release all interface pointers (both belong to the same object) |
1812 if (ppf != NULL) | 1860 if (ppf != NULL) |
1813 ppf->lpVtbl->Release(ppf); | 1861 ppf->lpVtbl->Release(ppf); |
1814 if (psl != NULL) | 1862 if (psl != NULL) |
1815 psl->lpVtbl->Release(psl); | 1863 psl->lpVtbl->Release(psl); |
1864 # ifdef FEAT_MBYTE | |
1865 if (pslw != NULL) | |
1866 pslw->lpVtbl->Release(pslw); | |
1867 # endif | |
1816 | 1868 |
1817 CoUninitialize(); | 1869 CoUninitialize(); |
1818 return rfname; | 1870 return rfname; |
1819 } | 1871 } |
1820 #endif | 1872 #endif |