1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel 4 * FILE: ntoskrnl/ex/win32k.c 5 * PURPOSE: Executive Win32 Object Support (Desktop/WinStation) 6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 7 */ 8 9 #include <ntoskrnl.h> 10 #define NDEBUG 11 #include <debug.h> 12 13 typedef struct _WIN32_KERNEL_OBJECT_HEADER 14 { 15 ULONG SessionId; 16 } WIN32_KERNEL_OBJECT_HEADER, *PWIN32_KERNEL_OBJECT_HEADER; 17 18 19 /* DATA **********************************************************************/ 20 21 POBJECT_TYPE ExWindowStationObjectType = NULL; 22 POBJECT_TYPE ExDesktopObjectType = NULL; 23 24 GENERIC_MAPPING ExpWindowStationMapping = 25 { 26 STANDARD_RIGHTS_READ, 27 STANDARD_RIGHTS_WRITE, 28 STANDARD_RIGHTS_EXECUTE, 29 STANDARD_RIGHTS_REQUIRED 30 }; 31 32 GENERIC_MAPPING ExpDesktopMapping = 33 { 34 STANDARD_RIGHTS_READ, 35 STANDARD_RIGHTS_WRITE, 36 STANDARD_RIGHTS_EXECUTE, 37 STANDARD_RIGHTS_REQUIRED 38 }; 39 40 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectParse = NULL; 41 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectDelete = NULL; 42 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectOkToClose = NULL; 43 PKWIN32_SESSION_CALLOUT ExpDesktopObjectOkToClose = NULL; 44 PKWIN32_SESSION_CALLOUT ExpDesktopObjectDelete = NULL; 45 PKWIN32_SESSION_CALLOUT ExpDesktopObjectOpen = NULL; 46 PKWIN32_SESSION_CALLOUT ExpDesktopObjectClose = NULL; 47 48 /* FUNCTIONS ****************************************************************/ 49 50 NTSTATUS 51 NTAPI 52 ExpWin32SessionCallout( 53 _In_ PVOID Object, 54 _In_ PKWIN32_SESSION_CALLOUT CalloutProcedure, 55 _Inout_opt_ PVOID Parameter) 56 { 57 PWIN32_KERNEL_OBJECT_HEADER Win32ObjectHeader; 58 PVOID SessionEntry = NULL; 59 KAPC_STATE ApcState; 60 NTSTATUS Status; 61 62 /* The objects have a common header. And the kernel accesses it! 63 Thanks MS for this kind of retarded "design"! */ 64 Win32ObjectHeader = Object; 65 66 /* Check if we are not already in the correct session */ 67 if (!PsGetCurrentProcess()->ProcessInSession || 68 (PsGetCurrentProcessSessionId() != Win32ObjectHeader->SessionId)) 69 { 70 /* Get the session from the objects session Id */ 71 DPRINT("SessionId == %d\n", Win32ObjectHeader->SessionId); 72 SessionEntry = MmGetSessionById(Win32ObjectHeader->SessionId); 73 if (SessionEntry == NULL) 74 { 75 /* The requested session does not even exist! */ 76 ASSERT(FALSE); 77 return STATUS_NOT_FOUND; 78 } 79 80 /* Attach to the session */ 81 Status = MmAttachSession(SessionEntry, &ApcState); 82 if (!NT_SUCCESS(Status)) 83 { 84 DPRINT1("Could not attach to 0x%p, object %p, callout 0x%p\n", 85 SessionEntry, 86 Win32ObjectHeader, 87 CalloutProcedure); 88 89 /* Cleanup and return */ 90 MmQuitNextSession(SessionEntry); 91 ASSERT(FALSE); 92 return Status; 93 } 94 } 95 96 /* Call the callout routine */ 97 Status = CalloutProcedure(Parameter); 98 99 /* Check if we have a session */ 100 if (SessionEntry != NULL) 101 { 102 /* Detach from the session and quit using it */ 103 MmDetachSession(SessionEntry, &ApcState); 104 MmQuitNextSession(SessionEntry); 105 } 106 107 /* Return the callback status */ 108 return Status; 109 } 110 111 BOOLEAN 112 NTAPI 113 ExpDesktopOkToClose( IN PEPROCESS Process OPTIONAL, 114 IN PVOID Object, 115 IN HANDLE Handle, 116 IN KPROCESSOR_MODE AccessMode) 117 { 118 WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; 119 NTSTATUS Status; 120 121 Parameters.Process = Process; 122 Parameters.Object = Object; 123 Parameters.Handle = Handle; 124 Parameters.PreviousMode = AccessMode; 125 126 Status = ExpWin32SessionCallout(Object, 127 ExpDesktopObjectOkToClose, 128 &Parameters); 129 130 return NT_SUCCESS(Status); 131 } 132 133 BOOLEAN 134 NTAPI 135 ExpWindowStationOkToClose( IN PEPROCESS Process OPTIONAL, 136 IN PVOID Object, 137 IN HANDLE Handle, 138 IN KPROCESSOR_MODE AccessMode) 139 { 140 WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; 141 NTSTATUS Status; 142 143 Parameters.Process = Process; 144 Parameters.Object = Object; 145 Parameters.Handle = Handle; 146 Parameters.PreviousMode = AccessMode; 147 148 Status = ExpWin32SessionCallout(Object, 149 ExpWindowStationObjectOkToClose, 150 &Parameters); 151 152 return NT_SUCCESS(Status); 153 } 154 155 VOID 156 NTAPI 157 ExpWinStaObjectDelete(PVOID DeletedObject) 158 { 159 WIN32_DELETEMETHOD_PARAMETERS Parameters; 160 161 /* Fill out the callback structure */ 162 Parameters.Object = DeletedObject; 163 164 ExpWin32SessionCallout(DeletedObject, 165 ExpWindowStationObjectDelete, 166 &Parameters); 167 } 168 169 NTSTATUS 170 NTAPI 171 ExpWinStaObjectParse(IN PVOID ParseObject, 172 IN PVOID ObjectType, 173 IN OUT PACCESS_STATE AccessState, 174 IN KPROCESSOR_MODE AccessMode, 175 IN ULONG Attributes, 176 IN OUT PUNICODE_STRING CompleteName, 177 IN OUT PUNICODE_STRING RemainingName, 178 IN OUT PVOID Context OPTIONAL, 179 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, 180 OUT PVOID *Object) 181 { 182 WIN32_PARSEMETHOD_PARAMETERS Parameters; 183 184 /* Fill out the callback structure */ 185 Parameters.ParseObject = ParseObject; 186 Parameters.ObjectType = ObjectType; 187 Parameters.AccessState = AccessState; 188 Parameters.AccessMode = AccessMode; 189 Parameters.Attributes = Attributes; 190 Parameters.CompleteName = CompleteName; 191 Parameters.RemainingName = RemainingName; 192 Parameters.Context = Context; 193 Parameters.SecurityQos = SecurityQos; 194 Parameters.Object = Object; 195 196 return ExpWin32SessionCallout(ParseObject, 197 ExpWindowStationObjectParse, 198 &Parameters); 199 } 200 VOID 201 NTAPI 202 ExpDesktopDelete(PVOID DeletedObject) 203 { 204 WIN32_DELETEMETHOD_PARAMETERS Parameters; 205 206 /* Fill out the callback structure */ 207 Parameters.Object = DeletedObject; 208 209 ExpWin32SessionCallout(DeletedObject, 210 ExpDesktopObjectDelete, 211 &Parameters); 212 } 213 214 NTSTATUS 215 NTAPI 216 ExpDesktopOpen(IN OB_OPEN_REASON Reason, 217 IN PEPROCESS Process OPTIONAL, 218 IN PVOID ObjectBody, 219 IN ACCESS_MASK GrantedAccess, 220 IN ULONG HandleCount) 221 { 222 WIN32_OPENMETHOD_PARAMETERS Parameters; 223 224 Parameters.OpenReason = Reason; 225 Parameters.Process = Process; 226 Parameters.Object = ObjectBody; 227 Parameters.GrantedAccess = GrantedAccess; 228 Parameters.HandleCount = HandleCount; 229 230 return ExpWin32SessionCallout(ObjectBody, 231 ExpDesktopObjectOpen, 232 &Parameters); 233 } 234 235 VOID 236 NTAPI 237 ExpDesktopClose(IN PEPROCESS Process OPTIONAL, 238 IN PVOID Object, 239 IN ACCESS_MASK GrantedAccess, 240 IN ULONG ProcessHandleCount, 241 IN ULONG SystemHandleCount) 242 { 243 WIN32_CLOSEMETHOD_PARAMETERS Parameters; 244 245 Parameters.Process = Process; 246 Parameters.Object = Object; 247 Parameters.AccessMask = GrantedAccess; 248 Parameters.ProcessHandleCount = ProcessHandleCount; 249 Parameters.SystemHandleCount = SystemHandleCount; 250 251 ExpWin32SessionCallout(Object, 252 ExpDesktopObjectClose, 253 &Parameters); 254 } 255 256 CODE_SEG("INIT") 257 BOOLEAN 258 NTAPI 259 ExpWin32kInit(VOID) 260 { 261 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 262 UNICODE_STRING Name; 263 NTSTATUS Status; 264 DPRINT("Creating Win32 Object Types\n"); 265 266 /* Create the window station Object Type */ 267 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); 268 RtlInitUnicodeString(&Name, L"WindowStation"); 269 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); 270 ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping; 271 ObjectTypeInitializer.PoolType = NonPagedPool; 272 ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete; 273 ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse; 274 ObjectTypeInitializer.OkayToCloseProcedure = ExpWindowStationOkToClose; 275 ObjectTypeInitializer.SecurityRequired = TRUE; 276 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK | 277 OBJ_PERMANENT | 278 OBJ_EXCLUSIVE; 279 ObjectTypeInitializer.ValidAccessMask = STANDARD_RIGHTS_REQUIRED; 280 Status = ObCreateObjectType(&Name, 281 &ObjectTypeInitializer, 282 NULL, 283 &ExWindowStationObjectType); 284 if (!NT_SUCCESS(Status)) return FALSE; 285 286 /* Create desktop object type */ 287 RtlInitUnicodeString(&Name, L"Desktop"); 288 ObjectTypeInitializer.GenericMapping = ExpDesktopMapping; 289 ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete; 290 ObjectTypeInitializer.ParseProcedure = NULL; 291 ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose; 292 ObjectTypeInitializer.OpenProcedure = ExpDesktopOpen; 293 ObjectTypeInitializer.CloseProcedure = ExpDesktopClose; 294 Status = ObCreateObjectType(&Name, 295 &ObjectTypeInitializer, 296 NULL, 297 &ExDesktopObjectType); 298 if (!NT_SUCCESS(Status)) return FALSE; 299 300 return TRUE; 301 } 302 303 /* EOF */ 304