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 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() */

View file

@ -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);

View file

@ -67,6 +67,40 @@ 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
{
PVOID BaseAddress;

View file

@ -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 <ntoskrnl.h>
@ -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 */

View file

@ -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,8 +76,14 @@ 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)

View file

@ -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);

View file

@ -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,

View file

@ -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
@ -235,12 +270,21 @@ DllMain (
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));

View file

@ -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

View file

@ -30,6 +30,7 @@
/* INCLUDES ******************************************************************/
#include <w32k.h>
#include <pseh.h>
#define NDEBUG
#include <debug.h>
@ -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

View file

@ -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 **********************************************************/
/*

View file

@ -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 {

View file

@ -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;

View file

@ -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 |\