- Add flags for NtCreateProcessEx for upcoming patch.
[reactos.git] / reactos / subsys / win32k / main / dllmain.c
index 0a6710a..94eb7a8 100644 (file)
  *
  *  Entry Point for win32k.sys
  */
-#include <win32k/ntddraw.h> /* FIXME: FIX THIS! */
+
 #include <w32k.h>
+#include <win32k/ntddraw.h>
 #include <include/napi.h>
 
 #define NDEBUG
-#include <win32k/debug1.h>
 #include <debug.h>
 
 BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
 
-extern SSDT Win32kSSDT[];
-extern SSPT Win32kSSPT[];
+extern ULONG_PTR Win32kSSDT[];
+extern UCHAR Win32kSSPT[];
 extern ULONG Win32kNumberOfSysCalls;
 
 PSHARED_SECTION_POOL SessionSharedSectionPool = NULL;
 
-NTSTATUS STDCALL
-Win32kProcessCallback (struct _EPROCESS *Process,
-                    BOOLEAN Create)
+NTSTATUS 
+STDCALL
+Win32kProcessCallback(struct _EPROCESS *Process,
+                      BOOLEAN Create)
 {
-  PW32PROCESS Win32Process;
+    PW32PROCESS Win32Process;
+    DECLARE_RETURN(NTSTATUS);
+    
+    DPRINT("Enter Win32kProcessCallback\n");
+    UserEnterExclusive();
+    
+    /* Get the Win32 Process */
+    Win32Process = PsGetProcessWin32Process(Process);
+    
+    /* Allocate one if needed */
+    if (!Win32Process)
+    {
+        /* FIXME - lock the process */
+        Win32Process = ExAllocatePoolWithTag(NonPagedPool,
+                                             sizeof(W32PROCESS),
+                                             TAG('W', '3', '2', 'p'));
+
+        if (Win32Process == NULL) RETURN( STATUS_NO_MEMORY);
+
+        RtlZeroMemory(Win32Process, sizeof(W32PROCESS));
+        
+        PsSetProcessWin32Process(Process, Win32Process);
+        /* FIXME - unlock the process */
+    }
 
-  Win32Process = (PW32PROCESS)Process->Win32Process;
   if (Create)
     {
       DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
 
-      InitializeListHead(&Win32Process->ClassListHead);
-      ExInitializeFastMutex(&Win32Process->ClassListLock);
+      InitializeListHead(&Win32Process->ClassList);
 
       InitializeListHead(&Win32Process->MenuListHead);
-      ExInitializeFastMutex(&Win32Process->MenuListLock);
 
       InitializeListHead(&Win32Process->PrivateFontListHead);
       ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
@@ -78,11 +99,13 @@ Win32kProcessCallback (struct _EPROCESS *Process,
       IntCleanupCurIcons(Process, Win32Process);
       IntEngCleanupDriverObjs(Process, Win32Process);
       CleanupMonitorImpl();
-
+      
+      /* no process windows should exist at this point, or the function will assert! */
+      DestroyProcessClasses(Win32Process);
 
       GDI_CleanupForProcess(Process);
 
-      IntGraphicsCheck(FALSE);
+      co_IntGraphicsCheck(FALSE);
 
       /*
        * Deregister logon application automatically
@@ -93,19 +116,47 @@ Win32kProcessCallback (struct _EPROCESS *Process,
       }
     }
 
-  return STATUS_SUCCESS;
+  RETURN( STATUS_SUCCESS);
+  
+CLEANUP:
+  UserLeave();
+  DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_);
+  END_CLEANUP;
 }
 
 
-NTSTATUS STDCALL
-Win32kThreadCallback (struct _ETHREAD *Thread,
-                   BOOLEAN Create)
+NTSTATUS 
+STDCALL
+Win32kThreadCallback(struct _ETHREAD *Thread,
+                     BOOLEAN Create)
 {
-  struct _EPROCESS *Process;
-  PW32THREAD Win32Thread;
+    struct _EPROCESS *Process;
+    PW32THREAD Win32Thread;
+    DECLARE_RETURN(NTSTATUS);
+    
+    DPRINT("Enter Win32kThreadCallback\n");
+    UserEnterExclusive();
+
+    Process = Thread->ThreadsProcess;
+    
+    /* Get the Win32 Thread */
+    Win32Thread = PsGetThreadWin32Thread(Thread);
+    
+    /* Allocate one if needed */
+    if (!Win32Thread)
+    {
+        /* FIXME - lock the process */
+        Win32Thread = ExAllocatePoolWithTag(NonPagedPool,
+                                            sizeof(W32THREAD),
+                                            TAG('W', '3', '2', 't'));
 
-  Process = Thread->ThreadsProcess;
-  Win32Thread = Thread->Tcb.Win32Thread;
+        if (Win32Thread == NULL) RETURN( STATUS_NO_MEMORY);
+
+        RtlZeroMemory(Win32Thread, sizeof(W32THREAD));
+        
+        PsSetThreadWin32Thread(Thread, Win32Thread);
+        /* FIXME - unlock the process */
+    }
   if (Create)
     {
       HWINSTA hWinSta = NULL;
@@ -161,22 +212,24 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
         }
       }
       Win32Thread->IsExiting = FALSE;
-      IntDestroyCaret(Win32Thread);
+      co_IntDestroyCaret(Win32Thread);
       Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
       Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
       Win32Thread->MessagePumpHookValue = 0;
       InitializeListHead(&Win32Thread->WindowListHead);
-      ExInitializeFastMutex(&Win32Thread->WindowListLock);
       InitializeListHead(&Win32Thread->W32CallbackListHead);
     }
   else
     {
+      PSINGLE_LIST_ENTRY e;
+      
       DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
 
       Win32Thread->IsExiting = TRUE;
       HOOK_DestroyThreadHooks(Thread);
       UnregisterThreadHotKeys(Thread);
-      DestroyThreadWindows(Thread);
+      /* what if this co_ func crash in umode? what will clean us up then? */
+      co_DestroyThreadWindows(Thread);
       IntBlockInput(Win32Thread, FALSE);
       MsqDestroyMessageQueue(Win32Thread->MessageQueue);
       IntCleanupThreadCallbacks(Win32Thread);
@@ -184,9 +237,26 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
       {
         ObDereferenceObject(Win32Thread->Desktop);
       }
+      
+      /* cleanup user object references stack */
+      e = PopEntryList(&Win32Thread->ReferencesList);
+      while (e)
+      {
+         PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
+         DPRINT1("thread clean: remove reference obj 0x%x\n",ref->obj);
+         ObmDereferenceObject(ref->obj);
+         
+         e = PopEntryList(&Win32Thread->ReferencesList);
+      }
+      PsSetThreadWin32Thread(Thread, NULL);
     }
 
-  return STATUS_SUCCESS;
+  RETURN( STATUS_SUCCESS);
+  
+CLEANUP:
+  UserLeave();
+  DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_);
+  END_CLEANUP;
 }
 
 /* Only used in ntuser/input.c KeyboardThreadMain(). If it's
@@ -237,7 +307,7 @@ DriverEntry (
 {
   NTSTATUS Status;
   BOOLEAN Result;
-  W32_OBJECT_CALLBACK Win32kObjectCallbacks;
+  W32_CALLOUT_DATA CalloutData;
 
   /*
    * Register user mode call interface
@@ -254,24 +324,22 @@ DriverEntry (
       return STATUS_UNSUCCESSFUL;
     }
 
-  /*
-   * Register Object Manager Callbacks
-   */
-    Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectOpen;
-    Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse;
-    Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete;
-    Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind;
-    Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate;
-    Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete;
-  /*
-   * Register our per-process and per-thread structures.
-   */
-  PsEstablishWin32Callouts (Win32kProcessCallback,
-                           Win32kThreadCallback,
-                           &Win32kObjectCallbacks,
-                           0,
-                           sizeof(W32THREAD),
-                           sizeof(W32PROCESS));
+    /*
+     * Register Object Manager Callbacks
+     */
+    CalloutData.WinStaCreate = IntWinStaObjectOpen;
+    CalloutData.WinStaParse = IntWinStaObjectParse;
+    CalloutData.WinStaDelete = IntWinStaObjectDelete;
+    CalloutData.WinStaFind = IntWinStaObjectFind;
+    CalloutData.DesktopCreate = IntDesktopObjectCreate;
+    CalloutData.DesktopDelete = IntDesktopObjectDelete;
+    CalloutData.W32ProcessCallout = Win32kProcessCallback;
+    CalloutData.W32ThreadCallout = Win32kThreadCallback;
+    
+    /*
+     * Register our per-process and per-thread structures.
+     */
+    PsEstablishWin32Callouts(&CalloutData);
 
   Status = IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
                                           &SessionSharedSectionPool);
@@ -280,6 +348,20 @@ DriverEntry (
     DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status);
   }
 
+  Status = InitUserImpl();
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to initialize user implementation!\n");
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  Status = InitHotkeyImpl();
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to initialize hotkey implementation!\n");
+    return STATUS_UNSUCCESSFUL;
+  }
+
   Status = InitWindowStationImpl();
   if (!NT_SUCCESS(Status))
   {