[WIN32K:NTUSER]
[reactos.git] / reactos / win32ss / user / ntuser / main.c
index 9f04f9d..f9aed03 100644 (file)
@@ -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);
@@ -24,9 +24,6 @@ NTSTATUS GdiProcessDestroy(PEPROCESS Process);
 NTSTATUS GdiThreadCreate(PETHREAD Thread);
 NTSTATUS GdiThreadDestroy(PETHREAD Thread);
 
-HANDLE GlobalUserHeap = NULL;
-PVOID GlobalUserHeapSection = NULL;
-
 PSERVERINFO gpsi = NULL; // Global User Server Information.
 
 SHORT gusLanguageID;
@@ -103,7 +100,8 @@ do { \
  * Called from IntDereferenceProcessInfo
  */
 VOID
-UserDeleteW32Process(PPROCESSINFO ppiCurrent)
+UserDeleteW32Process(
+    _Pre_notnull_ __drv_freesMem(Mem) PPROCESSINFO ppiCurrent)
 {
     if (ppiCurrent->InputIdleEvent)
     {
@@ -136,7 +134,6 @@ UserProcessCreate(PEPROCESS Process)
     InitializeListHead(&ppiCurrent->DriverObjListHead);
     ExInitializeFastMutex(&ppiCurrent->DriverObjListLock);
 
-    ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
     {
         PKEVENT Event;
 
@@ -164,9 +161,10 @@ UserProcessCreate(PEPROCESS Process)
     }
 
     ppiCurrent->peProcess = Process;
+    ppiCurrent->W32Pid = HandleToUlong(PsGetProcessId(Process));
 
     /* Setup process flags */
-    ppiCurrent->W32PF_flags = W32PF_PROCESSCONNECTED;
+    ppiCurrent->W32PF_flags |= W32PF_PROCESSCONNECTED;
     if ( Process->Peb->ProcessParameters &&
          Process->Peb->ProcessParameters->WindowFlags & STARTF_SCRNSAVER )
     {
@@ -175,7 +173,7 @@ UserProcessCreate(PEPROCESS Process)
     }
 
     // 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;
 }
@@ -222,22 +220,18 @@ UserProcessDestroy(PEPROCESS Process)
         ppiCurrent->hdeskStartup = NULL;
     }
 
-#ifdef NEW_CURSORICON
     /* Clean up the process icon cache */
     IntCleanupCurIconCache(ppiCurrent);
-#endif
 
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
-CreateProcessCallback(PEPROCESS Process)
+InitProcessCallback(PEPROCESS Process)
 {
-    PPROCESSINFO ppiCurrent;
     NTSTATUS Status;
-    SIZE_T ViewSize = 0;
-    LARGE_INTEGER Offset;
-    PVOID UserBase = NULL;
+    PPROCESSINFO ppiCurrent;
+    PVOID KernelMapping = NULL, UserMapping = NULL;
 
     /* We might be called with an already allocated win32 process */
     ppiCurrent = PsGetProcessWin32Process(Process);
@@ -246,6 +240,8 @@ CreateProcessCallback(PEPROCESS Process)
         /* 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);
@@ -258,32 +254,21 @@ CreateProcessCallback(PEPROCESS Process)
 
 #if DBG
     DbgInitDebugChannels();
-#if KDBG
+#if defined(KDBG)
     KdRosRegisterCliCallback(DbgGdiKdbgCliCallback);
 #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);
@@ -308,14 +293,14 @@ CreateProcessCallback(PEPROCESS Process)
     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;
 
@@ -355,7 +340,7 @@ DestroyProcessCallback(PEPROCESS Process)
 NTSTATUS
 APIENTRY
 Win32kProcessCallback(PEPROCESS Process,
-                      BOOLEAN Create)
+                      BOOLEAN Initialize)
 {
     NTSTATUS Status;
 
@@ -365,13 +350,13 @@ Win32kProcessCallback(PEPROCESS Process,
 
     UserEnterExclusive();
 
-    if (Create)
+    if (Initialize)
     {
-        Status = CreateProcessCallback(Process);
+        Status = InitProcessCallback(Process);
     }
     else
     {
-        Status = DestroyProcessCallback(Process);
+        Status = ExitProcessCallback(Process);
     }
 
     UserLeave();
@@ -393,11 +378,7 @@ AllocW32Thread(IN  PETHREAD Thread,
 
     /* Check that we were not called with an already existing Win32 thread info */
     ptiCurrent = PsGetThreadWin32Thread(Thread);
-    if (ptiCurrent)
-    {
-        ERR_CH(UserThread, "PsGetThreadWin32Thread returned non-NULL thread info!!\n");
-        // return STATUS_SUCCESS;
-    }
+    NT_ASSERT(ptiCurrent == NULL);
 
     /* Allocate a new Win32 thread info */
     ptiCurrent = ExAllocatePoolWithTag(NonPagedPool,
@@ -465,7 +446,7 @@ UserThreadDestroy(PETHREAD Thread)
 }
 
 NTSTATUS NTAPI
-CreateThreadCallback(PETHREAD Thread)
+InitThreadCallback(PETHREAD Thread)
 {
     PEPROCESS Process;
     PCLIENTINFO pci;
@@ -474,12 +455,15 @@ CreateThreadCallback(PETHREAD Thread)
     NTSTATUS Status = STATUS_SUCCESS;
     PTEB pTeb;
     LARGE_INTEGER LargeTickCount;
+    PRTL_USER_PROCESS_PARAMETERS ProcessParams;
 
     Process = Thread->ThreadsProcess;
 
     pTeb = NtCurrentTeb();
     ASSERT(pTeb);
 
+    ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters;
+
     /* Allocate a new Win32 thread info */
     Status = AllocW32Thread(Thread, &ptiCurrent);
     if (!NT_SUCCESS(Status))
@@ -503,8 +487,6 @@ CreateThreadCallback(PETHREAD Thread)
     InitializeListHead(&ptiCurrent->W32CallbackListHead);
     InitializeListHead(&ptiCurrent->PostedMessagesListHead);
     InitializeListHead(&ptiCurrent->SentMessagesListHead);
-    InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
-    InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
     InitializeListHead(&ptiCurrent->PtiLink);
     for (i = 0; i < NB_HOOKS; i++)
     {
@@ -523,12 +505,12 @@ CreateThreadCallback(PETHREAD Thread)
         goto error;
     }
     Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
-                                       *ExEventObjectType, KernelMode,
+                                       *ExEventObjectType, UserMode,
                                        (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
     if (!NT_SUCCESS(Status))
     {
         ERR_CH(UserThread, "Failed referencing the event object, Status 0x%08x.\n", Status);
-        ZwClose(ptiCurrent->hEventQueueClient);
+        ObCloseHandle(ptiCurrent->hEventQueueClient, UserMode);
         ptiCurrent->hEventQueueClient = NULL;
         goto error;
     }
@@ -570,6 +552,24 @@ CreateThreadCallback(PETHREAD Thread)
         pci->CodePage = ptiCurrent->KeyboardLayout->CodePage;
     }
 
+    /* Need to pass the user Startup Information to the current process. */
+    if ( ProcessParams )
+    {
+       if ( ptiCurrent->ppi->usi.cb == 0 )      // Not initialized yet.
+       {
+          if ( ProcessParams->WindowFlags != 0 ) // Need window flags set.
+          {
+             ptiCurrent->ppi->usi.cb          = sizeof(USERSTARTUPINFO);
+             ptiCurrent->ppi->usi.dwX         = ProcessParams->StartingX;
+             ptiCurrent->ppi->usi.dwY         = ProcessParams->StartingY;
+             ptiCurrent->ppi->usi.dwXSize     = ProcessParams->CountX;
+             ptiCurrent->ppi->usi.dwYSize     = ProcessParams->CountY;
+             ptiCurrent->ppi->usi.dwFlags     = ProcessParams->WindowFlags;
+             ptiCurrent->ppi->usi.wShowWindow = (WORD)ProcessParams->ShowWindowFlags;
+          }
+       }
+    }
+
     /* Assign a default window station and desktop to the process */
     /* Do not try to open a desktop or window station before winlogon initializes */
     if (ptiCurrent->ppi->hdeskStartup == NULL && gpidLogon != 0)
@@ -578,13 +578,11 @@ CreateThreadCallback(PETHREAD Thread)
         HDESK hDesk = NULL;
         UNICODE_STRING DesktopPath;
         PDESKTOP pdesk;
-        PRTL_USER_PROCESS_PARAMETERS ProcessParams;
 
         /*
          * inherit the thread desktop and process window station (if not yet inherited) from the process startup
          * info structure. See documentation of CreateProcess()
          */
-        ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters;
 
         Status = STATUS_UNSUCCESSFUL;
         if (ProcessParams && ProcessParams->DesktopInfo.Length > 0)
@@ -672,15 +670,18 @@ CreateThreadCallback(PETHREAD Thread)
     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;
 }
 
+VOID
+UserDisplayNotifyShutdown(PPROCESSINFO ppiCurrent);
+
 NTSTATUS
 NTAPI
-DestroyThreadCallback(PETHREAD Thread)
+ExitThreadCallback(PETHREAD Thread)
 {
     PTHREADINFO *ppti;
     PSINGLE_LIST_ENTRY psle;
@@ -707,6 +708,8 @@ DestroyThreadCallback(PETHREAD Thread)
     ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
     ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
 
+    UserCloseClipboard();
+
     /* Decrement thread count and check if its 0 */
     ppiCurrent->cThreads--;
 
@@ -777,6 +780,12 @@ DestroyThreadCallback(PETHREAD Thread)
         }
     }
 
+    if (ptiCurrent->cEnterCount)
+    {
+       KeSetKernelStackSwapEnable(TRUE);
+       ptiCurrent->cEnterCount = 0;
+    }
+
     /* Find the THREADINFO in the PROCESSINFO's list */
     ppti = &ppiCurrent->ptiList;
     while (*ppti != NULL && *ppti != ptiCurrent)
@@ -801,6 +810,11 @@ DestroyThreadCallback(PETHREAD Thread)
        gptiForeground = NULL;
     }
 
+    /* Restore display mode when we are the last thread, and we changed the display mode */
+    if (ppiCurrent->cThreads == 0)
+        UserDisplayNotifyShutdown(ppiCurrent);
+
+
     // Fixes CORE-6384 & CORE-7030.
 /*    if (ptiLastInput == ptiCurrent)
     {
@@ -817,7 +831,7 @@ DestroyThreadCallback(PETHREAD Thread)
 
     if (ptiCurrent->hEventQueueClient != NULL)
     {
-       ZwClose(ptiCurrent->hEventQueueClient);
+       ObCloseHandle(ptiCurrent->hEventQueueClient, UserMode);
        ObDereferenceObject(ptiCurrent->pEventQueueServer);
     }
     ptiCurrent->hEventQueueClient = NULL;
@@ -846,12 +860,12 @@ Win32kThreadCallback(PETHREAD Thread,
     if (Type == PsW32ThreadCalloutInitialize)
     {
         ASSERT(PsGetThreadWin32Thread(Thread) == NULL);
-        Status = CreateThreadCallback(Thread);
+        Status = InitThreadCallback(Thread);
     }
-    else
+    else // if (Type == PsW32ThreadCalloutExit)
     {
         ASSERT(PsGetThreadWin32Thread(Thread) != NULL);
-        Status = DestroyThreadCallback(Thread);
+        Status = ExitThreadCallback(Thread);
     }
 
     UserLeave();
@@ -859,7 +873,7 @@ Win32kThreadCallback(PETHREAD Thread,
     return Status;
 }
 
-
+_Function_class_(DRIVER_UNLOAD)
 VOID NTAPI
 DriverUnload(IN PDRIVER_OBJECT DriverObject)
 {
@@ -883,7 +897,7 @@ DriverUnload(IN PDRIVER_OBJECT DriverObject)
 /*
  * This definition doesn't work
  */
-INIT_FUNCTION
+INIT_SECTION
 NTSTATUS
 APIENTRY
 DriverEntry(
@@ -937,7 +951,7 @@ DriverEntry(
     PsEstablishWin32Callouts(&CalloutData);
 
     /* Register service hook callbacks */
-#if DBG
+#if DBG && defined(KDBG)
     KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0);
     KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0);
 #endif
@@ -985,6 +999,8 @@ DriverEntry(
     NT_ROF(InitTimerImpl());
     NT_ROF(InitDCEImpl());
 
+    gusLanguageID = UserGetLanguageID();
+
     /* Initialize FreeType library */
     if (!InitFontSupport())
     {
@@ -992,8 +1008,6 @@ DriverEntry(
         return Status;
     }
 
-    gusLanguageID = UserGetLanguageID();
-
     return STATUS_SUCCESS;
 }