- Add global user heap (un)map helper functions that will be used in other portions of code.
- For consistency purpose also add the note about the mapping in desktop.c (see r65863 for what I mean).
- Temporarily add many trace messages.

svn path=/trunk/; revision=65891
This commit is contained in:
Hermès Bélusca-Maïto 2014-12-29 13:56:28 +00:00
parent 3793271edf
commit 7c39a4ecb6
7 changed files with 153 additions and 44 deletions

View file

@ -1849,9 +1849,13 @@ IntUnmapDesktopView(IN PDESKTOP pdesk)
TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk); TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
ppi = PsGetCurrentProcessWin32Process(); ppi = PsGetCurrentProcessWin32Process();
PrevLink = &ppi->HeapMappings.Next;
/* Unmap if we're the last thread using the desktop */ /*
* Unmap if we're the last thread using the desktop.
* Start the search at the next mapping: skip the first entry
* as it must be the global user heap mapping.
*/
PrevLink = &ppi->HeapMappings.Next;
HeapMapping = *PrevLink; HeapMapping = *PrevLink;
while (HeapMapping != NULL) while (HeapMapping != NULL)
{ {

View file

@ -15,8 +15,8 @@
HANDLE hModuleWin; HANDLE hModuleWin;
NTSTATUS DestroyProcessCallback(PEPROCESS Process); NTSTATUS ExitProcessCallback(PEPROCESS Process);
NTSTATUS NTAPI DestroyThreadCallback(PETHREAD Thread); NTSTATUS NTAPI ExitThreadCallback(PETHREAD Thread);
// TODO: Should be moved to some GDI header // TODO: Should be moved to some GDI header
NTSTATUS GdiProcessCreate(PEPROCESS Process); NTSTATUS GdiProcessCreate(PEPROCESS Process);
@ -163,7 +163,7 @@ UserProcessCreate(PEPROCESS Process)
ppiCurrent->peProcess = Process; ppiCurrent->peProcess = Process;
/* Setup process flags */ /* Setup process flags */
ppiCurrent->W32PF_flags = W32PF_PROCESSCONNECTED; ppiCurrent->W32PF_flags |= W32PF_PROCESSCONNECTED;
if ( Process->Peb->ProcessParameters && if ( Process->Peb->ProcessParameters &&
Process->Peb->ProcessParameters->WindowFlags & STARTF_SCRNSAVER ) Process->Peb->ProcessParameters->WindowFlags & STARTF_SCRNSAVER )
{ {
@ -172,7 +172,7 @@ UserProcessCreate(PEPROCESS Process)
} }
// FIXME: check if this process is allowed. // FIXME: check if this process is allowed.
ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off. ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application will get it toggled off.
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -228,13 +228,11 @@ UserProcessDestroy(PEPROCESS Process)
} }
NTSTATUS NTSTATUS
CreateProcessCallback(PEPROCESS Process) InitProcessCallback(PEPROCESS Process)
{ {
PPROCESSINFO ppiCurrent;
NTSTATUS Status; NTSTATUS Status;
SIZE_T ViewSize = 0; PPROCESSINFO ppiCurrent;
LARGE_INTEGER Offset; PVOID KernelMapping = NULL, UserMapping = NULL;
PVOID UserBase = NULL;
/* We might be called with an already allocated win32 process */ /* We might be called with an already allocated win32 process */
ppiCurrent = PsGetProcessWin32Process(Process); ppiCurrent = PsGetProcessWin32Process(Process);
@ -243,6 +241,8 @@ CreateProcessCallback(PEPROCESS Process)
/* There is no more to do for us (this is a success code!) */ /* There is no more to do for us (this is a success code!) */
return STATUS_ALREADY_WIN32; return STATUS_ALREADY_WIN32;
} }
// if (ppiCurrent->W32PF_flags & W32PF_PROCESSCONNECTED)
// return STATUS_ALREADY_WIN32;
/* Allocate a new Win32 process info */ /* Allocate a new Win32 process info */
Status = AllocW32Process(Process, &ppiCurrent); Status = AllocW32Process(Process, &ppiCurrent);
@ -260,27 +260,16 @@ CreateProcessCallback(PEPROCESS Process)
#endif #endif
#endif #endif
/* Map the global heap into the process */ /* Map the global user heap into the process */
Offset.QuadPart = 0; Status = MapGlobalUserHeap(Process, &KernelMapping, &UserMapping);
Status = MmMapViewOfSection(GlobalUserHeapSection,
PsGetCurrentProcess(),
&UserBase,
0,
0,
&Offset,
&ViewSize,
ViewUnmap,
SEC_NO_CHANGE,
PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
TRACE_CH(UserProcess, "Failed to map the global heap! 0x%x\n", Status); TRACE_CH(UserProcess, "Failed to map the global heap! 0x%x\n", Status);
goto error; goto error;
} }
ppiCurrent->HeapMappings.Next = NULL;
ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap; TRACE_CH(UserProcess, "InitProcessCallback -- We have KernelMapping 0x%p and UserMapping 0x%p with delta = 0x%x\n",
ppiCurrent->HeapMappings.UserMapping = UserBase; KernelMapping, UserMapping, (ULONG_PTR)KernelMapping - (ULONG_PTR)UserMapping);
ppiCurrent->HeapMappings.Count = 1;
/* Initialize USER process info */ /* Initialize USER process info */
Status = UserProcessCreate(Process); Status = UserProcessCreate(Process);
@ -305,14 +294,14 @@ CreateProcessCallback(PEPROCESS Process)
return STATUS_SUCCESS; return STATUS_SUCCESS;
error: error:
ERR_CH(UserProcess, "CreateProcessCallback failed! Freeing ppi 0x%p for PID:0x%lx\n", ERR_CH(UserProcess, "InitProcessCallback failed! Freeing ppi 0x%p for PID:0x%lx\n",
ppiCurrent, HandleToUlong(Process->UniqueProcessId)); ppiCurrent, HandleToUlong(Process->UniqueProcessId));
DestroyProcessCallback(Process); ExitProcessCallback(Process);
return Status; return Status;
} }
NTSTATUS NTSTATUS
DestroyProcessCallback(PEPROCESS Process) ExitProcessCallback(PEPROCESS Process)
{ {
PPROCESSINFO ppiCurrent, *pppi; PPROCESSINFO ppiCurrent, *pppi;
@ -352,7 +341,7 @@ DestroyProcessCallback(PEPROCESS Process)
NTSTATUS NTSTATUS
APIENTRY APIENTRY
Win32kProcessCallback(PEPROCESS Process, Win32kProcessCallback(PEPROCESS Process,
BOOLEAN Create) BOOLEAN Initialize)
{ {
NTSTATUS Status; NTSTATUS Status;
@ -362,13 +351,13 @@ Win32kProcessCallback(PEPROCESS Process,
UserEnterExclusive(); UserEnterExclusive();
if (Create) if (Initialize)
{ {
Status = CreateProcessCallback(Process); Status = InitProcessCallback(Process);
} }
else else
{ {
Status = DestroyProcessCallback(Process); Status = ExitProcessCallback(Process);
} }
UserLeave(); UserLeave();
@ -462,7 +451,7 @@ UserThreadDestroy(PETHREAD Thread)
} }
NTSTATUS NTAPI NTSTATUS NTAPI
CreateThreadCallback(PETHREAD Thread) InitThreadCallback(PETHREAD Thread)
{ {
PEPROCESS Process; PEPROCESS Process;
PCLIENTINFO pci; PCLIENTINFO pci;
@ -669,15 +658,15 @@ CreateThreadCallback(PETHREAD Thread)
return STATUS_SUCCESS; return STATUS_SUCCESS;
error: error:
ERR_CH(UserThread, "CreateThreadCallback failed! Freeing pti 0x%p for TID:0x%lx\n", ERR_CH(UserThread, "InitThreadCallback failed! Freeing pti 0x%p for TID:0x%lx\n",
ptiCurrent, HandleToUlong(Thread->Cid.UniqueThread)); ptiCurrent, HandleToUlong(Thread->Cid.UniqueThread));
DestroyThreadCallback(Thread); ExitThreadCallback(Thread);
return Status; return Status;
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
DestroyThreadCallback(PETHREAD Thread) ExitThreadCallback(PETHREAD Thread)
{ {
PTHREADINFO *ppti; PTHREADINFO *ppti;
PSINGLE_LIST_ENTRY psle; PSINGLE_LIST_ENTRY psle;
@ -843,12 +832,12 @@ Win32kThreadCallback(PETHREAD Thread,
if (Type == PsW32ThreadCalloutInitialize) if (Type == PsW32ThreadCalloutInitialize)
{ {
ASSERT(PsGetThreadWin32Thread(Thread) == NULL); ASSERT(PsGetThreadWin32Thread(Thread) == NULL);
Status = CreateThreadCallback(Thread); Status = InitThreadCallback(Thread);
} }
else else // if (Type == PsW32ThreadCalloutExit)
{ {
ASSERT(PsGetThreadWin32Thread(Thread) != NULL); ASSERT(PsGetThreadWin32Thread(Thread) != NULL);
Status = DestroyThreadCallback(Thread); Status = ExitThreadCallback(Thread);
} }
UserLeave(); UserLeave();

View file

@ -123,7 +123,7 @@ UserInitialize(VOID)
// { // {
/* Initialize the current thread */ /* Initialize the current thread */
Status = CreateThreadCallback(PsGetCurrentThread()); Status = InitThreadCallback(PsGetCurrentThread());
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
// } // }

View file

@ -42,7 +42,7 @@ PWND FASTCALL IntGetWindowObject(HWND hWnd);
/*************** MAIN.C ***************/ /*************** MAIN.C ***************/
NTSTATUS NTAPI CreateThreadCallback(PETHREAD Thread); NTSTATUS NTAPI InitThreadCallback(PETHREAD Thread);
/*************** WINSTA.C ***************/ /*************** WINSTA.C ***************/

View file

@ -227,3 +227,111 @@ UserCreateHeap(OUT PVOID *SectionObject,
return pHeap; return pHeap;
} }
NTSTATUS
UnmapGlobalUserHeap(IN PEPROCESS Process)
{
NTSTATUS Status = STATUS_SUCCESS;
PPROCESSINFO W32Process;
PW32HEAP_USER_MAPPING HeapMapping;
TRACE_CH(UserProcess, "IntUnmapDesktopView called for process 0x%p\n", Process);
W32Process = PsGetProcessWin32Process(Process);
if (W32Process == NULL)
{
ERR_CH(UserProcess, "UnmapGlobalUserHeap - We don't have a Win32 process!\n");
ASSERT(FALSE);
}
/* The first mapping entry must be the global user heap */
HeapMapping = &W32Process->HeapMappings;
ASSERT(HeapMapping->KernelMapping == (PVOID)GlobalUserHeap);
/* Unmap if we're the last thread using the global user heap */
if (--HeapMapping->Count == 0)
{
TRACE_CH(UserProcess, "UnmapGlobalUserHeap - Unmapping\n");
Status = MmUnmapViewOfSection(Process, HeapMapping->UserMapping);
}
return Status;
}
NTSTATUS
MapGlobalUserHeap(IN PEPROCESS Process,
OUT PVOID* KernelMapping,
OUT PVOID* UserMapping)
{
NTSTATUS Status;
PPROCESSINFO W32Process;
PW32HEAP_USER_MAPPING HeapMapping;
PVOID UserBase = NULL;
SIZE_T ViewSize = 0;
LARGE_INTEGER Offset;
TRACE_CH(UserProcess, "MapGlobalUserHeap called for process 0x%p\n", Process);
W32Process = PsGetProcessWin32Process(Process);
if (W32Process == NULL)
{
ERR_CH(UserProcess, "MapGlobalUserHeap - We don't have a Win32 process!\n");
ASSERT(FALSE);
}
TRACE_CH(UserProcess, "MapGlobalUserHeap - We got a Win32 process, find for existing global user heap mapping...\n");
/* The first mapping entry must be the global user heap */
HeapMapping = &W32Process->HeapMappings;
/* Find out if another thread already mapped the global user heap */
if (HeapMapping->KernelMapping == (PVOID)GlobalUserHeap)
{
HeapMapping->Count++;
TRACE_CH(UserProcess, "MapGlobalUserHeap - A mapping was found, return it.\n");
*KernelMapping = HeapMapping->KernelMapping;
*UserMapping = HeapMapping->UserMapping;
return STATUS_SUCCESS;
}
TRACE_CH(UserProcess, "MapGlobalUserHeap - No mapping was found, let's map...\n");
/* We're the first, map the global heap into the process */
Offset.QuadPart = 0;
Status = MmMapViewOfSection(GlobalUserHeapSection,
Process,
&UserBase,
0,
0,
&Offset,
&ViewSize,
ViewUnmap,
SEC_NO_CHANGE,
PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
if (!NT_SUCCESS(Status))
{
ERR_CH(UserProcess, "MapGlobalUserHeap - Failed to map the global heap! 0x%x\n", Status);
return Status;
}
TRACE_CH(UserProcess, "MapGlobalUserHeap -- Mapped kernel global heap 0x%p to user space at 0x%p\n",
GlobalUserHeap, UserBase);
/* Add the mapping */
HeapMapping->Next = NULL;
HeapMapping->KernelMapping = (PVOID)GlobalUserHeap;
HeapMapping->UserMapping = UserBase;
HeapMapping->Limit = ViewSize;
HeapMapping->Count = 1;
*KernelMapping = HeapMapping->KernelMapping;
*UserMapping = HeapMapping->UserMapping;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -22,6 +22,14 @@ UserCreateHeap(OUT PVOID *SectionObject,
IN OUT PVOID *SystemBase, IN OUT PVOID *SystemBase,
IN SIZE_T HeapSize); IN SIZE_T HeapSize);
NTSTATUS
UnmapGlobalUserHeap(IN PEPROCESS Process);
NTSTATUS
MapGlobalUserHeap(IN PEPROCESS Process,
OUT PVOID* KernelMapping,
OUT PVOID* UserMapping);
static __inline PVOID static __inline PVOID
UserHeapAlloc(SIZE_T Bytes) UserHeapAlloc(SIZE_T Bytes)
{ {

View file

@ -216,7 +216,7 @@ ClientThreadSetupHelper(BOOL IsCallback)
{ {
/* /*
* Normally we are called by win32k so the win32 thread pointers * Normally we are called by win32k so the win32 thread pointers
* should be valid as they are set in win32k::CreateThreadCallback. * should be valid as they are set in win32k::InitThreadCallback.
*/ */
PCLIENTINFO ClientInfo = GetWin32ClientInfo(); PCLIENTINFO ClientInfo = GetWin32ClientInfo();
BOOLEAN IsFirstThread = _InterlockedExchange8((PCHAR)&gfFirstThread, FALSE); BOOLEAN IsFirstThread = _InterlockedExchange8((PCHAR)&gfFirstThread, FALSE);