Window = UserGetWindowObject(hWnd);
if (Window)
{
-// UserRefObjectCo(Window);
+// USER_REFERENCE_ENTRY Ref;
+// UserRefObjectCo(Window, &Ref);
if (!IntGetOwner(Window) && !IntGetParent(Window))
{
* IntDestroyWindow
*
* Destroy storage associated to a window. "Internals" p.358
+ *
+ * This is the "functional" DestroyWindows function ei. all stuff
+ * done in CreateWindow is undone here and not in DestroyWindow:-P
+
*/
-static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
PW32PROCESS ProcessData,
PW32THREAD ThreadData,
BOOLEAN SendMessages)
IntSendDestroyMsg(Child->hSelf);
}
else
- co_IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
+ co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
UserDerefObject(Child);
}
IntDestroyScrollBars(Window);
- /* remove the window from the class object */
- RemoveEntryList(&Window->ClassListEntry);
-
/* dereference the class */
- ClassDereferenceObject(Window->Class);
+ ClassDerefObject(Window->Class);
Window->Class = NULL;
if(Window->WindowRegion)
PW32THREAD WThread;
PLIST_ENTRY Current;
PWINDOW_OBJECT Wnd;
-
- WThread = Thread->Tcb.Win32Thread;
+ USER_REFERENCE_ENTRY Ref;
+ WThread = (PW32THREAD)Thread->Tcb.Win32Thread;
while (!IsListEmpty(&WThread->WindowListHead))
{
//ASSERT(co_UserDestroyWindow(Wnd));
- UserRefObjectCo(Wnd);//faxme: temp hack??
+ UserRefObjectCo(Wnd, &Ref);//faxme: temp hack??
if (!co_UserDestroyWindow(Wnd))
{
DPRINT1("Unable to destroy window 0x%x at thread cleanup... This is _VERY_ bad!\n", Wnd);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
- if(!(W32Thread = Thread->Tcb.Win32Thread))
+ if(!(W32Thread = (PW32THREAD)Thread->Tcb.Win32Thread))
{
ObDereferenceObject(Thread);
DPRINT("Thread is not a GUI Thread!\n");
BOOL bUnicodeWindow)
{
PWINSTATION_OBJECT WinSta;
- PWNDCLASS_OBJECT Class;
+ PWNDCLASS_OBJECT Class = NULL;
PWINDOW_OBJECT Window = NULL;
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
HWND ParentWindowHandle;
HWND OwnerWindowHandle;
PMENU_OBJECT SystemMenu;
- HANDLE Handle;
+ HWND hWnd;
POINT Pos;
SIZE Size;
#if 0
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
BOOL MenuChanged;
- BOOL ClassFound;
DECLARE_RETURN(HWND);
BOOL HasOwner;
+ USER_REFERENCE_ENTRY ParentRef, Ref;
ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
OwnerWindowHandle = NULL;
else
{
//temp hack
- PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent);
- if (Par)
- OwnerWindowHandle = UserGetAncestor(Par, GA_ROOT)->hSelf;
+ PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root;
+ if (Par && (Root = UserGetAncestor(Par, GA_ROOT)))
+ OwnerWindowHandle = Root->hSelf;
}
}
else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
// {
ParentWindow = UserGetWindowObject(ParentWindowHandle);
- if (ParentWindow) UserRefObjectCo(ParentWindow);
+ if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
// }
// else
// {
/* FIXME: parent must belong to the current process */
/* Check the class. */
- ClassFound = ClassReferenceClassByNameOrAtom(&Class, ClassName->Buffer, hInstance);
- if (!ClassFound)
+ Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
+ if (!Class)
{
if (IS_ATOM(ClassName->Buffer))
{
RETURN((HWND)0);
}
+ ClassRefObject(Class);
+
/* Check the window station. */
if (PsGetWin32Thread()->Desktop == NULL)
{
- ClassDereferenceObject(Class);
-
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
RETURN( (HWND)0);
}
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+
+ //FIXME: Reference thread/desktop instead
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
/* Create the window object. */
Window = (PWINDOW_OBJECT)
- ObmCreateObject(&gHandleTable, &Handle,
+ ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
);
- DPRINT("Created object with handle %X\n", Handle);
+ DPRINT("Created object with handle %X\n", hWnd);
if (!Window)
{
ObDereferenceObject(WinSta);
- ClassDereferenceObject(Class);
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
RETURN( (HWND)0);
}
- UserRefObjectCo(Window);
-
+ UserRefObjectCo(Window, &Ref);
ObDereferenceObject(WinSta);
if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
{
/* If there is no desktop window yet, we must be creating it */
- PsGetWin32Thread()->Desktop->DesktopWindow = Handle;
+ PsGetWin32Thread()->Desktop->DesktopWindow = hWnd;
}
/*
* Fill out the structure describing it.
*/
Window->Class = Class;
-
- InsertTailList(&Class->ClassWindowsListHead, &Window->ClassListEntry);
-
Window->SystemMenu = (HMENU)0;
Window->ContextHelpId = 0;
Window->IDMenu = 0;
Window->Instance = hInstance;
- Window->hSelf = Handle;
+ Window->hSelf = hWnd;
+
+ if (!hMenu)
+ hMenu = Class->hMenu;
+
if (0 != (dwStyle & WS_CHILD))
{
Window->IDMenu = (UINT) hMenu;
Window->LastChild = NULL;
Window->PrevSibling = NULL;
Window->NextSibling = NULL;
+ Window->ExtraDataSize = Class->cbWndExtra;
/* extra window data */
- if (Class->cbWndExtra != 0)
- {
+ if (Class->cbWndExtra)
Window->ExtraData = (PCHAR)(Window + 1);
- Window->ExtraDataSize = Class->cbWndExtra;
- RtlZeroMemory(Window->ExtraData, Window->ExtraDataSize);
- }
- else
- {
- Window->ExtraData = NULL;
- Window->ExtraDataSize = 0;
- }
InitializeListHead(&Window->PropListHead);
InitializeListHead(&Window->WndObjListHead);
TAG_STRING);
if (NULL == Window->WindowName.Buffer)
{
- ClassDereferenceObject(Class);
DPRINT1("Failed to allocate mem for window name\n");
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
RETURN( NULL);
Cs.dwExStyle = dwExStyle;
CbtCreate.lpcs = &Cs;
CbtCreate.hwndInsertAfter = HWND_TOP;
- if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
+ if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
{
-
/* FIXME - Delete window object and remove it from the thread windows list */
/* FIXME - delete allocated DCE */
-
- ClassDereferenceObject(Class);
DPRINT1("CBT-hook returned !0\n");
RETURN( (HWND) NULL);
}
PRTL_USER_PROCESS_PARAMETERS ProcessParams;
BOOL CalculatedDefPosSize = FALSE;
- IntGetDesktopWorkArea(Window->OwnerThread->Tcb.Win32Thread->Desktop, &WorkArea);
+ IntGetDesktopWorkArea(((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
rc = WorkArea;
ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
/* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack,
&MaxTrack);
- if (MaxSize.x < nWidth)
- nWidth = MaxSize.x;
- if (MaxSize.y < nHeight)
- nHeight = MaxSize.y;
- if (nWidth < MinTrack.x )
- nWidth = MinTrack.x;
- if (nHeight < MinTrack.y )
- nHeight = MinTrack.y;
- if (nWidth < 0)
- nWidth = 0;
- if (nHeight < 0)
- nHeight = 0;
+ if (MaxSize.x < Size.cx)
+ Size.cx = MaxSize.x;
+ if (MaxSize.y < Size.cy)
+ Size.cy = MaxSize.y;
+ if (Size.cx < MinTrack.x )
+ Size.cx = MinTrack.x;
+ if (Size.cy < MinTrack.y )
+ Size.cy = MinTrack.y;
+ if (Size.cx < 0)
+ Size.cx = 0;
+ if (Size.cy < 0)
+ Size.cy = 0;
}
Window->WindowRect.left = Pos.x;
Cs.y = Pos.y;
DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
- DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
+ DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, Size.cx, Size.cy);
DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n");
Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) &Cs);
if (!Result)
if (Result == (LRESULT)-1)
{
/* FIXME: Cleanup. */
- ClassDereferenceObject(Class);
DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
RETURN((HWND)0);
}
if ((!hWndParent) && (!HasOwner))
{
DPRINT("Sending CREATED notify\n");
- co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
+ co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
}
else
{
co_WinPosShowWindow(Window, dwShowMode);
}
- DPRINT("IntCreateWindow(): = %X\n", Handle);
+ DPRINT("IntCreateWindow(): = %X\n", hWnd);
DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
- RETURN((HWND)Handle);
+ RETURN(hWnd);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
if (ParentWindow) UserDerefObjectCo(ParentWindow);
-
+ if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
END_CLEANUP;
}
ASSERT_REFS_CO(Window); //fixme: temp hack?
- /* Check for owner thread and desktop window */
- if ((Window->OwnerThread != PsGetCurrentThread()) || IntIsDesktopWindow(Window))
+ /* Check for owner thread */
+ if ((Window->OwnerThread != PsGetCurrentThread()))
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
HWND *ChildHandle;
PWINDOW_OBJECT Child, Desktop;
- Desktop = UserGetWindowObject(IntGetDesktopWindow());
+ Desktop = IntIsDesktopWindow(Window) ? Window :
+ UserGetWindowObject(IntGetDesktopWindow());
Children = IntWinListChildren(Desktop);
if (Children)
if (IntWndBelongsToThread(Child, PsGetWin32Thread()))
{
-
- UserRefObjectCo(Child);//temp hack?
+ USER_REFERENCE_ENTRY ChildRef;
+ UserRefObjectCo(Child, &ChildRef);//temp hack?
co_UserDestroyWindow(Child);
UserDerefObjectCo(Child);//temp hack?
}
/* Destroy the window storage */
- co_IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
+ co_UserFreeWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
return TRUE;
}
PWINDOW_OBJECT Window;
DECLARE_RETURN(BOOLEAN);
BOOLEAN ret;
+ USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserDestroyWindow\n");
UserEnterExclusive();
RETURN(FALSE);
}
- UserRefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..
+ UserRefObjectCo(Window, &Ref);//faxme: dunno if win should be reffed during destroy..
ret = co_UserDestroyWindow(Window);
UserDerefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..
/* 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 || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), FALSE)) &&
+ if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), TRUE)) &&
(!ClassAtom || Child->Class->Atom == ClassAtom))
{
Ret = Child->hSelf;
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, FALSE);
+ &WindowName, &TopLevelWindow->WindowName, TRUE);
ClassMatches = !CheckClassName ||
ClassAtom == TopLevelWindow->Class->Atom;
{
PWINDOW_OBJECT WndAncestor, Parent;
+ if (Wnd->hSelf == IntGetDesktopWindow())
+ {
+ return NULL;
+ }
+
switch (Type)
{
case GA_PARENT:
{
PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
HWND hWndOldParent = NULL;
+ USER_REFERENCE_ENTRY Ref, ParentRef;
if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
{
return( NULL);
}
- UserRefObjectCo(Wnd);
- UserRefObjectCo(WndParent);
+ UserRefObjectCo(Wnd, &Ref);
+ UserRefObjectCo(WndParent, &ParentRef);
WndOldParent = co_IntSetParent(Wnd, WndParent);
PWINSTATION_OBJECT WinStaObject;
PWINDOW_OBJECT WndShell;
DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
+ NTSTATUS Status;
DPRINT("Enter NtUserSetShellWindowEx\n");
UserEnterExclusive();
RETURN(FALSE);
}
- NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
+ Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode,
0,
&WinStaObject);
RETURN( FALSE);
}
- UserRefObjectCo(WndShell);
+ UserRefObjectCo(WndShell, &Ref);
co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
WinStaObject->ShellWindow = hwndShell;
/*
* Remove extended window style bit WS_EX_TOPMOST for shell windows.
*/
- WindowStation = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
+ WindowStation = ((PW32THREAD)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
if(WindowStation)
{
if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
}
Safepl.flags = 0;
- Safepl.showCmd = ((Window->Flags & WINDOWOBJECT_RESTOREMAX) ? SW_MAXIMIZE : SW_SHOWNORMAL);
+ if (0 == (Window->Style & WS_VISIBLE))
+ {
+ Safepl.showCmd = SW_HIDE;
+ }
+ else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+ 0 != (Window->Style & WS_MAXIMIZE))
+ {
+ Safepl.showCmd = SW_MAXIMIZE;
+ }
+ else if (0 != (Window->Style & WS_MINIMIZE))
+ {
+ Safepl.showCmd = SW_MINIMIZE;
+ }
+ else if (0 != (Window->Style & WS_MINIMIZE))
+ {
+ Safepl.showCmd = SW_SHOWNORMAL;
+ }
Size.x = Window->WindowRect.left;
Size.y = Window->WindowRect.top;
if (Changed && Repaint)
{
- UserRefObjectCo(Window);
+ USER_REFERENCE_ENTRY Ref;
+
+ UserRefObjectCo(Window, &Ref);
co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
WINDOWPLACEMENT Safepl;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserSetWindowPlacement\n");
UserEnterExclusive();
RETURN( FALSE);
}
- UserRefObjectCo(Window);
+ UserRefObjectCo(Window, &Ref);
if ((Window->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
{
DECLARE_RETURN(BOOL);
PWINDOW_OBJECT Window;
BOOL ret;
+ USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserSetWindowPos\n");
UserEnterExclusive();
RETURN(FALSE);
}
- UserRefObjectCo(Window);
+ UserRefObjectCo(Window, &Ref);
ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
UserDerefObjectCo(Window);
if(bRedraw)
{
- UserRefObjectCo(Window);
+ USER_REFERENCE_ENTRY Ref;
+ UserRefObjectCo(Window, &Ref);
co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
UserDerefObjectCo(Window);
}
PWINDOW_OBJECT Window;
BOOL ret;
DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserShowWindow\n");
UserEnterExclusive();
RETURN(FALSE);
}
- UserRefObjectCo(Window);
+ UserRefObjectCo(Window, &Ref);
ret = co_WinPosShowWindow(Window, nCmdShow);
UserDerefObjectCo(Window);
/*
* @unimplemented
*/
-DWORD STDCALL
-NtUserShowWindowAsync(DWORD Unknown0,
- DWORD Unknown1)
+BOOL STDCALL
+NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
{
+#if 0
UNIMPLEMENTED
-
return 0;
+#else
+ return NtUserShowWindow(hWnd, nCmdShow);
+#endif
}
}
-/*
- * @implemented
- */
-VOID STDCALL
-NtUserValidateRect(HWND hWnd, const RECT* Rect)
-{
- return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
-}
/*
HWND Ret;
PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
DECLARE_RETURN(HWND);
+ USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserWindowFromPoint\n");
UserEnterExclusive();
//hmm... threads live on desktops thus we have a reference on the desktop and indirectly the desktop window
//its possible this referencing is useless, thou it shouldnt hurt...
- UserRefObjectCo(DesktopWindow);
+ UserRefObjectCo(DesktopWindow, &Ref);
Hit = co_WinPosWindowFromPoint(DesktopWindow, PsGetWin32Thread()->MessageQueue, &pt, &Window);
NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data)
{
DECLARE_RETURN(DWORD);
+ WndProcHandle Entry;
DPRINT("Enter NtUserDereferenceWndProcHandle\n");
UserEnterShared();
- WndProcHandle Entry;
if (((DWORD)wpHandle & 0xFFFF0000) == 0xFFFF0000)
{
Entry = WndProcHandlesArray[(DWORD)wpHandle & 0x0000FFFF];