2

I am fully aware that in the past Windows sockets used to be implemented as third party user mode DLLs only and that sockets and object handles were unrelated. However, on modern Windows NT systems sockets are full kernel objects although there is some user mode state as well.

1 Answers1

5

Unfortunately, there is no single API for that particular query. You have to access the NT Object Manager directly and locate the desired handle within its list of known handles, then you can retrieve the handle's object type (amongst other things).

Inside NT's Object Manager

Pushing the Limits of Windows: Handles

HOWTO: Enumerate handles

WinObj: The ultimate Object Manager namespace viewer

Update: I forgot about NtQueryObject(). You can query a HANDLE for its ObjectTypeInformation class, which returns a PUBLIC_OBJECT_TYPE_INFORMATION struct:

typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
    UNICODE_STRING TypeName;
    ULONG Reserved [22];    // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;

For example:

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);
}

std::wstring cs = GetHandleTypeName((HANDLE)TheDesiredSocket);
MessageBoxW(cs.c_str());

See these for some more information about using NtQueryObject() with Sockets:

C++ Get Handle of Open Sockets of a Program

socket handles

Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • That sounds like it'd be slow as well which would also be bad. – Molly Stewart-Gallus Feb 16 '15 at 19:45
  • 2
    Correct me if I'm wrong, but aren't sockets implemented as *File* handles? The handle type can be queried using the native API, specifically [NtQueryObject](https://msdn.microsoft.com/en-us/library/windows/hardware/ff556684.aspx) (see [ZwQueryObject](https://msdn.microsoft.com/en-us/library/windows/hardware/ff567062.aspx) for documentation). Passing `ObjectTypeInformation` as the [OBJECT_INFORMATION_CLASS](https://msdn.microsoft.com/en-us/library/windows/hardware/ff550964.aspx) will get you the object type name. – IInspectable Feb 16 '15 at 20:32
  • @IInspectable: beat me to it.. I was in the process of adding that info to my answer when you posted your comment. – Remy Lebeau Feb 16 '15 at 20:39
  • [This function may be changed or removed from Windows without further notice.] That's a pity. – Molly Stewart-Gallus Feb 16 '15 at 20:55
  • @StevenStewart-Gallus: on the other hand, Microsoft rarely actually does that for most APIs. Granted, the Nt/Zw functions are internal functions, and more susceptible to change since most apps should not be calling them directly. But devs who do use them need to be aware of their volatility since they are internal functions. – Remy Lebeau Feb 16 '15 at 20:58
  • I don't believe that you are allowed to use these functions for applications certified for Windows Phone though right? – Molly Stewart-Gallus Feb 16 '15 at 21:09
  • @StevenStewart-Gallus: I would not know, as I do not do any Windows Phone development. But I suspect not. – Remy Lebeau Feb 16 '15 at 22:00