检测文件是在本地打开还是过度共享

Detect if file is open locally or over share

我正在尝试检查文件是否在 Win32 中打开:

bool CheckFileUnlocked(const TCHAR *file)
{
    HANDLE fh = ::CreateFile(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if(fh != NULL && fh != INVALID_HANDLE_VALUE) {
        return (CloseHandle(fh) == TRUE);
    }
    return false;
}

我需要能够区分文件是否在本地打开,在这种情况下,函数必须 return true 以防止它是从共享路径打开的。该文件本身可通过网络访问,并映射到共享驱动器中。上面的函数尝试以独占访问权限打开文件。我尝试添加 else 子句减少到:

bool CheckFileUnlocked(const TCHAR *file)
{
    HANDLE fh = ::CreateFile(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if(fh != NULL && fh != INVALID_HANDLE_VALUE) {
        return (CloseHandle(fh) == TRUE);
    } else {
        fh = ::CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
        if(fh != NULL && fh != INVALID_HANDLE_VALUE) {
            return (CloseHandle(fh) == TRUE);
        }
    }
    return false;
}

但我仍然无法确定该文件是在本地打开的还是在另一个系统上通过网络打开的。我也尝试了 LockFileEx()UnlockFileEx(),但我猜这些可能是错误的方法。我如何在不实际查询应用程序 (LibreOffice Writer) 的情况下解决这个问题,假设它提供对这种情况的 API 级别访问(LO 实际上在打开所述文档时提供弹出窗口并允许以只读方式打开它,或者打开副本)?

你可以试试GetFileInformationByHandleEx:

  • FileRemoteProtocolInfo 应该 return 网络访问属性,并且可能应该在本地文件上失败
  • FileStorageInfo应该return存储的属性,它可能会在网络上失败(但需要验证)