Author: greatlrd
Date: Sun May 21 02:09:42 2006
New Revision: 21956
URL:
http://svn.reactos.ru/svn/reactos?rev=21956&view=rev
Log:
Bug 1507 patch from w3seek : This patch fixes more issues with NtUserFindWindowEx. (one
example of bugs have been fixed with this patch is the tray icon)
Modified:
trunk/reactos/subsystems/win32/win32k/include/class.h
trunk/reactos/subsystems/win32/win32k/ntuser/class.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/subsystems/win32/win32k/include/class.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/class.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/class.h Sun May 21 02:09:42 2006
@@ -70,6 +70,10 @@
OUT PWINDOWCLASS **Link OPTIONAL);
BOOL
+IntGetAtomFromStringOrAtom(IN PUNICODE_STRING ClassName,
+ OUT RTL_ATOM *Atom);
+
+BOOL
IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
IN BOOL FreeOnFailure);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c Sun May 21 02:09:42 2006
@@ -835,12 +835,11 @@
}
ClassSize = sizeof(WINDOWCLASS) + lpwcx->cbClsExtra;
- ClassSize += ClassName->Length + sizeof(UNICODE_NULL);
- ClassSize += MenuName->Length + sizeof(UNICODE_NULL);
- if (ClassName->Length != 0)
- ClassSize += RtlUnicodeStringToAnsiSize(ClassName);
if (MenuName->Length != 0)
+ {
+ ClassSize += MenuName->Length + sizeof(UNICODE_NULL);
ClassSize += RtlUnicodeStringToAnsiSize(MenuName);
+ }
if (Desktop != NULL)
{
@@ -996,14 +995,11 @@
return Class;
}
-RTL_ATOM
-IntGetClassAtom(IN PUNICODE_STRING ClassName,
- IN HINSTANCE hInstance OPTIONAL,
- IN PW32PROCESSINFO pi OPTIONAL,
- OUT PWINDOWCLASS *BaseClass OPTIONAL,
- OUT PWINDOWCLASS **Link OPTIONAL)
-{
- RTL_ATOM Atom = (RTL_ATOM)0;
+BOOL
+IntGetAtomFromStringOrAtom(IN PUNICODE_STRING ClassName,
+ OUT RTL_ATOM *Atom)
+{
+ BOOL Ret = FALSE;
if (ClassName->Length != 0)
{
@@ -1038,8 +1034,12 @@
/* lookup the atom */
Status = RtlLookupAtomInAtomTable(gAtomTable,
AtomName,
- &Atom);
- if (!NT_SUCCESS(Status))
+ Atom);
+ if (NT_SUCCESS(Status))
+ {
+ Ret = TRUE;
+ }
+ else
{
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
@@ -1054,10 +1054,25 @@
else
{
ASSERT(IS_ATOM(ClassName->Buffer));
- Atom = (RTL_ATOM)((ULONG_PTR)ClassName->Buffer);
- }
-
- if (BaseClass != NULL && Atom != (RTL_ATOM)0)
+ *Atom = (RTL_ATOM)((ULONG_PTR)ClassName->Buffer);
+ Ret = TRUE;
+ }
+
+ return Ret;
+}
+
+RTL_ATOM
+IntGetClassAtom(IN PUNICODE_STRING ClassName,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN PW32PROCESSINFO pi OPTIONAL,
+ OUT PWINDOWCLASS *BaseClass OPTIONAL,
+ OUT PWINDOWCLASS **Link OPTIONAL)
+{
+ RTL_ATOM Atom = (RTL_ATOM)0;
+
+ if (IntGetAtomFromStringOrAtom(ClassName,
+ &Atom) &&
+ BaseClass != NULL && Atom != (RTL_ATOM)0)
{
PWINDOWCLASS Class;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Sun May 21 02:09:42 2006
@@ -2344,7 +2344,7 @@
}
-HWND FASTCALL
+static HWND FASTCALL
IntFindWindow(PWINDOW_OBJECT Parent,
PWINDOW_OBJECT ChildAfter,
RTL_ATOM ClassAtom,
@@ -2356,7 +2356,7 @@
ASSERT(Parent);
- CheckWindowName = (WindowName && (WindowName->Length > 0));
+ CheckWindowName = WindowName->Length != 0;
if((List = IntWinListChildren(Parent)))
{
@@ -2425,14 +2425,66 @@
PUNICODE_STRING ucWindowName)
{
PWINDOW_OBJECT Parent, ChildAfter;
- UNICODE_STRING ClassName, WindowName;
- NTSTATUS Status;
+ UNICODE_STRING ClassName = {0}, WindowName = {0};
HWND Desktop, Ret = NULL;
- RTL_ATOM ClassAtom;
+ RTL_ATOM ClassAtom = (RTL_ATOM)0;
DECLARE_RETURN(HWND);
DPRINT("Enter NtUserFindWindowEx\n");
UserEnterShared();
+
+ _SEH_TRY
+ {
+ if (ucClassName != NULL)
+ {
+ ClassName = ProbeForReadUnicodeString(ucClassName);
+ if (ClassName.Length != 0)
+ {
+ ProbeForRead(ClassName.Buffer,
+ ClassName.Length,
+ sizeof(WCHAR));
+ }
+ else if (IS_ATOM(ClassName.Buffer))
+ {
+ if (!IntGetAtomFromStringOrAtom(&ClassName,
+ &ClassAtom))
+ {
+ _SEH_LEAVE;
+ }
+ }
+ }
+
+ if (ucWindowName != NULL)
+ {
+ WindowName = ProbeForReadUnicodeString(ucWindowName);
+ if (WindowName.Length != 0)
+ {
+ ProbeForRead(WindowName.Buffer,
+ WindowName.Length,
+ sizeof(WCHAR));
+ }
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ RETURN(NULL);
+ }
+ _SEH_END;
+
+ if (ucClassName != NULL && ClassName.Length == 0)
+ {
+ if (!IS_ATOM(ClassName.Buffer))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN(NULL);
+ }
+ else if (ClassAtom == (RTL_ATOM)0)
+ {
+ /* LastError code was set by IntGetAtomFromStringOrAtom */
+ RETURN(NULL);
+ }
+ }
Desktop = IntGetCurrentThreadDesktopWindow();
@@ -2456,158 +2508,91 @@
RETURN( NULL);
}
- /* copy the window name */
- Status = IntSafeCopyUnicodeString(&WindowName, ucWindowName);
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- goto Cleanup3;
- }
-
- /* safely copy the class name */
- Status = MmCopyFromCaller(&ClassName, ucClassName, sizeof(UNICODE_STRING));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- goto Cleanup2;
- }
- if(ClassName.Length > 0 && ClassName.Buffer)
- {
- WCHAR *buf;
- /* safely copy the class name string (NULL terminated because class-lookup
- depends on it... */
- buf = ExAllocatePoolWithTag(PagedPool, ClassName.Length + sizeof(WCHAR),
TAG_STRING);
- if(!buf)
- {
- SetLastWin32Error(STATUS_INSUFFICIENT_RESOURCES);
- goto Cleanup2;
- }
- Status = MmCopyFromCaller(buf, ClassName.Buffer, ClassName.Length);
- if(!NT_SUCCESS(Status))
- {
- ExFreePool(buf);
- SetLastNtError(Status);
- goto Cleanup2;
- }
- ClassName.Buffer = buf;
- /* make sure the string is null-terminated */
- buf += ClassName.Length / sizeof(WCHAR);
- *buf = L'\0';
- }
-
- /* find the class object */
- if(ClassName.Buffer)
- {
- PWINSTATION_OBJECT WinStaObject;
-
- if (PsGetWin32Thread()->Desktop == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- goto Cleanup;
- }
-
- WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
-
- Status = RtlLookupAtomInAtomTable(
- WinStaObject->AtomTable,
- ClassName.Buffer,
- &ClassAtom);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to lookup class atom!\n");
- SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
- goto Cleanup;
- }
- }
-
- if(Parent->hSelf == Desktop)
- {
- HWND *List, *phWnd;
- PWINDOW_OBJECT TopLevelWindow;
- BOOLEAN CheckWindowName;
- BOOLEAN CheckClassName;
- BOOLEAN WindowMatches;
- BOOLEAN ClassMatches;
-
- /* windows searches through all top-level windows if the parent is the desktop
- window */
-
- if((List = IntWinListChildren(Parent)))
- {
- phWnd = List;
-
- if(ChildAfter)
- {
- /* skip handles before and including ChildAfter */
- while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
- ;
- }
-
- CheckWindowName = WindowName.Length > 0;
- CheckClassName = ClassName.Buffer != NULL;
-
- /* search children */
- while(*phWnd)
- {
- if(!(TopLevelWindow = UserGetWindowObject(*(phWnd++))))
- {
- continue;
- }
-
- /* Do not send WM_GETTEXT messages in the kernel mode version!
- The user mode version however calls GetWindowText() which will
- send WM_GETTEXT messages to windows belonging to its processes */
- WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
- &WindowName, &TopLevelWindow->WindowName,
TRUE);
- ClassMatches = !CheckClassName ||
- ClassAtom == TopLevelWindow->Class->Atom;
-
- if (WindowMatches && ClassMatches)
- {
- Ret = TopLevelWindow->hSelf;
- break;
- }
-
- if (IntFindWindow(TopLevelWindow, NULL, ClassAtom, &WindowName))
- {
- /* window returns the handle of the top-level window, in case it found
- the child window */
- Ret = TopLevelWindow->hSelf;
- break;
- }
-
- }
- ExFreePool(List);
- }
- }
- else
- Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
+ _SEH_TRY
+ {
+ if(Parent->hSelf == Desktop)
+ {
+ HWND *List, *phWnd;
+ PWINDOW_OBJECT TopLevelWindow;
+ BOOLEAN CheckWindowName;
+ BOOLEAN WindowMatches;
+ BOOLEAN ClassMatches;
+
+ /* windows searches through all top-level windows if the parent is the desktop
+ window */
+
+ if((List = IntWinListChildren(Parent)))
+ {
+ phWnd = List;
+
+ if(ChildAfter)
+ {
+ /* skip handles before and including ChildAfter */
+ while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+ ;
+ }
+
+ CheckWindowName = WindowName.Length != 0;
+
+ /* search children */
+ while(*phWnd)
+ {
+ if(!(TopLevelWindow = UserGetWindowObject(*(phWnd++))))
+ {
+ continue;
+ }
+
+ /* Do not send WM_GETTEXT messages in the kernel mode version!
+ The user mode version however calls GetWindowText() which will
+ send WM_GETTEXT messages to windows belonging to its processes */
+ WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
+ &WindowName, &TopLevelWindow->WindowName,
TRUE);
+ ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
+ ClassAtom == TopLevelWindow->Class->Atom;
+
+ if (WindowMatches && ClassMatches)
+ {
+ Ret = TopLevelWindow->hSelf;
+ break;
+ }
+
+ if (IntFindWindow(TopLevelWindow, NULL, ClassAtom, &WindowName))
+ {
+ /* window returns the handle of the top-level window, in case it
found
+ the child window */
+ Ret = TopLevelWindow->hSelf;
+ break;
+ }
+
+ }
+ ExFreePool(List);
+ }
+ }
+ else
+ Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
#if 0
- if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
- {
- /* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
- search the message-only windows. Should this also be done if
- Parent is the desktop window??? */
- PWINDOW_OBJECT MsgWindows;
-
- if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
- {
- Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
- }
- }
+ if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
+ {
+ /* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
+ search the message-only windows. Should this also be done if
+ Parent is the desktop window??? */
+ PWINDOW_OBJECT MsgWindows;
+
+ if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
+ {
+ Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
+ }
+ }
#endif
-
-Cleanup:
- if(ClassName.Length > 0 && ClassName.Buffer)
- ExFreePool(ClassName.Buffer);
-
-Cleanup2:
- RtlFreeUnicodeString(&WindowName);
-
-Cleanup3:
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ Ret = NULL;
+ }
+ _SEH_END;
RETURN( Ret);