ReactOS  0.4.13-dev-92-gf251225
ghost.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS user32.dll
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Window ghosting feature
5  * COPYRIGHT: Copyright 2018 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6  */
7 
8 #include <win32k.h>
9 #include "ghostwnd.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 DBG_DEFAULT_CHANNEL(UserInput);
15 
18 
20 
21 /*
22  * GhostThreadMain
23  *
24  * Creates ghost windows and exits when no non-responsive window remains.
25  */
26 VOID NTAPI
28 {
29  TRACE("Ghost thread started\n");
30 
32 
34 
35  //TODO: Implement. This thread should handle all ghost windows and exit when no ghost window is needed.
36 
38 
39  UserLeave();
40 }
41 
43 {
44  BOOLEAN Ret = FALSE;
45  UNICODE_STRING ClassName;
46  INT iCls, Len;
47  RTL_ATOM Atom = 0;
48 
49  if (!Window)
50  return FALSE;
51 
52  if (Window->fnid && !(Window->fnid & FNID_DESTROY))
53  {
54  if (LookupFnIdToiCls(Window->fnid, &iCls))
55  {
56  Atom = gpsi->atomSysClass[iCls];
57  }
58  }
59 
60  // check class name
61  RtlInitUnicodeString(&ClassName, NULL);
62  Len = UserGetClassName(Window->pcls, &ClassName, Atom, FALSE);
63  if (Len > 0)
64  {
65  Ret = RtlEqualUnicodeString(&ClassName, &GhostClass, TRUE);
66  }
67  else
68  {
69  DPRINT1("Unable to get class name\n");
70  }
71  RtlFreeUnicodeString(&ClassName);
72 
73  return Ret;
74 }
75 
77 {
78  RTL_ATOM Atom;
79  HWND hwndGhost;
80 
81  if (!IntGetAtomFromStringOrAtom(&GhostProp, &Atom))
82  return NULL;
83 
84  hwndGhost = UserGetProp(pHungWnd, Atom, TRUE);
85  if (hwndGhost)
86  {
87  if (ValidateHwndNoErr(hwndGhost))
88  return hwndGhost;
89 
90  DPRINT("Not a window\n");
91  }
92 
93  return NULL;
94 }
95 
97 {
98  PWND pHungWnd = ValidateHwndNoErr(hwndHung);
99  if (!pHungWnd)
100  {
101  DPRINT("Not a window\n");
102  return NULL;
103  }
104  return IntGhostWindowFromHungWindow(pHungWnd);
105 }
106 
108 {
109  const GHOST_DATA *UserData;
110  HWND hwndTarget;
111 
112  if (!IntIsGhostWindow(pGhostWnd))
113  {
114  DPRINT("Not a ghost window\n");
115  return NULL;
116  }
117 
118  UserData = (const GHOST_DATA *)pGhostWnd->dwUserData;
119  if (UserData)
120  {
121  _SEH2_TRY
122  {
123  ProbeForRead(UserData, sizeof(GHOST_DATA), 1);
124  hwndTarget = UserData->hwndTarget;
125  }
127  {
128  DPRINT1("Exception!\n");
129  hwndTarget = NULL;
130  }
131  _SEH2_END;
132  }
133  else
134  {
135  DPRINT("No user data\n");
136  hwndTarget = NULL;
137  }
138 
139  if (hwndTarget)
140  {
141  if (ValidateHwndNoErr(hwndTarget))
142  return hwndTarget;
143 
144  DPRINT1("Not a window\n");
145  }
146 
147  return NULL;
148 }
149 
151 {
152  PWND pGhostWnd = ValidateHwndNoErr(hwndGhost);
153  return IntHungWindowFromGhostWindow(pGhostWnd);
154 }
155 
157 {
158  PWND pHungWnd = ValidateHwndNoErr(hwndHung);
159  if (!pHungWnd)
160  {
161  DPRINT1("Not a window\n");
162  return FALSE; // not a window
163  }
164 
165  if (!MsqIsHung(pHungWnd->head.pti))
166  {
167  DPRINT1("Not hung window\n");
168  return FALSE; // not hung window
169  }
170 
171  if (!(pHungWnd->style & WS_VISIBLE))
172  return FALSE; // invisible
173 
174  if (pHungWnd->style & WS_CHILD)
175  return FALSE; // child
176 
177  if (IntIsGhostWindow(pHungWnd))
178  {
179  DPRINT1("IntIsGhostWindow\n");
180  return FALSE; // ghost window cannot be ghosted
181  }
182 
183  if (IntGhostWindowFromHungWindow(pHungWnd))
184  {
185  DPRINT("Already ghosting\n");
186  return FALSE; // already ghosting
187  }
188 
189  // TODO: Find a way to pass the hwnd of pHungWnd to the ghost thread as we can't pass parameters directly
190 
191  if (!gptiGhostThread)
193 
194  return TRUE;
195 }
#define TRUE
Definition: types.h:120
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
Definition: window.c:96
unsigned short RTL_ATOM
Definition: atom.c:42
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
BOOL FASTCALL MsqIsHung(PTHREADINFO pti)
Definition: msgqueue.c:2194
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
static UNICODE_STRING GhostProp
Definition: ghost.c:17
DBG_DEFAULT_CHANNEL(UserInput)
#define WS_CHILD
Definition: pedump.c:617
#define FNID_DESTROY
Definition: ntuser.h:859
_Out_ RTL_ATOM * Atom
Definition: class.h:54
#define FASTCALL
Definition: nt_native.h:50
PSERVERINFO gpsi
Definition: main.c:27
int32_t INT
Definition: typedefs.h:56
_SEH2_TRY
Definition: create.c:4250
Definition: window.c:29
HWND FASTCALL IntHungWindowFromGhostWindow(PWND pGhostWnd)
Definition: ghost.c:107
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
THRDESKHEAD head
Definition: ntuser.h:659
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
INT UserGetClassName(IN PCLS Class, IN OUT PUNICODE_STRING ClassName, IN RTL_ATOM Atom, IN BOOL Ansi)
Definition: class.c:1604
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define TRACE(s)
Definition: solgame.cpp:4
#define GHOSTCLASSNAME
Definition: ghostwnd.h:10
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define ST_GHOST_THREAD
Definition: csr.h:37
struct tagUserData UserData
BOOL FASTCALL IntIsGhostWindow(PWND Window)
Definition: ghost.c:42
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
#define Len
Definition: deflate.h:82
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PTHREADINFO gptiGhostThread
Definition: ghost.c:19
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
HWND FASTCALL IntGhostWindowFromHungWindow(PWND pHungWnd)
Definition: ghost.c:76
#define GHOST_PROP
Definition: ghostwnd.h:11
BOOL FASTCALL IntMakeHungWindowGhosted(HWND hwndHung)
Definition: ghost.c:156
Definition: ntuser.h:657
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
LONG_PTR dwUserData
Definition: ntuser.h:705
HWND FASTCALL UserGhostWindowFromHungWindow(HWND hwndHung)
Definition: ghost.c:96
BOOL FASTCALL LookupFnIdToiCls(int FnId, int *iCls)
Definition: class.c:131
#define DPRINT1
Definition: precomp.h:8
static UNICODE_STRING GhostClass
Definition: ghost.c:16
VOID NTAPI UserGhostThreadEntry(VOID)
Definition: ghost.c:27
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
HWND FASTCALL UserHungWindowFromGhostWindow(HWND hwndGhost)
Definition: ghost.c:150
#define WS_VISIBLE
Definition: pedump.c:620
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1013
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
DWORD style
Definition: ntuser.h:670