ReactOS 0.4.17-dev-769-g1500a35
obhandle.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ob/obhandle.c
5 * PURPOSE: Manages all functions related to the Object Manager handle
6 * implementation, including creating and destroying handles
7 * and/or handle tables, duplicating objects, and setting the
8 * permanent or temporary flags.
9 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
10 * Eric Kohl
11 * Thomas Weidenmueller (w3seek@reactos.org)
12 */
13
14/* INCLUDES ******************************************************************/
15
16#include <ntoskrnl.h>
17#define NDEBUG
18#include <debug.h>
19
21
22/* PRIVATE FUNCTIONS *********************************************************/
23
27{
29
30 /* Lock the process */
31 if (ExAcquireRundownProtection(&Process->RundownProtect))
32 {
33 /* Get the handle table */
34 HandleTable = Process->ObjectTable;
35 if (!HandleTable)
36 {
37 /* No table, release the lock */
38 ExReleaseRundownProtection(&Process->RundownProtect);
39 }
40 }
41
42 /* Return the handle table */
43 return HandleTable;
44}
45
46VOID
49{
50 /* Release the process lock */
51 ExReleaseRundownProtection(&Process->RundownProtect);
52}
53
57{
60
62
63 /* Ensure the handle table doesn't go away while we use it */
65
66 if (HandleTable != NULL)
67 {
68 /* Count the number of handles the process has */
69 HandleCount = HandleTable->HandleCount;
70
71 /* Let the handle table go */
73 }
74 else
75 {
76 /* No handle table, no handles */
77 HandleCount = 0;
78 }
79
80 return HandleCount;
81}
82
91 OUT PACCESS_MASK AuditMask)
92{
93 PHANDLE_TABLE_ENTRY HandleEntry;
94 POBJECT_HEADER ObjectHeader;
99
100 /* Assume failure */
101 *Object = NULL;
102
103 /* Check if this is a special handle */
104 if (HandleToLong(Handle) < 0)
105 {
106 /* Check if the caller wants the current process */
107 if (Handle == NtCurrentProcess())
108 {
109 /* Return handle info */
110 HandleInformation->HandleAttributes = 0;
111 HandleInformation->GrantedAccess = Process->GrantedAccess;
112
113 /* No audit mask */
114 *AuditMask = 0;
115
116 /* Reference ourselves */
117 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
119
120 /* Return the pointer */
121 *Object = Process;
122 ASSERT(*Object != NULL);
123 return STATUS_SUCCESS;
124 }
125
126 /* Check if the caller wants the current thread */
127 if (Handle == NtCurrentThread())
128 {
129 /* Return handle information */
130 HandleInformation->HandleAttributes = 0;
131 HandleInformation->GrantedAccess = Thread->GrantedAccess;
132
133 /* Reference ourselves */
134 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
136
137 /* No audit mask */
138 *AuditMask = 0;
139
140 /* Return the pointer */
141 *Object = Thread;
142 ASSERT(*Object != NULL);
143 return STATUS_SUCCESS;
144 }
145
146 /* This is a kernel handle... do we have access? */
147 if (AccessMode == KernelMode)
148 {
149 /* Use the kernel handle table and get the actual handle value */
152 }
153 else
154 {
155 /* This is an illegal attempt to access a kernel handle */
157 }
158 }
159
160 /* Enter a critical region while we touch the handle table */
163
164 /* Get the handle entry */
166 if (HandleEntry)
167 {
168 /* Get the object header and validate the type*/
169 ObjectHeader = ObpGetHandleObject(HandleEntry);
170
171 /* Get the granted access and validate it */
172 GrantedAccess = HandleEntry->GrantedAccess;
173
174 /* Mask out the internal attributes */
176
177 /* Fill out the information */
178 HandleInformation->HandleAttributes = Attributes;
179 HandleInformation->GrantedAccess = GrantedAccess;
180
181 /* No audit mask (FIXME!) */
182 *AuditMask = 0;
183
184 /* Return the pointer */
185 *Object = &ObjectHeader->Body;
186
187 /* Add a reference */
189
190 /* Unlock the handle */
193
194 /* Return success */
195 ASSERT(*Object != NULL);
196 return STATUS_SUCCESS;
197 }
198 else
199 {
200 /* Invalid handle */
202 }
203
204 /* Return failure status */
206 return Status;
207}
208
210NTAPI
214{
215 POBJECT_HEADER ObjectHeader;
219
220 /* Get the object header */
221 ObjectHeader = ObpGetHandleObject(HandleEntry);
222
223 /* Make sure it's valid and matching */
224 if ((FindData->ObjectHeader) && (FindData->ObjectHeader != ObjectHeader))
225 {
226 /* No match, fail */
227 return FALSE;
228 }
229
230 /* Now attempt to match the object type */
231 if ((FindData->ObjectType) && (FindData->ObjectType != ObjectHeader->Type))
232 {
233 /* No match, fail */
234 return FALSE;
235 }
236
237 /* Check if we have extra information */
238 if (FindData->HandleInformation)
239 {
240 /* Get the granted access and attributes */
241 GrantedAccess = HandleEntry->GrantedAccess;
242 HandleAttributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
243
244 /* Attempt to match them */
247 {
248 /* No match, fail */
249 return FALSE;
250 }
251 }
252
253 /* We have a match */
254 return TRUE;
255}
256
258NTAPI
260{
263 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase, OldHandleDatabase;
264 ULONG i;
265 ULONG Size, OldSize;
266 OBJECT_HANDLE_COUNT_DATABASE SingleDatabase;
267 PAGED_CODE();
268
269 /* Get the handle info */
270 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
271 if (!HandleInfo) return NULL;
272
273 /* Check if we only have one entry */
274 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
275 {
276 /* Fill out the single entry */
277 SingleDatabase.CountEntries = 1;
278 SingleDatabase.HandleCountEntries[0] = HandleInfo->SingleEntry;
279
280 /* Use this as the old size */
281 OldHandleDatabase = &SingleDatabase;
282 OldSize = sizeof(SingleDatabase);
283
284 /* Now we'll have two entries, and an entire DB */
285 i = 2;
287 ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
288 }
289 else
290 {
291 /* We already have a DB, get the information from it */
292 OldHandleDatabase = HandleInfo->HandleCountDatabase;
293 i = OldHandleDatabase->CountEntries;
294 OldSize = sizeof(OBJECT_HANDLE_COUNT_DATABASE) +
295 ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
296
297 /* Add 4 more entries */
298 i += 4;
299 Size = OldSize + (4 * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
300 }
301
302 /* Allocate the DB */
304 if (!HandleDatabase) return NULL;
305
306 /* Copy the old database */
307 RtlCopyMemory(HandleDatabase, OldHandleDatabase, OldSize);
308
309 /* Check if we he had a single entry before */
310 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
311 {
312 /* Now we have more */
313 ObjectHeader->Flags &= ~OB_FLAG_SINGLE_PROCESS;
314 }
315 else
316 {
317 /* Otherwise we had a DB, free it */
318 ExFreePoolWithTag(OldHandleDatabase, TAG_OB_HANDLE);
319 }
320
321 /* Find the end of the copy and zero out the new data */
322 FreeEntry = (PVOID)((ULONG_PTR)HandleDatabase + OldSize);
323 RtlZeroMemory(FreeEntry, Size - OldSize);
324
325 /* Set the new information and return the free entry */
326 HandleDatabase->CountEntries = i;
327 HandleInfo->HandleCountDatabase = HandleDatabase;
328 return FreeEntry;
329}
330
332NTAPI
335 IN OUT PULONG NewProcessHandleCount)
336{
338 POBJECT_HANDLE_COUNT_ENTRY HandleEntry, FreeEntry = NULL;
339 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
340 ULONG i;
341 PAGED_CODE();
342
343 /* Get the handle info and check if we only have one entry */
344 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
345 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
346 {
347 /* Check if the entry is free */
348 if (!HandleInfo->SingleEntry.HandleCount)
349 {
350 /* Add ours */
351 HandleInfo->SingleEntry.HandleCount = 1;
352 HandleInfo->SingleEntry.Process = Process;
353
354 /* Return success and 1 handle */
355 *NewProcessHandleCount = 1;
356 return STATUS_SUCCESS;
357 }
358 else if (HandleInfo->SingleEntry.Process == Process)
359 {
360 /* Busy entry, but same process */
361 *NewProcessHandleCount = ++HandleInfo->SingleEntry.HandleCount;
362 return STATUS_SUCCESS;
363 }
364 else
365 {
366 /* Insert a new entry */
367 FreeEntry = ObpInsertHandleCount(ObjectHeader);
368 if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
369 ASSERT(!FreeEntry->Process);
370 ASSERT(!FreeEntry->HandleCount);
371
372 /* Fill it out */
373 FreeEntry->Process = Process;
374 FreeEntry->HandleCount = 1;
375
376 /* Return success and 1 handle */
377 *NewProcessHandleCount = 1;
378 return STATUS_SUCCESS;
379 }
380 }
381
382 /* We have a database instead */
383 HandleDatabase = HandleInfo->HandleCountDatabase;
384 if (HandleDatabase)
385 {
386 /* Get the entries and loop them */
387 i = HandleDatabase->CountEntries;
388 HandleEntry = &HandleDatabase->HandleCountEntries[0];
389 while (i)
390 {
391 /* Check if this is a match */
392 if (HandleEntry->Process == Process)
393 {
394 /* Found it, get the process handle count */
395 *NewProcessHandleCount = ++HandleEntry->HandleCount;
396 return STATUS_SUCCESS;
397 }
398 else if (!HandleEntry->HandleCount)
399 {
400 /* Found a free entry */
401 FreeEntry = HandleEntry;
402 }
403
404 /* Keep looping */
405 HandleEntry++;
406 i--;
407 }
408
409 /* Check if we couldn't find a free entry */
410 if (!FreeEntry)
411 {
412 /* Allocate one */
413 FreeEntry = ObpInsertHandleCount(ObjectHeader);
414 if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
415 ASSERT(!FreeEntry->Process);
416 ASSERT(!FreeEntry->HandleCount);
417 }
418
419 /* Fill out the entry */
420 FreeEntry->Process = Process;
421 FreeEntry->HandleCount = 1;
422 *NewProcessHandleCount = 1;
423 }
424
425 /* Return success if we got here */
426 return STATUS_SUCCESS;
427}
428
430NTAPI
434{
435 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
436 ULONG PagedPoolCharge, NonPagedPoolCharge;
437
438 /* Get quota information */
439 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
440 *NewObject = FALSE;
441
442 /* Check if this is a new object */
443 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
444 {
445 /* Remove the flag */
446 ObjectHeader->Flags &= ~ OB_FLAG_CREATE_INFO;
447 if (ObjectQuota)
448 {
449 /* We have a quota, get the charges */
450 PagedPoolCharge = ObjectQuota->PagedPoolCharge +
451 ObjectQuota->SecurityDescriptorCharge;
452 NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
453 }
454 else
455 {
456 /* Get it from the object type */
457 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
458 NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
459 }
460
461 /* Is this the system process? */
463 {
464 /* It is, don't do anything */
465 ObjectHeader->QuotaBlockCharged = OBP_SYSTEM_PROCESS_QUOTA;
466 }
467 else
468 {
469 /* Charge the quota */
470 ObjectHeader->QuotaBlockCharged = PsChargeSharedPoolQuota(PsGetCurrentProcess(),
471 PagedPoolCharge,
472 NonPagedPoolCharge);
473 }
474
475 /* Check if we don't have a quota block */
476 if (!ObjectHeader->QuotaBlockCharged) return STATUS_QUOTA_EXCEEDED;
477
478 /* Now set the flag */
479 *NewObject = TRUE;
480 }
481
482 /* Return success */
483 return STATUS_SUCCESS;
484}
485
487NTAPI
489{
491
492 /* We're only interested if the object for this access state has an SD */
493 SecurityDescriptor = AccessState->SecurityDescriptor;
495 {
496 /* Check if the SD has a system ACL but hasn't been granted access to get/set it */
497 if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
498 !(AccessState->PreviouslyGrantedAccess & ACCESS_SYSTEM_SECURITY))
499 {
500 /* We're gonna need access */
501 AccessState->RemainingDesiredAccess |= ACCESS_SYSTEM_SECURITY;
502 }
503 }
504
505 /* This can't fail */
506 return STATUS_SUCCESS;
507}
508
509/*++
510* @name ObpDecrementHandleCount
511*
512* The ObpDecrementHandleCount routine <FILLMEIN>
513*
514* @param ObjectBody
515* <FILLMEIN>.
516*
517* @param Process
518* <FILLMEIN>.
519*
520* @param GrantedAccess
521* <FILLMEIN>.
522*
523* @return None.
524*
525* @remarks None.
526*
527*--*/
528VOID
529NTAPI
534{
535 POBJECT_HEADER ObjectHeader;
536 LONG SystemHandleCount, ProcessHandleCount;
537 LONG NewCount;
538 KIRQL CalloutIrql;
540 POBJECT_HANDLE_COUNT_ENTRY HandleEntry;
541 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
542 ULONG i;
543 PAGED_CODE();
544
545 /* Get the object type and header */
546 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
548 "%s - Decrementing count for: %p. HC PC %lx %lx\n",
550 ObjectBody,
551 ObjectHeader->HandleCount,
552 ObjectHeader->PointerCount);
553
554 /* Lock the object */
555 ObpAcquireObjectLock(ObjectHeader);
556
557 /* Set default counts */
558 SystemHandleCount = ObjectHeader->HandleCount;
560
561 /* Decrement the handle count */
562 NewCount = InterlockedDecrementSizeT(&ObjectHeader->HandleCount);
563
564 /* Check if we're out of handles and this was an exclusive object */
565 if (!(NewCount) && (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
566 {
567 /* Clear the exclusive flag */
568 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = NULL;
569 }
570
571 /* Is the object type keeping track of handles? */
572 if (ObjectType->TypeInfo.MaintainHandleCount)
573 {
574 /* Get handle information */
575 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
576
577 /* Check if there's only a single entry */
578 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
579 {
580 /* It should be us */
581 ASSERT(HandleInfo->SingleEntry.Process == Process);
582 ASSERT(HandleInfo->SingleEntry.HandleCount > 0);
583
584 /* Get the handle counts */
586 HandleEntry = &HandleInfo->SingleEntry;
587 }
588 else
589 {
590 /* Otherwise, get the database */
591 HandleDatabase = HandleInfo->HandleCountDatabase;
592 if (HandleDatabase)
593 {
594 /* Get the entries and loop them */
595 i = HandleDatabase->CountEntries;
596 HandleEntry = &HandleDatabase->HandleCountEntries[0];
597 while (i)
598 {
599 /* Check if this is a match */
600 if ((HandleEntry->HandleCount) &&
601 (HandleEntry->Process == Process))
602 {
603 /* Found it, get the process handle count */
604 ProcessHandleCount = HandleEntry->HandleCount--;
605 break;
606 }
607
608 /* Keep looping */
609 HandleEntry++;
610 i--;
611 }
612 }
613 else
614 {
615 /* No database, so no entry */
616 HandleEntry = NULL;
617 }
618 }
619
620 /* Check if this is the last handle */
621 if (ProcessHandleCount == 1)
622 {
623 /* Then clear the entry */
624 HandleEntry->Process = NULL;
625 HandleEntry->HandleCount = 0;
626 }
627 }
628
629 /* Release the lock */
630 ObpReleaseObjectLock(ObjectHeader);
631
632 /* Check if we have a close procedure */
633 if (ObjectType->TypeInfo.CloseProcedure)
634 {
635 /* Call it */
636 ObpCalloutStart(&CalloutIrql);
637 ObjectType->TypeInfo.CloseProcedure(Process,
638 ObjectBody,
641 SystemHandleCount);
642 ObpCalloutEnd(CalloutIrql, "Close", ObjectType, ObjectBody);
643 }
644
645 /* Check if we should delete the object */
646 ObpDeleteNameCheck(ObjectBody);
647
648 /* Decrease the total number of handles for this type */
649 InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfHandles);
651 "%s - Decremented count for: %p. HC PC %lx %lx\n",
653 ObjectBody,
654 ObjectHeader->HandleCount,
655 ObjectHeader->PointerCount);
656}
657
658/*++
659* @name ObpCloseHandleTableEntry
660*
661* The ObpCloseHandleTableEntry routine <FILLMEIN>
662*
663* @param HandleTable
664* <FILLMEIN>.
665*
666* @param HandleEntry
667* <FILLMEIN>.
668*
669* @param Handle
670* <FILLMEIN>.
671*
672* @param AccessMode
673* <FILLMEIN>.
674*
675* @param IgnoreHandleProtection
676* <FILLMEIN>.
677*
678* @return <FILLMEIN>.
679*
680* @remarks None.
681*
682*--*/
684NTAPI
686 IN PHANDLE_TABLE_ENTRY HandleEntry,
689 IN BOOLEAN IgnoreHandleProtection)
690{
691 PVOID Body;
693 POBJECT_HEADER ObjectHeader;
695 KIRQL CalloutIrql;
696 PAGED_CODE();
697
698 /* Get the object data */
699 ObjectHeader = ObpGetHandleObject(HandleEntry);
700 ObjectType = ObjectHeader->Type;
701 Body = &ObjectHeader->Body;
702 GrantedAccess = HandleEntry->GrantedAccess;
704 "%s - Closing handle: %p for %p. HC PC %lx %lx\n",
706 Handle,
707 Body,
708 ObjectHeader->HandleCount,
709 ObjectHeader->PointerCount);
710
711 /* Check if the object has an Okay To Close procedure */
712 if (ObjectType->TypeInfo.OkayToCloseProcedure)
713 {
714 /* Call it and check if it's not letting us close it */
715 ObpCalloutStart(&CalloutIrql);
716 if (!ObjectType->TypeInfo.OkayToCloseProcedure(PsGetCurrentProcess(),
717 Body,
718 Handle,
719 AccessMode))
720 {
721 /* Fail */
722 ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
725 }
726
727 /* Success, validate callout return */
728 ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
729 }
730
731 /* The callback allowed us to close it, but does the handle itself? */
732 if ((HandleEntry->GrantedAccess & ObpAccessProtectCloseBit) &&
733 !(IgnoreHandleProtection))
734 {
735 /* It doesn't, are we from user mode? */
736 if (AccessMode != KernelMode)
737 {
738 /* We are! Unlock the entry */
740
741 /* Make sure we have a debug port */
742 if (PsGetCurrentProcess()->DebugPort)
743 {
744 /* Raise an exception */
746 }
747 else
748 {
749 /* Return the error instead */
751 }
752 }
753 else
754 {
755 /* Otherwise, bugcheck the OS */
756 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 0, 0, 0);
757 }
758 }
759
760 /* Destroy and unlock the handle entry */
761 ExDestroyHandle(HandleTable, Handle, HandleEntry);
762
763 /* Now decrement the handle count */
767 ObjectType);
768
769 /* Dereference the object as well */
771
772 /* Return to caller */
774 "%s - Closed handle: %p for %p.\n",
776 Handle,
777 Body);
778 return STATUS_SUCCESS;
779}
780
781/*++
782* @name ObpIncrementHandleCount
783*
784* The ObpIncrementHandleCount routine <FILLMEIN>
785*
786* @param Object
787* <FILLMEIN>.
788*
789* @param AccessState
790* <FILLMEIN>.
791*
792* @param AccessMode
793* <FILLMEIN>.
794*
795* @param HandleAttributes
796* <FILLMEIN>.
797*
798* @param Process
799* <FILLMEIN>.
800*
801* @param OpenReason
802* <FILLMEIN>.
803*
804* @return <FILLMEIN>.
805*
806* @remarks None.
807*
808*--*/
810NTAPI
816 IN OB_OPEN_REASON OpenReason)
817{
818 POBJECT_HEADER ObjectHeader;
822 PEPROCESS ExclusiveProcess;
824 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
825 KIRQL CalloutIrql;
827 ULONG Total;
829 BOOLEAN ObjectLocked;
830 PAGED_CODE();
831
832 /* Get the object header and type */
833 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
834 ObjectType = ObjectHeader->Type;
836 "%s - Incrementing count for: %p. Reason: %lx. HC PC %lx %lx\n",
838 Object,
839 OpenReason,
840 ObjectHeader->HandleCount,
841 ObjectHeader->PointerCount);
842
843 /* Check if caller is forcing user mode */
845 {
846 /* Force it */
848 }
849 else
850 {
851 /* Keep original setting */
853 }
854
855 /* Lock the object */
856 ObpAcquireObjectLock(ObjectHeader);
857 ObjectLocked = TRUE;
858
859 /* Charge quota and remove the creator info flag */
861 if (!NT_SUCCESS(Status)) goto Quickie;
862
863 /* Check if the open is exclusive */
865 {
866 /* Check if the object allows this, or if the inherit flag was given */
868 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
869 {
870 /* Incorrect attempt */
872 goto Quickie;
873 }
874
875 /* Check if we have access to it */
876 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
877 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
878 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
879 {
880 /* This isn't the right process */
882 goto Quickie;
883 }
884
885 /* Now you got exclusive access */
886 Exclusive = TRUE;
887 }
888 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
890 {
891 /* Caller didn't want exclusive access, but the object is exclusive */
893 goto Quickie;
894 }
895
896 /* Check for exclusive kernel object */
897 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
898 if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
900 {
901 /* Caller is not kernel, but the object is kernel exclusive */
903 goto Quickie;
904 }
905
906 /*
907 * Check if this is an object that went from 0 handles back to existence,
908 * but doesn't have an open procedure, only a close procedure. This means
909 * that it will never realize that the object is back alive, so we must
910 * fail the request.
911 */
912 if (!(ObjectHeader->HandleCount) &&
913 !(NewObject) &&
914 (ObjectType->TypeInfo.MaintainHandleCount) &&
915 !(ObjectType->TypeInfo.OpenProcedure) &&
916 (ObjectType->TypeInfo.CloseProcedure))
917 {
918 /* Fail */
920 goto Quickie;
921 }
922
923 /* Check if we're opening an existing handle */
924 if ((OpenReason == ObOpenHandle) ||
925 ((OpenReason == ObDuplicateHandle) && (AccessState)))
926 {
927 /* Validate the caller's access to this object */
930 TRUE,
931 ProbeMode,
932 &Status))
933 {
934 /* Access was denied, so fail */
935 goto Quickie;
936 }
937 }
938 else if (OpenReason == ObCreateHandle)
939 {
940 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
941 if (AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED)
942 {
943 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
944 AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
945 AccessState->RemainingDesiredAccess |= GENERIC_ALL;
946 }
947
948 /* Check if we have to map the GENERIC mask */
949 if (AccessState->RemainingDesiredAccess & GENERIC_ACCESS)
950 {
951 /* Map it to the correct access masks */
952 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
953 &ObjectType->TypeInfo.GenericMapping);
954 }
955
956 /* Check if the caller is trying to access system security */
957 if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY)
958 {
959 /* Client must be warranted SeSecurityPrivilege to touch SACLs */
961 {
962 /* FIXME: Generate an audit alarm, security manager must be alerted */
964 goto Quickie;
965 }
966
967 /* Privilege held, grant it so the access state reflects reality */
968 AccessState->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
969 AccessState->RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
970 }
971 }
972
973 /* Check if this is an exclusive handle */
974 if (Exclusive)
975 {
976 /* Save the owner process */
977 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
978 }
979
980 /* Increase the handle count */
983
984 /* Check if we have a handle database */
985 if (ObjectType->TypeInfo.MaintainHandleCount)
986 {
987 /* Increment the handle database */
988 Status = ObpIncrementHandleDataBase(ObjectHeader,
989 Process,
991 if (!NT_SUCCESS(Status))
992 {
993 /* FIXME: This should never happen for now */
994 DPRINT1("Unhandled case\n");
995 ASSERT(FALSE);
996 goto Quickie;
997 }
998 }
999
1000 /* Release the lock */
1001 ObpReleaseObjectLock(ObjectHeader);
1002 ObjectLocked = FALSE;
1003
1004 /* Check if we have an open procedure */
1006 if (ObjectType->TypeInfo.OpenProcedure)
1007 {
1008 /* Call it */
1009 ObpCalloutStart(&CalloutIrql);
1010 ACCESS_MASK GrantedAccess = AccessState ? AccessState->PreviouslyGrantedAccess : 0;
1011 Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
1012 ProbeMode,
1013 Process,
1014 Object,
1017 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1018
1019 /* Check if the open procedure failed */
1020 if (!NT_SUCCESS(Status))
1021 {
1022 /* FIXME: This should never happen for now */
1023 DPRINT1("Unhandled case\n");
1024 ASSERT(FALSE);
1025 goto Quickie;
1026 }
1027 }
1028
1029 /* Check if this is a create operation */
1030 if (OpenReason == ObCreateHandle)
1031 {
1032 /* Check if we have creator info */
1033 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1034 if (CreatorInfo)
1035 {
1036 /* We do, acquire the lock */
1038
1039 /* Insert us on the list */
1040 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1041
1042 /* Release the lock */
1044 }
1045 }
1046
1047 /* Increase total number of handles */
1048 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1049 if (Total > ObjectType->HighWaterNumberOfHandles)
1050 {
1051 /* Fixup count */
1052 ObjectType->HighWaterNumberOfHandles = Total;
1053 }
1054
1055 /* Trace call and return */
1057 "%s - Incremented count for: %p. Reason: %lx HC PC %lx %lx\n",
1059 Object,
1060 OpenReason,
1061 ObjectHeader->HandleCount,
1062 ObjectHeader->PointerCount);
1063
1064Quickie:
1065 if (ObjectLocked)
1066 {
1067 ObpReleaseObjectLock(ObjectHeader);
1068 }
1069
1070 return Status;
1071}
1072
1073/*++
1074* @name ObpIncrementUnnamedHandleCount
1075*
1076* The ObpIncrementUnnamedHandleCount routine <FILLMEIN>
1077*
1078* @param Object
1079* <FILLMEIN>.
1080*
1081* @param AccessState
1082* <FILLMEIN>.
1083*
1084* @param AccessMode
1085* <FILLMEIN>.
1086*
1087* @param HandleAttributes
1088* <FILLMEIN>.
1089*
1090* @param Process
1091* <FILLMEIN>.
1092*
1093* @param OpenReason
1094* <FILLMEIN>.
1095*
1096* @return <FILLMEIN>.
1097*
1098* @remarks None.
1099*
1100*--*/
1102NTAPI
1108{
1109 POBJECT_HEADER ObjectHeader;
1113 PEPROCESS ExclusiveProcess;
1115 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1116 KIRQL CalloutIrql;
1117 ULONG Total;
1118 BOOLEAN ObjectLocked;
1119
1120 /* Get the object header and type */
1121 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1122 ObjectType = ObjectHeader->Type;
1124 "%s - Incrementing count for: %p. UNNAMED. HC PC %lx %lx\n",
1126 Object,
1127 ObjectHeader->HandleCount,
1128 ObjectHeader->PointerCount);
1129
1130 /* Lock the object */
1131 ObpAcquireObjectLock(ObjectHeader);
1132 ObjectLocked = TRUE;
1133
1134 /* Charge quota and remove the creator info flag */
1136 if (!NT_SUCCESS(Status)) goto Quickie;
1137
1138 /* Check if the open is exclusive */
1140 {
1141 /* Check if the object allows this, or if the inherit flag was given */
1142 if ((HandleAttributes & OBJ_INHERIT) ||
1143 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
1144 {
1145 /* Incorrect attempt */
1147 goto Quickie;
1148 }
1149
1150 /* Check if we have access to it */
1151 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
1152 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
1153 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
1154 {
1155 /* This isn't the right process */
1157 goto Quickie;
1158 }
1159
1160 /* Now you got exclusive access */
1161 Exclusive = TRUE;
1162 }
1163 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
1164 (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader)))
1165 {
1166 /* Caller didn't want exclusive access, but the object is exclusive */
1168 goto Quickie;
1169 }
1170
1171 /*
1172 * Check if this is an object that went from 0 handles back to existence,
1173 * but doesn't have an open procedure, only a close procedure. This means
1174 * that it will never realize that the object is back alive, so we must
1175 * fail the request.
1176 */
1177 if (!(ObjectHeader->HandleCount) &&
1178 !(NewObject) &&
1179 (ObjectType->TypeInfo.MaintainHandleCount) &&
1180 !(ObjectType->TypeInfo.OpenProcedure) &&
1181 (ObjectType->TypeInfo.CloseProcedure))
1182 {
1183 /* Fail */
1185 goto Quickie;
1186 }
1187
1188 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
1190 {
1191 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
1192 *DesiredAccess &= ~MAXIMUM_ALLOWED;
1194 }
1195
1196 /* Check if we have to map the GENERIC mask */
1198 {
1199 /* Map it to the correct access masks */
1201 &ObjectType->TypeInfo.GenericMapping);
1202 }
1203
1204 /* Check if this is an exclusive handle */
1205 if (Exclusive)
1206 {
1207 /* Save the owner process */
1208 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
1209 }
1210
1211 /* Increase the handle count */
1212 InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
1214
1215 /* Check if we have a handle database */
1216 if (ObjectType->TypeInfo.MaintainHandleCount)
1217 {
1218 /* Increment the handle database */
1219 Status = ObpIncrementHandleDataBase(ObjectHeader,
1220 Process,
1222 if (!NT_SUCCESS(Status))
1223 {
1224 /* FIXME: This should never happen for now */
1225 DPRINT1("Unhandled case\n");
1226 ASSERT(FALSE);
1227 goto Quickie;
1228 }
1229 }
1230
1231 /* Release the lock */
1232 ObpReleaseObjectLock(ObjectHeader);
1233 ObjectLocked = FALSE;
1234
1235 /* Check if we have an open procedure */
1237 if (ObjectType->TypeInfo.OpenProcedure)
1238 {
1239 /* Call it */
1240 ObpCalloutStart(&CalloutIrql);
1241 Status = ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
1242 AccessMode,
1243 Process,
1244 Object,
1247 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1248
1249 /* Check if the open procedure failed */
1250 if (!NT_SUCCESS(Status))
1251 {
1252 /* FIXME: This should never happen for now */
1253 DPRINT1("Unhandled case\n");
1254 ASSERT(FALSE);
1255 goto Quickie;
1256 }
1257 }
1258
1259 /* Check if we have creator info */
1260 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1261 if (CreatorInfo)
1262 {
1263 /* We do, acquire the lock */
1265
1266 /* Insert us on the list */
1267 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1268
1269 /* Release the lock */
1271 }
1272
1273 /* Increase total number of handles */
1274 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1275 if (Total > ObjectType->HighWaterNumberOfHandles)
1276 {
1277 /* Fixup count */
1278 ObjectType->HighWaterNumberOfHandles = Total;
1279 }
1280
1281 /* Trace call and return */
1283 "%s - Incremented count for: %p. UNNAMED HC PC %lx %lx\n",
1285 Object,
1286 ObjectHeader->HandleCount,
1287 ObjectHeader->PointerCount);
1288
1289Quickie:
1290 if (ObjectLocked)
1291 {
1292 ObpReleaseObjectLock(ObjectHeader);
1293 }
1294
1295 return Status;
1296}
1297
1298/*++
1299* @name ObpCreateUnnamedHandle
1300*
1301* The ObpCreateUnnamedHandle routine <FILLMEIN>
1302*
1303* @param Object
1304* <FILLMEIN>.
1305*
1306* @param DesiredAccess
1307* <FILLMEIN>.
1308*
1309* @param AdditionalReferences
1310* <FILLMEIN>.
1311*
1312* @param HandleAttributes
1313* <FILLMEIN>.
1314*
1315* @param AccessMode
1316* <FILLMEIN>.
1317*
1318* @param ReturnedObject
1319* <FILLMEIN>.
1320*
1321* @param ReturnedHandle
1322* <FILLMEIN>.
1323*
1324* @return <FILLMEIN>.
1325*
1326* @remarks None.
1327*
1328*--*/
1330NTAPI
1333 IN ULONG AdditionalReferences,
1336 OUT PVOID *ReturnedObject,
1337 OUT PHANDLE ReturnedHandle)
1338{
1339 HANDLE_TABLE_ENTRY NewEntry;
1340 POBJECT_HEADER ObjectHeader;
1341 HANDLE Handle;
1343 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1348 PAGED_CODE();
1349
1350 /* Get the object header and type */
1351 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1352 ObjectType = ObjectHeader->Type;
1354 "%s - Creating handle for: %p. UNNAMED. HC PC %lx %lx\n",
1356 Object,
1357 ObjectHeader->HandleCount,
1358 ObjectHeader->PointerCount);
1359
1360 /* Save the object header */
1361 NewEntry.Object = ObjectHeader;
1362
1363 /* Mask out the internal attributes */
1365
1366 /* Check if this is a kernel handle */
1368 {
1369 /* Set the handle table */
1372
1373 /* Check if we're not in the system process */
1375 {
1376 /* Attach to the system process */
1378 AttachedToProcess = TRUE;
1379 }
1380 }
1381 else
1382 {
1383 /* Get the current handle table */
1384 HandleTable = PsGetCurrentProcess()->ObjectTable;
1385 }
1386
1387 /* Increment the handle count */
1390 AccessMode,
1393 if (!NT_SUCCESS(Status))
1394 {
1395 /*
1396 * We failed (meaning security failure, according to NT Internals)
1397 * detach and return
1398 */
1399 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1400 return Status;
1401 }
1402
1403 /* Remove what's not in the valid access mask */
1404 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1406
1407 /* Handle extra references */
1408 if (AdditionalReferences)
1409 {
1410 /* Add them to the header */
1412 AdditionalReferences);
1413 }
1414
1415 /* Save the access mask */
1416 NewEntry.GrantedAccess = GrantedAccess;
1417
1418 /*
1419 * Create the actual handle. We'll need to do this *after* calling
1420 * ObpIncrementHandleCount to make sure that Object Security is valid
1421 * (specified in Gl00my documentation on Ob)
1422 */
1424 "%s - Handle Properties: [%p-%lx-%lx]\n",
1426 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1427 Handle = ExCreateHandle(HandleTable, &NewEntry);
1428
1429 /* Make sure we got a handle */
1430 if (Handle)
1431 {
1432 /* Check if this was a kernel handle */
1434
1435 /* Return handle and object */
1436 *ReturnedHandle = Handle;
1437
1438 /* Return the new object only if caller wanted it biased */
1439 if ((AdditionalReferences) && (ReturnedObject))
1440 {
1441 /* Return it */
1442 *ReturnedObject = Object;
1443 }
1444
1445 /* Detach if needed */
1446 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1447
1448 /* Trace and return */
1450 "%s - Returning Handle: %p HC PC %lx %lx\n",
1452 Handle,
1453 ObjectHeader->HandleCount,
1454 ObjectHeader->PointerCount);
1455 return STATUS_SUCCESS;
1456 }
1457
1458 /* Handle extra references */
1459 if (AdditionalReferences)
1460 {
1461 /* Dereference it as many times as required */
1463 -(LONG)AdditionalReferences);
1464 }
1465
1466 /* Decrement the handle count and detach */
1467 ObpDecrementHandleCount(&ObjectHeader->Body,
1470 ObjectType);
1471
1472 /* Detach and fail */
1473 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1475}
1476
1477/*++
1478* @name ObpCreateHandle
1479*
1480* The ObpCreateHandle routine <FILLMEIN>
1481*
1482* @param OpenReason
1483* <FILLMEIN>.
1484*
1485* @param Object
1486* <FILLMEIN>.
1487*
1488* @param Type
1489* <FILLMEIN>.
1490*
1491* @param AccessState
1492* <FILLMEIN>.
1493*
1494* @param AdditionalReferences
1495* <FILLMEIN>.
1496*
1497* @param HandleAttributes
1498* <FILLMEIN>.
1499*
1500* @param AccessMode
1501* <FILLMEIN>.
1502*
1503* @param ReturnedObject
1504* <FILLMEIN>.
1505*
1506* @param ReturnedHandle
1507* <FILLMEIN>.
1508*
1509* @return <FILLMEIN>.
1510*
1511* @remarks Cleans up the Lookup Context on return.
1512*
1513*--*/
1515NTAPI
1517 IN PVOID Object,
1520 IN ULONG AdditionalReferences,
1524 OUT PVOID *ReturnedObject,
1525 OUT PHANDLE ReturnedHandle)
1526{
1527 HANDLE_TABLE_ENTRY NewEntry;
1528 POBJECT_HEADER ObjectHeader;
1529 HANDLE Handle;
1531 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1536 PAUX_ACCESS_DATA AuxData;
1537 PAGED_CODE();
1538
1539 /* Get the object header and type */
1540 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1541 ObjectType = ObjectHeader->Type;
1543 "%s - Creating handle for: %p. Reason: %lx. HC PC %lx %lx\n",
1545 Object,
1546 OpenReason,
1547 ObjectHeader->HandleCount,
1548 ObjectHeader->PointerCount);
1549
1550 /* Check if the types match */
1551 if ((Type) && (ObjectType != Type))
1552 {
1553 /* They don't, cleanup */
1556 }
1557
1558 /* Save the object header */
1559 NewEntry.Object = ObjectHeader;
1560
1561 /* Check if this is a kernel handle */
1563 {
1564 /* Set the handle table */
1567
1568 /* Check if we're not in the system process */
1570 {
1571 /* Attach to the system process */
1573 AttachedToProcess = TRUE;
1574 }
1575 }
1576 else
1577 {
1578 /* Get the current handle table */
1579 HandleTable = PsGetCurrentProcess()->ObjectTable;
1580 }
1581
1582 /* Increment the handle count */
1585 AccessMode,
1588 OpenReason);
1589 if (!NT_SUCCESS(Status))
1590 {
1591 /*
1592 * We failed (meaning security failure, according to NT Internals)
1593 * detach and return
1594 */
1596 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1597 return Status;
1598 }
1599
1600 /* Check if we are doing audits on close */
1601 if (AccessState->GenerateOnClose)
1602 {
1603 /* Force the attribute on */
1605 }
1606
1607 /* Mask out the internal attributes */
1609
1610 /* Get the original desired access */
1611 DesiredAccess = AccessState->RemainingDesiredAccess |
1612 AccessState->PreviouslyGrantedAccess;
1613
1614 /* Remove what's not in the valid access mask */
1615 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1617
1618 /* Update the value in the access state */
1619 AccessState->PreviouslyGrantedAccess = GrantedAccess;
1620
1621 /* Get the auxiliary data */
1622 AuxData = AccessState->AuxData;
1623
1624 /* Handle extra references */
1625 if (AdditionalReferences)
1626 {
1627 /* Add them to the header */
1629 AdditionalReferences);
1630 }
1631
1632 /* Now we can release the object */
1634
1635 /* Save the access mask */
1636 NewEntry.GrantedAccess = GrantedAccess;
1637
1638 /*
1639 * Create the actual handle. We'll need to do this *after* calling
1640 * ObpIncrementHandleCount to make sure that Object Security is valid
1641 * (specified in Gl00my documentation on Ob)
1642 */
1644 "%s - Handle Properties: [%p-%lx-%lx]\n",
1646 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1647 Handle = ExCreateHandle(HandleTable, &NewEntry);
1648
1649 /* Make sure we got a handle */
1650 if (Handle)
1651 {
1652 /* Check if this was a kernel handle */
1654
1655 /* Return it */
1656 *ReturnedHandle = Handle;
1657
1658 /* Check if we need to generate on audit */
1659 if (AccessState->GenerateAudit)
1660 {
1661 /* Audit the handle creation */
1662 //SeAuditHandleCreation(AccessState, Handle);
1663 }
1664
1665 /* Check if this was a create */
1666 if (OpenReason == ObCreateHandle)
1667 {
1668 /* Check if we need to audit the privileges */
1669 if ((AuxData->PrivilegesUsed) &&
1670 (AuxData->PrivilegesUsed->PrivilegeCount))
1671 {
1672 /* Do the audit */
1673#if 0
1675 &AccessState->
1678 AuxData->PrivilegesUsed,
1679 TRUE,
1681#endif
1682 }
1683 }
1684
1685 /* Return the new object only if caller wanted it biased */
1686 if ((AdditionalReferences) && (ReturnedObject))
1687 {
1688 /* Return it */
1689 *ReturnedObject = Object;
1690 }
1691
1692 /* Detach if needed */
1693 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1694
1695 /* Trace and return */
1697 "%s - Returning Handle: %p HC PC %lx %lx\n",
1699 Handle,
1700 ObjectHeader->HandleCount,
1701 ObjectHeader->PointerCount);
1702 return STATUS_SUCCESS;
1703 }
1704
1705 /* Decrement the handle count and detach */
1706 ObpDecrementHandleCount(&ObjectHeader->Body,
1709 ObjectType);
1710
1711 /* Handle extra references */
1712 if (AdditionalReferences)
1713 {
1714 /* Check how many extra references were added */
1715 if (AdditionalReferences > 1)
1716 {
1717 /* Dereference it many times */
1719 -(LONG)(AdditionalReferences - 1));
1720 }
1721
1722 /* Dereference the object one last time */
1724 }
1725
1726 /* Detach if necessary and fail */
1727 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1729}
1730
1731/*++
1732* @name ObpCloseHandle
1733*
1734* The ObpCloseHandle routine <FILLMEIN>
1735*
1736* @param Handle
1737* <FILLMEIN>.
1738*
1739* @param AccessMode
1740* <FILLMEIN>.
1741*
1742* @return <FILLMEIN>.
1743*
1744* @remarks None.
1745*
1746*--*/
1748NTAPI
1751{
1753 BOOLEAN AttachedToProcess = FALSE;
1755 PHANDLE_TABLE_ENTRY HandleTableEntry;
1758 PAGED_CODE();
1760 "%s - Closing handle: %p\n", __FUNCTION__, Handle);
1761
1762 if (AccessMode == KernelMode && Handle == (HANDLE)-1)
1763 return STATUS_INVALID_HANDLE;
1764
1765 /* Check if we're dealing with a kernel handle */
1767 {
1768 /* Use the kernel table and convert the handle */
1771
1772 /* Check if we're not in the system process */
1774 {
1775 /* Attach to the system process */
1777 AttachedToProcess = TRUE;
1778 }
1779 }
1780 else
1781 {
1782 /* Use the process's handle table */
1783 HandleTable = Process->ObjectTable;
1784 }
1785
1786 /* Enter a critical region to protect handle access */
1788
1789 /* Get the handle entry */
1790 HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
1791 if (HandleTableEntry)
1792 {
1793 /* Now close the entry */
1795 HandleTableEntry,
1796 Handle,
1797 AccessMode,
1798 FALSE);
1799
1800 /* We can quit the critical region now */
1802
1803 /* Detach and return success */
1804 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1805 }
1806 else
1807 {
1808 /* We failed, quit the critical region */
1810
1811 /* Detach */
1812 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1813
1814 /* Check if we have a valid handle that's not the process or thread */
1815 if ((Handle) &&
1816 (Handle != NtCurrentProcess()) &&
1817 (Handle != NtCurrentThread()))
1818 {
1819 /* Check if we came from user mode */
1820 if (AccessMode != KernelMode)
1821 {
1822 /* Check if we have no debug port */
1823 if (Process->DebugPort)
1824 {
1825 /* Make sure we're not attached */
1826 if (!KeIsAttachedProcess())
1827 {
1828 /* Raise an exception */
1830 }
1831 }
1832 }
1833 else
1834 {
1835 /* This is kernel mode. Check if we're exiting */
1837 (Process->Peb))
1838 {
1839 /* Check if the debugger is enabled */
1841 {
1842 /* Bugcheck */
1843 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
1844 }
1845 }
1846 }
1847 }
1848
1849 /* Set invalid status */
1851 }
1852
1853 /* Return status */
1855 "%s - Closed handle: %p S: %lx\n",
1857 return Status;
1858}
1859
1889static BOOLEAN
1890NTAPI
1892 _Inout_ PHANDLE_TABLE_ENTRY HandleTableEntry,
1894{
1896
1897 /* Define the handle inheritance, using the OBJ_INHERIT attribute */
1898 if (SetHandleInfo->Information.Inherit)
1899 {
1900 /* If inheritance is not supported for this object,
1901 * fail without changing anything */
1902 POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1903 if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1904 return FALSE;
1905
1906 HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1907 }
1908 else
1909 {
1910 HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1911 }
1912
1913 /* Define the handle protection, using the protect-from-close bit */
1914 if (SetHandleInfo->Information.ProtectFromClose)
1915 HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1916 else
1917 HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1918
1919 return TRUE;
1920}
1921
1922/*++
1923* @name ObpCloseHandleCallback
1924*
1925* The ObpCloseHandleCallback routine <FILLMEIN>
1926*
1927* @param HandleTable
1928* <FILLMEIN>.
1929*
1930* @param Object
1931* <FILLMEIN>.
1932*
1933* @param GrantedAccess
1934* <FILLMEIN>.
1935*
1936* @param Context
1937* <FILLMEIN>.
1938*
1939* @return <FILLMEIN>.
1940*
1941* @remarks None.
1942*
1943*--*/
1944BOOLEAN
1945NTAPI
1949{
1951
1952 /* Simply decrement the handle count */
1954 HandleTableEntry,
1955 Handle,
1956 CloseContext->AccessMode,
1957 TRUE);
1958 return TRUE;
1959}
1960
1961/*++
1962* @name ObpDuplicateHandleCallback
1963*
1964* The ObpDuplicateHandleCallback routine <FILLMEIN>
1965*
1966* @param HandleTable
1967* <FILLMEIN>.
1968*
1969* @param HandleTableEntry
1970* <FILLMEIN>.
1971*
1972* @param Context
1973* <FILLMEIN>.
1974*
1975* @return <FILLMEIN>.
1976*
1977* @remarks None.
1978*
1979*--*/
1980BOOLEAN
1981NTAPI
1984 IN PHANDLE_TABLE_ENTRY OldEntry,
1985 IN PHANDLE_TABLE_ENTRY HandleTableEntry)
1986{
1987 POBJECT_HEADER ObjectHeader;
1988 BOOLEAN Ret = FALSE;
1991 PAGED_CODE();
1992
1993 /* Make sure that the handle is inheritable */
1994 Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0;
1995 if (Ret)
1996 {
1997 /* Get the object header */
1998 ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1999
2000 /* Increment the pointer count */
2002
2003 /* Release the handle lock */
2005
2006 /* Setup the access state */
2007 AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess;
2008
2009 /* Call the shared routine for incrementing handles */
2010 Status = ObpIncrementHandleCount(&ObjectHeader->Body,
2011 &AccessState,
2012 KernelMode,
2013 HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES,
2014 Process,
2016 if (!NT_SUCCESS(Status))
2017 {
2018 /* Return failure */
2019 ObDereferenceObject(&ObjectHeader->Body);
2020 Ret = FALSE;
2021 }
2022 }
2023 else
2024 {
2025 /* Release the handle lock */
2027 }
2028
2029 /* Return duplication result */
2030 return Ret;
2031}
2032
2033/*++
2034* @name ObClearProcessHandleTable
2035*
2036* The ObClearProcessHandleTable routine clears the handle table
2037* of the given process.
2038*
2039* @param Process
2040* The process of which the handle table should be cleared.
2041*
2042* @return None.
2043*
2044* @remarks None.
2045*
2046*--*/
2047VOID
2048NTAPI
2050{
2054 BOOLEAN AttachedToProcess = FALSE;
2055
2056 ASSERT(Process);
2057
2058 /* Ensure the handle table doesn't go away while we use it */
2060 if (!HandleTable) return;
2061
2062 /* Attach to the current process if needed */
2064 {
2066 AttachedToProcess = TRUE;
2067 }
2068
2069 /* Enter a critical region */
2071
2072 /* Fill out the context */
2073 Context.AccessMode = UserMode;
2074 Context.HandleTable = HandleTable;
2075
2076 /* Sweep the handle table to close all handles */
2079 &Context);
2080
2081 /* Leave the critical region */
2083
2084 /* Detach if needed */
2085 if (AttachedToProcess)
2087
2088 /* Let the handle table go */
2090}
2091
2092/*++
2093* @name ObInitProcess
2094*
2095* The ObInitProcess routine initializes the handle table for the process
2096* to be initialized, by either creating a new one or duplicating it from
2097* the parent process.
2098*
2099* @param Parent
2100* A parent process (optional).
2101*
2102* @param Process
2103* The process to initialize.
2104*
2105* @return Success or failure.
2106*
2107* @remarks None.
2108*
2109*--*/
2111NTAPI
2114{
2115 PHANDLE_TABLE ParentTable, ObjectTable;
2116
2117 /* Check for a parent */
2118 if (Parent)
2119 {
2120 /* Reference the parent's table */
2122 if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2123
2124 /* Duplicate it */
2125 ObjectTable = ExDupHandleTable(Process,
2126 ParentTable,
2128 OBJ_INHERIT);
2129 }
2130 else
2131 {
2132 /* Otherwise just create a new table */
2133 ParentTable = NULL;
2134 ObjectTable = ExCreateHandleTable(Process);
2135 }
2136
2137 /* Make sure we have a table */
2138 if (ObjectTable)
2139 {
2140 /* Associate it */
2141 Process->ObjectTable = ObjectTable;
2142
2143 /* Check for auditing */
2145 {
2146 /* FIXME: TODO */
2147 DPRINT1("Need auditing!\n");
2148 }
2149
2150 /* Get rid of the old table now */
2151 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2152
2153 /* We are done */
2154 return STATUS_SUCCESS;
2155 }
2156 else
2157 {
2158 /* Fail */
2159 Process->ObjectTable = NULL;
2160 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2162 }
2163}
2164
2165/*++
2166* @name ObKillProcess
2167*
2168* The ObKillProcess routine performs rundown operations on the process,
2169* then clears and destroys its handle table.
2170*
2171* @param Process
2172* The process to be killed.
2173*
2174* @return None.
2175*
2176* @remarks Called by the Object Manager cleanup code (kernel)
2177* when a process is to be destroyed.
2178*
2179*--*/
2180VOID
2181NTAPI
2183{
2186 BOOLEAN HardErrors;
2187 PAGED_CODE();
2188
2189 /* Wait for process rundown and then complete it */
2191 ExRundownCompleted(&Process->RundownProtect);
2192
2193 /* Get the object table */
2194 HandleTable = Process->ObjectTable;
2195 if (!HandleTable) return;
2196
2197 /* Disable hard errors while we close handles */
2198 HardErrors = IoSetThreadHardErrorMode(FALSE);
2199
2200 /* Enter a critical region */
2202
2203 /* Fill out the context */
2204 Context.AccessMode = KernelMode;
2205 Context.HandleTable = HandleTable;
2206
2207 /* Sweep the handle table to close all handles */
2210 &Context);
2211 ASSERT(HandleTable->HandleCount == 0);
2212
2213 /* Leave the critical region */
2215
2216 /* Re-enable hard errors */
2217 IoSetThreadHardErrorMode(HardErrors);
2218
2219 /* Destroy the object table */
2220 Process->ObjectTable = NULL;
2222}
2223
2225NTAPI
2228 IN PEPROCESS TargetProcess OPTIONAL,
2234{
2235 HANDLE_TABLE_ENTRY NewHandleEntry;
2236 BOOLEAN AttachedToProcess = FALSE;
2237 PVOID SourceObject;
2238 POBJECT_HEADER ObjectHeader;
2240 HANDLE NewHandle;
2243 ACCESS_MASK TargetAccess, SourceAccess;
2246 AUX_ACCESS_DATA AuxData;
2249 ULONG AuditMask;
2251
2252 PAGED_CODE();
2254 "%s - Duplicating handle: %p for %p into %p\n",
2257 SourceProcess,
2258 TargetProcess);
2259
2260 /* Assume failure */
2262
2263 /* Check if we're not duplicating the same access */
2265 {
2266 /* Validate the desired access */
2267 Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2268 if (!NT_SUCCESS(Status)) return Status;
2269 }
2270
2271 /* Reference the object table */
2274
2275 /* Reference the process object */
2277 SourceProcess,
2280 &SourceObject,
2282 &AuditMask);
2283 if (!NT_SUCCESS(Status))
2284 {
2285 /* Fail */
2286 ObDereferenceProcessHandleTable(SourceProcess);
2287 return Status;
2288 }
2289 else
2290 {
2291 /* Check if we have to don't have to audit object close */
2292 if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2293 {
2294 /* Then there is no audit mask */
2295 AuditMask = 0;
2296 }
2297 }
2298
2299 /* Check if there's no target process */
2300 if (!TargetProcess)
2301 {
2302 /* Check if the caller wanted actual duplication */
2304 {
2305 /* Invalid request */
2307 }
2308 else
2309 {
2310 /* Otherwise, do the attach */
2311 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2312
2313 /* Close the handle and detach */
2316 }
2317
2318 /* Return */
2319 ObDereferenceProcessHandleTable(SourceProcess);
2320 ObDereferenceObject(SourceObject);
2321 return Status;
2322 }
2323
2324 /* Create a kernel handle if asked, but only in the system process */
2325 if (PreviousMode == KernelMode &&
2327 TargetProcess == PsInitialSystemProcess)
2328 {
2330 }
2331
2332 /* Get the target handle table */
2334 if (!HandleTable)
2335 {
2336 /* Check if the caller wanted us to close the handle */
2338 {
2339 /* Do the attach */
2340 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2341
2342 /* Close the handle and detach */
2345 }
2346
2347 /* Return */
2348 ObDereferenceProcessHandleTable(SourceProcess);
2349 ObDereferenceObject(SourceObject);
2351 }
2352
2353 /* Get the source access */
2354 SourceAccess = HandleInformation.GrantedAccess;
2355
2356 /* Check if we're not in the target process */
2357 if (TargetProcess != PsGetCurrentProcess())
2358 {
2359 /* Attach to it */
2360 KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2361 AttachedToProcess = TRUE;
2362 }
2363
2364 /* Check if we're duplicating the attributes */
2366 {
2367 /* Duplicate them */
2368 HandleAttributes = HandleInformation.HandleAttributes;
2369 }
2370 else
2371 {
2372 /* Don't allow caller to bypass auditing */
2373 HandleAttributes |= HandleInformation.HandleAttributes &
2375 }
2376
2377 /* Check if we're duplicating the access */
2378 if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2379
2380 /* Get object data */
2381 ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2382 ObjectType = ObjectHeader->Type;
2383
2384 /* Fill out the entry */
2385 RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2386 NewHandleEntry.Object = ObjectHeader;
2388
2389 /* Check if we're using a generic mask */
2391 {
2392 /* Map it */
2394 &ObjectType->TypeInfo.GenericMapping);
2395 }
2396
2397 /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2398 TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2400 NewHandleEntry.GrantedAccess = TargetAccess;
2401
2402 /* Check if we're asking for new access */
2403 if (TargetAccess & ~SourceAccess)
2404 {
2405 /* We are. We need the security procedure to validate this */
2406 if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2407 {
2408 /* Use our built-in access state */
2411 &AuxData,
2412 TargetAccess,
2413 &ObjectType->TypeInfo.GenericMapping);
2414 }
2415 else
2416 {
2417 /* Otherwise we can't allow this privilege elevation */
2419 }
2420 }
2421 else
2422 {
2423 /* We don't need an access state */
2425 }
2426
2427 /* Make sure the access state was created OK */
2428 if (NT_SUCCESS(Status))
2429 {
2430 /* Add a new handle */
2431 Status = ObpIncrementHandleCount(SourceObject,
2437 }
2438
2439 /* Check if we were attached */
2440 if (AttachedToProcess)
2441 {
2442 /* We can safely detach now */
2444 AttachedToProcess = FALSE;
2445 }
2446
2447 /* Check if we have to close the source handle */
2449 {
2450 /* Attach and close */
2451 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2454 }
2455
2456 /* Check if we had an access state */
2458
2459 /* Now check if incrementing actually failed */
2460 if (!NT_SUCCESS(Status))
2461 {
2462 /* Dereference handle tables */
2463 ObDereferenceProcessHandleTable(SourceProcess);
2464 ObDereferenceProcessHandleTable(TargetProcess);
2465
2466 /* Dereference the source object */
2467 ObDereferenceObject(SourceObject);
2468 return Status;
2469 }
2470
2471 if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2472 {
2473 NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2474 NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2475 }
2476
2477 /* Now create the handle */
2478 NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2479 if (!NewHandle)
2480 {
2481 /* Undo the increment */
2482 ObpDecrementHandleCount(SourceObject,
2483 TargetProcess,
2484 TargetAccess,
2485 ObjectType);
2486
2487 /* Deference the object and set failure status */
2488 ObDereferenceObject(SourceObject);
2490 }
2491
2492 /* Mark it as a kernel handle if requested */
2493 if (KernelHandle)
2494 {
2495 NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2496 }
2497
2498 /* Return the handle */
2499 if (TargetHandle) *TargetHandle = NewHandle;
2500
2501 /* Dereference handle tables */
2502 ObDereferenceProcessHandleTable(SourceProcess);
2503 ObDereferenceProcessHandleTable(TargetProcess);
2504
2505 /* Return status */
2507 "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2509 NewHandle,
2510 SourceProcess,
2511 TargetProcess,
2512 SourceObject,
2513 ObjectHeader->PointerCount,
2514 ObjectHeader->HandleCount);
2515 return Status;
2516}
2517
2518/* PUBLIC FUNCTIONS *********************************************************/
2519
2520/*++
2521* @name ObOpenObjectByName
2522* @implemented NT4
2523*
2524* The ObOpenObjectByName routine <FILLMEIN>
2525*
2526* @param ObjectAttributes
2527* <FILLMEIN>.
2528*
2529* @param ObjectType
2530* <FILLMEIN>.
2531*
2532* @param AccessMode
2533* <FILLMEIN>.
2534*
2535* @param PassedAccessState
2536* <FILLMEIN>.
2537*
2538* @param DesiredAccess
2539* <FILLMEIN>.
2540*
2541* @param ParseContext
2542* <FILLMEIN>.
2543*
2544* @param Handle
2545* <FILLMEIN>.
2546*
2547* @return <FILLMEIN>.
2548*
2549* @remarks None.
2550*
2551*--*/
2553NTAPI
2559 IN OUT PVOID ParseContext,
2561{
2562 PVOID Object = NULL;
2564 NTSTATUS Status, Status2;
2565 POBJECT_HEADER ObjectHeader;
2567 OB_OPEN_REASON OpenReason;
2568 POB_TEMP_BUFFER TempBuffer;
2569 PAGED_CODE();
2570
2571 /* Assume failure */
2572 *Handle = NULL;
2573
2574 /* Check if we didn't get any Object Attributes */
2575 if (!ObjectAttributes)
2576 {
2577 /* Fail with special status code */
2579 }
2580
2581 /* Allocate the temporary buffer */
2583 sizeof(OB_TEMP_BUFFER),
2585 if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES;
2586
2587 /* Capture all the info */
2589 AccessMode,
2590 AccessMode,
2591 TRUE,
2592 &TempBuffer->ObjectCreateInfo,
2593 &ObjectName);
2594 if (!NT_SUCCESS(Status))
2595 {
2596 /* Fail */
2598 return Status;
2599 }
2600
2601 /* Check if we didn't get an access state */
2602 if (!PassedAccessState)
2603 {
2604 /* Try to get the generic mapping if we can */
2605 if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping;
2606
2607 /* Use our built-in access state */
2608 PassedAccessState = &TempBuffer->LocalAccessState;
2610 &TempBuffer->AuxData,
2613 if (!NT_SUCCESS(Status)) goto Quickie;
2614 }
2615
2616 /* Get the security descriptor */
2617 if (TempBuffer->ObjectCreateInfo.SecurityDescriptor)
2618 {
2619 /* Save it in the access state */
2622 }
2623
2624 /* Validate the access mask */
2626 if (!NT_SUCCESS(Status))
2627 {
2628 /* Cleanup after lookup */
2630 goto Cleanup;
2631 }
2632
2633 /* Now do the lookup */
2635 &ObjectName,
2636 TempBuffer->ObjectCreateInfo.Attributes,
2637 ObjectType,
2638 AccessMode,
2639 ParseContext,
2640 TempBuffer->ObjectCreateInfo.SecurityQos,
2641 NULL,
2643 &TempBuffer->LookupContext,
2644 &Object);
2645 if (!NT_SUCCESS(Status))
2646 {
2647 /* Cleanup after lookup */
2649 goto Cleanup;
2650 }
2651
2652 /* Check if this object has create information */
2653 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2654 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
2655 {
2656 /* Then we are creating a new handle */
2657 OpenReason = ObCreateHandle;
2658
2659 /* Check if we still have create info */
2660 if (ObjectHeader->ObjectCreateInfo)
2661 {
2662 /* Free it */
2663 ObpFreeObjectCreateInformation(ObjectHeader->
2664 ObjectCreateInfo);
2665 ObjectHeader->ObjectCreateInfo = NULL;
2666 }
2667 }
2668 else
2669 {
2670 /* Otherwise, we are merely opening it */
2671 OpenReason = ObOpenHandle;
2672 }
2673
2674 /* Check if we have invalid object attributes */
2675 if (ObjectHeader->Type->TypeInfo.InvalidAttributes &
2676 TempBuffer->ObjectCreateInfo.Attributes)
2677 {
2678 /* Set failure code */
2680
2681 /* Cleanup after lookup */
2683
2684 /* Dereference the object */
2686 }
2687 else
2688 {
2689 /* Create the actual handle now */
2690 Status2 = ObpCreateHandle(OpenReason,
2691 Object,
2692 ObjectType,
2694 0,
2695 TempBuffer->ObjectCreateInfo.Attributes,
2696 &TempBuffer->LookupContext,
2697 AccessMode,
2698 NULL,
2699 Handle);
2700 if (!NT_SUCCESS(Status2))
2701 {
2703 Status = Status2;
2704 }
2705 }
2706
2707Cleanup:
2708 /* Delete the access state */
2709 if (PassedAccessState == &TempBuffer->LocalAccessState)
2710 {
2712 }
2713
2714Quickie:
2715 /* Release the object attributes and temporary buffer */
2719
2720 /* Return status */
2722 "%s - returning Object %p with PC S: %lx %lx\n",
2724 Object,
2725 Object ? OBJECT_TO_OBJECT_HEADER(Object)->PointerCount : -1,
2726 Status);
2727 return Status;
2728}
2729
2730/*++
2731* @name ObOpenObjectByPointer
2732* @implemented NT4
2733*
2734* The ObOpenObjectByPointer routine <FILLMEIN>
2735*
2736* @param Object
2737* <FILLMEIN>.
2738*
2739* @param HandleAttributes
2740* <FILLMEIN>.
2741*
2742* @param PassedAccessState
2743* <FILLMEIN>.
2744*
2745* @param DesiredAccess
2746* <FILLMEIN>.
2747*
2748* @param ObjectType
2749* <FILLMEIN>.
2750*
2751* @param AccessMode
2752* <FILLMEIN>.
2753*
2754* @param Handle
2755* <FILLMEIN>.
2756*
2757* @return <FILLMEIN>.
2758*
2759* @remarks None.
2760*
2761*--*/
2763NTAPI
2771{
2775 AUX_ACCESS_DATA AuxData;
2776 PAGED_CODE();
2777
2778 /* Assume failure */
2779 *Handle = NULL;
2780
2781 /* Reference the object */
2783 0,
2784 ObjectType,
2785 AccessMode);
2786 if (!NT_SUCCESS(Status)) return Status;
2787
2788 /* Get the Header Info */
2790
2791 /* Check if we didn't get an access state */
2792 if (!PassedAccessState)
2793 {
2794 /* Use our built-in access state */
2797 &AuxData,
2799 &Header->Type->TypeInfo.GenericMapping);
2800 if (!NT_SUCCESS(Status))
2801 {
2802 /* Fail */
2804 return Status;
2805 }
2806 }
2807
2808 /* Check if we have invalid object attributes */
2809 if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
2810 {
2811 /* Delete the access state */
2813 {
2815 }
2816
2817 /* Dereference the object */
2820 }
2821
2822 /* Create the handle */
2824 Object,
2825 ObjectType,
2827 0,
2829 NULL,
2830 AccessMode,
2831 NULL,
2832 Handle);
2834
2835 /* Delete the access state */
2837 {
2839 }
2840
2841 /* Return */
2843 "%s - returning Object with PC S: %lx %lx\n",
2845 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
2846 Status);
2847 return Status;
2848}
2849
2850/*++
2851* @name ObFindHandleForObject
2852* @implemented NT4
2853*
2854* The ObFindHandleForObject routine <FILLMEIN>
2855*
2856* @param Process
2857* <FILLMEIN>.
2858*
2859* @param Object
2860* <FILLMEIN>.
2861*
2862* @param ObjectType
2863* <FILLMEIN>.
2864*
2865* @param HandleInformation
2866* <FILLMEIN>.
2867*
2868* @param HandleReturn
2869* <FILLMEIN>.
2870*
2871* @return <FILLMEIN>.
2872*
2873* @remarks None.
2874*
2875*--*/
2876BOOLEAN
2877NTAPI
2879 IN PVOID Object,
2883{
2884 OBP_FIND_HANDLE_DATA FindData;
2886 PVOID ObjectTable;
2887
2888 /* Make sure we have an object table */
2890 if (ObjectTable)
2891 {
2892 /* Check if we have an object */
2893 if (Object)
2894 {
2895 /* Set its header */
2897 }
2898 else
2899 {
2900 /* Otherwise, no object to match*/
2901 FindData.ObjectHeader = NULL;
2902 }
2903
2904 /* Set other information */
2905 FindData.ObjectType = ObjectType;
2907
2908 /* Enumerate the handle table */
2909 if (ExEnumHandleTable(Process->ObjectTable,
2911 &FindData,
2912 Handle))
2913 {
2914 /* Set success */
2915 Result = TRUE;
2916 }
2917
2918 /* Let go of the table */
2920 }
2921
2922 /* Return the result */
2923 return Result;
2924}
2925
2926/*++
2927* @name ObInsertObject
2928* @implemented NT4
2929*
2930* The ObInsertObject routine <FILLMEIN>
2931*
2932* @param Object
2933* <FILLMEIN>.
2934*
2935* @param PassedAccessState
2936* <FILLMEIN>.
2937*
2938* @param DesiredAccess
2939* <FILLMEIN>.
2940*
2941* @param AdditionalReferences
2942* <FILLMEIN>.
2943*
2944* @param ReferencedObject
2945* <FILLMEIN>.
2946*
2947* @param Handle
2948* <FILLMEIN>.
2949*
2950* @return <FILLMEIN>.
2951*
2952* @remarks None.
2953*
2954*--*/
2956NTAPI
2963{
2964 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2965 POBJECT_HEADER ObjectHeader;
2968 PVOID InsertObject;
2969 PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
2970 BOOLEAN SdAllocated = FALSE;
2971 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2973 ACCESS_STATE LocalAccessState;
2974 AUX_ACCESS_DATA AuxData;
2975 OB_OPEN_REASON OpenReason;
2977 NTSTATUS Status = STATUS_SUCCESS, RealStatus;
2978 BOOLEAN IsNewObject;
2979 PAGED_CODE();
2980
2981 /* Get the Header */
2982 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2983
2984 /* Detect invalid insert */
2985 if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO))
2986 {
2987 /* Display warning and break into debugger */
2988 DPRINT1("OB: Attempting to insert existing object %p\n", Object);
2989 DbgBreakPoint();
2990
2991 /* Allow debugger to continue */
2994 }
2995
2996 /* Get the create and name info, as well as the object type */
2997 ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
2998 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
2999 ObjectType = ObjectHeader->Type;
3000 ObjectName = NULL;
3001
3002 /* Check if this is an named object */
3003 if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
3004 {
3005 /* Get the object name */
3006 ObjectName = &ObjectNameInfo->Name;
3007 }
3008
3009 /* Sanity check */
3010 ASSERT((Handle) ||
3011 ((ObjectPointerBias == 0) &&
3012 (ObjectName == NULL) &&
3013 (ObjectType->TypeInfo.SecurityRequired) &&
3014 (NewObject == NULL)));
3015
3016 /* Check if the object is unnamed and also doesn't have security */
3018 if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName))
3019 {
3020 /* Assume failure */
3021 *Handle = NULL;
3022 ObjectHeader->ObjectCreateInfo = NULL;
3023
3024 /* Create the handle */
3028 ObjectCreateInfo->Attributes,
3030 NewObject,
3031 Handle);
3032
3033 /* Free the create information */
3034 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3035
3036 /* Release the object name information */
3037 ObpDereferenceNameInfo(ObjectNameInfo);
3038
3039 /* Remove the extra keep-alive reference */
3041
3042 /* Return */
3044 "%s - returning Object with PC S: %lx %lx\n",
3046 ObjectHeader->PointerCount,
3047 Status);
3048 return Status;
3049 }
3050
3051 /* Check if we didn't get an access state */
3052 if (!AccessState)
3053 {
3054 /* Use our built-in access state */
3055 AccessState = &LocalAccessState;
3056 Status = SeCreateAccessState(&LocalAccessState,
3057 &AuxData,
3059 &ObjectType->TypeInfo.GenericMapping);
3060 if (!NT_SUCCESS(Status))
3061 {
3062 /* Fail */
3063 ObpDereferenceNameInfo(ObjectNameInfo);
3065 return Status;
3066 }
3067 }
3068
3069 /* Save the security descriptor */
3070 AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;
3071
3072 /* Validate the access mask */
3074 if (!NT_SUCCESS(Status))
3075 {
3076 /* Fail */
3077 ObpDereferenceNameInfo(ObjectNameInfo);
3079 return Status;
3080 }
3081
3082 /* Setup a lookup context */
3084 InsertObject = Object;
3085 OpenReason = ObCreateHandle;
3086
3087 /* Check if the object is named */
3088 if (ObjectName)
3089 {
3090 /* Look it up */
3091 Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory,
3092 ObjectName,
3093 ObjectCreateInfo->Attributes,
3094 ObjectType,
3095 (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ?
3097 ObjectCreateInfo->ParseContext,
3098 ObjectCreateInfo->SecurityQos,
3099 Object,
3101 &Context,
3102 &InsertObject);
3103
3104 /* Check if we found an object that doesn't match the one requested */
3105 if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject))
3106 {
3107 /* This means we're opening an object, not creating a new one */
3108 OpenReason = ObOpenHandle;
3109
3110 /* Make sure the caller said it's OK to do this */
3111 if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
3112 {
3113 /* He did, but did he want this type? */
3114 if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type)
3115 {
3116 /* Wrong type, so fail */
3118 }
3119 else
3120 {
3121 /* Right type, so warn */
3123 }
3124 }
3125 else
3126 {
3127 /* Check if this was a symbolic link */
3128 if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
3130 {
3131 /* Dereference it */
3132 ObDereferenceObject(InsertObject);
3133 }
3134
3135 /* Caller wanted to create a new object, fail */
3137 }
3138 }
3139
3140 /* Check if anything until now failed */
3141 if (!NT_SUCCESS(Status))
3142 {
3143 /* Cleanup after lookup */
3145
3146 /* Remove query reference that we added */
3147 ObpDereferenceNameInfo(ObjectNameInfo);
3148
3149 /* Dereference the object and delete the access state */
3151 if (AccessState == &LocalAccessState)
3152 {
3153 /* We used a local one; delete it */
3155 }
3156
3157 /* Return failure code */
3158 return Status;
3159 }
3160 else
3161 {
3162 /* Check if this is a symbolic link */
3164 {
3165 /* Create the internal name */
3167 }
3168 }
3169 }
3170
3171 /* Now check if this object is being created */
3172 if (InsertObject == Object)
3173 {
3174 /* Check if it's named or forces security */
3175 if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired))
3176 {
3177 /* Make sure it's inserted into an object directory */
3178 if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
3179 {
3180 /* Get the current descriptor */
3181 ObGetObjectSecurity(ObjectNameInfo->Directory,
3182 &ParentDescriptor,
3183 &SdAllocated);
3184 }
3185
3186 /* Now assign it */
3188 ParentDescriptor,
3189 Object,
3190 ObjectType);
3191
3192 /* Check if we captured one */
3193 if (ParentDescriptor)
3194 {
3195 /* We did, release it */
3196 ObReleaseObjectSecurity(ParentDescriptor, SdAllocated);
3197 }
3198 else if (NT_SUCCESS(Status))
3199 {
3200 /* Other we didn't, but we were able to use the current SD */
3202 ObjectCreateInfo->ProbeMode,
3203 TRUE);
3204
3205 /* Clear the current one */
3206 AccessState->SecurityDescriptor =
3207 ObjectCreateInfo->SecurityDescriptor = NULL;
3208 }
3209 }
3210
3211 /* Check if anything until now failed */
3212 if (!NT_SUCCESS(Status))
3213 {
3214 /* Check if the directory was added */
3215 if (Context.DirectoryLocked)
3216 {
3217 /* Weird case where we need to do a manual delete */
3218 DPRINT1("Unhandled path\n");
3219 ASSERT(FALSE);
3220 }
3221
3222 /* Cleanup the lookup */
3224
3225 /* Remove query reference that we added */
3226 ObpDereferenceNameInfo(ObjectNameInfo);
3227
3228 /* Dereference the object and delete the access state */
3230 if (AccessState == &LocalAccessState)
3231 {
3232 /* We used a local one; delete it */
3234 }
3235
3236 /* Return failure code */
3237 ASSERT(FALSE);
3238 return Status;
3239 }
3240 }
3241
3242 /* Save the actual status until here */
3243 RealStatus = Status;
3244
3245 /* Check if caller wants us to create a handle */
3246 ObjectHeader->ObjectCreateInfo = NULL;
3247 if (Handle)
3248 {
3249 /* Create the handle */
3250 Status = ObpCreateHandle(OpenReason,
3251 InsertObject,
3252 NULL,
3255 ObjectCreateInfo->Attributes,
3256 &Context,
3258 NewObject,
3259 Handle);
3260 if (!NT_SUCCESS(Status))
3261 {
3262 /* If the object had a name, backout everything */
3264
3265 /* Return the status of the failure */
3266 *Handle = NULL;
3267 RealStatus = Status;
3268 }
3269
3270 /* Remove a query reference */
3271 ObpDereferenceNameInfo(ObjectNameInfo);
3272
3273 /* Remove the extra keep-alive reference */
3275 }
3276 else
3277 {
3278 /* Otherwise, lock the object */
3279 ObpAcquireObjectLock(ObjectHeader);
3280
3281 /* And charge quota for the process to make it appear as used */
3282 RealStatus = ObpChargeQuotaForObject(ObjectHeader,
3283 ObjectType,
3284 &IsNewObject);
3285
3286 /* Release the lock */
3287 ObpReleaseObjectLock(ObjectHeader);
3288
3289 /* Check if we failed and dereference the object if so */
3290 if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
3291 }
3292
3293 /* We can delete the Create Info now */
3294 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3295
3296 /* Check if we created our own access state and delete it if so */
3297 if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState);
3298
3299 /* Return status code */
3301 "%s - returning Object with PC RS/S: %lx %lx %lx\n",
3303 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
3304 RealStatus, Status);
3305 return RealStatus;
3306}
3307
3335NTAPI
3340{
3341 OBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleAttributesContext;
3342 BOOLEAN Result, AttachedToProcess = FALSE;
3345
3346 PAGED_CODE();
3347
3348 /* Check if this is a kernel handle */
3350 {
3351 /* Use the kernel table and convert the handle */
3354
3355 /* Check if we're not in the system process */
3357 {
3358 /* Attach to the system process */
3360 AttachedToProcess = TRUE;
3361 }
3362 }
3363 else
3364 {
3365 /* Get the current process' handle table */
3366 HandleTable = PsGetCurrentProcess()->ObjectTable;
3367 }
3368
3369 /* Initialize the handle attribute context */
3370 SetHandleAttributesContext.PreviousMode = PreviousMode;
3371 SetHandleAttributesContext.Information = *HandleFlags;
3372
3373 /* Invoke the ObpSetHandleAttributes callback */
3375 Handle,
3377 (ULONG_PTR)&SetHandleAttributesContext);
3378
3379 /* Detach from the system process if needed */
3380 if (AttachedToProcess)
3382
3383 /* Return the result as an NTSTATUS value */
3385}
3386
3387/*++
3388* @name ObCloseHandle
3389* @implemented NT5.1
3390*
3391* The ObCloseHandle routine <FILLMEIN>
3392*
3393* @param Handle
3394* <FILLMEIN>.
3395*
3396* @param AccessMode
3397* <FILLMEIN>.
3398*
3399* @return <FILLMEIN>.
3400*
3401* @remarks None.
3402*
3403*--*/
3405NTAPI
3408{
3409 /* Call the internal API */
3411}
3412
3413/*++
3414* @name NtClose
3415* @implemented NT4
3416*
3417* The NtClose routine <FILLMEIN>
3418*
3419* @param Handle
3420* <FILLMEIN>.
3421*
3422* @return <FILLMEIN>.
3423*
3424* @remarks None.
3425*
3426*--*/
3428NTAPI
3430{
3431 /* Call the internal API */
3433}
3434
3436NTAPI
3437NtDuplicateObject(IN HANDLE SourceProcessHandle,
3444{
3445 PEPROCESS SourceProcess, TargetProcess, Target;
3446 HANDLE hTarget;
3450 "%s - Duplicating handle: %p for %p into %p.\n",
3453 SourceProcessHandle,
3455
3456 /* Check if we have a target handle */
3457 if ((TargetHandle) && (PreviousMode != KernelMode))
3458 {
3459 /* Enter SEH */
3460 _SEH2_TRY
3461 {
3462 /* Probe the handle and assume failure */
3464 *TargetHandle = NULL;
3465 }
3467 {
3468 /* Return the exception code */
3470 }
3471 _SEH2_END;
3472 }
3473
3474 /* Now reference the input handle */
3475 Status = ObReferenceObjectByHandle(SourceProcessHandle,
3479 (PVOID*)&SourceProcess,
3480 NULL);
3481 if (!NT_SUCCESS(Status)) return Status;
3482
3483 /* Check if got a target handle */
3485 {
3486 /* Now reference the output handle */
3491 (PVOID*)&TargetProcess,
3492 NULL);
3493 if (NT_SUCCESS(Status))
3494 {
3495 /* Use this target process */
3496 Target = TargetProcess;
3497 }
3498 else
3499 {
3500 /* No target process */
3501 Target = NULL;
3502 }
3503 }
3504 else
3505 {
3506 /* No target process */
3508 Target = NULL;
3509 }
3510
3511 /* Call the internal routine */
3512 Status = ObDuplicateObject(SourceProcess,
3514 Target,
3515 &hTarget,
3518 Options,
3519 PreviousMode);
3520
3521 /* Check if the caller wanted the return handle */
3522 if (TargetHandle)
3523 {
3524 /* Protect the write to user mode */
3525 _SEH2_TRY
3526 {
3527 /* Write the new handle */
3528 *TargetHandle = hTarget;
3529 }
3531 {
3532 /* Otherwise, get the exception code */
3534 }
3535 _SEH2_END;
3536 }
3537
3538 /* Dereference the processes */
3540 "%s - Duplicated handle: %p into %p S %lx\n",
3542 hTarget,
3544 Status);
3546 ObDereferenceObject(SourceProcess);
3547 return Status;
3548}
3549
3550BOOLEAN
3551NTAPI
3553{
3554 /* Use the inlined version. We know we are in kernel mode. */
3556}
3557
3558/* EOF */
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define OBJ_PROTECT_CLOSE
#define ObpSymbolicLinkObjectType
Definition: ObTypes.cpp:171
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
Type
Definition: Type.h:7
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define GENERIC_ACCESS
Definition: security.c:35
#define HandleToLong(h)
Definition: basetsd.h:74
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
Definition: Header.h:9
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
HANDLE KernelHandle
Definition: legacy.c:24
static const WCHAR Cleanup[]
Definition: register.c:80
#define __FUNCTION__
Definition: types.h:116
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExWaitForRundownProtectionRelease
Definition: ex.h:141
#define ExReleaseRundownProtection
Definition: ex.h:139
#define ExGetPreviousMode
Definition: ex.h:143
#define ExRundownCompleted
Definition: ex.h:142
#define ExAcquireRundownProtection
Definition: ex.h:138
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define PROCESS_DUP_HANDLE
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:168
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:235
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
ObjectType
Definition: metafile.c:88
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
_In_ HANDLE SourceHandle
Definition: obfuncs.h:438
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:440
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:442
_In_ HANDLE _In_opt_ HANDLE TargetProcessHandle
Definition: obfuncs.h:439
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:104
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:89
#define OB_FLAG_EXCLUSIVE
Definition: obtypes.h:86
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:95
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:112
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:83
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:127
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:108
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:84
struct _OBJECT_HANDLE_COUNT_ENTRY OBJECT_HANDLE_COUNT_ENTRY
#define OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(h)
Definition: obtypes.h:117
@ ObOpenHandle
Definition: obtypes.h:162
@ ObCreateHandle
Definition: obtypes.h:161
@ ObInheritHandle
Definition: obtypes.h:164
@ ObDuplicateHandle
Definition: obtypes.h:163
struct _OBJECT_HANDLE_COUNT_DATABASE OBJECT_HANDLE_COUNT_DATABASE
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
enum _OB_OPEN_REASON OB_OPEN_REASON
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define NtCurrentProcess()
Definition: nt_native.h:1660
#define GENERIC_ALL
Definition: nt_native.h:92
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
VOID NTAPI ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context)
Definition: handle.c:1232
BOOLEAN NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
Definition: handle.c:1189
BOOLEAN NTAPI ExEnumHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_ENUM_HANDLE_CALLBACK EnumHandleProcedure, IN OUT PVOID Context, OUT PHANDLE EnumHandle OPTIONAL)
Definition: handle.c:1271
HANDLE NTAPI ExCreateHandle(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:827
PHANDLE_TABLE NTAPI ExCreateHandleTable(IN PEPROCESS Process OPTIONAL)
Definition: handle.c:801
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:984
VOID NTAPI ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, IN PVOID DestroyHandleProcedure OPTIONAL)
Definition: handle.c:963
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
Definition: handle.c:1046
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
PHANDLE_TABLE NTAPI ExDupHandleTable(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, IN ULONG_PTR Mask)
Definition: handle.c:1072
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
NTSTATUS NTAPI SeDefaultObjectMethod(_In_ PVOID Object, _In_ SECURITY_OPERATION_CODE OperationType, _In_ PSECURITY_INFORMATION SecurityInformation, _Inout_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_opt_ PULONG ReturnLength, _Inout_opt_ PSECURITY_DESCRIPTOR *OldSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode)
const LUID SeSecurityPrivilege
Definition: priv.c:27
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726
NTSTATUS NTAPI KeRaiseUserException(IN NTSTATUS ExceptionCode)
Definition: except.c:413
POBJECT_TYPE PsProcessType
Definition: process.c:20
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
VOID NTAPI SeDeleteAccessState(_In_ PACCESS_STATE AccessState)
Deletes an allocated access state from the memory.
Definition: access.c:150
NTSTATUS NTAPI SeCreateAccessState(_Out_ PACCESS_STATE AccessState, _Out_ __drv_aliasesMem PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
Creates an access state.
Definition: access.c:121
VOID NTAPI SePrivilegeObjectAuditAlarm(_In_ HANDLE Handle, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE CurrentMode)
Raises an audit with alarm notification message when an object tries to acquire this privilege.
Definition: audit.c:1321
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_QUOTA_EXCEEDED
Definition: ntstatus.h:398
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define STATUS_HANDLE_NOT_CLOSABLE
Definition: ntstatus.h:819
NTSTATUS NTAPI ObpCaptureObjectCreateInformation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE CreatorMode, IN BOOLEAN AllocateFromLookaside, IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, OUT PUNICODE_STRING ObjectName)
Definition: oblife.c:456
#define OBJ_HANDLE_ATTRIBUTES
Definition: ob.h:52
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
#define OBP_SYSTEM_PROCESS_QUOTA
Definition: ob.h:64
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:74
VOID NTAPI ObpCreateSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:334
#define ObpGetHandleObject(x)
Definition: ob.h:91
BOOLEAN NTAPI ObCheckObjectAccess(IN PVOID Object, IN OUT PACCESS_STATE AccessState, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus)
Definition: obsecure.c:441
struct _OBP_CLOSE_HANDLE_CONTEXT * POBP_CLOSE_HANDLE_CONTEXT
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301
#define ObpAccessProtectCloseBit
Definition: ob.h:59
#define TAG_OB_TEMP_STORAGE
Definition: ob.h:160
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
#define ObMarkHandleAsKernelHandle(Handle)
Definition: ob.h:85
#define OB_HANDLE_DEBUG
Definition: ob.h:17
#define OBJ_AUDIT_OBJECT_CLOSE
Definition: ob.h:51
NTSTATUS NTAPI ObpLookupObjectName(IN HANDLE RootHandle OPTIONAL, IN OUT PUNICODE_STRING ObjectName, IN ULONG Attributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, IN PVOID InsertObject OPTIONAL, IN OUT PACCESS_STATE AccessState, OUT POBP_LOOKUP_CONTEXT LookupContext, OUT PVOID *FoundObject)
Definition: obname.c:446
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Initializes a new object directory lookup context. Used for lookup operations (insertions/deletions) ...
Definition: ob_x.h:258
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Releases an initialized object directory lookup context. Unlocks it if necessary, and dereferences th...
Definition: ob_x.h:323
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:56
NTSTATUS NTAPI ObpIncrementUnnamedHandleCount(IN PVOID Object, IN PACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process)
Definition: obhandle.c:1103
BOOLEAN NTAPI ObIsKernelHandle(IN HANDLE Handle)
Definition: obhandle.c:3552
NTSTATUS NTAPI ObpCreateHandle(IN OB_OPEN_REASON OpenReason, IN PVOID Object, IN POBJECT_TYPE Type OPTIONAL, IN PACCESS_STATE AccessState, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN POBP_LOOKUP_CONTEXT Context, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1516
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3406
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2182
NTSTATUS NTAPI ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN IgnoreHandleProtection)
Definition: obhandle.c:685
BOOLEAN NTAPI ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:211
VOID NTAPI ObDereferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:48
static BOOLEAN NTAPI ObpSetHandleAttributes(_Inout_ PHANDLE_TABLE_ENTRY HandleTableEntry, _In_ ULONG_PTR Context)
Internal callback used by ObSetHandleAttributes(). Updates the attributes of a handle given by its ha...
Definition: obhandle.c:1891
NTSTATUS NTAPI ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, IN POBJECT_TYPE ObjectType, OUT PBOOLEAN NewObject)
Definition: obhandle.c:431
POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader)
Definition: obhandle.c:259
NTSTATUS NTAPI ObpCreateUnnamedHandle(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1331
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
NTSTATUS NTAPI ObSetHandleAttributes(_In_ HANDLE Handle, _In_ POBJECT_HANDLE_FLAG_INFORMATION HandleFlags, _In_ KPROCESSOR_MODE PreviousMode)
Sets the attributes (inheritable and protect-from-close) of an existing object handle.
Definition: obhandle.c:3336
VOID NTAPI ObpDecrementHandleCount(IN PVOID ObjectBody, IN PEPROCESS Process, IN ACCESS_MASK GrantedAccess, IN POBJECT_TYPE ObjectType)
Definition: obhandle.c:530
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2957
NTSTATUS NTAPI ObpReferenceProcessObjectByHandle(IN HANDLE Handle, IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation, OUT PACCESS_MASK AuditMask)
Definition: obhandle.c:85
BOOLEAN NTAPI ObpCloseHandleCallback(IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:1946
NTSTATUS NTAPI ObpCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:1749
NTSTATUS NTAPI ObDuplicateObject(IN PEPROCESS SourceProcess, IN HANDLE SourceHandle, IN PEPROCESS TargetProcess OPTIONAL, IN PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options, IN KPROCESSOR_MODE PreviousMode)
Definition: obhandle.c:2226
NTSTATUS NTAPI ObpValidateAccessMask(IN PACCESS_STATE AccessState)
Definition: obhandle.c:488
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2049
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3437
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2878
NTSTATUS NTAPI ObpIncrementHandleCount(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
Definition: obhandle.c:811
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3429
PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:26
BOOLEAN NTAPI ObpDuplicateHandleCallback(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY OldEntry, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: obhandle.c:1982
NTSTATUS NTAPI ObpIncrementHandleDataBase(IN POBJECT_HEADER ObjectHeader, IN PEPROCESS Process, IN OUT PULONG NewProcessHandleCount)
Definition: obhandle.c:333
NTSTATUS NTAPI ObInitProcess(IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Process)
Definition: obhandle.c:2112
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2764
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2554
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:493
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:380
NTSTATUS NTAPI ObGetObjectSecurity(IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated)
Definition: obsecure.c:612
VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated)
Definition: obsecure.c:712
NTSTATUS NTAPI ObAssignSecurity(IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PVOID Object, IN POBJECT_TYPE Type)
Definition: obsecure.c:550
long LONG
Definition: pedump.c:60
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
PEPROCESS_QUOTA_BLOCK NTAPI PsChargeSharedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T AmountToChargePaged, _In_ SIZE_T AmountToChargeNonPaged)
Charges the shared (paged and non paged) pool quotas. The function is used exclusively by the Object ...
Definition: quota.c:674
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
#define OBJ_INHERIT
Definition: winternl.h:225
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:235
GENERIC_MAPPING GenericMapping
Definition: setypes.h:259
PPRIVILEGE_SET PrivilegesUsed
Definition: setypes.h:258
KPROCESS Pcb
Definition: pstypes.h:1399
Definition: extypes.h:767
PVOID Object
Definition: extypes.h:770
ULONG GrantedAccess
Definition: extypes.h:777
ULONG_PTR ObAttributes
Definition: extypes.h:771
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:365
KPROCESSOR_MODE ProbeMode
Definition: obtypes.h:361
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: obtypes.h:366
OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]
Definition: obtypes.h:472
Definition: obtypes.h:464
ULONG HandleCount
Definition: obtypes.h:466
struct _EPROCESS * Process
Definition: obtypes.h:465
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:479
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:480
POBJECT_DIRECTORY Directory
Definition: obtypes.h:453
UNICODE_STRING Name
Definition: obtypes.h:454
UCHAR Flags
Definition: obtypes.h:518
LONG_PTR HandleCount
Definition: obtypes.h:511
LONG_PTR PointerCount
Definition: obtypes.h:508
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:521
POBJECT_TYPE Type
Definition: obtypes.h:514
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:411
PHANDLE_TABLE HandleTable
Definition: ob.h:117
KPROCESSOR_MODE AccessMode
Definition: ob.h:118
POBJECT_HANDLE_INFORMATION HandleInformation
Definition: ob.h:125
POBJECT_TYPE ObjectType
Definition: ob.h:124
POBJECT_HEADER ObjectHeader
Definition: ob.h:123
OBJECT_HANDLE_FLAG_INFORMATION Information
Definition: ob.h:112
KPROCESSOR_MODE PreviousMode
Definition: ob.h:111
OBP_LOOKUP_CONTEXT LookupContext
Definition: ob.h:165
OBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: ob.h:164
AUX_ACCESS_DATA AuxData
Definition: ob.h:166
ACCESS_STATE LocalAccessState
Definition: ob.h:163
$ULONG PrivilegeCount
Definition: setypes.h:86
#define TAG_OB_HANDLE
Definition: tag.h:126
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static ULONG HandleCount
Definition: uefidisk.c:67
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
NTSYSAPI void WINAPI DbgBreakPoint(void)
@ ProcessHandleCount
Definition: winternl.h:1902
#define NtCurrentThread()
Definition: winternl.h:5372
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KAPC_STATE
Definition: ketypes.h:1727
_Must_inspect_result_ _In_ _In_ ULONG ProbeMode
Definition: mmfuncs.h:561
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44
#define ObDereferenceObject
Definition: obfuncs.h:203
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG ObjectPointerBias
Definition: obfuncs.h:73
_Inout_opt_ PACCESS_STATE PassedAccessState
Definition: obfuncs.h:71
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG _Out_opt_ PVOID * NewObject
Definition: obfuncs.h:74
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20
#define SE_SACL_PRESENT
Definition: setypes.h:835