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