Fixed some bugs.
authorDavid Welch <welch@cwcom.net>
Wed, 17 Jul 2002 21:04:57 +0000 (21:04 +0000)
committerDavid Welch <welch@cwcom.net>
Wed, 17 Jul 2002 21:04:57 +0000 (21:04 +0000)
svn path=/trunk/; revision=3243

38 files changed:
reactos/include/ddk/zwtypes.h
reactos/include/napi/core.h
reactos/include/user32/callback.h
reactos/include/win32k/region.h
reactos/lib/user32/misc/dllmain.c
reactos/lib/user32/windows/window.c
reactos/ntoskrnl/cc/copy.c
reactos/ntoskrnl/cc/misc.c
reactos/ntoskrnl/cc/pin.c
reactos/ntoskrnl/cc/view.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/ke/bug.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/trap.s
reactos/ntoskrnl/ke/kthread.c
reactos/ntoskrnl/ke/main.c
reactos/ntoskrnl/ldr/loader.c
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/mm/pagefile.c
reactos/ntoskrnl/ob/object.c
reactos/ntoskrnl/ps/process.c
reactos/subsys/system/winlogon/winlogon.c
reactos/subsys/win32k/include/callback.h
reactos/subsys/win32k/include/class.h
reactos/subsys/win32k/include/msgqueue.h
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/include/winsta.h
reactos/subsys/win32k/ntuser/callback.c
reactos/subsys/win32k/ntuser/class.c
reactos/subsys/win32k/ntuser/guicheck.c
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/msgqueue.c
reactos/subsys/win32k/ntuser/windc.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winpos.c
reactos/subsys/win32k/ntuser/winsta.c
reactos/subsys/win32k/objects/region.c

index d2d3ca6..9bf9115 100644 (file)
@@ -82,13 +82,15 @@ typedef enum _JOBOBJECTINFOCLASS {               // Q S
 #define ProcessWx86Information                 19
 #define ProcessHandleCount                     20
 #define ProcessAffinityMask                    21
-#define ProcessImageFileName                   22      // ???
 #define ProcessPriorityBoost                   22
 #define ProcessDeviceMap                       23
 #define ProcessSessionInformation              24
 #define ProcessForegroundInformation           25
 #define ProcessWow64Information                        26
-#define MaxProcessInfoClass                    26
+/* ReactOS private. */
+#define ProcessImageFileName                   27
+#define ProcessDesktop                          28
+#define MaxProcessInfoClass                    29
 
 /*
  * thread query / set information class
index d4967e7..ca13d20 100644 (file)
@@ -1,19 +1,35 @@
 #ifndef __INCLUDE_NAPI_CORE_H
 #define __INCLUDE_NAPI_CORE_H
 
+#include "../ntoskrnl/include/internal/ke.h"
+
 #define MM_CORE_DUMP_HEADER_MAGIC         (0xdeafbead)
 #define MM_CORE_DUMP_HEADER_VERSION       (0x1)
+#define MM_CORE_DUMP_TYPE_MINIMAL         (0x1)
+#define MM_CORE_DUMP_TYPE_FULL            (0x2)
 
 typedef struct _MM_CORE_DUMP_HEADER
 {
-   ULONG Magic;
-   ULONG Version;
-   CONTEXT Context;
-   ULONG DumpLength;
-   ULONG BugCode;
-   ULONG ExceptionCode;
-   ULONG Cr2;
-   ULONG Cr3;
+  ULONG Magic;
+  ULONG Version;
+  ULONG Type;
+  KTRAP_FRAME TrapFrame;
+  ULONG BugCheckCode;
+  ULONG BugCheckParameters[4];
+  PVOID FaultingStackBase;
+  ULONG FaultingStackSize;
+  ULONG PhysicalMemorySize;
 } MM_CORE_DUMP_HEADER, *PMM_CORE_DUMP_HEADER;
 
+typedef struct _MM_DUMP_POINTERS
+{
+  PVOID Context;
+  NTSTATUS (*DeviceInit)(PVOID Context);
+  NTSTATUS (*DeviceWrite)(PVOID Context, ULONG Block, PMDL Mdl);
+  NTSTATUS (*DeviceFinish)(PVOID Context);
+} MM_DUMP_POINTERS, *PMM_DUMP_POINTERS;
+
+#define FSCTL_GET_DUMP_BLOCK_MAP                     (('R' << 24) | 0xF1)
+#define IOCTL_GET_DUMP_POINTERS                      (('R' << 24) | 0xF2)
+
 #endif /* __INCLUDE_NAPI_CORE_H */
index 2b24d8c..ee2bc98 100644 (file)
@@ -6,7 +6,8 @@
 #define USER32_CALLBACK_SENDNCCREATE        (2)
 #define USER32_CALLBACK_SENDNCCALCSIZE      (3)
 #define USER32_CALLBACK_SENDCREATE          (4)
-#define USER32_CALLBACK_MAXIMUM             (5)
+#define USER32_CALLBACK_SENDGETMINMAXINFO   (5)
+#define USER32_CALLBACK_MAXIMUM             (6)
 
 typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
 {
@@ -29,14 +30,14 @@ typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS
 typedef struct _SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS
 {
   HWND Wnd;
-  CREATESTRUCT CreateStruct;
+  CREATESTRUCTW CreateStruct;
 } SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS, 
   *PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS;
 
 typedef struct _SENDCREATEMESSAGE_CALLBACK_ARGUMENTS
 {
   HWND Wnd;
-  CREATESTRUCT CreateStruct;
+  CREATESTRUCTW CreateStruct;
 } SENDCREATEMESSAGE_CALLBACK_ARGUMENTS, *PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS;
 
 typedef struct _SENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS
@@ -56,6 +57,18 @@ typedef struct _SENDNCCALCSIZEMESSAGE_CALLBACK_RESULT
 } SENDNCCALCSIZEMESSAGE_CALLBACK_RESULT, 
   *PSENDNCCALCSIZEMESSAGE_CALLBACK_RESULT;
 
+typedef struct _SENDGETMINMAXINFO_CALLBACK_ARGUMENTS
+{
+  HWND Wnd;
+  MINMAXINFO MinMaxInfo;
+} SENDGETMINMAXINFO_CALLBACK_ARGUMENTS, *PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS;
+
+typedef struct _SENDGETMINMAXINFO_CALLBACK_RESULT
+{
+  LRESULT Result;
+  MINMAXINFO MinMaxInfo;
+} SENDGETMINMAXINFO_CALLBACK_RESULT, *PSENDGETMINMAXINFO_CALLBACK_RESULT;
+
 NTSTATUS STDCALL
 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
 NTSTATUS STDCALL
@@ -64,5 +77,7 @@ NTSTATUS STDCALL
 User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
 NTSTATUS STDCALL
 User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS STDCALL
+User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
 
 #endif /* __INCLUDE_USER32_CALLBACK_H */
index ae73c33..1b6b80b 100644 (file)
@@ -28,6 +28,8 @@ INT STDCALL
 W32kGetBoxRgn(HRGN hRgn, PRECT Rect);
 HRGN STDCALL
 W32kCropRgn(HRGN hDest, HRGN hSrc, const RECT* Rect, const POINT* Point);
+HRGN STDCALL
+W32kUnionRectWithRgn(HRGN hDest, const RECT* Rect);
 
 INT
 STDCALL
index 5fa32a3..2044577 100644 (file)
@@ -59,6 +59,8 @@ Init(VOID)
     (PVOID)User32SendNCCREATEMessageForKernel;
   NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDCREATE] =
     (PVOID)User32SendCREATEMessageForKernel;
+  NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDGETMINMAXINFO] =
+    (PVOID)User32SendGETMINMAXINFOMessageForKernel;
 
   //ProcessWindowStation = CreateWindowStationW(L"WinStaName",0,GENERIC_ALL,NULL);
   //Desktop = CreateDesktopA(NULL,NULL,NULL,0,0,NULL);
index 578c8a5..49629f7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.7 2002/07/04 19:56:34 dwelch Exp $
+/* $Id: window.c,v 1.8 2002/07/17 21:04:54 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS STDCALL
+User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+  PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS CallbackArgs;
+  SENDGETMINMAXINFO_CALLBACK_RESULT Result;
+  WNDPROC Proc;
+
+  DbgPrint("User32SendGETMINAXINFOMessageForKernel.\n");
+  CallbackArgs = (PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS)Arguments;
+  if (ArgumentLength != sizeof(SENDGETMINMAXINFO_CALLBACK_ARGUMENTS))
+    {
+      DbgPrint("Wrong length.\n");
+      return(STATUS_INFO_LENGTH_MISMATCH);
+    }
+  Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
+  DbgPrint("Proc %X\n", Proc);
+  /* Call the window procedure; notice kernel messages are always unicode. */
+  Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_GETMINMAXINFO, 
+                                 0, (LPARAM)&CallbackArgs->MinMaxInfo);
+  Result.MinMaxInfo = CallbackArgs->MinMaxInfo;
+  DbgPrint("Returning result %d.\n", Result);
+  ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS);
+  /* Doesn't return. */
+}
+
 NTSTATUS STDCALL
 User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
 {
index ec00dab..93408cc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: copy.c,v 1.6 2002/06/10 21:11:56 hbirr Exp $
+/* $Id: copy.c,v 1.7 2002/07/17 21:04:55 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -84,7 +84,7 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
          CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
        }
       /*
-       * Otherwise read in a much as we can.
+       * Otherwise read in as much as we can.
        */
       else
        {
@@ -194,7 +194,8 @@ ReadCacheSegment(PCACHE_SEGMENT CacheSeg)
   return STATUS_SUCCESS;
 }
 
-NTSTATUS WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
+NTSTATUS 
+WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
 {
   ULONG Size;
   PMDL Mdl;
@@ -202,20 +203,24 @@ NTSTATUS WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
   IO_STATUS_BLOCK IoStatus;
   LARGE_INTEGER SegOffset;
 
+  CacheSeg->Dirty = FALSE;
   SegOffset.QuadPart = CacheSeg->FileOffset;
   Size = CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset;
   if (Size > CacheSeg->Bcb->CacheSegmentSize)
-  {
-    Size = CacheSeg->Bcb->CacheSegmentSize;
-  }
+    {
+      Size = CacheSeg->Bcb->CacheSegmentSize;
+    }
   Mdl = MmCreateMdl(NULL, CacheSeg->BaseAddress, Size);
   MmBuildMdlForNonPagedPool(Mdl);
-  Status = IoPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &IoStatus, TRUE);
+  Status = IoPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &IoStatus, 
+                      TRUE);
   if (!NT_SUCCESS(Status))
-  {
-    DPRINT1("IoPageWrite failed, Status %x\n", Status);
-  }
-  return Status;
+    {
+      DPRINT1("IoPageWrite failed, Status %x\n", Status);
+      CacheSeg->Dirty = TRUE;
+      return(Status);
+    }
+  return(STATUS_SUCCESS);
 }
 
 BOOLEAN STDCALL
@@ -307,8 +312,7 @@ CcCopyRead (IN PFILE_OBJECT FileObject,
       Length -= TempLength;
       ReadOffset += TempLength;
       Buffer += TempLength;
-    }
-  
+    }  
   while (Length > 0)
     {
       TempLength = min(max(Bcb->CacheSegmentSize, 65536), Length);
@@ -325,12 +329,11 @@ CcCopyRead (IN PFILE_OBJECT FileObject,
 }
 
 BOOLEAN STDCALL
-CcCopyWrite (
-   IN PFILE_OBJECT FileObject,
-   IN PLARGE_INTEGER FileOffset,
-   IN ULONG Length,
-   IN BOOLEAN Wait,
-   IN PVOID Buffer)
+CcCopyWrite (IN PFILE_OBJECT FileObject,
+            IN PLARGE_INTEGER FileOffset,
+            IN ULONG Length,
+            IN BOOLEAN Wait,
+            IN PVOID Buffer)
 {
    NTSTATUS Status;
    ULONG WriteOffset;
@@ -343,156 +346,157 @@ CcCopyWrite (
    BOOLEAN Valid;
 
    DPRINT("CcCopyWrite(FileObject %x, FileOffset %x, "
-             "Length %d, Wait %d, Buffer %x)\n",
+         "Length %d, Wait %d, Buffer %x)\n",
           FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, Buffer);
 
    Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
    WriteOffset = (ULONG)FileOffset->QuadPart;
 
    if (!Wait)
-   {
-     // testing, if the requested datas are available
-     KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
-     current_entry = Bcb->BcbSegmentListHead.Flink;
-     while (current_entry != &Bcb->BcbSegmentListHead)
      {
-       CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
-       if (!CacheSeg->Valid)
-       {
-         if ((WriteOffset >= CacheSeg->FileOffset && WriteOffset < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
-           || (WriteOffset + Length > CacheSeg->FileOffset && WriteOffset + Length <= CacheSeg->FileOffset + Bcb->CacheSegmentSize))
-         {
-           KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-           // datas not available
-           return FALSE;
-         }
-       }
-       current_entry = current_entry->Flink;
+       /* testing, if the requested datas are available */
+       KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
+       current_entry = Bcb->BcbSegmentListHead.Flink;
+       while (current_entry != &Bcb->BcbSegmentListHead)
+        {
+          CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+                                       BcbSegmentListEntry);
+          if (!CacheSeg->Valid)
+            {
+              if ((WriteOffset >= CacheSeg->FileOffset && 
+                   WriteOffset < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
+                  || (WriteOffset + Length > CacheSeg->FileOffset && 
+                      WriteOffset + Length <= CacheSeg->FileOffset + 
+                      Bcb->CacheSegmentSize))
+                {
+                  KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
+                  /* datas not available */
+                  return(FALSE);
+                }
+            }
+          current_entry = current_entry->Flink;
+        }
+       KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
      }
-     KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-   }
 
    TempLength = WriteOffset % Bcb->CacheSegmentSize;
    if (TempLength != 0)
-   {
-      TempLength = min (Length, Bcb->CacheSegmentSize - TempLength);
-      Status = CcRosRequestCacheSegment(Bcb,
-                 ROUND_DOWN(WriteOffset, Bcb->CacheSegmentSize),
-                 &BaseAddress, &Valid, &CacheSeg);
-      if (!NT_SUCCESS(Status))
-      {
-        return FALSE;
-      }
-      if (!Valid)
-      {
-         if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
-         {
-           return FALSE;
-         }
-      }
-      memcpy (BaseAddress + WriteOffset % Bcb->CacheSegmentSize, Buffer, TempLength);
-      if (!NT_SUCCESS(WriteCacheSegment(CacheSeg)))
-      {
-        return FALSE;
-      }
-      CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
-
-      Length -= TempLength;
-      WriteOffset += TempLength;
-      Buffer += TempLength;
-   }
-
-   while (Length > 0)
-   {
-      TempLength = min (Bcb->CacheSegmentSize, Length);
-      Status = CcRosRequestCacheSegment(Bcb, WriteOffset,
-                 &BaseAddress, &Valid, &CacheSeg);
-      if (!NT_SUCCESS(Status))
-      {
-         return FALSE;
-      }
-      if (!Valid && TempLength < Bcb->CacheSegmentSize)
-      {
-        if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
-        {
-          return FALSE;
-        }
-      }
-      memcpy (BaseAddress, Buffer, TempLength);
-      if (!NT_SUCCESS(WriteCacheSegment(CacheSeg)))
-      {
-        return FALSE;
-      }
-      CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
-      Length -= TempLength;
-      WriteOffset += TempLength;
-      Buffer += TempLength;
-   }
-   return TRUE;
-}
-
-BOOLEAN STDCALL
-CcZeroData (
-    IN PFILE_OBJECT     FileObject,
-    IN PLARGE_INTEGER   StartOffset,
-    IN PLARGE_INTEGER   EndOffset,
-    IN BOOLEAN          Wait
-)
-{
-   NTSTATUS Status;
-   LARGE_INTEGER WriteOffset;
-   ULONG Length;
-   PMDL Mdl;
-   ULONG i;
-   IO_STATUS_BLOCK Iosb;
-
-   DPRINT("CcZeroData(FileObject %x, StartOffset %I64x, EndOffset %I64x, Wait %d\n",
-          FileObject, StartOffset->QuadPart, EndOffset->QuadPart, Wait);
-
-   Length = EndOffset->u.LowPart - StartOffset->u.LowPart;
-
-   // FIXME: NT uses the shared chache map field for cached/non cached detection
-   if (((PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext)->Bcb == NULL)
-   {
-      // File is not cached
-
-      CHECKPOINT;
-      
-      WriteOffset.QuadPart = StartOffset->QuadPart;
-     
-      while (Length > 0)
-      {
-        if (Length + WriteOffset.u.LowPart % PAGESIZE > 262144)
-        {
-            Mdl = MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, 262144 - WriteOffset.u.LowPart % PAGESIZE);
-           WriteOffset.QuadPart += (262144 - WriteOffset.u.LowPart % PAGESIZE);
-           Length -= (262144 - WriteOffset.u.LowPart % PAGESIZE);
-        }
-        else
+     {
+       ULONG ROffset;
+       ROffset = ROUND_DOWN(WriteOffset, Bcb->CacheSegmentSize);
+       TempLength = min (Length, Bcb->CacheSegmentSize - TempLength);
+       Status = CcRosRequestCacheSegment(Bcb, ROffset,
+                                        &BaseAddress, &Valid, &CacheSeg);
+       if (!NT_SUCCESS(Status))
         {
-            Mdl = MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, Length - WriteOffset.u.LowPart % PAGESIZE);
-           WriteOffset.QuadPart += (Length - WriteOffset.u.LowPart % PAGESIZE);
-           Length = 0;
+          return(FALSE);
         }
-         if (Mdl == NULL)
+       if (!Valid)
         {
-            return FALSE;
+          if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
+            {
+              return(FALSE);
+            }
         }
-         Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
-        for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++)
+       memcpy (BaseAddress + WriteOffset % Bcb->CacheSegmentSize, 
+              Buffer, TempLength);
+       CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
+       
+       Length -= TempLength;
+       WriteOffset += TempLength;
+       Buffer += TempLength;
+     }
+   
+   while (Length > 0)
+     {
+       TempLength = min (Bcb->CacheSegmentSize, Length);
+       Status = CcRosRequestCacheSegment(Bcb, WriteOffset,
+                                        &BaseAddress, &Valid, &CacheSeg);
+       if (!NT_SUCCESS(Status))
         {
-            ((PULONG)(Mdl + 1))[i] = CcZeroPage.u.LowPart;
+          return(FALSE);
         }
-         Status = IoPageWrite(FileObject, Mdl, StartOffset, &Iosb, TRUE);
-        if (!NT_SUCCESS(Status))
+       if (!Valid && TempLength < Bcb->CacheSegmentSize)
         {
-           return FALSE;
+          if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
+            {
+              return FALSE;
+            }
         }
-      }
-   }
-   else
-   {
-      // File is cached
+       memcpy (BaseAddress, Buffer, TempLength);
+       CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
+       Length -= TempLength;
+       WriteOffset += TempLength;
+       Buffer += TempLength;
+     }
+   return(TRUE);
+}
+
+BOOLEAN STDCALL
+CcZeroData (IN PFILE_OBJECT     FileObject,
+           IN PLARGE_INTEGER   StartOffset,
+           IN PLARGE_INTEGER   EndOffset,
+           IN BOOLEAN          Wait)
+{
+  NTSTATUS Status;
+  LARGE_INTEGER WriteOffset;
+  ULONG Length;
+  PMDL Mdl;
+  ULONG i;
+  IO_STATUS_BLOCK Iosb;
+  
+  DPRINT("CcZeroData(FileObject %x, StartOffset %I64x, EndOffset %I64x, "
+        "Wait %d\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart, 
+        Wait);
+  
+  Length = EndOffset->u.LowPart - StartOffset->u.LowPart;
+
+  /* 
+   * FIXME: NT uses the shared cache map field for cached/non cached detection
+   */
+  if (((PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext)->Bcb == NULL)
+    {
+      /* File is not cached */
+      WriteOffset.QuadPart = StartOffset->QuadPart;
+      
+      while (Length > 0)
+       {
+         if (Length + WriteOffset.u.LowPart % PAGESIZE > 262144)
+           {
+             Mdl = MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, 
+                               262144 - WriteOffset.u.LowPart % PAGESIZE);
+             WriteOffset.QuadPart += 
+               (262144 - WriteOffset.u.LowPart % PAGESIZE);
+             Length -= (262144 - WriteOffset.u.LowPart % PAGESIZE);
+           }
+         else
+           {
+             Mdl = 
+               MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, 
+                           Length - WriteOffset.u.LowPart % PAGESIZE);
+             WriteOffset.QuadPart += 
+               (Length - WriteOffset.u.LowPart % PAGESIZE);
+             Length = 0;
+           }
+         if (Mdl == NULL)
+           {
+             return(FALSE);
+           }
+         Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
+         for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++)
+           {
+             ((PULONG)(Mdl + 1))[i] = CcZeroPage.u.LowPart;
+           }
+         Status = IoPageWrite(FileObject, Mdl, StartOffset, &Iosb, TRUE);
+         if (!NT_SUCCESS(Status))
+           {
+             return(FALSE);
+           }
+       }
+    }
+  else
+    {
+      /* File is cached */
       KIRQL oldirql;
       PBCB Bcb;
       PLIST_ENTRY current_entry;
@@ -503,123 +507,135 @@ CcZeroData (
       ULONG size;
       PHYSICAL_ADDRESS page;
 
-      CHECKPOINT;
       Start = StartOffset->u.LowPart;
       Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
       if (Wait)
-      {
-          // testing, if the requested datas are available
+       {
+          /* testing, if the requested datas are available */
          KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
          current_entry = Bcb->BcbSegmentListHead.Flink;
          while (current_entry != &Bcb->BcbSegmentListHead)
-         {
-            CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
-            if (!CacheSeg->Valid)
-            {
-               if ((Start >= CacheSeg->FileOffset && Start < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
-                  || (Start + Length > CacheSeg->FileOffset && 
-                      Start + Length <= CacheSeg->FileOffset + Bcb->CacheSegmentSize))
+           {
+             CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+                                          BcbSegmentListEntry);
+             if (!CacheSeg->Valid)
                {
-                  KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-                  // datas not available
-                  return FALSE;
+                 if ((Start >= CacheSeg->FileOffset && 
+                      Start < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
+                     || (Start + Length > CacheSeg->FileOffset && 
+                         Start + Length <= 
+                         CacheSeg->FileOffset + Bcb->CacheSegmentSize))
+                   {
+                     KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
+                     /* datas not available */
+                     return(FALSE);
+                   }
                }
-            }
-            current_entry = current_entry->Flink;
-         }
+             current_entry = current_entry->Flink;
+           }
          KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-      }
-
+       }
+      
       while (Length > 0)
-      {
-        WriteOffset.QuadPart = ROUND_DOWN(Start, Bcb->CacheSegmentSize);
-         if (Start % Bcb->CacheSegmentSize + Length > 262144)
-        {
-            Mdl = MmCreateMdl(NULL, NULL, 262144);
-            if (Mdl == NULL)
-            {
-               return FALSE;
-            }
-            Status = CcRosGetCacheSegmentChain (Bcb, ROUND_DOWN(Start, Bcb->CacheSegmentSize), 
-                                                262144, &CacheSeg);
-            if (!NT_SUCCESS(Status))
-            {
-               ExFreePool(Mdl);
-               return FALSE;
-            }
-        }
-        else
-        {
-            Mdl = MmCreateMdl(NULL, (PVOID)ROUND_DOWN(Start, Bcb->CacheSegmentSize), 
-                              ROUND_UP(Start % Bcb->CacheSegmentSize + Length, Bcb->CacheSegmentSize));
-            if (Mdl == NULL)
-            {
-               return FALSE;
-            }
-            Status = CcRosGetCacheSegmentChain (Bcb, ROUND_DOWN(Start, Bcb->CacheSegmentSize), 
-                                                min(ROUND_UP(Start % Bcb->CacheSegmentSize 
-                                                  + Length, Bcb->CacheSegmentSize), 
-                                                Bcb->AllocationSize.u.LowPart 
-                                                  - ROUND_DOWN(Start, Bcb->CacheSegmentSize)), 
-                                                &CacheSeg);
-            if (!NT_SUCCESS(Status))
-            {
-               ExFreePool(Mdl);
-               return FALSE;
-            }
-        }
-        Mdl->MdlFlags |= (MDL_PAGES_LOCKED|MDL_IO_PAGE_READ);
-        current = CacheSeg;
-        count = 0;
-        while (current != NULL)
-        {
-           if (Start % Bcb->CacheSegmentSize || 
-               Start % Bcb->CacheSegmentSize + Length < Bcb->CacheSegmentSize)
+       {
+         ULONG RStart = ROUND_DOWN(Start, Bcb->CacheSegmentSize);
+         WriteOffset.QuadPart = ROUND_DOWN(Start, Bcb->CacheSegmentSize);
+         if (Start % Bcb->CacheSegmentSize + Length > 262144)
            {
-               if (!current->Valid)
+             Mdl = MmCreateMdl(NULL, NULL, 262144);
+             if (Mdl == NULL)
                {
-                  // Segment lesen
-                  Status = ReadCacheSegment(current);
-                  if (!NT_SUCCESS(Status))
-                  {
-                     DPRINT1("ReadCacheSegment failed, status %x\n", Status);
-                  }
+                 return FALSE;
+               }
+             Status = CcRosGetCacheSegmentChain (Bcb, RStart,
+                                                 262144, &CacheSeg);
+             if (!NT_SUCCESS(Status))
+               {
+                 ExFreePool(Mdl);
+                 return(FALSE);
                }
-               TempLength = min (Length, Bcb->CacheSegmentSize - Start % Bcb->CacheSegmentSize);
-               memset (current->BaseAddress + Start % Bcb->CacheSegmentSize, 0, TempLength);
            }
-           else
+         else
            {
-               TempLength = Bcb->CacheSegmentSize;
-               memset (current->BaseAddress, 0, Bcb->CacheSegmentSize);
+             ULONG RLength;
+             Mdl = MmCreateMdl(NULL, (PVOID)RStart,
+                               ROUND_UP(Start % Bcb->CacheSegmentSize + 
+                                        Length, Bcb->CacheSegmentSize));
+             if (Mdl == NULL)
+               {
+                 return(FALSE);
+               }
+             RLength = ROUND_UP(RStart + Length, Bcb->CacheSegmentSize);
+             RLength = min(RLength, Bcb->AllocationSize.u.LowPart);
+             RLength -= RStart;
+             Status = CcRosGetCacheSegmentChain (Bcb, RStart, RLength,
+                                                 &CacheSeg);
+             if (!NT_SUCCESS(Status))
+               {
+                 ExFreePool(Mdl);
+                 return(FALSE);
+               }
            }
-            Start += TempLength;
-           Length -= TempLength;
-
-           size = ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG));
-           for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE) && count < size; i++)
+         Mdl->MdlFlags |= (MDL_PAGES_LOCKED|MDL_IO_PAGE_READ);
+         current = CacheSeg;
+         count = 0;
+         while (current != NULL)
+           {
+             if ((Start % Bcb->CacheSegmentSize) != 0 || 
+                 Start % Bcb->CacheSegmentSize + Length < 
+                 Bcb->CacheSegmentSize)
+               {
+                 if (!current->Valid)
+                   {
+                     /* Segment lesen */
+                     Status = ReadCacheSegment(current);
+                     if (!NT_SUCCESS(Status))
+                       {
+                         DPRINT1("ReadCacheSegment failed, status %x\n", 
+                                 Status);
+                       }
+                   }
+                 TempLength = min (Length, Bcb->CacheSegmentSize - 
+                                   Start % Bcb->CacheSegmentSize);
+                 memset (current->BaseAddress + Start % Bcb->CacheSegmentSize,
+                         0, TempLength);
+               }
+             else
+               {
+                 TempLength = Bcb->CacheSegmentSize;
+                 memset (current->BaseAddress, 0, Bcb->CacheSegmentSize);
+               }
+             Start += TempLength;
+             Length -= TempLength;
+             
+             size = ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG));
+             for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE) && 
+                    count < size; i++)
+               {
+                 PVOID Address;
+                 Address = current->BaseAddress + (i * PAGESIZE);
+                 page = 
+                   MmGetPhysicalAddressForProcess(NULL, Address);
+                 ((PULONG)(Mdl + 1))[count++] = page.u.LowPart;
+               }
+             current = current->NextInChain;
+           }
+         
+         /* Write the Segment */
+         Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Iosb, TRUE);
+         if (!NT_SUCCESS(Status))
            {
-              page = MmGetPhysicalAddressForProcess(NULL, current->BaseAddress + (i * PAGESIZE));
-              ((PULONG)(Mdl + 1))[count++] = page.u.LowPart;
+             DPRINT1("IoPageWrite failed, status %x\n", Status);
            }
-           current = current->NextInChain;
-        }
-
-        // Write the Segment
-        Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Iosb, TRUE);
-        if (!NT_SUCCESS(Status))
-        {
-           DPRINT1("IoPageWrite failed, status %x\n", Status);
-        }
-        current = CacheSeg;
-        while (current != NULL)
-        {
-           previous = current;
-           current = current->NextInChain;
-            CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
-        }
-      }
-   }
-   return TRUE;
+         current = CacheSeg;
+         while (current != NULL)
+           {
+             previous = current;
+             current = current->NextInChain;
+             CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
+           }
+       }
+    }
+  return(TRUE);
 }
 
index e8f29ef..40ce9d9 100644 (file)
@@ -66,38 +66,39 @@ CcMdlReadComplete (IN       PFILE_OBJECT    FileObject,
 }
 
 VOID STDCALL
-CcSetFileSizes (
-   IN PFILE_OBJECT FileObject,
-   IN PCC_FILE_SIZES FileSizes)
+CcSetFileSizes (IN PFILE_OBJECT FileObject,
+               IN PCC_FILE_SIZES FileSizes)
 {
   KIRQL oldirql;
   PBCB Bcb;
   PLIST_ENTRY current_entry;
   PCACHE_SEGMENT current;
 
-  DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n", FileObject, FileSizes);
+  DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n", 
+        FileObject, FileSizes);
   DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
          (ULONG)FileSizes->AllocationSize.QuadPart,
          (ULONG)FileSizes->FileSize.QuadPart,
          (ULONG)FileSizes->ValidDataLength.QuadPart);
 
   Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
-
+  
   KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
-
+  
   if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
-  {
-    current_entry = Bcb->BcbSegmentListHead.Flink;
-    while (current_entry != &Bcb->BcbSegmentListHead)
     {
-      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
-      current_entry = current_entry->Flink;
-      if (current->FileOffset > FileSizes->AllocationSize.QuadPart)
-      {
-        CcRosFreeCacheSegment(Bcb, current);
-      }
+      current_entry = Bcb->BcbSegmentListHead.Flink;
+      while (current_entry != &Bcb->BcbSegmentListHead)
+       {
+         current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+                                     BcbSegmentListEntry);
+         current_entry = current_entry->Flink;
+         if (current->FileOffset > FileSizes->AllocationSize.QuadPart)
+           {
+             CcRosFreeCacheSegment(Bcb, current);
+           }
+       }
     }
-  }
   Bcb->AllocationSize = FileSizes->AllocationSize;
   Bcb->FileSize = FileSizes->FileSize;
   KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
index 921f8fa..46b7692 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pin.c,v 1.2 2001/12/29 14:32:21 dwelch Exp $
+/* $Id: pin.c,v 1.3 2002/07/17 21:04:55 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -32,91 +32,90 @@ typedef struct _INTERNAL_BCB
 {
   PUBLIC_BCB PFCB;
   PCACHE_SEGMENT CacheSegment;
-}
-INTERNAL_BCB, *PINTERNAL_BCB;
+} INTERNAL_BCB, *PINTERNAL_BCB;
 
 BOOLEAN STDCALL
-CcMapData (
-   IN PFILE_OBJECT FileObject,
-   IN PLARGE_INTEGER FileOffset,
-   IN ULONG Length,
-   IN BOOLEAN Wait,
-   OUT PVOID *pBcb,
-   OUT PVOID *pBuffer)
+CcMapData (IN PFILE_OBJECT FileObject,
+          IN PLARGE_INTEGER FileOffset,
+          IN ULONG Length,
+          IN BOOLEAN Wait,
+          OUT PVOID *pBcb,
+          OUT PVOID *pBuffer)
 {
-   ULONG ReadOffset;
-   BOOLEAN Valid;
-   PBCB Bcb;
-   PCACHE_SEGMENT CacheSeg;
-   NTSTATUS Status;
-   PINTERNAL_BCB iBcb;
-
-   DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
-           " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
-           Length, Wait, pBcb, pBuffer);
-
-   ReadOffset = FileOffset->QuadPart;
-   Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
-
-   DPRINT("AllocationSize %d, FileSize %d\n",
+  ULONG ReadOffset;
+  BOOLEAN Valid;
+  PBCB Bcb;
+  PCACHE_SEGMENT CacheSeg;
+  NTSTATUS Status;
+  PINTERNAL_BCB iBcb;
+  ULONG ROffset;
+  
+  DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
+        " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
+        Length, Wait, pBcb, pBuffer);
+  
+  ReadOffset = FileOffset->QuadPart;
+  Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
+  
+  DPRINT("AllocationSize %d, FileSize %d\n",
          (ULONG)Bcb->AllocationSize.QuadPart,
          (ULONG)Bcb->FileSize.QuadPart);
-
-   if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
-   {
-      return FALSE;
-   }
-   Status = CcRosRequestCacheSegment(Bcb,
-               ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize),
-               pBuffer,
-               &Valid,
-               &CacheSeg);
-   if (!NT_SUCCESS(Status))
-   {
-      return FALSE;
-   }
-   if (!Valid)
-   {
+  
+  if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
+    {
+      return(FALSE);
+    }
+  ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
+  Status = CcRosRequestCacheSegment(Bcb,
+                                   ROffset,
+                                   pBuffer,
+                                   &Valid,
+                                   &CacheSeg);
+  if (!NT_SUCCESS(Status))
+    {
+      return(FALSE);
+    }
+  if (!Valid)
+    {
       if (!Wait)
-      {
+       {
           CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
-             return FALSE;
-      }
+         return(FALSE);
+       }
       if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
-      {
-        return FALSE;
-      }
-   }
-   *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
-   iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB));
-   if (iBcb == NULL)
-   {
-     CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
-     return FALSE;
-   }
-   iBcb->CacheSegment = CacheSeg;
-   iBcb->PFCB.MappedLength = Length;
-   iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
-   *pBcb = (PVOID)iBcb;
-   return TRUE;
+       {
+         return(FALSE);
+       }
+    }
+  *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
+  iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB));
+  if (iBcb == NULL)
+    {
+      CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
+      return FALSE;
+    }
+  iBcb->CacheSegment = CacheSeg;
+  iBcb->PFCB.MappedLength = Length;
+  iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
+  *pBcb = (PVOID)iBcb;
+  return(TRUE);
 }
 
 VOID STDCALL
-CcUnpinData (
-   IN PVOID Bcb)
+CcUnpinData (IN PVOID Bcb)
 {
-   PINTERNAL_BCB iBcb = Bcb;
-   CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, FALSE, FALSE);
-   ExFreePool(iBcb);
+  PINTERNAL_BCB iBcb = Bcb;
+  CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, 
+                          FALSE, FALSE);
+  ExFreePool(iBcb);
 }
 
 VOID STDCALL
-CcSetDirtyPinnedData (
-    IN PVOID Bcb,
-    IN PLARGE_INTEGER Lsn)
+CcSetDirtyPinnedData (IN PVOID Bcb,
+                     IN PLARGE_INTEGER Lsn)
 {
    PINTERNAL_BCB iBcb = Bcb;
-   // FIXME: write only the modifyed 4-pages back
+   /* FIXME: write only the modifyed 4-pages back */
    WriteCacheSegment(iBcb->CacheSegment);
 }
 
index 0715e33..f381ea2 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: view.c,v 1.43 2002/06/10 21:11:56 hbirr Exp $
+/* $Id: view.c,v 1.44 2002/07/17 21:04:55 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -62,8 +62,6 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-extern void * alloca(size_t);
-
 /* GLOBALS *******************************************************************/
 
 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
@@ -144,26 +142,32 @@ CcRosReleaseCacheSegment(PBCB Bcb,
                         BOOLEAN Dirty,
                         BOOLEAN Mapped)
 {
-   DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
-         Bcb, CacheSeg, Valid);
-   
-   CacheSeg->Valid = Valid;
-   CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
-   if (Mapped)
-     {
-       CacheSeg->MappedCount++;
-     }
-   ExReleaseFastMutex(&CacheSeg->Lock);
-   ExAcquireFastMutex(&ViewLock);
-   RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry);
-   InsertTailList(&CacheSegmentLRUListHead, 
-                 &CacheSeg->CacheSegmentLRUListEntry);
-   ExReleaseFastMutex(&ViewLock);
-   InterlockedDecrement(&CacheSeg->ReferenceCount);
+  BOOLEAN WasDirty = CacheSeg->Dirty;
 
-   DPRINT("CcReleaseCachePage() finished\n");
-   
-   return(STATUS_SUCCESS);
+  DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
+        Bcb, CacheSeg, Valid);
+  
+  CacheSeg->Valid = Valid;
+  CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
+  if (Mapped)
+    {
+      CacheSeg->MappedCount++;
+    }
+  ExReleaseFastMutex(&CacheSeg->Lock);
+  ExAcquireFastMutex(&ViewLock);
+  if (!WasDirty && CacheSeg->Dirty)
+    {
+      InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
+    }
+  RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry);
+  InsertTailList(&CacheSegmentLRUListHead, 
+                &CacheSeg->CacheSegmentLRUListEntry);
+  ExReleaseFastMutex(&ViewLock);
+  InterlockedDecrement(&CacheSeg->ReferenceCount);
+  
+  DPRINT("CcReleaseCachePage() finished\n");
+  
+  return(STATUS_SUCCESS);
 }
 
 PCACHE_SEGMENT CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
@@ -510,11 +514,34 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
 {
    PLIST_ENTRY current_entry;
    PCACHE_SEGMENT current;
+   NTSTATUS Status;
    
    DPRINT("CcRosReleaseFileCache(FileObject %x, Bcb %x)\n", Bcb->FileObject, 
          Bcb);
 
    MmFreeSectionSegments(Bcb->FileObject);
+
+   /*
+    * Write back dirty cache segments.
+    */
+   current_entry = Bcb->BcbSegmentListHead.Flink;
+   while (current_entry != &Bcb->BcbSegmentListHead)
+     {
+       current = 
+         CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
+       if (current->Dirty)
+        {
+          Status = WriteCacheSegment(current);
+          if (!NT_SUCCESS(Status))
+            {
+              DPRINT1("Failed to write cache segment (Status %X)\n", Status);
+            }
+          ExAcquireFastMutex(&ViewLock);
+          RemoveEntryList(&current->DirtySegmentListEntry);
+          ExReleaseFastMutex(&ViewLock);
+        }
+       current_entry = current_entry->Flink;
+     }
    
    /*
     * Release all cache segments.
index bc96180..75cc857 100644 (file)
@@ -18,6 +18,7 @@ typedef struct _WINSTATION_OBJECT
   LIST_ENTRY DesktopListHead;
   PRTL_ATOM_TABLE AtomTable;
   PVOID HandleTable;
+  struct _DESKTOP_OBJECT* ActiveDesktop;
   /* FIXME: Clipboard */
 } WINSTATION_OBJECT, *PWINSTATION_OBJECT;
 
@@ -28,8 +29,15 @@ typedef struct _DESKTOP_OBJECT
   LIST_ENTRY ListEntry;
   KSPIN_LOCK Lock;
   UNICODE_STRING Name;
+  /* Pointer to the associated window station. */
   struct _WINSTATION_OBJECT *WindowStation;
+  /* Head of the list of windows in this desktop. */
   LIST_ENTRY WindowListHead;
+  /* Pointer to the active queue. */
+  PVOID ActiveMessageQueue;
+  /* Handle of the desktop window. */
+  HANDLE DesktopWindow;
+  HANDLE PrevActiveWindow;
 } DESKTOP_OBJECT, *PDESKTOP_OBJECT;
 
 
index e5dd92c..f795cee 100644 (file)
@@ -538,5 +538,13 @@ extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
 PMM_PAGEOP
 MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
                 PMM_SECTION_SEGMENT Segment, ULONG Offset);
+struct _KTRAP_FRAME;
+NTSTATUS STDCALL 
+MmDumpToPagingFile(ULONG BugCode,
+                  ULONG BugCodeParameter1,
+                  ULONG BugCodeParameter2,
+                  ULONG BugCodeParameter3,
+                  ULONG BugCodeParameter4,
+                  struct _KTRAP_FRAME* TrapFrame);
 
 #endif
index 145ee64..2b50b17 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bug.c,v 1.23 2002/05/14 21:19:18 dwelch Exp $
+/* $Id: bug.c,v 1.24 2002/07/17 21:04:55 dwelch Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/bug.c
@@ -81,8 +81,13 @@ KeBugCheckWithTf(ULONG BugCheckCode,
                 ULONG BugCheckParameter4,
                 PKTRAP_FRAME Tf)
 {
+  KIRQL oldIrql;
+  KeRaiseIrql(HIGH_LEVEL, &oldIrql);
   DbgPrint("Bug detected code: 0x%X\n", BugCheckCode);
   KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
+  MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, 
+                    BugCheckParameter2, BugCheckParameter3,
+                    BugCheckParameter4, Tf);
   for(;;);
 }
 
@@ -104,7 +109,6 @@ KeBugCheckEx(ULONG BugCheckCode,
   PRTL_MESSAGE_RESOURCE_ENTRY Message;
   NTSTATUS Status;
   
-  /* PJS: disable interrupts first, then do the rest */
   __asm__("cli\n\t");
   DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
           BugCheckCode,
@@ -150,8 +154,10 @@ KeBugCheckEx(ULONG BugCheckCode,
               PsGetCurrentThread(),
               PsGetCurrentThread()->Cid.UniqueThread);
     }
-//   PsDumpThreads();
   KeDumpStackFrames((PULONG)__builtin_frame_address(0));
+  MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, 
+                    BugCheckParameter2, BugCheckParameter3,
+                    BugCheckParameter4, NULL);
   
   if (KdDebuggerEnabled)
     {
index 038003b..30bcc26 100644 (file)
@@ -423,13 +423,15 @@ KiDoubleFaultHandler(VOID)
 }
 
 VOID
-KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2)
+KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG Parameter1, ULONG Parameter2)
 {
   unsigned int cr3;
   unsigned int i;
   ULONG StackLimit;
   PULONG Frame;
   ULONG Esp0;
+  ULONG ExceptionNr = (ULONG)Tf->DebugArgMark;
+  ULONG cr2 = (ULONG)Tf->DebugPointer;
 
   Esp0 = (ULONG)Tf;
   
@@ -519,11 +521,15 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
    NTSTATUS Status;
    ULONG Esp0;
 
+   /* Store the exception number in an unused field in the trap frame. */
+   Tf->DebugArgMark = (PVOID)ExceptionNr;
+
    /* Use the address of the trap frame as approximation to the ring0 esp */
    Esp0 = (ULONG)&Tf->Eip;
   
    /* Get CR2 */
    __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
+   Tf->DebugPointer = (PVOID)cr2;
    
    /*
     * If this was a V86 mode exception then handle it specially
index 249463c..27343e7 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: trap.s,v 1.12 2002/01/27 01:11:23 dwelch Exp $
+/* $Id: trap.s,v 1.13 2002/07/17 21:04:55 dwelch Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/trap.s
@@ -136,8 +136,9 @@ _KiTrapProlog:
        pushl   $0     /* XXX: TempCS */
        pushl   $0     /* XXX: DebugPointer */
        pushl   $0     /* XXX: DebugArgMark */
-       pushl   $0     /* XXX: DebugEIP */
-       pushl   $0     /* XXX: DebugEBP */
+       movl    0x60(%esp), %ebx
+       pushl   %ebx   /* XXX: DebugEIP */
+       pushl   %ebp   /* XXX: DebugEBP */
 
        /* Load the segment registers */
        movl    $KERNEL_DS, %ebx
@@ -150,10 +151,14 @@ _KiTrapProlog:
        movw    %bx,%es
 
        movl    %esp, %ebx
-
+       movl    %esp, %ebp
+       
        /* Save a pointer to the trap frame in the current KTHREAD */
-       movl  %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
-
+       cmpl    $0, %edi
+       je      .L6
+       movl    %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
+.L6:   
+       
        /* Call the C exception handler */
        pushl   %esi
        pushl   %ebx
@@ -172,7 +177,7 @@ _KiTrapProlog:
 .L4:
        pushl   $0      
        jmp     .L3     
-                               
+                                       
 .globl _KiTrap0
 _KiTrap0:
        /* No error code */
index b60e383..589fe7f 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: kthread.c,v 1.28 2002/07/10 15:13:33 ekohl Exp $
+/* $Id: kthread.c,v 1.29 2002/07/17 21:04:55 dwelch Exp $
  *
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Microkernel thread support
@@ -233,12 +233,12 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
   /*
    * Initialize ReactOS specific members
    */
-   Thread->ProcessThreadListEntry.Flink = NULL;
-   Thread->ProcessThreadListEntry.Blink = NULL;
-   KeInitializeDpc(&Thread->TimerDpc,
-                  (PKDEFERRED_ROUTINE)PiTimeoutThread,
-                  Thread);
-   Thread->LastEip = 0;
+  Thread->ProcessThreadListEntry.Flink = NULL;
+  Thread->ProcessThreadListEntry.Blink = NULL;
+  KeInitializeDpc(&Thread->TimerDpc,
+                 (PKDEFERRED_ROUTINE)PiTimeoutThread,
+                 Thread);
+  Thread->LastEip = 0;
    
    /*
     * Do x86 specific part
index 5fc540d..3ec66b8 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: main.c,v 1.128 2002/06/27 17:47:55 ekohl Exp $
+/* $Id: main.c,v 1.129 2002/07/17 21:04:55 dwelch Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c
@@ -507,10 +507,10 @@ ExpInitializeExecutive(VOID)
   NtEarlyInitVdm();
   
   MmInit1(FirstKrnlPhysAddr,
-    LastKrnlPhysAddr,
-    LastKernelAddress,
-    (PADDRESS_RANGE)&KeMemoryMap,
-    KeMemoryMapRangeCount);
+         LastKrnlPhysAddr,
+         LastKernelAddress,
+         (PADDRESS_RANGE)&KeMemoryMap,
+         KeMemoryMapRangeCount);
   
   /* create default nls tables */
   RtlpInitNlsTables();
@@ -613,6 +613,7 @@ ExpInitializeExecutive(VOID)
   /*
    * Initalize services loaded at boot time
    */
+  *(PULONG)0 = 0;
   DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
   for (i=0; i < KeLoaderBlock.ModsCount; i++)
     {
index 969a8c5..b6a1584 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: loader.c,v 1.115 2002/07/13 12:44:08 chorns Exp $
+/* $Id: loader.c,v 1.116 2002/07/17 21:04:56 dwelch Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -1554,7 +1554,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase,
       CPRINT("Failed to allocate a virtual section for driver\n");
       return STATUS_UNSUCCESSFUL;
     }
-   CPRINT("DriverBase: %x\n", DriverBase);
+  DbgPrint("DriverBase for %wZ: %x\n", FileName, DriverBase);
   CHECKPOINT;
   /*  Copy headers over */
   memcpy(DriverBase, ModuleLoadBase, PEOptionalHeader->SizeOfHeaders);
index 2e4d14d..e3d7e94 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mminit.c,v 1.35 2002/06/04 15:26:57 dwelch Exp $
+/* $Id: mminit.c,v 1.36 2002/07/17 21:04:56 dwelch Exp $
  *
  * COPYRIGHT:   See COPYING in the top directory
  * PROJECT:     ReactOS kernel 
@@ -267,7 +267,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
     */
 #ifndef MP
    /* FIXME: This is broken in SMP mode */
-   //MmDeletePageTable(NULL, 0);
+   MmDeletePageTable(NULL, 0);
 #endif
    /*
     * Free all pages not used for kernel memory
index 07e1ee9..1c6b265 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: pagefile.c,v 1.20 2002/05/14 21:19:19 dwelch Exp $
+/* $Id: pagefile.c,v 1.21 2002/07/17 21:04:56 dwelch Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/pagefile.c
@@ -32,6 +32,7 @@
 #include <internal/io.h>
 #include <internal/mm.h>
 #include <napi/core.h>
+#include <internal/ps.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -90,10 +91,12 @@ static ULONG MiReservedSwapPages;
  */
 #define MM_PAGEFILE_COMMIT_GRACE      (256)
 
-#if 0
 static PVOID MmCoreDumpPageFrame;
-static BYTE MmCoreDumpHeader[PAGESIZE];
-#endif
+static PULONG MmCoreDumpBlockMap;
+static ULONG MmCoreDumpSize;
+static PULONG MmCoreDumpBlockMap = NULL;
+static MM_DUMP_POINTERS MmCoreDumpDeviceFuncs;
+DWORD MmCoreDumpType;
 
 /*
  * Translate between a swap entry and a file and offset pair.
@@ -196,6 +199,19 @@ MmInitPagingFile(VOID)
        PagingFileList[i] = NULL;
      }
    MiPagingFileCount = 0;
+
+   /*
+    * Initialize the crash dump support.
+    */
+   MmCoreDumpPageFrame = MmAllocateSection(PAGESIZE);
+   if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
+     {
+       MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
+     }
+   else
+     {
+       MmCoreDumpSize = 1024 * 1024;
+     }
 }
 
 BOOLEAN
@@ -341,27 +357,137 @@ MmAllocSwapPage(VOID)
    return(0);
 }
 
-#if 0
-NTSTATUS STDCALL MmDumpToPagingFile(PCONTEXT Context,
-                                   ULONG BugCode,
-                                   ULONG ExceptionCode,
-                                   ULONG Cr2)
+NTSTATUS STDCALL 
+MmDumpToPagingFile(ULONG BugCode,
+                  ULONG BugCodeParameter1,
+                  ULONG BugCodeParameter2,
+                  ULONG BugCodeParameter3,
+                  ULONG BugCodeParameter4,
+                  PKTRAP_FRAME TrapFrame)
 {
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->Magic = 
-     MM_CORE_DUMP_HEADER_MAGIC;
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->Version = 
-     MM_CORE_DUMP_HEADER_VERSION;
-   memcpy(&((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->Context,
-         Context,
-         sizeof(CONTEXT));
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->DumpLength = 0;
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->BugCode = BugCode;
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->ExceptionCode = 
-     ExceptionCode;
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->Cr2 = Cr2;
-   ((PMM_CORE_DUMP_HEADER)MmCoreDumpHeader)->Cr3 = 0;
+  PMM_CORE_DUMP_HEADER Headers;
+  PVOID Context;
+  NTSTATUS Status;
+  UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)];
+  PMDL Mdl = (PMDL)MdlBase;
+  PETHREAD Thread = PsGetCurrentThread();
+  ULONG StackSize;
+  PULONG MdlMap;
+  ULONG NextOffset = 0;
+  ULONG i;
+
+  if (MmCoreDumpBlockMap == NULL)
+    {
+      return(STATUS_UNSUCCESSFUL);
+    }
+
+  DbgPrint("MM: Dumping core");
+
+  /* Prepare the dump headers. */
+  Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
+  Headers->Magic = MM_CORE_DUMP_HEADER_MAGIC;
+  Headers->Version = MM_CORE_DUMP_HEADER_VERSION;
+  Headers->Type = MmCoreDumpType;
+  if (TrapFrame != NULL)
+    {
+      if (!(TrapFrame->Eflags & (1 << 17)))
+       {
+         memcpy(&Headers->TrapFrame, TrapFrame, 
+                sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
+       }
+      else
+       {
+         memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME));
+       }
+    }
+  Headers->BugCheckCode = BugCode;
+  Headers->BugCheckParameters[0] = BugCodeParameter1;
+  Headers->BugCheckParameters[1] = BugCodeParameter2;
+  Headers->BugCheckParameters[2] = BugCodeParameter3;
+  Headers->BugCheckParameters[3] = BugCodeParameter4;
+  Headers->FaultingStackBase = (PVOID)Thread->Tcb.StackLimit;
+  Headers->FaultingStackSize = StackSize =
+    (ULONG)(Thread->Tcb.StackBase - Thread->Tcb.StackLimit);
+  Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGESIZE;
+
+  /* Initialize the dump device. */
+  Context = MmCoreDumpDeviceFuncs.Context;
+  Status = MmCoreDumpDeviceFuncs.DeviceInit(Context);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("MM: Failed to initialize core dump device.\n");
+      return(Status);
+    }
+
+  /* Initialize the MDL. */
+  Mdl->Next = NULL;
+  Mdl->Size = sizeof(MDL) + sizeof(PVOID);
+  Mdl->MdlFlags = MDL_SOURCE_IS_NONPAGED_POOL;
+  Mdl->Process = NULL;
+  Mdl->MappedSystemVa = MmCoreDumpPageFrame;
+  Mdl->StartVa = NULL;
+  Mdl->ByteCount = PAGESIZE;
+  Mdl->ByteOffset = 0;
+  MdlMap = (PULONG)(Mdl + 1);
+
+  /* Dump the header. */
+  MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart;
+  Status = MmCoreDumpDeviceFuncs.DeviceWrite(Context, 
+                                            MmCoreDumpBlockMap[NextOffset], 
+                                            Mdl);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("MM: Failed to write core dump header\n.");
+    }
+  NextOffset++;
+  DbgPrint(".");
+
+  /* Write out the kernel mode stack of the faulting thread. */
+  for (i = 0; i < (StackSize / PAGESIZE); i++)
+    {
+      Mdl->MappedSystemVa = (PVOID)(Thread->Tcb.StackLimit + (i * PAGESIZE));
+      MdlMap[0] = MmGetPhysicalAddress(Mdl->MappedSystemVa).u.LowPart;      
+      Status = 
+       MmCoreDumpDeviceFuncs.DeviceWrite(Context, 
+                                         MmCoreDumpBlockMap[NextOffset],
+                                         Mdl);
+      if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("MM: Failed to write page to core dump.\n");
+         return(Status);
+       }
+      DbgPrint(".");
+      NextOffset++;
+    }
+
+  /* Write out the contents of physical memory. */
+  if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
+    {
+      for (i = 0; i < MmStats.NrTotalPages; i++)
+       {
+         LARGE_INTEGER PhysicalAddress;
+         PhysicalAddress.QuadPart = i * PAGESIZE;
+         MdlMap[0] = i * PAGESIZE;
+         MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
+                                         PAGE_READWRITE,
+                                         PhysicalAddress);
+         Status = 
+           MmCoreDumpDeviceFuncs.DeviceWrite(Context, 
+                                             MmCoreDumpBlockMap[NextOffset],
+                                             Mdl);
+         if (!NT_SUCCESS(Status))
+           {
+             DPRINT1("MM: Failed to write page to core dump.\n");
+             return(Status);
+           }
+         DbgPrint(".");
+         NextOffset++;
+       }
+    }
+
+  DbgPrint("\n");
+  return(STATUS_SUCCESS);
 }
-#endif
 
 NTSTATUS STDCALL
 NtCreatePagingFile(IN PUNICODE_STRING FileName,
@@ -443,12 +569,11 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
        return(Status);
      }
    
-   NtClose(FileHandle);
-   
    PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile));
    if (PagingFile == NULL)
      {
        ObDereferenceObject(FileObject);
+       NtClose(FileHandle);
        return(STATUS_NO_MEMORY);
      }
    
@@ -466,9 +591,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
    
    if (PagingFile->AllocMap == NULL)
      {
-       ExFreePool(PagingFile);
-       ObDereferenceObject(FileObject);
-       return(STATUS_NO_MEMORY);
+       ExFreePool(PagingFile);
+       ObDereferenceObject(FileObject);
+       NtClose(FileHandle);
+       return(STATUS_NO_MEMORY);
      }
    
    KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
@@ -484,6 +610,57 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
    MiPagingFileCount++;
    KeReleaseSpinLock(&PagingFileListLock, oldIrql);
    
+   /* Check whether this pagefile can be a crash dump target. */
+   if (PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
+       MmCoreDumpBlockMap != NULL)
+     {
+       MmCoreDumpBlockMap = 
+        ExAllocatePool(NonPagedPool, 
+                       (MmCoreDumpSize / PAGESIZE) * sizeof(ULONG));
+       if (MmCoreDumpBlockMap == NULL)
+        {
+          DPRINT1("Failed to allocate block map.\n");
+          NtClose(FileHandle);
+          return(STATUS_SUCCESS);
+        }
+       Status = ZwFsControlFile(FileHandle,
+                               NULL,
+                               NULL,
+                               NULL,
+                               &IoStatus,
+                               FSCTL_GET_DUMP_BLOCK_MAP,
+                               &MmCoreDumpSize,
+                               sizeof(ULONG),
+                               MmCoreDumpBlockMap,
+                               (MmCoreDumpSize / PAGESIZE) * sizeof(ULONG));
+       if (!NT_SUCCESS(Status))
+        {
+          DPRINT1("Failed to get dump block map (Status %X)\n", Status);
+          NtClose(FileHandle);
+          ExFreePool(MmCoreDumpBlockMap);
+          MmCoreDumpBlockMap = NULL;
+          return(STATUS_SUCCESS);
+        }
+       Status = ZwDeviceIoControlFile(FileHandle,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     &IoStatus,
+                                     IOCTL_GET_DUMP_POINTERS,
+                                     NULL,
+                                     0,
+                                     &MmCoreDumpDeviceFuncs,
+                                     sizeof(MmCoreDumpDeviceFuncs));
+       if (!NT_SUCCESS(Status))
+        {
+          DPRINT1("Failed to get dump block map (Status %X)\n", Status);
+          NtClose(FileHandle);
+          ExFreePool(MmCoreDumpBlockMap);
+          MmCoreDumpBlockMap = NULL;
+          return(STATUS_SUCCESS);
+        }
+     }
+   NtClose(FileHandle);
    return(STATUS_SUCCESS);
 }
 
index de46ed3..9d1b0c3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: object.c,v 1.51 2002/06/20 21:31:39 ekohl Exp $
+/* $Id: object.c,v 1.52 2002/07/17 21:04:56 dwelch Exp $
  * 
  * COPYRIGHT:     See COPYING in the top level directory
  * PROJECT:       ReactOS kernel
@@ -321,7 +321,10 @@ ObCreateObject(OUT PHANDLE Handle,
     }
   RtlFreeUnicodeString( &RemainingPath );
 
-  *Object = HEADER_TO_BODY(Header);
+  if (Object != NULL)
+    {
+      *Object = HEADER_TO_BODY(Header);
+    }
 
   if (Handle != NULL)
   {
index 24ba6d6..771748b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.85 2002/07/13 12:44:08 chorns Exp $
+/* $Id: process.c,v 1.86 2002/07/17 21:04:56 dwelch Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
@@ -194,7 +194,6 @@ PiKillMostProcesses(VOID)
 VOID
 PsInitProcessManagment(VOID)
 {
-
    PKPROCESS KProcess;
    KIRQL oldIrql;
    NTSTATUS Status;
@@ -970,7 +969,6 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
        
       case ProcessImageFileName:
        memcpy(Process->ImageFileName, ProcessInformation, 8);
-//      DPRINT1("Process->ImageFileName %.8s\n", Process->ImageFileName);
        Status = STATUS_SUCCESS;
        break;
        
@@ -996,6 +994,11 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
       case ProcessWow64Information:
       default:
        Status = STATUS_INVALID_INFO_CLASS;
+
+     case ProcessDesktop:
+       Process->Win32Desktop = *(PHANDLE)ProcessInformation;
+       Status = STATUS_SUCCESS;
+       break;
      }
    ObDereferenceObject(Process);
    return(Status);
index 89485fd..97e5e46 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: winlogon.c,v 1.9 2002/06/11 22:09:03 dwelch Exp $
+/* $Id: winlogon.c,v 1.10 2002/07/17 21:04:57 dwelch Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -204,36 +204,37 @@ WinMain(HINSTANCE hInstance,
        int nShowCmd)
 {
 #if 0
-   LSA_STRING ProcessName;
-   NTSTATUS Status;
-   HANDLE LsaHandle;
-   LSA_OPERATIONAL_MODE Mode;
+  LSA_STRING ProcessName;
+  NTSTATUS Status;
+  HANDLE LsaHandle;
+  LSA_OPERATIONAL_MODE Mode;
 #endif
-   CHAR LoginPrompt[] = "login:";
-   CHAR PasswordPrompt[] = "password:";
-   DWORD Result;
-   CHAR LoginName[255];
-   CHAR Password[255];
-   BOOL Success;
-   ULONG i;
-
-   /*
-    * FIXME: Create a security descriptor with
-    *        one ACE containing the Winlogon SID
-    */
-
-   /*
-    * Create the interactive window station
-    */
-   InteractiveWindowStation = CreateWindowStationW(
-      L"WinSta0", 0, GENERIC_ALL, NULL);
+  CHAR LoginPrompt[] = "login:";
+  CHAR PasswordPrompt[] = "password:";
+  DWORD Result;
+  CHAR LoginName[255];
+  CHAR Password[255];
+  BOOL Success;
+  ULONG i;
+  NTSTATUS Status;
+  
+  /*
+   * FIXME: Create a security descriptor with
+   *        one ACE containing the Winlogon SID
+   */
+  
+  /*
+   * Create the interactive window station
+   */
+   InteractiveWindowStation = 
+     CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL);
    if (InteractiveWindowStation == NULL)
      {
        DbgPrint("Failed to create window station (0x%X)\n", GetLastError());
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
        ExitProcess(1);
      }
-
+   
    /*
     * Set the process window station
     */
@@ -242,46 +243,53 @@ WinMain(HINSTANCE hInstance,
    /*
     * Create the application desktop
     */
-   ApplicationDesktop = CreateDesktopW(
-      L"Default",
-      NULL,
-      NULL,
-      0,      /* FIXME: Set some flags */
-      GENERIC_ALL,
-      NULL);  /* FIXME: Create security descriptor (access to all) */
+   ApplicationDesktop = 
+     CreateDesktopW(L"Default",
+                   NULL,
+                   NULL,
+                   0,      /* FIXME: Set some flags */
+                   GENERIC_ALL,
+                   NULL); 
 
    /*
     * Create the winlogon desktop
     */
-   WinlogonDesktop = CreateDesktopW(
-      L"Winlogon",
-      NULL,
-      NULL,
-      0,      /* FIXME: Set some flags */
-      GENERIC_ALL,
-      NULL);  /* FIXME: Create security descriptor (access for winlogon only) */
-
+   WinlogonDesktop = CreateDesktopW(L"Winlogon",
+                                   NULL,
+                                   NULL,
+                                   0,      /* FIXME: Set some flags */
+                                   GENERIC_ALL,
+                                   NULL);  
+   
    /*
     * Create the screen saver desktop
     */
-   ScreenSaverDesktop = CreateDesktopW(
-      L"Screen-Saver",
-      NULL,
-      NULL,
-      0,      /* FIXME: Set some flags */
-      GENERIC_ALL,
-      NULL);  /* FIXME: Create security descriptor (access to all) */
-
+   ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver",
+                                      NULL,
+                                      NULL,
+                                      0,      /* FIXME: Set some flags */
+                                      GENERIC_ALL,
+                                      NULL);  
+   
    /*
     * Switch to winlogon desktop
     */
-   Success = SwitchDesktop(WinlogonDesktop);
+   /* FIXME: Do start up in the application desktop for now. */
+   Status = NtSetInformationProcess(NtCurrentProcess(),
+                                   ProcessDesktop,
+                                   &ApplicationDesktop,
+                                   sizeof(ApplicationDesktop));
+   if (!NT_SUCCESS(Status))
+     {
+       DbgPrint("WL: Cannot set default desktop for winlogon.\n");
+     }
+   SetThreadDesktop(ApplicationDesktop);
+   Success = SwitchDesktop(ApplicationDesktop);
    if (!Success)
-   {
-      DbgPrint("Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
-   }
-
-
+     {
+       DbgPrint("Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
+     }
+   
    AllocConsole();
    SetConsoleTitle( "Winlogon" );
    /* start system processes (services.exe & lsass.exe) */
@@ -296,7 +304,7 @@ WinMain(HINSTANCE hInstance,
    Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
    if (!NT_SUCCESS(Status))
      {
-       DbgPrint("WL: Failed to connect to lsass\n");
+       DbgPrint("WL: Failed to connect to lsass\n");
        return(1);
      }
 #endif
@@ -306,51 +314,51 @@ WinMain(HINSTANCE hInstance,
     *        Register SAS with the window.
     *        Register for logoff notification
     */
-
+   
    /* Main loop */
    for (;;)
      {
 #if 0
-       /* Display login prompt */
-       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
-                    LoginPrompt,
-                    strlen(LoginPrompt),  // wcslen(LoginPrompt),
-                    &Result,
-                    NULL);
-       i = 0;
-       do
-         {
-            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
-                        &LoginName[i],
-                        1,
-                        &Result,
-                        NULL);
-            i++;
-         } while (LoginName[i - 1] != '\n');
-       LoginName[i - 1] = 0;
-       
+       /* Display login prompt */
+       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
+                   LoginPrompt,
+                   strlen(LoginPrompt),  // wcslen(LoginPrompt),
+                   &Result,
+                   NULL);
+       i = 0;
+       do
+        {
+          ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                      &LoginName[i],
+                      1,
+                      &Result,
+                      NULL);
+          i++;
+        } while (LoginName[i - 1] != '\n');
+       LoginName[i - 1] = 0;
+       
        /* Display password prompt */
-       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
-                    PasswordPrompt,
-                    strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
-                    &Result,
-                    NULL);
-       i = 0;
-       do
-         {
-            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
-                        &Password[i],
-                        1,
-                        &Result,
-                        NULL);
-            i++;
-         } while (Password[i - 1] != '\n');
-       Password[i - 1] =0;
+       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
+                   PasswordPrompt,
+                   strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
+                   &Result,
+                   NULL);
+       i = 0;
+       do
+        {
+          ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                      &Password[i],
+                      1,
+                      &Result,
+                      NULL);
+          i++;
+        } while (Password[i - 1] != '\n');
+       Password[i - 1] =0;
 #endif
-       DoLoginUser(LoginName, Password);
+       DoLoginUser(LoginName, Password);
      }
-
+   
    ExitProcess(0);
-
+   
    return 0;
 }
index 21cab96..ef1bae9 100644 (file)
@@ -8,9 +8,15 @@ W32kCallWindowProc(WNDPROC Proc,
                   WPARAM wParam,
                   LPARAM lParam);
 LRESULT STDCALL
-W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct);
+W32kCallTrampolineWindowProc(WNDPROC Proc,
+                            HWND Wnd,
+                            UINT Message,
+                            WPARAM wParam,
+                            LPARAM lParam);
 LRESULT STDCALL
-W32kSendCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct);
+W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCTW* CreateStruct);
+LRESULT STDCALL
+W32kSendCREATEMessage(HWND Wnd, CREATESTRUCTW* CreateStruct);
 VOID STDCALL
 W32kCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
                            HWND hWnd,
@@ -20,5 +26,7 @@ W32kCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
 LRESULT STDCALL
 W32kSendNCCALCSIZEMessage(HWND Wnd, BOOL Validate, RECT Rect1,
                          RECT Rect2, RECT Rect3, PWINDOWPOS Pos);
+LRESULT STDCALL
+W32kSendGETMINMAXINFOMessage(HWND Wnd, MINMAXINFO* MinMaxInfo);
 
 #endif /* __SUBSYS_WIN32K_INCLUDE_CALLBACK_H */
index 87a8787..ca3af54 100644 (file)
@@ -33,6 +33,9 @@ ClassReferenceClassByAtom(PWNDCLASS_OBJECT *Class,
 NTSTATUS
 ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class,
                                LPWSTR ClassNameOrAtom);
+PWNDCLASS_OBJECT
+W32kCreateClass(LPWNDCLASSEX lpwcx,
+               BOOL bUnicodeClass);
 
 #endif /* __WIN32K_CLASS_H */
 
index 47d7ba1..170926e 100644 (file)
@@ -58,6 +58,10 @@ typedef struct _USER_MESSAGE_QUEUE
   BOOLEAN PaintPosted;
   /* Count of paints pending. */
   ULONG PaintCount;
+  /* Current active window for this queue. */
+  HWND ActiveWindow;
+  /* Current capture window for this queue. */
+  HWND CaptureWindow;
 } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
 
 VOID
@@ -103,6 +107,12 @@ MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue);
 VOID
 MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
                     PUSER_SENT_MESSAGE_NOTIFY NotifyMessage);
+LRESULT STDCALL
+W32kSendMessage(HWND hWnd,
+               UINT Msg,
+               WPARAM wParam,
+               LPARAM lParam,
+               BOOL KernelMessage);
 
 #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
 
index 283575a..75e25b5 100644 (file)
@@ -5,6 +5,7 @@
 #include <ddk/ntddk.h>
 #include <include/class.h>
 #include <include/msgqueue.h>
+#include <include/winsta.h>
 
 typedef struct _INTERNALPOS
 {
@@ -91,6 +92,18 @@ PWINDOW_OBJECT
 W32kGetWindowObject(HWND hWnd);
 VOID
 W32kReleaseWindowObject(PWINDOW_OBJECT Window);
+HWND STDCALL
+W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
+                       PWNDCLASS_OBJECT DesktopClass,
+                       ULONG Width, ULONG Height);
+BOOL
+W32kIsDesktopWindow(HWND hWnd);
+HWND
+W32kGetActiveWindow(VOID);
+BOOL
+W32kIsWindowVisible(HWND Wnd);
+BOOL
+W32kIsChildWindow(HWND Parent, HWND Child);
 
 #endif /* __WIN32K_WINDOW_H */
 
index d9d8a10..0bf8505 100644 (file)
@@ -30,6 +30,10 @@ ValidateDesktopHandle(HDESK Desktop,
                      KPROCESSOR_MODE AccessMode,
                      ACCESS_MASK DesiredAccess,
                      PDESKTOP_OBJECT *Object);
+LRESULT CALLBACK
+W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+PDESKTOP_OBJECT
+W32kGetActiveDesktop(VOID);
 
 #endif /* __WIN32K_WINSTA_H */
 
index 6080499..f09e607 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: callback.c,v 1.5 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: callback.c,v 1.6 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -95,7 +95,7 @@ W32kSendNCCALCSIZEMessage(HWND Wnd, BOOL Validate, PRECT Rect,
 }
 
 LRESULT STDCALL
-W32kSendCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct)
+W32kSendCREATEMessage(HWND Wnd, CREATESTRUCTW* CreateStruct)
 {
   SENDCREATEMESSAGE_CALLBACK_ARGUMENTS Arguments;
   LRESULT Result;
@@ -120,7 +120,7 @@ W32kSendCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct)
 }
 
 LRESULT STDCALL
-W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct)
+W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCTW* CreateStruct)
 {
   SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS Arguments;
   LRESULT Result;
@@ -157,6 +157,11 @@ W32kCallWindowProc(WNDPROC Proc,
   PVOID ResultPointer;
   ULONG ResultLength;
 
+  if (W32kIsDesktopWindow(Wnd))
+    {
+      return(W32kDesktopWindowProc(Wnd, Message, wParam, lParam));
+    }
+
   Arguments.Proc = Proc;
   Arguments.Wnd = Wnd;
   Arguments.Msg = Message;
@@ -176,4 +181,65 @@ W32kCallWindowProc(WNDPROC Proc,
   return(Result);
 }
 
+LRESULT STDCALL
+W32kSendGETMINMAXINFOMessage(HWND Wnd, MINMAXINFO* MinMaxInfo)
+{
+  SENDGETMINMAXINFO_CALLBACK_ARGUMENTS Arguments;
+  SENDGETMINMAXINFO_CALLBACK_RESULT Result;
+  NTSTATUS Status;
+  PVOID ResultPointer;
+  ULONG ResultLength;
+
+  Arguments.Wnd = Wnd;
+  Arguments.MinMaxInfo = *MinMaxInfo;
+  ResultPointer = &Result;
+  ResultLength = sizeof(Result);
+  Status = NtW32Call(USER32_CALLBACK_SENDGETMINMAXINFO,
+                    &Arguments,
+                    sizeof(SENDGETMINMAXINFO_CALLBACK_ARGUMENTS),
+                    &ResultPointer,
+                    &ResultLength);
+  if (!NT_SUCCESS(Status))
+    {
+      return(0);
+    }
+  return(Result.Result);  
+}
+
+LRESULT STDCALL
+W32kCallTrampolineWindowProc(WNDPROC Proc,
+                            HWND Wnd,
+                            UINT Message,
+                            WPARAM wParam,
+                            LPARAM lParam)
+{
+  switch (Message)
+    {
+    case WM_NCCREATE:
+      return(W32kSendNCCREATEMessage(Wnd, (CREATESTRUCTW*)lParam));
+     
+    case WM_CREATE:
+      return(W32kSendCREATEMessage(Wnd, (CREATESTRUCTW*)lParam));
+
+    case WM_GETMINMAXINFO:
+      return(W32kSendGETMINMAXINFOMessage(Wnd, (MINMAXINFO*)lParam));
+
+    case WM_NCCALCSIZE:
+      {
+       if (wParam)
+         {
+           return(W32kSendNCCALCSIZEMessage(Wnd, TRUE, NULL, 
+                                            (NCCALCSIZE_PARAMS*)lParam));
+         }
+       else
+         {
+           return(W32kSendNCCALCSIZEMessage(Wnd, FALSE, (RECT*)lParam, NULL));
+         }
+      }
+
+    default:
+      return(W32kCallWindowProc(Proc, Wnd, Message, wParam, lParam));
+    }
+}
+
 /* EOF */
index b956e13..e504eab 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: class.c,v 1.8 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: class.c,v 1.9 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -164,6 +164,37 @@ NtUserGetWOWClass(DWORD Unknown0,
   return(0);
 }
 
+PWNDCLASS_OBJECT
+W32kCreateClass(LPWNDCLASSEX lpwcx,
+               BOOL bUnicodeClass)
+{
+  PWNDCLASS_OBJECT ClassObject;
+  WORD  objectSize;
+  LPTSTR  namePtr;
+
+  objectSize = sizeof(WNDCLASS_OBJECT) +
+    (lpwcx->lpszMenuName != 0 ? ((wcslen (lpwcx->lpszMenuName) + 1) * 2) : 0) +
+    ((wcslen (lpwcx->lpszClassName) + 1) * 2);
+  ClassObject = ObmCreateObject(NULL, NULL, otClass, objectSize);
+  if (ClassObject == 0)
+    {          
+      return(NULL);
+    }
+
+  ClassObject->Class = *lpwcx;
+  ClassObject->Unicode = bUnicodeClass;
+  namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT));
+  if (lpwcx->lpszMenuName != 0)
+    {
+      ClassObject->Class.lpszMenuName = namePtr;
+      wcscpy (namePtr, lpwcx->lpszMenuName);
+      namePtr += wcslen (lpwcx->lpszMenuName + 1);
+    }
+  ClassObject->Class.lpszClassName = namePtr;
+  wcscpy (namePtr, lpwcx->lpszClassName);
+  return(ClassObject);
+}
+
 RTL_ATOM STDCALL
 NtUserRegisterClassExWOW(LPWNDCLASSEX lpwcx,
                         BOOL bUnicodeClass,
@@ -186,8 +217,6 @@ NtUserRegisterClassExWOW(LPWNDCLASSEX lpwcx,
   PWNDCLASS_OBJECT ClassObject;
   NTSTATUS Status;
   RTL_ATOM Atom;
-  WORD  objectSize;
-  LPTSTR  namePtr;
   
   W32kGuiCheck();
 
@@ -216,33 +245,16 @@ NtUserRegisterClassExWOW(LPWNDCLASSEX lpwcx,
       SetLastNtError(Status);
 
       return((RTL_ATOM)0);
-  }
-
-  objectSize = sizeof(WNDCLASS_OBJECT) +
-    (lpwcx->lpszMenuName != 0 ? ((wcslen (lpwcx->lpszMenuName) + 1) * 2) : 0) +
-    ((wcslen (lpwcx->lpszClassName) + 1) * 2);
-  ClassObject = ObmCreateObject(NULL, NULL, otClass, objectSize);
-  if (ClassObject == 0)
+    }
+  ClassObject = W32kCreateClass(lpwcx, bUnicodeClass);
+  if (ClassObject == NULL)
     {
       RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom);
       ObDereferenceObject(WinStaObject);
       DPRINT("Failed creating window class object\n");
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      
       return((RTL_ATOM)0);
     }
-
-  ClassObject->Class = *lpwcx;
-  ClassObject->Unicode = bUnicodeClass;
-  namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT));
-  if (lpwcx->lpszMenuName != 0)
-    {
-      ClassObject->Class.lpszMenuName = namePtr;
-      wcscpy (namePtr, lpwcx->lpszMenuName);
-      namePtr += wcslen (lpwcx->lpszMenuName + 1);
-    }
-  ClassObject->Class.lpszClassName = namePtr;
-  wcscpy (namePtr, lpwcx->lpszClassName);
   ExAcquireFastMutex(&PsGetWin32Process()->ClassListLock);
   InsertTailList(&PsGetWin32Process()->ClassListHead, &ClassObject->ListEntry);
   ExReleaseFastMutex(&PsGetWin32Process()->ClassListLock);
index 0566e0b..6dec43e 100644 (file)
@@ -1,4 +1,4 @@
- /* $Id: guicheck.c,v 1.5 2002/07/04 19:56:37 dwelch Exp $
+ /* $Id: guicheck.c,v 1.6 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -68,7 +68,7 @@ W32kGuiCheck(VOID)
                                         GENERIC_ALL,
                                         ExDesktopObjectType,
                                         UserMode,
-                                        &PsGetWin32Thread()->Desktop,
+                                        (PVOID*)&PsGetWin32Thread()->Desktop,
                                         NULL);
       if (!NT_SUCCESS(Status))
        {
index d994bc9..4d901a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.7 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: message.c,v 1.8 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -231,7 +231,6 @@ NtUserPeekMessage(LPMSG lpMsg,
   PUSER_MESSAGE_QUEUE ThreadQueue;
   BOOLEAN Present;
   PUSER_MESSAGE Message;
-  NTSTATUS Status;
   BOOLEAN RemoveMessages;
 
   /* Initialize the thread's win32 state if necessary. */ 
@@ -325,10 +324,11 @@ NtUserQuerySendMessage(DWORD Unknown0)
 }
 
 LRESULT STDCALL
-NtUserSendMessage(HWND hWnd,
-                 UINT Msg,
-                 WPARAM wParam,
-                 LPARAM lParam)
+W32kSendMessage(HWND hWnd,
+               UINT Msg,
+               WPARAM wParam,
+               LPARAM lParam,
+               BOOL KernelMessage)
 {
   LRESULT Result;
   NTSTATUS Status;
@@ -352,8 +352,17 @@ NtUserSendMessage(HWND hWnd,
 
   if (Window->MessageQueue == PsGetWin32Thread()->MessageQueue)
     {
-      Result = W32kCallWindowProc(NULL, hWnd, Msg, wParam, lParam);
-      return(Result);
+      if (KernelMessage)
+       {
+         Result = W32kCallTrampolineWindowProc(NULL, hWnd, Msg, wParam,
+                                               lParam);
+         return(Result);
+       }
+      else
+       {
+         Result = W32kCallWindowProc(NULL, hWnd, Msg, wParam, lParam);
+         return(Result);
+       }
     }
   else
     {
@@ -391,6 +400,15 @@ NtUserSendMessage(HWND hWnd,
     }
 }
 
+LRESULT STDCALL
+NtUserSendMessage(HWND hWnd,
+                 UINT Msg,
+                 WPARAM wParam,
+                 LPARAM lParam)
+{
+  return(W32kSendMessage(hWnd, Msg, wParam, lParam, FALSE));
+}
+
 BOOL STDCALL
 NtUserSendMessageCallback(HWND hWnd,
                          UINT Msg,
index 1dce3b1..45ebbef 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: msgqueue.c,v 1.4 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: msgqueue.c,v 1.5 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -138,6 +138,7 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
   ExAcquireFastMutex(&MessageQueue->Lock);
   if (IsListEmpty(&MessageQueue->SentMessagesListHead))
     {
+      ExReleaseFastMutex(&MessageQueue->Lock);
       return(FALSE);
     }
   Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
index fc8151e..1d5ace5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: windc.c,v 1.1 2002/07/04 20:12:27 dwelch Exp $
+/* $Id: windc.c,v 1.2 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 #include <include/error.h>
 #include <include/winsta.h>
 #include <include/msgqueue.h>
+#include <include/window.h>
+#include <include/rect.h>
 
 #define NDEBUG
 #include <debug.h>
 
 /* FUNCTIONS *****************************************************************/
 
+BOOL STATIC
+DceGetVisRect(PWINDOW_OBJECT Window, BOOL ClientArea, RECT* Rect)
+{
+  if (ClientArea)
+    {
+      *Rect = Window->ClientRect;
+    }
+  else
+    {
+      *Rect = Window->WindowRect;
+    }
+
+  if (Window->Style & WS_VISIBLE)
+    {
+      INT XOffset = Rect->left;
+      INT YOffset = Rect->top;
+
+      while ((Window = Window->Parent) != NULL)
+       {
+         if ((Window->Style & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE)
+           {
+             W32kSetEmptyRect(Rect);
+             return(FALSE);
+           }
+         XOffset += Window->ClientRect.left;
+         YOffset += Window->ClientRect.top;
+         W32kOffsetRect(Rect, Window->ClientRect.left, 
+                        Window->ClientRect.top);
+         if (Window->ClientRect.left >= Window->ClientRect.right ||
+             Window->ClientRect.top >= Window->ClientRect.bottom ||
+             Rect->left >= Window->ClientRect.right ||
+             Rect->right <= Window->ClientRect.left ||
+             Rect->top >= Window->ClientRect.bottom ||
+             Rect->bottom <= Window->ClientRect.top)
+           {
+             W32kSetEmptyRect(Rect);
+             return(FALSE);
+           }
+         Rect->left = max(Rect->left, Window->ClientRect.left);
+         Rect->right = min(Rect->right, Window->ClientRect.right);
+         Rect->top = max(Rect->top, Window->ClientRect.top);
+         Rect->bottom = min(Rect->bottom, Window->ClientRect.bottom);
+       }
+      W32kOffsetRect(Rect, -XOffset, -YOffset);
+      return(TRUE);
+    }
+  W32kSetEmptyRect(Rect);
+  return(FALSE);
+}
+
+BOOL
+DceAddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, 
+               HRGN ClipRgn, PRECT Rect, INT XOffset, INT YOffset)
+{
+  PLIST_ENTRY ChildListEntry;
+  PWINDOW_OBJECT Child;
+  RECT Rect1;
+
+  ChildListEntry = Parent->ChildrenListHead.Flink;
+  while (ChildListEntry != &Parent->ChildrenListHead)
+    {
+      Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT, 
+                               SiblingListEntry);
+      if (Child == End)
+       {
+         return(TRUE);
+       }
+      if (Child->Style & WS_VISIBLE)
+       {
+         Rect1.left = Child->WindowRect.left + XOffset;
+         Rect1.top = Child->WindowRect.top + YOffset;
+         Rect1.right = Child->WindowRect.right + XOffset;
+         Rect1.bottom = Child->WindowRect.bottom + YOffset;
+
+         if (W32kIntersectRect(&Rect1, &Rect1, Rect))
+           {
+             W32kUnionRectWithRgn(ClipRgn, &Rect1);
+           }
+       }
+      ChildListEntry = ChildListEntry->Flink;
+    }
+  return(FALSE);
+}
+
 HRGN 
 DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)
 {
+  PWINDOW_OBJECT Window;
+  PWINDOW_OBJECT Child;
+  HRGN VisRgn;
+  RECT Rect;
+
+  Window = W32kGetWindowObject(hWnd);
+  Child = W32kGetWindowObject(hWndChild);
+
+  if (Window != NULL && DceGetVisRect(Window, !(Flags & DCX_WINDOW), &Rect))
+    {
+      if ((VisRgn = W32kCreateRectRgnIndirect(&Rect)) != NULL)
+       {
+         HRGN ClipRgn = W32kCreateRectRgn(0, 0, 0, 0);
+         INT XOffset, YOffset;
+
+         if (ClipRgn != NULL)
+           {
+             if (Flags & DCX_CLIPCHILDREN && 
+                 !IsListEmpty(&Window->ChildrenListHead))
+               {
+                 if (Flags & DCX_WINDOW)
+                   {
+                     XOffset = Window->ClientRect.left -
+                       Window->WindowRect.left;
+                     YOffset = Window->ClientRect.top -
+                       Window->WindowRect.top;
+                   }           
+                 else
+                   {
+                     XOffset = YOffset = 0;
+                   }
+                 DceAddClipRects(Window, NULL, ClipRgn, &Rect,
+                                 XOffset, YOffset);
+               }
+
+             if (CFlags & DCX_CLIPCHILDREN && Child &&
+                 !IsListEmpty(&Child->ChildrenListHead))
+               {
+                 if (Flags & DCX_WINDOW)
+                   {
+                     XOffset = Window->ClientRect.left -
+                       Window->WindowRect.left;
+                     YOffset = Window->ClientRect.top -
+                       Window->WindowRect.top;
+                   }
+                 else
+                   {
+                     XOffset = YOffset = 0;
+                   }
+
+                 XOffset += Child->ClientRect.left;
+                 YOffset += Child->ClientRect.top;
+
+                 DceAddClipRects(Child, NULL, ClipRgn, &Rect,
+                                 XOffset, YOffset);
+               }
+
+             if (Flags & DCX_WINDOW)
+               {
+                 XOffset = -Window->WindowRect.left;
+                 YOffset = -Window->WindowRect.top;
+               }
+             else
+               {
+                 XOffset = -Window->ClientRect.left;
+                 YOffset = -Window->ClientRect.top;
+               }
+
+             if (Flags & DCX_CLIPSIBLINGS && Window->Parent != NULL)
+               {
+                 DceAddClipRects(Window->Parent, Window, ClipRgn,
+                                 &Rect, XOffset, YOffset);
+               }
+             
+             while (Window->Style & WS_CHILD)
+               {
+                 Window = Window->Parent;
+                 XOffset -= Window->ClientRect.left;
+                 YOffset -= Window->ClientRect.top;
+                 if (Window->Style & WS_CLIPSIBLINGS && 
+                     Window->Parent != NULL)
+                   {
+                     DceAddClipRects(Window->Parent, Window, ClipRgn,
+                                     &Rect, XOffset, YOffset);
+                   }
+               }
 
+             W32kCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
+             W32kDeleteObject(ClipRgn);
+           }
+         else
+           {
+             W32kDeleteObject(VisRgn);
+             VisRgn = 0;
+           }
+       }
+    }
+  else
+    {
+      VisRgn = W32kCreateRectRgn(0, 0, 0, 0);
+    }
+  W32kReleaseWindowObject(Window);
+  W32kReleaseWindowObject(Child);
+  return(VisRgn);
 }
 
 INT STDCALL
index 2309dd6..067e25b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.8 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: window.c,v 1.9 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 #include <include/winpos.h>
 #include <include/callback.h>
 #include <include/msgqueue.h>
+#include <include/rect.h>
 
 //#define NDEBUG
 #include <debug.h>
 
 /* FUNCTIONS *****************************************************************/
 
+VOID
+W32kSetFocusWindow(HWND hWnd)
+{
+}
+
+BOOL
+W32kIsChildWindow(HWND Parent, HWND Child)
+{
+  PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Child);
+  PWINDOW_OBJECT Window = BaseWindow;
+  while (Window != NULL && Window->Style & WS_CHILD)
+    {
+      if (Window->Self == Parent)
+       {
+         W32kReleaseWindowObject(BaseWindow);
+         return(TRUE);
+       }
+      Window = Window->Parent;
+    }
+  W32kReleaseWindowObject(BaseWindow);
+  return(FALSE);  
+}
+
+BOOL
+W32kIsWindowVisible(HWND Wnd)
+{
+  PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Wnd);
+  PWINDOW_OBJECT Window = BaseWindow;
+  BOOLEAN Result = FALSE;
+  while (Window != NULL && Window->Style & WS_CHILD)
+    {
+      if (!(Window->Style & WS_VISIBLE))
+       {
+         W32kReleaseWindowObject(BaseWindow);
+         return(FALSE);
+       }
+      Window = Window->Parent;
+    }
+  if (Window != NULL && Window->Style & WS_VISIBLE)
+    {
+      Result = TRUE;
+    }
+  W32kReleaseWindowObject(BaseWindow);
+  return(Result);
+}
+
+BOOL
+W32kIsDesktopWindow(HWND hWnd)
+{
+  PWINDOW_OBJECT WindowObject;
+  BOOL IsDesktop;
+  WindowObject = W32kGetWindowObject(hWnd);
+  IsDesktop = WindowObject->Parent == NULL;
+  W32kReleaseWindowObject(WindowObject);
+  return(IsDesktop);
+}
+
 PWINDOW_OBJECT
 W32kGetWindowObject(HWND hWnd)
 {
@@ -54,16 +112,52 @@ W32kReleaseWindowObject(PWINDOW_OBJECT Window)
 VOID
 W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
 {
+  Rect->left = Rect->bottom = 0;
+  Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
+  Rect->top = WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
 }
 
 HWND
 W32kGetActiveWindow(VOID)
 {
+  PUSER_MESSAGE_QUEUE Queue;
+  Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
+  if (Queue == NULL)
+    {
+      return(NULL);
+    }
+  else
+    {
+      return(Queue->ActiveWindow);
+    }
+}
+
+HWND
+W32kGetFocusWindow(VOID)
+{
+  PUSER_MESSAGE_QUEUE Queue;
+  Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
+  if (Queue == NULL)
+    {
+      return(NULL);
+    }
+  else
+    {
+      return(Queue->FocusWindow);
+    }
 }
 
+
 WNDPROC
 W32kGetWindowProc(HWND Wnd)
 {
+  PWINDOW_OBJECT WindowObject;
+  WNDPROC WndProc;
+
+  WindowObject = W32kGetWindowObject(Wnd);
+  WndProc = WindowObject->Class->Class.lpfnWndProc;
+  W32kReleaseWindowObject(Wnd);
+  return(WndProc);
 }
 
 NTSTATUS
@@ -100,6 +194,57 @@ NtUserChildWindowFromPointEx(HWND Parent,
   return(0);
 }
 
+HWND STDCALL
+W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
+                       PWNDCLASS_OBJECT DesktopClass,
+                       ULONG Width, ULONG Height)
+{
+  PWSTR WindowName;
+  HWND Handle;
+  PWINDOW_OBJECT WindowObject;
+
+  /* Create the window object. */
+  WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable, 
+                                                &Handle, 
+                                                otWindow, 
+                                                sizeof(WINDOW_OBJECT));
+  if (!WindowObject) 
+    {
+      return((HWND)0);
+    }
+
+  /*
+   * Fill out the structure describing it.
+   */
+  WindowObject->Class = DesktopClass;
+  WindowObject->ExStyle = 0;
+  WindowObject->Style = WS_VISIBLE;
+  WindowObject->x = 0;
+  WindowObject->y = 0;
+  WindowObject->Width = Width;
+  WindowObject->Height = Height;
+  WindowObject->ParentHandle = NULL;
+  WindowObject->Parent = NULL;
+  WindowObject->Menu = NULL;
+  WindowObject->Instance = NULL;
+  WindowObject->Parameters = NULL;
+  WindowObject->Self = Handle;
+  WindowObject->MessageQueue = NULL;
+  WindowObject->ExtraData = NULL;
+  WindowObject->ExtraDataSize = 0;
+  WindowObject->WindowRect.left = 0;
+  WindowObject->WindowRect.top = 0;
+  WindowObject->WindowRect.right = Width;
+  WindowObject->WindowRect.bottom = Height;
+  WindowObject->ClientRect = WindowObject->WindowRect;
+
+  WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
+  wcscpy(WindowName, L"DESKTOP");
+  RtlInitUnicodeString(&WindowObject->WindowName, WindowName);
+
+  return(Handle);
+}
+
 HWND STDCALL
 NtUserCreateWindowEx(DWORD dwExStyle,
                     PUNICODE_STRING lpClassName,
@@ -118,11 +263,12 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   PWINSTATION_OBJECT WinStaObject;
   PWNDCLASS_OBJECT ClassObject;
   PWINDOW_OBJECT WindowObject;
+  PWINDOW_OBJECT ParentWindow;
   UNICODE_STRING WindowName;
   NTSTATUS Status;
   HANDLE Handle;
   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-  CREATESTRUCT Cs;
+  CREATESTRUCTW Cs;
   LRESULT Result;
   
   DPRINT("NtUserCreateWindowEx\n");
@@ -136,7 +282,15 @@ NtUserCreateWindowEx(DWORD dwExStyle,
       return((HWND)0);
     }
 
-  /* FIXME: Validate the parent window. */
+  if (hWndParent != NULL)
+    {
+      ParentWindow = W32kGetWindowObject(hWndParent);
+    }
+  else
+    {
+      hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
+      ParentWindow = W32kGetWindowObject(hWndParent);
+    }
 
   /* Check the class. */
   Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
@@ -187,14 +341,13 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   WindowObject->y = y;
   WindowObject->Width = nWidth;
   WindowObject->Height = nHeight;
-  WindowObject->Parent = hWndParent;
+  WindowObject->ParentHandle = hWndParent;
   WindowObject->Menu = hMenu;
   WindowObject->Instance = hInstance;
   WindowObject->Parameters = lpParam;
   WindowObject->Self = Handle;
   WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
-
-  /* FIXME: Add the window parent. */
+  WindowObject->Parent = ParentWindow;
 
   RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
   RtlFreeUnicodeString(&WindowName);
@@ -229,7 +382,12 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                  &WindowObject->ListEntry);
   ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
 
-  /* FIXME: Insert the window into the desktop window list. */
+  /* 
+   * Insert the window into the list of windows associated with the thread's
+   * desktop. 
+   */
+  InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
+                &WindowObject->DesktopListEntry);
 
   /* FIXME: Maybe allocate a DCE for this window. */
 
@@ -342,8 +500,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                         NewPos.right, NewPos.bottom, SwFlag);
     }
 
-  /* FIXME: Need to set up parent window. */
-#if 0
   /* Notify the parent window of a new child. */
   if ((WindowObject->Style & WS_CHILD) ||
       (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
@@ -354,7 +510,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                         MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
                         (LPARAM)WindowObject->Self);
     }
-#endif
 
   if (dwStyle & WS_VISIBLE)
     {
index eda22de..b080269 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: winpos.c,v 1.2 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: winpos.c,v 1.3 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 
 /* FUNCTIONS *****************************************************************/
 
+#define HAS_DLGFRAME(Style, ExStyle) \
+       (((ExStyle) & WS_EX_DLGMODALFRAME) || \
+        (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
+
+#define HAS_THICKFRAME(Style, ExStyle) \
+       (((Style) & WS_THICKFRAME) && \
+        !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
+
+BOOL
+WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
+{
+}
+
 POINT STATIC
 WinPosFindIconPos(HWND hWnd, POINT Pos)
 {
@@ -223,6 +236,62 @@ UINT
 WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
                    POINT* MinTrack, POINT* MaxTrack)
 {
+  MINMAXINFO MinMax;
+  INT XInc, YInc;
+  INTERNALPOS* Pos;
+
+  /* Get default values. */
+  MinMax.ptMaxSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
+  MinMax.ptMaxSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
+  MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
+  MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
+  MinMax.ptMaxTrackSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
+  MinMax.ptMaxTrackSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
+
+  if (HAS_DLGFRAME(Window->Style, Window->ExStyle))
+    {
+      XInc = NtUserGetSystemMetrics(SM_CXDLGFRAME);
+      YInc = NtUserGetSystemMetrics(SM_CYDLGFRAME);
+    }
+  else
+    {
+      XInc = YInc = 0;
+      if (HAS_THICKFRAME(Window->Style, Window->ExStyle))
+       {
+         XInc += NtUserGetSystemMetrics(SM_CXFRAME);
+         YInc += NtUserGetSystemMetrics(SM_CYFRAME);
+       }
+      if (Window->Style & WS_BORDER)
+       {
+         XInc += NtUserGetSystemMetrics(SM_CXBORDER);
+         YInc += NtUserGetSystemMetrics(SM_CYBORDER);
+       }
+    }
+  MinMax.ptMaxSize.x += 2 * XInc;
+  MinMax.ptMaxSize.y += 2 * YInc;
+
+  Pos = Window->InternalPos;
+  if (Pos != NULL)
+    {
+      MinMax.ptMaxPosition = Pos->MaxPos;
+    }
+  else
+    {
+      MinMax.ptMaxPosition.x -= XInc;
+      MinMax.ptMaxPosition.y -= YInc;
+    }
+
+  W32kSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax, TRUE);
+
+  MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
+                               MinMax.ptMinTrackSize.x);
+  MinMax.ptMaxTrackSize.y = max(MinMax.ptMaxTrackSize.y,
+                               MinMax.ptMinTrackSize.y);
+
+  if (MaxSize) *MaxSize = MinMax.ptMaxSize;
+  if (MaxPos) *MaxPos = MinMax.ptMaxPosition;
+  if (MinTrack) *MinTrack = MinMax.ptMinTrackSize;
+  if (MaxTrack) *MaxTrack = MinMax.ptMaxTrackSize;
 }
 
 BOOL STATIC
@@ -288,7 +357,11 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
 
   /* FIXME: Get current active window from active queue. */
 
-  /* FIXME: Check if the window is for a desktop. */
+  /* Check if the window is for a desktop. */
+  if (Wnd == PsGetWin32Thread()->Desktop->DesktopWindow)
+    {
+      return(FALSE);
+    }
 
   Status = 
     ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
@@ -557,7 +630,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
     }
 
   if (Window->Style & WS_CHILD &&
-      /* !IsWindowVisible(WindowObject->Parent->Self) && */
+      !W32kIsWindowVisible(Window->Parent->Self) &&
       (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
     {
       if (Cmd == SW_HIDE)
@@ -583,10 +656,24 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
          if (Cmd == SW_HIDE)
            {
              /* Hide the window. */
+             if (Wnd == W32kGetActiveWindow())
+               {
+                 WinPosActivateOtherWindow(Window);
+               }
+             /* Revert focus to parent. */
+             if (Wnd == W32kGetFocusWindow() ||
+                 W32kIsChildWindow(Wnd, W32kGetFocusWindow()))
+               {
+                 W32kSetFocusWindow(Window->Parent->Self);
+               }
            }
        }
       /* FIXME: Check for window destruction. */
-      /* FIXME: Show title for minimized windows. */
+      /* Show title for minimized windows. */
+      if (Window->Style & WS_MINIMIZE)
+       {
+         WinPosShowIconTitle(Window, TRUE);
+       }
     }
 
   if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
index 8fb0bdc..7df5159 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: winsta.c,v 1.4 2002/07/04 19:56:37 dwelch Exp $
+/* $Id: winsta.c,v 1.5 2002/07/17 21:04:57 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  *                   the first USER32/GDI32 call not related
  *                   to window station/desktop handling
  */
+
+/* INCLUDES ******************************************************************/
+
 #include <ddk/ntddk.h>
 #include <win32k/win32k.h>
 #include <include/winsta.h>
 #include <include/object.h>
+#include <include/guicheck.h>
+#include <napi/win32.h>
+#include <include/class.h>
+#include <include/window.h>
 
 //#define NDEBUG
 #include <debug.h>
 
+/* GLOBALS *******************************************************************/
+
 #define WINSTA_ROOT_NAME L"\\Windows\\WindowStations"
 
+LRESULT CALLBACK
+W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+STATIC PWNDCLASS_OBJECT DesktopWindowClass;
 
-HDESK InputDesktop; /* Currently active desktop */
+/* Currently active desktop */
+STATIC HDESK InputDesktopHandle = NULL; 
+STATIC PDESKTOP_OBJECT InputDesktop = NULL;
+STATIC PWINSTATION_OBJECT InputWindowStation = NULL;
+
+/* FUNCTIONS *****************************************************************/
+
+PDESKTOP_OBJECT
+W32kGetActiveDesktop(VOID)
+{
+  return(InputDesktop);
+}
 
 NTSTATUS
 InitWindowStationImpl(VOID)
@@ -34,6 +58,7 @@ InitWindowStationImpl(VOID)
   HANDLE WindowStationsDirectory;
   UNICODE_STRING UnicodeString;
   NTSTATUS Status;
+  WNDCLASSEX wcx;
 
   /*
    * Create the '\Windows\WindowStations' directory
@@ -57,7 +82,19 @@ InitWindowStationImpl(VOID)
       return Status;
     }
 
-  return STATUS_SUCCESS;
+  /* 
+   * Create the desktop window class
+   */
+  wcx.style = 0;
+  wcx.lpfnWndProc = W32kDesktopWindowProc;
+  wcx.cbClsExtra = wcx.cbWndExtra = 0;
+  wcx.hInstance = wcx.hIcon = wcx.hCursor = NULL;
+  wcx.hbrBackground = NULL;
+  wcx.lpszMenuName = NULL;
+  wcx.lpszClassName = L"DesktopWindowClass";
+  DesktopWindowClass = W32kCreateClass(&wcx, TRUE);
+
+  return(STATUS_SUCCESS);
 }
 
 NTSTATUS
@@ -475,14 +512,12 @@ NtUserCloseDesktop(
  *   Handle to the new desktop that can be closed with NtUserCloseDesktop()
  *   Zero on failure
  */
-HDESK
-STDCALL
-NtUserCreateDesktop(
-  PUNICODE_STRING lpszDesktopName,
-  DWORD dwFlags,
-  ACCESS_MASK dwDesiredAccess,
-  LPSECURITY_ATTRIBUTES lpSecurity,
-  HWINSTA hWindowStation)
+HDESK STDCALL
+NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName,
+                   DWORD dwFlags,
+                   ACCESS_MASK dwDesiredAccess,
+                   LPSECURITY_ATTRIBUTES lpSecurity,
+                   HWINSTA hWindowStation)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   PWINSTATION_OBJECT WinStaObject;
@@ -492,17 +527,17 @@ NtUserCreateDesktop(
   NTSTATUS Status;
   HDESK Desktop;
 
-  Status = ValidateWindowStationHandle(
-    hWindowStation,
-    KernelMode,
-    0,
-    &WinStaObject);
+  Status = ValidateWindowStationHandle(hWindowStation,
+                                      KernelMode,
+                                      0,
+                                      &WinStaObject);
   if (!NT_SUCCESS(Status))
-  {
-    DPRINT("Failed validation of window station handle (0x%X)\n", hWindowStation);
-    return (HDESK)0;
-  }
-
+    {
+      DPRINT("Failed validation of window station handle (0x%X)\n", 
+            hWindowStation);
+      return((HDESK)0);
+    }
+  
   wcscpy(NameBuffer, WINSTA_ROOT_NAME);
   wcscat(NameBuffer, L"\\");
   wcscat(NameBuffer, WinStaObject->Name.Buffer);
@@ -515,43 +550,47 @@ NtUserCreateDesktop(
   DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
 
   /* Initialize ObjectAttributes for the desktop object */
-  InitializeObjectAttributes(
-    &ObjectAttributes,
-    &DesktopName,
-    0,
-    NULL,
-    NULL);
-
-  Status = ObOpenObjectByName(
-    &ObjectAttributes,
-    ExDesktopObjectType,
-    NULL,
-    UserMode,
-    dwDesiredAccess,
-    NULL,
-    &Desktop);
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &DesktopName,
+                            0,
+                            NULL,
+                            NULL);
+  Status = ObOpenObjectByName(&ObjectAttributes,
+                             ExDesktopObjectType,
+                             NULL,
+                             UserMode,
+                             dwDesiredAccess,
+                             NULL,
+                             &Desktop);
   if (NT_SUCCESS(Status))
-  {
-    DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
-    return (HDESK)Desktop;
-  }
+    {
+      DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
+      return((HDESK)Desktop);
+    }
 
   DPRINT("Status for open operation (0x%X)\n", Status);
 
-  Status = ObCreateObject(
-    &Desktop,
-    STANDARD_RIGHTS_REQUIRED,
-    &ObjectAttributes,
-    ExDesktopObjectType,
-    (PVOID*)&DesktopObject);
+  Status = ObCreateObject(&Desktop,
+                         STANDARD_RIGHTS_REQUIRED,
+                         &ObjectAttributes,
+                         ExDesktopObjectType,
+                         (PVOID*)&DesktopObject);
   if (!NT_SUCCESS(Status))
-  {
-    DPRINT("Failed creating desktop (%wZ)\n", &DesktopName);
-    SetLastNtError(STATUS_UNSUCCESSFUL);
-    return (HDESK)0;
-  }
-
-  return (HDESK)Desktop;
+    {
+      DPRINT("Failed creating desktop (%wZ)\n", &DesktopName);
+      SetLastNtError(STATUS_UNSUCCESSFUL);
+      return((HDESK)0);
+    }
+  
+  /* Initialize some local (to win32k) desktop state. */
+  DesktopObject->ActiveMessageQueue = NULL;  
+  InitializeListHead(&DesktopObject->WindowListHead);
+  DesktopObject->DesktopWindow = 
+    W32kCreateDesktopWindow(DesktopObject->WindowStation,
+                           DesktopWindowClass,
+                           640, 480);
+
+  return((HDESK)Desktop);
 }
 
 HDESK STDCALL
@@ -703,30 +742,54 @@ NtUserOpenInputDesktop(
   return (HDESK)0;
 }
 
-BOOL
-STDCALL
-NtUserPaintDesktop(
-  HDC hDC)
+BOOL STDCALL
+NtUserPaintDesktop(HDC hDC)
 {
   UNIMPLEMENTED
 
   return FALSE;
 }
 
-DWORD
-STDCALL
-NtUserResolveDesktopForWOW(
-  DWORD Unknown0)
+DWORD STDCALL
+NtUserResolveDesktopForWOW(DWORD Unknown0)
 {
   UNIMPLEMENTED
-
   return 0;
 }
 
 BOOL STDCALL
 NtUserSetThreadDesktop(HDESK hDesktop)
-{
-  return(FALSE);
+{  
+  PDESKTOP_OBJECT DesktopObject;
+  NTSTATUS Status;
+
+  /* Initialize the Win32 state if necessary. */
+  W32kGuiCheck();
+
+  /* Validate the new desktop. */
+  Status = ValidateDesktopHandle(hDesktop,
+                                KernelMode,
+                                0,
+                                &DesktopObject);
+  if (!NT_SUCCESS(Status)) 
+    {
+      DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
+      return(FALSE);
+    }
+
+  /* Check for setting the same desktop as before. */
+  if (DesktopObject == PsGetWin32Thread()->Desktop)
+    {
+      ObDereferenceObject(DesktopObject);
+      return(TRUE);
+    }
+
+  /* FIXME: Should check here to see if the thread has any windows. */
+
+  ObDereferenceObject(PsGetWin32Thread()->Desktop);
+  PsGetWin32Thread()->Desktop = DesktopObject;
+
+  return(TRUE);
 }
 
 /*
@@ -737,34 +800,56 @@ NtUserSetThreadDesktop(HDESK hDesktop)
  * RETURNS:
  *   Status
  */
-BOOL
-STDCALL
-NtUserSwitchDesktop(
-  HDESK hDesktop)
+BOOL STDCALL
+NtUserSwitchDesktop(HDESK hDesktop)
 {
-  PDESKTOP_OBJECT Object;
+  PDESKTOP_OBJECT DesktopObject;
   NTSTATUS Status;
 
   DPRINT("About to switch desktop (0x%X)\n", hDesktop);
 
-  Status = ValidateDesktopHandle(
-    hDesktop,
-    KernelMode,
-    0,
-    &Object);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-    return FALSE;
-  }
-
-  ObDereferenceObject(Object);
+  Status = ValidateDesktopHandle(hDesktop,
+                                KernelMode,
+                                0,
+                                &DesktopObject);
+  if (!NT_SUCCESS(Status)) 
+    {
+      DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
+      return(FALSE);
+    }
 
   /* FIXME: Fail if the desktop belong to an invisible window station */
   /* FIXME: Fail if the process is associated with a secured
             desktop such as Winlogon or Screen-Saver */
-
   /* FIXME: Connect to input device */
-  return TRUE;
+
+  /* Set the active desktop in the desktop's window station. */
+  DesktopObject->WindowStation->ActiveDesktop = DesktopObject;
+
+  /* Set the global state. */
+  InputDesktopHandle = hDesktop;
+  InputDesktop = DesktopObject;
+  InputWindowStation = DesktopObject->WindowStation;
+
+  ObDereferenceObject(DesktopObject);
+
+  return(TRUE);
+}
+
+LRESULT CALLBACK
+W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  switch (msg)
+    {
+    case WM_CREATE:
+      return(0);
+
+    case WM_NCCREATE:
+      return(1);
+
+    default:
+      return(0);
+    }
 }
 
 /* EOF */
index e42aeb1..73ed9c1 100644 (file)
@@ -20,6 +20,11 @@ W32kCropRgn(HRGN hDest, HRGN hSrc, const RECT* Rect, const POINT* Point)
        return NULL;
 }
 
+HRGN STDCALL
+W32kUnionRectWithRgn(HRGN hDest, const RECT* Rect)
+{
+}
+
 INT STDCALL
 W32kCombineRgn(HRGN  hDest,
               HRGN  hSrc1,