2015-01-08 01:00:03 +00:00
|
|
|
/*
|
2006-11-08 11:47:44 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: ntuser init. and main funcs.
|
2014-12-27 19:16:05 +00:00
|
|
|
* FILE: win32ss/user/ntuser/ntuser.c
|
2006-11-08 11:47:44 +00:00
|
|
|
*/
|
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
2011-08-21 12:38:52 +00:00
|
|
|
DBG_DEFAULT_CHANNEL(UserMisc);
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2015-01-05 22:32:16 +00:00
|
|
|
BOOL FASTCALL RegisterControlAtoms(VOID);
|
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
/* GLOBALS ********************************************************************/
|
2009-07-13 03:49:58 +00:00
|
|
|
|
2011-08-22 19:58:32 +00:00
|
|
|
PTHREADINFO gptiCurrent = NULL;
|
2012-04-21 18:18:59 +00:00
|
|
|
PPROCESSINFO gppiInputProvider = NULL;
|
2016-06-01 15:24:38 +00:00
|
|
|
BOOL g_AlwaysDisplayVersion = FALSE;
|
2007-02-28 13:21:48 +00:00
|
|
|
ERESOURCE UserLock;
|
2015-01-08 00:56:51 +00:00
|
|
|
ATOM AtomMessage; // Window Message atom.
|
|
|
|
ATOM AtomWndObj; // Window Object atom.
|
|
|
|
ATOM AtomLayer; // Window Layer atom.
|
2011-08-22 19:58:32 +00:00
|
|
|
ATOM AtomFlashWndState; // Window Flash State atom.
|
2015-01-08 00:56:51 +00:00
|
|
|
ATOM AtomDDETrack; // Window DDE Tracking atom.
|
|
|
|
ATOM AtomQOS; // Window DDE Quality of Service atom.
|
2009-07-13 03:49:58 +00:00
|
|
|
HINSTANCE hModClient = NULL;
|
2009-07-23 01:34:31 +00:00
|
|
|
BOOL ClientPfnInit = FALSE;
|
2013-01-04 00:41:10 +00:00
|
|
|
ATOM gaGuiConsoleWndClass;
|
2022-01-26 22:29:19 +00:00
|
|
|
ATOM AtomImeLevel;
|
2009-06-25 02:43:38 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2009-07-13 03:49:58 +00:00
|
|
|
static
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
InitUserAtoms(VOID)
|
|
|
|
{
|
2015-01-05 22:32:16 +00:00
|
|
|
RegisterControlAtoms();
|
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
gpsi->atomSysClass[ICLS_MENU] = 32768;
|
|
|
|
gpsi->atomSysClass[ICLS_DESKTOP] = 32769;
|
|
|
|
gpsi->atomSysClass[ICLS_DIALOG] = 32770;
|
|
|
|
gpsi->atomSysClass[ICLS_SWITCH] = 32771;
|
|
|
|
gpsi->atomSysClass[ICLS_ICONTITLE] = 32772;
|
|
|
|
gpsi->atomSysClass[ICLS_TOOLTIPS] = 32774;
|
|
|
|
|
|
|
|
/* System Message Atom */
|
|
|
|
AtomMessage = IntAddGlobalAtom(L"Message", TRUE);
|
|
|
|
gpsi->atomSysClass[ICLS_HWNDMESSAGE] = AtomMessage;
|
|
|
|
|
|
|
|
/* System Context Help Id Atom */
|
|
|
|
gpsi->atomContextHelpIdProp = IntAddGlobalAtom(L"SysCH", TRUE);
|
|
|
|
|
|
|
|
gpsi->atomIconSmProp = IntAddGlobalAtom(L"SysICS", TRUE);
|
|
|
|
gpsi->atomIconProp = IntAddGlobalAtom(L"SysIC", TRUE);
|
|
|
|
|
|
|
|
gpsi->atomFrostedWindowProp = IntAddGlobalAtom(L"SysFrostedWindow", TRUE);
|
|
|
|
|
2015-01-05 22:32:16 +00:00
|
|
|
AtomDDETrack = IntAddGlobalAtom(L"SysDT", TRUE);
|
2015-01-08 00:56:51 +00:00
|
|
|
AtomQOS = IntAddGlobalAtom(L"SysQOS", TRUE);
|
2022-01-26 22:29:19 +00:00
|
|
|
AtomImeLevel = IntAddGlobalAtom(L"SysIMEL", TRUE);
|
2015-01-05 22:32:16 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
/*
|
|
|
|
* FIXME: AddPropW uses the global kernel atom table, thus leading to conflicts if we use
|
2015-01-05 22:32:16 +00:00
|
|
|
* the win32k atom table for this one. What is the right thing to do ?
|
2014-12-27 19:16:05 +00:00
|
|
|
*/
|
|
|
|
// AtomWndObj = IntAddGlobalAtom(L"SysWNDO", TRUE);
|
|
|
|
NtAddAtom(L"SysWNDO", 14, &AtomWndObj);
|
2015-01-05 22:32:16 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
AtomLayer = IntAddGlobalAtom(L"SysLayer", TRUE);
|
|
|
|
AtomFlashWndState = IntAddGlobalAtom(L"FlashWState", TRUE);
|
2009-07-13 03:49:58 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2009-07-13 03:49:58 +00:00
|
|
|
}
|
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2020-10-06 19:44:01 +00:00
|
|
|
CODE_SEG("INIT")
|
2010-11-03 00:51:19 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
InitUserImpl(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
NTSTATUS Status;
|
2016-06-01 15:24:38 +00:00
|
|
|
HKEY hKey;
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
if (!UserCreateHandleTable())
|
|
|
|
{
|
|
|
|
ERR("Failed creating handle table\n");
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
Status = InitSessionImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ERR("Error init session impl.\n");
|
|
|
|
return Status;
|
|
|
|
}
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
InitUserAtoms();
|
2009-07-13 03:49:58 +00:00
|
|
|
|
2016-06-01 15:24:38 +00:00
|
|
|
Status = RegOpenKey(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
|
|
|
|
&hKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DWORD dwValue = 0;
|
|
|
|
RegReadDWORD(hKey, L"DisplayVersion", &dwValue);
|
|
|
|
g_AlwaysDisplayVersion = !!dwValue;
|
|
|
|
ZwClose(hKey);
|
|
|
|
}
|
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
InitSysParams();
|
2009-06-25 02:43:38 +00:00
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2014-12-17 00:33:40 +00:00
|
|
|
UserInitialize(VOID)
|
2009-06-25 02:43:38 +00:00
|
|
|
{
|
2011-05-24 16:23:36 +00:00
|
|
|
static const DWORD wPattern55AA[] = /* 32 bit aligned */
|
|
|
|
{ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
|
|
|
|
0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa };
|
2011-05-21 06:34:02 +00:00
|
|
|
HBITMAP hPattern55AABitmap = NULL;
|
2010-11-03 12:20:07 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2015-10-15 09:44:20 +00:00
|
|
|
NT_ASSERT(PsGetCurrentThreadWin32Thread() != NULL);
|
|
|
|
|
|
|
|
// Create Event for Disconnect Desktop.
|
2010-11-03 12:20:07 +00:00
|
|
|
|
2013-01-04 00:41:10 +00:00
|
|
|
Status = UserCreateWinstaDirectory();
|
2012-02-24 15:22:11 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2019-01-05 15:50:32 +00:00
|
|
|
/* Initialize the Video */
|
2010-11-03 12:20:07 +00:00
|
|
|
Status = InitVideo();
|
2019-01-05 15:50:32 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed, bugcheck */
|
|
|
|
KeBugCheckEx(VIDEO_DRIVER_INIT_FAILURE, Status, 0, 0, USER_VERSION);
|
|
|
|
}
|
2010-11-03 12:20:07 +00:00
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
// {
|
|
|
|
// DrvInitConsole.
|
|
|
|
// DrvChangeDisplaySettings.
|
|
|
|
// Update Shared Device Caps.
|
|
|
|
// Initialize User Screen.
|
|
|
|
// }
|
2009-08-17 00:30:25 +00:00
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
// Set Global SERVERINFO Error flags.
|
|
|
|
// Load Resources.
|
|
|
|
|
|
|
|
NtUserUpdatePerUserSystemParameters(0, TRUE);
|
|
|
|
|
2011-05-21 06:34:02 +00:00
|
|
|
if (gpsi->hbrGray == NULL)
|
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
hPattern55AABitmap = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)wPattern55AA);
|
2015-03-25 22:38:20 +00:00
|
|
|
if (hPattern55AABitmap == NULL)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
2014-12-27 19:16:05 +00:00
|
|
|
gpsi->hbrGray = IntGdiCreatePatternBrush(hPattern55AABitmap);
|
2017-02-20 10:10:37 +00:00
|
|
|
|
2015-03-25 22:38:20 +00:00
|
|
|
if (gpsi->hbrGray == NULL)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
2011-05-21 06:34:02 +00:00
|
|
|
}
|
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2014-12-17 00:33:40 +00:00
|
|
|
* Called from usersrv.
|
2009-06-25 02:43:38 +00:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
APIENTRY
|
|
|
|
NtUserInitialize(
|
2014-12-27 19:16:05 +00:00
|
|
|
DWORD dwWinVersion,
|
|
|
|
HANDLE hPowerRequestEvent,
|
|
|
|
HANDLE hMediaRequestEvent)
|
2009-06-25 02:43:38 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2014-11-02 11:30:14 +00:00
|
|
|
TRACE("Enter NtUserInitialize(%lx, %p, %p)\n",
|
|
|
|
dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
|
2009-06-25 02:43:38 +00:00
|
|
|
|
2014-12-17 00:33:40 +00:00
|
|
|
/* Check if we are already initialized */
|
|
|
|
if (gpepCSRSS)
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
/* Check Windows USER subsystem version */
|
|
|
|
if (dwWinVersion != USER_VERSION)
|
2009-06-25 02:43:38 +00:00
|
|
|
{
|
2019-01-05 15:50:32 +00:00
|
|
|
/* No match, bugcheck */
|
|
|
|
KeBugCheckEx(WIN32K_INIT_OR_RIT_FAILURE, 0, 0, dwWinVersion, USER_VERSION);
|
2009-06-25 02:43:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Acquire exclusive lock */
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2014-12-17 00:33:40 +00:00
|
|
|
/* Save the EPROCESS of CSRSS */
|
[WIN32K]
Reintroduce CSR support for kernel mode, based on code from Ge that was wiped out in revision 58770, and by ntdll CSR code. Is needed for kernel to user-mode CSR callbacks.
For readers, I remind you the big callback picture in the Win32 subsystem:
- In Windows NT 3.1 and 3.51, USER and GDI was modeled against client/server model (USER32.DLL and WINSRV.DLL, and GDI32.DLL and GDISRV.DLL), all running in user mode (using the CSR API).
- Starting Windows NT 4.0 (and up), some USER and GDI parts were moved into kernel mode (in the WIN32K.SYS driver) to speedup communication. We get:
* GDI32.DLL as the client, doing win32k system calls (kernel-mode system calls to win32k),
* and USER32.DLL, WINSRV.DLL and WIN32K.SYS working in tandem, USER32.DLL being the client and {WINSRV.DLL, WIN32K.SYS} being the server.
USER32.DLL can do win32k system calls or CSR calls to WINSRV.DLL (client to server calls). For server-to-server calls, we have WINSRV.DLL
doing win32k system calls, or WIN32K.SYS doing CSR calls back to WINSRV.DLL . Also, there is the possibility for WIN32K.SYS to make user-mode
callbacks to USER32.DLL.
svn path=/trunk/; revision=65817
2014-12-23 21:17:24 +00:00
|
|
|
InitCsrProcess(/*PsGetCurrentProcess()*/);
|
2012-10-01 23:10:10 +00:00
|
|
|
|
2014-12-17 00:33:40 +00:00
|
|
|
// Initialize Power Request List (use hPowerRequestEvent).
|
|
|
|
// Initialize Media Change (use hMediaRequestEvent).
|
|
|
|
|
[NTGDI][NTUSER] Load DirectX graphics driver at system startup (#4551)
CORE-18221
Load the DirectX graphics kernel driver (dxg.sys) by win32k at WINSRV
initialization time, in NtUserInitialize(). Keep it always loaded in
memory, as on Windows, instead of loading it only by DirectX dlls.
This fixes the problem of acessing this driver: we need only to call
DxDdEnableDirectDraw() and do other stuff when DirectDraw/Direct3D is
required by anything. In other cases, it is called from win32k PDEV
functions when changing display mode (as in Windows). Since it's used
by other things too, it needs to be always loaded.
Otherwise, if it's not loaded, its APIs are not accessible when needed,
and execution fails.
For example, it fixes display mode change problem in VMWare, when a
new mode fails to be applied. Indeed, when it manages DirectDraw stuff,
it calls DXG routines, and therefore fails if dxg.sys isn't loaded
in memory at this moment.
- Implement InitializeGreCSRSS() initialization routine, that initializes
supplemental NTGDI/GRE data once CSRSS and WINSRV are loaded:
* Call DxDdStartupDxGraphics() inside it, which loads dxg.sys.
* Additionally, move fonts and language ID initialization there, from
win32k!DriverEntry. Confirmed by analysis on Windows.
- Call InitializeGreCSRSS() in NtUserInitialize() main initialization routine
(called by WINSRV initialization).
Moved to NTGDI from previously NTUSER place:
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
2022-06-18 18:35:17 +00:00
|
|
|
/* Initialize various GDI stuff (DirectX, fonts, language ID etc.) */
|
|
|
|
if (!InitializeGreCSRSS())
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2009-06-25 02:43:38 +00:00
|
|
|
|
|
|
|
/* Initialize USER */
|
2014-12-17 00:33:40 +00:00
|
|
|
Status = UserInitialize();
|
2009-06-25 02:43:38 +00:00
|
|
|
|
|
|
|
/* Return */
|
|
|
|
UserLeave();
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-08 11:47:44 +00:00
|
|
|
/*
|
|
|
|
RETURN
|
|
|
|
True if current thread owns the lock (possibly shared)
|
|
|
|
*/
|
2009-08-24 20:09:58 +00:00
|
|
|
BOOL FASTCALL UserIsEntered(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
return ExIsResourceAcquiredExclusiveLite(&UserLock) ||
|
|
|
|
ExIsResourceAcquiredSharedLite(&UserLock);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 20:09:58 +00:00
|
|
|
BOOL FASTCALL UserIsEnteredExclusive(VOID)
|
2007-02-28 13:21:48 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
return ExIsResourceAcquiredExclusiveLite(&UserLock);
|
2007-02-28 13:21:48 +00:00
|
|
|
}
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2007-02-28 13:21:48 +00:00
|
|
|
VOID FASTCALL CleanupUserImpl(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
ExDeleteResourceLite(&UserLock);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2022-04-16 21:53:37 +00:00
|
|
|
// Win: EnterSharedCrit
|
2007-02-28 13:21:48 +00:00
|
|
|
VOID FASTCALL UserEnterShared(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
KeEnterCriticalRegion();
|
|
|
|
ExAcquireResourceSharedLite(&UserLock, TRUE);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2022-04-16 21:53:37 +00:00
|
|
|
// Win: EnterCrit
|
2007-02-28 13:21:48 +00:00
|
|
|
VOID FASTCALL UserEnterExclusive(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
ASSERT_NOGDILOCKS();
|
|
|
|
KeEnterCriticalRegion();
|
|
|
|
ExAcquireResourceExclusiveLite(&UserLock, TRUE);
|
|
|
|
gptiCurrent = PsGetCurrentThreadWin32Thread();
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2022-04-16 21:53:37 +00:00
|
|
|
// Win: LeaveCrit
|
2007-02-28 13:21:48 +00:00
|
|
|
VOID FASTCALL UserLeave(VOID)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2014-12-27 19:16:05 +00:00
|
|
|
ASSERT_NOGDILOCKS();
|
|
|
|
ASSERT(UserIsEntered());
|
|
|
|
ExReleaseResourceLite(&UserLock);
|
|
|
|
KeLeaveCriticalRegion();
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
2014-12-27 19:16:05 +00:00
|
|
|
|
|
|
|
/* EOF */
|