NtUserHwndSetRedirectionInfo and NtUserHwndQueryRedirectionInfo

Spent a little time figuring these out based on some code I ran into for capturing screen data using DWM surface handles (Specifically, DwmGetDxSharedSurface)

For those that don't know, most user32 system calls on windows insider (and maybe soon, if not already, upcoming/existing Windows 10 patches) are actually defined in "win32u.dll" which exports a lot of Win32k related syscalls.

Since this is going to be a thing I decided knowing more about some of the calls wouldn't hurt, so here we go.

#pragma pack(push, 1)
typedef struct _REDIRECTION_SHARED_SURFACE  
{
    DWORD FmtWindow;
    int PresentFlags;                   // optional IN parameter
    unsigned __int64 UpdateId;
    LUID AdapterLuid;                   // optional IN parameter
    HANDLE SurfaceHandle;
} REDIRECTION_SHARED_SURFACE, *PREDIRECTION_SHARED_SURFACE;
static_assert(sizeof(_REDIRECTION_SHARED_SURFACE) == 32, "Invalid REDIRECTION_SHARED_SURFACE size.");

typedef struct _REDIRECTION_SURFACE_UPDATE_ID  
{
    ULONGLONG a1;
    ULONGLONG a2;
} REDIRECTION_SURFACE_UPDATE_ID, *PREDIRECTION_SURFACE_UPDATE_ID;
static_assert(sizeof(REDIRECTION_SURFACE_UPDATE_ID) == 16, "Invalid REDIRECTION_SURFACE_UPDATE_ID size.");  
#pragma pack(pop)

typedef enum _REDIRECTIONINFOCLASS  
{
    RedirectionSharedSurface = 0,       // REDIRECTION_SHARED_SURFACE
    RedirectionSurfaceUpdateId = 1,     // REDIRECTION_SURFACE_UPDATE_ID
    RedirectionPresentFlags = 2,        // int
    RedirectionRgnHandle = 3,           // HRGN
    RedirectionHintDxUpdate = 4         // __m128i (2 x 64-bit QWORD)
} REDIRECTIONINFOCLASS;

// __int64 __fastcall NtUserHwndSetRedirectionInfo(__int64 a1, int a2, _DWORD *a3, unsigned int a4)
typedef BOOL(WINAPI *NtUserHwndSetRedirectionInfo_t)(  
    HWND hWnd,
    REDIRECTIONINFOCLASS RedirectionInformationClass,
    PVOID RedirectionInformation,
    SIZE_T size
    );

// __int64 __fastcall NtUserHwndQueryRedirectionInfo(__int64 a1, signed int a2, __int128 *a3, unsigned __int64 a4)
typedef BOOL(WINAPI *NtUserHwndQueryRedirectionInfo_t)(  
    HWND hWnd,
    REDIRECTIONINFOCLASS RedirectionInformationClass,
    PVOID RedirectionInformation,
    SIZE_T *Size
    );

These APIs work similarly to ntdll *INFOCLASS syscalls except the APIs return a BOOL instead of NTSTATUS. The error code (non-nt) is set in the functions, however, so GetLastError should work on failure.

These are only tested on Windows 10 x64, and some of the definitions might be different from their x86 counterparts.

Whats interesting about RedirectionPresentFlags is it sounds like you might be able to set some adapter flags for any given process, although trying to set DXGI_PRESENT_RESTRICT_TO_OUTPUT didn't seem to work on notepad.exe

Oh well

Andrew Artz

Read more posts by this author.