From 5307ffb9c668014bd480c2f994e34cabd5281cad Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 12 Mar 2005 14:15:49 +0000 Subject: [PATCH] Alex Ionescu Move win32k callbacks to win32k where they belong. Registration is done with Ps function just like on XP+. Also allows non-win32k stuff to manage their own desktops and window stations. svn path=/trunk/; revision=13968 --- reactos/include/ddk/defines.h | 21 ++ reactos/include/ddk/psfuncs.h | 2 +- reactos/include/ddk/pstypes.h | 34 ++ reactos/ntoskrnl/ex/win32k.c | 397 +++++++----------------- reactos/ntoskrnl/ps/win32.c | 17 +- reactos/subsys/win32k/include/desktop.h | 10 + reactos/subsys/win32k/include/winsta.h | 23 ++ reactos/subsys/win32k/main/dllmain.c | 50 ++- reactos/subsys/win32k/ntuser/desktop.c | 54 ++++ reactos/subsys/win32k/ntuser/message.c | 7 + reactos/subsys/win32k/ntuser/winsta.c | 159 ++++++++++ reactos/w32api/include/ddk/ntifs.h | 26 +- reactos/w32api/include/ddk/winddk.h | 16 + reactos/w32api/include/winnt.h | 4 +- 14 files changed, 528 insertions(+), 292 deletions(-) diff --git a/reactos/include/ddk/defines.h b/reactos/include/ddk/defines.h index 56cc075b23d..3b173eea85e 100644 --- a/reactos/include/ddk/defines.h +++ b/reactos/include/ddk/defines.h @@ -77,6 +77,27 @@ enum #define HIGH_LEVEL 31 // Highest interrupt level #define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization level +#define WINSTA_ACCESSCLIPBOARD (0x4L) +#define WINSTA_ACCESSGLOBALATOMS (0x20L) +#define WINSTA_CREATEDESKTOP (0x8L) +#define WINSTA_ENUMDESKTOPS (0x1L) +#define WINSTA_ENUMERATE (0x100L) +#define WINSTA_EXITWINDOWS (0x40L) +#define WINSTA_READATTRIBUTES (0x2L) +#define WINSTA_READSCREEN (0x200L) +#define WINSTA_WRITEATTRIBUTES (0x10L) + +#define DF_ALLOWOTHERACCOUNTHOOK (0x1L) +#define DESKTOP_CREATEMENU (0x4L) +#define DESKTOP_CREATEWINDOW (0x2L) +#define DESKTOP_ENUMERATE (0x40L) +#define DESKTOP_HOOKCONTROL (0x8L) +#define DESKTOP_JOURNALPLAYBACK (0x20L) +#define DESKTOP_JOURNALRECORD (0x10L) +#define DESKTOP_READOBJECTS (0x1L) +#define DESKTOP_SWITCHDESKTOP (0x100L) +#define DESKTOP_WRITEOBJECTS (0x80L) + #endif /* __ASM__ */ /* Values returned by KeGetPreviousMode() */ diff --git a/reactos/include/ddk/psfuncs.h b/reactos/include/ddk/psfuncs.h index cca162f1c33..574af3ee203 100644 --- a/reactos/include/ddk/psfuncs.h +++ b/reactos/include/ddk/psfuncs.h @@ -360,7 +360,7 @@ STDCALL PsSetThreadWin32Thread( VOID STDCALL STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize); diff --git a/reactos/include/ddk/pstypes.h b/reactos/include/ddk/pstypes.h index a1ce54d444b..7b31e080fcc 100644 --- a/reactos/include/ddk/pstypes.h +++ b/reactos/include/ddk/pstypes.h @@ -66,6 +66,40 @@ typedef NTSTATUS STDCALL_FUNC typedef NTSTATUS STDCALL_FUNC (*PW32_THREAD_CALLBACK)(struct _ETHREAD *Thread, BOOLEAN Create); + +/* + * Callbacks used for Win32 objects... this define won't be needed after the Object Manager + * rewrite -- Alex + */ +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_PARSE_ROUTINE)(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + +typedef VOID STDCALL_FUNC +(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject); + +typedef PVOID STDCALL_FUNC +(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject, + PWSTR Name, + ULONG Attributes); + +typedef struct _W32_OBJECT_CALLBACK { + OBJECT_CREATE_ROUTINE WinStaCreate; + OBJECT_PARSE_ROUTINE WinStaParse; + OBJECT_DELETE_ROUTINE WinStaDelete; + OBJECT_FIND_ROUTINE WinStaFind; + OBJECT_CREATE_ROUTINE DesktopCreate; + OBJECT_DELETE_ROUTINE DesktopDelete; +} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK; typedef struct _STACK_INFORMATION { diff --git a/reactos/ntoskrnl/ex/win32k.c b/reactos/ntoskrnl/ex/win32k.c index 7fc3ed9a645..6a93e857465 100644 --- a/reactos/ntoskrnl/ex/win32k.c +++ b/reactos/ntoskrnl/ex/win32k.c @@ -5,7 +5,8 @@ * FILE: ntoskrnl/ex/win32k.c * PURPOSE: Executive Win32 subsystem support * - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Moved callbacks to win32k and cleanup. + * Casper S. Hornstrup (chorns@users.sourceforge.net) */ #include @@ -14,320 +15,160 @@ /* DATA **********************************************************************/ -#define WINSTA_ACCESSCLIPBOARD (0x4L) -#define WINSTA_ACCESSGLOBALATOMS (0x20L) -#define WINSTA_CREATEDESKTOP (0x8L) -#define WINSTA_ENUMDESKTOPS (0x1L) -#define WINSTA_ENUMERATE (0x100L) -#define WINSTA_EXITWINDOWS (0x40L) -#define WINSTA_READATTRIBUTES (0x2L) -#define WINSTA_READSCREEN (0x200L) -#define WINSTA_WRITEATTRIBUTES (0x10L) - -#define DF_ALLOWOTHERACCOUNTHOOK (0x1L) -#define DESKTOP_CREATEMENU (0x4L) -#define DESKTOP_CREATEWINDOW (0x2L) -#define DESKTOP_ENUMERATE (0x40L) -#define DESKTOP_HOOKCONTROL (0x8L) -#define DESKTOP_JOURNALPLAYBACK (0x20L) -#define DESKTOP_JOURNALRECORD (0x10L) -#define DESKTOP_READOBJECTS (0x1L) -#define DESKTOP_SWITCHDESKTOP (0x100L) -#define DESKTOP_WRITEOBJECTS (0x80L) - POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL; POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL; static GENERIC_MAPPING ExpWindowStationMapping = { - STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN, - STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES, - STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS, - STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | - WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | - WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES + + STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN, + STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES, + STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS, + STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | + WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | + WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES }; static GENERIC_MAPPING ExpDesktopMapping = { - STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS, - STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | - DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS, - STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP, - STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | - DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | - DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS + + STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS, + STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | + DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS, + STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP, + STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | + DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | + DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS }; +OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate = NULL; +OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse = NULL; +OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete = NULL; +OBJECT_FIND_ROUTINE ExpWindowStationObjectFind = NULL; +OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate = NULL; +OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete = NULL; + /* FUNCTIONS ****************************************************************/ - -NTSTATUS STDCALL +NTSTATUS +STDCALL ExpWinStaObjectCreate(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes) + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) { - PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; - UNICODE_STRING UnicodeString; - NTSTATUS Status; - - if (RemainingPath == NULL) - { - return STATUS_SUCCESS; - } - - if (wcschr((RemainingPath + 1), '\\') != NULL) - { - return STATUS_UNSUCCESSFUL; - } - - RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); - - DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString); - - Status = RtlpCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer, NonPagedPool); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - KeInitializeSpinLock(&WinSta->Lock); - - InitializeListHead(&WinSta->DesktopListHead); - -#if 1 - WinSta->AtomTable = NULL; -#endif - - Status = RtlCreateAtomTable(37, &WinSta->AtomTable); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&WinSta->Name); - return Status; - } - - WinSta->SystemMenuTemplate = (HANDLE)0; - - DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); - - return STATUS_SUCCESS; + /* Call the Registered Callback */ + return ExpWindowStationObjectCreate(ObjectBody, + Parent, + RemainingPath, + ObjectAttributes); } -VOID STDCALL +VOID +STDCALL ExpWinStaObjectDelete(PVOID DeletedObject) { - PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; - - DPRINT("Deleting window station (0x%X)\n", WinSta); - - RtlDestroyAtomTable(WinSta->AtomTable); - - RtlFreeUnicodeString(&WinSta->Name); + /* Call the Registered Callback */ + ExpWindowStationObjectDelete(DeletedObject); } PVOID +STDCALL ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject, - PWSTR Name, - ULONG Attributes) + PWSTR Name, + ULONG Attributes) { - PLIST_ENTRY Current; - PDESKTOP_OBJECT CurrentObject; - - DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); - - if (Name[0] == 0) - { - return NULL; - } - - Current = WinStaObject->DesktopListHead.Flink; - while (Current != &WinStaObject->DesktopListHead) - { - CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry); - DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name); - if (Attributes & OBJ_CASE_INSENSITIVE) - { - if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0) - { - DPRINT("Found desktop at (0x%X)\n", CurrentObject); - return CurrentObject; - } - } - else - { - if (wcscmp(CurrentObject->Name.Buffer, Name) == 0) - { - DPRINT("Found desktop at (0x%X)\n", CurrentObject); - return CurrentObject; - } - } - Current = Current->Flink; - } - - DPRINT("Returning NULL\n"); - - return NULL; + /* Call the Registered Callback */ + return ExpWindowStationObjectFind(WinStaObject, + Name, + Attributes); } -NTSTATUS STDCALL +NTSTATUS +STDCALL ExpWinStaObjectParse(PVOID Object, - PVOID *NextObject, - PUNICODE_STRING FullPath, - PWSTR *Path, - ULONG Attributes) + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes) { - PVOID FoundObject; - NTSTATUS Status; - PWSTR End; - - DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); - - *NextObject = NULL; - - if ((Path == NULL) || ((*Path) == NULL)) - { - return STATUS_SUCCESS; - } - - End = wcschr((*Path) + 1, '\\'); - if (End != NULL) - { - DPRINT("Name contains illegal characters\n"); - return STATUS_UNSUCCESSFUL; - } - - FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes); - if (FoundObject == NULL) - { - DPRINT("Name was not found\n"); - return STATUS_UNSUCCESSFUL; - } - - Status = ObReferenceObjectByPointer( - FoundObject, - STANDARD_RIGHTS_REQUIRED, - NULL, - UserMode); - - *NextObject = FoundObject; - *Path = NULL; - - return Status; + /* Call the Registered Callback */ + return ExpWindowStationObjectParse(Object, + NextObject, + FullPath, + Path, + Attributes); } -NTSTATUS STDCALL -ExpDesktopObjectCreate(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes) +NTSTATUS +STDCALL +ExpDesktopCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) { - PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; - UNICODE_STRING UnicodeString; - - if (RemainingPath == NULL) - { - return STATUS_SUCCESS; - } - - if (wcschr((RemainingPath + 1), '\\') != NULL) - { - return STATUS_UNSUCCESSFUL; - } - - RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); - - DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString); - - KeInitializeSpinLock(&Desktop->Lock); - - Desktop->WindowStation = (PWINSTATION_OBJECT)Parent; - - /* Put the desktop on the window station's list of associcated desktops */ - ExInterlockedInsertTailList( - &Desktop->WindowStation->DesktopListHead, - &Desktop->ListEntry, - &Desktop->WindowStation->Lock); - - return RtlpCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer, NonPagedPool); + /* Call the Registered Callback */ + return ExpDesktopObjectCreate(ObjectBody, + Parent, + RemainingPath, + ObjectAttributes); } -VOID STDCALL -ExpDesktopObjectDelete(PVOID DeletedObject) +VOID +STDCALL +ExpDesktopDelete(PVOID DeletedObject) { - PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; - KIRQL OldIrql; - - DPRINT("Deleting desktop (0x%X)\n", Desktop); - - /* Remove the desktop from the window station's list of associcated desktops */ - KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql); - RemoveEntryList(&Desktop->ListEntry); - KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql); - - RtlFreeUnicodeString(&Desktop->Name); + /* Call the Registered Callback */ + ExpDesktopObjectDelete(DeletedObject); } -VOID INIT_FUNCTION +VOID +INIT_FUNCTION ExpWin32kInit(VOID) { - /* Create window station object type */ - ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - if (ExWindowStationObjectType == NULL) - { - CPRINT("Could not create window station object type\n"); - KEBUGCHECK(0); - } + /* Create window station object type */ + ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); + ExWindowStationObjectType->TotalObjects = 0; + ExWindowStationObjectType->TotalHandles = 0; + ExWindowStationObjectType->PeakObjects = 0; + ExWindowStationObjectType->PeakHandles = 0; + ExWindowStationObjectType->PagedPoolCharge = 0; + ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT); + ExWindowStationObjectType->Mapping = &ExpWindowStationMapping; + ExWindowStationObjectType->Dump = NULL; + ExWindowStationObjectType->Open = NULL; + ExWindowStationObjectType->Close = NULL; + ExWindowStationObjectType->Delete = ExpWinStaObjectDelete; + ExWindowStationObjectType->Parse = ExpWinStaObjectParse; + ExWindowStationObjectType->Security = NULL; + ExWindowStationObjectType->QueryName = NULL; + ExWindowStationObjectType->OkayToClose = NULL; + ExWindowStationObjectType->Create = ExpWinStaObjectCreate; + ExWindowStationObjectType->DuplicationNotify = NULL; + RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation"); + ObpCreateTypeObject(ExWindowStationObjectType); - ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); - ExWindowStationObjectType->TotalObjects = 0; - ExWindowStationObjectType->TotalHandles = 0; - ExWindowStationObjectType->PeakObjects = 0; - ExWindowStationObjectType->PeakHandles = 0; - ExWindowStationObjectType->PagedPoolCharge = 0; - ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT); - ExWindowStationObjectType->Mapping = &ExpWindowStationMapping; - ExWindowStationObjectType->Dump = NULL; - ExWindowStationObjectType->Open = NULL; - ExWindowStationObjectType->Close = NULL; - ExWindowStationObjectType->Delete = ExpWinStaObjectDelete; - ExWindowStationObjectType->Parse = ExpWinStaObjectParse; - ExWindowStationObjectType->Security = NULL; - ExWindowStationObjectType->QueryName = NULL; - ExWindowStationObjectType->OkayToClose = NULL; - ExWindowStationObjectType->Create = ExpWinStaObjectCreate; - ExWindowStationObjectType->DuplicationNotify = NULL; - RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation"); - - ObpCreateTypeObject(ExWindowStationObjectType); - - /* Create desktop object type */ - ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - if (ExDesktopObjectType == NULL) - { - CPRINT("Could not create desktop object type\n"); - KEBUGCHECK(0); - } - - ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K'); - ExDesktopObjectType->TotalObjects = 0; - ExDesktopObjectType->TotalHandles = 0; - ExDesktopObjectType->PeakObjects = 0; - ExDesktopObjectType->PeakHandles = 0; - ExDesktopObjectType->PagedPoolCharge = 0; - ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT); - ExDesktopObjectType->Mapping = &ExpDesktopMapping; - ExDesktopObjectType->Dump = NULL; - ExDesktopObjectType->Open = NULL; - ExDesktopObjectType->Close = NULL; - ExDesktopObjectType->Delete = ExpDesktopObjectDelete; - ExDesktopObjectType->Parse = NULL; - ExDesktopObjectType->Security = NULL; - ExDesktopObjectType->QueryName = NULL; - ExDesktopObjectType->OkayToClose = NULL; - ExDesktopObjectType->Create = ExpDesktopObjectCreate; - ExDesktopObjectType->DuplicationNotify = NULL; - RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop"); - - ObpCreateTypeObject(ExDesktopObjectType); + /* Create desktop object type */ + ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K'); + ExDesktopObjectType->TotalObjects = 0; + ExDesktopObjectType->TotalHandles = 0; + ExDesktopObjectType->PeakObjects = 0; + ExDesktopObjectType->PeakHandles = 0; + ExDesktopObjectType->PagedPoolCharge = 0; + ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT); + ExDesktopObjectType->Mapping = &ExpDesktopMapping; + ExDesktopObjectType->Dump = NULL; + ExDesktopObjectType->Open = NULL; + ExDesktopObjectType->Close = NULL; + ExDesktopObjectType->Delete = ExpDesktopDelete; + ExDesktopObjectType->Parse = NULL; + ExDesktopObjectType->Security = NULL; + ExDesktopObjectType->QueryName = NULL; + ExDesktopObjectType->OkayToClose = NULL; + ExDesktopObjectType->Create = ExpDesktopCreate; + ExDesktopObjectType->DuplicationNotify = NULL; + RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop"); + ObpCreateTypeObject(ExDesktopObjectType); } /* EOF */ diff --git a/reactos/ntoskrnl/ps/win32.c b/reactos/ntoskrnl/ps/win32.c index 6e9ef4d07ba..c3f15ad102e 100644 --- a/reactos/ntoskrnl/ps/win32.c +++ b/reactos/ntoskrnl/ps/win32.c @@ -21,6 +21,13 @@ static PW32_THREAD_CALLBACK PspWin32ThreadCallback = NULL; static ULONG PspWin32ProcessSize = 0; static ULONG PspWin32ThreadSize = 0; +extern OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate; +extern OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse; +extern OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete; +extern OBJECT_FIND_ROUTINE ExpWindowStationObjectFind; +extern OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate; +extern OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete; + /* FUNCTIONS ***************************************************************/ PW32THREAD STDCALL @@ -59,7 +66,7 @@ PsCreateWin32Process(PEPROCESS Process) VOID STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize) @@ -69,9 +76,15 @@ PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PspWin32ProcessSize = W32ProcessSize; PspWin32ThreadSize = W32ThreadSize; + + ExpWindowStationObjectCreate = W32ObjectCallback->WinStaCreate; + ExpWindowStationObjectParse = W32ObjectCallback->WinStaParse; + ExpWindowStationObjectDelete = W32ObjectCallback->WinStaDelete; + ExpWindowStationObjectFind = W32ObjectCallback->WinStaFind; + ExpDesktopObjectCreate = W32ObjectCallback->DesktopCreate; + ExpDesktopObjectDelete = W32ObjectCallback->DesktopDelete; } - NTSTATUS PsInitWin32Thread (PETHREAD Thread) { diff --git a/reactos/subsys/win32k/include/desktop.h b/reactos/subsys/win32k/include/desktop.h index 58949bf6d7e..bb01c3ebe9e 100644 --- a/reactos/subsys/win32k/include/desktop.h +++ b/reactos/subsys/win32k/include/desktop.h @@ -20,6 +20,16 @@ InitDesktopImpl(VOID); NTSTATUS FASTCALL CleanupDesktopImpl(VOID); +NTSTATUS +STDCALL +IntDesktopObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +VOID STDCALL +IntDesktopObjectDelete(PVOID DeletedObject); + VOID FASTCALL IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect); diff --git a/reactos/subsys/win32k/include/winsta.h b/reactos/subsys/win32k/include/winsta.h index 5b57c075c62..73daafb4070 100644 --- a/reactos/subsys/win32k/include/winsta.h +++ b/reactos/subsys/win32k/include/winsta.h @@ -23,6 +23,29 @@ InitWindowStationImpl(VOID); NTSTATUS FASTCALL CleanupWindowStationImpl(VOID); +NTSTATUS +STDCALL +IntWinStaObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +VOID STDCALL +IntWinStaObjectDelete(PVOID DeletedObject); + +PVOID STDCALL +IntWinStaObjectFind(PVOID Object, + PWSTR Name, + ULONG Attributes); + +NTSTATUS +STDCALL +IntWinStaObjectParse(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + NTSTATUS FASTCALL IntValidateWindowStationHandle( HWINSTA WindowStation, diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index b0c46d2c961..ece94e4daf6 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -35,11 +35,45 @@ typedef NTSTATUS (STDCALL *PW32_THREAD_CALLBACK)( struct _ETHREAD *Thread, BOOLEAN Create); +/* + * Callbacks used for Win32 objects... this define won't be needed after the Object Manager + * rewrite -- Alex + */ +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_PARSE_ROUTINE)(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + +typedef VOID STDCALL_FUNC +(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject); + +typedef PVOID STDCALL_FUNC +(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject, + PWSTR Name, + ULONG Attributes); + +typedef struct _W32_OBJECT_CALLBACK { + OBJECT_CREATE_ROUTINE WinStaCreate; + OBJECT_PARSE_ROUTINE WinStaParse; + OBJECT_DELETE_ROUTINE WinStaDelete; + OBJECT_FIND_ROUTINE WinStaFind; + OBJECT_CREATE_ROUTINE DesktopCreate; + OBJECT_DELETE_ROUTINE DesktopDelete; +} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK; + VOID STDCALL PsEstablishWin32Callouts( PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize); @@ -219,6 +253,7 @@ DllMain ( { NTSTATUS Status; BOOLEAN Result; + W32_OBJECT_CALLBACK Win32kObjectCallbacks; /* * Register user mode call interface @@ -234,13 +269,22 @@ DllMain ( DPRINT1("Adding system services failed!\n"); return STATUS_UNSUCCESSFUL; } - + + /* + * Register Object Manager Callbacks + */ + Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectCreate; + Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse; + Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete; + Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind; + Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate; + Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete; /* * Register our per-process and per-thread structures. */ PsEstablishWin32Callouts (Win32kProcessCallback, Win32kThreadCallback, - 0, + &Win32kObjectCallbacks, 0, sizeof(W32THREAD), sizeof(W32PROCESS)); diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c index 55e4fa2f103..ccc92975055 100644 --- a/reactos/subsys/win32k/ntuser/desktop.c +++ b/reactos/subsys/win32k/ntuser/desktop.c @@ -66,6 +66,60 @@ CleanupDesktopImpl(VOID) return STATUS_SUCCESS; } +/* OBJECT CALLBACKS **********************************************************/ + +NTSTATUS STDCALL +IntDesktopObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) +{ + PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; + UNICODE_STRING UnicodeString; + + if (RemainingPath == NULL) + { + return STATUS_SUCCESS; + } + + if (wcschr((RemainingPath + 1), '\\') != NULL) + { + return STATUS_UNSUCCESSFUL; + } + + RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); + + DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString); + + KeInitializeSpinLock(&Desktop->Lock); + + Desktop->WindowStation = (PWINSTATION_OBJECT)Parent; + + /* Put the desktop on the window station's list of associcated desktops */ + ExInterlockedInsertTailList( + &Desktop->WindowStation->DesktopListHead, + &Desktop->ListEntry, + &Desktop->WindowStation->Lock); + + return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer); +} + +VOID STDCALL +IntDesktopObjectDelete(PVOID DeletedObject) +{ + PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; + KIRQL OldIrql; + + DPRINT("Deleting desktop (0x%X)\n", Desktop); + + /* Remove the desktop from the window station's list of associcated desktops */ + KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql); + RemoveEntryList(&Desktop->ListEntry); + KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql); + + RtlFreeUnicodeString(&Desktop->Name); +} + /* PRIVATE FUNCTIONS **********************************************************/ NTSTATUS FASTCALL diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 3b8e33a9493..cb273ae387a 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -30,6 +30,7 @@ /* INCLUDES ******************************************************************/ #include +#include #define NDEBUG #include @@ -113,6 +114,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) PUNICODE_STRING ClassName; UINT Size; + _SEH_TRY { if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size) { return (UINT) wParam; @@ -163,6 +165,11 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) { return MsgMemoryEntry->Size; } + } _SEH_HANDLE { + + DPRINT1("BOO!\n"); + return 0; + } _SEH_END; } static FASTCALL NTSTATUS diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index a070b596e1e..ebc03026d7b 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -80,6 +80,165 @@ CleanupWindowStationImpl(VOID) return STATUS_SUCCESS; } +/* OBJECT CALLBACKS **********************************************************/ + +NTSTATUS +STDCALL +IntWinStaObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) +{ + PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; + UNICODE_STRING UnicodeString; + NTSTATUS Status; + + if (RemainingPath == NULL) + { + return STATUS_SUCCESS; + } + + if (wcschr((RemainingPath + 1), '\\') != NULL) + { + return STATUS_UNSUCCESSFUL; + } + + RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); + + DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString); + + Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + KeInitializeSpinLock(&WinSta->Lock); + + InitializeListHead(&WinSta->DesktopListHead); + +#if 1 + WinSta->AtomTable = NULL; +#endif + + Status = RtlCreateAtomTable(37, &WinSta->AtomTable); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&WinSta->Name); + return Status; + } + + WinSta->SystemMenuTemplate = (HANDLE)0; + + DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); + + return STATUS_SUCCESS; +} + +VOID STDCALL +IntWinStaObjectDelete(PVOID DeletedObject) +{ + PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; + + DPRINT("Deleting window station (0x%X)\n", WinSta); + + RtlDestroyAtomTable(WinSta->AtomTable); + + RtlFreeUnicodeString(&WinSta->Name); +} + +PVOID STDCALL +IntWinStaObjectFind(PVOID Object, + PWSTR Name, + ULONG Attributes) +{ + PLIST_ENTRY Current; + PDESKTOP_OBJECT CurrentObject; + PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)Object; + + DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); + + if (Name[0] == 0) + { + return NULL; + } + + Current = WinStaObject->DesktopListHead.Flink; + while (Current != &WinStaObject->DesktopListHead) + { + CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry); + DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name); + if (Attributes & OBJ_CASE_INSENSITIVE) + { + if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0) + { + DPRINT("Found desktop at (0x%X)\n", CurrentObject); + return CurrentObject; + } + } + else + { + if (wcscmp(CurrentObject->Name.Buffer, Name) == 0) + { + DPRINT("Found desktop at (0x%X)\n", CurrentObject); + return CurrentObject; + } + } + Current = Current->Flink; + } + + DPRINT("Returning NULL\n"); + + return NULL; +} + +NTSTATUS +STDCALL +IntWinStaObjectParse(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes) +{ + PVOID FoundObject; + NTSTATUS Status; + PWSTR End; + + DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); + + *NextObject = NULL; + + if ((Path == NULL) || ((*Path) == NULL)) + { + return STATUS_SUCCESS; + } + + End = wcschr((*Path) + 1, '\\'); + if (End != NULL) + { + DPRINT("Name contains illegal characters\n"); + return STATUS_UNSUCCESSFUL; + } + + FoundObject = IntWinStaObjectFind(Object, (*Path) + 1, Attributes); + if (FoundObject == NULL) + { + DPRINT("Name was not found\n"); + return STATUS_UNSUCCESSFUL; + } + + Status = ObReferenceObjectByPointer( + FoundObject, + STANDARD_RIGHTS_REQUIRED, + NULL, + UserMode); + + *NextObject = FoundObject; + *Path = NULL; + + return Status; +} + /* PRIVATE FUNCTIONS **********************************************************/ /* diff --git a/reactos/w32api/include/ddk/ntifs.h b/reactos/w32api/include/ddk/ntifs.h index 3a8eead52dc..e11f33905ff 100644 --- a/reactos/w32api/include/ddk/ntifs.h +++ b/reactos/w32api/include/ddk/ntifs.h @@ -315,6 +315,7 @@ extern PACL SeSystemDefaultDacl; #define TOKEN_ADJUST_PRIVILEGES (0x0020) #define TOKEN_ADJUST_GROUPS (0x0040) #define TOKEN_ADJUST_DEFAULT (0x0080) +#define TOKEN_ADJUST_SESSIONID (0x0100) #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\ TOKEN_ASSIGN_PRIMARY |\ @@ -324,7 +325,8 @@ extern PACL SeSystemDefaultDacl; TOKEN_QUERY_SOURCE |\ TOKEN_ADJUST_PRIVILEGES |\ TOKEN_ADJUST_GROUPS |\ - TOKEN_ADJUST_DEFAULT) + TOKEN_ADJUST_DEFAULT |\ + TOKEN_ADJUST_SESSIONID) #define TOKEN_READ (STANDARD_RIGHTS_READ |\ TOKEN_QUERY) @@ -1216,13 +1218,23 @@ typedef struct _GENERATE_NAME_CONTEXT { ULONG LastIndexValue; } GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT; +typedef struct _HANDLE_TABLE_ENTRY_INFO { + ULONG AuditMask; +} HANDLE_TABLE_ENTRY_INFO, *PHANDLE_TABLE_ENTRY_INFO; + typedef struct _HANDLE_TABLE_ENTRY { - PVOID Object; - ULONG ObjectAttributes; - ULONG GrantedAccess; - USHORT GrantedAccessIndex; - USHORT CreatorBackTraceIndex; - ULONG NextFreeTableEntry; + union { + PVOID Object; + ULONG ObAttributes; + PHANDLE_TABLE_ENTRY_INFO InfoTable; + ULONG_PTR Value; + } u1; + union { + ULONG GrantedAccess; + USHORT GrantedAccessIndex; + LONG NextFreeTableEntry; + } u2; + USHORT CreatorBackTraceIndex; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; typedef struct _MAPPING_PAIR { diff --git a/reactos/w32api/include/ddk/winddk.h b/reactos/w32api/include/ddk/winddk.h index 7032b66035d..8be213b4c51 100644 --- a/reactos/w32api/include/ddk/winddk.h +++ b/reactos/w32api/include/ddk/winddk.h @@ -126,6 +126,18 @@ static __inline struct _KPCR * KeGetCurrentKPCR( return (struct _KPCR *) Value; } +static __inline struct _KPRCB * KeGetCurrentPrcb( + VOID) +{ + ULONG Value; + + __asm__ __volatile__ ("movl %%fs:0x20, %0\n\t" + : "=r" (Value) + : /* no inputs */ + ); + return (struct _KPRCB *) Value; +} + /* ** Simple structures */ @@ -3795,6 +3807,10 @@ typedef enum _PROCESSINFOCLASS { ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, + ProcessUnknown33, + ProcessUnknown34, + ProcessUnknown35, + ProcessCookie, MaxProcessInfoClass } PROCESSINFOCLASS; diff --git a/reactos/w32api/include/winnt.h b/reactos/w32api/include/winnt.h index 3ad766c187b..35fdbc6785b 100644 --- a/reactos/w32api/include/winnt.h +++ b/reactos/w32api/include/winnt.h @@ -1140,6 +1140,7 @@ typedef DWORD FLONG; #define TOKEN_ADJUST_PRIVILEGES (0x0020) #define TOKEN_ADJUST_GROUPS (0x0040) #define TOKEN_ADJUST_DEFAULT (0x0080) +#define TOKEN_ADJUST_SESSIONID (0x0100) #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\ TOKEN_ASSIGN_PRIMARY |\ TOKEN_DUPLICATE |\ @@ -1148,7 +1149,8 @@ typedef DWORD FLONG; TOKEN_QUERY_SOURCE |\ TOKEN_ADJUST_PRIVILEGES |\ TOKEN_ADJUST_GROUPS |\ - TOKEN_ADJUST_DEFAULT) + TOKEN_ADJUST_DEFAULT |\ + TOKEN_ADJUST_SESSIONID) #define TOKEN_READ (STANDARD_RIGHTS_READ |\ TOKEN_QUERY) #define TOKEN_WRITE (STANDARD_RIGHTS_WRITE |\