forked from aniani/vim
patch 8.1.1784: MS-Windows: resolve() does not work if serial nr duplicated
Problem: MS-Windows: resolve() does not work if serial nr duplicated. Solution: Use another method to get the full path. (Ken Takata, closes #4661)
This commit is contained in:
parent
dff2adc8dd
commit
3f9bdeb2a5
138
src/os_mswin.c
138
src/os_mswin.c
@ -1703,55 +1703,12 @@ mch_print_set_fg(long_u fgcol)
|
|||||||
# include <shlobj.h>
|
# include <shlobj.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
typedef enum _FILE_INFO_BY_HANDLE_CLASS_ {
|
typedef BOOL (WINAPI *pfnGetFinalPathNameByHandleW)(
|
||||||
FileBasicInfo_,
|
|
||||||
FileStandardInfo_,
|
|
||||||
FileNameInfo_,
|
|
||||||
FileRenameInfo_,
|
|
||||||
FileDispositionInfo_,
|
|
||||||
FileAllocationInfo_,
|
|
||||||
FileEndOfFileInfo_,
|
|
||||||
FileStreamInfo_,
|
|
||||||
FileCompressionInfo_,
|
|
||||||
FileAttributeTagInfo_,
|
|
||||||
FileIdBothDirectoryInfo_,
|
|
||||||
FileIdBothDirectoryRestartInfo_,
|
|
||||||
FileIoPriorityHintInfo_,
|
|
||||||
FileRemoteProtocolInfo_,
|
|
||||||
FileFullDirectoryInfo_,
|
|
||||||
FileFullDirectoryRestartInfo_,
|
|
||||||
FileStorageInfo_,
|
|
||||||
FileAlignmentInfo_,
|
|
||||||
FileIdInfo_,
|
|
||||||
FileIdExtdDirectoryInfo_,
|
|
||||||
FileIdExtdDirectoryRestartInfo_,
|
|
||||||
FileDispositionInfoEx_,
|
|
||||||
FileRenameInfoEx_,
|
|
||||||
MaximumFileInfoByHandleClass_
|
|
||||||
} FILE_INFO_BY_HANDLE_CLASS_;
|
|
||||||
|
|
||||||
typedef struct _FILE_NAME_INFO_ {
|
|
||||||
DWORD FileNameLength;
|
|
||||||
WCHAR FileName[1];
|
|
||||||
} FILE_NAME_INFO_;
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
|
|
||||||
HANDLE hFile,
|
|
||||||
FILE_INFO_BY_HANDLE_CLASS_ FileInformationClass,
|
|
||||||
LPVOID lpFileInformation,
|
|
||||||
DWORD dwBufferSize);
|
|
||||||
static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *pfnGetVolumeInformationByHandleW)(
|
|
||||||
HANDLE hFile,
|
HANDLE hFile,
|
||||||
LPWSTR lpVolumeNameBuffer,
|
LPWSTR lpszFilePath,
|
||||||
DWORD nVolumeNameSize,
|
DWORD cchFilePath,
|
||||||
LPDWORD lpVolumeSerialNumber,
|
DWORD dwFlags);
|
||||||
LPDWORD lpMaximumComponentLength,
|
static pfnGetFinalPathNameByHandleW pGetFinalPathNameByHandleW = NULL;
|
||||||
LPDWORD lpFileSystemFlags,
|
|
||||||
LPWSTR lpFileSystemNameBuffer,
|
|
||||||
DWORD nFileSystemNameSize);
|
|
||||||
static pfnGetVolumeInformationByHandleW pGetVolumeInformationByHandleW = NULL;
|
|
||||||
|
|
||||||
# define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
|
# define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
|
||||||
|
|
||||||
@ -1791,28 +1748,21 @@ resolve_reparse_point(char_u *fname)
|
|||||||
{
|
{
|
||||||
HANDLE h = INVALID_HANDLE_VALUE;
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
WCHAR *p;
|
WCHAR *p, *wp;
|
||||||
char_u *rfname = NULL;
|
char_u *rfname = NULL;
|
||||||
FILE_NAME_INFO_ *nameinfo = NULL;
|
WCHAR *buff = NULL;
|
||||||
WCHAR buff[MAX_PATH], *volnames = NULL;
|
|
||||||
HANDLE hv;
|
|
||||||
DWORD snfile, snfind;
|
|
||||||
static BOOL loaded = FALSE;
|
static BOOL loaded = FALSE;
|
||||||
|
|
||||||
if (pGetFileInformationByHandleEx == NULL ||
|
if (pGetFinalPathNameByHandleW == NULL)
|
||||||
pGetVolumeInformationByHandleW == NULL)
|
|
||||||
{
|
{
|
||||||
HMODULE hmod = GetModuleHandle("kernel32.dll");
|
HMODULE hmod = GetModuleHandle("kernel32.dll");
|
||||||
|
|
||||||
if (loaded == TRUE)
|
if (loaded == TRUE)
|
||||||
return NULL;
|
return NULL;
|
||||||
pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx)
|
pGetFinalPathNameByHandleW = (pfnGetFinalPathNameByHandleW)
|
||||||
GetProcAddress(hmod, "GetFileInformationByHandleEx");
|
GetProcAddress(hmod, "GetFinalPathNameByHandleW");
|
||||||
pGetVolumeInformationByHandleW = (pfnGetVolumeInformationByHandleW)
|
|
||||||
GetProcAddress(hmod, "GetVolumeInformationByHandleW");
|
|
||||||
loaded = TRUE;
|
loaded = TRUE;
|
||||||
if (pGetFileInformationByHandleEx == NULL ||
|
if (pGetFinalPathNameByHandleW == NULL)
|
||||||
pGetVolumeInformationByHandleW == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1833,60 +1783,32 @@ resolve_reparse_point(char_u *fname)
|
|||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1);
|
size = pGetFinalPathNameByHandleW(h, NULL, 0, 0);
|
||||||
nameinfo = alloc(size + sizeof(WCHAR));
|
if (size == 0)
|
||||||
if (nameinfo == NULL)
|
goto fail;
|
||||||
|
buff = ALLOC_MULT(WCHAR, size);
|
||||||
|
if (buff == NULL)
|
||||||
|
goto fail;
|
||||||
|
if (pGetFinalPathNameByHandleW(h, buff, size, 0) == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!pGetFileInformationByHandleEx(h, FileNameInfo_, nameinfo, size))
|
if (wcsncmp(buff, L"\\\\?\\UNC\\", 8) == 0)
|
||||||
goto fail;
|
{
|
||||||
|
buff[6] = L'\\';
|
||||||
nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = 0;
|
wp = buff + 6;
|
||||||
|
}
|
||||||
if (!pGetVolumeInformationByHandleW(
|
else if (wcsncmp(buff, L"\\\\?\\", 4) == 0)
|
||||||
h, NULL, 0, &snfile, NULL, NULL, NULL, 0))
|
wp = buff + 4;
|
||||||
goto fail;
|
|
||||||
|
|
||||||
hv = FindFirstVolumeW(buff, MAX_PATH);
|
|
||||||
if (hv == INVALID_HANDLE_VALUE)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
do {
|
|
||||||
GetVolumeInformationW(
|
|
||||||
buff, NULL, 0, &snfind, NULL, NULL, NULL, 0);
|
|
||||||
if (snfind == snfile)
|
|
||||||
break;
|
|
||||||
} while (FindNextVolumeW(hv, buff, MAX_PATH));
|
|
||||||
|
|
||||||
FindVolumeClose(hv);
|
|
||||||
|
|
||||||
if (snfind != snfile)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
size = 0;
|
|
||||||
if (!GetVolumePathNamesForVolumeNameW(buff, NULL, 0, &size) &&
|
|
||||||
GetLastError() != ERROR_MORE_DATA)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
volnames = ALLOC_MULT(WCHAR, size);
|
|
||||||
if (!GetVolumePathNamesForVolumeNameW(buff, volnames, size,
|
|
||||||
&size))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
wcscpy(buff, volnames);
|
|
||||||
if (nameinfo->FileName[0] == '\\')
|
|
||||||
wcscat(buff, nameinfo->FileName + 1);
|
|
||||||
else
|
else
|
||||||
wcscat(buff, nameinfo->FileName);
|
wp = buff;
|
||||||
rfname = utf16_to_enc(buff, NULL);
|
|
||||||
|
rfname = utf16_to_enc(wp, NULL);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (h != INVALID_HANDLE_VALUE)
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
if (nameinfo != NULL)
|
if (buff != NULL)
|
||||||
vim_free(nameinfo);
|
vim_free(buff);
|
||||||
if (volnames != NULL)
|
|
||||||
vim_free(volnames);
|
|
||||||
|
|
||||||
return rfname;
|
return rfname;
|
||||||
}
|
}
|
||||||
|
@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1784,
|
||||||
/**/
|
/**/
|
||||||
1783,
|
1783,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user