rewrote NtUserBuildHwndList()

svn path=/trunk/; revision=9314
This commit is contained in:
Thomas Bluemel 2004-05-05 22:26:04 +00:00
parent e8953aae82
commit 879f672ffe
2 changed files with 125 additions and 110 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: message.c,v 1.61 2004/05/05 22:13:17 weiden Exp $ /* $Id: message.c,v 1.62 2004/05/05 22:26:03 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -450,10 +450,9 @@ IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *Hit
{ {
if(Wnd != Window) if(Wnd != Window)
{ {
MSG NewMsg = *Msg;
/* post the message to the other window */ /* post the message to the other window */
NewMsg.hwnd = Wnd->Self; Msg->hwnd = Wnd->Self;
MsqPostMessage(Wnd->MessageQueue, &NewMsg, FALSE); MsqPostMessage(Wnd->MessageQueue, Msg, FALSE);
/* eat the message */ /* eat the message */
IntReleaseWindowObject(Wnd); IntReleaseWindowObject(Wnd);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: window.c,v 1.223 2004/05/02 17:25:21 weiden Exp $ /* $Id: window.c,v 1.224 2004/05/05 22:26:04 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1144,119 +1144,135 @@ NtUserBuildHwndList(
HWND* pWnd, HWND* pWnd,
ULONG nBufSize) ULONG nBufSize)
{ {
NTSTATUS Status;
ULONG dwCount = 0; ULONG dwCount = 0;
/* FIXME handle bChildren */ /* FIXME handle bChildren */
if(hwndParent) if(hwndParent)
{ {
PWINDOW_OBJECT WindowObject = NULL; PWINDOW_OBJECT Window, Child;
PWINDOW_OBJECT Child; if(!(Window = IntGetWindowObject(hwndParent)))
WindowObject = IntGetWindowObject ( hwndParent );
if ( !WindowObject )
{ {
DPRINT("Bad window handle 0x%x\n", hwndParent); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
IntLockRelatives(Window);
for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
{
if(dwCount++ < nBufSize && pWnd)
{
Status = MmCopyToCaller(pWnd++, &Child->Self, sizeof(HWND));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
break;
}
}
}
IntUnLockRelatives(Window);
IntReleaseWindowObject(Window);
}
else if(dwThreadId)
{
PETHREAD Thread;
PW32THREAD W32Thread;
PLIST_ENTRY Current;
PWINDOW_OBJECT *Window;
Status = PsLookupThreadByThreadId((PVOID)dwThreadId, &Thread);
if(!NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
if(!(W32Thread = Thread->Win32Thread))
{
ObDereferenceObject(Thread);
DPRINT1("Thread is not a GUI Thread!\n");
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
IntLockThreadWindows(W32Thread);
Current = W32Thread->WindowListHead.Flink;
while(Current != &(W32Thread->WindowListHead))
{
*Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
ASSERT(*Window);
if(dwCount < nBufSize && pWnd && ((*Window)->Style & WS_CHILD))
{
Status = MmCopyToCaller(pWnd++, &(*Window)->Self, sizeof(HWND));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
break;
}
}
if(!((*Window)->Style & WS_CHILD))
{
dwCount++;
}
Current = Current->Flink;
}
IntUnLockThreadWindows(W32Thread);
ObDereferenceObject(Thread);
}
else
{
PDESKTOP_OBJECT Desktop;
PWINDOW_OBJECT Window, Child;
if(hDesktop == NULL && !(Desktop = IntGetActiveDesktop()))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
if(hDesktop)
{
Status = IntValidateDesktopHandle(hDesktop,
UserMode,
0,
&Desktop);
if(!NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
}
if(!(Window = IntGetWindowObject(Desktop->DesktopWindow)))
{
if(hDesktop)
ObDereferenceObject(Desktop);
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return 0; return 0;
} }
IntLockRelatives(WindowObject ); IntLockRelatives(Window);
Child = WindowObject->FirstChild; for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
while (Child)
{ {
if ( pWnd && dwCount < nBufSize ) if(dwCount++ < nBufSize && pWnd)
pWnd[dwCount] = Child->Self;
dwCount++;
Child = Child->NextSibling;
}
IntUnLockRelatives(WindowObject);
IntReleaseWindowObject ( WindowObject );
}
else if ( dwThreadId )
{ {
NTSTATUS Status; Status = MmCopyToCaller(pWnd++, &Child->Self, sizeof(HWND));
struct _ETHREAD* Thread; if(!NT_SUCCESS(Status))
struct _EPROCESS* ThreadsProcess; {
struct _W32PROCESS* Win32Process; SetLastNtError(Status);
struct _WINSTATION_OBJECT* WindowStation; break;
PUSER_HANDLE_TABLE HandleTable; }
PLIST_ENTRY Current; }
PUSER_HANDLE_BLOCK Block = NULL; }
ULONG i; IntUnLockRelatives(Window);
Status = PsLookupThreadByThreadId ( (PVOID)dwThreadId, &Thread ); IntReleaseWindowObject(Window);
if ( !NT_SUCCESS(Status) || !Thread )
{
DPRINT("Bad ThreadId 0x%x\n", dwThreadId );
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
ThreadsProcess = Thread->ThreadsProcess;
ASSERT(ThreadsProcess);
Win32Process = ThreadsProcess->Win32Process;
ASSERT(Win32Process);
WindowStation = Win32Process->WindowStation;
ASSERT(WindowStation);
HandleTable = (PUSER_HANDLE_TABLE)(WindowStation->HandleTable);
ASSERT(HandleTable);
ObDereferenceObject(Thread);
ObmpLockHandleTable(HandleTable);
Current = HandleTable->ListHead.Flink;
while ( Current != &HandleTable->ListHead )
{
Block = CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
for ( i = 0; i < HANDLE_BLOCK_ENTRIES; i++ )
{
PVOID ObjectBody = Block->Handles[i].ObjectBody;
if ( ObjectBody )
{
if ( pWnd && dwCount < nBufSize )
{
pWnd[dwCount] =
(HWND)IntReferenceWindowObject(ObjectBody);
}
dwCount++;
}
}
Current = Current->Flink;
}
ObmpUnlockHandleTable(HandleTable);
}
else
{
PDESKTOP_OBJECT DesktopObject = NULL;
KIRQL OldIrql;
PWINDOW_OBJECT Child, WndDesktop;
#if 0
if(hDesktop) if(hDesktop)
DesktopObject = IntGetDesktopObject ( hDesktop ); ObDereferenceObject(Desktop);
else
#endif
DesktopObject = IntGetActiveDesktop();
if (!DesktopObject)
{
DPRINT("Bad desktop handle 0x%x\n", hDesktop );
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
KeAcquireSpinLock ( &DesktopObject->Lock, &OldIrql );
WndDesktop = IntGetWindowObject(DesktopObject->DesktopWindow);
Child = (WndDesktop ? WndDesktop->FirstChild : NULL);
while (Child)
{
if ( pWnd && dwCount < nBufSize )
pWnd[dwCount] = Child->Self;
dwCount++;
Child = Child->NextSibling;
}
KeReleaseSpinLock ( &DesktopObject->Lock, OldIrql );
} }
return dwCount; return dwCount;