ReactOS 0.4.17-dev-1133-gc25e4fd
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*--*/
809static
817 IN OB_OPEN_REASON OpenReason)
818{
819 POBJECT_HEADER ObjectHeader;
823 PEPROCESS ExclusiveProcess;
825 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
826 KIRQL CalloutIrql;
828 ULONG Total;
830 BOOLEAN ObjectLocked;
831 PAGED_CODE();
832
833 /* Get the object header and type */
834 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
835 ObjectType = ObjectHeader->Type;
837 "%s - Incrementing count for: %p. Reason: %lx. HC PC %lx %lx\n",
839 Object,
840 OpenReason,
841 ObjectHeader->HandleCount,
842 ObjectHeader->PointerCount);
843
844 /* Check if caller is forcing user mode */
846 {
847 /* Force it */
849 }
850 else
851 {
852 /* Keep original setting */
854 }
855
856 /* Lock the object */
857 ObpAcquireObjectLock(ObjectHeader);
858 ObjectLocked = TRUE;
859
860 /* Charge quota and remove the creator info flag */
862 if (!NT_SUCCESS(Status)) goto Quickie;
863
864 /* Check if the open is exclusive */
866 {
867 /* Check if the object allows this, or if the inherit flag was given */
869 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
870 {
871 /* Incorrect attempt */
873 goto Quickie;
874 }
875
876 /* Check if we have access to it */
877 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
878 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
879 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
880 {
881 /* This isn't the right process */
883 goto Quickie;
884 }
885
886 /* Now you got exclusive access */
887 Exclusive = TRUE;
888 }
889 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
891 {
892 /* Caller didn't want exclusive access, but the object is exclusive */
894 goto Quickie;
895 }
896
897 /* Check for exclusive kernel object */
898 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
899 if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
901 {
902 /* Caller is not kernel, but the object is kernel exclusive */
904 goto Quickie;
905 }
906
907 /*
908 * Check if this is an object that went from 0 handles back to existence,
909 * but doesn't have an open procedure, only a close procedure. This means
910 * that it will never realize that the object is back alive, so we must
911 * fail the request.
912 */
913 if (!(ObjectHeader->HandleCount) &&
914 !(NewObject) &&
915 (ObjectType->TypeInfo.MaintainHandleCount) &&
916 !(ObjectType->TypeInfo.OpenProcedure) &&
917 (ObjectType->TypeInfo.CloseProcedure))
918 {
919 /* Fail */
921 goto Quickie;
922 }
923
924 /* Check if we're opening an existing handle */
925 if ((OpenReason == ObOpenHandle) ||
926 ((OpenReason == ObDuplicateHandle) && (AccessState)))
927 {
928 /* Validate the caller's access to this object */
931 TRUE,
932 ProbeMode,
933 &Status))
934 {
935 /* Access was denied, so fail */
936 goto Quickie;
937 }
938 }
939 else if (OpenReason == ObCreateHandle)
940 {
941 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
942 if (AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED)
943 {
944 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
945 AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
946 AccessState->RemainingDesiredAccess |= GENERIC_ALL;
947 }
948
949 /* Check if we have to map the GENERIC mask */
950 if (AccessState->RemainingDesiredAccess & GENERIC_ACCESS)
951 {
952 /* Map it to the correct access masks */
953 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
954 &ObjectType->TypeInfo.GenericMapping);
955 }
956
957 /* Check if the caller is trying to access system security */
958 if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY)
959 {
960 /* Client must be warranted SeSecurityPrivilege to touch SACLs */
962 {
963 /* FIXME: Generate an audit alarm, security manager must be alerted */
965 goto Quickie;
966 }
967
968 /* Privilege held, grant it so the access state reflects reality */
969 AccessState->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
970 AccessState->RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
971 }
972 }
973
974 /* Check if this is an exclusive handle */
975 if (Exclusive)
976 {
977 /* Save the owner process */
978 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
979 }
980
981 /* Increase the handle count */
984
985 /* Check if we have a handle database */
986 if (ObjectType->TypeInfo.MaintainHandleCount)
987 {
988 /* Increment the handle database */
989 Status = ObpIncrementHandleDataBase(ObjectHeader,
990 Process,
992 if (!NT_SUCCESS(Status))
993 {
994 /* FIXME: This should never happen for now */
995 DPRINT1("Unhandled case\n");
996 ASSERT(FALSE);
997 goto Quickie;
998 }
999 }
1000
1001 /* Release the lock */
1002 ObpReleaseObjectLock(ObjectHeader);
1003 ObjectLocked = FALSE;
1004
1005 if (AccessState)
1006 {
1007 /* Get the combined desired access */
1008 ACCESS_MASK DesiredAccess = AccessState->RemainingDesiredAccess |
1009 AccessState->PreviouslyGrantedAccess;
1010
1011 /* Remove what's not valid */
1012 *GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1014 }
1015
1016 /* Check if we have an open procedure */
1018 if (ObjectType->TypeInfo.OpenProcedure)
1019 {
1020 /* Call it */
1021 ObpCalloutStart(&CalloutIrql);
1022 Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
1023 ProbeMode,
1024 Process,
1025 Object,
1028 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1029
1030 /* Check if the open procedure failed */
1031 if (!NT_SUCCESS(Status))
1032 {
1033 /* FIXME: This should never happen for now */
1034 DPRINT1("Unhandled case\n");
1035 ASSERT(FALSE);
1036 goto Quickie;
1037 }
1038 }
1039
1040 /* Check if this is a create operation */
1041 if (OpenReason == ObCreateHandle)
1042 {
1043 /* Check if we have creator info */
1044 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1045 if (CreatorInfo)
1046 {
1047 /* We do, acquire the lock */
1049
1050 /* Insert us on the list */
1051 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1052
1053 /* Release the lock */
1055 }
1056 }
1057
1058 /* Increase total number of handles */
1059 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1060 if (Total > ObjectType->HighWaterNumberOfHandles)
1061 {
1062 /* Fixup count */
1063 ObjectType->HighWaterNumberOfHandles = Total;
1064 }
1065
1066 /* Trace call and return */
1068 "%s - Incremented count for: %p. Reason: %lx HC PC %lx %lx\n",
1070 Object,
1071 OpenReason,
1072 ObjectHeader->HandleCount,
1073 ObjectHeader->PointerCount);
1074
1075Quickie:
1076 if (ObjectLocked)
1077 {
1078 ObpReleaseObjectLock(ObjectHeader);
1079 }
1080
1081 return Status;
1082}
1083
1084/*++
1085* @name ObpIncrementUnnamedHandleCount
1086*
1087* The ObpIncrementUnnamedHandleCount routine <FILLMEIN>
1088*
1089* @param Object
1090* <FILLMEIN>.
1091*
1092* @param AccessState
1093* <FILLMEIN>.
1094*
1095* @param AccessMode
1096* <FILLMEIN>.
1097*
1098* @param HandleAttributes
1099* <FILLMEIN>.
1100*
1101* @param Process
1102* <FILLMEIN>.
1103*
1104* @param OpenReason
1105* <FILLMEIN>.
1106*
1107* @return <FILLMEIN>.
1108*
1109* @remarks None.
1110*
1111*--*/
1113NTAPI
1119{
1120 POBJECT_HEADER ObjectHeader;
1124 PEPROCESS ExclusiveProcess;
1126 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1127 KIRQL CalloutIrql;
1128 ULONG Total;
1129 BOOLEAN ObjectLocked;
1130
1131 /* Get the object header and type */
1132 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1133 ObjectType = ObjectHeader->Type;
1135 "%s - Incrementing count for: %p. UNNAMED. HC PC %lx %lx\n",
1137 Object,
1138 ObjectHeader->HandleCount,
1139 ObjectHeader->PointerCount);
1140
1141 /* Lock the object */
1142 ObpAcquireObjectLock(ObjectHeader);
1143 ObjectLocked = TRUE;
1144
1145 /* Charge quota and remove the creator info flag */
1147 if (!NT_SUCCESS(Status)) goto Quickie;
1148
1149 /* Check if the open is exclusive */
1151 {
1152 /* Check if the object allows this, or if the inherit flag was given */
1153 if ((HandleAttributes & OBJ_INHERIT) ||
1154 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
1155 {
1156 /* Incorrect attempt */
1158 goto Quickie;
1159 }
1160
1161 /* Check if we have access to it */
1162 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
1163 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
1164 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
1165 {
1166 /* This isn't the right process */
1168 goto Quickie;
1169 }
1170
1171 /* Now you got exclusive access */
1172 Exclusive = TRUE;
1173 }
1174 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
1175 (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader)))
1176 {
1177 /* Caller didn't want exclusive access, but the object is exclusive */
1179 goto Quickie;
1180 }
1181
1182 /*
1183 * Check if this is an object that went from 0 handles back to existence,
1184 * but doesn't have an open procedure, only a close procedure. This means
1185 * that it will never realize that the object is back alive, so we must
1186 * fail the request.
1187 */
1188 if (!(ObjectHeader->HandleCount) &&
1189 !(NewObject) &&
1190 (ObjectType->TypeInfo.MaintainHandleCount) &&
1191 !(ObjectType->TypeInfo.OpenProcedure) &&
1192 (ObjectType->TypeInfo.CloseProcedure))
1193 {
1194 /* Fail */
1196 goto Quickie;
1197 }
1198
1199 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
1201 {
1202 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
1203 *DesiredAccess &= ~MAXIMUM_ALLOWED;
1205 }
1206
1207 /* Check if we have to map the GENERIC mask */
1209 {
1210 /* Map it to the correct access masks */
1212 &ObjectType->TypeInfo.GenericMapping);
1213 }
1214
1215 /* Check if this is an exclusive handle */
1216 if (Exclusive)
1217 {
1218 /* Save the owner process */
1219 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
1220 }
1221
1222 /* Increase the handle count */
1223 InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
1225
1226 /* Check if we have a handle database */
1227 if (ObjectType->TypeInfo.MaintainHandleCount)
1228 {
1229 /* Increment the handle database */
1230 Status = ObpIncrementHandleDataBase(ObjectHeader,
1231 Process,
1233 if (!NT_SUCCESS(Status))
1234 {
1235 /* FIXME: This should never happen for now */
1236 DPRINT1("Unhandled case\n");
1237 ASSERT(FALSE);
1238 goto Quickie;
1239 }
1240 }
1241
1242 /* Release the lock */
1243 ObpReleaseObjectLock(ObjectHeader);
1244 ObjectLocked = FALSE;
1245
1246 /* Check if we have an open procedure */
1248 if (ObjectType->TypeInfo.OpenProcedure)
1249 {
1250 /* Call it */
1251 ObpCalloutStart(&CalloutIrql);
1252 Status = ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
1253 AccessMode,
1254 Process,
1255 Object,
1258 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1259
1260 /* Check if the open procedure failed */
1261 if (!NT_SUCCESS(Status))
1262 {
1263 /* FIXME: This should never happen for now */
1264 DPRINT1("Unhandled case\n");
1265 ASSERT(FALSE);
1266 goto Quickie;
1267 }
1268 }
1269
1270 /* Check if we have creator info */
1271 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1272 if (CreatorInfo)
1273 {
1274 /* We do, acquire the lock */
1276
1277 /* Insert us on the list */
1278 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1279
1280 /* Release the lock */
1282 }
1283
1284 /* Increase total number of handles */
1285 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1286 if (Total > ObjectType->HighWaterNumberOfHandles)
1287 {
1288 /* Fixup count */
1289 ObjectType->HighWaterNumberOfHandles = Total;
1290 }
1291
1292 /* Trace call and return */
1294 "%s - Incremented count for: %p. UNNAMED HC PC %lx %lx\n",
1296 Object,
1297 ObjectHeader->HandleCount,
1298 ObjectHeader->PointerCount);
1299
1300Quickie:
1301 if (ObjectLocked)
1302 {
1303 ObpReleaseObjectLock(ObjectHeader);
1304 }
1305
1306 return Status;
1307}
1308
1309/*++
1310* @name ObpCreateUnnamedHandle
1311*
1312* The ObpCreateUnnamedHandle routine <FILLMEIN>
1313*
1314* @param Object
1315* <FILLMEIN>.
1316*
1317* @param DesiredAccess
1318* <FILLMEIN>.
1319*
1320* @param AdditionalReferences
1321* <FILLMEIN>.
1322*
1323* @param HandleAttributes
1324* <FILLMEIN>.
1325*
1326* @param AccessMode
1327* <FILLMEIN>.
1328*
1329* @param ReturnedObject
1330* <FILLMEIN>.
1331*
1332* @param ReturnedHandle
1333* <FILLMEIN>.
1334*
1335* @return <FILLMEIN>.
1336*
1337* @remarks None.
1338*
1339*--*/
1341NTAPI
1344 IN ULONG AdditionalReferences,
1347 OUT PVOID *ReturnedObject,
1348 OUT PHANDLE ReturnedHandle)
1349{
1350 HANDLE_TABLE_ENTRY NewEntry;
1351 POBJECT_HEADER ObjectHeader;
1352 HANDLE Handle;
1354 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1359 PAGED_CODE();
1360
1361 /* Get the object header and type */
1362 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1363 ObjectType = ObjectHeader->Type;
1365 "%s - Creating handle for: %p. UNNAMED. HC PC %lx %lx\n",
1367 Object,
1368 ObjectHeader->HandleCount,
1369 ObjectHeader->PointerCount);
1370
1371 /* Save the object header */
1372 NewEntry.Object = ObjectHeader;
1373
1374 /* Mask out the internal attributes */
1376
1377 /* Check if this is a kernel handle */
1379 {
1380 /* Set the handle table */
1383
1384 /* Check if we're not in the system process */
1386 {
1387 /* Attach to the system process */
1389 AttachedToProcess = TRUE;
1390 }
1391 }
1392 else
1393 {
1394 /* Get the current handle table */
1395 HandleTable = PsGetCurrentProcess()->ObjectTable;
1396 }
1397
1398 /* Increment the handle count */
1401 AccessMode,
1404 if (!NT_SUCCESS(Status))
1405 {
1406 /*
1407 * We failed (meaning security failure, according to NT Internals)
1408 * detach and return
1409 */
1410 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1411 return Status;
1412 }
1413
1414 /* Remove what's not in the valid access mask */
1415 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1417
1418 /* Handle extra references */
1419 if (AdditionalReferences)
1420 {
1421 /* Add them to the header */
1423 AdditionalReferences);
1424 }
1425
1426 /* Save the access mask */
1427 NewEntry.GrantedAccess = GrantedAccess;
1428
1429 /*
1430 * Create the actual handle. We'll need to do this *after* calling
1431 * ObpIncrementHandleCount to make sure that Object Security is valid
1432 * (specified in Gl00my documentation on Ob)
1433 */
1435 "%s - Handle Properties: [%p-%lx-%lx]\n",
1437 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1438 Handle = ExCreateHandle(HandleTable, &NewEntry);
1439
1440 /* Make sure we got a handle */
1441 if (Handle)
1442 {
1443 /* Check if this was a kernel handle */
1445
1446 /* Return handle and object */
1447 *ReturnedHandle = Handle;
1448
1449 /* Return the new object only if caller wanted it biased */
1450 if ((AdditionalReferences) && (ReturnedObject))
1451 {
1452 /* Return it */
1453 *ReturnedObject = Object;
1454 }
1455
1456 /* Detach if needed */
1457 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1458
1459 /* Trace and return */
1461 "%s - Returning Handle: %p HC PC %lx %lx\n",
1463 Handle,
1464 ObjectHeader->HandleCount,
1465 ObjectHeader->PointerCount);
1466 return STATUS_SUCCESS;
1467 }
1468
1469 /* Handle extra references */
1470 if (AdditionalReferences)
1471 {
1472 /* Dereference it as many times as required */
1474 -(LONG)AdditionalReferences);
1475 }
1476
1477 /* Decrement the handle count and detach */
1478 ObpDecrementHandleCount(&ObjectHeader->Body,
1481 ObjectType);
1482
1483 /* Detach and fail */
1484 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1486}
1487
1488/*++
1489* @name ObpCreateHandle
1490*
1491* The ObpCreateHandle routine <FILLMEIN>
1492*
1493* @param OpenReason
1494* <FILLMEIN>.
1495*
1496* @param Object
1497* <FILLMEIN>.
1498*
1499* @param Type
1500* <FILLMEIN>.
1501*
1502* @param AccessState
1503* <FILLMEIN>.
1504*
1505* @param AdditionalReferences
1506* <FILLMEIN>.
1507*
1508* @param HandleAttributes
1509* <FILLMEIN>.
1510*
1511* @param AccessMode
1512* <FILLMEIN>.
1513*
1514* @param ReturnedObject
1515* <FILLMEIN>.
1516*
1517* @param ReturnedHandle
1518* <FILLMEIN>.
1519*
1520* @return <FILLMEIN>.
1521*
1522* @remarks Cleans up the Lookup Context on return.
1523*
1524*--*/
1525static
1527NTAPI
1529 IN PVOID Object,
1532 IN ULONG AdditionalReferences,
1536 OUT PVOID *ReturnedObject,
1537 OUT PHANDLE ReturnedHandle)
1538{
1540 HANDLE_TABLE_ENTRY NewEntry;
1541 POBJECT_HEADER ObjectHeader;
1542 HANDLE Handle;
1544 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1549 PAUX_ACCESS_DATA AuxData;
1550 PAGED_CODE();
1551
1552 /* Get the object header and type */
1553 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1554 ObjectType = ObjectHeader->Type;
1556 "%s - Creating handle for: %p. Reason: %lx. HC PC %lx %lx\n",
1558 Object,
1559 OpenReason,
1560 ObjectHeader->HandleCount,
1561 ObjectHeader->PointerCount);
1562
1563 /* Check if the types match */
1564 if ((Type) && (ObjectType != Type))
1565 {
1566 /* They don't, cleanup */
1569 }
1570
1571 /* Save the object header */
1572 NewEntry.Object = ObjectHeader;
1573
1574 /* Check if this is a kernel handle */
1576 {
1577 /* Set the handle table */
1580
1581 /* Check if we're not in the system process */
1583 {
1584 /* Attach to the system process */
1586 AttachedToProcess = TRUE;
1588 }
1589 }
1590 else
1591 {
1592 /* Get the current handle table */
1593 HandleTable = Process->ObjectTable;
1594 }
1595
1596 /* Increment the handle count */
1600 AccessMode,
1602 Process,
1603 OpenReason);
1604 if (!NT_SUCCESS(Status))
1605 {
1606 /*
1607 * We failed (meaning security failure, according to NT Internals)
1608 * detach and return
1609 */
1611 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1612 return Status;
1613 }
1614
1615 /* Check if we are doing audits on close */
1616 if (AccessState->GenerateOnClose)
1617 {
1618 /* Force the attribute on */
1620 }
1621
1622 /* Mask out the internal attributes */
1624
1625 /* Update the value in the access state */
1626 AccessState->PreviouslyGrantedAccess = GrantedAccess;
1627
1628 /* Get the auxiliary data */
1629 AuxData = AccessState->AuxData;
1630
1631 /* Handle extra references */
1632 if (AdditionalReferences)
1633 {
1634 /* Add them to the header */
1636 AdditionalReferences);
1637 }
1638
1639 /* Now we can release the object */
1641
1642 /* Save the access mask */
1643 NewEntry.GrantedAccess = GrantedAccess;
1644
1645 /*
1646 * Create the actual handle. We'll need to do this *after* calling
1647 * ObpIncrementHandleCount to make sure that Object Security is valid
1648 * (specified in Gl00my documentation on Ob)
1649 */
1651 "%s - Handle Properties: [%p-%lx-%lx]\n",
1653 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1654 Handle = ExCreateHandle(HandleTable, &NewEntry);
1655
1656 /* Make sure we got a handle */
1657 if (Handle)
1658 {
1659 /* Check if this was a kernel handle */
1661
1662 /* Return it */
1663 *ReturnedHandle = Handle;
1664
1665 /* Check if we need to generate on audit */
1666 if (AccessState->GenerateAudit)
1667 {
1668 /* Audit the handle creation */
1669 //SeAuditHandleCreation(AccessState, Handle);
1670 }
1671
1672 /* Check if this was a create */
1673 if (OpenReason == ObCreateHandle)
1674 {
1675 /* Check if we need to audit the privileges */
1676 if ((AuxData->PrivilegesUsed) &&
1677 (AuxData->PrivilegesUsed->PrivilegeCount))
1678 {
1679 /* Do the audit */
1680#if 0
1682 &AccessState->
1685 AuxData->PrivilegesUsed,
1686 TRUE,
1688#endif
1689 }
1690 }
1691
1692 /* Return the new object only if caller wanted it biased */
1693 if ((AdditionalReferences) && (ReturnedObject))
1694 {
1695 /* Return it */
1696 *ReturnedObject = Object;
1697 }
1698
1699 /* Detach if needed */
1700 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1701
1702 /* Trace and return */
1704 "%s - Returning Handle: %p HC PC %lx %lx\n",
1706 Handle,
1707 ObjectHeader->HandleCount,
1708 ObjectHeader->PointerCount);
1709 return STATUS_SUCCESS;
1710 }
1711
1712 /* Decrement the handle count and detach */
1713 ObpDecrementHandleCount(&ObjectHeader->Body,
1714 Process,
1716 ObjectType);
1717
1718 /* Handle extra references */
1719 if (AdditionalReferences)
1720 {
1721 /* Check how many extra references were added */
1722 if (AdditionalReferences > 1)
1723 {
1724 /* Dereference it many times */
1726 -(LONG)(AdditionalReferences - 1));
1727 }
1728
1729 /* Dereference the object one last time */
1731 }
1732
1733 /* Detach if necessary and fail */
1734 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1736}
1737
1738/*++
1739* @name ObpCloseHandle
1740*
1741* The ObpCloseHandle routine <FILLMEIN>
1742*
1743* @param Handle
1744* <FILLMEIN>.
1745*
1746* @param AccessMode
1747* <FILLMEIN>.
1748*
1749* @return <FILLMEIN>.
1750*
1751* @remarks None.
1752*
1753*--*/
1755NTAPI
1758{
1760 BOOLEAN AttachedToProcess = FALSE;
1762 PHANDLE_TABLE_ENTRY HandleTableEntry;
1765 PAGED_CODE();
1767 "%s - Closing handle: %p\n", __FUNCTION__, Handle);
1768
1769 if (AccessMode == KernelMode && Handle == (HANDLE)-1)
1770 return STATUS_INVALID_HANDLE;
1771
1772 /* Check if we're dealing with a kernel handle */
1774 {
1775 /* Use the kernel table and convert the handle */
1778
1779 /* Check if we're not in the system process */
1781 {
1782 /* Attach to the system process */
1784 AttachedToProcess = TRUE;
1785 }
1786 }
1787 else
1788 {
1789 /* Use the process's handle table */
1790 HandleTable = Process->ObjectTable;
1791 }
1792
1793 /* Enter a critical region to protect handle access */
1795
1796 /* Get the handle entry */
1797 HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
1798 if (HandleTableEntry)
1799 {
1800 /* Now close the entry */
1802 HandleTableEntry,
1803 Handle,
1804 AccessMode,
1805 FALSE);
1806
1807 /* We can quit the critical region now */
1809
1810 /* Detach and return success */
1811 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1812 }
1813 else
1814 {
1815 /* We failed, quit the critical region */
1817
1818 /* Detach */
1819 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1820
1821 /* Check if we have a valid handle that's not the process or thread */
1822 if ((Handle) &&
1823 (Handle != NtCurrentProcess()) &&
1824 (Handle != NtCurrentThread()))
1825 {
1826 /* Check if we came from user mode */
1827 if (AccessMode != KernelMode)
1828 {
1829 /* Check if we have no debug port */
1830 if (Process->DebugPort)
1831 {
1832 /* Make sure we're not attached */
1833 if (!KeIsAttachedProcess())
1834 {
1835 /* Raise an exception */
1837 }
1838 }
1839 }
1840 else
1841 {
1842 /* This is kernel mode. Check if we're exiting */
1844 (Process->Peb))
1845 {
1846 /* Check if the debugger is enabled */
1848 {
1849 /* Bugcheck */
1850 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
1851 }
1852 }
1853 }
1854 }
1855
1856 /* Set invalid status */
1858 }
1859
1860 /* Return status */
1862 "%s - Closed handle: %p S: %lx\n",
1864 return Status;
1865}
1866
1896static BOOLEAN
1897NTAPI
1899 _Inout_ PHANDLE_TABLE_ENTRY HandleTableEntry,
1901{
1903
1904 /* Define the handle inheritance, using the OBJ_INHERIT attribute */
1905 if (SetHandleInfo->Information.Inherit)
1906 {
1907 /* If inheritance is not supported for this object,
1908 * fail without changing anything */
1909 POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1910 if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1911 return FALSE;
1912
1913 HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1914 }
1915 else
1916 {
1917 HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1918 }
1919
1920 /* Define the handle protection, using the protect-from-close bit */
1921 if (SetHandleInfo->Information.ProtectFromClose)
1922 HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1923 else
1924 HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1925
1926 return TRUE;
1927}
1928
1929/*++
1930* @name ObpCloseHandleCallback
1931*
1932* The ObpCloseHandleCallback routine <FILLMEIN>
1933*
1934* @param HandleTable
1935* <FILLMEIN>.
1936*
1937* @param Object
1938* <FILLMEIN>.
1939*
1940* @param GrantedAccess
1941* <FILLMEIN>.
1942*
1943* @param Context
1944* <FILLMEIN>.
1945*
1946* @return <FILLMEIN>.
1947*
1948* @remarks None.
1949*
1950*--*/
1951BOOLEAN
1952NTAPI
1956{
1958
1959 /* Simply decrement the handle count */
1961 HandleTableEntry,
1962 Handle,
1963 CloseContext->AccessMode,
1964 TRUE);
1965 return TRUE;
1966}
1967
1968/*++
1969* @name ObpDuplicateHandleCallback
1970*
1971* The ObpDuplicateHandleCallback routine <FILLMEIN>
1972*
1973* @param HandleTable
1974* <FILLMEIN>.
1975*
1976* @param HandleTableEntry
1977* <FILLMEIN>.
1978*
1979* @param Context
1980* <FILLMEIN>.
1981*
1982* @return <FILLMEIN>.
1983*
1984* @remarks None.
1985*
1986*--*/
1987BOOLEAN
1988NTAPI
1991 IN PHANDLE_TABLE_ENTRY OldEntry,
1992 IN PHANDLE_TABLE_ENTRY HandleTableEntry)
1993{
1994 POBJECT_HEADER ObjectHeader;
1995 BOOLEAN Ret = FALSE;
1997 PAGED_CODE();
1998
1999 /* Make sure that the handle is inheritable */
2000 Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0;
2001 if (Ret)
2002 {
2003 /* Get the object header */
2004 ObjectHeader = ObpGetHandleObject(HandleTableEntry);
2005
2006 /* Increment the pointer count */
2008
2009 /* Release the handle lock */
2011
2012 /* Call the shared routine for incrementing handles */
2013 Status = ObpIncrementHandleCount(&ObjectHeader->Body,
2014 NULL,
2015 &HandleTableEntry->GrantedAccess,
2016 KernelMode,
2017 HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES,
2018 Process,
2020 if (!NT_SUCCESS(Status))
2021 {
2022 /* Return failure */
2023 ObDereferenceObject(&ObjectHeader->Body);
2024 Ret = FALSE;
2025 }
2026 }
2027 else
2028 {
2029 /* Release the handle lock */
2031 }
2032
2033 /* Return duplication result */
2034 return Ret;
2035}
2036
2037/*++
2038* @name ObClearProcessHandleTable
2039*
2040* The ObClearProcessHandleTable routine clears the handle table
2041* of the given process.
2042*
2043* @param Process
2044* The process of which the handle table should be cleared.
2045*
2046* @return None.
2047*
2048* @remarks None.
2049*
2050*--*/
2051VOID
2052NTAPI
2054{
2058 BOOLEAN AttachedToProcess = FALSE;
2059
2060 ASSERT(Process);
2061
2062 /* Ensure the handle table doesn't go away while we use it */
2064 if (!HandleTable) return;
2065
2066 /* Attach to the current process if needed */
2068 {
2070 AttachedToProcess = TRUE;
2071 }
2072
2073 /* Enter a critical region */
2075
2076 /* Fill out the context */
2077 Context.AccessMode = UserMode;
2078 Context.HandleTable = HandleTable;
2079
2080 /* Sweep the handle table to close all handles */
2083 &Context);
2084
2085 /* Leave the critical region */
2087
2088 /* Detach if needed */
2089 if (AttachedToProcess)
2091
2092 /* Let the handle table go */
2094}
2095
2096/*++
2097* @name ObInitProcess
2098*
2099* The ObInitProcess routine initializes the handle table for the process
2100* to be initialized, by either creating a new one or duplicating it from
2101* the parent process.
2102*
2103* @param Parent
2104* A parent process (optional).
2105*
2106* @param Process
2107* The process to initialize.
2108*
2109* @return Success or failure.
2110*
2111* @remarks None.
2112*
2113*--*/
2115NTAPI
2118{
2119 PHANDLE_TABLE ParentTable, ObjectTable;
2120
2121 /* Check for a parent */
2122 if (Parent)
2123 {
2124 /* Reference the parent's table */
2126 if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2127
2128 /* Duplicate it */
2129 ObjectTable = ExDupHandleTable(Process,
2130 ParentTable,
2132 OBJ_INHERIT);
2133 }
2134 else
2135 {
2136 /* Otherwise just create a new table */
2137 ParentTable = NULL;
2138 ObjectTable = ExCreateHandleTable(Process);
2139 }
2140
2141 /* Make sure we have a table */
2142 if (ObjectTable)
2143 {
2144 /* Associate it */
2145 Process->ObjectTable = ObjectTable;
2146
2147 /* Check for auditing */
2149 {
2150 /* FIXME: TODO */
2151 DPRINT1("Need auditing!\n");
2152 }
2153
2154 /* Get rid of the old table now */
2155 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2156
2157 /* We are done */
2158 return STATUS_SUCCESS;
2159 }
2160 else
2161 {
2162 /* Fail */
2163 Process->ObjectTable = NULL;
2164 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2166 }
2167}
2168
2169/*++
2170* @name ObKillProcess
2171*
2172* The ObKillProcess routine performs rundown operations on the process,
2173* then clears and destroys its handle table.
2174*
2175* @param Process
2176* The process to be killed.
2177*
2178* @return None.
2179*
2180* @remarks Called by the Object Manager cleanup code (kernel)
2181* when a process is to be destroyed.
2182*
2183*--*/
2184VOID
2185NTAPI
2187{
2190 BOOLEAN HardErrors;
2191 PAGED_CODE();
2192
2193 /* Wait for process rundown and then complete it */
2195 ExRundownCompleted(&Process->RundownProtect);
2196
2197 /* Get the object table */
2198 HandleTable = Process->ObjectTable;
2199 if (!HandleTable) return;
2200
2201 /* Disable hard errors while we close handles */
2202 HardErrors = IoSetThreadHardErrorMode(FALSE);
2203
2204 /* Enter a critical region */
2206
2207 /* Fill out the context */
2208 Context.AccessMode = KernelMode;
2209 Context.HandleTable = HandleTable;
2210
2211 /* Sweep the handle table to close all handles */
2214 &Context);
2215 ASSERT(HandleTable->HandleCount == 0);
2216
2217 /* Leave the critical region */
2219
2220 /* Re-enable hard errors */
2221 IoSetThreadHardErrorMode(HardErrors);
2222
2223 /* Destroy the object table */
2224 Process->ObjectTable = NULL;
2226}
2227
2229NTAPI
2232 IN PEPROCESS TargetProcess OPTIONAL,
2238{
2239 HANDLE_TABLE_ENTRY NewHandleEntry;
2240 BOOLEAN AttachedToProcess = FALSE;
2241 PVOID SourceObject;
2242 POBJECT_HEADER ObjectHeader;
2244 HANDLE NewHandle;
2247 ACCESS_MASK TargetAccess, SourceAccess;
2250 AUX_ACCESS_DATA AuxData;
2253 ULONG AuditMask;
2255
2256 PAGED_CODE();
2258 "%s - Duplicating handle: %p for %p into %p\n",
2261 SourceProcess,
2262 TargetProcess);
2263
2264 /* Assume failure */
2266
2267 /* Check if we're not duplicating the same access */
2269 {
2270 /* Validate the desired access */
2271 Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2272 if (!NT_SUCCESS(Status)) return Status;
2273 }
2274
2275 /* Reference the object table */
2278
2279 /* Reference the process object */
2281 SourceProcess,
2284 &SourceObject,
2286 &AuditMask);
2287 if (!NT_SUCCESS(Status))
2288 {
2289 /* Fail */
2290 ObDereferenceProcessHandleTable(SourceProcess);
2291 return Status;
2292 }
2293 else
2294 {
2295 /* Check if we have to don't have to audit object close */
2296 if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2297 {
2298 /* Then there is no audit mask */
2299 AuditMask = 0;
2300 }
2301 }
2302
2303 /* Check if there's no target process */
2304 if (!TargetProcess)
2305 {
2306 /* Check if the caller wanted actual duplication */
2308 {
2309 /* Invalid request */
2311 }
2312 else
2313 {
2314 /* Otherwise, do the attach */
2315 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2316
2317 /* Close the handle and detach */
2320 }
2321
2322 /* Return */
2323 ObDereferenceProcessHandleTable(SourceProcess);
2324 ObDereferenceObject(SourceObject);
2325 return Status;
2326 }
2327
2328 /* Create a kernel handle if asked, but only in the system process */
2329 if (PreviousMode == KernelMode &&
2331 TargetProcess == PsInitialSystemProcess)
2332 {
2334 }
2335
2336 /* Get the target handle table */
2338 if (!HandleTable)
2339 {
2340 /* Check if the caller wanted us to close the handle */
2342 {
2343 /* Do the attach */
2344 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2345
2346 /* Close the handle and detach */
2349 }
2350
2351 /* Return */
2352 ObDereferenceProcessHandleTable(SourceProcess);
2353 ObDereferenceObject(SourceObject);
2355 }
2356
2357 /* Get the source access */
2358 SourceAccess = HandleInformation.GrantedAccess;
2359
2360 /* Check if we're not in the target process */
2361 if (TargetProcess != PsGetCurrentProcess())
2362 {
2363 /* Attach to it */
2364 KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2365 AttachedToProcess = TRUE;
2366 }
2367
2368 /* Check if we're duplicating the attributes */
2370 {
2371 /* Duplicate them */
2372 HandleAttributes = HandleInformation.HandleAttributes;
2373 }
2374 else
2375 {
2376 /* Don't allow caller to bypass auditing */
2377 HandleAttributes |= HandleInformation.HandleAttributes &
2379 }
2380
2381 /* Check if we're duplicating the access */
2382 if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2383
2384 /* Get object data */
2385 ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2386 ObjectType = ObjectHeader->Type;
2387
2388 /* Fill out the entry */
2389 RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2390 NewHandleEntry.Object = ObjectHeader;
2392
2393 /* Check if we're using a generic mask */
2395 {
2396 /* Map it */
2398 &ObjectType->TypeInfo.GenericMapping);
2399 }
2400
2401 /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2402 TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2404 NewHandleEntry.GrantedAccess = TargetAccess;
2405
2406 /* Check if we're asking for new access */
2407 if (TargetAccess & ~SourceAccess)
2408 {
2409 /* We are. We need the security procedure to validate this */
2410 if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2411 {
2412 /* Use our built-in access state */
2415 &AuxData,
2416 TargetAccess,
2417 &ObjectType->TypeInfo.GenericMapping);
2418 }
2419 else
2420 {
2421 /* Otherwise we can't allow this privilege elevation */
2423 }
2424 }
2425 else
2426 {
2427 /* We don't need an access state */
2429 }
2430
2431 /* Make sure the access state was created OK */
2432 if (NT_SUCCESS(Status))
2433 {
2434 /* Add a new handle */
2435 Status = ObpIncrementHandleCount(SourceObject,
2437 &NewHandleEntry.GrantedAccess,
2442 }
2443
2444 /* Check if we were attached */
2445 if (AttachedToProcess)
2446 {
2447 /* We can safely detach now */
2449 AttachedToProcess = FALSE;
2450 }
2451
2452 /* Check if we have to close the source handle */
2454 {
2455 /* Attach and close */
2456 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2459 }
2460
2461 /* Check if we had an access state */
2463
2464 /* Now check if incrementing actually failed */
2465 if (!NT_SUCCESS(Status))
2466 {
2467 /* Dereference handle tables */
2468 ObDereferenceProcessHandleTable(SourceProcess);
2469 ObDereferenceProcessHandleTable(TargetProcess);
2470
2471 /* Dereference the source object */
2472 ObDereferenceObject(SourceObject);
2473 return Status;
2474 }
2475
2476 if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2477 {
2478 NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2479 NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2480 }
2481
2482 /* Now create the handle */
2483 NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2484 if (!NewHandle)
2485 {
2486 /* Undo the increment */
2487 ObpDecrementHandleCount(SourceObject,
2488 TargetProcess,
2489 TargetAccess,
2490 ObjectType);
2491
2492 /* Deference the object and set failure status */
2493 ObDereferenceObject(SourceObject);
2495 }
2496
2497 /* Mark it as a kernel handle if requested */
2498 if (KernelHandle)
2499 {
2500 NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2501 }
2502
2503 /* Return the handle */
2504 if (TargetHandle) *TargetHandle = NewHandle;
2505
2506 /* Dereference handle tables */
2507 ObDereferenceProcessHandleTable(SourceProcess);
2508 ObDereferenceProcessHandleTable(TargetProcess);
2509
2510 /* Return status */
2512 "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2514 NewHandle,
2515 SourceProcess,
2516 TargetProcess,
2517 SourceObject,
2518 ObjectHeader->PointerCount,
2519 ObjectHeader->HandleCount);
2520 return Status;
2521}
2522
2523/* PUBLIC FUNCTIONS *********************************************************/
2524
2525/*++
2526* @name ObOpenObjectByName
2527* @implemented NT4
2528*
2529* The ObOpenObjectByName routine <FILLMEIN>
2530*
2531* @param ObjectAttributes
2532* <FILLMEIN>.
2533*
2534* @param ObjectType
2535* <FILLMEIN>.
2536*
2537* @param AccessMode
2538* <FILLMEIN>.
2539*
2540* @param PassedAccessState
2541* <FILLMEIN>.
2542*
2543* @param DesiredAccess
2544* <FILLMEIN>.
2545*
2546* @param ParseContext
2547* <FILLMEIN>.
2548*
2549* @param Handle
2550* <FILLMEIN>.
2551*
2552* @return <FILLMEIN>.
2553*
2554* @remarks None.
2555*
2556*--*/
2558NTAPI
2564 IN OUT PVOID ParseContext,
2566{
2567 PVOID Object = NULL;
2569 NTSTATUS Status, Status2;
2570 POBJECT_HEADER ObjectHeader;
2572 OB_OPEN_REASON OpenReason;
2573 POB_TEMP_BUFFER TempBuffer;
2574 PAGED_CODE();
2575
2576 /* Assume failure */
2577 *Handle = NULL;
2578
2579 /* Check if we didn't get any Object Attributes */
2580 if (!ObjectAttributes)
2581 {
2582 /* Fail with special status code */
2584 }
2585
2586 /* Allocate the temporary buffer */
2588 sizeof(OB_TEMP_BUFFER),
2590 if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES;
2591
2592 /* Capture all the info */
2594 AccessMode,
2595 AccessMode,
2596 TRUE,
2597 &TempBuffer->ObjectCreateInfo,
2598 &ObjectName);
2599 if (!NT_SUCCESS(Status))
2600 {
2601 /* Fail */
2603 return Status;
2604 }
2605
2606 /* Check if we didn't get an access state */
2607 if (!PassedAccessState)
2608 {
2609 /* Try to get the generic mapping if we can */
2610 if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping;
2611
2612 /* Use our built-in access state */
2613 PassedAccessState = &TempBuffer->LocalAccessState;
2615 &TempBuffer->AuxData,
2618 if (!NT_SUCCESS(Status)) goto Quickie;
2619 }
2620
2621 /* Get the security descriptor */
2622 if (TempBuffer->ObjectCreateInfo.SecurityDescriptor)
2623 {
2624 /* Save it in the access state */
2627 }
2628
2629 /* Validate the access mask */
2631 if (!NT_SUCCESS(Status))
2632 {
2633 /* Cleanup after lookup */
2635 goto Cleanup;
2636 }
2637
2638 /* Now do the lookup */
2640 &ObjectName,
2641 TempBuffer->ObjectCreateInfo.Attributes,
2642 ObjectType,
2643 AccessMode,
2644 ParseContext,
2645 TempBuffer->ObjectCreateInfo.SecurityQos,
2646 NULL,
2648 &TempBuffer->LookupContext,
2649 &Object);
2650 if (!NT_SUCCESS(Status))
2651 {
2652 /* Cleanup after lookup */
2654 goto Cleanup;
2655 }
2656
2657 /* Check if this object has create information */
2658 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2659 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
2660 {
2661 /* Then we are creating a new handle */
2662 OpenReason = ObCreateHandle;
2663
2664 /* Check if we still have create info */
2665 if (ObjectHeader->ObjectCreateInfo)
2666 {
2667 /* Free it */
2668 ObpFreeObjectCreateInformation(ObjectHeader->
2669 ObjectCreateInfo);
2670 ObjectHeader->ObjectCreateInfo = NULL;
2671 }
2672 }
2673 else
2674 {
2675 /* Otherwise, we are merely opening it */
2676 OpenReason = ObOpenHandle;
2677 }
2678
2679 /* Check if we have invalid object attributes */
2680 if (ObjectHeader->Type->TypeInfo.InvalidAttributes &
2681 TempBuffer->ObjectCreateInfo.Attributes)
2682 {
2683 /* Set failure code */
2685
2686 /* Cleanup after lookup */
2688
2689 /* Dereference the object */
2691 }
2692 else
2693 {
2694 /* Create the actual handle now */
2695 Status2 = ObpCreateHandle(OpenReason,
2696 Object,
2697 ObjectType,
2699 0,
2700 TempBuffer->ObjectCreateInfo.Attributes,
2701 &TempBuffer->LookupContext,
2702 AccessMode,
2703 NULL,
2704 Handle);
2705 if (!NT_SUCCESS(Status2))
2706 {
2708 Status = Status2;
2709 }
2710 }
2711
2712Cleanup:
2713 /* Delete the access state */
2714 if (PassedAccessState == &TempBuffer->LocalAccessState)
2715 {
2717 }
2718
2719Quickie:
2720 /* Release the object attributes and temporary buffer */
2724
2725 /* Return status */
2727 "%s - returning Object %p with PC S: %lx %lx\n",
2729 Object,
2730 Object ? OBJECT_TO_OBJECT_HEADER(Object)->PointerCount : -1,
2731 Status);
2732 return Status;
2733}
2734
2735/*++
2736* @name ObOpenObjectByPointer
2737* @implemented NT4
2738*
2739* The ObOpenObjectByPointer routine <FILLMEIN>
2740*
2741* @param Object
2742* <FILLMEIN>.
2743*
2744* @param HandleAttributes
2745* <FILLMEIN>.
2746*
2747* @param PassedAccessState
2748* <FILLMEIN>.
2749*
2750* @param DesiredAccess
2751* <FILLMEIN>.
2752*
2753* @param ObjectType
2754* <FILLMEIN>.
2755*
2756* @param AccessMode
2757* <FILLMEIN>.
2758*
2759* @param Handle
2760* <FILLMEIN>.
2761*
2762* @return <FILLMEIN>.
2763*
2764* @remarks None.
2765*
2766*--*/
2768NTAPI
2776{
2780 AUX_ACCESS_DATA AuxData;
2781 PAGED_CODE();
2782
2783 /* Assume failure */
2784 *Handle = NULL;
2785
2786 /* Reference the object */
2788 0,
2789 ObjectType,
2790 AccessMode);
2791 if (!NT_SUCCESS(Status)) return Status;
2792
2793 /* Get the Header Info */
2795
2796 /* Check if we didn't get an access state */
2797 if (!PassedAccessState)
2798 {
2799 /* Use our built-in access state */
2802 &AuxData,
2804 &Header->Type->TypeInfo.GenericMapping);
2805 if (!NT_SUCCESS(Status))
2806 {
2807 /* Fail */
2809 return Status;
2810 }
2811 }
2812
2813 /* Check if we have invalid object attributes */
2814 if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
2815 {
2816 /* Delete the access state */
2818 {
2820 }
2821
2822 /* Dereference the object */
2825 }
2826
2827 /* Create the handle */
2829 Object,
2830 ObjectType,
2832 0,
2834 NULL,
2835 AccessMode,
2836 NULL,
2837 Handle);
2839
2840 /* Delete the access state */
2842 {
2844 }
2845
2846 /* Return */
2848 "%s - returning Object with PC S: %lx %lx\n",
2850 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
2851 Status);
2852 return Status;
2853}
2854
2855/*++
2856* @name ObFindHandleForObject
2857* @implemented NT4
2858*
2859* The ObFindHandleForObject routine <FILLMEIN>
2860*
2861* @param Process
2862* <FILLMEIN>.
2863*
2864* @param Object
2865* <FILLMEIN>.
2866*
2867* @param ObjectType
2868* <FILLMEIN>.
2869*
2870* @param HandleInformation
2871* <FILLMEIN>.
2872*
2873* @param HandleReturn
2874* <FILLMEIN>.
2875*
2876* @return <FILLMEIN>.
2877*
2878* @remarks None.
2879*
2880*--*/
2881BOOLEAN
2882NTAPI
2884 IN PVOID Object,
2888{
2889 OBP_FIND_HANDLE_DATA FindData;
2891 PVOID ObjectTable;
2892
2893 /* Make sure we have an object table */
2895 if (ObjectTable)
2896 {
2897 /* Check if we have an object */
2898 if (Object)
2899 {
2900 /* Set its header */
2902 }
2903 else
2904 {
2905 /* Otherwise, no object to match*/
2906 FindData.ObjectHeader = NULL;
2907 }
2908
2909 /* Set other information */
2910 FindData.ObjectType = ObjectType;
2912
2913 /* Enumerate the handle table */
2914 if (ExEnumHandleTable(Process->ObjectTable,
2916 &FindData,
2917 Handle))
2918 {
2919 /* Set success */
2920 Result = TRUE;
2921 }
2922
2923 /* Let go of the table */
2925 }
2926
2927 /* Return the result */
2928 return Result;
2929}
2930
2931/*++
2932* @name ObInsertObject
2933* @implemented NT4
2934*
2935* The ObInsertObject routine <FILLMEIN>
2936*
2937* @param Object
2938* <FILLMEIN>.
2939*
2940* @param PassedAccessState
2941* <FILLMEIN>.
2942*
2943* @param DesiredAccess
2944* <FILLMEIN>.
2945*
2946* @param AdditionalReferences
2947* <FILLMEIN>.
2948*
2949* @param ReferencedObject
2950* <FILLMEIN>.
2951*
2952* @param Handle
2953* <FILLMEIN>.
2954*
2955* @return <FILLMEIN>.
2956*
2957* @remarks None.
2958*
2959*--*/
2961NTAPI
2968{
2969 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2970 POBJECT_HEADER ObjectHeader;
2973 PVOID InsertObject;
2974 PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
2975 BOOLEAN SdAllocated = FALSE;
2976 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2978 ACCESS_STATE LocalAccessState;
2979 AUX_ACCESS_DATA AuxData;
2980 OB_OPEN_REASON OpenReason;
2982 NTSTATUS Status = STATUS_SUCCESS, RealStatus;
2983 BOOLEAN IsNewObject;
2984 PAGED_CODE();
2985
2986 /* Get the Header */
2987 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2988
2989 /* Detect invalid insert */
2990 if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO))
2991 {
2992 /* Display warning and break into debugger */
2993 DPRINT1("OB: Attempting to insert existing object %p\n", Object);
2994 DbgBreakPoint();
2995
2996 /* Allow debugger to continue */
2999 }
3000
3001 /* Get the create and name info, as well as the object type */
3002 ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
3003 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
3004 ObjectType = ObjectHeader->Type;
3005 ObjectName = NULL;
3006
3007 /* Check if this is an named object */
3008 if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
3009 {
3010 /* Get the object name */
3011 ObjectName = &ObjectNameInfo->Name;
3012 }
3013
3014 /* Sanity check */
3015 ASSERT((Handle) ||
3016 ((ObjectPointerBias == 0) &&
3017 (ObjectName == NULL) &&
3018 (ObjectType->TypeInfo.SecurityRequired) &&
3019 (NewObject == NULL)));
3020
3021 /* Check if the object is unnamed and also doesn't have security */
3023 if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName))
3024 {
3025 /* Assume failure */
3026 *Handle = NULL;
3027 ObjectHeader->ObjectCreateInfo = NULL;
3028
3029 /* Create the handle */
3033 ObjectCreateInfo->Attributes,
3035 NewObject,
3036 Handle);
3037
3038 /* Free the create information */
3039 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3040
3041 /* Release the object name information */
3042 ObpDereferenceNameInfo(ObjectNameInfo);
3043
3044 /* Remove the extra keep-alive reference */
3046
3047 /* Return */
3049 "%s - returning Object with PC S: %lx %lx\n",
3051 ObjectHeader->PointerCount,
3052 Status);
3053 return Status;
3054 }
3055
3056 /* Check if we didn't get an access state */
3057 if (!AccessState)
3058 {
3059 /* Use our built-in access state */
3060 AccessState = &LocalAccessState;
3061 Status = SeCreateAccessState(&LocalAccessState,
3062 &AuxData,
3064 &ObjectType->TypeInfo.GenericMapping);
3065 if (!NT_SUCCESS(Status))
3066 {
3067 /* Fail */
3068 ObpDereferenceNameInfo(ObjectNameInfo);
3070 return Status;
3071 }
3072 }
3073
3074 /* Save the security descriptor */
3075 AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;
3076
3077 /* Validate the access mask */
3079 if (!NT_SUCCESS(Status))
3080 {
3081 /* Fail */
3082 ObpDereferenceNameInfo(ObjectNameInfo);
3084 return Status;
3085 }
3086
3087 /* Setup a lookup context */
3089 InsertObject = Object;
3090 OpenReason = ObCreateHandle;
3091
3092 /* Check if the object is named */
3093 if (ObjectName)
3094 {
3095 /* Look it up */
3096 Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory,
3097 ObjectName,
3098 ObjectCreateInfo->Attributes,
3099 ObjectType,
3100 (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ?
3102 ObjectCreateInfo->ParseContext,
3103 ObjectCreateInfo->SecurityQos,
3104 Object,
3106 &Context,
3107 &InsertObject);
3108
3109 /* Check if we found an object that doesn't match the one requested */
3110 if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject))
3111 {
3112 /* This means we're opening an object, not creating a new one */
3113 OpenReason = ObOpenHandle;
3114
3115 /* Make sure the caller said it's OK to do this */
3116 if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
3117 {
3118 /* He did, but did he want this type? */
3119 if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type)
3120 {
3121 /* Wrong type, so fail */
3123 }
3124 else
3125 {
3126 /* Right type, so warn */
3128 }
3129 }
3130 else
3131 {
3132 /* Check if this was a symbolic link */
3133 if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
3135 {
3136 /* Dereference it */
3137 ObDereferenceObject(InsertObject);
3138 }
3139
3140 /* Caller wanted to create a new object, fail */
3142 }
3143 }
3144
3145 /* Check if anything until now failed */
3146 if (!NT_SUCCESS(Status))
3147 {
3148 /* Cleanup after lookup */
3150
3151 /* Remove query reference that we added */
3152 ObpDereferenceNameInfo(ObjectNameInfo);
3153
3154 /* Dereference the object and delete the access state */
3156 if (AccessState == &LocalAccessState)
3157 {
3158 /* We used a local one; delete it */
3160 }
3161
3162 /* Return failure code */
3163 return Status;
3164 }
3165 else
3166 {
3167 /* Check if this is a symbolic link */
3169 {
3170 /* Create the internal name */
3172 }
3173 }
3174 }
3175
3176 /* Now check if this object is being created */
3177 if (InsertObject == Object)
3178 {
3179 /* Check if it's named or forces security */
3180 if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired))
3181 {
3182 /* Make sure it's inserted into an object directory */
3183 if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
3184 {
3185 /* Get the current descriptor */
3186 ObGetObjectSecurity(ObjectNameInfo->Directory,
3187 &ParentDescriptor,
3188 &SdAllocated);
3189 }
3190
3191 /* Now assign it */
3193 ParentDescriptor,
3194 Object,
3195 ObjectType);
3196
3197 /* Check if we captured one */
3198 if (ParentDescriptor)
3199 {
3200 /* We did, release it */
3201 ObReleaseObjectSecurity(ParentDescriptor, SdAllocated);
3202 }
3203 else if (NT_SUCCESS(Status))
3204 {
3205 /* Other we didn't, but we were able to use the current SD */
3207 ObjectCreateInfo->ProbeMode,
3208 TRUE);
3209
3210 /* Clear the current one */
3211 AccessState->SecurityDescriptor =
3212 ObjectCreateInfo->SecurityDescriptor = NULL;
3213 }
3214 }
3215
3216 /* Check if anything until now failed */
3217 if (!NT_SUCCESS(Status))
3218 {
3219 /* Check if the directory was added */
3220 if (Context.DirectoryLocked)
3221 {
3222 /* Weird case where we need to do a manual delete */
3223 DPRINT1("Unhandled path\n");
3224 ASSERT(FALSE);
3225 }
3226
3227 /* Cleanup the lookup */
3229
3230 /* Remove query reference that we added */
3231 ObpDereferenceNameInfo(ObjectNameInfo);
3232
3233 /* Dereference the object and delete the access state */
3235 if (AccessState == &LocalAccessState)
3236 {
3237 /* We used a local one; delete it */
3239 }
3240
3241 /* Return failure code */
3242 ASSERT(FALSE);
3243 return Status;
3244 }
3245 }
3246
3247 /* Save the actual status until here */
3248 RealStatus = Status;
3249
3250 /* Check if caller wants us to create a handle */
3251 ObjectHeader->ObjectCreateInfo = NULL;
3252 if (Handle)
3253 {
3254 /* Create the handle */
3255 Status = ObpCreateHandle(OpenReason,
3256 InsertObject,
3257 NULL,
3260 ObjectCreateInfo->Attributes,
3261 &Context,
3263 NewObject,
3264 Handle);
3265 if (!NT_SUCCESS(Status))
3266 {
3267 /* If the object had a name, backout everything */
3269
3270 /* Return the status of the failure */
3271 *Handle = NULL;
3272 RealStatus = Status;
3273 }
3274
3275 /* Remove a query reference */
3276 ObpDereferenceNameInfo(ObjectNameInfo);
3277
3278 /* Remove the extra keep-alive reference */
3280 }
3281 else
3282 {
3283 /* Otherwise, lock the object */
3284 ObpAcquireObjectLock(ObjectHeader);
3285
3286 /* And charge quota for the process to make it appear as used */
3287 RealStatus = ObpChargeQuotaForObject(ObjectHeader,
3288 ObjectType,
3289 &IsNewObject);
3290
3291 /* Release the lock */
3292 ObpReleaseObjectLock(ObjectHeader);
3293
3294 /* Check if we failed and dereference the object if so */
3295 if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
3296 }
3297
3298 /* We can delete the Create Info now */
3299 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3300
3301 /* Check if we created our own access state and delete it if so */
3302 if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState);
3303
3304 /* Return status code */
3306 "%s - returning Object with PC RS/S: %lx %lx %lx\n",
3308 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
3309 RealStatus, Status);
3310 return RealStatus;
3311}
3312
3340NTAPI
3345{
3346 OBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleAttributesContext;
3347 BOOLEAN Result, AttachedToProcess = FALSE;
3350
3351 PAGED_CODE();
3352
3353 /* Check if this is a kernel handle */
3355 {
3356 /* Use the kernel table and convert the handle */
3359
3360 /* Check if we're not in the system process */
3362 {
3363 /* Attach to the system process */
3365 AttachedToProcess = TRUE;
3366 }
3367 }
3368 else
3369 {
3370 /* Get the current process' handle table */
3371 HandleTable = PsGetCurrentProcess()->ObjectTable;
3372 }
3373
3374 /* Initialize the handle attribute context */
3375 SetHandleAttributesContext.PreviousMode = PreviousMode;
3376 SetHandleAttributesContext.Information = *HandleFlags;
3377
3378 /* Invoke the ObpSetHandleAttributes callback */
3380 Handle,
3382 (ULONG_PTR)&SetHandleAttributesContext);
3383
3384 /* Detach from the system process if needed */
3385 if (AttachedToProcess)
3387
3388 /* Return the result as an NTSTATUS value */
3390}
3391
3392/*++
3393* @name ObCloseHandle
3394* @implemented NT5.1
3395*
3396* The ObCloseHandle routine <FILLMEIN>
3397*
3398* @param Handle
3399* <FILLMEIN>.
3400*
3401* @param AccessMode
3402* <FILLMEIN>.
3403*
3404* @return <FILLMEIN>.
3405*
3406* @remarks None.
3407*
3408*--*/
3410NTAPI
3413{
3414 /* Call the internal API */
3416}
3417
3418/*++
3419* @name NtClose
3420* @implemented NT4
3421*
3422* The NtClose routine <FILLMEIN>
3423*
3424* @param Handle
3425* <FILLMEIN>.
3426*
3427* @return <FILLMEIN>.
3428*
3429* @remarks None.
3430*
3431*--*/
3433NTAPI
3435{
3436 /* Call the internal API */
3438}
3439
3441NTAPI
3442NtDuplicateObject(IN HANDLE SourceProcessHandle,
3449{
3450 PEPROCESS SourceProcess, TargetProcess, Target;
3451 HANDLE hTarget;
3455 "%s - Duplicating handle: %p for %p into %p.\n",
3458 SourceProcessHandle,
3460
3461 /* Check if we have a target handle */
3462 if ((TargetHandle) && (PreviousMode != KernelMode))
3463 {
3464 /* Enter SEH */
3465 _SEH2_TRY
3466 {
3467 /* Probe the handle and assume failure */
3469 *TargetHandle = NULL;
3470 }
3472 {
3473 /* Return the exception code */
3475 }
3476 _SEH2_END;
3477 }
3478
3479 /* Now reference the input handle */
3480 Status = ObReferenceObjectByHandle(SourceProcessHandle,
3484 (PVOID*)&SourceProcess,
3485 NULL);
3486 if (!NT_SUCCESS(Status)) return Status;
3487
3488 /* Check if got a target handle */
3490 {
3491 /* Now reference the output handle */
3496 (PVOID*)&TargetProcess,
3497 NULL);
3498 if (NT_SUCCESS(Status))
3499 {
3500 /* Use this target process */
3501 Target = TargetProcess;
3502 }
3503 else
3504 {
3505 /* No target process */
3506 Target = NULL;
3507 }
3508 }
3509 else
3510 {
3511 /* No target process */
3513 Target = NULL;
3514 }
3515
3516 /* Call the internal routine */
3517 Status = ObDuplicateObject(SourceProcess,
3519 Target,
3520 &hTarget,
3523 Options,
3524 PreviousMode);
3525
3526 /* Check if the caller wanted the return handle */
3527 if (TargetHandle)
3528 {
3529 /* Protect the write to user mode */
3530 _SEH2_TRY
3531 {
3532 /* Write the new handle */
3533 *TargetHandle = hTarget;
3534 }
3536 {
3537 /* Otherwise, get the exception code */
3539 }
3540 _SEH2_END;
3541 }
3542
3543 /* Dereference the processes */
3545 "%s - Duplicated handle: %p into %p S %lx\n",
3547 hTarget,
3549 Status);
3551 ObDereferenceObject(SourceProcess);
3552 return Status;
3553}
3554
3555BOOLEAN
3556NTAPI
3558{
3559 /* Use the inlined version. We know we are in kernel mode. */
3561}
3562
3563/* 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:447
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:449
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:451
_In_ HANDLE _In_opt_ HANDLE TargetProcessHandle
Definition: obfuncs.h:448
#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:1751
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:892
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:1114
static NTSTATUS ObpIncrementHandleCount(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN OUT PACCESS_MASK GrantedAccess, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
Definition: obhandle.c:811
BOOLEAN NTAPI ObIsKernelHandle(IN HANDLE Handle)
Definition: obhandle.c:3557
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3411
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2186
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:1898
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:1342
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:3341
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:2962
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:1953
NTSTATUS NTAPI ObpCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:1756
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:2230
NTSTATUS NTAPI ObpValidateAccessMask(IN PACCESS_STATE AccessState)
Definition: obhandle.c:488
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2053
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:3442
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2883
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3434
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:1989
NTSTATUS NTAPI ObpIncrementHandleDataBase(IN POBJECT_HEADER ObjectHeader, IN PEPROCESS Process, IN OUT PULONG NewProcessHandleCount)
Definition: obhandle.c:333
static 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:1528
NTSTATUS NTAPI ObInitProcess(IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Process)
Definition: obhandle.c:2116
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:2769
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:2559
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:2325
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:1467
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:374
KPROCESSOR_MODE ProbeMode
Definition: obtypes.h:370
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: obtypes.h:375
OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]
Definition: obtypes.h:481
Definition: obtypes.h:473
ULONG HandleCount
Definition: obtypes.h:475
struct _EPROCESS * Process
Definition: obtypes.h:474
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:488
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:489
POBJECT_DIRECTORY Directory
Definition: obtypes.h:462
UNICODE_STRING Name
Definition: obtypes.h:463
UCHAR Flags
Definition: obtypes.h:527
LONG_PTR HandleCount
Definition: obtypes.h:520
LONG_PTR PointerCount
Definition: obtypes.h:517
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:530
POBJECT_TYPE Type
Definition: obtypes.h:523
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:420
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