ReactOS 0.4.17-dev-579-gd2025ff
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,
200 ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object);
201 }
202
203 /* Check if we have a delete procedure */
204 if (ObjectType->TypeInfo.DeleteProcedure)
205 {
206 /* Save whether we were deleted from worker thread or not */
207 if (!CalledFromWorkerThread) Header->Flags |= OB_FLAG_DEFER_DELETE;
208
209 /* Call it */
210 ObpCalloutStart(&CalloutIrql);
211 ObjectType->TypeInfo.DeleteProcedure(Object);
212 ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object);
213 }
214
215 /* Now de-allocate all object members */
217}
218
219VOID
220NTAPI
222{
223 POBJECT_HEADER ReapObject, NextObject;
224
225 /* Start reaping */
226 do
227 {
228 /* Get the reap object */
230
231 /* Start deletion loop */
232 do
233 {
234 /* Get the next object */
235 NextObject = ReapObject->NextToFree;
236
237 /* Delete the object */
238 ObpDeleteObject(&ReapObject->Body, TRUE);
239
240 /* Move to the next one */
241 ReapObject = NextObject;
242 } while ((ReapObject) && (ReapObject != (PVOID)1));
243 } while ((ObpReaperList != (PVOID)1) ||
245}
246
247/*++
248* @name ObpSetPermanentObject
249*
250* The ObpSetPermanentObject routine makes an sets or clears the permanent
251* flag of an object, thus making it either permanent or temporary.
252*
253* @param ObjectBody
254* Pointer to the object to make permanent or temporary.
255*
256* @param Permanent
257* Flag specifying which operation to perform.
258*
259* @return None.
260*
261* @remarks If the object is being made temporary, then it will be checked
262* as a candidate for immediate removal from the namespace.
263*
264*--*/
265VOID
268 IN BOOLEAN Permanent)
269{
270 POBJECT_HEADER ObjectHeader;
271
272 /* Get the header */
273 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
274
275 /* Acquire object lock */
276 ObpAcquireObjectLock(ObjectHeader);
277
278 /* Check what we're doing to it */
279 if (Permanent)
280 {
281 /* Set it to permanent */
282 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
283
284 /* Release the lock */
285 ObpReleaseObjectLock(ObjectHeader);
286 }
287 else
288 {
289 /* Remove the flag */
290 ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
291
292 /* Release the lock */
293 ObpReleaseObjectLock(ObjectHeader);
294
295 /* Check if we should delete the object now */
296 ObpDeleteNameCheck(ObjectBody);
297 }
298}
299
300PWCHAR
301NTAPI
303 IN BOOLEAN UseLookaside,
305{
308
309 /* Set the maximum length to the length plus the terminator */
311
312 /* Check if we should use the lookaside buffer */
313 if (!(UseLookaside) || (MaximumLength > OBP_NAME_LOOKASIDE_MAX_SIZE))
314 {
315 /* Nope, allocate directly from pool */
316 /* Since we later use MaximumLength to detect that we're not allocating
317 * from a list, we need at least MaximumLength + sizeof(UNICODE_NULL)
318 * here.
319 *
320 * People do call this with UseLookasideList FALSE so the distinction
321 * is critical.
322 */
324 {
326 }
330 }
331 else
332 {
333 /* Allocate from the lookaside */
336 }
337
338 /* Setup the string */
339 ObjectName->MaximumLength = (USHORT)MaximumLength;
340 ObjectName->Length = (USHORT)Length;
341 ObjectName->Buffer = Buffer;
342 return Buffer;
343}
344
345VOID
346NTAPI
348{
349 PVOID Buffer = Name->Buffer;
350
351 /* We know this is a pool-allocation if the size doesn't match */
352 if (Name->MaximumLength != OBP_NAME_LOOKASIDE_MAX_SIZE)
353 {
354 /*
355 * Free it from the pool.
356 *
357 * We cannot use here ExFreePoolWithTag(..., OB_NAME_TAG); , because
358 * the object name may have been massaged during operation by different
359 * object parse routines. If the latter ones have to resolve a symbolic
360 * link (e.g. as is done by CmpParseKey() and CmpGetSymbolicLink()),
361 * the original object name is freed and re-allocated from the pool,
362 * possibly with a different pool tag. At the end of the day, the new
363 * object name can be reallocated and completely different, but we
364 * should still be able to free it!
365 */
367 }
368 else
369 {
370 /* Otherwise, free from the lookaside */
372 }
373}
374
376NTAPI
380 IN BOOLEAN UseLookaside)
381{
383 ULONG StringLength;
385 UNICODE_STRING LocalName;
386 PAGED_CODE();
387
388 /* Initialize the Input String */
389 RtlInitEmptyUnicodeString(CapturedName, NULL, 0);
390
391 /* Protect everything */
393 {
394 /* Check if we came from user mode */
395 if (AccessMode != KernelMode)
396 {
397 /* First Probe the String */
399 ProbeForRead(LocalName.Buffer, LocalName.Length, sizeof(WCHAR));
400 }
401 else
402 {
403 /* No probing needed */
404 LocalName = *ObjectName;
405 }
406
407 /* Make sure there really is a string */
408 StringLength = LocalName.Length;
409 if (StringLength)
410 {
411 /* Check that the size is a valid WCHAR multiple */
412 if ((StringLength & (sizeof(WCHAR) - 1)) ||
413 /* Check that the NULL-termination below will work */
414 (StringLength == (MAXUSHORT - sizeof(UNICODE_NULL) + 1)))
415 {
416 /* PS: Please keep the checks above expanded for clarity */
418 }
419 else
420 {
421 /* Allocate the string buffer */
423 UseLookaside,
424 CapturedName);
425 if (!StringBuffer)
426 {
427 /* Set failure code */
429 }
430 else
431 {
432 /* Copy the name */
433 RtlCopyMemory(StringBuffer, LocalName.Buffer, StringLength);
434 StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
435 }
436 }
437 }
438 }
440 {
441 /* Handle exception and free the string buffer */
443 if (StringBuffer)
444 {
445 ObpFreeObjectNameBuffer(CapturedName);
446 }
447 }
448 _SEH2_END;
449
450 /* Return */
451 return Status;
452}
453
455NTAPI
458 IN KPROCESSOR_MODE CreatorMode,
459 IN BOOLEAN AllocateFromLookaside,
460 IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
462{
463 ULONG SdCharge, QuotaInfoSize;
467 PUNICODE_STRING LocalObjectName = NULL;
468 PAGED_CODE();
469
470 /* Zero out the Capture Data */
471 RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
472
473 /* SEH everything here for protection */
475 {
476 /* Check if we got attributes */
478 {
479 /* Check if we're in user mode */
480 if (AccessMode != KernelMode)
481 {
482 /* Probe the attributes */
484 sizeof(OBJECT_ATTRIBUTES),
485 sizeof(ULONG));
486 }
487
488 /* Validate the Size and Attributes */
489 if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
491 {
492 /* Invalid combination, fail */
494 }
495
496 /* Set some Create Info and do not allow user-mode kernel handles */
497 ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
498 ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_KERNEL_ATTRIBUTES;
499 if (CreatorMode != KernelMode) ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
500 LocalObjectName = ObjectAttributes->ObjectName;
501 SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
502 SecurityQos = ObjectAttributes->SecurityQualityOfService;
503
504 /* Check if we have a security descriptor */
506 {
507 /* Capture it. Note: This has an implicit memory barrier due
508 to the function call, so cleanup is safe here.) */
512 TRUE,
513 &ObjectCreateInfo->
515 if (!NT_SUCCESS(Status))
516 {
517 /* Capture failed, quit */
518 ObjectCreateInfo->SecurityDescriptor = NULL;
519 _SEH2_YIELD(return Status);
520 }
521
522 /*
523 * By default, assume a SD size of 1024 and allow twice its
524 * size.
525 * If SD size happen to be bigger than that, then allow it
526 */
527 SdCharge = 2048;
528 SeComputeQuotaInformationSize(ObjectCreateInfo->SecurityDescriptor,
529 &QuotaInfoSize);
530 if ((2 * QuotaInfoSize) > 2048)
531 {
532 SdCharge = 2 * QuotaInfoSize;
533 }
534
535 /* Save the probe mode and security descriptor size */
536 ObjectCreateInfo->SecurityDescriptorCharge = SdCharge;
537 ObjectCreateInfo->ProbeMode = AccessMode;
538 }
539
540 /* Check if we have QoS */
541 if (SecurityQos)
542 {
543 /* Check if we came from user mode */
544 if (AccessMode != KernelMode)
545 {
546 /* Validate the QoS */
547 ProbeForRead(SecurityQos,
549 sizeof(ULONG));
550 }
551
552 /* Save Info */
553 ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
554 ObjectCreateInfo->SecurityQos =
555 &ObjectCreateInfo->SecurityQualityOfService;
556 }
557 }
558 else
559 {
560 /* We don't have a name */
561 LocalObjectName = NULL;
562 }
563 }
565 {
566 /* Cleanup and return the exception code */
567 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
569 }
570 _SEH2_END;
571
572 /* Now check if the Object Attributes had an Object Name */
573 if (LocalObjectName)
574 {
576 LocalObjectName,
578 AllocateFromLookaside);
579 }
580 else
581 {
582 /* Clear the string */
583 RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
584
585 /* It cannot have specified a Root Directory */
586 if (ObjectCreateInfo->RootDirectory)
587 {
589 }
590 }
591
592 /* Cleanup if we failed */
593 if (!NT_SUCCESS(Status))
594 {
595 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
596 }
597
598 /* Return status to caller */
599 return Status;
600}
601
602VOID
603NTAPI
605{
606 /* Call the macro. We use this function to isolate Ob internals from Io */
608}
609
611NTAPI
615 IN ULONG ObjectSize,
617 IN POBJECT_HEADER *ObjectHeader)
618{
620 ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
623 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
626 ULONG FinalSize;
627 ULONG Tag;
628 PAGED_CODE();
629
630 /* Accounting */
632
633 /* Check if we don't have an Object Type yet */
634 if (!ObjectType)
635 {
636 /* Use default tag and non-paged pool */
639 }
640 else
641 {
642 /* Use the pool and tag given */
643 PoolType = ObjectType->TypeInfo.PoolType;
644 Tag = ObjectType->Key;
645 }
646
647 /* Check if we have no create information (ie: we're an object type) */
648 if (!ObjectCreateInfo)
649 {
650 /* Use defaults */
651 QuotaSize = HandleSize = 0;
652 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
653 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
654 }
655 else
656 {
657 /* Check if we have quota */
658 if ((((ObjectCreateInfo->PagedPoolCharge !=
659 ObjectType->TypeInfo.DefaultPagedPoolCharge) ||
660 (ObjectCreateInfo->NonPagedPoolCharge !=
661 ObjectType->TypeInfo.DefaultNonPagedPoolCharge) ||
662 (ObjectCreateInfo->SecurityDescriptorCharge > 2048)) &&
664 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
665 {
666 /* Set quota size */
667 QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO);
669 }
670 else
671 {
672 /* No Quota */
673 QuotaSize = 0;
674 }
675
676 /* Check if we have a handle database */
677 if (ObjectType->TypeInfo.MaintainHandleCount)
678 {
679 /* Set handle database size */
680 HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO);
682 }
683 else
684 {
685 /* None */
686 HandleSize = 0;
687 }
688
689 /* Check if the Object has a name */
690 if (ObjectName->Buffer)
691 {
692 /* Set name size */
693 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
695 }
696 else
697 {
698 /* No name */
699 NameSize = 0;
700 }
701
702 /* Check if the Object maintains type lists */
703 if (ObjectType->TypeInfo.MaintainTypeList)
704 {
705 /* Set owner/creator size */
706 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
708 }
709 else
710 {
711 /* No info */
712 CreatorSize = 0;
713 }
714 }
715
716 /* Set final header size */
717 FinalSize = QuotaSize +
718 HandleSize +
719 NameSize +
720 CreatorSize +
722
723 /* Allocate memory for the Object and Header */
724 Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
726
727 /* Check if we have a quota header */
728 if (QuotaSize)
729 {
730 /* Initialize quota info */
732 QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge;
733 QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge;
734 QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge;
735 QuotaInfo->ExclusiveProcess = NULL;
736 Header = (POBJECT_HEADER)(QuotaInfo + 1);
737 }
738
739 /* Check if we have a handle database header */
740 if (HandleSize)
741 {
742 /* Initialize Handle Info */
744 HandleInfo->SingleEntry.HandleCount = 0;
745 Header = (POBJECT_HEADER)(HandleInfo + 1);
746 }
747
748 /* Check if we have a name header */
749 if (NameSize)
750 {
751 /* Initialize the Object Name Info */
753 NameInfo->Name = *ObjectName;
754 NameInfo->Directory = NULL;
755 NameInfo->QueryReferences = 1;
756
757 /* Check if this is a call with the special protection flag */
758 if ((PreviousMode == KernelMode) &&
759 (ObjectCreateInfo) &&
760 (ObjectCreateInfo->Attributes & OBJ_KERNEL_EXCLUSIVE))
761 {
762 /* Set flag which will make the object protected from user-mode */
764 }
765
766 /* Set the header pointer */
767 Header = (POBJECT_HEADER)(NameInfo + 1);
768 }
769
770 /* Check if we have a creator header */
771 if (CreatorSize)
772 {
773 /* Initialize Creator Info */
774 CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
775 CreatorInfo->CreatorBackTraceIndex = 0;
777 InitializeListHead(&CreatorInfo->TypeList);
778 Header = (POBJECT_HEADER)(CreatorInfo + 1);
779 }
780
781 /* Check for quota information */
782 if (QuotaSize)
783 {
784 /* Set the offset */
785 Header->QuotaInfoOffset = (UCHAR)(QuotaSize +
786 HandleSize +
787 NameSize +
788 CreatorSize);
789 }
790 else
791 {
792 /* No offset */
793 Header->QuotaInfoOffset = 0;
794 }
795
796 /* Check for handle information */
797 if (HandleSize)
798 {
799 /* Set the offset */
800 Header->HandleInfoOffset = (UCHAR)(HandleSize +
801 NameSize +
802 CreatorSize);
803 }
804 else
805 {
806 /* No offset */
807 Header->HandleInfoOffset = 0;
808 }
809
810 /* Check for name information */
811 if (NameSize)
812 {
813 /* Set the offset */
814 Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize);
815 }
816 else
817 {
818 /* No Name */
819 Header->NameInfoOffset = 0;
820 }
821
822 /* Set the new object flag */
824
825 /* Remember if we have creator info */
826 if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO;
827
828 /* Remember if we have handle info */
829 if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS;
830
831 /* Initialize the object header */
832 Header->PointerCount = 1;
833 Header->HandleCount = 0;
834 Header->Type = ObjectType;
835 Header->ObjectCreateInfo = ObjectCreateInfo;
836 Header->SecurityDescriptor = NULL;
837
838 /* Check if this is a permanent object */
839 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
840 {
841 /* Set the needed flag so we can check */
842 Header->Flags |= OB_FLAG_PERMANENT;
843 }
844
845 /* Check if this is an exclusive object */
846 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
847 {
848 /* Set the needed flag so we can check */
849 Header->Flags |= OB_FLAG_EXCLUSIVE;
850 }
851
852 /* Set kernel-mode flag */
854
855 /* Check if we have a type */
856 if (ObjectType)
857 {
858 /* Increase the number of objects of this type */
859 InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfObjects);
860
861 /* Update the high water */
862 ObjectType->HighWaterNumberOfObjects = max(ObjectType->
863 TotalNumberOfObjects,
864 ObjectType->
865 HighWaterNumberOfObjects);
866 }
867
868 /* Return Header */
869 *ObjectHeader = Header;
870 return STATUS_SUCCESS;
871}
872
889static
890ULONG
892 _In_ POBJECT_HEADER ObjectHeader)
893{
894 ULONG NameSize = 0;
897 PAGED_CODE();
898
899 /* Get the name info */
900 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
901 if (!NameInfo)
902 {
903 return 0;
904 }
905
906 /* Get the parent directory from the object name too */
907 ParentDirectory = NameInfo->Directory;
908 if (!ParentDirectory)
909 {
910 return 0;
911 }
912
913 /* Take into account the name size of this object and loop for all parent directories */
914 NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
915 for (;;)
916 {
917 /* Get the name info from the parent directory */
920 if (!NameInfo)
921 {
922 /* Stop looking if this is the last one */
923 break;
924 }
925
926 /* Get the parent directory */
927 ParentDirectory = NameInfo->Directory;
928 if (!ParentDirectory)
929 {
930 /* This is the last directory, stop looking */
931 break;
932 }
933
934 /*
935 * Take into account the size of this name info,
936 * keep looking for other parent directories.
937 */
938 NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
939 }
940
941 /* Include the size of the object name information as well as the NULL terminator */
942 NameSize += sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
943 return NameSize;
944}
945
947NTAPI
951 POBJECT_TYPE_INFORMATION ObjectTypeInfo,
954{
956 PWSTR InfoBuffer;
957
958 /* The string of the object type name has to be NULL-terminated */
959 ASSERT(ObjectType->Name.MaximumLength >= ObjectType->Name.Length + sizeof(UNICODE_NULL));
960
961 /* Enter SEH */
963 {
964 /*
965 * Set return length aligned to 4-byte or 8-byte boundary. Windows has a bug
966 * where the returned length pointer is always aligned to a 4-byte boundary.
967 * If one were to allocate a pool of memory in kernel mode to retrieve all
968 * the object types info with this return length, Windows will bugcheck with
969 * BAD_POOL_HEADER in 64-bit upon you free the said allocated memory.
970 *
971 * More than that, Windows uses MaximumLength for the calculation of the returned
972 * length and MaximumLength does not always guarantee the name type is NULL-terminated
973 * leading the ObQueryTypeInfo function to overrun the buffer.
974 */
975 *ReturnLength += sizeof(*ObjectTypeInfo) +
976 ALIGN_UP(ObjectType->Name.Length + sizeof(UNICODE_NULL), ULONG_PTR);
977
978 /* Check if that is too much */
979 if (Length < *ReturnLength)
980 {
982 }
983
984 /* Build the data */
985 ObjectTypeInfo->TotalNumberOfHandles =
986 ObjectType->TotalNumberOfHandles;
987 ObjectTypeInfo->TotalNumberOfObjects =
988 ObjectType->TotalNumberOfObjects;
989 ObjectTypeInfo->HighWaterNumberOfHandles =
990 ObjectType->HighWaterNumberOfHandles;
991 ObjectTypeInfo->HighWaterNumberOfObjects =
992 ObjectType->HighWaterNumberOfObjects;
993 ObjectTypeInfo->PoolType =
994 ObjectType->TypeInfo.PoolType;
995 ObjectTypeInfo->DefaultNonPagedPoolCharge =
996 ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
997 ObjectTypeInfo->DefaultPagedPoolCharge =
998 ObjectType->TypeInfo.DefaultPagedPoolCharge;
999 ObjectTypeInfo->ValidAccessMask =
1000 ObjectType->TypeInfo.ValidAccessMask;
1001 ObjectTypeInfo->SecurityRequired =
1002 ObjectType->TypeInfo.SecurityRequired;
1003 ObjectTypeInfo->InvalidAttributes =
1004 ObjectType->TypeInfo.InvalidAttributes;
1005 ObjectTypeInfo->GenericMapping =
1006 ObjectType->TypeInfo.GenericMapping;
1007 ObjectTypeInfo->MaintainHandleCount =
1008 ObjectType->TypeInfo.MaintainHandleCount;
1009
1010 /* Setup the name buffer */
1011 InfoBuffer = (PWSTR)(ObjectTypeInfo + 1);
1012 ObjectTypeInfo->TypeName.Buffer = InfoBuffer;
1013 ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength;
1014 ObjectTypeInfo->TypeName.Length = ObjectType->Name.Length;
1015
1016 /* Copy it */
1017 RtlCopyMemory(InfoBuffer,
1018 ObjectType->Name.Buffer,
1019 ObjectType->Name.Length);
1020
1021 /* Null-terminate it */
1022 (InfoBuffer)[ObjectType->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
1023 }
1025 {
1026 /* Otherwise, get the exception code */
1028 }
1029 _SEH2_END;
1030
1031 /* Return status to caller */
1032 return Status;
1033}
1034
1035
1036/* PUBLIC FUNCTIONS **********************************************************/
1037
1039NTAPI
1044 IN OUT PVOID ParseContext OPTIONAL,
1045 IN ULONG ObjectSize,
1046 IN ULONG PagedPoolCharge OPTIONAL,
1047 IN ULONG NonPagedPoolCharge OPTIONAL,
1048 OUT PVOID *Object)
1049{
1051 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
1054
1055 /* Allocate a capture buffer */
1057 if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
1058
1059 /* Capture all the info */
1061 ProbeMode,
1062 AccessMode,
1063 FALSE,
1064 ObjectCreateInfo,
1065 &ObjectName);
1066 if (NT_SUCCESS(Status))
1067 {
1068 /* Validate attributes */
1069 if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
1070 {
1071 /* Fail */
1073 }
1074 else
1075 {
1076 /* Check if we have a paged charge */
1077 if (!PagedPoolCharge)
1078 {
1079 /* Save it */
1080 PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
1081 }
1082
1083 /* Check for nonpaged charge */
1084 if (!NonPagedPoolCharge)
1085 {
1086 /* Save it */
1087 NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1088 }
1089
1090 /* Write the pool charges */
1091 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1092 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1093
1094 /* Allocate the Object */
1095 Status = ObpAllocateObject(ObjectCreateInfo,
1096 &ObjectName,
1097 Type,
1098 ObjectSize,
1099 AccessMode,
1100 &Header);
1101 if (NT_SUCCESS(Status))
1102 {
1103 /* Return the Object */
1104 *Object = &Header->Body;
1105
1106 /* Check if this is a permanent object */
1107 if (Header->Flags & OB_FLAG_PERMANENT)
1108 {
1109 /* Do the privilege check */
1111 ProbeMode))
1112 {
1113 /* Fail */
1116 }
1117 }
1118
1119 /* Return status */
1120 return Status;
1121 }
1122 }
1123
1124 /* Release the Capture Info, we don't need it */
1125 ObpFreeObjectCreateInformation(ObjectCreateInfo);
1127 return Status;
1128 }
1129
1130 /* We failed, so release the Buffer */
1132 return Status;
1133}
1134
1136NTAPI
1138 IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
1141{
1143 POBJECT_TYPE LocalObjectType;
1144 ULONG HeaderSize;
1147 PWCHAR p;
1148 ULONG i;
1150 ANSI_STRING AnsiName;
1151 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1152
1153 /* Verify parameters */
1154 if (!(TypeName) ||
1155 !(TypeName->Length) ||
1156 (TypeName->Length % sizeof(WCHAR)) ||
1157 !(ObjectTypeInitializer) ||
1158 (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1159 (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1160 (ObjectTypeInitializer->MaintainHandleCount &&
1161 (!(ObjectTypeInitializer->OpenProcedure) &&
1162 !ObjectTypeInitializer->CloseProcedure)) ||
1163 ((!ObjectTypeInitializer->UseDefaultObject) &&
1164 (ObjectTypeInitializer->PoolType != NonPagedPool)))
1165 {
1166 /* Fail */
1168 }
1169
1170 /* Make sure the name doesn't have a separator */
1171 p = TypeName->Buffer;
1172 i = TypeName->Length / sizeof(WCHAR);
1173 while (i--)
1174 {
1175 /* Check for one and fail */
1177 }
1178
1179 /* Setup a lookup context */
1181
1182 /* Check if we've already created the directory of types */
1184 {
1185 /* Lock the lookup context */
1187
1188 /* Do the lookup */
1190 TypeName,
1192 FALSE,
1193 &Context))
1194 {
1195 /* We have already created it, so fail */
1198 }
1199 }
1200
1201 /* Now make a copy of the object name */
1203 TypeName->MaximumLength,
1204 OB_NAME_TAG);
1205 if (!ObjectName.Buffer)
1206 {
1207 /* Out of memory, fail */
1210 }
1211
1212 /* Set the length and copy the name */
1213 ObjectName.MaximumLength = TypeName->MaximumLength;
1214 RtlCopyUnicodeString(&ObjectName, TypeName);
1215
1216 /* Allocate the Object */
1218 &ObjectName,
1220 sizeof(OBJECT_TYPE),
1221 KernelMode,
1222 &Header);
1223 if (!NT_SUCCESS(Status))
1224 {
1225 /* Free the name and fail */
1227 ExFreePool(ObjectName.Buffer);
1228 return Status;
1229 }
1230
1231 /* Setup the flags and name */
1232 LocalObjectType = (POBJECT_TYPE)&Header->Body;
1233 LocalObjectType->Name = ObjectName;
1235
1236 /* Clear accounting data */
1237 LocalObjectType->TotalNumberOfObjects =
1238 LocalObjectType->TotalNumberOfHandles =
1239 LocalObjectType->HighWaterNumberOfObjects =
1240 LocalObjectType->HighWaterNumberOfHandles = 0;
1241
1242 /* Check if this is the first Object Type */
1244 {
1245 /* It is, so set this as the type object */
1246 ObpTypeObjectType = LocalObjectType;
1247 Header->Type = ObpTypeObjectType;
1248
1249 /* Set the hard-coded key and object count */
1250 LocalObjectType->TotalNumberOfObjects = 1;
1251 LocalObjectType->Key = TAG_OBJECT_TYPE;
1252 }
1253 else
1254 {
1255 /* Convert the tag to ASCII */
1256 Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1257 if (NT_SUCCESS(Status))
1258 {
1259 /* For every missing character, use a space */
1260 for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1261
1262 /* Set the key and free the converted name */
1263 LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1264 RtlFreeAnsiString(&AnsiName);
1265 }
1266 else
1267 {
1268 /* Just copy the characters */
1269 LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1270 }
1271 }
1272
1273 /* Set up the type information */
1274 LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1275 LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1276
1277 /* Check if we have to maintain a type list */
1279 {
1280 /* Enable support */
1281 LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1282 }
1283
1284 /* Calculate how much space our header'll take up */
1285 HeaderSize = sizeof(OBJECT_HEADER) +
1286 sizeof(OBJECT_HEADER_NAME_INFO) +
1287 (ObjectTypeInitializer->MaintainHandleCount ?
1288 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1289
1290 /* Check the pool type */
1291 if (ObjectTypeInitializer->PoolType == NonPagedPool)
1292 {
1293 /* Update the NonPaged Pool charge */
1294 LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1295 }
1296 else
1297 {
1298 /* Update the Paged Pool charge */
1299 LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1300 }
1301
1302 /* All objects types need a security procedure */
1303 if (!ObjectTypeInitializer->SecurityProcedure)
1304 {
1306 }
1307
1308 /* Select the Wait Object */
1309 if (LocalObjectType->TypeInfo.UseDefaultObject)
1310 {
1311 /* Add the SYNCHRONIZE access mask since it's waitable */
1312 LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1313
1314 /* Use the "Default Object", a simple event */
1315 LocalObjectType->DefaultObject = &ObpDefaultObject;
1316 }
1317 /* The File Object gets an optimized hack so it can be waited on */
1318 else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1319 {
1320 /* Wait on the File Object's event directly */
1322 Event));
1323 }
1324 else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1325 {
1326 /* Wait on the LPC Port's object directly */
1328 WaitEvent));
1329 }
1330 else
1331 {
1332 /* No default Object */
1333 LocalObjectType->DefaultObject = NULL;
1334 }
1335
1336 /* Initialize Object Type components */
1337 ExInitializeResourceLite(&LocalObjectType->Mutex);
1338 for (i = 0; i < 4; i++)
1339 {
1340 /* Initialize the object locks */
1341 ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1342 }
1343 InitializeListHead(&LocalObjectType->TypeList);
1344
1345 /* Lock the object type */
1347
1348 /* Get creator info and insert it into the type list */
1350 if (CreatorInfo)
1351 {
1353 &CreatorInfo->TypeList);
1354
1355 /* CORE-8423: Avoid inserting this a second time if someone creates a
1356 * handle to the object type (bug in Windows 2003) */
1357 Header->Flags &= ~OB_FLAG_CREATE_INFO;
1358 }
1359
1360 /* Set the index and the entry into the object type array */
1361 LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1362
1363 ASSERT(LocalObjectType->Index != 0);
1364
1365 if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1366 {
1367 /* It fits, insert it */
1368 ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1369 }
1370
1371 /* Release the object type */
1373
1374 /* Check if we're actually creating the directory object itself */
1375 if (!(ObpTypeDirectoryObject) ||
1377 {
1378 /* Check if the type directory exists */
1380 {
1381 /* Reference it */
1383 }
1384
1385 /* Cleanup the lookup context */
1387
1388 /* Return the object type and success */
1389 *ObjectType = LocalObjectType;
1390 return STATUS_SUCCESS;
1391 }
1392
1393 /* If we got here, then we failed */
1396}
1397
1398VOID
1399NTAPI
1401{
1402 POBJECT_HEADER ObjectHeader;
1403 PAGED_CODE();
1404
1405 /* Check if there is anything to free */
1406 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1407 if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
1408 (ObjectHeader->ObjectCreateInfo != NULL))
1409 {
1410 /* Free the create info */
1412 ObjectHeader->ObjectCreateInfo = NULL;
1413 }
1414}
1415
1416VOID
1417NTAPI
1419{
1420 ULONG i;
1422
1423 /* Loop our locks */
1424 for (i = 0; i < 4; i++)
1425 {
1426 /* Delete each one */
1427 ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1428 }
1429
1430 /* Delete our main mutex */
1432}
1433
1434/*++
1435* @name ObMakeTemporaryObject
1436* @implemented NT4
1437*
1438* The ObMakeTemporaryObject routine <FILLMEIN>
1439*
1440* @param ObjectBody
1441* <FILLMEIN>
1442*
1443* @return None.
1444*
1445* @remarks None.
1446*
1447*--*/
1448VOID
1449NTAPI
1451{
1452 PAGED_CODE();
1453
1454 /* Call the internal API */
1455 ObpSetPermanentObject(ObjectBody, FALSE);
1456}
1457
1458/*++
1459* @name NtMakeTemporaryObject
1460* @implemented NT4
1461*
1462* The NtMakeTemporaryObject routine <FILLMEIN>
1463*
1464* @param ObjectHandle
1465* <FILLMEIN>
1466*
1467* @return STATUS_SUCCESS or appropriate error value.
1468*
1469* @remarks None.
1470*
1471*--*/
1473NTAPI
1475{
1476 PVOID ObjectBody;
1478 PAGED_CODE();
1479
1480 /* Reference the object for DELETE access */
1481 Status = ObReferenceObjectByHandle(ObjectHandle,
1482 DELETE,
1483 NULL,
1485 &ObjectBody,
1486 NULL);
1487 if (Status != STATUS_SUCCESS) return Status;
1488
1489 /* Set it as temporary and dereference it */
1490 ObpSetPermanentObject(ObjectBody, FALSE);
1491 ObDereferenceObject(ObjectBody);
1492 return STATUS_SUCCESS;
1493}
1494
1495/*++
1496* @name NtMakePermanentObject
1497* @implemented NT4
1498*
1499* The NtMakePermanentObject routine <FILLMEIN>
1500*
1501* @param ObjectHandle
1502* <FILLMEIN>
1503*
1504* @return STATUS_SUCCESS or appropriate error value.
1505*
1506* @remarks None.
1507*
1508*--*/
1510NTAPI
1512{
1513 PVOID ObjectBody;
1516 PAGED_CODE();
1517
1518 /* Make sure that the caller has SeCreatePermanentPrivilege */
1520 {
1522 }
1523
1524 /* Reference the object */
1525 Status = ObReferenceObjectByHandle(ObjectHandle,
1526 0,
1527 NULL,
1529 &ObjectBody,
1530 NULL);
1531 if (Status != STATUS_SUCCESS) return Status;
1532
1533 /* Set it as permanent and dereference it */
1534 ObpSetPermanentObject(ObjectBody, TRUE);
1535 ObDereferenceObject(ObjectBody);
1536 return STATUS_SUCCESS;
1537}
1538
1539/*++
1540* @name NtQueryObject
1541* @implemented NT4
1542*
1543* The NtQueryObject routine <FILLMEIN>
1544*
1545* @param ObjectHandle
1546* <FILLMEIN>
1547*
1548* @param ObjectInformationClass
1549* <FILLMEIN>
1550*
1551* @param ObjectInformation
1552* <FILLMEIN>
1553*
1554* @param Length
1555* <FILLMEIN>
1556*
1557* @param ResultLength
1558* <FILLMEIN>
1559*
1560* @return STATUS_SUCCESS or appropriate error value.
1561*
1562* @remarks None.
1563*
1564*--*/
1566NTAPI
1570 IN ULONG Length,
1572{
1573 OBJECT_HANDLE_INFORMATION HandleInfo;
1574 POBJECT_HEADER ObjectHeader = NULL;
1576 POBJECT_BASIC_INFORMATION BasicInfo;
1577 ULONG InfoLength = 0;
1578 PVOID Object = NULL;
1580 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1584 PAGED_CODE();
1585
1586 /* Check if the caller is from user mode */
1587 if (PreviousMode != KernelMode)
1588 {
1589 /* Protect validation with SEH */
1590 _SEH2_TRY
1591 {
1592 /* Probe the input structure */
1594
1595 /* If we have a result length, probe it too */
1597 }
1599 {
1600 /* Return the exception code */
1602 }
1603 _SEH2_END;
1604 }
1605
1606 /*
1607 * Make sure this isn't a generic type query, since the caller doesn't
1608 * have to give a handle for it
1609 */
1611 {
1612 /* Reference the object */
1613 Status = ObReferenceObjectByHandle(ObjectHandle,
1614 0,
1615 NULL,
1617 &Object,
1618 &HandleInfo);
1619 if (!NT_SUCCESS (Status)) return Status;
1620
1621 /* Get the object header */
1622 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1623 ObjectType = ObjectHeader->Type;
1624 }
1625
1626 _SEH2_TRY
1627 {
1628 /* Check the information class */
1629 switch (ObjectInformationClass)
1630 {
1631 /* Basic info */
1633
1634 /* Validate length */
1635 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1636 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1637 {
1638 /* Fail */
1640 break;
1641 }
1642
1643 /* Fill out the basic information */
1645 BasicInfo->Attributes = HandleInfo.HandleAttributes;
1646 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1647 BasicInfo->HandleCount = ObjectHeader->HandleCount;
1648 BasicInfo->PointerCount = ObjectHeader->PointerCount;
1649
1650 /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1651 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1652 {
1653 /* Set the flag */
1654 BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1655 }
1656 if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1657 {
1658 /* Set the flag */
1659 BasicInfo->Attributes |= OBJ_PERMANENT;
1660 }
1661
1662 /* Copy quota information */
1663 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1664 if (ObjectQuota != NULL)
1665 {
1666 BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1667 BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1668 }
1669 else
1670 {
1671 BasicInfo->PagedPoolCharge = 0;
1672 BasicInfo->NonPagedPoolCharge = 0;
1673 }
1674
1675 /* Copy name information */
1676 BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader);
1677 BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length +
1678 sizeof(UNICODE_NULL);
1679
1680 /* Check if this is a symlink */
1681 if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1682 {
1683 /* Return the creation time */
1684 BasicInfo->CreationTime.QuadPart =
1685 ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1686 }
1687 else
1688 {
1689 /* Otherwise return 0 */
1690 BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1691 }
1692
1693 /* Copy security information */
1694 BasicInfo->SecurityDescriptorSize = 0;
1695 if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1696 ObjectHeader->SecurityDescriptor != NULL)
1697 {
1702
1703 ObjectType->TypeInfo.SecurityProcedure(Object,
1704 QuerySecurityDescriptor,
1706 NULL,
1707 &BasicInfo->SecurityDescriptorSize,
1708 &ObjectHeader->SecurityDescriptor,
1709 ObjectType->TypeInfo.PoolType,
1710 &ObjectType->TypeInfo.GenericMapping,
1712 }
1713
1714 /* Break out with success */
1716 break;
1717
1718 /* Name information */
1720
1721 /* Call the helper and break out */
1725 Length,
1726 &InfoLength);
1727 break;
1728
1729 /* Information about this type */
1731
1732 /* Call the helper and break out */
1733 Status = ObQueryTypeInfo(ObjectHeader->Type,
1736 Length,
1737 &InfoLength);
1738 break;
1739
1740 /* Information about all types */
1742 DPRINT1("NOT IMPLEMENTED!\n");
1743 InfoLength = Length;
1745 break;
1746
1747 /* Information about the handle flags */
1749
1750 /* Validate length */
1751 InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
1753 {
1755 break;
1756 }
1757
1758 /* Get the structure */
1761
1762 /* Set the flags */
1763 HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1764 HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1765 OBJ_PROTECT_CLOSE) != 0;
1766
1767 /* Break out with success */
1769 break;
1770
1771 /* Anything else */
1772 default:
1773
1774 /* Fail it */
1775 InfoLength = Length;
1777 break;
1778 }
1779
1780 /* Check if the caller wanted the return length */
1781 if (ResultLength)
1782 {
1783 /* Write the length */
1784 *ResultLength = InfoLength;
1785 }
1786 }
1788 {
1789 /* Otherwise, get the exception code */
1791 }
1792 _SEH2_END;
1793
1794 /* Dereference the object if we had referenced it */
1796
1797 /* Return status */
1798 return Status;
1799}
1800
1845NTAPI
1847 _In_ HANDLE ObjectHandle,
1851{
1854
1855 PAGED_CODE();
1856
1857 /* Validate the information class */
1858 switch (ObjectInformationClass)
1859 {
1861 {
1863
1864 /* Validate the length */
1865 if (Length != sizeof(HandleFlags))
1867
1868 /* Save the previous mode */
1870
1871 /* If we were called from user mode, probe and capture the
1872 * attribute buffer, otherwise just copy it directly. */
1873 if (PreviousMode != KernelMode)
1874 {
1875 _SEH2_TRY
1876 {
1877 ProbeForRead(ObjectInformation, sizeof(HandleFlags), sizeof(BOOLEAN));
1879 }
1881 {
1882 /* Return the exception code */
1884 }
1885 _SEH2_END;
1886 }
1887 else
1888 {
1890 }
1891
1892 Status = ObSetHandleAttributes(ObjectHandle, &HandleFlags, PreviousMode);
1893 break;
1894 }
1895
1897 {
1899
1902
1903 /* Only a system process can do this */
1906 {
1907 DPRINT1("Privilege not held\n");
1909 }
1910
1911 /* Get the object directory */
1912 Status = ObReferenceObjectByHandle(ObjectHandle,
1913 0,
1916 (PVOID*)&Directory,
1917 NULL);
1918 if (NT_SUCCESS(Status))
1919 {
1920 /* Setup a lookup context */
1921 OBP_LOOKUP_CONTEXT LookupContext;
1922 ObpInitializeLookupContext(&LookupContext);
1923
1924 /* Set the directory session ID */
1927 ObpReleaseDirectoryLock(Directory, &LookupContext);
1928
1929 /* We're done, release the context and dereference the directory */
1930 ObpReleaseLookupContext(&LookupContext);
1932 }
1933 break;
1934 }
1935
1936 default:
1937 /* Unsupported class */
1939 break;
1940 }
1941
1942 return Status;
1943}
1944
1945/* 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
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define OBJ_PROTECT_CLOSE
#define ObpDirectoryObjectType
Definition: ObTypes.cpp:170
#define ObpSymbolicLinkObjectType
Definition: ObTypes.cpp:171
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Type
Definition: Type.h:7
unsigned char BOOLEAN
Definition: actypes.h:127
#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 STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
LPWSTR Name
Definition: desk.c:124
#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
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#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:143
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:699
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
Status
Definition: gdiplustypes.h:24
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 FLG_MAINTAIN_OBJECT_TYPELIST
Definition: pstypes.h:64
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedCompareExchange
Definition: interlocked.h:119
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
ObjectType
Definition: metafile.c:88
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KernelMode
Definition: asm.h:38
@ 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
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3942
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Out_writes_bytes_to_(s, c)
Definition: no_sal2.h:190
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
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
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
OBJECT_TYPE
Definition: ntobjenum.h:13
@ FILE_OBJECT
Definition: ntobjenum.h:17
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 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_INVALID_INFO_CLASS
Definition: ntstatus.h:333
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN BOOLEAN SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:158
#define OBP_SYSTEM_PROCESS_QUOTA
Definition: ob.h:64
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
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
NTSTATUS NTAPI ObSetHandleAttributes(_In_ HANDLE Handle, _In_ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags, _In_ KPROCESSOR_MODE PreviousMode)
Sets the attributes (inheritable and protect-from-close) of an existing object handle.
Definition: obhandle.c:3327
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:456
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:612
ULONG ObpObjectsWithPoolQuota
Definition: oblife.c:31
POBJECT_TYPE ObpTypeObjectType
Definition: oblife.c:22
NTSTATUS NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1511
VOID NTAPI ObpDeleteObjectType(IN PVOID Object)
Definition: oblife.c:1418
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:1040
VOID FASTCALL ObpSetPermanentObject(IN PVOID ObjectBody, IN BOOLEAN Permanent)
Definition: oblife.c:267
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:948
VOID NTAPI ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: oblife.c:604
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:1567
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
VOID NTAPI ObDeleteCapturedInsertInfo(IN PVOID Object)
Definition: oblife.c:1400
PWCHAR NTAPI ObpAllocateObjectNameBuffer(IN ULONG Length, IN BOOLEAN UseLookaside, IN OUT PUNICODE_STRING ObjectName)
Definition: oblife.c:302
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1137
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:377
GENERAL_LOOKASIDE ObpNameBufferLookasideList
Definition: oblife.c:26
ULONG ObpObjectsCreated
Definition: oblife.c:31
WORK_QUEUE_ITEM ObpReaperWorkItem
Definition: oblife.c:28
NTSTATUS NTAPI NtSetInformationObject(_In_ HANDLE ObjectHandle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _In_reads_bytes_(Length) PVOID ObjectInformation, _In_ ULONG Length)
Sets information for an object or for a handle to an object.
Definition: oblife.c:1846
VOID NTAPI ObpReapObject(IN PVOID Parameter)
Definition: oblife.c:221
VOID NTAPI ObpDeleteObject(IN PVOID Object, IN BOOLEAN CalledFromWorkerThread)
Definition: oblife.c:147
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1450
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
Definition: oblife.c:26
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1474
ULONG ObpObjectsWithHandleDB
Definition: oblife.c:32
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:891
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:493
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
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
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
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_VOLATILE
Definition: pseh2_64.h:208
#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
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#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
_In_ PVOID Context
Definition: storport.h:2269
ACCESS_MASK GrantedAccess
Definition: winternl.h:2680
ULONG HandleCount
Definition: obtypes.h:447
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:460
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:461
POBJECT_DIRECTORY Directory
Definition: obtypes.h:434
UNICODE_STRING Name
Definition: obtypes.h:435
PEPROCESS ExclusiveProcess
Definition: obtypes.h:478
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:505
volatile PVOID NextToFree
Definition: obtypes.h:493
UCHAR Flags
Definition: obtypes.h:499
LONG_PTR HandleCount
Definition: obtypes.h:492
LONG_PTR PointerCount
Definition: obtypes.h:489
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:502
POBJECT_TYPE Type
Definition: obtypes.h:495
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:373
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:367
ULONG TotalNumberOfHandles
Definition: obtypes.h:389
ULONG Index
Definition: obtypes.h:387
LIST_ENTRY TypeList
Definition: obtypes.h:384
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:390
ULONG TotalNumberOfObjects
Definition: obtypes.h:388
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:392
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:394
ERESOURCE Mutex
Definition: obtypes.h:383
ULONG Key
Definition: obtypes.h:393
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:391
UNICODE_STRING Name
Definition: obtypes.h:385
PVOID DefaultObject
Definition: obtypes.h:386
#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
unsigned char UCHAR
Definition: typedefs.h:53
#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
uint64_t ULONGLONG
Definition: typedefs.h:67
#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
#define OUT
Definition: typedefs.h:40
#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:3782
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4071
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3821
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
@ ObjectSessionInformation
Definition: winternl.h:1877
@ ObjectHandleFlagInformation
Definition: winternl.h:1876
@ ObjectTypesInformation
Definition: winternl.h:1875
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
_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
_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:336
#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