ReactOS  0.4.12-dev-685-gf36cbf7
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  DPRINT("FIXME: Should return quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
114 #if 0
115  PsReturnSharedPoolQuota(ObjectHeader->QuotaBlockCharged,
116  PagedPoolCharge,
117  NonPagedPoolCharge);
118 #endif
119 
120  }
121  }
122 
123  /* Check if a handle database was active */
124  if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
125  {
126  /* Free it */
127  ExFreePool(HandleInfo->HandleCountDatabase);
128  HandleInfo->HandleCountDatabase = NULL;
129  }
130 
131  /* Check if we have a name */
132  if ((NameInfo) && (NameInfo->Name.Buffer))
133  {
134  /* Free it */
135  ExFreePool(NameInfo->Name.Buffer);
136  NameInfo->Name.Buffer = NULL;
137  }
138 
139  /* Catch invalid access */
140  Header->Type = (POBJECT_TYPE)(ULONG_PTR)0xBAADB0B0BAADB0B0ULL;
141 
142  /* Free the object using the same allocation tag */
143  ExFreePoolWithTag(HeaderLocation, ObjectType->Key);
144 }
145 
146 VOID
147 NTAPI
149  IN BOOLEAN CalledFromWorkerThread)
150 {
153  POBJECT_HEADER_NAME_INFO NameInfo;
154  POBJECT_HEADER_CREATOR_INFO CreatorInfo;
155  KIRQL CalloutIrql;
156  PAGED_CODE();
157 
158  /* Get the header and type */
160  ObjectType = Header->Type;
161 
162  /* Get creator and name information */
164  CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header);
165 
166  /* Check if the object is on a type list */
167  if ((CreatorInfo) && !(IsListEmpty(&CreatorInfo->TypeList)))
168  {
169  /* Lock the object type */
171 
172  /* Remove the object from the type list */
173  RemoveEntryList(&CreatorInfo->TypeList);
174 
175  /* Release the lock */
177  }
178 
179  /* Check if we have a name */
180  if ((NameInfo) && (NameInfo->Name.Buffer))
181  {
182  /* Free it */
183  ExFreePool(NameInfo->Name.Buffer);
184  RtlInitEmptyUnicodeString(&NameInfo->Name, NULL, 0);
185  }
186 
187  /* Check if we have a security descriptor */
188  if (Header->SecurityDescriptor)
189  {
190  /* Call the security procedure to delete it */
191  ObpCalloutStart(&CalloutIrql);
192  ObjectType->TypeInfo.SecurityProcedure(Object,
193  DeleteSecurityDescriptor,
194  0,
195  NULL,
196  NULL,
197  &Header->SecurityDescriptor,
198  0,
199  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 
219 VOID
220 NTAPI
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 *--*/
265 VOID
266 FASTCALL
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 
300 PWCHAR
301 NTAPI
303  IN BOOLEAN UseLookaside,
305 {
307  PVOID Buffer;
308 
309  /* Set the maximum length to the length plus the terminator */
310  MaximumLength = Length + sizeof(UNICODE_NULL);
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  }
329  OB_NAME_TAG);
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 
345 VOID
346 NTAPI
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 
375 NTSTATUS
376 NTAPI
380  IN BOOLEAN UseLookaside)
381 {
383  ULONG StringLength;
384  PWCHAR _SEH2_VOLATILE StringBuffer = NULL;
385  UNICODE_STRING LocalName;
386  PAGED_CODE();
387 
388  /* Initialize the Input String */
389  RtlInitEmptyUnicodeString(CapturedName, NULL, 0);
390 
391  /* Protect everything */
392  _SEH2_TRY
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 
454 NTSTATUS
455 NTAPI
458  IN KPROCESSOR_MODE CreatorMode,
459  IN BOOLEAN AllocateFromLookaside,
460  IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
462 {
463  ULONG SdCharge, QuotaInfoSize;
466  PSECURITY_QUALITY_OF_SERVICE SecurityQos;
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 */
474  _SEH2_TRY
475  {
476  /* Check if we got attributes */
477  if (ObjectAttributes)
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 */
505  if (SecurityDescriptor)
506  {
507  /* Capture it. Note: This has an implicit memory barrier due
508  to the function call, so cleanup is safe here.) */
510  AccessMode,
511  NonPagedPool,
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,
577  AccessMode,
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 
602 VOID
603 NTAPI
605 {
606  /* Call the macro. We use this function to isolate Ob internals from Io */
608 }
609 
610 NTSTATUS
611 NTAPI
615  IN ULONG ObjectSize,
617  IN POBJECT_HEADER *ObjectHeader)
618 {
620  ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
621  POBJECT_HEADER_HANDLE_INFO HandleInfo;
622  POBJECT_HEADER_NAME_INFO NameInfo;
623  POBJECT_HEADER_CREATOR_INFO CreatorInfo;
624  POBJECT_HEADER_QUOTA_INFO QuotaInfo;
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 */
638  Tag = 'TjbO';
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 */
731  QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)Header;
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 */
743  HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
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 */
752  NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
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 */
823  Header->Flags = OB_FLAG_CREATE_INFO;
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 
873 NTSTATUS
874 NTAPI
876  OUT POBJECT_TYPE_INFORMATION ObjectTypeInfo,
877  IN ULONG Length,
879 {
881  PWSTR InfoBuffer;
882 
883  /* Enter SEH */
884  _SEH2_TRY
885  {
886  /* Set return length aligned to 4-byte boundary */
887  *ReturnLength += sizeof(*ObjectTypeInfo) +
888  ALIGN_UP(ObjectType->Name.MaximumLength, ULONG);
889 
890  /* Check if thats too much though. */
891  if (Length < *ReturnLength)
892  {
894  }
895 
896  /* Build the data */
897  ObjectTypeInfo->TotalNumberOfHandles =
898  ObjectType->TotalNumberOfHandles;
899  ObjectTypeInfo->TotalNumberOfObjects =
900  ObjectType->TotalNumberOfObjects;
901  ObjectTypeInfo->HighWaterNumberOfHandles =
902  ObjectType->HighWaterNumberOfHandles;
903  ObjectTypeInfo->HighWaterNumberOfObjects =
904  ObjectType->HighWaterNumberOfObjects;
905  ObjectTypeInfo->PoolType =
906  ObjectType->TypeInfo.PoolType;
907  ObjectTypeInfo->DefaultNonPagedPoolCharge =
908  ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
909  ObjectTypeInfo->DefaultPagedPoolCharge =
910  ObjectType->TypeInfo.DefaultPagedPoolCharge;
911  ObjectTypeInfo->ValidAccessMask =
912  ObjectType->TypeInfo.ValidAccessMask;
913  ObjectTypeInfo->SecurityRequired =
914  ObjectType->TypeInfo.SecurityRequired;
915  ObjectTypeInfo->InvalidAttributes =
916  ObjectType->TypeInfo.InvalidAttributes;
917  ObjectTypeInfo->GenericMapping =
918  ObjectType->TypeInfo.GenericMapping;
919  ObjectTypeInfo->MaintainHandleCount =
920  ObjectType->TypeInfo.MaintainHandleCount;
921 
922  /* Setup the name buffer */
923  InfoBuffer = (PWSTR)(ObjectTypeInfo + 1);
924  ObjectTypeInfo->TypeName.Buffer = InfoBuffer;
925  ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength;
926  ObjectTypeInfo->TypeName.Length = ObjectType->Name.Length;
927 
928  /* Copy it */
929  RtlCopyMemory(InfoBuffer,
930  ObjectType->Name.Buffer,
931  ObjectType->Name.Length);
932 
933  /* Null-terminate it */
934  (InfoBuffer)[ObjectType->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
935  }
937  {
938  /* Otherwise, get the exception code */
940  }
941  _SEH2_END;
942 
943  /* Return status to caller */
944  return Status;
945 }
946 
947 
948 /* PUBLIC FUNCTIONS **********************************************************/
949 
950 NTSTATUS
951 NTAPI
956  IN OUT PVOID ParseContext OPTIONAL,
957  IN ULONG ObjectSize,
958  IN ULONG PagedPoolCharge OPTIONAL,
959  IN ULONG NonPagedPoolCharge OPTIONAL,
960  OUT PVOID *Object)
961 {
963  POBJECT_CREATE_INFORMATION ObjectCreateInfo;
966 
967  /* Allocate a capture buffer */
969  if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
970 
971  /* Capture all the info */
973  ProbeMode,
974  AccessMode,
975  FALSE,
976  ObjectCreateInfo,
977  &ObjectName);
978  if (NT_SUCCESS(Status))
979  {
980  /* Validate attributes */
981  if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
982  {
983  /* Fail */
985  }
986  else
987  {
988  /* Check if we have a paged charge */
989  if (!PagedPoolCharge)
990  {
991  /* Save it */
992  PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
993  }
994 
995  /* Check for nonpaged charge */
996  if (!NonPagedPoolCharge)
997  {
998  /* Save it */
999  NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1000  }
1001 
1002  /* Write the pool charges */
1003  ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1004  ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1005 
1006  /* Allocate the Object */
1007  Status = ObpAllocateObject(ObjectCreateInfo,
1008  &ObjectName,
1009  Type,
1010  ObjectSize,
1011  AccessMode,
1012  &Header);
1013  if (NT_SUCCESS(Status))
1014  {
1015  /* Return the Object */
1016  *Object = &Header->Body;
1017 
1018  /* Check if this is a permanent object */
1019  if (Header->Flags & OB_FLAG_PERMANENT)
1020  {
1021  /* Do the privilege check */
1023  ProbeMode))
1024  {
1025  /* Fail */
1028  }
1029  }
1030 
1031  /* Return status */
1032  return Status;
1033  }
1034  }
1035 
1036  /* Release the Capture Info, we don't need it */
1037  ObpFreeObjectCreateInformation(ObjectCreateInfo);
1039  }
1040 
1041  /* We failed, so release the Buffer */
1043  return Status;
1044 }
1045 
1046 NTSTATUS
1047 NTAPI
1049  IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
1050  IN PVOID Reserved,
1052 {
1054  POBJECT_TYPE LocalObjectType;
1055  ULONG HeaderSize;
1056  NTSTATUS Status;
1058  PWCHAR p;
1059  ULONG i;
1061  ANSI_STRING AnsiName;
1062  POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1063 
1064  /* Verify parameters */
1065  if (!(TypeName) ||
1066  !(TypeName->Length) ||
1067  (TypeName->Length % sizeof(WCHAR)) ||
1068  !(ObjectTypeInitializer) ||
1069  (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1070  (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1071  (ObjectTypeInitializer->MaintainHandleCount &&
1072  (!(ObjectTypeInitializer->OpenProcedure) &&
1073  !ObjectTypeInitializer->CloseProcedure)) ||
1074  ((!ObjectTypeInitializer->UseDefaultObject) &&
1075  (ObjectTypeInitializer->PoolType != NonPagedPool)))
1076  {
1077  /* Fail */
1078  return STATUS_INVALID_PARAMETER;
1079  }
1080 
1081  /* Make sure the name doesn't have a separator */
1082  p = TypeName->Buffer;
1083  i = TypeName->Length / sizeof(WCHAR);
1084  while (i--)
1085  {
1086  /* Check for one and fail */
1088  }
1089 
1090  /* Setup a lookup context */
1092 
1093  /* Check if we've already created the directory of types */
1095  {
1096  /* Acquire the directory lock */
1098 
1099  /* Do the lookup */
1101  TypeName,
1103  FALSE,
1104  &Context))
1105  {
1106  /* We have already created it, so fail */
1109  }
1110  }
1111 
1112  /* Now make a copy of the object name */
1114  TypeName->MaximumLength,
1115  OB_NAME_TAG);
1116  if (!ObjectName.Buffer)
1117  {
1118  /* Out of memory, fail */
1121  }
1122 
1123  /* Set the length and copy the name */
1124  ObjectName.MaximumLength = TypeName->MaximumLength;
1125  RtlCopyUnicodeString(&ObjectName, TypeName);
1126 
1127  /* Allocate the Object */
1129  &ObjectName,
1131  sizeof(OBJECT_TYPE),
1132  KernelMode,
1133  &Header);
1134  if (!NT_SUCCESS(Status))
1135  {
1136  /* Free the name and fail */
1138  ExFreePool(ObjectName.Buffer);
1139  return Status;
1140  }
1141 
1142  /* Setup the flags and name */
1143  LocalObjectType = (POBJECT_TYPE)&Header->Body;
1144  LocalObjectType->Name = ObjectName;
1146 
1147  /* Clear accounting data */
1148  LocalObjectType->TotalNumberOfObjects =
1149  LocalObjectType->TotalNumberOfHandles =
1150  LocalObjectType->HighWaterNumberOfObjects =
1151  LocalObjectType->HighWaterNumberOfHandles = 0;
1152 
1153  /* Check if this is the first Object Type */
1155  {
1156  /* It is, so set this as the type object */
1157  ObpTypeObjectType = LocalObjectType;
1158  Header->Type = ObpTypeObjectType;
1159 
1160  /* Set the hard-coded key and object count */
1161  LocalObjectType->TotalNumberOfObjects = 1;
1162  LocalObjectType->Key = 'TjbO';
1163  }
1164  else
1165  {
1166  /* Convert the tag to ASCII */
1167  Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1168  if (NT_SUCCESS(Status))
1169  {
1170  /* For every missing character, use a space */
1171  for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1172 
1173  /* Set the key and free the converted name */
1174  LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1175  RtlFreeAnsiString(&AnsiName);
1176  }
1177  else
1178  {
1179  /* Just copy the characters */
1180  LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1181  }
1182  }
1183 
1184  /* Set up the type information */
1185  LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1186  LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1187 
1188  /* Check if we have to maintain a type list */
1190  {
1191  /* Enable support */
1192  LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1193  }
1194 
1195  /* Calculate how much space our header'll take up */
1196  HeaderSize = sizeof(OBJECT_HEADER) +
1197  sizeof(OBJECT_HEADER_NAME_INFO) +
1198  (ObjectTypeInitializer->MaintainHandleCount ?
1199  sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1200 
1201  /* Check the pool type */
1202  if (ObjectTypeInitializer->PoolType == NonPagedPool)
1203  {
1204  /* Update the NonPaged Pool charge */
1205  LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1206  }
1207  else
1208  {
1209  /* Update the Paged Pool charge */
1210  LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1211  }
1212 
1213  /* All objects types need a security procedure */
1214  if (!ObjectTypeInitializer->SecurityProcedure)
1215  {
1217  }
1218 
1219  /* Select the Wait Object */
1220  if (LocalObjectType->TypeInfo.UseDefaultObject)
1221  {
1222  /* Add the SYNCHRONIZE access mask since it's waitable */
1223  LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1224 
1225  /* Use the "Default Object", a simple event */
1226  LocalObjectType->DefaultObject = &ObpDefaultObject;
1227  }
1228  /* The File Object gets an optimized hack so it can be waited on */
1229  else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1230  {
1231  /* Wait on the File Object's event directly */
1232  LocalObjectType->DefaultObject = UlongToPtr(FIELD_OFFSET(FILE_OBJECT,
1233  Event));
1234  }
1235  else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1236  {
1237  /* Wait on the LPC Port's object directly */
1239  WaitEvent));
1240  }
1241  else
1242  {
1243  /* No default Object */
1244  LocalObjectType->DefaultObject = NULL;
1245  }
1246 
1247  /* Initialize Object Type components */
1248  ExInitializeResourceLite(&LocalObjectType->Mutex);
1249  for (i = 0; i < 4; i++)
1250  {
1251  /* Initialize the object locks */
1252  ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1253  }
1254  InitializeListHead(&LocalObjectType->TypeList);
1255 
1256  /* Lock the object type */
1258 
1259  /* Get creator info and insert it into the type list */
1260  CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header);
1261  if (CreatorInfo)
1262  {
1264  &CreatorInfo->TypeList);
1265 
1266  /* CORE-8423: Avoid inserting this a second time if someone creates a
1267  * handle to the object type (bug in Windows 2003) */
1268  Header->Flags &= ~OB_FLAG_CREATE_INFO;
1269  }
1270 
1271  /* Set the index and the entry into the object type array */
1272  LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1273 
1274  ASSERT(LocalObjectType->Index != 0);
1275 
1276  if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1277  {
1278  /* It fits, insert it */
1279  ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1280  }
1281 
1282  /* Release the object type */
1284 
1285  /* Check if we're actually creating the directory object itself */
1286  if (!(ObpTypeDirectoryObject) ||
1288  {
1289  /* Check if the type directory exists */
1291  {
1292  /* Reference it */
1294  }
1295 
1296  /* Cleanup the lookup context */
1298 
1299  /* Return the object type and success */
1300  *ObjectType = LocalObjectType;
1301  return STATUS_SUCCESS;
1302  }
1303 
1304  /* If we got here, then we failed */
1307 }
1308 
1309 VOID
1310 NTAPI
1312 {
1313  POBJECT_HEADER ObjectHeader;
1314  PAGED_CODE();
1315 
1316  /* Check if there is anything to free */
1317  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1318  if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
1319  (ObjectHeader->ObjectCreateInfo != NULL))
1320  {
1321  /* Free the create info */
1323  ObjectHeader->ObjectCreateInfo = NULL;
1324  }
1325 }
1326 
1327 VOID
1328 NTAPI
1330 {
1331  ULONG i;
1333 
1334  /* Loop our locks */
1335  for (i = 0; i < 4; i++)
1336  {
1337  /* Delete each one */
1338  ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1339  }
1340 
1341  /* Delete our main mutex */
1343 }
1344 
1345 /*++
1346 * @name ObMakeTemporaryObject
1347 * @implemented NT4
1348 *
1349 * The ObMakeTemporaryObject routine <FILLMEIN>
1350 *
1351 * @param ObjectBody
1352 * <FILLMEIN>
1353 *
1354 * @return None.
1355 *
1356 * @remarks None.
1357 *
1358 *--*/
1359 VOID
1360 NTAPI
1362 {
1363  PAGED_CODE();
1364 
1365  /* Call the internal API */
1366  ObpSetPermanentObject(ObjectBody, FALSE);
1367 }
1368 
1369 /*++
1370 * @name NtMakeTemporaryObject
1371 * @implemented NT4
1372 *
1373 * The NtMakeTemporaryObject routine <FILLMEIN>
1374 *
1375 * @param ObjectHandle
1376 * <FILLMEIN>
1377 *
1378 * @return STATUS_SUCCESS or appropriate error value.
1379 *
1380 * @remarks None.
1381 *
1382 *--*/
1383 NTSTATUS
1384 NTAPI
1386 {
1387  PVOID ObjectBody;
1388  NTSTATUS Status;
1389  PAGED_CODE();
1390 
1391  /* Reference the object for DELETE access */
1392  Status = ObReferenceObjectByHandle(ObjectHandle,
1393  DELETE,
1394  NULL,
1396  &ObjectBody,
1397  NULL);
1398  if (Status != STATUS_SUCCESS) return Status;
1399 
1400  /* Set it as temporary and dereference it */
1401  ObpSetPermanentObject(ObjectBody, FALSE);
1402  ObDereferenceObject(ObjectBody);
1403  return STATUS_SUCCESS;
1404 }
1405 
1406 /*++
1407 * @name NtMakePermanentObject
1408 * @implemented NT4
1409 *
1410 * The NtMakePermanentObject routine <FILLMEIN>
1411 *
1412 * @param ObjectHandle
1413 * <FILLMEIN>
1414 *
1415 * @return STATUS_SUCCESS or appropriate error value.
1416 *
1417 * @remarks None.
1418 *
1419 *--*/
1420 NTSTATUS
1421 NTAPI
1423 {
1424  PVOID ObjectBody;
1425  NTSTATUS Status;
1427  PAGED_CODE();
1428 
1429  /* Make sure that the caller has SeCreatePermanentPrivilege */
1431  {
1433  }
1434 
1435  /* Reference the object */
1436  Status = ObReferenceObjectByHandle(ObjectHandle,
1437  0,
1438  NULL,
1439  PreviousMode,
1440  &ObjectBody,
1441  NULL);
1442  if (Status != STATUS_SUCCESS) return Status;
1443 
1444  /* Set it as permanent and dereference it */
1445  ObpSetPermanentObject(ObjectBody, TRUE);
1446  ObDereferenceObject(ObjectBody);
1447  return STATUS_SUCCESS;
1448 }
1449 
1450 /*++
1451 * @name NtQueryObject
1452 * @implemented NT4
1453 *
1454 * The NtQueryObject routine <FILLMEIN>
1455 *
1456 * @param ObjectHandle
1457 * <FILLMEIN>
1458 *
1459 * @param ObjectInformationClass
1460 * <FILLMEIN>
1461 *
1462 * @param ObjectInformation
1463 * <FILLMEIN>
1464 *
1465 * @param Length
1466 * <FILLMEIN>
1467 *
1468 * @param ResultLength
1469 * <FILLMEIN>
1470 *
1471 * @return STATUS_SUCCESS or appropriate error value.
1472 *
1473 * @remarks None.
1474 *
1475 *--*/
1476 NTSTATUS
1477 NTAPI
1478 NtQueryObject(IN HANDLE ObjectHandle,
1481  IN ULONG Length,
1483 {
1484  OBJECT_HANDLE_INFORMATION HandleInfo;
1485  POBJECT_HEADER ObjectHeader = NULL;
1487  POBJECT_BASIC_INFORMATION BasicInfo;
1488  ULONG InfoLength = 0;
1489  PVOID Object = NULL;
1490  NTSTATUS Status;
1491  POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1495  PAGED_CODE();
1496 
1497  /* Check if the caller is from user mode */
1498  if (PreviousMode != KernelMode)
1499  {
1500  /* Protect validation with SEH */
1501  _SEH2_TRY
1502  {
1503  /* Probe the input structure */
1505 
1506  /* If we have a result length, probe it too */
1508  }
1510  {
1511  /* Return the exception code */
1513  }
1514  _SEH2_END;
1515  }
1516 
1517  /*
1518  * Make sure this isn't a generic type query, since the caller doesn't
1519  * have to give a handle for it
1520  */
1522  {
1523  /* Reference the object */
1524  Status = ObReferenceObjectByHandle(ObjectHandle,
1525  0,
1526  NULL,
1528  &Object,
1529  &HandleInfo);
1530  if (!NT_SUCCESS (Status)) return Status;
1531 
1532  /* Get the object header */
1533  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1534  ObjectType = ObjectHeader->Type;
1535  }
1536 
1537  _SEH2_TRY
1538  {
1539  /* Check the information class */
1540  switch (ObjectInformationClass)
1541  {
1542  /* Basic info */
1544 
1545  /* Validate length */
1546  InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1547  if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1548  {
1549  /* Fail */
1551  break;
1552  }
1553 
1554  /* Fill out the basic information */
1556  BasicInfo->Attributes = HandleInfo.HandleAttributes;
1557  BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1558  BasicInfo->HandleCount = ObjectHeader->HandleCount;
1559  BasicInfo->PointerCount = ObjectHeader->PointerCount;
1560 
1561  /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1562  if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1563  {
1564  /* Set the flag */
1565  BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1566  }
1567  if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1568  {
1569  /* Set the flag */
1570  BasicInfo->Attributes |= OBJ_PERMANENT;
1571  }
1572 
1573  /* Copy quota information */
1574  ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1575  if (ObjectQuota != NULL)
1576  {
1577  BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1578  BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1579  }
1580  else
1581  {
1582  BasicInfo->PagedPoolCharge = 0;
1583  BasicInfo->NonPagedPoolCharge = 0;
1584  }
1585 
1586  /* Copy name information */
1587  BasicInfo->NameInfoSize = 0; /* FIXME*/
1588  BasicInfo->TypeInfoSize = 0; /* FIXME*/
1589 
1590  /* Check if this is a symlink */
1591  if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1592  {
1593  /* Return the creation time */
1594  BasicInfo->CreationTime.QuadPart =
1595  ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1596  }
1597  else
1598  {
1599  /* Otherwise return 0 */
1600  BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1601  }
1602 
1603  /* Copy security information */
1604  BasicInfo->SecurityDescriptorSize = 0;
1605  if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1606  ObjectHeader->SecurityDescriptor != NULL)
1607  {
1612 
1613  ObjectType->TypeInfo.SecurityProcedure(Object,
1614  QuerySecurityDescriptor,
1616  NULL,
1617  &BasicInfo->SecurityDescriptorSize,
1618  &ObjectHeader->SecurityDescriptor,
1619  ObjectType->TypeInfo.PoolType,
1620  &ObjectType->TypeInfo.GenericMapping);
1621  }
1622 
1623  /* Break out with success */
1625  break;
1626 
1627  /* Name information */
1628  case ObjectNameInformation:
1629 
1630  /* Call the helper and break out */
1634  Length,
1635  &InfoLength);
1636  break;
1637 
1638  /* Information about this type */
1639  case ObjectTypeInformation:
1640 
1641  /* Call the helper and break out */
1642  Status = ObQueryTypeInfo(ObjectHeader->Type,
1645  Length,
1646  &InfoLength);
1647  break;
1648 
1649  /* Information about all types */
1651  DPRINT1("NOT IMPLEMENTED!\n");
1652  InfoLength = Length;
1654  break;
1655 
1656  /* Information about the handle flags */
1657  case ObjectHandleFlagInformation:
1658 
1659  /* Validate length */
1660  InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
1662  {
1664  break;
1665  }
1666 
1667  /* Get the structure */
1668  HandleFlags = (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
1670 
1671  /* Set the flags */
1672  HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1673  HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1674  OBJ_PROTECT_CLOSE) != 0;
1675 
1676  /* Break out with success */
1678  break;
1679 
1680  /* Anything else */
1681  default:
1682 
1683  /* Fail it */
1684  InfoLength = Length;
1686  break;
1687  }
1688 
1689  /* Check if the caller wanted the return length */
1690  if (ResultLength)
1691  {
1692  /* Write the length */
1693  *ResultLength = InfoLength;
1694  }
1695  }
1697  {
1698  /* Otherwise, get the exception code */
1700  }
1701  _SEH2_END;
1702 
1703  /* Dereference the object if we had referenced it */
1705 
1706  /* Return status */
1707  return Status;
1708 }
1709 
1710 /*++
1711 * @name NtSetInformationObject
1712 * @implemented NT4
1713 *
1714 * The NtSetInformationObject routine <FILLMEIN>
1715 *
1716 * @param ObjectHandle
1717 * <FILLMEIN>
1718 *
1719 * @param ObjectInformationClass
1720 * <FILLMEIN>
1721 *
1722 * @param ObjectInformation
1723 * <FILLMEIN>
1724 *
1725 * @param Length
1726 * <FILLMEIN>
1727 *
1728 * @return STATUS_SUCCESS or appropriate error value.
1729 *
1730 * @remarks None.
1731 *
1732 *--*/
1733 NTSTATUS
1734 NTAPI
1738  IN ULONG Length)
1739 {
1740  NTSTATUS Status;
1742  PVOID ObjectTable;
1746  BOOLEAN AttachedToProcess = FALSE;
1747  PAGED_CODE();
1748 
1749  /* Validate the information class */
1750  switch (ObjectInformationClass)
1751  {
1752  case ObjectHandleFlagInformation:
1753 
1754  /* Validate the length */
1756  {
1757  /* Invalid length */
1759  }
1760 
1761  /* Save the previous mode */
1762  Context.PreviousMode = ExGetPreviousMode();
1763 
1764  /* Check if we were called from user mode */
1765  if (Context.PreviousMode != KernelMode)
1766  {
1767  /* Enter SEH */
1768  _SEH2_TRY
1769  {
1770  /* Probe and capture the attribute buffer */
1773  sizeof(BOOLEAN));
1776  }
1778  {
1779  /* Return the exception code */
1781  }
1782  _SEH2_END;
1783  }
1784  else
1785  {
1786  /* Just copy the buffer directly */
1789  }
1790 
1791  /* Check if this is a kernel handle */
1792  if (ObpIsKernelHandle(ObjectHandle, Context.PreviousMode))
1793  {
1794  /* Get the actual handle */
1795  ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
1796  ObjectTable = ObpKernelHandleTable;
1797 
1798  /* Check if we're not in the system process */
1800  {
1801  /* Attach to it */
1803  AttachedToProcess = TRUE;
1804  }
1805  }
1806  else
1807  {
1808  /* Use the current table */
1809  ObjectTable = PsGetCurrentProcess()->ObjectTable;
1810  }
1811 
1812  /* Change the handle attributes */
1813  if (!ExChangeHandle(ObjectTable,
1814  ObjectHandle,
1816  (ULONG_PTR)&Context))
1817  {
1818  /* Some failure */
1820  }
1821  else
1822  {
1823  /* We are done */
1825  }
1826 
1827  /* De-attach if we were attached, and return status */
1828  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1829  break;
1830 
1831  case ObjectSessionInformation:
1832 
1833  /* Only a system process can do this */
1836  {
1837  /* Fail */
1838  DPRINT1("Privilege not held\n");
1840  }
1841  else
1842  {
1843  /* Get the object directory */
1844  Status = ObReferenceObjectByHandle(ObjectHandle,
1845  0,
1847  PreviousMode,
1848  (PVOID*)&Directory,
1849  NULL);
1850  if (NT_SUCCESS(Status))
1851  {
1852  /* FIXME: Missng locks */
1853  /* Set its session ID */
1854  Directory->SessionId = PsGetCurrentProcessSessionId();
1856  }
1857  }
1858  break;
1859 
1860  default:
1861  /* Unsupported class */
1863  break;
1864  }
1865 
1866  return Status;
1867 }
1868 
1869 /* EOF */
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#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:612
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:38
#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:1048
struct _OBJECT_HEADER_HANDLE_INFO * POBJECT_HEADER_HANDLE_INFO
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KAPC_STATE
Definition: ketypes.h:1273
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
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:348
#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:1856
Type
Definition: Type.h:6
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
LONG_PTR HandleCount
Definition: obtypes.h:490
ULONG NtGlobalFlag
Definition: init.c:51
ULONG ObpObjectsCreated
Definition: oblife.c:31
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:458
struct _OBJECT_SYMBOLIC_LINK * POBJECT_SYMBOLIC_LINK
const LUID SeCreatePermanentPrivilege
Definition: priv.c:37
NTSTATUS NTAPI SeComputeQuotaInformationSize(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PULONG QuotaInfoSize)
VOID NTAPI ObpDeleteObject(IN PVOID Object, IN BOOLEAN CalledFromWorkerThread)
Definition: oblife.c:148
#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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
WORK_QUEUE_ITEM ObpReaperWorkItem
Definition: oblife.c:28
uint16_t * PWSTR
Definition: typedefs.h:54
GENERAL_LOOKASIDE ObpNameBufferLookasideList
Definition: oblife.c:26
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
#define KeGetPreviousMode()
Definition: ketypes.h:1081
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:456
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
UNICODE_STRING Name
Definition: obtypes.h:433
VOID FASTCALL ObpSetPermanentObject(IN PVOID ObjectBody, IN BOOLEAN Permanent)
Definition: oblife.c:267
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:296
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:562
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1135
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OBJ_PERMANENT
Definition: winternl.h:226
PVOID DefaultObject
Definition: obtypes.h:384
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:64
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2966
ULONG ObpObjectsWithPoolQuota
Definition: oblife.c:31
IN CINT OUT PVOID ObjectInformation
Definition: conport.c:47
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1385
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
uint16_t * PWCHAR
Definition: typedefs.h:54
struct _OBJECT_HEADER_CREATOR_INFO * POBJECT_HEADER_CREATOR_INFO
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_In_ PVOID Parameter
Definition: ldrtypes.h:239
#define InsertTailList(ListHead, Entry)
#define WCHAR
Definition: msvc.h:43
volatile PVOID ObpReaperList
Definition: oblife.c:29
#define FASTCALL
Definition: nt_native.h:50
_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:1153
#define PAGED_CODE()
Definition: video.h:57
NTSTATUS NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1422
ULONG TotalNumberOfHandles
Definition: obtypes.h:387
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
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:311
#define OBJ_PROTECT_CLOSE
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
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
Definition: oblife.c:26
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:496
ACCESS_MASK GrantedAccess
Definition: iotypes.h:158
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
enum _OBJECT_INFORMATION_CLASS OBJECT_INFORMATION_CLASS
#define UNICODE_NULL
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
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:377
NTSTATUS NTAPI NtSetInformationObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, IN PVOID ObjectInformation, IN ULONG Length)
Definition: oblife.c:1735
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
ULONG ObpObjectsWithName
Definition: oblife.c:31
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
#define FLG_MAINTAIN_OBJECT_TYPELIST
Definition: pstypes.h:69
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:429
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:392
ERESOURCE Mutex
Definition: obtypes.h:381
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
void DPRINT(...)
Definition: polytest.cpp:61
_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:1329
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
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:952
OBJECT_TYPE
Definition: ntobjenum.h:27
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:46
struct _OBJECT_HEADER_QUOTA_INFO OBJECT_HEADER_QUOTA_INFO
VOID NTAPI ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: oblife.c:604
#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:151
#define ObpDirectoryObjectType
Definition: ObTypes.c:123
#define UlongToPtr(ul)
Definition: basetsd.h:98
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:459
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
INT POOL_TYPE
Definition: typedefs.h:76
uint64_t ULONGLONG
Definition: typedefs.h:65
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
volatile PVOID NextToFree
Definition: obtypes.h:491
#define OBJ_INHERIT
Definition: winternl.h:225
static OB_SECURITY_METHOD SeDefaultObjectMethod
Definition: ObTypes.c:139
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:190
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:272
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
ULONG ObpObjectsWithCreatorInfo
Definition: oblife.c:32
#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:875
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
static IUnknown Object
Definition: main.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define READ_CONTROL
Definition: nt_native.h:58
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:284
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:437
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:226
static const WCHAR L[]
Definition: oid.c:1250
#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:123
VOID FASTCALL ObpDeallocateObject(IN PVOID Object)
Definition: oblife.c:39
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:388
KPROCESS Pcb
Definition: pstypes.h:1193
#define SYNCHRONIZE
Definition: nt_native.h:61
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:389
VOID NTAPI ObDeleteCapturedInsertInfo(IN PVOID Object)
Definition: oblife.c:1311
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:98
Status
Definition: gdiplustypes.h:24
const LUID SeTcbPrivilege
Definition: priv.c:28
#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:302
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:255
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:392
struct _OBJECT_HEADER_QUOTA_INFO * POBJECT_HEADER_QUOTA_INFO
_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:4424
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:124
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:221
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:351
#define InterlockedIncrement
Definition: armddk.h:53
ACCESS_MASK GrantedAccess
Definition: winternl.h:1251
#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:753
#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:1484
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#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
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:81
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define DPRINT1
Definition: precomp.h:8
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
#define OB_FLAG_CREATOR_INFO
Definition: obtypes.h:99
struct _OBJECT_HEADER_NAME_INFO OBJECT_HEADER_NAME_INFO
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
struct tagContext Context
Definition: acpixf.h:1020
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:221
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define OB_FLAG_SECURITY
Definition: obtypes.h:102
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS NTAPI SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, IN KPROCESSOR_MODE CurrentMode, IN POOL_TYPE PoolType, IN BOOLEAN CaptureIfKernel, OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Definition: sd.c:434
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:73
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 OUT PSTR Buffer
Definition: progress.h:34
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3718
POBJECT_TYPE ObpObjectTypes[32]
Definition: oblife.c:33
LIST_ENTRY TypeList
Definition: obtypes.h:382
return STATUS_SUCCESS
Definition: btrfs.c:2725
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:264
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:503
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
signed int * PLONG
Definition: retypes.h:5
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#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:1478
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
struct _OBJECT_HEADER_CREATOR_INFO OBJECT_HEADER_CREATOR_INFO
#define DELETE
Definition: nt_native.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68