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