Author: hbelusca Date: Mon Dec 29 13:56:28 2014 New Revision: 65891
URL: http://svn.reactos.org/svn/reactos?rev=65891&view=rev Log: [WIN32K] - 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.
Modified: trunk/reactos/win32ss/user/ntuser/desktop.c trunk/reactos/win32ss/user/ntuser/main.c trunk/reactos/win32ss/user/ntuser/ntuser.c trunk/reactos/win32ss/user/ntuser/userfuncs.h trunk/reactos/win32ss/user/ntuser/usrheap.c trunk/reactos/win32ss/user/ntuser/usrheap.h trunk/reactos/win32ss/user/user32/misc/dllmain.c
Modified: trunk/reactos/win32ss/user/ntuser/desktop.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/desktop... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/desktop.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/desktop.c [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -1849,9 +1849,13 @@ TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
ppi = PsGetCurrentProcessWin32Process(); + + /* + * 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; - - /* Unmap if we're the last thread using the desktop */ HeapMapping = *PrevLink; while (HeapMapping != NULL) {
Modified: trunk/reactos/win32ss/user/ntuser/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/main.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -15,8 +15,8 @@
HANDLE hModuleWin;
-NTSTATUS DestroyProcessCallback(PEPROCESS Process); -NTSTATUS NTAPI DestroyThreadCallback(PETHREAD Thread); +NTSTATUS ExitProcessCallback(PEPROCESS Process); +NTSTATUS NTAPI ExitThreadCallback(PETHREAD Thread);
// TODO: Should be moved to some GDI header NTSTATUS GdiProcessCreate(PEPROCESS Process); @@ -163,7 +163,7 @@ ppiCurrent->peProcess = Process;
/* Setup process flags */ - ppiCurrent->W32PF_flags = W32PF_PROCESSCONNECTED; + ppiCurrent->W32PF_flags |= W32PF_PROCESSCONNECTED; if ( Process->Peb->ProcessParameters && Process->Peb->ProcessParameters->WindowFlags & STARTF_SCRNSAVER ) { @@ -172,7 +172,7 @@ }
// 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; } @@ -228,13 +228,11 @@ }
NTSTATUS -CreateProcessCallback(PEPROCESS Process) -{ +InitProcessCallback(PEPROCESS Process) +{ + NTSTATUS Status; PPROCESSINFO ppiCurrent; - NTSTATUS Status; - SIZE_T ViewSize = 0; - LARGE_INTEGER Offset; - PVOID UserBase = NULL; + PVOID KernelMapping = NULL, UserMapping = NULL;
/* We might be called with an already allocated win32 process */ ppiCurrent = PsGetProcessWin32Process(Process); @@ -243,6 +241,8 @@ /* There is no more to do for us (this is a success code!) */ return STATUS_ALREADY_WIN32; } + // if (ppiCurrent->W32PF_flags & W32PF_PROCESSCONNECTED) + // return STATUS_ALREADY_WIN32;
/* Allocate a new Win32 process info */ Status = AllocW32Process(Process, &ppiCurrent); @@ -260,27 +260,16 @@ #endif #endif
- /* Map the global heap into the process */ - Offset.QuadPart = 0; - 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... */ + /* Map the global user heap into the process */ + Status = MapGlobalUserHeap(Process, &KernelMapping, &UserMapping); if (!NT_SUCCESS(Status)) { TRACE_CH(UserProcess, "Failed to map the global heap! 0x%x\n", Status); goto error; } - ppiCurrent->HeapMappings.Next = NULL; - ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap; - ppiCurrent->HeapMappings.UserMapping = UserBase; - ppiCurrent->HeapMappings.Count = 1; + + TRACE_CH(UserProcess, "InitProcessCallback -- We have KernelMapping 0x%p and UserMapping 0x%p with delta = 0x%x\n", + KernelMapping, UserMapping, (ULONG_PTR)KernelMapping - (ULONG_PTR)UserMapping);
/* Initialize USER process info */ Status = UserProcessCreate(Process); @@ -305,14 +294,14 @@ return STATUS_SUCCESS;
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)); - DestroyProcessCallback(Process); + ExitProcessCallback(Process); return Status; }
NTSTATUS -DestroyProcessCallback(PEPROCESS Process) +ExitProcessCallback(PEPROCESS Process) { PPROCESSINFO ppiCurrent, *pppi;
@@ -352,7 +341,7 @@ NTSTATUS APIENTRY Win32kProcessCallback(PEPROCESS Process, - BOOLEAN Create) + BOOLEAN Initialize) { NTSTATUS Status;
@@ -362,13 +351,13 @@
UserEnterExclusive();
- if (Create) - { - Status = CreateProcessCallback(Process); + if (Initialize) + { + Status = InitProcessCallback(Process); } else { - Status = DestroyProcessCallback(Process); + Status = ExitProcessCallback(Process); }
UserLeave(); @@ -462,7 +451,7 @@ }
NTSTATUS NTAPI -CreateThreadCallback(PETHREAD Thread) +InitThreadCallback(PETHREAD Thread) { PEPROCESS Process; PCLIENTINFO pci; @@ -669,15 +658,15 @@ return STATUS_SUCCESS;
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)); - DestroyThreadCallback(Thread); + ExitThreadCallback(Thread); return Status; }
NTSTATUS NTAPI -DestroyThreadCallback(PETHREAD Thread) +ExitThreadCallback(PETHREAD Thread) { PTHREADINFO *ppti; PSINGLE_LIST_ENTRY psle; @@ -843,12 +832,12 @@ if (Type == PsW32ThreadCalloutInitialize) { ASSERT(PsGetThreadWin32Thread(Thread) == NULL); - Status = CreateThreadCallback(Thread); - } - else + Status = InitThreadCallback(Thread); + } + else // if (Type == PsW32ThreadCalloutExit) { ASSERT(PsGetThreadWin32Thread(Thread) != NULL); - Status = DestroyThreadCallback(Thread); + Status = ExitThreadCallback(Thread); }
UserLeave();
Modified: trunk/reactos/win32ss/user/ntuser/ntuser.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntuser.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -123,7 +123,7 @@ // {
/* Initialize the current thread */ - Status = CreateThreadCallback(PsGetCurrentThread()); + Status = InitThreadCallback(PsGetCurrentThread()); if (!NT_SUCCESS(Status)) return Status;
// }
Modified: trunk/reactos/win32ss/user/ntuser/userfuncs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/userfun... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -42,7 +42,7 @@
/*************** MAIN.C ***************/
-NTSTATUS NTAPI CreateThreadCallback(PETHREAD Thread); +NTSTATUS NTAPI InitThreadCallback(PETHREAD Thread);
/*************** WINSTA.C ***************/
Modified: trunk/reactos/win32ss/user/ntuser/usrheap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/usrheap... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/usrheap.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/usrheap.c [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -227,3 +227,111 @@
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 */
Modified: trunk/reactos/win32ss/user/ntuser/usrheap.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/usrheap... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/usrheap.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/usrheap.h [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -21,6 +21,14 @@ UserCreateHeap(OUT PVOID *SectionObject, IN OUT PVOID *SystemBase, IN SIZE_T HeapSize); + +NTSTATUS +UnmapGlobalUserHeap(IN PEPROCESS Process); + +NTSTATUS +MapGlobalUserHeap(IN PEPROCESS Process, + OUT PVOID* KernelMapping, + OUT PVOID* UserMapping);
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Modified: trunk/reactos/win32ss/user/user32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/dl... ============================================================================== --- trunk/reactos/win32ss/user/user32/misc/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/misc/dllmain.c [iso-8859-1] Mon Dec 29 13:56:28 2014 @@ -216,7 +216,7 @@ { /* * 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(); BOOLEAN IsFirstThread = _InterlockedExchange8((PCHAR)&gfFirstThread, FALSE);