- Fix assert with WinSnap. Added support functions to be used later.

svn path=/trunk/; revision=56832
This commit is contained in:
James Tabor 2012-07-04 22:59:27 +00:00
parent 03578273c3
commit 5c5f00b225
3 changed files with 57 additions and 12 deletions

View file

@ -466,6 +466,23 @@ IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
} }
// Only one Q can have active foreground even when there are more than one desktop. // Only one Q can have active foreground even when there are more than one desktop.
if (NewQueue) gpqForeground = pdo->ActiveMessageQueue; if (NewQueue) gpqForeground = pdo->ActiveMessageQueue;
else gpqForeground = NULL;
}
PWND FASTCALL
IntGetThreadDesktopWindow(PTHREADINFO pti)
{
if (!pti) pti = PsGetCurrentThreadWin32Thread();
if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
return NULL;
}
PWND FASTCALL co_GetDesktopWindow(PWND pWnd)
{
if (pWnd->head.rpdesk &&
pWnd->head.rpdesk->pDeskInfo)
return pWnd->head.rpdesk->pDeskInfo->spwnd;
return NULL;
} }
HWND FASTCALL IntGetDesktopWindow(VOID) HWND FASTCALL IntGetDesktopWindow(VOID)
@ -530,6 +547,21 @@ HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
LRESULT FASTCALL
DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_NCCREATE:
if (!Wnd->fnid)
{
Wnd->fnid = FNID_DESKTOP;
}
return (LRESULT)TRUE;
}
return 0;
}
HDC FASTCALL HDC FASTCALL
UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd) UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd)
{ {
@ -1335,16 +1367,17 @@ NtUserOpenInputDesktop(
{ {
PDESKTOP pdesk; PDESKTOP pdesk;
NTSTATUS Status; NTSTATUS Status;
HDESK hdesk; HDESK hdesk = NULL;
TRACE("Enter NtUserOpenInputDesktop\n"); UserEnterExclusive();
TRACE("Enter NtUserOpenInputDesktop InputDesktopHandle 0x%x\n",InputDesktopHandle);
/* Get a pointer to the desktop object */ /* Get a pointer to the desktop object */
Status = IntValidateDesktopHandle(InputDesktopHandle, UserMode, 0, &pdesk); Status = IntValidateDesktopHandle(InputDesktopHandle, UserMode, 0, &pdesk);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
TRACE("Validation of input desktop handle (0x%X) failed\n", InputDesktop); ERR("Validation of input desktop handle (0x%X) failed\n", InputDesktopHandle);
return NULL; goto Exit;
} }
/* Create a new handle to the object */ /* Create a new handle to the object */
@ -1363,10 +1396,11 @@ NtUserOpenInputDesktop(
{ {
ERR("Failed to open input desktop object\n"); ERR("Failed to open input desktop object\n");
SetLastNtError(Status); SetLastNtError(Status);
return NULL; goto Exit;
} }
Exit:
TRACE("NtUserOpenInputDesktop returning 0x%x\n",hdesk); TRACE("NtUserOpenInputDesktop returning 0x%x\n",hdesk);
UserLeave();
return hdesk; return hdesk;
} }
@ -1397,15 +1431,12 @@ NtUserCloseDesktop(HDESK hDesktop)
{ {
PDESKTOP pdesk; PDESKTOP pdesk;
NTSTATUS Status; NTSTATUS Status;
PTHREADINFO pti;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
pti = PsGetCurrentThreadWin32Thread();
TRACE("NtUserCloseDesktop called (0x%x)\n", hDesktop); TRACE("NtUserCloseDesktop called (0x%x)\n", hDesktop);
UserEnterExclusive(); UserEnterExclusive();
if( hDesktop == pti->hdesk || hDesktop == pti->ppi->hdeskStartup) if( hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
{ {
ERR("Attempted to close thread desktop\n"); ERR("Attempted to close thread desktop\n");
EngSetLastError(ERROR_BUSY); EngSetLastError(ERROR_BUSY);
@ -1526,7 +1557,7 @@ NtUserSwitchDesktop(HDESK hdesk)
/* Set the global state. */ /* Set the global state. */
InputDesktop = pdesk; InputDesktop = pdesk;
InputDesktopHandle = hdesk; InputDesktopHandle = hdesk;
TRACE("SwitchDesktop InputDesktopHandle 0x%x\n",InputDesktopHandle);
ObDereferenceObject(pdesk); ObDereferenceObject(pdesk);
RETURN(TRUE); RETURN(TRUE);
@ -1780,6 +1811,13 @@ IntSetThreadDesktop(IN HDESK hDesktop,
return FALSE; return FALSE;
} }
/* Desktop is being re-set so clear out foreground. */
if (pti->rpdesk != pdesk && pti->MessageQueue == gpqForeground)
{
// Like above, there shouldn't be any windows, hooks or anything active on this threads desktop!
IntSetFocusMessageQueue(NULL);
}
/* Before doing the switch, map the new desktop heap and allocate the new pcti */ /* Before doing the switch, map the new desktop heap and allocate the new pcti */
if(pdesk != NULL) if(pdesk != NULL)
{ {
@ -1846,6 +1884,8 @@ IntSetThreadDesktop(IN HDESK hDesktop,
else else
{ {
RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO)); RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO));
pci->fsHooks = pti->fsHooks;
pci->dwTIFlags = pti->TIF_flags;
} }
} }
else else

View file

@ -275,4 +275,8 @@ DesktopHeapAddressToUser(PVOID lpMem)
return NULL; return NULL;
} }
PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO);
PWND FASTCALL co_GetDesktopWindow(PWND);
LRESULT FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM);
/* EOF */ /* EOF */

View file

@ -1048,7 +1048,7 @@ IntRemoveHook(PHOOK Hook)
pti->fsHooks &= ~HOOKID_TO_FLAG(HookId); pti->fsHooks &= ~HOOKID_TO_FLAG(HookId);
_SEH2_TRY _SEH2_TRY
{ {
GetWin32ClientInfo()->fsHooks = pti->fsHooks; pti->pClientInfo->fsHooks = pti->fsHooks;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -1106,6 +1106,7 @@ HOOK_DestroyThreadHooks(PETHREAD Thread)
} }
} }
pti->fsHooks = 0; pti->fsHooks = 0;
pti->pClientInfo->fsHooks = 0;
} }
// Global search based on Thread and cleanup. // Global search based on Thread and cleanup.
if (pdo->pDeskInfo->fsHooks) if (pdo->pDeskInfo->fsHooks)