[CMAKE]
[reactos.git] / subsystems / win32 / win32k / main / dllmain.c
index 5985317..caa5ee3 100644 (file)
@@ -114,12 +114,37 @@ Win32kProcessCallback(struct _EPROCESS *Process,
         Win32Process->peProcess = Process;
         /* setup process flags */
         Win32Process->W32PF_flags = 0;
+
+        /* Create pools for GDI object attributes */
+        Win32Process->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
+        Win32Process->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
+        Win32Process->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
+        ASSERT(Win32Process->pPoolDcAttr);
+        ASSERT(Win32Process->pPoolBrushAttr);
+        ASSERT(Win32Process->pPoolRgnAttr);
     }
     else
     {
         DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
         Win32Process->W32PF_flags |= W32PF_TERMINATED;
 
+        /* Notify logon application to restart shell if needed */
+        if(Win32Process->rpdeskStartup->pDeskInfo)
+        {
+            if(Win32Process->rpdeskStartup->pDeskInfo->ppiShellProcess == Win32Process)
+            {
+                DWORD ExitCode;
+                ExitCode = PsGetProcessExitStatus(Win32Process->peProcess);
+
+                DPRINT1("Shell process is exiting (%d)\n", ExitCode);
+
+                UserPostMessage(hwndSAS, 
+                                WM_LOGONNOTIFY, 
+                                LN_SHELL_EXITED, 
+                                ExitCode);
+            }
+        }
+
         if (Win32Process->InputIdleEvent)
         {
            EngFreeMem((PVOID)Win32Process->InputIdleEvent);
@@ -146,8 +171,19 @@ Win32kProcessCallback(struct _EPROCESS *Process,
             LogonProcess = NULL;
         }
 
+        /* Close the startup desktop */
+        ASSERT(Win32Process->rpdeskStartup);
+        ASSERT(Win32Process->hdeskStartup);
+        ObDereferenceObject(Win32Process->rpdeskStartup);
+        ZwClose(Win32Process->hdeskStartup);
+
+        /* Close the current window station */
         UserSetProcessWindowStation(NULL);
 
+        /* Destroy GDI pools */
+        GdiPoolDestroy(Win32Process->pPoolDcAttr);
+        GdiPoolDestroy(Win32Process->pPoolBrushAttr);
+        GdiPoolDestroy(Win32Process->pPoolRgnAttr);
     }
 
     RETURN( STATUS_SUCCESS);
@@ -199,6 +235,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
         HDESK hDesk = NULL;
         NTSTATUS Status;
         PUNICODE_STRING DesktopPath;
+        PDESKTOP pdesk;
         PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
 
         DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
@@ -211,37 +248,6 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
             InitializeListHead(&Win32Thread->aphkStart[i]);
         }
 
-        /*
-         * inherit the thread desktop and process window station (if not yet inherited) from the process startup
-         * info structure. See documentation of CreateProcess()
-         */
-        DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
-        Status = IntParseDesktopPath(Process,
-                                     DesktopPath,
-                                     &hWinSta,
-                                     &hDesk);
-        if(NT_SUCCESS(Status))
-        {
-            if(hWinSta != NULL)
-            {
-                if(!UserSetProcessWindowStation(hWinSta))
-                {
-                    DPRINT1("Failed to set process window station\n");
-                }
-            }
-
-            if (hDesk != NULL)
-            {
-                if (!IntSetThreadDesktop(hDesk, FALSE))
-                {
-                        DPRINT1("Unable to set thread desktop\n");
-                }
-            }
-        }
-        else
-        {
-           DPRINT1("No Desktop handle for this Thread!\n");
-        }
         Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
         co_IntDestroyCaret(Win32Thread);
         Win32Thread->ppi = PsGetCurrentProcessWin32Process();
@@ -254,6 +260,59 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
         }
         Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
         Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
+        Win32Thread->pEThread = Thread;
+
+        /* HAAAAAAAACK! This should go to Win32kProcessCallback */
+        if(Win32Thread->ppi->hdeskStartup == NULL)
+        {
+            /*
+             * inherit the thread desktop and process window station (if not yet inherited) from the process startup
+             * info structure. See documentation of CreateProcess()
+             */
+            DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
+            Status = IntParseDesktopPath(Process,
+                                         DesktopPath,
+                                         &hWinSta,
+                                         &hDesk);
+            if(NT_SUCCESS(Status))
+            {
+                if(hWinSta != NULL)
+                {
+                    if(!UserSetProcessWindowStation(hWinSta))
+                    {
+                        DPRINT1("Failed to set process window station\n");
+                    }
+                }
+
+                if (hDesk != NULL)
+                {
+                    /* Validate the new desktop. */
+                    Status = IntValidateDesktopHandle(hDesk,
+                                                      UserMode,
+                                                      0,
+                                                      &pdesk);
+
+                    if(NT_SUCCESS(Status))
+                    {
+                        Win32Thread->ppi->hdeskStartup = hDesk;
+                        Win32Thread->ppi->rpdeskStartup = pdesk;
+                    }
+                }
+            }
+            else
+            {
+               DPRINT1("No Desktop handle for this Thread!\n");
+            }
+        }
+
+        if (Win32Thread->ppi->hdeskStartup != NULL)
+        {
+            if (!IntSetThreadDesktop(Win32Thread->ppi->hdeskStartup, FALSE))
+            {
+                DPRINT1("Unable to set thread desktop\n");
+            }
+        }
+
         pTeb = NtCurrentTeb();
         if (pTeb)
         { /* Attempt to startup client support which should have been initialized in IntSetThreadDesktop. */
@@ -281,7 +340,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
            // System thread running! Now SendMessage should be okay.
            Win32Thread->pcti = &Win32Thread->cti;
         }
-        Win32Thread->pEThread = Thread;
+        GetW32ThreadInfo();
     }
     else
     {
@@ -440,7 +499,7 @@ DriverEntry(
     /* Register our per-process and per-thread structures. */
     PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
 
-#if 0 // DBG
+#if DBG_ENABLE_SERVICE_HOOKS
     /* Register service hook callbacks */
     KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0);
     KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0);