[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.
This commit is contained in:
Hermès Bélusca-Maïto 2021-09-02 01:11:19 +02:00
parent a407cb8f10
commit 4cbc61fd02
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 58 additions and 23 deletions

View file

@ -553,14 +553,51 @@ NtUserProcessConnect(
_SEH2_TRY _SEH2_TRY
{ {
UINT i;
// FIXME: Check that pUserConnect->ulVersion == USER_VERSION; // FIXME: Check that pUserConnect->ulVersion == USER_VERSION;
// FIXME: Check the value of pUserConnect->dwDispatchCount.
ProbeForWrite(pUserConnect, sizeof(*pUserConnect), sizeof(PVOID)); 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 = pUserConnect->siClient.ulSharedDelta =
(ULONG_PTR)W32Process->HeapMappings.KernelMapping - (ULONG_PTR)W32Process->HeapMappings.KernelMapping -
(ULONG_PTR)W32Process->HeapMappings.UserMapping; (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) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {

View file

@ -39,13 +39,12 @@ typedef struct
extern HINSTANCE User32Instance; extern HINSTANCE User32Instance;
#define user32_module User32Instance #define user32_module User32Instance
extern PPROCESSINFO g_ppi; extern PPROCESSINFO g_ppi;
extern ULONG_PTR g_ulSharedDelta;
extern PSERVERINFO gpsi;
extern SHAREDINFO gSharedInfo; extern SHAREDINFO gSharedInfo;
extern BOOLEAN gfLogonProcess; extern PSERVERINFO gpsi;
extern BOOLEAN gfServerProcess;
extern PUSER_HANDLE_TABLE gHandleTable; extern PUSER_HANDLE_TABLE gHandleTable;
extern PUSER_HANDLE_ENTRY gHandleEntries; extern PUSER_HANDLE_ENTRY gHandleEntries;
extern BOOLEAN gfLogonProcess;
extern BOOLEAN gfServerProcess;
extern CRITICAL_SECTION U32AccelCacheLock; extern CRITICAL_SECTION U32AccelCacheLock;
extern HINSTANCE ghImm32; extern HINSTANCE ghImm32;
extern RTL_CRITICAL_SECTION gcsUserApiHook; extern RTL_CRITICAL_SECTION gcsUserApiHook;

View file

@ -4,8 +4,8 @@ static __inline PVOID
SharedPtrToUser(PVOID Ptr) SharedPtrToUser(PVOID Ptr)
{ {
ASSERT(Ptr != NULL); ASSERT(Ptr != NULL);
ASSERT(g_ulSharedDelta != 0); ASSERT(gSharedInfo.ulSharedDelta != 0);
return (PVOID)((ULONG_PTR)Ptr - g_ulSharedDelta); return (PVOID)((ULONG_PTR)Ptr - gSharedInfo.ulSharedDelta);
} }
static __inline PVOID static __inline PVOID

View file

@ -27,11 +27,10 @@ static ULONG User32TlsIndex;
HINSTANCE User32Instance; HINSTANCE User32Instance;
PPROCESSINFO g_ppi = NULL; PPROCESSINFO g_ppi = NULL;
SHAREDINFO gSharedInfo = {0};
PSERVERINFO gpsi = NULL;
PUSER_HANDLE_TABLE gHandleTable = NULL; PUSER_HANDLE_TABLE gHandleTable = NULL;
PUSER_HANDLE_ENTRY gHandleEntries = NULL; PUSER_HANDLE_ENTRY gHandleEntries = NULL;
PSERVERINFO gpsi = NULL;
SHAREDINFO gSharedInfo = {0};
ULONG_PTR g_ulSharedDelta;
BOOLEAN gfLogonProcess = FALSE; BOOLEAN gfLogonProcess = FALSE;
BOOLEAN gfServerProcess = FALSE; BOOLEAN gfServerProcess = FALSE;
BOOLEAN gfFirstThread = TRUE; BOOLEAN gfFirstThread = TRUE;
@ -271,6 +270,7 @@ ClientThreadSetupHelper(BOOL IsCallback)
/* Minimal setup of the connect info structure */ /* Minimal setup of the connect info structure */
UserCon.ulVersion = USER_VERSION; UserCon.ulVersion = USER_VERSION;
// UserCon.dwDispatchCount;
/* Connect to win32k */ /* Connect to win32k */
Status = NtUserProcessConnect(NtCurrentProcess(), Status = NtUserProcessConnect(NtCurrentProcess(),
@ -280,13 +280,13 @@ ClientThreadSetupHelper(BOOL IsCallback)
/* Retrieve data */ /* Retrieve data */
g_ppi = ClientInfo->ppi; // Snapshot PI, used as pointer only! 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; 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"); TRACE("Checkpoint (register PFN)\n");
@ -418,6 +418,7 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/)
/* Minimal setup of the connect info structure */ /* Minimal setup of the connect info structure */
UserCon->ulVersion = USER_VERSION; UserCon->ulVersion = USER_VERSION;
// UserCon->dwDispatchCount;
TRACE("HACK: Hackish NtUserProcessConnect call!!\n"); TRACE("HACK: Hackish NtUserProcessConnect call!!\n");
/* Connect to win32k */ /* Connect to win32k */
@ -433,12 +434,10 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/)
/* Retrieve data */ /* Retrieve data */
g_ppi = GetWin32ClientInfo()->ppi; // Snapshot PI, used as pointer only! 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 = 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 // FIXME: Yet another hack... This call should normally not be done here, but