Author: amunger Date: Thu Jun 1 00:36:01 2006 New Revision: 22132
URL: http://svn.reactos.ru/svn/reactos?rev=22132&view=rev Log: Merge 21956, 21957, 21960 from trunk. NtUserFindWindowEx fixes. Fixes missing volume icon in the TNA.
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/window.c branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/include/class.h branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/class.c branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/window.c URL: http://svn.reactos.ru/svn/reactos/branches/ros-branch-0_3_0/reactos/dll/win3... ============================================================================== --- branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/window.c (original) +++ branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/window.c Thu Jun 1 00:36:01 2006 @@ -516,33 +516,51 @@ LPCSTR lpszClass, LPCSTR lpszWindow) { - UNICODE_STRING ucClassName; - UNICODE_STRING ucWindowName; + UNICODE_STRING ucClassName, *pucClassName = NULL; + UNICODE_STRING ucWindowName, *pucWindowName = NULL; HWND Result;
- if (lpszClass == NULL) - { - ucClassName.Buffer = NULL; - ucClassName.Length = 0; - } - else if (IS_ATOM(lpszClass)) + if (IS_ATOM(lpszClass)) { ucClassName.Buffer = (LPWSTR)lpszClass; ucClassName.Length = 0; + pucClassName = &ucClassName; } - else + else if (lpszClass != NULL) { - RtlCreateUnicodeStringFromAsciiz(&ucClassName, (LPSTR)lpszClass); + if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName, + (LPSTR)lpszClass)) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + pucClassName = &ucClassName; }
- RtlCreateUnicodeStringFromAsciiz(&ucWindowName, (LPSTR)lpszWindow); - - Result = NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, - &ucWindowName); - - if (!IS_ATOM(lpszClass)) + if (lpszWindow != NULL) + { + if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName, + (LPSTR)lpszWindow)) + { + if (!IS_ATOM(lpszClass) && lpszClass != NULL) + RtlFreeUnicodeString(&ucWindowName); + + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + pucWindowName = &ucWindowName; + } + + Result = NtUserFindWindowEx(hwndParent, + hwndChildAfter, + pucClassName, + pucWindowName); + + if (!IS_ATOM(lpszClass) && lpszClass != NULL) RtlFreeUnicodeString(&ucClassName); - RtlFreeUnicodeString(&ucWindowName); + if (lpszWindow != NULL) + RtlFreeUnicodeString(&ucWindowName);
return Result; } @@ -557,27 +575,33 @@ LPCWSTR lpszClass, LPCWSTR lpszWindow) { - UNICODE_STRING ucClassName; - UNICODE_STRING ucWindowName; - - if (lpszClass == NULL) + UNICODE_STRING ucClassName, *pucClassName = NULL; + UNICODE_STRING ucWindowName, *pucWindowName = NULL; + + if (IS_ATOM(lpszClass)) { - ucClassName.Buffer = NULL; ucClassName.Length = 0; + ucClassName.Buffer = (LPWSTR)lpszClass; + pucClassName = &ucClassName; } - else if (IS_ATOM(lpszClass)) + else if (lpszClass != NULL) { - RtlInitUnicodeString(&ucClassName, NULL); - ucClassName.Buffer = (LPWSTR)lpszClass; + RtlInitUnicodeString(&ucClassName, + lpszClass); + pucClassName = &ucClassName; } - else + + if (lpszWindow != NULL) { - RtlInitUnicodeString(&ucClassName, lpszClass); + RtlInitUnicodeString(&ucWindowName, + lpszWindow); + pucWindowName = &ucWindowName; }
- RtlInitUnicodeString(&ucWindowName, lpszWindow); - - return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName); + return NtUserFindWindowEx(hwndParent, + hwndChildAfter, + pucClassName, + pucWindowName); }
Modified: branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/include/class.h URL: http://svn.reactos.ru/svn/reactos/branches/ros-branch-0_3_0/reactos/subsyste... ============================================================================== --- branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/include/class.h (original) +++ branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/include/class.h Thu Jun 1 00:36:01 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: branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/class.c URL: http://svn.reactos.ru/svn/reactos/branches/ros-branch-0_3_0/reactos/subsyste... ============================================================================== --- branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/class.c (original) +++ branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/class.c Thu Jun 1 00:36:01 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: branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.ru/svn/reactos/branches/ros-branch-0_3_0/reactos/subsyste... ============================================================================== --- branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/window.c (original) +++ branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/window.c Thu Jun 1 00:36:01 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,73 @@ 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(); + + if (ucClassName != NULL || ucWindowName != NULL) + { + _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)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + _SEH_LEAVE; + } + + 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) + { + if (ClassName.Length == 0 && ClassName.Buffer != NULL && + !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 +2515,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);