ReactOS 0.4.15-dev-8419-g7f0e8a3
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
15
18
20
21/*
22 * GhostThreadMain
23 *
24 * Creates ghost windows and exits when no non-responsive window remains.
25 */
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{
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 {
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, MSQ_HUNG))
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}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
_Out_ RTL_ATOM * Atom
Definition: class.h:54
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
#define Len
Definition: deflate.h:82
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
PSERVERINFO gpsi
Definition: imm.c:18
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GHOSTCLASSNAME
Definition: ghostwnd.h:10
#define GHOST_PROP
Definition: ghostwnd.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define FNID_DESTROY
Definition: ntuser.h:898
if(dx< 0)
Definition: linetemp.h:194
struct tagUserData UserData
unsigned short RTL_ATOM
Definition: atom.c:42
BOOL FASTCALL MsqIsHung(PTHREADINFO pti, DWORD TimeOut)
Definition: msgqueue.c:2143
#define MSQ_HUNG
Definition: msgqueue.h:3
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define FASTCALL
Definition: nt_native.h:50
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
HWND FASTCALL UserHungWindowFromGhostWindow(HWND hwndGhost)
Definition: ghost.c:150
HWND FASTCALL IntGhostWindowFromHungWindow(PWND pHungWnd)
Definition: ghost.c:76
static UNICODE_STRING GhostClass
Definition: ghost.c:16
BOOL FASTCALL IntMakeHungWindowGhosted(HWND hwndHung)
Definition: ghost.c:156
PTHREADINFO gptiGhostThread
Definition: ghost.c:19
HWND FASTCALL IntHungWindowFromGhostWindow(PWND pGhostWnd)
Definition: ghost.c:107
BOOL FASTCALL IntIsGhostWindow(PWND Window)
Definition: ghost.c:42
HWND FASTCALL UserGhostWindowFromHungWindow(HWND hwndHung)
Definition: ghost.c:96
VOID NTAPI UserGhostThreadEntry(VOID)
Definition: ghost.c:27
static UNICODE_STRING GhostProp
Definition: ghost.c:17
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define WS_CHILD
Definition: pedump.c:617
#define WS_VISIBLE
Definition: pedump.c:620
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define DPRINT
Definition: sndvol32.h:73
#define TRACE(s)
Definition: solgame.cpp:4
Definition: window.c:28
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
DWORD style
Definition: ntuser.h:706
LONG_PTR dwUserData
Definition: ntuser.h:741
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1060
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
INT UserGetClassName(IN PCLS Class, IN OUT PUNICODE_STRING ClassName, IN RTL_ATOM Atom, IN BOOL Ansi)
Definition: class.c:1645
BOOL FASTCALL LookupFnIdToiCls(int FnId, int *iCls)
Definition: class.c:131
#define ST_GHOST_THREAD
Definition: csr.h:37
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46