Author: tkreuzer
Date: Sat Apr 14 04:06:21 2007
New Revision: 26336
URL:
http://svn.reactos.org/svn/reactos?rev=26336&view=rev
Log:
NtUserBuildHwndList:
- non-recursive implementation, which saves stack space and should be about twice as
fast.
- use SEH instead of MmCopyToCaller
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Sat Apr 14 04:06:21 2007
@@ -1128,43 +1128,6 @@
return(0);
}
-STATIC
-ULONG
-STDCALL
-IntBuildHwndList(
- PWINDOW_OBJECT Window,
- BOOLEAN bChildren,
- HWND* pWnd,
- ULONG nBufSize)
-{
- NTSTATUS Status;
- PWINDOW_OBJECT Child;
- ULONG dwInc, dwCount = 0;
-
- for(Child = Window->FirstChild; Child != NULL; Child = Child->NextSibling)
- {
- if(dwCount++ < nBufSize && pWnd)
- {
- Status = MmCopyToCaller(pWnd++, &Child->hSelf, sizeof(HWND));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- break;
- }
- }
- if (bChildren)
- {
- dwInc = IntBuildHwndList(Child,
- bChildren,
- pWnd,
- nBufSize > dwCount ? nBufSize - dwCount : 0);
- dwCount += dwInc;
- pWnd += dwInc;
- }
- }
- return dwCount;
-}
-
/*
* As best as I can figure, this function is used by EnumWindows,
* EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
@@ -1193,7 +1156,7 @@
if (hwndParent || !dwThreadId)
{
PDESKTOP_OBJECT Desktop;
- PWINDOW_OBJECT Window;
+ PWINDOW_OBJECT Parent, Window;
if(!hwndParent)
{
@@ -1222,16 +1185,55 @@
hDesktop = 0;
}
- if(!(Window = UserGetWindowObject(hwndParent)))
- {
- if(hDesktop)
+ if((Parent = UserGetWindowObject(hwndParent)) &&
+ (Window = Parent->FirstChild))
+ {
+ BOOL bGoDown = TRUE;
+
+ Status = STATUS_SUCCESS;
+ while(TRUE)
{
- ObDereferenceObject(Desktop);
+ if (bGoDown)
+ {
+ if(dwCount++ < nBufSize && pWnd)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(pWnd, sizeof(HWND), 1);
+ *pWnd = Window->hSelf;
+ pWnd++;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ break;
+ }
+ }
+ if (Window->FirstChild && bChildren)
+ {
+ Window = Window->FirstChild;
+ continue;
+ }
+ bGoDown = FALSE;
+ }
+ if (Window->NextSibling)
+ {
+ Window = Window->NextSibling;
+ bGoDown = TRUE;
+ continue;
+ }
+ Window = Window->Parent;
+ if (Window == Parent)
+ {
+ break;
+ }
}
- return 0;
- }
-
- dwCount = IntBuildHwndList(Window, bChildren, pWnd, nBufSize);
+ }
if(hDesktop)
{