仅在现代 Windows NT 系统上,我可以在运行时确定句柄是引用套接字还是对象句柄吗?

Ste*_*lus 2 sockets windows winapi winsock

我完全清楚,过去 Windows 套接字仅作为第三方用户模式 ​​DLL 实现,并且套接字和对象句柄是不相关的。然而,在现代 Windows NT 系统上,套接字是完整的内核对象,尽管也有一些用户模式状态。

Rem*_*eau 5

不幸的是,没有针对该特定查询的单一 API。您必须直接访问 NT 对象管理器并在其已知句柄列表中找到所需的句柄,然后您可以检索句柄的对象类型(除其他外)。

NT 对象管理器内部

突破 Windows 的极限:句柄

HOWTO:枚举句柄

WinObj:终极对象管理器名称空间查看器

更新:我忘记了NtQueryObject()。您可以查询 aHANDLEObjectTypeInformation类,该类返回一个PUBLIC_OBJECT_TYPE_INFORMATION结构:

typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
    UNICODE_STRING TypeName;
    ULONG Reserved [22];    // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
Run Code Online (Sandbox Code Playgroud)

例如:

std::wstring GetHandleTypeName(HANDLE hHandle)
{
    typedef NTSTATUS (NTAPI *NtQueryObjectPtr)(
          HANDLE Handle,
          OBJECT_INFORMATION_CLASS ObjectInformationClass,
          PVOID ObjectInformation,
          ULONG ObjectInformationLength,
          PULONG ReturnLength);

    HMODULE hMod = LoadLibrary(_T("NtDll.dll"));
    NtQueryObjectPtr QueryObj = (NtQueryObjectPtr) ::GetProcAddress(hMod, "NtQueryObject");
    ASSERT(QueryObj);

    ULONG OutSize = 0;
    NTSTATUS NtStatus = QueryObj(hHandle, ObjectTypeInformation, NULL, 0, &OutSize);
    std::vector<BYTE> buffer(OutSize);
    PPUBLIC_OBJECT_TYPE_INFORMATION TypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION) &buffer[0];
    ULONG InSize = OutSize;
    NtStatus = QueryObj(hHandle, ObjectTypeInformation, TypeInfo, InSize, &OutSize);
    return std::wstring(TypeInfo->TypeName.Buffer, TypeInfo->TypeName.Length);
}
Run Code Online (Sandbox Code Playgroud)

std::wstring cs = GetHandleTypeName((HANDLE)TheDesiredSocket);
MessageBoxW(cs.c_str());
Run Code Online (Sandbox Code Playgroud)

NtQueryObject()有关使用套接字的更多信息,请参阅以下内容:

C++ 获取程序打开套接字的句柄

插座手柄

  • 如果我错了,请纠正我,但是套接字不是作为 *File* 句柄实现的吗?可以使用本机 API 查询句柄类型,特别是 [NtQueryObject](https://msdn.microsoft.com/en-us/library/windows/hardware/ff556684.aspx)(请参阅 [ZwQueryObject](https:// msdn.microsoft.com/en-us/library/windows/hardware/ff567062.aspx)了解文档)。将“ObjectTypeInformation”作为 [OBJECT_INFORMATION_CLASS](https://msdn.microsoft.com/en-us/library/windows/hardware/ff550964.aspx) 传递将为您提供对象类型名称。 (2认同)