- Fix finding of windows by classes in NtUserFindWindow.

- Marshal WM_COPYDATA messages.

svn path=/trunk/; revision=12331
This commit is contained in:
Filip Navara 2004-12-25 20:30:50 +00:00
parent 2d0fbe6020
commit 681a0743e5
3 changed files with 80 additions and 36 deletions

View file

@ -1,4 +1,4 @@
/* $Id: message.c,v 1.45 2004/12/13 15:39:52 navaraf Exp $
/* $Id: message.c,v 1.46 2004/12/25 20:30:49 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -190,6 +190,7 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
KMMsg->lParam = (LPARAM) DdeLparam;
}
break;
case WM_DDE_EXECUTE:
{
SIZE_T Size;
@ -217,6 +218,31 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
GlobalUnlock((HGLOBAL) UMMsg->lParam);
}
break;
case WM_COPYDATA:
{
PCOPYDATASTRUCT pUMCopyData = (PCOPYDATASTRUCT)UMMsg->lParam;
PCOPYDATASTRUCT pKMCopyData;
pKMCopyData = HeapAlloc(GetProcessHeap(), 0,
sizeof(COPYDATASTRUCT) + pUMCopyData->cbData);
if (pKMCopyData == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
pKMCopyData->dwData = pUMCopyData->dwData;
pKMCopyData->cbData = pUMCopyData->cbData;
pKMCopyData->lpData = pKMCopyData + 1;
RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData,
pUMCopyData->cbData);
KMMsg->lParam = (LPARAM)pKMCopyData;
}
break;
default:
break;
}
@ -231,6 +257,7 @@ MsgiUMToKMCleanup(PMSG UMMsg, PMSG KMMsg)
{
case WM_DDE_ACK:
case WM_DDE_EXECUTE:
case WM_COPYDATA:
HeapFree(GetProcessHeap(), 0, (LPVOID) KMMsg->lParam);
break;
default:
@ -322,6 +349,13 @@ MsgiKMToUMMessage(PMSG KMMsg, PMSG UMMsg)
}
break;
case WM_COPYDATA:
{
PCOPYDATASTRUCT pKMCopyData = (PCOPYDATASTRUCT)KMMsg->lParam;
pKMCopyData->lpData = pKMCopyData + 1;
}
break;
default:
break;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: message.c,v 1.76 2004/12/11 19:39:18 weiden Exp $
/* $Id: message.c,v 1.77 2004/12/25 20:30:50 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -81,6 +81,7 @@ static MSGMEMORY MsgMemory[] =
{ WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
};
@ -149,6 +150,9 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
break;
case WM_COPYDATA:
return sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
default:
assert(FALSE);
return 0;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: window.c,v 1.257 2004/12/13 00:11:59 weiden Exp $
/* $Id: window.c,v 1.258 2004/12/25 20:30:50 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -2273,7 +2273,7 @@ NtUserFillWindow(DWORD Unknown0,
HWND FASTCALL
IntFindWindow(PWINDOW_OBJECT Parent,
PWINDOW_OBJECT ChildAfter,
PWNDCLASS_OBJECT ClassObject,
RTL_ATOM ClassAtom,
PUNICODE_STRING WindowName)
{
BOOL CheckWindowName;
@ -2305,11 +2305,8 @@ IntFindWindow(PWINDOW_OBJECT Parent,
/* 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 */
if(((!CheckWindowName || (CheckWindowName && !RtlCompareUnicodeString(WindowName, &(Child->WindowName), FALSE))) &&
(!ClassObject || (ClassObject && (Child->Class == ClassObject))))
||
((!CheckWindowName || (CheckWindowName && !RtlCompareUnicodeString(WindowName, &(Child->WindowName), FALSE))) &&
(!ClassObject || (ClassObject && (Child->Class == ClassObject)))))
if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), FALSE)) &&
(!ClassAtom || Child->Class->Atom == ClassAtom))
{
Ret = Child->Self;
IntReleaseWindowObject(Child);
@ -2358,8 +2355,7 @@ NtUserFindWindowEx(HWND hwndParent,
UNICODE_STRING ClassName, WindowName;
NTSTATUS Status;
HWND Desktop, Ret = NULL;
PWNDCLASS_OBJECT ClassObject = NULL;
BOOL ClassFound;
RTL_ATOM ClassAtom;
Desktop = IntGetCurrentThreadDesktopWindow();
@ -2427,25 +2423,38 @@ NtUserFindWindowEx(HWND hwndParent,
/* find the class object */
if(ClassName.Buffer)
{
/* this expects the string in ClassName to be NULL-terminated! */
ClassFound = ClassReferenceClassByNameOrAtom(&ClassObject, ClassName.Buffer, NULL);
if(!ClassFound)
{
if (IS_ATOM(ClassName.Buffer))
DPRINT1("Window class not found (%lx)\n", (ULONG_PTR)ClassName.Buffer);
else
DPRINT1("Window class not found (%S)\n", ClassName.Buffer);
SetLastWin32Error(ERROR_FILE_NOT_FOUND);
goto Cleanup;
}
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->Self == Desktop)
{
HWND *List, *phWnd;
PWINDOW_OBJECT TopLevelWindow;
BOOL CheckWindowName;
BOOLEAN CheckWindowName;
BOOLEAN CheckClassName;
BOOLEAN WindowMatches;
BOOLEAN ClassMatches;
/* windows searches through all top-level windows if the parent is the desktop
window */
@ -2461,6 +2470,7 @@ NtUserFindWindowEx(HWND hwndParent,
}
CheckWindowName = WindowName.Length > 0;
CheckClassName = ClassName.Buffer != NULL;
/* search children */
while(*phWnd)
@ -2473,18 +2483,19 @@ NtUserFindWindowEx(HWND hwndParent,
/* 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 */
if(((!CheckWindowName || (CheckWindowName && !RtlCompareUnicodeString(&WindowName, &(TopLevelWindow->WindowName), FALSE))) &&
(!ClassObject || (ClassObject && (TopLevelWindow->Class == ClassObject))))
||
((!CheckWindowName || (CheckWindowName && !RtlCompareUnicodeString(&WindowName, &(TopLevelWindow->WindowName), FALSE))) &&
(!ClassObject || (ClassObject && (TopLevelWindow->Class == ClassObject)))))
WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
&WindowName, &TopLevelWindow->WindowName, FALSE);
ClassMatches = !CheckClassName ||
ClassAtom == TopLevelWindow->Class->Atom;
if (WindowMatches && ClassMatches)
{
Ret = TopLevelWindow->Self;
IntReleaseWindowObject(TopLevelWindow);
break;
}
if(IntFindWindow(TopLevelWindow, NULL, ClassObject, &WindowName))
if (IntFindWindow(TopLevelWindow, NULL, ClassAtom, &WindowName))
{
/* window returns the handle of the top-level window, in case it found
the child window */
@ -2499,7 +2510,7 @@ NtUserFindWindowEx(HWND hwndParent,
}
}
else
Ret = IntFindWindow(Parent, ChildAfter, ClassObject, &WindowName);
Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
#if 0
if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
@ -2511,17 +2522,12 @@ NtUserFindWindowEx(HWND hwndParent,
if((MsgWindows = IntGetWindowObject(IntGetMessageWindow())))
{
Ret = IntFindWindow(MsgWindows, ChildAfter, ClassObject, &WindowName);
Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
IntReleaseWindowObject(MsgWindows);
}
}
#endif
if (ClassObject != NULL)
{
ClassDereferenceObject(ClassObject);
}
Cleanup:
if(ClassName.Length > 0 && ClassName.Buffer)
ExFreePool(ClassName.Buffer);