Alex Ionescu <ionucu@videotron.ca>

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
This commit is contained in:
Filip Navara 2005-03-12 14:15:49 +00:00
parent 510dc740a5
commit 5307ffb9c6
14 changed files with 528 additions and 292 deletions

View file

@ -77,6 +77,27 @@ enum
#define HIGH_LEVEL 31 // Highest interrupt level #define HIGH_LEVEL 31 // Highest interrupt level
#define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization 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__ */ #endif /* __ASM__ */
/* Values returned by KeGetPreviousMode() */ /* Values returned by KeGetPreviousMode() */

View file

@ -360,7 +360,7 @@ STDCALL PsSetThreadWin32Thread(
VOID STDCALL VOID STDCALL
STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
PW32_THREAD_CALLBACK W32ThreadCallback, PW32_THREAD_CALLBACK W32ThreadCallback,
PVOID Param3, PW32_OBJECT_CALLBACK W32ObjectCallback,
PVOID Param4, PVOID Param4,
ULONG W32ThreadSize, ULONG W32ThreadSize,
ULONG W32ProcessSize); ULONG W32ProcessSize);

View file

@ -67,6 +67,40 @@ typedef NTSTATUS STDCALL_FUNC
(*PW32_THREAD_CALLBACK)(struct _ETHREAD *Thread, (*PW32_THREAD_CALLBACK)(struct _ETHREAD *Thread,
BOOLEAN Create); 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 typedef struct _STACK_INFORMATION
{ {
PVOID BaseAddress; PVOID BaseAddress;

View file

@ -5,7 +5,8 @@
* FILE: ntoskrnl/ex/win32k.c * FILE: ntoskrnl/ex/win32k.c
* PURPOSE: Executive Win32 subsystem support * 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 <ntoskrnl.h> #include <ntoskrnl.h>
@ -14,31 +15,11 @@
/* DATA **********************************************************************/ /* 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 ExWindowStationObjectType = NULL;
POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL; POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
static GENERIC_MAPPING ExpWindowStationMapping = { static GENERIC_MAPPING ExpWindowStationMapping = {
STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN, STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN,
STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES, STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES,
STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS, STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS,
@ -48,6 +29,7 @@ static GENERIC_MAPPING ExpWindowStationMapping = {
}; };
static GENERIC_MAPPING ExpDesktopMapping = { static GENERIC_MAPPING ExpDesktopMapping = {
STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS, STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS,
STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS, DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS,
@ -57,226 +39,93 @@ static GENERIC_MAPPING ExpDesktopMapping = {
DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS 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 ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS
NTSTATUS STDCALL STDCALL
ExpWinStaObjectCreate(PVOID ObjectBody, ExpWinStaObjectCreate(PVOID ObjectBody,
PVOID Parent, PVOID Parent,
PWSTR RemainingPath, PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes) struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{ {
PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; /* Call the Registered Callback */
UNICODE_STRING UnicodeString; return ExpWindowStationObjectCreate(ObjectBody,
NTSTATUS Status; Parent,
RemainingPath,
if (RemainingPath == NULL) ObjectAttributes);
{
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;
} }
VOID STDCALL VOID
STDCALL
ExpWinStaObjectDelete(PVOID DeletedObject) ExpWinStaObjectDelete(PVOID DeletedObject)
{ {
PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; /* Call the Registered Callback */
ExpWindowStationObjectDelete(DeletedObject);
DPRINT("Deleting window station (0x%X)\n", WinSta);
RtlDestroyAtomTable(WinSta->AtomTable);
RtlFreeUnicodeString(&WinSta->Name);
} }
PVOID PVOID
STDCALL
ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject, ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
PWSTR Name, PWSTR Name,
ULONG Attributes) ULONG Attributes)
{ {
PLIST_ENTRY Current; /* Call the Registered Callback */
PDESKTOP_OBJECT CurrentObject; return ExpWindowStationObjectFind(WinStaObject,
Name,
DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); Attributes);
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 NTSTATUS
STDCALL
ExpWinStaObjectParse(PVOID Object, ExpWinStaObjectParse(PVOID Object,
PVOID *NextObject, PVOID *NextObject,
PUNICODE_STRING FullPath, PUNICODE_STRING FullPath,
PWSTR *Path, PWSTR *Path,
ULONG Attributes) ULONG Attributes)
{ {
PVOID FoundObject; /* Call the Registered Callback */
NTSTATUS Status; return ExpWindowStationObjectParse(Object,
PWSTR End; NextObject,
FullPath,
DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); Path,
Attributes);
*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;
} }
NTSTATUS STDCALL NTSTATUS
ExpDesktopObjectCreate(PVOID ObjectBody, STDCALL
ExpDesktopCreate(PVOID ObjectBody,
PVOID Parent, PVOID Parent,
PWSTR RemainingPath, PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes) struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{ {
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; /* Call the Registered Callback */
UNICODE_STRING UnicodeString; return ExpDesktopObjectCreate(ObjectBody,
Parent,
if (RemainingPath == NULL) RemainingPath,
{ ObjectAttributes);
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);
} }
VOID STDCALL VOID
ExpDesktopObjectDelete(PVOID DeletedObject) STDCALL
ExpDesktopDelete(PVOID DeletedObject)
{ {
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; /* Call the Registered Callback */
KIRQL OldIrql; ExpDesktopObjectDelete(DeletedObject);
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);
} }
VOID INIT_FUNCTION VOID
INIT_FUNCTION
ExpWin32kInit(VOID) ExpWin32kInit(VOID)
{ {
/* Create window station object type */ /* Create window station object type */
ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
if (ExWindowStationObjectType == NULL)
{
CPRINT("Could not create window station object type\n");
KEBUGCHECK(0);
}
ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
ExWindowStationObjectType->TotalObjects = 0; ExWindowStationObjectType->TotalObjects = 0;
ExWindowStationObjectType->TotalHandles = 0; ExWindowStationObjectType->TotalHandles = 0;
@ -296,17 +145,10 @@ ExpWin32kInit(VOID)
ExWindowStationObjectType->Create = ExpWinStaObjectCreate; ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
ExWindowStationObjectType->DuplicationNotify = NULL; ExWindowStationObjectType->DuplicationNotify = NULL;
RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation"); RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation");
ObpCreateTypeObject(ExWindowStationObjectType); ObpCreateTypeObject(ExWindowStationObjectType);
/* Create desktop object type */ /* Create desktop object type */
ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(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->Tag = TAG('D', 'E', 'S', 'K');
ExDesktopObjectType->TotalObjects = 0; ExDesktopObjectType->TotalObjects = 0;
ExDesktopObjectType->TotalHandles = 0; ExDesktopObjectType->TotalHandles = 0;
@ -318,15 +160,14 @@ ExpWin32kInit(VOID)
ExDesktopObjectType->Dump = NULL; ExDesktopObjectType->Dump = NULL;
ExDesktopObjectType->Open = NULL; ExDesktopObjectType->Open = NULL;
ExDesktopObjectType->Close = NULL; ExDesktopObjectType->Close = NULL;
ExDesktopObjectType->Delete = ExpDesktopObjectDelete; ExDesktopObjectType->Delete = ExpDesktopDelete;
ExDesktopObjectType->Parse = NULL; ExDesktopObjectType->Parse = NULL;
ExDesktopObjectType->Security = NULL; ExDesktopObjectType->Security = NULL;
ExDesktopObjectType->QueryName = NULL; ExDesktopObjectType->QueryName = NULL;
ExDesktopObjectType->OkayToClose = NULL; ExDesktopObjectType->OkayToClose = NULL;
ExDesktopObjectType->Create = ExpDesktopObjectCreate; ExDesktopObjectType->Create = ExpDesktopCreate;
ExDesktopObjectType->DuplicationNotify = NULL; ExDesktopObjectType->DuplicationNotify = NULL;
RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop"); RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop");
ObpCreateTypeObject(ExDesktopObjectType); ObpCreateTypeObject(ExDesktopObjectType);
} }

View file

@ -21,6 +21,13 @@ static PW32_THREAD_CALLBACK PspWin32ThreadCallback = NULL;
static ULONG PspWin32ProcessSize = 0; static ULONG PspWin32ProcessSize = 0;
static ULONG PspWin32ThreadSize = 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 ***************************************************************/ /* FUNCTIONS ***************************************************************/
PW32THREAD STDCALL PW32THREAD STDCALL
@ -59,7 +66,7 @@ PsCreateWin32Process(PEPROCESS Process)
VOID STDCALL VOID STDCALL
PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
PW32_THREAD_CALLBACK W32ThreadCallback, PW32_THREAD_CALLBACK W32ThreadCallback,
PVOID Param3, PW32_OBJECT_CALLBACK W32ObjectCallback,
PVOID Param4, PVOID Param4,
ULONG W32ThreadSize, ULONG W32ThreadSize,
ULONG W32ProcessSize) ULONG W32ProcessSize)
@ -69,8 +76,14 @@ PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
PspWin32ProcessSize = W32ProcessSize; PspWin32ProcessSize = W32ProcessSize;
PspWin32ThreadSize = W32ThreadSize; PspWin32ThreadSize = W32ThreadSize;
}
ExpWindowStationObjectCreate = W32ObjectCallback->WinStaCreate;
ExpWindowStationObjectParse = W32ObjectCallback->WinStaParse;
ExpWindowStationObjectDelete = W32ObjectCallback->WinStaDelete;
ExpWindowStationObjectFind = W32ObjectCallback->WinStaFind;
ExpDesktopObjectCreate = W32ObjectCallback->DesktopCreate;
ExpDesktopObjectDelete = W32ObjectCallback->DesktopDelete;
}
NTSTATUS NTSTATUS
PsInitWin32Thread (PETHREAD Thread) PsInitWin32Thread (PETHREAD Thread)

View file

@ -20,6 +20,16 @@ InitDesktopImpl(VOID);
NTSTATUS FASTCALL NTSTATUS FASTCALL
CleanupDesktopImpl(VOID); CleanupDesktopImpl(VOID);
NTSTATUS
STDCALL
IntDesktopObjectCreate(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes);
VOID STDCALL
IntDesktopObjectDelete(PVOID DeletedObject);
VOID FASTCALL VOID FASTCALL
IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect); IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect);

View file

@ -23,6 +23,29 @@ InitWindowStationImpl(VOID);
NTSTATUS FASTCALL NTSTATUS FASTCALL
CleanupWindowStationImpl(VOID); 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 NTSTATUS FASTCALL
IntValidateWindowStationHandle( IntValidateWindowStationHandle(
HWINSTA WindowStation, HWINSTA WindowStation,

View file

@ -35,11 +35,45 @@ typedef NTSTATUS (STDCALL *PW32_THREAD_CALLBACK)(
struct _ETHREAD *Thread, struct _ETHREAD *Thread,
BOOLEAN Create); 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 VOID STDCALL
PsEstablishWin32Callouts( PsEstablishWin32Callouts(
PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_PROCESS_CALLBACK W32ProcessCallback,
PW32_THREAD_CALLBACK W32ThreadCallback, PW32_THREAD_CALLBACK W32ThreadCallback,
PVOID Param3, PW32_OBJECT_CALLBACK W32ObjectCallback,
PVOID Param4, PVOID Param4,
ULONG W32ThreadSize, ULONG W32ThreadSize,
ULONG W32ProcessSize); ULONG W32ProcessSize);
@ -219,6 +253,7 @@ DllMain (
{ {
NTSTATUS Status; NTSTATUS Status;
BOOLEAN Result; BOOLEAN Result;
W32_OBJECT_CALLBACK Win32kObjectCallbacks;
/* /*
* Register user mode call interface * Register user mode call interface
@ -235,12 +270,21 @@ DllMain (
return STATUS_UNSUCCESSFUL; 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. * Register our per-process and per-thread structures.
*/ */
PsEstablishWin32Callouts (Win32kProcessCallback, PsEstablishWin32Callouts (Win32kProcessCallback,
Win32kThreadCallback, Win32kThreadCallback,
0, &Win32kObjectCallbacks,
0, 0,
sizeof(W32THREAD), sizeof(W32THREAD),
sizeof(W32PROCESS)); sizeof(W32PROCESS));

View file

@ -66,6 +66,60 @@ CleanupDesktopImpl(VOID)
return STATUS_SUCCESS; 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 **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS FASTCALL NTSTATUS FASTCALL

View file

@ -30,6 +30,7 @@
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include <w32k.h> #include <w32k.h>
#include <pseh.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -113,6 +114,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
PUNICODE_STRING ClassName; PUNICODE_STRING ClassName;
UINT Size; UINT Size;
_SEH_TRY {
if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size) if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
{ {
return (UINT) wParam; return (UINT) wParam;
@ -163,6 +165,11 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
{ {
return MsgMemoryEntry->Size; return MsgMemoryEntry->Size;
} }
} _SEH_HANDLE {
DPRINT1("BOO!\n");
return 0;
} _SEH_END;
} }
static FASTCALL NTSTATUS static FASTCALL NTSTATUS

View file

@ -80,6 +80,165 @@ CleanupWindowStationImpl(VOID)
return STATUS_SUCCESS; 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 **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
/* /*

View file

@ -315,6 +315,7 @@ extern PACL SeSystemDefaultDacl;
#define TOKEN_ADJUST_PRIVILEGES (0x0020) #define TOKEN_ADJUST_PRIVILEGES (0x0020)
#define TOKEN_ADJUST_GROUPS (0x0040) #define TOKEN_ADJUST_GROUPS (0x0040)
#define TOKEN_ADJUST_DEFAULT (0x0080) #define TOKEN_ADJUST_DEFAULT (0x0080)
#define TOKEN_ADJUST_SESSIONID (0x0100)
#define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\ #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
TOKEN_ASSIGN_PRIMARY |\ TOKEN_ASSIGN_PRIMARY |\
@ -324,7 +325,8 @@ extern PACL SeSystemDefaultDacl;
TOKEN_QUERY_SOURCE |\ TOKEN_QUERY_SOURCE |\
TOKEN_ADJUST_PRIVILEGES |\ TOKEN_ADJUST_PRIVILEGES |\
TOKEN_ADJUST_GROUPS |\ TOKEN_ADJUST_GROUPS |\
TOKEN_ADJUST_DEFAULT) TOKEN_ADJUST_DEFAULT |\
TOKEN_ADJUST_SESSIONID)
#define TOKEN_READ (STANDARD_RIGHTS_READ |\ #define TOKEN_READ (STANDARD_RIGHTS_READ |\
TOKEN_QUERY) TOKEN_QUERY)
@ -1216,13 +1218,23 @@ typedef struct _GENERATE_NAME_CONTEXT {
ULONG LastIndexValue; ULONG LastIndexValue;
} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT; } 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 { typedef struct _HANDLE_TABLE_ENTRY {
union {
PVOID Object; PVOID Object;
ULONG ObjectAttributes; ULONG ObAttributes;
PHANDLE_TABLE_ENTRY_INFO InfoTable;
ULONG_PTR Value;
} u1;
union {
ULONG GrantedAccess; ULONG GrantedAccess;
USHORT GrantedAccessIndex; USHORT GrantedAccessIndex;
LONG NextFreeTableEntry;
} u2;
USHORT CreatorBackTraceIndex; USHORT CreatorBackTraceIndex;
ULONG NextFreeTableEntry;
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _MAPPING_PAIR { typedef struct _MAPPING_PAIR {

View file

@ -126,6 +126,18 @@ static __inline struct _KPCR * KeGetCurrentKPCR(
return (struct _KPCR *) Value; 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 ** Simple structures
*/ */
@ -3795,6 +3807,10 @@ typedef enum _PROCESSINFOCLASS {
ProcessDebugObjectHandle, ProcessDebugObjectHandle,
ProcessDebugFlags, ProcessDebugFlags,
ProcessHandleTracing, ProcessHandleTracing,
ProcessUnknown33,
ProcessUnknown34,
ProcessUnknown35,
ProcessCookie,
MaxProcessInfoClass MaxProcessInfoClass
} PROCESSINFOCLASS; } PROCESSINFOCLASS;

View file

@ -1140,6 +1140,7 @@ typedef DWORD FLONG;
#define TOKEN_ADJUST_PRIVILEGES (0x0020) #define TOKEN_ADJUST_PRIVILEGES (0x0020)
#define TOKEN_ADJUST_GROUPS (0x0040) #define TOKEN_ADJUST_GROUPS (0x0040)
#define TOKEN_ADJUST_DEFAULT (0x0080) #define TOKEN_ADJUST_DEFAULT (0x0080)
#define TOKEN_ADJUST_SESSIONID (0x0100)
#define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\ #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
TOKEN_ASSIGN_PRIMARY |\ TOKEN_ASSIGN_PRIMARY |\
TOKEN_DUPLICATE |\ TOKEN_DUPLICATE |\
@ -1148,7 +1149,8 @@ typedef DWORD FLONG;
TOKEN_QUERY_SOURCE |\ TOKEN_QUERY_SOURCE |\
TOKEN_ADJUST_PRIVILEGES |\ TOKEN_ADJUST_PRIVILEGES |\
TOKEN_ADJUST_GROUPS |\ TOKEN_ADJUST_GROUPS |\
TOKEN_ADJUST_DEFAULT) TOKEN_ADJUST_DEFAULT |\
TOKEN_ADJUST_SESSIONID)
#define TOKEN_READ (STANDARD_RIGHTS_READ |\ #define TOKEN_READ (STANDARD_RIGHTS_READ |\
TOKEN_QUERY) TOKEN_QUERY)
#define TOKEN_WRITE (STANDARD_RIGHTS_WRITE |\ #define TOKEN_WRITE (STANDARD_RIGHTS_WRITE |\