Ms. Molly Stewart-Gallus
Ms. Molly Stewart-Gallus

Reputation: 1168

On modern Windows NT systems only, can I determine at runtime whether a handle refers to a socket or an object handle?

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.

Upvotes: 2

Views: 387

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595412

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

Upvotes: 5

Related Questions