mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
rewrote NtUserBuildHwndList()
svn path=/trunk/; revision=9314
This commit is contained in:
parent
e8953aae82
commit
879f672ffe
2 changed files with 125 additions and 110 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue