Для сильно улфбчивых
процитирую общеизвестные сорсы:
BOOL NtUserSetThreadDesktop(
IN HDESK hdesk)
{
PDESKTOP pdesk = NULL;
NTSTATUS Status = STATUS_SUCCESS;
BEGINRECV(BOOL, FALSE);
Status = ValidateHdesk(hdesk, UserMode, 0, &pdesk);
if (NT_SUCCESS(Status)) {
retval = xxxSetThreadDesktop(hdesk, pdesk);
LogDesktop(pdesk, LD_DEREF_VALIDATE_HDESK1, FALSE, (ULONG_PTR)PtiCurrent());
ObDereferenceObject(pdesk);
} else if (hdesk == NULL && PsGetCurrentProcess() == gpepCSRSS) {
retval = xxxSetThreadDesktop(NULL, NULL);
} else
retval = FALSE;
TRACE("NtUserSetThreadDesktop");
ENDRECV();
}
...
NTSTATUS ValidateHdesk(
HDESK hdesk,
KPROCESSOR_MODE AccessMode,
ACCESS_MASK amDesired,
PDESKTOP* ppdesk)
{
NTSTATUS Status;
Status = ObReferenceObjectByHandle(
hdesk,
amDesired,
*ExDesktopObjectType,
AccessMode,
ppdesk,
NULL);
if (NT_SUCCESS(Status)) {
if ((*ppdesk)->dwSessionId != gSessionId) {
RIPNTERR3(STATUS_INVALID_HANDLE, RIP_WARNING,
"SessionId %d. Wrong session id %d for pdesk %#p",
gSessionId, (*ppdesk)->dwSessionId, *ppdesk);
goto Error;
}
LogDesktop(*ppdesk, LDL_VALIDATE_HDESK, TRUE, (ULONG_PTR)PtiCurrent());
if ((*ppdesk)->dwDTFlags & (DF_DESTROYED | DF_DESKWNDDESTROYED | DF_DYING)) {
RIPNTERR1(STATUS_INVALID_HANDLE, RIP_ERROR,
"ValidateHdesk: destroyed desktop %#p",
*ppdesk);
Error:
ObDereferenceObject(*ppdesk);
#if DBG
*ppdesk = NULL;
#endif // DBG
return STATUS_INVALID_HANDLE;
}
} else {
RIPNTERR1(Status, RIP_VERBOSE, "ValidateHdesk failed for %#p", hdesk);
}
return Status;
}
good luck