Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在现代Windows NT系统上,我能否在运行时确定句柄是指套接字还是对象句柄?_Windows_Sockets_Winapi_Winsock - Fatal编程技术网

仅在现代Windows NT系统上,我能否在运行时确定句柄是指套接字还是对象句柄?

仅在现代Windows NT系统上,我能否在运行时确定句柄是指套接字还是对象句柄?,windows,sockets,winapi,winsock,Windows,Sockets,Winapi,Winsock,我完全知道,在过去,Windows套接字只作为第三方用户模式DLL实现,套接字和对象句柄是不相关的。然而,在现代Windows NT系统上,套接字是完整的内核对象,尽管也有一些用户模式状态。不幸的是,对于特定的查询没有单一的API。您必须直接访问NT对象管理器,并在其已知句柄列表中找到所需的句柄,然后才能检索句柄的对象类型 更新:我忘了。您可以查询其ObjectTypeInformation类的句柄,该类返回公共\u对象\u类型\u信息结构: 例如: std::wstring GetHandle

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

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

更新:我忘了。您可以查询其ObjectTypeInformation类的句柄,该类返回公共\u对象\u类型\u信息结构:

例如:

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);
}
有关将NtQueryObject与套接字一起使用的更多信息,请参见以下内容:


不幸的是,对于这个特定的查询没有单一的API。您必须直接访问NT对象管理器,并在其已知句柄列表中找到所需的句柄,然后才能检索句柄的对象类型

更新:我忘了。您可以查询其ObjectTypeInformation类的句柄,该类返回公共\u对象\u类型\u信息结构:

例如:

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);
}
有关将NtQueryObject与套接字一起使用的更多信息,请参见以下内容:


这听起来也很慢,这也很糟糕。如果我错了,请纠正我,但是套接字不是作为文件句柄实现的吗?可以使用本机API查询句柄类型,具体请参见文档。将ObjectTypeInformation作为传递将获得对象类型名称。@IInspectable:请告诉我。。您发表评论时,我正在将这些信息添加到我的答案中。[此功能可能会在不另行通知的情况下从Windows中更改或删除。]这真是太遗憾了。@StevenStewart Gallus:另一方面,对于大多数API,Microsoft实际上很少这样做。当然,Nt/Zw函数是内部函数,更容易更改,因为大多数应用程序不应该直接调用它们。但是使用它们的开发人员需要注意它们的波动性,因为它们是内部函数。这听起来也很慢,这也很糟糕。如果我错了,请纠正我,但是套接字不是作为文件句柄实现的吗?可以使用本机API查询句柄类型,具体请参见文档。将ObjectTypeInformation作为传递将获得对象类型名称。@IInspectable:请告诉我。。您发表评论时,我正在将这些信息添加到我的答案中。[此功能可能会在不另行通知的情况下从Windows中更改或删除。]这真是太遗憾了。@StevenStewart Gallus:另一方面,对于大多数API,Microsoft实际上很少这样做。当然,Nt/Zw函数是内部函数,更容易更改,因为大多数应用程序不应该直接调用它们。但是使用它们的开发人员需要知道它们的波动性,因为它们是内部函数。你是如何找到一个你不知道其出处的句柄的?你是如何找到一个你不知道其出处的句柄的?
std::wstring cs = GetHandleTypeName((HANDLE)TheDesiredSocket);
MessageBoxW(cs.c_str());