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