xref: /reactos/win32ss/user/ntuser/ntuser.c (revision 4093d0e1)
1 /*
2  *  COPYRIGHT:        See COPYING in the top level directory
3  *  PROJECT:          ReactOS kernel
4  *  PURPOSE:          ntuser init. and main funcs.
5  *  FILE:             win32ss/user/ntuser/ntuser.c
6  */
7 
8 #include <win32k.h>
9 DBG_DEFAULT_CHANNEL(UserMisc);
10 
11 BOOL FASTCALL RegisterControlAtoms(VOID);
12 
13 /* GLOBALS ********************************************************************/
14 
15 PTHREADINFO gptiCurrent = NULL;
16 PPROCESSINFO gppiInputProvider = NULL;
17 BOOL g_AlwaysDisplayVersion = FALSE;
18 ERESOURCE UserLock;
19 ATOM AtomMessage;       // Window Message atom.
20 ATOM AtomWndObj;        // Window Object atom.
21 ATOM AtomLayer;         // Window Layer atom.
22 ATOM AtomFlashWndState; // Window Flash State atom.
23 ATOM AtomDDETrack;      // Window DDE Tracking atom.
24 ATOM AtomQOS;           // Window DDE Quality of Service atom.
25 HINSTANCE hModClient = NULL;
26 BOOL ClientPfnInit = FALSE;
27 ATOM gaGuiConsoleWndClass;
28 ATOM AtomImeLevel;
29 
30 /* PRIVATE FUNCTIONS **********************************************************/
31 
32 static
33 NTSTATUS FASTCALL
InitUserAtoms(VOID)34 InitUserAtoms(VOID)
35 {
36     RegisterControlAtoms();
37 
38     gpsi->atomSysClass[ICLS_MENU]      = 32768;
39     gpsi->atomSysClass[ICLS_DESKTOP]   = 32769;
40     gpsi->atomSysClass[ICLS_DIALOG]    = 32770;
41     gpsi->atomSysClass[ICLS_SWITCH]    = 32771;
42     gpsi->atomSysClass[ICLS_ICONTITLE] = 32772;
43     gpsi->atomSysClass[ICLS_TOOLTIPS]  = 32774;
44 
45     /* System Message Atom */
46     AtomMessage = IntAddGlobalAtom(L"Message", TRUE);
47     gpsi->atomSysClass[ICLS_HWNDMESSAGE] = AtomMessage;
48 
49     /* System Context Help Id Atom */
50     gpsi->atomContextHelpIdProp = IntAddGlobalAtom(L"SysCH", TRUE);
51 
52     gpsi->atomIconSmProp = IntAddGlobalAtom(L"SysICS", TRUE);
53     gpsi->atomIconProp   = IntAddGlobalAtom(L"SysIC", TRUE);
54 
55     gpsi->atomFrostedWindowProp = IntAddGlobalAtom(L"SysFrostedWindow", TRUE);
56 
57     AtomDDETrack = IntAddGlobalAtom(L"SysDT", TRUE);
58     AtomQOS      = IntAddGlobalAtom(L"SysQOS", TRUE);
59     AtomImeLevel = IntAddGlobalAtom(L"SysIMEL", TRUE);
60 
61     /*
62      * FIXME: AddPropW uses the global kernel atom table, thus leading to conflicts if we use
63      * the win32k atom table for this one. What is the right thing to do ?
64      */
65     // AtomWndObj = IntAddGlobalAtom(L"SysWNDO", TRUE);
66     NtAddAtom(L"SysWNDO", 14, &AtomWndObj);
67 
68     AtomLayer = IntAddGlobalAtom(L"SysLayer", TRUE);
69     AtomFlashWndState = IntAddGlobalAtom(L"FlashWState", TRUE);
70 
71     return STATUS_SUCCESS;
72 }
73 
74 /* FUNCTIONS ******************************************************************/
75 
76 CODE_SEG("INIT")
77 NTSTATUS
78 NTAPI
InitUserImpl(VOID)79 InitUserImpl(VOID)
80 {
81     NTSTATUS Status;
82     HKEY hKey;
83 
84     if (!UserCreateHandleTable())
85     {
86         ERR("Failed creating handle table\n");
87         return STATUS_INSUFFICIENT_RESOURCES;
88     }
89 
90     Status = InitSessionImpl();
91     if (!NT_SUCCESS(Status))
92     {
93         ERR("Error init session impl.\n");
94         return Status;
95     }
96 
97     InitUserAtoms();
98 
99     Status = RegOpenKey(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
100                         &hKey);
101     if (NT_SUCCESS(Status))
102     {
103         DWORD dwValue = 0;
104         RegReadDWORD(hKey, L"DisplayVersion", &dwValue);
105         g_AlwaysDisplayVersion = !!dwValue;
106         ZwClose(hKey);
107     }
108 
109     InitSysParams();
110 
111     return STATUS_SUCCESS;
112 }
113 
114 NTSTATUS
115 NTAPI
UserInitialize(VOID)116 UserInitialize(VOID)
117 {
118     static const DWORD wPattern55AA[] = /* 32 bit aligned */
119     { 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
120       0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa };
121     HBITMAP hPattern55AABitmap = NULL;
122     NTSTATUS Status;
123 
124     NT_ASSERT(PsGetCurrentThreadWin32Thread() != NULL);
125 
126 // Create Event for Disconnect Desktop.
127 
128     Status = UserCreateWinstaDirectory();
129     if (!NT_SUCCESS(Status)) return Status;
130 
131     /* Initialize the Video */
132     Status = InitVideo();
133     if (!NT_SUCCESS(Status))
134     {
135         /* We failed, bugcheck */
136         KeBugCheckEx(VIDEO_DRIVER_INIT_FAILURE, Status, 0, 0, USER_VERSION);
137     }
138 
139 // {
140 //     DrvInitConsole.
141 //     DrvChangeDisplaySettings.
142 //     Update Shared Device Caps.
143 //     Initialize User Screen.
144 // }
145 
146 // Set Global SERVERINFO Error flags.
147 // Load Resources.
148 
149     NtUserUpdatePerUserSystemParameters(0, TRUE);
150 
151     if (gpsi->hbrGray == NULL)
152     {
153         hPattern55AABitmap = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)wPattern55AA);
154         if (hPattern55AABitmap == NULL)
155             return STATUS_INSUFFICIENT_RESOURCES;
156 
157         gpsi->hbrGray = IntGdiCreatePatternBrush(hPattern55AABitmap);
158 
159         if (gpsi->hbrGray == NULL)
160             return STATUS_INSUFFICIENT_RESOURCES;
161     }
162 
163     return STATUS_SUCCESS;
164 }
165 
166 /*
167  * Called from usersrv.
168  */
169 NTSTATUS
170 APIENTRY
NtUserInitialize(DWORD dwWinVersion,HANDLE hPowerRequestEvent,HANDLE hMediaRequestEvent)171 NtUserInitialize(
172     DWORD  dwWinVersion,
173     HANDLE hPowerRequestEvent,
174     HANDLE hMediaRequestEvent)
175 {
176     NTSTATUS Status;
177 
178     TRACE("Enter NtUserInitialize(%lx, %p, %p)\n",
179           dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
180 
181     /* Check if we are already initialized */
182     if (gpepCSRSS)
183         return STATUS_UNSUCCESSFUL;
184 
185     /* Check Windows USER subsystem version */
186     if (dwWinVersion != USER_VERSION)
187     {
188         /* No match, bugcheck */
189         KeBugCheckEx(WIN32K_INIT_OR_RIT_FAILURE, 0, 0, dwWinVersion, USER_VERSION);
190     }
191 
192     /* Acquire exclusive lock */
193     UserEnterExclusive();
194 
195     /* Save the EPROCESS of CSRSS */
196     InitCsrProcess(/*PsGetCurrentProcess()*/);
197 
198     /* Initialize Power Request List */
199     Status = IntInitWin32PowerManagement(hPowerRequestEvent);
200     if (!NT_SUCCESS(Status))
201     {
202         UserLeave();
203         return Status;
204     }
205 
206 // Initialize Media Change (use hMediaRequestEvent).
207 
208     /* Initialize various GDI stuff (DirectX, fonts, language ID etc.) */
209     if (!InitializeGreCSRSS())
210         return STATUS_UNSUCCESSFUL;
211 
212     /* Initialize USER */
213     Status = UserInitialize();
214 
215     /* Return */
216     UserLeave();
217     return Status;
218 }
219 
220 
221 /*
222 RETURN
223    True if current thread owns the lock (possibly shared)
224 */
UserIsEntered(VOID)225 BOOL FASTCALL UserIsEntered(VOID)
226 {
227     return ExIsResourceAcquiredExclusiveLite(&UserLock) ||
228            ExIsResourceAcquiredSharedLite(&UserLock);
229 }
230 
UserIsEnteredExclusive(VOID)231 BOOL FASTCALL UserIsEnteredExclusive(VOID)
232 {
233     return ExIsResourceAcquiredExclusiveLite(&UserLock);
234 }
235 
CleanupUserImpl(VOID)236 VOID FASTCALL CleanupUserImpl(VOID)
237 {
238     ExDeleteResourceLite(&UserLock);
239 }
240 
241 // Win: EnterSharedCrit
UserEnterShared(VOID)242 VOID FASTCALL UserEnterShared(VOID)
243 {
244     KeEnterCriticalRegion();
245     ExAcquireResourceSharedLite(&UserLock, TRUE);
246 }
247 
248 // Win: EnterCrit
UserEnterExclusive(VOID)249 VOID FASTCALL UserEnterExclusive(VOID)
250 {
251     ASSERT_NOGDILOCKS();
252     KeEnterCriticalRegion();
253     ExAcquireResourceExclusiveLite(&UserLock, TRUE);
254     gptiCurrent = PsGetCurrentThreadWin32Thread();
255 }
256 
257 // Win: LeaveCrit
UserLeave(VOID)258 VOID FASTCALL UserLeave(VOID)
259 {
260     ASSERT_NOGDILOCKS();
261     ASSERT(UserIsEntered());
262     ExReleaseResourceLite(&UserLock);
263     KeLeaveCriticalRegion();
264 }
265 
266 /* EOF */
267