From 9d6848e6edac7b87f35722215d50becf76d6e81e Mon Sep 17 00:00:00 2001 From: David Welch Date: Wed, 17 Jul 2002 21:04:57 +0000 Subject: [PATCH] Fixed some bugs. svn path=/trunk/; revision=3243 --- reactos/include/ddk/zwtypes.h | 6 +- reactos/include/napi/core.h | 32 +- reactos/include/user32/callback.h | 21 +- reactos/include/win32k/region.h | 2 + reactos/lib/user32/misc/dllmain.c | 2 + reactos/lib/user32/windows/window.c | 27 +- reactos/ntoskrnl/cc/copy.c | 516 +++++++++++----------- reactos/ntoskrnl/cc/misc.c | 33 +- reactos/ntoskrnl/cc/pin.c | 137 +++--- reactos/ntoskrnl/cc/view.c | 71 ++- reactos/ntoskrnl/include/internal/ex.h | 8 + reactos/ntoskrnl/include/internal/mm.h | 8 + reactos/ntoskrnl/ke/bug.c | 12 +- reactos/ntoskrnl/ke/i386/exp.c | 8 +- reactos/ntoskrnl/ke/i386/trap.s | 19 +- reactos/ntoskrnl/ke/kthread.c | 14 +- reactos/ntoskrnl/ke/main.c | 11 +- reactos/ntoskrnl/ldr/loader.c | 4 +- reactos/ntoskrnl/mm/mminit.c | 4 +- reactos/ntoskrnl/mm/pagefile.c | 233 ++++++++-- reactos/ntoskrnl/ob/object.c | 7 +- reactos/ntoskrnl/ps/process.c | 9 +- reactos/subsys/system/winlogon/winlogon.c | 192 ++++---- reactos/subsys/win32k/include/callback.h | 12 +- reactos/subsys/win32k/include/class.h | 3 + reactos/subsys/win32k/include/msgqueue.h | 10 + reactos/subsys/win32k/include/window.h | 13 + reactos/subsys/win32k/include/winsta.h | 4 + reactos/subsys/win32k/ntuser/callback.c | 72 ++- reactos/subsys/win32k/ntuser/class.c | 58 ++- reactos/subsys/win32k/ntuser/guicheck.c | 4 +- reactos/subsys/win32k/ntuser/message.c | 34 +- reactos/subsys/win32k/ntuser/msgqueue.c | 3 +- reactos/subsys/win32k/ntuser/windc.c | 191 +++++++- reactos/subsys/win32k/ntuser/window.c | 175 +++++++- reactos/subsys/win32k/ntuser/winpos.c | 95 +++- reactos/subsys/win32k/ntuser/winsta.c | 247 +++++++---- reactos/subsys/win32k/objects/region.c | 5 + 38 files changed, 1644 insertions(+), 658 deletions(-) diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index d2d3ca6d3a5..9bf911585dd 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -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 diff --git a/reactos/include/napi/core.h b/reactos/include/napi/core.h index d4967e7ea7b..ca13d207a27 100644 --- a/reactos/include/napi/core.h +++ b/reactos/include/napi/core.h @@ -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 */ diff --git a/reactos/include/user32/callback.h b/reactos/include/user32/callback.h index 2b24d8c4ef2..ee2bc98c0ac 100644 --- a/reactos/include/user32/callback.h +++ b/reactos/include/user32/callback.h @@ -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 */ diff --git a/reactos/include/win32k/region.h b/reactos/include/win32k/region.h index ae73c331f2f..1b6b80b1967 100644 --- a/reactos/include/win32k/region.h +++ b/reactos/include/win32k/region.h @@ -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 diff --git a/reactos/lib/user32/misc/dllmain.c b/reactos/lib/user32/misc/dllmain.c index 5fa32a306ae..20445774c19 100644 --- a/reactos/lib/user32/misc/dllmain.c +++ b/reactos/lib/user32/misc/dllmain.c @@ -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); diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 578c8a5c3f3..49629f7f8fb 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -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 @@ -19,6 +19,31 @@ /* 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) { diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index ec00dabfc25..93408ccddb1 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -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; - } - + { + 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)) + { + return(FALSE); + } + if (!Valid) + { + if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) + { + return(FALSE); + } + } + 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)) - { - 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; + { + 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); + 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 -) +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; + 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; - 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; - + /* + * 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 + { + 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) { - page = MmGetPhysicalAddressForProcess(NULL, current->BaseAddress + (i * PAGESIZE)); - ((PULONG)(Mdl + 1))[count++] = page.u.LowPart; + 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; } - 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; + + /* 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); } diff --git a/reactos/ntoskrnl/cc/misc.c b/reactos/ntoskrnl/cc/misc.c index e8f29ef592d..40ce9d967c4 100644 --- a/reactos/ntoskrnl/cc/misc.c +++ b/reactos/ntoskrnl/cc/misc.c @@ -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); diff --git a/reactos/ntoskrnl/cc/pin.c b/reactos/ntoskrnl/cc/pin.c index 921f8fadd3e..46b769204fc 100644 --- a/reactos/ntoskrnl/cc/pin.c +++ b/reactos/ntoskrnl/cc/pin.c @@ -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); } diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 0715e335046..f381ea24363 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -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 -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(¤t->DirtySegmentListEntry); + ExReleaseFastMutex(&ViewLock); + } + current_entry = current_entry->Flink; + } /* * Release all cache segments. diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index bc96180d306..75cc857abf1 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -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; diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index e5dd92c4750..f795ceef4ab 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -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 diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index 145ee64de5c..2b50b17b2cf 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -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) { diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 038003b60a4..30bcc26b0fe 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -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 diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 249463ca105..27343e78cd0 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -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 */ diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index b60e383c3e2..589fe7f2a3f 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -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 diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 5fc540d7cf4..3ec66b89ad7 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -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++) { diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 969a8c5c65e..b6a15845a9a 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -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); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 2e4d14d6a1f..e3d7e941c5d 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -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 diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 07e1ee9cc69..1c6b265d2a6 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -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 #include #include +#include #define NDEBUG #include @@ -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); } diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index de46ed3a19c..9d1b0c3e4bc 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -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) { diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 24ba6d62185..771748b1dee 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -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); diff --git a/reactos/subsys/system/winlogon/winlogon.c b/reactos/subsys/system/winlogon/winlogon.c index 89485fdd7d4..97e5e467669 100644 --- a/reactos/subsys/system/winlogon/winlogon.c +++ b/reactos/subsys/system/winlogon/winlogon.c @@ -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; } diff --git a/reactos/subsys/win32k/include/callback.h b/reactos/subsys/win32k/include/callback.h index 21cab96e390..ef1bae93d4f 100644 --- a/reactos/subsys/win32k/include/callback.h +++ b/reactos/subsys/win32k/include/callback.h @@ -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 */ diff --git a/reactos/subsys/win32k/include/class.h b/reactos/subsys/win32k/include/class.h index 87a8787ac12..ca3af5410d6 100644 --- a/reactos/subsys/win32k/include/class.h +++ b/reactos/subsys/win32k/include/class.h @@ -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 */ diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index 47d7ba1dc81..170926ea082 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -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)) diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index 283575aecea..75e25b5fc29 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -5,6 +5,7 @@ #include #include #include +#include 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 */ diff --git a/reactos/subsys/win32k/include/winsta.h b/reactos/subsys/win32k/include/winsta.h index d9d8a10ef63..0bf8505ecd9 100644 --- a/reactos/subsys/win32k/include/winsta.h +++ b/reactos/subsys/win32k/include/winsta.h @@ -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 */ diff --git a/reactos/subsys/win32k/ntuser/callback.c b/reactos/subsys/win32k/ntuser/callback.c index 6080499598b..f09e6076434 100644 --- a/reactos/subsys/win32k/ntuser/callback.c +++ b/reactos/subsys/win32k/ntuser/callback.c @@ -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 */ diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index b956e13b516..e504eabf40c 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -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); diff --git a/reactos/subsys/win32k/ntuser/guicheck.c b/reactos/subsys/win32k/ntuser/guicheck.c index 0566e0b6765..6dec43efb51 100644 --- a/reactos/subsys/win32k/ntuser/guicheck.c +++ b/reactos/subsys/win32k/ntuser/guicheck.c @@ -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)) { diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index d994bc9ddfb..4d901a78777 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -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, diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 1dce3b19da5..45ebbefd338 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -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); diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index fc8151ea069..1d5ace5d7c4 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -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 @@ -18,16 +18,205 @@ #include #include #include +#include +#include #define NDEBUG #include /* 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 diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 2309dd63940..067e25bde60 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -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 @@ -21,12 +21,70 @@ #include #include #include +#include //#define NDEBUG #include /* 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) { diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index eda22de0856..b0802697f0b 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -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 @@ -35,6 +35,19 @@ /* 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) diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 8fb0bdc3160..7df51591edc 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -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 @@ -14,18 +14,42 @@ * the first USER32/GDI32 call not related * to window station/desktop handling */ + +/* INCLUDES ******************************************************************/ + #include #include #include #include +#include +#include +#include +#include //#define NDEBUG #include +/* GLOBALS *******************************************************************/ + #define WINSTA_ROOT_NAME L"\\Windows\\WindowStations" +LRESULT CALLBACK +W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -HDESK InputDesktop; /* Currently active desktop */ +STATIC PWNDCLASS_OBJECT DesktopWindowClass; + +/* 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; - } + { + 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; + 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 */ diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index e42aeb10196..73ed9c19069 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -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,