【问题标题】:How to determine that two Win32 API handles represent the same object?如何确定两个 Win32 API 句柄代表同一个对象?
【发布时间】:2015-04-03 17:12:41
【问题描述】:

假设我有两个句柄:

HANDLE h1;
HANDLE h2;

两者都收到了来自某些 Windows API 函数的值 - 特别是,我对调用 CreateFile() 产生的句柄很感兴趣。如何确定 h1 和 h2 引用相同的底层对象 - 在 CreateFile() 的情况下 - 相同的文件、目录或设备?是否有一些 API 可以确定这一点?

【问题讨论】:

    标签: c++ winapi handle


    【解决方案1】:

    GetFileInformationByHandle API 返回可用于唯一标识被引用对象的信息:

    您可以比较BY_HANDLE_FILE_INFORMATION 结构中返回的 VolumeSerialNumber 和 FileIndex 成员,以确定两个路径是否映射到同一个目标;例如,您可以比较两个文件路径并确定它们是否映射到同一目录。

    例如:

    bool SameFile( HANDLE h1, HANDLE h2 ) {
        BY_HANDLE_FILE_INFORMATION bhfi1 = { 0 };
        BY_HANDLE_FILE_INFORMATION bhfi2 = { 0 };
        if ( ::GetFileInformationByHandle( h1, &bhfi1 ) &&
             ::GetFileInformationByHandle( h2, &bhfi2 ) ) {
            return ( ( bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh ) &&
                     ( bhfi1.nFileIndexLow  == bhfi2.nFileIndexLow ) &&
                     ( bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber ) );
        }
        return false;
    }
    

    【讨论】:

    • 这是否适用于问题中提到的设备句柄?
    • 设备句柄 - 不存在。当您尝试打开设备时,始终会创建 FILE_OBJECT 并且您可以处理它。更快需要询问 - 这是否适用于文件系统设备 - 不工作。甚至不是所有文件系统的序列号 - ntfs 的主要序列号
    • 网络共享和网络驱动器怎么样?假设我将 \\server\share 挂载为驱动器 X:,我从打开文件中获得一个文件句柄为 \\server\share\somefile.txt,从打开 X:\somefile.txt 获得另一个文件句柄。事实上,我在这两种情况下都打开了同一个文件。如果我指定标志 FILE_NAME_NORMALIZED,文件路径的方法在这种情况下是否有效?通过句柄信息有效吗?我想让情况更加复杂。假设 \\server\share 由运行 Samba 的 Linux 主机提供。什么适用于这种情况?
    【解决方案2】:

    Windows 10 的新功能:

    CompareObjectHandles - 比较两个对象句柄以确定它们是否引用相同的底层内核对象。

    https://msdn.microsoft.com/en-us/library/windows/desktop/mt438733(v=vs.85).aspx

    【讨论】:

      【解决方案3】:

      您可以使用 GetFinalPathNameByHandle 并比较两个句柄的文件路径。 https://msdn.microsoft.com/en-us/library/windows/desktop/aa364962(v=vs.85).aspx

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-19
      • 2013-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      相关资源
      最近更新 更多