ReactOS 0.4.17-dev-1218-gfae4549
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
1042{
1044 return NULL;
1045}
1046
1048NTAPI
1053 IN OUT PVOID ParseContext OPTIONAL,
1054 IN ULONG ObjectSize,
1055 IN ULONG PagedPoolCharge OPTIONAL,
1056 IN ULONG NonPagedPoolCharge OPTIONAL,
1057 OUT PVOID *Object)
1058{
1060 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
1063
1064 /* Allocate a capture buffer */
1066 if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
1067
1068 /* Capture all the info */
1070 ProbeMode,
1071 AccessMode,
1072 FALSE,
1073 ObjectCreateInfo,
1074 &ObjectName);
1075 if (NT_SUCCESS(Status))
1076 {
1077 /* Validate attributes */
1078 if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
1079 {
1080 /* Fail */
1082 }
1083 else
1084 {
1085 /* Check if we have a paged charge */
1086 if (!PagedPoolCharge)
1087 {
1088 /* Save it */
1089 PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
1090 }
1091
1092 /* Check for nonpaged charge */
1093 if (!NonPagedPoolCharge)
1094 {
1095 /* Save it */
1096 NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1097 }
1098
1099 /* Write the pool charges */
1100 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1101 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1102
1103 /* Allocate the Object */
1104 Status = ObpAllocateObject(ObjectCreateInfo,
1105 &ObjectName,
1106 Type,
1107 ObjectSize,
1108 AccessMode,
1109 &Header);
1110 if (NT_SUCCESS(Status))
1111 {
1112 /* Return the Object */
1113 *Object = &Header->Body;
1114
1115 /* Check if this is a permanent object */
1116 if (Header->Flags & OB_FLAG_PERMANENT)
1117 {
1118 /* Do the privilege check */
1120 ProbeMode))
1121 {
1122 /* Fail */
1125 }
1126 }
1127
1128 /* Return status */
1129 return Status;
1130 }
1131 }
1132
1133 /* Release the Capture Info, we don't need it */
1134 ObpFreeObjectCreateInformation(ObjectCreateInfo);
1136 return Status;
1137 }
1138
1139 /* We failed, so release the Buffer */
1141 return Status;
1142}
1143
1145NTAPI
1147 IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
1150{
1152 POBJECT_TYPE LocalObjectType;
1153 ULONG HeaderSize;
1156 PWCHAR p;
1157 ULONG i;
1159 ANSI_STRING AnsiName;
1160 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1161
1162 /* Verify parameters */
1163 if (!(TypeName) ||
1164 !(TypeName->Length) ||
1165 (TypeName->Length % sizeof(WCHAR)) ||
1166 !(ObjectTypeInitializer) ||
1167 (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1168 (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1169 (ObjectTypeInitializer->MaintainHandleCount &&
1170 (!(ObjectTypeInitializer->OpenProcedure) &&
1171 !ObjectTypeInitializer->CloseProcedure)) ||
1172 ((!ObjectTypeInitializer->UseDefaultObject) &&
1173 (ObjectTypeInitializer->PoolType != NonPagedPool)))
1174 {
1175 /* Fail */
1177 }
1178
1179 /* Make sure the name doesn't have a separator */
1180 p = TypeName->Buffer;
1181 i = TypeName->Length / sizeof(WCHAR);
1182 while (i--)
1183 {
1184 /* Check for one and fail */
1186 }
1187
1188 /* Setup a lookup context */
1190
1191 /* Check if we've already created the directory of types */
1193 {
1194 /* Lock the lookup context */
1196
1197 /* Do the lookup */
1199 TypeName,
1201 FALSE,
1202 &Context))
1203 {
1204 /* We have already created it, so fail */
1207 }
1208 }
1209
1210 /* Now make a copy of the object name */
1212 TypeName->MaximumLength,
1213 OB_NAME_TAG);
1214 if (!ObjectName.Buffer)
1215 {
1216 /* Out of memory, fail */
1219 }
1220
1221 /* Set the length and copy the name */
1222 ObjectName.MaximumLength = TypeName->MaximumLength;
1223 RtlCopyUnicodeString(&ObjectName, TypeName);
1224
1225 /* Allocate the Object */
1227 &ObjectName,
1229 sizeof(OBJECT_TYPE),
1230 KernelMode,
1231 &Header);
1232 if (!NT_SUCCESS(Status))
1233 {
1234 /* Free the name and fail */
1236 ExFreePool(ObjectName.Buffer);
1237 return Status;
1238 }
1239
1240 /* Setup the flags and name */
1241 LocalObjectType = (POBJECT_TYPE)&Header->Body;
1242 LocalObjectType->Name = ObjectName;
1244
1245 /* Clear accounting data */
1246 LocalObjectType->TotalNumberOfObjects =
1247 LocalObjectType->TotalNumberOfHandles =
1248 LocalObjectType->HighWaterNumberOfObjects =
1249 LocalObjectType->HighWaterNumberOfHandles = 0;
1250
1251 /* Check if this is the first Object Type */
1253 {
1254 /* It is, so set this as the type object */
1255 ObpTypeObjectType = LocalObjectType;
1256 Header->Type = ObpTypeObjectType;
1257
1258 /* Set the hard-coded key and object count */
1259 LocalObjectType->TotalNumberOfObjects = 1;
1260 LocalObjectType->Key = TAG_OBJECT_TYPE;
1261 }
1262 else
1263 {
1264 /* Convert the tag to ASCII */
1265 Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1266 if (NT_SUCCESS(Status))
1267 {
1268 /* For every missing character, use a space */
1269 for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1270
1271 /* Set the key and free the converted name */
1272 LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1273 RtlFreeAnsiString(&AnsiName);
1274 }
1275 else
1276 {
1277 /* Just copy the characters */
1278 LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1279 }
1280 }
1281
1282 /* Set up the type information */
1283 LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1284 LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1285
1286 /* Check if we have to maintain a type list */
1288 {
1289 /* Enable support */
1290 LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1291 }
1292
1293 /* Calculate how much space our header'll take up */
1294 HeaderSize = sizeof(OBJECT_HEADER) +
1295 sizeof(OBJECT_HEADER_NAME_INFO) +
1296 (ObjectTypeInitializer->MaintainHandleCount ?
1297 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1298
1299 /* Check the pool type */
1300 if (ObjectTypeInitializer->PoolType == NonPagedPool)
1301 {
1302 /* Update the NonPaged Pool charge */
1303 LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1304 }
1305 else
1306 {
1307 /* Update the Paged Pool charge */
1308 LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1309 }
1310
1311 /* All objects types need a security procedure */
1312 if (!ObjectTypeInitializer->SecurityProcedure)
1313 {
1315 }
1316
1317 /* Select the Wait Object */
1318 if (LocalObjectType->TypeInfo.UseDefaultObject)
1319 {
1320 /* Add the SYNCHRONIZE access mask since it's waitable */
1321 LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1322
1323 /* Use the "Default Object", a simple event */
1324 LocalObjectType->DefaultObject = &ObpDefaultObject;
1325 }
1326 /* The File Object gets an optimized hack so it can be waited on */
1327 else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1328 {
1329 /* Wait on the File Object's event directly */
1331 Event));
1332 }
1333 else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1334 {
1335 /* Wait on the LPC Port's object directly */
1337 WaitEvent));
1338 }
1339 else
1340 {
1341 /* No default Object */
1342 LocalObjectType->DefaultObject = NULL;
1343 }
1344
1345 /* Initialize Object Type components */
1346 ExInitializeResourceLite(&LocalObjectType->Mutex);
1347 for (i = 0; i < 4; i++)
1348 {
1349 /* Initialize the object locks */
1350 ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1351 }
1352 InitializeListHead(&LocalObjectType->TypeList);
1353
1354 /* Lock the object type */
1356
1357 /* Get creator info and insert it into the type list */
1359 if (CreatorInfo)
1360 {
1362 &CreatorInfo->TypeList);
1363
1364 /* CORE-8423: Avoid inserting this a second time if someone creates a
1365 * handle to the object type (bug in Windows 2003) */
1366 Header->Flags &= ~OB_FLAG_CREATE_INFO;
1367 }
1368
1369 /* Set the index and the entry into the object type array */
1370 LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1371
1372 ASSERT(LocalObjectType->Index != 0);
1373
1374 if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1375 {
1376 /* It fits, insert it */
1377 ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1378 }
1379
1380 /* Release the object type */
1382
1383 /* Check if we're actually creating the directory object itself */
1384 if (!(ObpTypeDirectoryObject) ||
1386 {
1387 /* Check if the type directory exists */
1389 {
1390 /* Reference it */
1392 }
1393
1394 /* Cleanup the lookup context */
1396
1397 /* Return the object type and success */
1398 *ObjectType = LocalObjectType;
1399 return STATUS_SUCCESS;
1400 }
1401
1402 /* If we got here, then we failed */
1405}
1406
1407VOID
1408NTAPI
1410{
1411 POBJECT_HEADER ObjectHeader;
1412 PAGED_CODE();
1413
1414 /* Check if there is anything to free */
1415 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1416 if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
1417 (ObjectHeader->ObjectCreateInfo != NULL))
1418 {
1419 /* Free the create info */
1421 ObjectHeader->ObjectCreateInfo = NULL;
1422 }
1423}
1424
1425VOID
1426NTAPI
1428{
1429 ULONG i;
1431
1432 /* Loop our locks */
1433 for (i = 0; i < 4; i++)
1434 {
1435 /* Delete each one */
1436 ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1437 }
1438
1439 /* Delete our main mutex */
1441}
1442
1443/*++
1444* @name ObMakeTemporaryObject
1445* @implemented NT4
1446*
1447* The ObMakeTemporaryObject routine <FILLMEIN>
1448*
1449* @param ObjectBody
1450* <FILLMEIN>
1451*
1452* @return None.
1453*
1454* @remarks None.
1455*
1456*--*/
1457VOID
1458NTAPI
1460{
1461 PAGED_CODE();
1462
1463 /* Call the internal API */
1464 ObpSetPermanentObject(ObjectBody, FALSE);
1465}
1466
1467/*++
1468* @name NtMakeTemporaryObject
1469* @implemented NT4
1470*
1471* The NtMakeTemporaryObject routine <FILLMEIN>
1472*
1473* @param ObjectHandle
1474* <FILLMEIN>
1475*
1476* @return STATUS_SUCCESS or appropriate error value.
1477*
1478* @remarks None.
1479*
1480*--*/
1482NTAPI
1484{
1485 PVOID ObjectBody;
1487 PAGED_CODE();
1488
1489 /* Reference the object for DELETE access */
1490 Status = ObReferenceObjectByHandle(ObjectHandle,
1491 DELETE,
1492 NULL,
1494 &ObjectBody,
1495 NULL);
1496 if (Status != STATUS_SUCCESS) return Status;
1497
1498 /* Set it as temporary and dereference it */
1499 ObpSetPermanentObject(ObjectBody, FALSE);
1500 ObDereferenceObject(ObjectBody);
1501 return STATUS_SUCCESS;
1502}
1503
1504/*++
1505* @name NtMakePermanentObject
1506* @implemented NT4
1507*
1508* The NtMakePermanentObject routine <FILLMEIN>
1509*
1510* @param ObjectHandle
1511* <FILLMEIN>
1512*
1513* @return STATUS_SUCCESS or appropriate error value.
1514*
1515* @remarks None.
1516*
1517*--*/
1519NTAPI
1521{
1522 PVOID ObjectBody;
1525 PAGED_CODE();
1526
1527 /* Make sure that the caller has SeCreatePermanentPrivilege */
1529 {
1531 }
1532
1533 /* Reference the object */
1534 Status = ObReferenceObjectByHandle(ObjectHandle,
1535 0,
1536 NULL,
1538 &ObjectBody,
1539 NULL);
1540 if (Status != STATUS_SUCCESS) return Status;
1541
1542 /* Set it as permanent and dereference it */
1543 ObpSetPermanentObject(ObjectBody, TRUE);
1544 ObDereferenceObject(ObjectBody);
1545 return STATUS_SUCCESS;
1546}
1547
1548/*++
1549* @name NtQueryObject
1550* @implemented NT4
1551*
1552* The NtQueryObject routine <FILLMEIN>
1553*
1554* @param ObjectHandle
1555* <FILLMEIN>
1556*
1557* @param ObjectInformationClass
1558* <FILLMEIN>
1559*
1560* @param ObjectInformation
1561* <FILLMEIN>
1562*
1563* @param Length
1564* <FILLMEIN>
1565*
1566* @param ResultLength
1567* <FILLMEIN>
1568*
1569* @return STATUS_SUCCESS or appropriate error value.
1570*
1571* @remarks None.
1572*
1573*--*/
1575NTAPI
1579 IN ULONG Length,
1581{
1582 OBJECT_HANDLE_INFORMATION HandleInfo;
1583 POBJECT_HEADER ObjectHeader = NULL;
1585 POBJECT_BASIC_INFORMATION BasicInfo;
1586 ULONG InfoLength = 0;
1587 PVOID Object = NULL;
1589 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1593 PAGED_CODE();
1594
1595 /* Check if the caller is from user mode */
1596 if (PreviousMode != KernelMode)
1597 {
1598 /* Protect validation with SEH */
1599 _SEH2_TRY
1600 {
1601 /* Probe the input structure */
1603
1604 /* If we have a result length, probe it too */
1606 }
1608 {
1609 /* Return the exception code */
1611 }
1612 _SEH2_END;
1613 }
1614
1615 /*
1616 * Make sure this isn't a generic type query, since the caller doesn't
1617 * have to give a handle for it
1618 */
1620 {
1621 /* Reference the object */
1622 Status = ObReferenceObjectByHandle(ObjectHandle,
1623 0,
1624 NULL,
1626 &Object,
1627 &HandleInfo);
1628 if (!NT_SUCCESS (Status)) return Status;
1629
1630 /* Get the object header */
1631 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1632 ObjectType = ObjectHeader->Type;
1633 }
1634
1635 _SEH2_TRY
1636 {
1637 /* Check the information class */
1638 switch (ObjectInformationClass)
1639 {
1640 /* Basic info */
1642
1643 /* Validate length */
1644 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1645 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1646 {
1647 /* Fail */
1649 break;
1650 }
1651
1652 /* Fill out the basic information */
1654 BasicInfo->Attributes = HandleInfo.HandleAttributes;
1655 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1656 BasicInfo->HandleCount = ObjectHeader->HandleCount;
1657 BasicInfo->PointerCount = ObjectHeader->PointerCount;
1658
1659 /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1660 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1661 {
1662 /* Set the flag */
1663 BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1664 }
1665 if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1666 {
1667 /* Set the flag */
1668 BasicInfo->Attributes |= OBJ_PERMANENT;
1669 }
1670
1671 /* Copy quota information */
1672 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1673 if (ObjectQuota != NULL)
1674 {
1675 BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1676 BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1677 }
1678 else
1679 {
1680 BasicInfo->PagedPoolCharge = 0;
1681 BasicInfo->NonPagedPoolCharge = 0;
1682 }
1683
1684 /* Copy name information */
1685 BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader);
1686 BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length +
1687 sizeof(UNICODE_NULL);
1688
1689 /* Check if this is a symlink */
1690 if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1691 {
1692 /* Return the creation time */
1693 BasicInfo->CreationTime.QuadPart =
1694 ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1695 }
1696 else
1697 {
1698 /* Otherwise return 0 */
1699 BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1700 }
1701
1702 /* Copy security information */
1703 BasicInfo->SecurityDescriptorSize = 0;
1704 if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1705 ObjectHeader->SecurityDescriptor != NULL)
1706 {
1711
1712 ObjectType->TypeInfo.SecurityProcedure(Object,
1713 QuerySecurityDescriptor,
1715 NULL,
1716 &BasicInfo->SecurityDescriptorSize,
1717 &ObjectHeader->SecurityDescriptor,
1718 ObjectType->TypeInfo.PoolType,
1719 &ObjectType->TypeInfo.GenericMapping,
1721 }
1722
1723 /* Break out with success */
1725 break;
1726
1727 /* Name information */
1729
1730 /* Call the helper and break out */
1734 Length,
1735 &InfoLength);
1736 break;
1737
1738 /* Information about this type */
1740
1741 /* Call the helper and break out */
1742 Status = ObQueryTypeInfo(ObjectHeader->Type,
1745 Length,
1746 &InfoLength);
1747 break;
1748
1749 /* Information about all types */
1751 DPRINT1("NOT IMPLEMENTED!\n");
1752 InfoLength = Length;
1754 break;
1755
1756 /* Information about the handle flags */
1758
1759 /* Validate length */
1760 InfoLength = sizeof(OBJECT_HANDLE_FLAG_INFORMATION);
1762 {
1764 break;
1765 }
1766
1767 /* Get the structure */
1769
1770 /* Set the flags */
1771 HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1772 HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1773 OBJ_PROTECT_CLOSE) != 0;
1774
1775 /* Break out with success */
1777 break;
1778
1779 /* Anything else */
1780 default:
1781
1782 /* Fail it */
1783 InfoLength = Length;
1785 break;
1786 }
1787
1788 /* Check if the caller wanted the return length */
1789 if (ResultLength)
1790 {
1791 /* Write the length */
1792 *ResultLength = InfoLength;
1793 }
1794 }
1796 {
1797 /* Otherwise, get the exception code */
1799 }
1800 _SEH2_END;
1801
1802 /* Dereference the object if we had referenced it */
1804
1805 /* Return status */
1806 return Status;
1807}
1808
1853NTAPI
1855 _In_ HANDLE ObjectHandle,
1859{
1862
1863 PAGED_CODE();
1864
1865 /* Validate the information class */
1866 switch (ObjectInformationClass)
1867 {
1869 {
1871
1872 /* Validate the length */
1873 if (Length != sizeof(HandleFlags))
1875
1876 /* Save the previous mode */
1878
1879 /* If we were called from user mode, probe and capture the
1880 * attribute buffer, otherwise just copy it directly. */
1881 if (PreviousMode != KernelMode)
1882 {
1883 _SEH2_TRY
1884 {
1885 ProbeForRead(ObjectInformation, sizeof(HandleFlags), sizeof(BOOLEAN));
1887 }
1889 {
1890 /* Return the exception code */
1892 }
1893 _SEH2_END;
1894 }
1895 else
1896 {
1898 }
1899
1900 Status = ObSetHandleAttributes(ObjectHandle, &HandleFlags, PreviousMode);
1901 break;
1902 }
1903
1905 {
1907
1910
1911 /* Only a system process can do this */
1914 {
1915 DPRINT1("Privilege not held\n");
1917 }
1918
1919 /* Get the object directory */
1920 Status = ObReferenceObjectByHandle(ObjectHandle,
1921 0,
1924 (PVOID*)&Directory,
1925 NULL);
1926 if (NT_SUCCESS(Status))
1927 {
1928 /* Setup a lookup context */
1929 OBP_LOOKUP_CONTEXT LookupContext;
1930 ObpInitializeLookupContext(&LookupContext);
1931
1932 /* Set the directory session ID */
1935 ObpReleaseDirectoryLock(Directory, &LookupContext);
1936
1937 /* We're done, release the context and dereference the directory */
1938 ObpReleaseLookupContext(&LookupContext);
1940 }
1941 break;
1942 }
1943
1944 default:
1945 /* Unsupported class */
1947 break;
1948 }
1949
1950 return Status;
1951}
1952
1953/* 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
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
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
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#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
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
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:104
struct _OBJECT_HANDLE_FLAG_INFORMATION OBJECT_HANDLE_FLAG_INFORMATION
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:89
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:86
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:95
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:112
struct _OBJECT_HEADER_HANDLE_INFO * POBJECT_HEADER_HANDLE_INFO
#define OB_FLAG_CREATOR_INFO
Definition: obtypes.h:85
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:83
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:108
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
enum _OBJECT_INFORMATION_CLASS OBJECT_INFORMATION_CLASS
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:84
struct _OBJECT_HEADER_CREATOR_INFO OBJECT_HEADER_CREATOR_INFO
#define OB_FLAG_PERMANENT
Definition: obtypes.h:87
struct _OBJECT_HEADER_NAME_INFO * POBJECT_HEADER_NAME_INFO
@ ObjectSessionInformation
Definition: obtypes.h:278
@ ObjectHandleFlagInformation
Definition: obtypes.h:276
@ ObjectTypesInformation
Definition: obtypes.h:275
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:90
struct _OBJECT_HANDLE_FLAG_INFORMATION * POBJECT_HANDLE_FLAG_INFORMATION
struct _OBJECT_HEADER_QUOTA_INFO OBJECT_HEADER_QUOTA_INFO
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:77
#define OB_FLAG_SECURITY
Definition: obtypes.h:88
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
struct _OBJECT_TYPE_INFORMATION OBJECT_TYPE_INFORMATION
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:78
struct _OBJECT_HEADER_HANDLE_INFO OBJECT_HEADER_HANDLE_INFO
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3962
#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:1163
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1173
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_FLAG_INFORMATION HandleFlags, _In_ KPROCESSOR_MODE PreviousMode)
Sets the attributes (inheritable and protect-from-close) of an existing object handle.
Definition: obhandle.c:3341
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 FASTCALL ObGetObjectType(_In_ PVOID Object)
Definition: oblife.c:1040
POBJECT_TYPE ObpTypeObjectType
Definition: oblife.c:22
NTSTATUS NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1520
VOID NTAPI ObpDeleteObjectType(IN PVOID Object)
Definition: oblife.c:1427
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:1049
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:58
NTSTATUS NTAPI NtQueryObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG Length, OUT PULONG ResultLength OPTIONAL)
Definition: oblife.c:1576
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
VOID NTAPI ObDeleteCapturedInsertInfo(IN PVOID Object)
Definition: oblife.c:1409
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:1146
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:1854
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:1459
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:1483
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
#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
LARGE_INTEGER CreationTime
Definition: obtypes.h:305
ACCESS_MASK GrantedAccess
Definition: obtypes.h:296
ULONG HandleCount
Definition: obtypes.h:475
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:488
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:489
POBJECT_DIRECTORY Directory
Definition: obtypes.h:462
UNICODE_STRING Name
Definition: obtypes.h:463
PEPROCESS ExclusiveProcess
Definition: obtypes.h:506
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:533
volatile PVOID NextToFree
Definition: obtypes.h:521
UCHAR Flags
Definition: obtypes.h:527
LONG_PTR HandleCount
Definition: obtypes.h:520
LONG_PTR PointerCount
Definition: obtypes.h:517
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:530
POBJECT_TYPE Type
Definition: obtypes.h:523
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:401
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:395
ULONG TotalNumberOfHandles
Definition: obtypes.h:417
ULONG Index
Definition: obtypes.h:415
LIST_ENTRY TypeList
Definition: obtypes.h:412
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:418
ULONG TotalNumberOfObjects
Definition: obtypes.h:416
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:420
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:422
ERESOURCE Mutex
Definition: obtypes.h:411
ULONG Key
Definition: obtypes.h:421
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:419
UNICODE_STRING Name
Definition: obtypes.h:413
PVOID DefaultObject
Definition: obtypes.h:414
#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
_In_ PGUID _In_ ULONG _Out_ PULONG ResultLength
Definition: ucxcontroller.h:83
_Must_inspect_result_ _In_ UCXENDPOINT _In_ PVOID Tag
Definition: ucxendpoint.h:325
#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_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3821
_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
_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