From 4cbc61fd0264fb805fbd7c367c3136e9a95d70f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 2 Sep 2021 01:11:19 +0200 Subject: [PATCH] [WIN32SS:NTUSER][USER32] NtUserProcessConnect() should return pointers in user client-space. (#3937) - Do the kernel/server --> user/client-space pointers conversion within NtUserProcessConnect(), instead of having the callers of this function doing this job. This makes the behaviour Windows-compatible. NOTE: the gHandleEntries pointer is ReactOS-specific! - Drop the g_ulSharedDelta global, just use instead gSharedInfo.ulSharedDelta. - Add extra documentation aspects for NtUserProcessConnect() that are not yet implemented in ReactOS. --- win32ss/user/ntuser/ntstubs.c | 45 ++++++++++++++++++++++++--- win32ss/user/user32/include/user32p.h | 7 ++--- win32ss/user/user32/include/user_x.h | 4 +-- win32ss/user/user32/misc/dllmain.c | 25 +++++++-------- 4 files changed, 58 insertions(+), 23 deletions(-) diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c index c770f883e25..4de9ea36a58 100644 --- a/win32ss/user/ntuser/ntstubs.c +++ b/win32ss/user/ntuser/ntstubs.c @@ -531,8 +531,8 @@ NtUserProcessConnect( TRACE("NtUserProcessConnect\n"); - if ( pUserConnect == NULL || - Size != sizeof(*pUserConnect) ) + if (pUserConnect == NULL || + Size != sizeof(*pUserConnect)) { return STATUS_UNSUCCESSFUL; } @@ -553,14 +553,51 @@ NtUserProcessConnect( _SEH2_TRY { + UINT i; + // FIXME: Check that pUserConnect->ulVersion == USER_VERSION; + // FIXME: Check the value of pUserConnect->dwDispatchCount. ProbeForWrite(pUserConnect, sizeof(*pUserConnect), sizeof(PVOID)); - pUserConnect->siClient.psi = gpsi; - pUserConnect->siClient.aheList = gHandleTable; + + // FIXME: Instead of assuming that the mapping of the heap desktop + // also holds there, we **MUST** create and map instead the shared + // section! Its client base must be stored in W32Process->pClientBase. + // What is currently done (ReactOS-specific only), is that within the + // IntUserHeapCommitRoutine()/MapGlobalUserHeap() routines we assume + // it's going to be also called early, so that we manually add a very + // first memory mapping that corresponds to the "global user heap", + // and that we use instead of a actual win32 "shared USER section" + // (see slide 29 of https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2011/BH_US_11_Mandt_win32k_Slides.pdf ) + pUserConnect->siClient.ulSharedDelta = (ULONG_PTR)W32Process->HeapMappings.KernelMapping - (ULONG_PTR)W32Process->HeapMappings.UserMapping; + +#define SERVER_TO_CLIENT(ptr) \ + ((PVOID)((ULONG_PTR)ptr - pUserConnect->siClient.ulSharedDelta)) + + ASSERT(gpsi); + ASSERT(gHandleTable); + + pUserConnect->siClient.psi = SERVER_TO_CLIENT(gpsi); + pUserConnect->siClient.aheList = SERVER_TO_CLIENT(gHandleTable); + pUserConnect->siClient.pDispInfo = NULL; + + // NOTE: kernel server should also have a SHAREDINFO gSharedInfo; + // FIXME: These USER window-proc data should be used somehow! + + pUserConnect->siClient.DefWindowMsgs.maxMsgs = 0; + pUserConnect->siClient.DefWindowMsgs.abMsgs = NULL; + pUserConnect->siClient.DefWindowSpecMsgs.maxMsgs = 0; + pUserConnect->siClient.DefWindowSpecMsgs.abMsgs = NULL; + + for (i = 0; i < ARRAYSIZE(pUserConnect->siClient.awmControl); ++i) + { + pUserConnect->siClient.awmControl[i].maxMsgs = 0; + pUserConnect->siClient.awmControl[i].abMsgs = NULL; + } +#undef SERVER_TO_CLIENT } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { diff --git a/win32ss/user/user32/include/user32p.h b/win32ss/user/user32/include/user32p.h index f2616ff8f95..deb57148f78 100644 --- a/win32ss/user/user32/include/user32p.h +++ b/win32ss/user/user32/include/user32p.h @@ -39,13 +39,12 @@ typedef struct extern HINSTANCE User32Instance; #define user32_module User32Instance extern PPROCESSINFO g_ppi; -extern ULONG_PTR g_ulSharedDelta; -extern PSERVERINFO gpsi; extern SHAREDINFO gSharedInfo; -extern BOOLEAN gfLogonProcess; -extern BOOLEAN gfServerProcess; +extern PSERVERINFO gpsi; extern PUSER_HANDLE_TABLE gHandleTable; extern PUSER_HANDLE_ENTRY gHandleEntries; +extern BOOLEAN gfLogonProcess; +extern BOOLEAN gfServerProcess; extern CRITICAL_SECTION U32AccelCacheLock; extern HINSTANCE ghImm32; extern RTL_CRITICAL_SECTION gcsUserApiHook; diff --git a/win32ss/user/user32/include/user_x.h b/win32ss/user/user32/include/user_x.h index c040afefb9c..e7774e4e2f7 100644 --- a/win32ss/user/user32/include/user_x.h +++ b/win32ss/user/user32/include/user_x.h @@ -4,8 +4,8 @@ static __inline PVOID SharedPtrToUser(PVOID Ptr) { ASSERT(Ptr != NULL); - ASSERT(g_ulSharedDelta != 0); - return (PVOID)((ULONG_PTR)Ptr - g_ulSharedDelta); + ASSERT(gSharedInfo.ulSharedDelta != 0); + return (PVOID)((ULONG_PTR)Ptr - gSharedInfo.ulSharedDelta); } static __inline PVOID diff --git a/win32ss/user/user32/misc/dllmain.c b/win32ss/user/user32/misc/dllmain.c index b757ea22e9d..72f82aa1b43 100644 --- a/win32ss/user/user32/misc/dllmain.c +++ b/win32ss/user/user32/misc/dllmain.c @@ -27,11 +27,10 @@ static ULONG User32TlsIndex; HINSTANCE User32Instance; PPROCESSINFO g_ppi = NULL; +SHAREDINFO gSharedInfo = {0}; +PSERVERINFO gpsi = NULL; PUSER_HANDLE_TABLE gHandleTable = NULL; PUSER_HANDLE_ENTRY gHandleEntries = NULL; -PSERVERINFO gpsi = NULL; -SHAREDINFO gSharedInfo = {0}; -ULONG_PTR g_ulSharedDelta; BOOLEAN gfLogonProcess = FALSE; BOOLEAN gfServerProcess = FALSE; BOOLEAN gfFirstThread = TRUE; @@ -271,6 +270,7 @@ ClientThreadSetupHelper(BOOL IsCallback) /* Minimal setup of the connect info structure */ UserCon.ulVersion = USER_VERSION; + // UserCon.dwDispatchCount; /* Connect to win32k */ Status = NtUserProcessConnect(NtCurrentProcess(), @@ -280,13 +280,13 @@ ClientThreadSetupHelper(BOOL IsCallback) /* Retrieve data */ g_ppi = ClientInfo->ppi; // Snapshot PI, used as pointer only! - g_ulSharedDelta = UserCon.siClient.ulSharedDelta; - gpsi = SharedPtrToUser(UserCon.siClient.psi); - gHandleTable = SharedPtrToUser(UserCon.siClient.aheList); - gHandleEntries = SharedPtrToUser(gHandleTable->handles); gSharedInfo = UserCon.siClient; + gpsi = gSharedInfo.psi; + gHandleTable = gSharedInfo.aheList; + /* ReactOS-Specific! */ gHandleEntries = SharedPtrToUser(gHandleTable->handles); - // ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); + // ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", + // gSharedInfo.psi, gSharedInfo.aheList, gSharedInfo.ulSharedDelta); } TRACE("Checkpoint (register PFN)\n"); @@ -418,6 +418,7 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/) /* Minimal setup of the connect info structure */ UserCon->ulVersion = USER_VERSION; + // UserCon->dwDispatchCount; TRACE("HACK: Hackish NtUserProcessConnect call!!\n"); /* Connect to win32k */ @@ -433,12 +434,10 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/) /* Retrieve data */ g_ppi = GetWin32ClientInfo()->ppi; // Snapshot PI, used as pointer only! - g_ulSharedDelta = UserCon->siClient.ulSharedDelta; - gpsi = SharedPtrToUser(UserCon->siClient.psi); - gHandleTable = SharedPtrToUser(UserCon->siClient.aheList); - gHandleEntries = SharedPtrToUser(gHandleTable->handles); gSharedInfo = UserCon->siClient; - gSharedInfo.psi = gpsi; + gpsi = gSharedInfo.psi; + gHandleTable = gSharedInfo.aheList; + /* ReactOS-Specific! */ gHandleEntries = SharedPtrToUser(gHandleTable->handles); } // FIXME: Yet another hack... This call should normally not be done here, but