ReactOS 0.4.15-dev-7788-g1ad9096
oblife.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/oblife.c
5 * PURPOSE: Manages the lifetime of an Object, including its creation,
6 * and deletion, as well as setting or querying any of its
7 * information while it is active. Since Object Types are also
8 * Objects, those are also managed here.
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
20extern ULONG NtGlobalFlag;
21
25
27
30
34
35/* PRIVATE FUNCTIONS *********************************************************/
36
37VOID
40{
41 PVOID HeaderLocation;
48 ULONG PagedPoolCharge, NonPagedPoolCharge;
49 PAGED_CODE();
50
51 /* Get the header and assume this is what we'll free */
53 ObjectType = Header->Type;
54 HeaderLocation = Header;
55
56 /* To find the header, walk backwards from how we allocated */
57 if ((CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header)))
58 {
59 HeaderLocation = CreatorInfo;
60 }
61 if ((NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header)))
62 {
63 HeaderLocation = NameInfo;
64 }
65 if ((HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(Header)))
66 {
67 HeaderLocation = HandleInfo;
68 }
69 if ((QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO(Header)))
70 {
71 HeaderLocation = QuotaInfo;
72 }
73
74 /* Decrease the total */
75 InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfObjects);
76
77 /* Check if we have create info */
78 if (Header->Flags & OB_FLAG_CREATE_INFO)
79 {
80 /* Double-check that it exists */
81 if (Header->ObjectCreateInfo)
82 {
83 /* Free it */
84 ObpFreeObjectCreateInformation(Header->ObjectCreateInfo);
85 Header->ObjectCreateInfo = NULL;
86 }
87 }
88 else
89 {
90 /* Check if it has a quota block */
91 if (Header->QuotaBlockCharged)
92 {
93 /* Check if we have quota information */
94 if (QuotaInfo)
95 {
96 /* Get charges from quota information */
97 PagedPoolCharge = QuotaInfo->PagedPoolCharge +
98 QuotaInfo->SecurityDescriptorCharge;
99 NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;
100 }
101 else
102 {
103 /* Get charges from object type */
104 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
105 NonPagedPoolCharge = ObjectType->
106 TypeInfo.DefaultNonPagedPoolCharge;
107
108 /* Add the SD charge too */
109 if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048;
110 }
111
112 /* Return the quota */
113 if (Header->QuotaBlockCharged != OBP_SYSTEM_PROCESS_QUOTA)
114 {
115 PsReturnSharedPoolQuota(Header->QuotaBlockCharged,
116 PagedPoolCharge,
117 NonPagedPoolCharge);
118 }
119 }
120 }
121
122 /* Check if a handle database was active */
123 if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
124 {
125 /* Free it */
126 ExFreePool(HandleInfo->HandleCountDatabase);
127 HandleInfo->HandleCountDatabase = NULL;
128 }
129
130 /* Check if we have a name */
131 if ((NameInfo) && (NameInfo->Name.Buffer))
132 {
133 /* Free it */
134 ExFreePool(NameInfo->Name.Buffer);
135 NameInfo->Name.Buffer = NULL;
136 }
137
138 /* Catch invalid access */
139 Header->Type = (POBJECT_TYPE)(ULONG_PTR)0xBAADB0B0BAADB0B0ULL;
140
141 /* Free the object using the same allocation tag */
142 ExFreePoolWithTag(HeaderLocation, ObjectType->Key);
143}
144
145VOID
146NTAPI
148 IN BOOLEAN CalledFromWorkerThread)
149{
153 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
154 KIRQL CalloutIrql;
155 PAGED_CODE();
156
157 /* Get the header and type */
159 ObjectType = Header->Type;
160
161 /* Get creator and name information */
164
165 /* Check if the object is on a type list */
166 if ((CreatorInfo) && !(IsListEmpty(&CreatorInfo->TypeList)))
167 {
168 /* Lock the object type */
170
171 /* Remove the object from the type list */
172 RemoveEntryList(&CreatorInfo->TypeList);
173
174 /* Release the lock */
176 }
177
178 /* Check if we have a name */
179 if ((NameInfo) && (NameInfo->Name.Buffer))
180 {
181 /* Free it */
182 ExFreePool(NameInfo->Name.Buffer);
183 RtlInitEmptyUnicodeString(&NameInfo->Name, NULL, 0);
184 }
185
186 /* Check if we have a security descriptor */
187 if (Header->SecurityDescriptor)
188 {
189 /* Call the security procedure to delete it */
190 ObpCalloutStart(&CalloutIrql);
191 ObjectType->TypeInfo.SecurityProcedure(Object,
192 DeleteSecurityDescriptor,
193 0,
194 NULL,
195 NULL,
196 &Header->SecurityDescriptor,
197 0,
198 NULL);
199 ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object);
200 }
201
202 /* Check if we have a delete procedure */
203 if (ObjectType->TypeInfo.DeleteProcedure)
204 {
205 /* Save whether we were deleted from worker thread or not */
206 if (!CalledFromWorkerThread) Header->Flags |= OB_FLAG_DEFER_DELETE;
207
208 /* Call it */
209 ObpCalloutStart(&CalloutIrql);
210 ObjectType->TypeInfo.DeleteProcedure(Object);
211 ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object);
212 }
213
214 /* Now de-allocate all object members */
216}
217
218VOID
219NTAPI
221{
222 POBJECT_HEADER ReapObject, NextObject;
223
224 /* Start reaping */
225 do
226 {
227 /* Get the reap object */
229
230 /* Start deletion loop */
231 do
232 {
233 /* Get the next object */
234 NextObject = ReapObject->NextToFree;
235
236 /* Delete the object */
237 ObpDeleteObject(&ReapObject->Body, TRUE);
238
239 /* Move to the next one */
240 ReapObject = NextObject;
241 } while ((ReapObject) && (ReapObject != (PVOID)1));
242 } while ((ObpReaperList != (PVOID)1) ||
244}
245
246/*++
247* @name ObpSetPermanentObject
248*
249* The ObpSetPermanentObject routine makes an sets or clears the permanent
250* flag of an object, thus making it either permanent or temporary.
251*
252* @param ObjectBody
253* Pointer to the object to make permanent or temporary.
254*
255* @param Permanent
256* Flag specifying which operation to perform.
257*
258* @return None.
259*
260* @remarks If the object is being made temporary, then it will be checked
261* as a candidate for immediate removal from the namespace.
262*
263*--*/
264VOID
267 IN BOOLEAN Permanent)
268{
269 POBJECT_HEADER ObjectHeader;
270
271 /* Get the header */
272 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
273
274 /* Acquire object lock */
275 ObpAcquireObjectLock(ObjectHeader);
276
277 /* Check what we're doing to it */
278 if (Permanent)
279 {
280 /* Set it to permanent */
281 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
282
283 /* Release the lock */
284 ObpReleaseObjectLock(ObjectHeader);
285 }
286 else
287 {
288 /* Remove the flag */
289 ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
290
291 /* Release the lock */
292 ObpReleaseObjectLock(ObjectHeader);
293
294 /* Check if we should delete the object now */
295 ObpDeleteNameCheck(ObjectBody);
296 }
297}
298
299PWCHAR
300NTAPI
302 IN BOOLEAN UseLookaside,
304{
307
308 /* Set the maximum length to the length plus the terminator */
310
311 /* Check if we should use the lookaside buffer */
312 if (!(UseLookaside) || (MaximumLength > OBP_NAME_LOOKASIDE_MAX_SIZE))
313 {
314 /* Nope, allocate directly from pool */
315 /* Since we later use MaximumLength to detect that we're not allocating
316 * from a list, we need at least MaximumLength + sizeof(UNICODE_NULL)
317 * here.
318 *
319 * People do call this with UseLookasideList FALSE so the distinction
320 * is critical.
321 */
323 {
325 }
329 }
330 else
331 {
332 /* Allocate from the lookaside */
335 }
336
337 /* Setup the string */
338 ObjectName->MaximumLength = (USHORT)MaximumLength;
339 ObjectName->Length = (USHORT)Length;
340 ObjectName->Buffer = Buffer;
341 return Buffer;
342}
343
344VOID
345NTAPI
347{
348 PVOID Buffer = Name->Buffer;
349
350 /* We know this is a pool-allocation if the size doesn't match */
351 if (Name->MaximumLength != OBP_NAME_LOOKASIDE_MAX_SIZE)
352 {
353 /*
354 * Free it from the pool.
355 *
356 * We cannot use here ExFreePoolWithTag(..., OB_NAME_TAG); , because
357 * the object name may have been massaged during operation by different
358 * object parse routines. If the latter ones have to resolve a symbolic
359 * link (e.g. as is done by CmpParseKey() and CmpGetSymbolicLink()),
360 * the original object name is freed and re-allocated from the pool,
361 * possibly with a different pool tag. At the end of the day, the new
362 * object name can be reallocated and completely different, but we
363 * should still be able to free it!
364 */
366 }
367 else
368 {
369 /* Otherwise, free from the lookaside */
371 }
372}
373
375NTAPI
379 IN BOOLEAN UseLookaside)
380{
382 ULONG StringLength;
384 UNICODE_STRING LocalName;
385 PAGED_CODE();
386
387 /* Initialize the Input String */
388 RtlInitEmptyUnicodeString(CapturedName, NULL, 0);
389
390 /* Protect everything */
392 {
393 /* Check if we came from user mode */
394 if (AccessMode != KernelMode)
395 {
396 /* First Probe the String */
398 ProbeForRead(LocalName.Buffer, LocalName.Length, sizeof(WCHAR));
399 }
400 else
401 {
402 /* No probing needed */
403 LocalName = *ObjectName;
404 }
405
406 /* Make sure there really is a string */
407 StringLength = LocalName.Length;
408 if (StringLength)
409 {
410 /* Check that the size is a valid WCHAR multiple */
411 if ((StringLength & (sizeof(WCHAR) - 1)) ||
412 /* Check that the NULL-termination below will work */
413 (StringLength == (MAXUSHORT - sizeof(UNICODE_NULL) + 1)))
414 {
415 /* PS: Please keep the checks above expanded for clarity */
417 }
418 else
419 {
420 /* Allocate the string buffer */
422 UseLookaside,
423 CapturedName);
424 if (!StringBuffer)
425 {
426 /* Set failure code */
428 }
429 else
430 {
431 /* Copy the name */
432 RtlCopyMemory(StringBuffer, LocalName.Buffer, StringLength);
433 StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
434 }
435 }
436 }
437 }
439 {
440 /* Handle exception and free the string buffer */
442 if (StringBuffer)
443 {
444 ObpFreeObjectNameBuffer(CapturedName);
445 }
446 }
447 _SEH2_END;
448
449 /* Return */
450 return Status;
451}
452
454NTAPI
457 IN KPROCESSOR_MODE CreatorMode,
458 IN BOOLEAN AllocateFromLookaside,
459 IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
461{
462 ULONG SdCharge, QuotaInfoSize;
466 PUNICODE_STRING LocalObjectName = NULL;
467 PAGED_CODE();
468
469 /* Zero out the Capture Data */
470 RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
471
472 /* SEH everything here for protection */
474 {
475 /* Check if we got attributes */
477 {
478 /* Check if we're in user mode */
479 if (AccessMode != KernelMode)
480 {
481 /* Probe the attributes */
483 sizeof(OBJECT_ATTRIBUTES),
484 sizeof(ULONG));
485 }
486
487 /* Validate the Size and Attributes */
488 if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
490 {
491 /* Invalid combination, fail */
493 }
494
495 /* Set some Create Info and do not allow user-mode kernel handles */
496 ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
497 ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_KERNEL_ATTRIBUTES;
498 if (CreatorMode != KernelMode) ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
499 LocalObjectName = ObjectAttributes->ObjectName;
500 SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
501 SecurityQos = ObjectAttributes->SecurityQualityOfService;
502
503 /* Check if we have a security descriptor */
505 {
506 /* Capture it. Note: This has an implicit memory barrier due
507 to the function call, so cleanup is safe here.) */
511 TRUE,
512 &ObjectCreateInfo->
514 if (!NT_SUCCESS(Status))
515 {
516 /* Capture failed, quit */
517 ObjectCreateInfo->SecurityDescriptor = NULL;
518 _SEH2_YIELD(return Status);
519 }
520
521 /*
522 * By default, assume a SD size of 1024 and allow twice its
523 * size.
524 * If SD size happen to be bigger than that, then allow it
525 */
526 SdCharge = 2048;
527 SeComputeQuotaInformationSize(ObjectCreateInfo->SecurityDescriptor,
528 &QuotaInfoSize);
529 if ((2 * QuotaInfoSize) > 2048)
530 {
531 SdCharge = 2 * QuotaInfoSize;
532 }
533
534 /* Save the probe mode and security descriptor size */
535 ObjectCreateInfo->SecurityDescriptorCharge = SdCharge;
536 ObjectCreateInfo->ProbeMode = AccessMode;
537 }
538
539 /* Check if we have QoS */
540 if (SecurityQos)
541 {
542 /* Check if we came from user mode */
543 if (AccessMode != KernelMode)
544 {
545 /* Validate the QoS */
546 ProbeForRead(SecurityQos,
548 sizeof(ULONG));
549 }
550
551 /* Save Info */
552 ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
553 ObjectCreateInfo->SecurityQos =
554 &ObjectCreateInfo->SecurityQualityOfService;
555 }
556 }
557 else
558 {
559 /* We don't have a name */
560 LocalObjectName = NULL;
561 }
562 }
564 {
565 /* Cleanup and return the exception code */
566 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
568 }
569 _SEH2_END;
570
571 /* Now check if the Object Attributes had an Object Name */
572 if (LocalObjectName)
573 {
575 LocalObjectName,
577 AllocateFromLookaside);
578 }
579 else
580 {
581 /* Clear the string */
582 RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
583
584 /* It cannot have specified a Root Directory */
585 if (ObjectCreateInfo->RootDirectory)
586 {
588 }
589 }
590
591 /* Cleanup if we failed */
592 if (!NT_SUCCESS(Status))
593 {
594 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
595 }
596
597 /* Return status to caller */
598 return Status;
599}
600
601VOID
602NTAPI
604{
605 /* Call the macro. We use this function to isolate Ob internals from Io */
607}
608
610NTAPI
614 IN ULONG ObjectSize,
616 IN POBJECT_HEADER *ObjectHeader)
617{
619 ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
622 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
625 ULONG FinalSize;
626 ULONG Tag;
627 PAGED_CODE();
628
629 /* Accounting */
631
632 /* Check if we don't have an Object Type yet */
633 if (!ObjectType)
634 {
635 /* Use default tag and non-paged pool */
638 }
639 else
640 {
641 /* Use the pool and tag given */
642 PoolType = ObjectType->TypeInfo.PoolType;
643 Tag = ObjectType->Key;
644 }
645
646 /* Check if we have no create information (ie: we're an object type) */
647 if (!ObjectCreateInfo)
648 {
649 /* Use defaults */
650 QuotaSize = HandleSize = 0;
651 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
652 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
653 }
654 else
655 {
656 /* Check if we have quota */
657 if ((((ObjectCreateInfo->PagedPoolCharge !=
658 ObjectType->TypeInfo.DefaultPagedPoolCharge) ||
659 (ObjectCreateInfo->NonPagedPoolCharge !=
660 ObjectType->TypeInfo.DefaultNonPagedPoolCharge) ||
661 (ObjectCreateInfo->SecurityDescriptorCharge > 2048)) &&
663 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
664 {
665 /* Set quota size */
666 QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO);
668 }
669 else
670 {
671 /* No Quota */
672 QuotaSize = 0;
673 }
674
675 /* Check if we have a handle database */
676 if (ObjectType->TypeInfo.MaintainHandleCount)
677 {
678 /* Set handle database size */
679 HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO);
681 }
682 else
683 {
684 /* None */
685 HandleSize = 0;
686 }
687
688 /* Check if the Object has a name */
689 if (ObjectName->Buffer)
690 {
691 /* Set name size */
692 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
694 }
695 else
696 {
697 /* No name */
698 NameSize = 0;
699 }
700
701 /* Check if the Object maintains type lists */
702 if (ObjectType->TypeInfo.MaintainTypeList)
703 {
704 /* Set owner/creator size */
705 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
707 }
708 else
709 {
710 /* No info */
711 CreatorSize = 0;
712 }
713 }
714
715 /* Set final header size */
716 FinalSize = QuotaSize +
717 HandleSize +
718 NameSize +
719 CreatorSize +
721
722 /* Allocate memory for the Object and Header */
723 Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
725
726 /* Check if we have a quota header */
727 if (QuotaSize)
728 {
729 /* Initialize quota info */
731 QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge;
732 QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge;
733 QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge;
734 QuotaInfo->ExclusiveProcess = NULL;
735 Header = (POBJECT_HEADER)(QuotaInfo + 1);
736 }
737
738 /* Check if we have a handle database header */
739 if (HandleSize)
740 {
741 /* Initialize Handle Info */
743 HandleInfo->SingleEntry.HandleCount = 0;
744 Header = (POBJECT_HEADER)(HandleInfo + 1);
745 }
746
747 /* Check if we have a name header */
748 if (NameSize)
749 {
750 /* Initialize the Object Name Info */
752 NameInfo->Name = *ObjectName;
753 NameInfo->Directory = NULL;
754 NameInfo->QueryReferences = 1;
755
756 /* Check if this is a call with the special protection flag */
757 if ((PreviousMode == KernelMode) &&
758 (ObjectCreateInfo) &&
759 (ObjectCreateInfo->Attributes & OBJ_KERNEL_EXCLUSIVE))
760 {
761 /* Set flag which will make the object protected from user-mode */
763 }
764
765 /* Set the header pointer */
766 Header = (POBJECT_HEADER)(NameInfo + 1);
767 }
768
769 /* Check if we have a creator header */
770 if (CreatorSize)
771 {
772 /* Initialize Creator Info */
773 CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
774 CreatorInfo->CreatorBackTraceIndex = 0;
776 InitializeListHead(&CreatorInfo->TypeList);
777 Header = (POBJECT_HEADER)(CreatorInfo + 1);
778 }
779
780 /* Check for quota information */
781 if (QuotaSize)
782 {
783 /* Set the offset */
784 Header->QuotaInfoOffset = (UCHAR)(QuotaSize +
785 HandleSize +
786 NameSize +
787 CreatorSize);
788 }
789 else
790 {
791 /* No offset */
792 Header->QuotaInfoOffset = 0;
793 }
794
795 /* Check for handle information */
796 if (HandleSize)
797 {
798 /* Set the offset */
799 Header->HandleInfoOffset = (UCHAR)(HandleSize +
800 NameSize +
801 CreatorSize);
802 }
803 else
804 {
805 /* No offset */
806 Header->HandleInfoOffset = 0;
807 }
808
809 /* Check for name information */
810 if (NameSize)
811 {
812 /* Set the offset */
813 Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize);
814 }
815 else
816 {
817 /* No Name */
818 Header->NameInfoOffset = 0;
819 }
820
821 /* Set the new object flag */
823
824 /* Remember if we have creator info */
825 if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO;
826
827 /* Remember if we have handle info */
828 if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS;
829
830 /* Initialize the object header */
831 Header->PointerCount = 1;
832 Header->HandleCount = 0;
833 Header->Type = ObjectType;
834 Header->ObjectCreateInfo = ObjectCreateInfo;
835 Header->SecurityDescriptor = NULL;
836
837 /* Check if this is a permanent object */
838 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
839 {
840 /* Set the needed flag so we can check */
841 Header->Flags |= OB_FLAG_PERMANENT;
842 }
843
844 /* Check if this is an exclusive object */
845 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
846 {
847 /* Set the needed flag so we can check */
848 Header->Flags |= OB_FLAG_EXCLUSIVE;
849 }
850
851 /* Set kernel-mode flag */
853
854 /* Check if we have a type */
855 if (ObjectType)
856 {
857 /* Increase the number of objects of this type */
858 InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfObjects);
859
860 /* Update the high water */
861 ObjectType->HighWaterNumberOfObjects = max(ObjectType->
862 TotalNumberOfObjects,
863 ObjectType->
864 HighWaterNumberOfObjects);
865 }
866
867 /* Return Header */
868 *ObjectHeader = Header;
869 return STATUS_SUCCESS;
870}
871
888static
889ULONG
891 _In_ POBJECT_HEADER ObjectHeader)
892{
893 ULONG NameSize = 0;
896 PAGED_CODE();
897
898 /* Get the name info */
899 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
900 if (!NameInfo)
901 {
902 return 0;
903 }
904
905 /* Get the parent directory from the object name too */
906 ParentDirectory = NameInfo->Directory;
907 if (!ParentDirectory)
908 {
909 return 0;
910 }
911
912 /* Take into account the name size of this object and loop for all parent directories */
913 NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
914 for (;;)
915 {
916 /* Get the name info from the parent directory */
919 if (!NameInfo)
920 {
921 /* Stop looking if this is the last one */
922 break;
923 }
924
925 /* Get the parent directory */
926 ParentDirectory = NameInfo->Directory;
927 if (!ParentDirectory)
928 {
929 /* This is the last directory, stop looking */
930 break;
931 }
932
933 /*
934 * Take into account the size of this name info,
935 * keep looking for other parent directories.
936 */
937 NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
938 }
939
940 /* Include the size of the object name information as well as the NULL terminator */
941 NameSize += sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
942 return NameSize;
943}
944
946NTAPI
950 POBJECT_TYPE_INFORMATION ObjectTypeInfo,
953{
955 PWSTR InfoBuffer;
956
957 /* The string of the object type name has to be NULL-terminated */
958 ASSERT(ObjectType->Name.MaximumLength >= ObjectType->Name.Length + sizeof(UNICODE_NULL));
959
960 /* Enter SEH */
962 {
963 /*
964 * Set return length aligned to 4-byte or 8-byte boundary. Windows has a bug
965 * where the returned length pointer is always aligned to a 4-byte boundary.
966 * If one were to allocate a pool of memory in kernel mode to retrieve all
967 * the object types info with this return length, Windows will bugcheck with
968 * BAD_POOL_HEADER in 64-bit upon you free the said allocated memory.
969 *
970 * More than that, Windows uses MaximumLength for the calculation of the returned
971 * length and MaximumLength does not always guarantee the name type is NULL-terminated
972 * leading the ObQueryTypeInfo function to overrun the buffer.
973 */
974 *ReturnLength += sizeof(*ObjectTypeInfo) +
975 ALIGN_UP(ObjectType->Name.Length + sizeof(UNICODE_NULL), ULONG_PTR);
976
977 /* Check if that is too much */
978 if (Length < *ReturnLength)
979 {
981 }
982
983 /* Build the data */
984 ObjectTypeInfo->TotalNumberOfHandles =
985 ObjectType->TotalNumberOfHandles;
986 ObjectTypeInfo->TotalNumberOfObjects =
987 ObjectType->TotalNumberOfObjects;
988 ObjectTypeInfo->HighWaterNumberOfHandles =
989 ObjectType->HighWaterNumberOfHandles;
990 ObjectTypeInfo->HighWaterNumberOfObjects =
991 ObjectType->HighWaterNumberOfObjects;
992 ObjectTypeInfo->PoolType =
993 ObjectType->TypeInfo.PoolType;
994 ObjectTypeInfo->DefaultNonPagedPoolCharge =
995 ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
996 ObjectTypeInfo->DefaultPagedPoolCharge =
997 ObjectType->TypeInfo.DefaultPagedPoolCharge;
998 ObjectTypeInfo->ValidAccessMask =
999 ObjectType->TypeInfo.ValidAccessMask;
1000 ObjectTypeInfo->SecurityRequired =
1001 ObjectType->TypeInfo.SecurityRequired;
1002 ObjectTypeInfo->InvalidAttributes =
1003 ObjectType->TypeInfo.InvalidAttributes;
1004 ObjectTypeInfo->GenericMapping =
1005 ObjectType->TypeInfo.GenericMapping;
1006 ObjectTypeInfo->MaintainHandleCount =
1007 ObjectType->TypeInfo.MaintainHandleCount;
1008
1009 /* Setup the name buffer */
1010 InfoBuffer = (PWSTR)(ObjectTypeInfo + 1);
1011 ObjectTypeInfo->TypeName.Buffer = InfoBuffer;
1012 ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength;
1013 ObjectTypeInfo->TypeName.Length = ObjectType->Name.Length;
1014
1015 /* Copy it */
1016 RtlCopyMemory(InfoBuffer,
1017 ObjectType->Name.Buffer,
1018 ObjectType->Name.Length);
1019
1020 /* Null-terminate it */
1021 (InfoBuffer)[ObjectType->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
1022 }
1024 {
1025 /* Otherwise, get the exception code */
1027 }
1028 _SEH2_END;
1029
1030 /* Return status to caller */
1031 return Status;
1032}
1033
1034
1035/* PUBLIC FUNCTIONS **********************************************************/
1036
1038NTAPI
1043 IN OUT PVOID ParseContext OPTIONAL,
1044 IN ULONG ObjectSize,
1045 IN ULONG PagedPoolCharge OPTIONAL,
1046 IN ULONG NonPagedPoolCharge OPTIONAL,
1047 OUT PVOID *Object)
1048{
1050 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
1053
1054 /* Allocate a capture buffer */
1056 if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
1057
1058 /* Capture all the info */
1060 ProbeMode,
1061 AccessMode,
1062 FALSE,
1063 ObjectCreateInfo,
1064 &ObjectName);
1065 if (NT_SUCCESS(Status))
1066 {
1067 /* Validate attributes */
1068 if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
1069 {
1070 /* Fail */
1072 }
1073 else
1074 {
1075 /* Check if we have a paged charge */
1076 if (!PagedPoolCharge)
1077 {
1078 /* Save it */
1079 PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
1080 }
1081
1082 /* Check for nonpaged charge */
1083 if (!NonPagedPoolCharge)
1084 {
1085 /* Save it */
1086 NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1087 }
1088
1089 /* Write the pool charges */
1090 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1091 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1092
1093 /* Allocate the Object */
1094 Status = ObpAllocateObject(ObjectCreateInfo,
1095 &ObjectName,
1096 Type,
1097 ObjectSize,
1098 AccessMode,
1099 &Header);
1100 if (NT_SUCCESS(Status))
1101 {
1102 /* Return the Object */
1103 *Object = &Header->Body;
1104
1105 /* Check if this is a permanent object */
1106 if (Header->Flags & OB_FLAG_PERMANENT)
1107 {
1108 /* Do the privilege check */
1110 ProbeMode))
1111 {
1112 /* Fail */
1115 }
1116 }
1117
1118 /* Return status */
1119 return Status;
1120 }
1121 }
1122
1123 /* Release the Capture Info, we don't need it */
1124 ObpFreeObjectCreateInformation(ObjectCreateInfo);
1126 return Status;
1127 }
1128
1129 /* We failed, so release the Buffer */
1131 return Status;
1132}
1133
1135NTAPI
1137 IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
1140{
1142 POBJECT_TYPE LocalObjectType;
1143 ULONG HeaderSize;
1146 PWCHAR p;
1147 ULONG i;
1149 ANSI_STRING AnsiName;
1150 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1151
1152 /* Verify parameters */
1153 if (!(TypeName) ||
1154 !(TypeName->Length) ||
1155 (TypeName->Length % sizeof(WCHAR)) ||
1156 !(ObjectTypeInitializer) ||
1157 (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1158 (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1159 (ObjectTypeInitializer->MaintainHandleCount &&
1160 (!(ObjectTypeInitializer->OpenProcedure) &&
1161 !ObjectTypeInitializer->CloseProcedure)) ||
1162 ((!ObjectTypeInitializer->UseDefaultObject) &&
1163 (ObjectTypeInitializer->PoolType != NonPagedPool)))
1164 {
1165 /* Fail */
1167 }
1168
1169 /* Make sure the name doesn't have a separator */
1170 p = TypeName->Buffer;
1171 i = TypeName->Length / sizeof(WCHAR);
1172 while (i--)
1173 {
1174 /* Check for one and fail */
1176 }
1177
1178 /* Setup a lookup context */
1180
1181 /* Check if we've already created the directory of types */
1183 {
1184 /* Lock the lookup context */
1186
1187 /* Do the lookup */
1189 TypeName,
1191 FALSE,
1192 &Context))
1193 {
1194 /* We have already created it, so fail */
1197 }
1198 }
1199
1200 /* Now make a copy of the object name */
1202 TypeName->MaximumLength,
1203 OB_NAME_TAG);
1204 if (!ObjectName.Buffer)
1205 {
1206 /* Out of memory, fail */
1209 }
1210
1211 /* Set the length and copy the name */
1212 ObjectName.MaximumLength = TypeName->MaximumLength;
1213 RtlCopyUnicodeString(&ObjectName, TypeName);
1214
1215 /* Allocate the Object */
1217 &ObjectName,
1219 sizeof(OBJECT_TYPE),
1220 KernelMode,
1221 &Header);
1222 if (!NT_SUCCESS(Status))
1223 {
1224 /* Free the name and fail */
1226 ExFreePool(ObjectName.Buffer);
1227 return Status;
1228 }
1229
1230 /* Setup the flags and name */
1231 LocalObjectType = (POBJECT_TYPE)&Header->Body;
1232 LocalObjectType->Name = ObjectName;
1234
1235 /* Clear accounting data */
1236 LocalObjectType->TotalNumberOfObjects =
1237 LocalObjectType->TotalNumberOfHandles =
1238 LocalObjectType->HighWaterNumberOfObjects =
1239 LocalObjectType->HighWaterNumberOfHandles = 0;
1240
1241 /* Check if this is the first Object Type */
1243 {
1244 /* It is, so set this as the type object */
1245 ObpTypeObjectType = LocalObjectType;
1246 Header->Type = ObpTypeObjectType;
1247
1248 /* Set the hard-coded key and object count */
1249 LocalObjectType->TotalNumberOfObjects = 1;
1250 LocalObjectType->Key = TAG_OBJECT_TYPE;
1251 }
1252 else
1253 {
1254 /* Convert the tag to ASCII */
1255 Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1256 if (NT_SUCCESS(Status))
1257 {
1258 /* For every missing character, use a space */
1259 for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1260
1261 /* Set the key and free the converted name */
1262 LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1263 RtlFreeAnsiString(&AnsiName);
1264 }
1265 else
1266 {
1267 /* Just copy the characters */
1268 LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1269 }
1270 }
1271
1272 /* Set up the type information */
1273 LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1274 LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1275
1276 /* Check if we have to maintain a type list */
1278 {
1279 /* Enable support */
1280 LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1281 }
1282
1283 /* Calculate how much space our header'll take up */
1284 HeaderSize = sizeof(OBJECT_HEADER) +
1285 sizeof(OBJECT_HEADER_NAME_INFO) +
1286 (ObjectTypeInitializer->MaintainHandleCount ?
1287 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1288
1289 /* Check the pool type */
1290 if (ObjectTypeInitializer->PoolType == NonPagedPool)
1291 {
1292 /* Update the NonPaged Pool charge */
1293 LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1294 }
1295 else
1296 {
1297 /* Update the Paged Pool charge */
1298 LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1299 }
1300
1301 /* All objects types need a security procedure */
1302 if (!ObjectTypeInitializer->SecurityProcedure)
1303 {
1305 }
1306
1307 /* Select the Wait Object */
1308 if (LocalObjectType->TypeInfo.UseDefaultObject)
1309 {
1310 /* Add the SYNCHRONIZE access mask since it's waitable */
1311 LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1312
1313 /* Use the "Default Object", a simple event */
1314 LocalObjectType->DefaultObject = &ObpDefaultObject;
1315 }
1316 /* The File Object gets an optimized hack so it can be waited on */
1317 else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1318 {
1319 /* Wait on the File Object's event directly */
1321 Event));
1322 }
1323 else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1324 {
1325 /* Wait on the LPC Port's object directly */
1327 WaitEvent));
1328 }
1329 else
1330 {
1331 /* No default Object */
1332 LocalObjectType->DefaultObject = NULL;
1333 }
1334
1335 /* Initialize Object Type components */
1336 ExInitializeResourceLite(&LocalObjectType->Mutex);
1337 for (i = 0; i < 4; i++)
1338 {
1339 /* Initialize the object locks */
1340 ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1341 }
1342 InitializeListHead(&LocalObjectType->TypeList);
1343
1344 /* Lock the object type */
1346
1347 /* Get creator info and insert it into the type list */
1349 if (CreatorInfo)
1350 {
1352 &CreatorInfo->TypeList);
1353
1354 /* CORE-8423: Avoid inserting this a second time if someone creates a
1355 * handle to the object type (bug in Windows 2003) */
1356 Header->Flags &= ~OB_FLAG_CREATE_INFO;
1357 }
1358
1359 /* Set the index and the entry into the object type array */
1360 LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1361
1362 ASSERT(LocalObjectType->Index != 0);
1363
1364 if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1365 {
1366 /* It fits, insert it */
1367 ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1368 }
1369
1370 /* Release the object type */
1372
1373 /* Check if we're actually creating the directory object itself */
1374 if (!(ObpTypeDirectoryObject) ||
1376 {
1377 /* Check if the type directory exists */
1379 {
1380 /* Reference it */
1382 }
1383
1384 /* Cleanup the lookup context */
1386
1387 /* Return the object type and success */
1388 *ObjectType = LocalObjectType;
1389 return STATUS_SUCCESS;
1390 }
1391
1392 /* If we got here, then we failed */
1395}
1396
1397VOID
1398NTAPI
1400{
1401 POBJECT_HEADER ObjectHeader;
1402 PAGED_CODE();
1403
1404 /* Check if there is anything to free */
1405 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1406 if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
1407 (ObjectHeader->ObjectCreateInfo != NULL))
1408 {
1409 /* Free the create info */
1411 ObjectHeader->ObjectCreateInfo = NULL;
1412 }
1413}
1414
1415VOID
1416NTAPI
1418{
1419 ULONG i;
1421
1422 /* Loop our locks */
1423 for (i = 0; i < 4; i++)
1424 {
1425 /* Delete each one */
1426 ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1427 }
1428
1429 /* Delete our main mutex */
1431}
1432
1433/*++
1434* @name ObMakeTemporaryObject
1435* @implemented NT4
1436*
1437* The ObMakeTemporaryObject routine <FILLMEIN>
1438*
1439* @param ObjectBody
1440* <FILLMEIN>
1441*
1442* @return None.
1443*
1444* @remarks None.
1445*
1446*--*/
1447VOID
1448NTAPI
1450{
1451 PAGED_CODE();
1452
1453 /* Call the internal API */
1454 ObpSetPermanentObject(ObjectBody, FALSE);
1455}
1456
1457/*++
1458* @name NtMakeTemporaryObject
1459* @implemented NT4
1460*
1461* The NtMakeTemporaryObject routine <FILLMEIN>
1462*
1463* @param ObjectHandle
1464* <FILLMEIN>
1465*
1466* @return STATUS_SUCCESS or appropriate error value.
1467*
1468* @remarks None.
1469*
1470*--*/
1472NTAPI
1474{
1475 PVOID ObjectBody;
1477 PAGED_CODE();
1478
1479 /* Reference the object for DELETE access */
1480 Status = ObReferenceObjectByHandle(ObjectHandle,
1481 DELETE,
1482 NULL,
1484 &ObjectBody,
1485 NULL);
1486 if (Status != STATUS_SUCCESS) return Status;
1487
1488 /* Set it as temporary and dereference it */
1489 ObpSetPermanentObject(ObjectBody, FALSE);
1490 ObDereferenceObject(ObjectBody);
1491 return STATUS_SUCCESS;
1492}
1493
1494/*++
1495* @name NtMakePermanentObject
1496* @implemented NT4
1497*
1498* The NtMakePermanentObject routine <FILLMEIN>
1499*
1500* @param ObjectHandle
1501* <FILLMEIN>
1502*
1503* @return STATUS_SUCCESS or appropriate error value.
1504*
1505* @remarks None.
1506*
1507*--*/
1509NTAPI
1511{
1512 PVOID ObjectBody;
1515 PAGED_CODE();
1516
1517 /* Make sure that the caller has SeCreatePermanentPrivilege */
1519 {
1521 }
1522
1523 /* Reference the object */
1524 Status = ObReferenceObjectByHandle(ObjectHandle,
1525 0,
1526 NULL,
1528 &ObjectBody,
1529 NULL);
1530 if (Status != STATUS_SUCCESS) return Status;
1531
1532 /* Set it as permanent and dereference it */
1533 ObpSetPermanentObject(ObjectBody, TRUE);
1534 ObDereferenceObject(ObjectBody);
1535 return STATUS_SUCCESS;
1536}
1537
1538/*++
1539* @name NtQueryObject
1540* @implemented NT4
1541*
1542* The NtQueryObject routine <FILLMEIN>
1543*
1544* @param ObjectHandle
1545* <FILLMEIN>
1546*
1547* @param ObjectInformationClass
1548* <FILLMEIN>
1549*
1550* @param ObjectInformation
1551* <FILLMEIN>
1552*
1553* @param Length
1554* <FILLMEIN>
1555*
1556* @param ResultLength
1557* <FILLMEIN>
1558*
1559* @return STATUS_SUCCESS or appropriate error value.
1560*
1561* @remarks None.
1562*
1563*--*/
1565NTAPI
1569 IN ULONG Length,
1571{
1572 OBJECT_HANDLE_INFORMATION HandleInfo;
1573 POBJECT_HEADER ObjectHeader = NULL;
1575 POBJECT_BASIC_INFORMATION BasicInfo;
1576 ULONG InfoLength = 0;
1577 PVOID Object = NULL;
1579 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1583 PAGED_CODE();
1584
1585 /* Check if the caller is from user mode */
1586 if (PreviousMode != KernelMode)
1587 {
1588 /* Protect validation with SEH */
1589 _SEH2_TRY
1590 {
1591 /* Probe the input structure */
1593
1594 /* If we have a result length, probe it too */
1596 }
1598 {
1599 /* Return the exception code */
1601 }
1602 _SEH2_END;
1603 }
1604
1605 /*
1606 * Make sure this isn't a generic type query, since the caller doesn't
1607 * have to give a handle for it
1608 */
1610 {
1611 /* Reference the object */
1612 Status = ObReferenceObjectByHandle(ObjectHandle,
1613 0,
1614 NULL,
1616 &Object,
1617 &HandleInfo);
1618 if (!NT_SUCCESS (Status)) return Status;
1619
1620 /* Get the object header */
1621 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1622 ObjectType = ObjectHeader->Type;
1623 }
1624
1625 _SEH2_TRY
1626 {
1627 /* Check the information class */
1628 switch (ObjectInformationClass)
1629 {
1630 /* Basic info */
1632
1633 /* Validate length */
1634 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1635 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1636 {
1637 /* Fail */
1639 break;
1640 }
1641
1642 /* Fill out the basic information */
1644 BasicInfo->Attributes = HandleInfo.HandleAttributes;
1645 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1646 BasicInfo->HandleCount = ObjectHeader->HandleCount;
1647 BasicInfo->PointerCount = ObjectHeader->PointerCount;
1648
1649 /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1650 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1651 {
1652 /* Set the flag */
1653 BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1654 }
1655 if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1656 {
1657 /* Set the flag */
1658 BasicInfo->Attributes |= OBJ_PERMANENT;
1659 }
1660
1661 /* Copy quota information */
1662 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1663 if (ObjectQuota != NULL)
1664 {
1665 BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1666 BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1667 }
1668 else
1669 {
1670 BasicInfo->PagedPoolCharge = 0;
1671 BasicInfo->NonPagedPoolCharge = 0;
1672 }
1673
1674 /* Copy name information */
1675 BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader);
1676 BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length +
1677 sizeof(UNICODE_NULL);
1678
1679 /* Check if this is a symlink */
1680 if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1681 {
1682 /* Return the creation time */
1683 BasicInfo->CreationTime.QuadPart =
1684 ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1685 }
1686 else
1687 {
1688 /* Otherwise return 0 */
1689 BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1690 }
1691
1692 /* Copy security information */
1693 BasicInfo->SecurityDescriptorSize = 0;
1694 if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1695 ObjectHeader->SecurityDescriptor != NULL)
1696 {
1701
1702 ObjectType->TypeInfo.SecurityProcedure(Object,
1703 QuerySecurityDescriptor,
1705 NULL,
1706 &BasicInfo->SecurityDescriptorSize,
1707 &ObjectHeader->SecurityDescriptor,
1708 ObjectType->TypeInfo.PoolType,
1709 &ObjectType->TypeInfo.GenericMapping);
1710 }
1711
1712 /* Break out with success */
1714 break;
1715
1716 /* Name information */
1718
1719 /* Call the helper and break out */
1723 Length,
1724 &InfoLength);
1725 break;
1726
1727 /* Information about this type */
1729
1730 /* Call the helper and break out */
1731 Status = ObQueryTypeInfo(ObjectHeader->Type,
1734 Length,
1735 &InfoLength);
1736 break;
1737
1738 /* Information about all types */
1740 DPRINT1("NOT IMPLEMENTED!\n");
1741 InfoLength = Length;
1743 break;
1744
1745 /* Information about the handle flags */
1746 case ObjectHandleFlagInformation:
1747
1748 /* Validate length */
1749 InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
1751 {
1753 break;
1754 }
1755
1756 /* Get the structure */
1759
1760 /* Set the flags */
1761 HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1762 HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1763 OBJ_PROTECT_CLOSE) != 0;
1764
1765 /* Break out with success */
1767 break;
1768
1769 /* Anything else */
1770 default:
1771
1772 /* Fail it */
1773 InfoLength = Length;
1775 break;
1776 }
1777
1778 /* Check if the caller wanted the return length */
1779 if (ResultLength)
1780 {
1781 /* Write the length */
1782 *ResultLength = InfoLength;
1783 }
1784 }
1786 {
1787 /* Otherwise, get the exception code */
1789 }
1790 _SEH2_END;
1791
1792 /* Dereference the object if we had referenced it */
1794
1795 /* Return status */
1796 return Status;
1797}
1798
1799/*++
1800* @name NtSetInformationObject
1801* @implemented NT4
1802*
1803* The NtSetInformationObject routine <FILLMEIN>
1804*
1805* @param ObjectHandle
1806* <FILLMEIN>
1807*
1808* @param ObjectInformationClass
1809* <FILLMEIN>
1810*
1811* @param ObjectInformation
1812* <FILLMEIN>
1813*
1814* @param Length
1815* <FILLMEIN>
1816*
1817* @return STATUS_SUCCESS or appropriate error value.
1818*
1819* @remarks None.
1820*
1821*--*/
1823NTAPI
1827 IN ULONG Length)
1828{
1831 PVOID ObjectTable;
1835 BOOLEAN AttachedToProcess = FALSE;
1836 PAGED_CODE();
1837
1838 /* Validate the information class */
1839 switch (ObjectInformationClass)
1840 {
1841 case ObjectHandleFlagInformation:
1842
1843 /* Validate the length */
1845 {
1846 /* Invalid length */
1848 }
1849
1850 /* Save the previous mode */
1851 Context.PreviousMode = ExGetPreviousMode();
1852
1853 /* Check if we were called from user mode */
1854 if (Context.PreviousMode != KernelMode)
1855 {
1856 /* Enter SEH */
1857 _SEH2_TRY
1858 {
1859 /* Probe and capture the attribute buffer */
1862 sizeof(BOOLEAN));
1865 }
1867 {
1868 /* Return the exception code */
1870 }
1871 _SEH2_END;
1872 }
1873 else
1874 {
1875 /* Just copy the buffer directly */
1878 }
1879
1880 /* Check if this is a kernel handle */
1881 if (ObpIsKernelHandle(ObjectHandle, Context.PreviousMode))
1882 {
1883 /* Get the actual handle */
1884 ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
1885 ObjectTable = ObpKernelHandleTable;
1886
1887 /* Check if we're not in the system process */
1889 {
1890 /* Attach to it */
1892 AttachedToProcess = TRUE;
1893 }
1894 }
1895 else
1896 {
1897 /* Use the current table */
1898 ObjectTable = PsGetCurrentProcess()->ObjectTable;
1899 }
1900
1901 /* Change the handle attributes */
1902 if (!ExChangeHandle(ObjectTable,
1903 ObjectHandle,
1905 (ULONG_PTR)&Context))
1906 {
1907 /* Some failure */
1909 }
1910 else
1911 {
1912 /* We are done */
1914 }
1915
1916 /* De-attach if we were attached, and return status */
1917 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1918 break;
1919
1920 case ObjectSessionInformation:
1921
1922 /* Only a system process can do this */
1925 {
1926 /* Fail */
1927 DPRINT1("Privilege not held\n");
1929 }
1930 else
1931 {
1932 /* Get the object directory */
1933 Status = ObReferenceObjectByHandle(ObjectHandle,
1934 0,
1937 (PVOID*)&Directory,
1938 NULL);
1939 if (NT_SUCCESS(Status))
1940 {
1941 /* Setup a lookup context */
1942 OBP_LOOKUP_CONTEXT LookupContext;
1943 ObpInitializeLookupContext(&LookupContext);
1944
1945 /* Set the directory session ID */
1948 ObpReleaseDirectoryLock(Directory, &LookupContext);
1949
1950 /* We're done, release the context and dereference the directory */
1951 ObpReleaseLookupContext(&LookupContext);
1953 }
1954 }
1955 break;
1956
1957 default:
1958 /* Unsupported class */
1960 break;
1961 }
1962
1963 return Status;
1964}
1965
1966/* EOF */
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
@ ObjectTypeInformation
Definition: DriverTester.h:56
@ ObjectBasicInformation
Definition: DriverTester.h:54
@ ObjectNameInformation
Definition: DriverTester.h:55
#define OBJ_PROTECT_CLOSE
#define ObpDirectoryObjectType
Definition: ObTypes.c:118
static OB_SECURITY_METHOD SeDefaultObjectMethod
Definition: ObTypes.c:134
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:119
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Type
Definition: Type.h:7
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
Definition: Header.h:9
IN CINT ObjectInformationClass
Definition: conport.c:47
IN CINT OUT PVOID ObjectInformation
Definition: conport.c:48
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#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:32
#define UlongToPtr(u)
Definition: config.h:106
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:140
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PDCB ParentDirectory
Definition: fatprocs.h:698
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
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
__in WDFOBJECT __in PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
Definition: handleapi.cpp:601
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define FLG_MAINTAIN_OBJECT_TYPELIST
Definition: pstypes.h:69
enum _OBJECT_INFORMATION_CLASS OBJECT_INFORMATION_CLASS
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
@ ObjectTypesInformation
Definition: winternl.h:851
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
#define InterlockedCompareExchange
Definition: interlocked.h:104
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define for
Definition: utility.h:88
ObjectType
Definition: metafile.c:81
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define _Out_writes_bytes_to_(size, count)
Definition: ms_sal.h:360
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
#define KeGetPreviousMode()
Definition: ketypes.h:1115
@ LookasideCreateInfoList
Definition: mmtypes.h:171
@ LookasideNameBufferList
Definition: mmtypes.h:172
struct _OBJECT_SYMBOLIC_LINK * POBJECT_SYMBOLIC_LINK
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:118
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:103
struct _OBJECT_HEADER_CREATOR_INFO * POBJECT_HEADER_CREATOR_INFO
struct _OBJECT_HEADER_QUOTA_INFO * POBJECT_HEADER_QUOTA_INFO
#define OB_FLAG_EXCLUSIVE
Definition: obtypes.h:100
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:126
struct _OBJECT_HEADER_HANDLE_INFO * POBJECT_HEADER_HANDLE_INFO
#define OB_FLAG_CREATOR_INFO
Definition: obtypes.h:99
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:97
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:122
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:98
struct _OBJECT_HEADER_CREATOR_INFO OBJECT_HEADER_CREATOR_INFO
struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION * POBJECT_HANDLE_ATTRIBUTE_INFORMATION
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
struct _OBJECT_HEADER_NAME_INFO * POBJECT_HEADER_NAME_INFO
struct _OBJECT_HEADER_NAME_INFO OBJECT_HEADER_NAME_INFO
struct _OBJECT_HEADER OBJECT_HEADER
struct _OBJECT_HEADER * POBJECT_HEADER
#define OB_FLAG_DEFER_DELETE
Definition: obtypes.h:104
struct _OBJECT_HEADER_QUOTA_INFO OBJECT_HEADER_QUOTA_INFO
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
#define OB_FLAG_SECURITY
Definition: obtypes.h:102
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
struct _OBJECT_TYPE_INFORMATION OBJECT_TYPE_INFORMATION
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION OBJECT_HANDLE_ATTRIBUTE_INFORMATION
struct _OBJECT_HEADER_HANDLE_INFO OBJECT_HEADER_HANDLE_INFO
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
#define FASTCALL
Definition: nt_native.h:50
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
struct _OBJECT_TYPE * POBJECT_TYPE
Definition: nt_native.h:34
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
OBJECT_TYPE
Definition: ntobjenum.h:13
@ FILE_OBJECT
Definition: ntobjenum.h:17
BOOLEAN NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
Definition: handle.c:1189
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
const LUID SeTcbPrivilege
Definition: priv.c:26
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
NTSTATUS NTAPI SeComputeQuotaInformationSize(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PULONG QuotaInfoSize)
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
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 SeCaptureSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Captures a security descriptor.
Definition: sd.c:386
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define L(x)
Definition: ntvdm.h:50
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
BOOLEAN NTAPI ObpSetHandleAttributes(IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, IN ULONG_PTR Context)
Definition: obhandle.c:1859
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
#define OBP_SYSTEM_PROCESS_QUOTA
Definition: ob.h:64
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:74
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN UCHAR SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:158
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Locks a directory for exclusive access. Used for writing/reading members of the directory object.
Definition: ob_x.h:212
FORCEINLINE VOID ObpAcquireLookupContextLock(IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_DIRECTORY Directory)
Locks an object directory lookup context for performing lookup operations (insertions/deletions) in a...
Definition: ob_x.h:281
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 PVOID ObpAllocateObjectCreateInfoBuffer(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:379
FORCEINLINE VOID ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Unlocks a previously shared or exclusively locked directory.
Definition: ob_x.h:238
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
#define OBP_NAME_LOOKASIDE_MAX_SIZE
Definition: ob_x.h:18
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:416
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
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
volatile PVOID ObpReaperList
Definition: oblife.c:29
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:455
NTSTATUS NTAPI ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN PUNICODE_STRING ObjectName, IN POBJECT_TYPE ObjectType, IN ULONG ObjectSize, IN KPROCESSOR_MODE PreviousMode, IN POBJECT_HEADER *ObjectHeader)
Definition: oblife.c:611
ULONG ObpObjectsWithPoolQuota
Definition: oblife.c:31
POBJECT_TYPE ObpTypeObjectType
Definition: oblife.c:22
NTSTATUS NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1510
VOID NTAPI ObpDeleteObjectType(IN PVOID Object)
Definition: oblife.c:1417
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
VOID FASTCALL ObpSetPermanentObject(IN PVOID ObjectBody, IN BOOLEAN Permanent)
Definition: oblife.c:266
POBJECT_TYPE ObpObjectTypes[32]
Definition: oblife.c:33
NTSTATUS NTAPI ObQueryTypeInfo(_In_ POBJECT_TYPE ObjectType, _Out_writes_bytes_to_(Length, *ReturnLength) POBJECT_TYPE_INFORMATION ObjectTypeInfo, _In_ ULONG Length, _Out_ PULONG ReturnLength)
Definition: oblife.c:947
VOID NTAPI ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: oblife.c:603
ULONG NtGlobalFlag
Definition: init.c:54
NTSTATUS NTAPI NtQueryObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG Length, OUT PULONG ResultLength OPTIONAL)
Definition: oblife.c:1566
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
VOID NTAPI ObDeleteCapturedInsertInfo(IN PVOID Object)
Definition: oblife.c:1399
PWCHAR NTAPI ObpAllocateObjectNameBuffer(IN ULONG Length, IN BOOLEAN UseLookaside, IN OUT PUNICODE_STRING ObjectName)
Definition: oblife.c:301
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
ULONG ObpObjectsWithCreatorInfo
Definition: oblife.c:32
NTSTATUS NTAPI ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, IN PUNICODE_STRING ObjectName, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN UseLookaside)
Definition: oblife.c:376
GENERAL_LOOKASIDE ObpNameBufferLookasideList
Definition: oblife.c:26
ULONG ObpObjectsCreated
Definition: oblife.c:31
WORK_QUEUE_ITEM ObpReaperWorkItem
Definition: oblife.c:28
VOID NTAPI ObpReapObject(IN PVOID Parameter)
Definition: oblife.c:220
VOID NTAPI ObpDeleteObject(IN PVOID Object, IN BOOLEAN CalledFromWorkerThread)
Definition: oblife.c:147
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1449
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
Definition: oblife.c:26
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:346
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1473
ULONG ObpObjectsWithHandleDB
Definition: oblife.c:32
NTSTATUS NTAPI NtSetInformationObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, IN PVOID ObjectInformation, IN ULONG Length)
Definition: oblife.c:1824
VOID FASTCALL ObpDeallocateObject(IN PVOID Object)
Definition: oblife.c:39
static ULONG ObpQueryNameInfoSize(_In_ POBJECT_HEADER ObjectHeader)
Queries the name info size of a given resource object. The function loops through all the parent dire...
Definition: oblife.c:890
ULONG ObpObjectsWithName
Definition: oblife.c:31
KEVENT ObpDefaultObject
Definition: oblife.c:23
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
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:494
unsigned short USHORT
Definition: pedump.c:61
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
VOID NTAPI PsReturnSharedPoolQuota(_In_ PEPROCESS_QUOTA_BLOCK QuotaBlock, _In_ SIZE_T AmountToReturnPaged, _In_ SIZE_T AmountToReturnNonPaged)
Returns the shared (paged and non paged) pool quotas. The function is used exclusively by the Object ...
Definition: quota.c:621
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_VOLATILE
Definition: pseh2_64.h:163
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base for all directory entries
Definition: entries.h:138
KPROCESS Pcb
Definition: pstypes.h:1262
ACCESS_MASK GrantedAccess
Definition: winternl.h:1251
ULONG HandleCount
Definition: obtypes.h:445
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:458
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:459
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
UNICODE_STRING Name
Definition: obtypes.h:433
PEPROCESS ExclusiveProcess
Definition: obtypes.h:476
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:503
volatile PVOID NextToFree
Definition: obtypes.h:491
UCHAR Flags
Definition: obtypes.h:497
LONG_PTR HandleCount
Definition: obtypes.h:490
LONG_PTR PointerCount
Definition: obtypes.h:487
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:500
POBJECT_TYPE Type
Definition: obtypes.h:493
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:371
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
ULONG TotalNumberOfHandles
Definition: obtypes.h:387
ULONG Index
Definition: obtypes.h:385
LIST_ENTRY TypeList
Definition: obtypes.h:382
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:388
ULONG TotalNumberOfObjects
Definition: obtypes.h:386
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:392
ERESOURCE Mutex
Definition: obtypes.h:381
ULONG Key
Definition: obtypes.h:391
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:389
UNICODE_STRING Name
Definition: obtypes.h:383
PVOID DefaultObject
Definition: obtypes.h:384
#define max(a, b)
Definition: svc.c:63
#define OB_NAME_TAG
Definition: tag.h:118
#define TAG_OBJECT_TYPE
Definition: tag.h:122
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
INT POOL_TYPE
Definition: typedefs.h:78
#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
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#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_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
_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
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
struct LOOKASIDE_ALIGN _GENERAL_LOOKASIDE GENERAL_LOOKASIDE
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KAPC_STATE
Definition: ketypes.h:1409
_Must_inspect_result_ _In_ _In_ ULONG ProbeMode
Definition: mmfuncs.h:561
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180