summaryrefslogtreecommitdiffstats
path: root/patches/source/vim/patches/7.4.012
blob: f831442ea56989b3b26780de00c4ad6faf5d850e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
To: vim_dev@googlegroups.com
Subject: Patch 7.4.012
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.4.012
Problem:    MS-Windows: resolving shortcut does not work properly with
	    multi-byte characters.
Solution:   Use wide system functions. (Ken Takata)
Files:	    src/os_mswin.c


*** ../vim-7.4.011/src/os_mswin.c	2013-06-16 16:41:11.000000000 +0200
--- src/os_mswin.c	2013-08-30 16:43:23.000000000 +0200
***************
*** 1761,1769 ****
      IPersistFile	*ppf = NULL;
      OLECHAR		wsz[MAX_PATH];
      WIN32_FIND_DATA	ffd; // we get those free of charge
!     TCHAR		buf[MAX_PATH]; // could have simply reused 'wsz'...
      char_u		*rfname = NULL;
      int			len;
  
      /* Check if the file name ends in ".lnk". Avoid calling
       * CoCreateInstance(), it's quite slow. */
--- 1761,1773 ----
      IPersistFile	*ppf = NULL;
      OLECHAR		wsz[MAX_PATH];
      WIN32_FIND_DATA	ffd; // we get those free of charge
!     CHAR		buf[MAX_PATH]; // could have simply reused 'wsz'...
      char_u		*rfname = NULL;
      int			len;
+ # ifdef FEAT_MBYTE
+     IShellLinkW		*pslw = NULL;
+     WIN32_FIND_DATAW	ffdw; // we get those free of charge
+ # endif
  
      /* Check if the file name ends in ".lnk". Avoid calling
       * CoCreateInstance(), it's quite slow. */
***************
*** 1775,1792 ****
  
      CoInitialize(NULL);
  
      // create a link manager object and request its interface
      hr = CoCreateInstance(
  	    &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  	    &IID_IShellLink, (void**)&psl);
      if (hr != S_OK)
! 	goto shortcut_error;
  
      // Get a pointer to the IPersistFile interface.
      hr = psl->lpVtbl->QueryInterface(
  	    psl, &IID_IPersistFile, (void**)&ppf);
      if (hr != S_OK)
! 	goto shortcut_error;
  
      // full path string must be in Unicode.
      MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH);
--- 1779,1840 ----
  
      CoInitialize(NULL);
  
+ # ifdef FEAT_MBYTE
+     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+     {
+ 	// create a link manager object and request its interface
+ 	hr = CoCreateInstance(
+ 		&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ 		&IID_IShellLinkW, (void**)&pslw);
+ 	if (hr == S_OK)
+ 	{
+ 	    WCHAR	*p = enc_to_utf16(fname, NULL);
+ 
+ 	    if (p != NULL)
+ 	    {
+ 		// Get a pointer to the IPersistFile interface.
+ 		hr = pslw->lpVtbl->QueryInterface(
+ 			pslw, &IID_IPersistFile, (void**)&ppf);
+ 		if (hr != S_OK)
+ 		    goto shortcut_errorw;
+ 
+ 		// "load" the name and resolve the link
+ 		hr = ppf->lpVtbl->Load(ppf, p, STGM_READ);
+ 		if (hr != S_OK)
+ 		    goto shortcut_errorw;
+ #  if 0  // This makes Vim wait a long time if the target does not exist.
+ 		hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
+ 		if (hr != S_OK)
+ 		    goto shortcut_errorw;
+ #  endif
+ 
+ 		// Get the path to the link target.
+ 		ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR));
+ 		hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0);
+ 		if (hr == S_OK && wsz[0] != NUL)
+ 		    rfname = utf16_to_enc(wsz, NULL);
+ 
+ shortcut_errorw:
+ 		vim_free(p);
+ 		if (hr == S_OK)
+ 		    goto shortcut_end;
+ 	    }
+ 	}
+ 	/* Retry with non-wide function (for Windows 98). */
+     }
+ # endif
      // create a link manager object and request its interface
      hr = CoCreateInstance(
  	    &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  	    &IID_IShellLink, (void**)&psl);
      if (hr != S_OK)
! 	goto shortcut_end;
  
      // Get a pointer to the IPersistFile interface.
      hr = psl->lpVtbl->QueryInterface(
  	    psl, &IID_IPersistFile, (void**)&ppf);
      if (hr != S_OK)
! 	goto shortcut_end;
  
      // full path string must be in Unicode.
      MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH);
***************
*** 1794,1805 ****
      // "load" the name and resolve the link
      hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
      if (hr != S_OK)
! 	goto shortcut_error;
! #if 0  // This makes Vim wait a long time if the target doesn't exist.
      hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI);
      if (hr != S_OK)
! 	goto shortcut_error;
! #endif
  
      // Get the path to the link target.
      ZeroMemory(buf, MAX_PATH);
--- 1842,1853 ----
      // "load" the name and resolve the link
      hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
      if (hr != S_OK)
! 	goto shortcut_end;
! # if 0  // This makes Vim wait a long time if the target doesn't exist.
      hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI);
      if (hr != S_OK)
! 	goto shortcut_end;
! # endif
  
      // Get the path to the link target.
      ZeroMemory(buf, MAX_PATH);
***************
*** 1807,1818 ****
      if (hr == S_OK && buf[0] != NUL)
  	rfname = vim_strsave(buf);
  
! shortcut_error:
      // Release all interface pointers (both belong to the same object)
      if (ppf != NULL)
  	ppf->lpVtbl->Release(ppf);
      if (psl != NULL)
  	psl->lpVtbl->Release(psl);
  
      CoUninitialize();
      return rfname;
--- 1855,1870 ----
      if (hr == S_OK && buf[0] != NUL)
  	rfname = vim_strsave(buf);
  
! shortcut_end:
      // Release all interface pointers (both belong to the same object)
      if (ppf != NULL)
  	ppf->lpVtbl->Release(ppf);
      if (psl != NULL)
  	psl->lpVtbl->Release(psl);
+ # ifdef FEAT_MBYTE
+     if (pslw != NULL)
+ 	pslw->lpVtbl->Release(pslw);
+ # endif
  
      CoUninitialize();
      return rfname;
*** ../vim-7.4.011/src/version.c	2013-08-30 16:35:41.000000000 +0200
--- src/version.c	2013-08-30 16:39:40.000000000 +0200
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     12,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
142. You dream about creating the world's greatest web site.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///