Browse Source

Improve the check for whether global and local config_dir are the same

Extend the string comparison of the two paths to include comparing their
file information structure.  (See Remarks under the MSDN docs for
GetFileInformationByHandle)

If the strings are identical we treat them as identical without checking
further whether the paths are valid. This matches the current
behaviour. Otherwise, the two paths are treated as identical if both
exist, are accessible and point to the same object in the file system.

Trac: #1359, #1376

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/406/head
Selva Nair 4 years ago committed by Gert Doering
parent
commit
941c33f149
  1. 61
      openvpn_config.c

61
openvpn_config.c

@ -337,6 +337,65 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags)
FindClose(find_handle);
}
/*
* Open a path and get its file information structure.
* Returns true on success, false on error.
*/
static bool
GetFileInfo(const wchar_t *path, BY_HANDLE_FILE_INFORMATION *info)
{
bool ret = false;
/* FILE_FLAG_BACKUP_SEMANTICS required to open directories */
HANDLE fd = CreateFileW(path, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (fd == INVALID_HANDLE_VALUE)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"GetFileInfo: Error opening path <%ls> (status = %lu)", path, GetLastError());
return ret;
}
ret = GetFileInformationByHandle(fd, info);
if (!ret)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"GetFileInfo: Error accessing file information for path <%ls> (status = %lu)", path, GetLastError());
}
else
{
PrintDebug(L"path = <%ls> volumeid = %lu file index = (%lu,%lu)", path, info->dwVolumeSerialNumber, info->nFileIndexLow, info->nFileIndexHigh);
}
CloseHandle(fd);
return ret;
}
/*
* Compare two paths by checking whether they point to the
* same object in the file system. Returns true if the paths
* are same, false otherwise.
* If the two paths are identical strings return true early.
* If any of the paths do not exist, are not accessible or
* fail to provide file information, we return false.
*/
static bool
IsSamePath(const wchar_t *path1, const wchar_t *path2)
{
BOOL ret = false;
BY_HANDLE_FILE_INFORMATION info1, info2;
if (_wcsicmp(path1, path2) == 0) return true;
if (GetFileInfo(path1, &info1) && GetFileInfo(path2, &info2))
{
ret = (info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
&& info1.nFileIndexLow == info2.nFileIndexLow
&& info1.nFileIndexHigh == info2.nFileIndexHigh);
}
return ret;
}
void
BuildFileList()
{
@ -372,7 +431,7 @@ BuildFileList()
root = NewConfigGroup(L"System Profiles", root, flags);
if (_tcscmp (o.global_config_dir, o.config_dir))
if (!IsSamePath(o.global_config_dir, o.config_dir))
BuildFileList0 (o.global_config_dir, recurse_depth, root, flags);
if (o.num_configs == 0 && issue_warnings)

Loading…
Cancel
Save