diff --git a/openvpn_config.c b/openvpn_config.c index c814797..347377a 100644 --- a/openvpn_config.c +++ b/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)