ReactOS  0.4.15-dev-3326-ga91f5e8
obhandle.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/obhandle.c
5  * PURPOSE: Manages all functions related to the Object Manager handle
6  * implementation, including creating and destroying handles
7  * and/or handle tables, duplicating objects, and setting the
8  * permanent or temporary flags.
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 
21 
22 #define TAG_OB_HANDLE 'dHbO'
23 
24 /* PRIVATE FUNCTIONS *********************************************************/
25 
27 NTAPI
29 {
31 
32  /* Lock the process */
33  if (ExAcquireRundownProtection(&Process->RundownProtect))
34  {
35  /* Get the handle table */
36  HandleTable = Process->ObjectTable;
37  if (!HandleTable)
38  {
39  /* No table, release the lock */
40  ExReleaseRundownProtection(&Process->RundownProtect);
41  }
42  }
43 
44  /* Return the handle table */
45  return HandleTable;
46 }
47 
48 VOID
49 NTAPI
51 {
52  /* Release the process lock */
53  ExReleaseRundownProtection(&Process->RundownProtect);
54 }
55 
56 ULONG
57 NTAPI
59 {
60  ULONG HandleCount;
62 
63  ASSERT(Process);
64 
65  /* Ensure the handle table doesn't go away while we use it */
67 
68  if (HandleTable != NULL)
69  {
70  /* Count the number of handles the process has */
71  HandleCount = HandleTable->HandleCount;
72 
73  /* Let the handle table go */
75  }
76  else
77  {
78  /* No handle table, no handles */
79  HandleCount = 0;
80  }
81 
82  return HandleCount;
83 }
84 
86 NTAPI
91  OUT PVOID *Object,
93  OUT PACCESS_MASK AuditMask)
94 {
95  PHANDLE_TABLE_ENTRY HandleEntry;
96  POBJECT_HEADER ObjectHeader;
101 
102  /* Assume failure */
103  *Object = NULL;
104 
105  /* Check if this is a special handle */
106  if (HandleToLong(Handle) < 0)
107  {
108  /* Check if the caller wants the current process */
109  if (Handle == NtCurrentProcess())
110  {
111  /* Return handle info */
112  HandleInformation->HandleAttributes = 0;
113  HandleInformation->GrantedAccess = Process->GrantedAccess;
114 
115  /* No audit mask */
116  *AuditMask = 0;
117 
118  /* Reference ourselves */
119  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
120  InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
121 
122  /* Return the pointer */
123  *Object = Process;
124  ASSERT(*Object != NULL);
125  return STATUS_SUCCESS;
126  }
127 
128  /* Check if the caller wants the current thread */
129  if (Handle == NtCurrentThread())
130  {
131  /* Return handle information */
132  HandleInformation->HandleAttributes = 0;
133  HandleInformation->GrantedAccess = Thread->GrantedAccess;
134 
135  /* Reference ourselves */
136  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
137  InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
138 
139  /* No audit mask */
140  *AuditMask = 0;
141 
142  /* Return the pointer */
143  *Object = Thread;
144  ASSERT(*Object != NULL);
145  return STATUS_SUCCESS;
146  }
147 
148  /* This is a kernel handle... do we have access? */
149  if (AccessMode == KernelMode)
150  {
151  /* Use the kernel handle table and get the actual handle value */
154  }
155  else
156  {
157  /* This is an illegal attempt to access a kernel handle */
158  return STATUS_INVALID_HANDLE;
159  }
160  }
161 
162  /* Enter a critical region while we touch the handle table */
163  ASSERT(HandleTable != NULL);
165 
166  /* Get the handle entry */
167  HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
168  if (HandleEntry)
169  {
170  /* Get the object header and validate the type*/
171  ObjectHeader = ObpGetHandleObject(HandleEntry);
172 
173  /* Get the granted access and validate it */
174  GrantedAccess = HandleEntry->GrantedAccess;
175 
176  /* Mask out the internal attributes */
178 
179  /* Fill out the information */
180  HandleInformation->HandleAttributes = Attributes;
181  HandleInformation->GrantedAccess = GrantedAccess;
182 
183  /* No audit mask (FIXME!) */
184  *AuditMask = 0;
185 
186  /* Return the pointer */
187  *Object = &ObjectHeader->Body;
188 
189  /* Add a reference */
190  InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
191 
192  /* Unlock the handle */
195 
196  /* Return success */
197  ASSERT(*Object != NULL);
198  return STATUS_SUCCESS;
199  }
200  else
201  {
202  /* Invalid handle */
204  }
205 
206  /* Return failure status */
208  return Status;
209 }
210 
211 BOOLEAN
212 NTAPI
214  IN HANDLE Handle,
215  IN PVOID Context)
216 {
217  POBJECT_HEADER ObjectHeader;
220  POBP_FIND_HANDLE_DATA FindData = Context;
221 
222  /* Get the object header */
223  ObjectHeader = ObpGetHandleObject(HandleEntry);
224 
225  /* Make sure it's valid and matching */
226  if ((FindData->ObjectHeader) && (FindData->ObjectHeader != ObjectHeader))
227  {
228  /* No match, fail */
229  return FALSE;
230  }
231 
232  /* Now attempt to match the object type */
233  if ((FindData->ObjectType) && (FindData->ObjectType != ObjectHeader->Type))
234  {
235  /* No match, fail */
236  return FALSE;
237  }
238 
239  /* Check if we have extra information */
240  if (FindData->HandleInformation)
241  {
242  /* Get the granted access and attributes */
243  GrantedAccess = HandleEntry->GrantedAccess;
244  HandleAttributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
245 
246  /* Attempt to match them */
249  {
250  /* No match, fail */
251  return FALSE;
252  }
253  }
254 
255  /* We have a match */
256  return TRUE;
257 }
258 
260 NTAPI
262 {
263  POBJECT_HEADER_HANDLE_INFO HandleInfo;
264  POBJECT_HANDLE_COUNT_ENTRY FreeEntry;
265  POBJECT_HANDLE_COUNT_DATABASE HandleDatabase, OldHandleDatabase;
266  ULONG i;
267  ULONG Size, OldSize;
268  OBJECT_HANDLE_COUNT_DATABASE SingleDatabase;
269  PAGED_CODE();
270 
271  /* Get the handle info */
272  HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
273  if (!HandleInfo) return NULL;
274 
275  /* Check if we only have one entry */
276  if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
277  {
278  /* Fill out the single entry */
279  SingleDatabase.CountEntries = 1;
280  SingleDatabase.HandleCountEntries[0] = HandleInfo->SingleEntry;
281 
282  /* Use this as the old size */
283  OldHandleDatabase = &SingleDatabase;
284  OldSize = sizeof(SingleDatabase);
285 
286  /* Now we'll have two entries, and an entire DB */
287  i = 2;
289  ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
290  }
291  else
292  {
293  /* We already have a DB, get the information from it */
294  OldHandleDatabase = HandleInfo->HandleCountDatabase;
295  i = OldHandleDatabase->CountEntries;
296  OldSize = sizeof(OBJECT_HANDLE_COUNT_DATABASE) +
297  ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
298 
299  /* Add 4 more entries */
300  i += 4;
301  Size = OldSize + (4 * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
302  }
303 
304  /* Allocate the DB */
306  if (!HandleDatabase) return NULL;
307 
308  /* Copy the old database */
309  RtlCopyMemory(HandleDatabase, OldHandleDatabase, OldSize);
310 
311  /* Check if we he had a single entry before */
312  if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
313  {
314  /* Now we have more */
315  ObjectHeader->Flags &= ~OB_FLAG_SINGLE_PROCESS;
316  }
317  else
318  {
319  /* Otherwise we had a DB, free it */
320  ExFreePoolWithTag(OldHandleDatabase, TAG_OB_HANDLE);
321  }
322 
323  /* Find the end of the copy and zero out the new data */
324  FreeEntry = (PVOID)((ULONG_PTR)HandleDatabase + OldSize);
325  RtlZeroMemory(FreeEntry, Size - OldSize);
326 
327  /* Set the new information and return the free entry */
328  HandleDatabase->CountEntries = i;
329  HandleInfo->HandleCountDatabase = HandleDatabase;
330  return FreeEntry;
331 }
332 
333 NTSTATUS
334 NTAPI
337  IN OUT PULONG NewProcessHandleCount)
338 {
339  POBJECT_HEADER_HANDLE_INFO HandleInfo;
340  POBJECT_HANDLE_COUNT_ENTRY HandleEntry, FreeEntry = NULL;
341  POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
342  ULONG i;
343  PAGED_CODE();
344 
345  /* Get the handle info and check if we only have one entry */
346  HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
347  if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
348  {
349  /* Check if the entry is free */
350  if (!HandleInfo->SingleEntry.HandleCount)
351  {
352  /* Add ours */
353  HandleInfo->SingleEntry.HandleCount = 1;
354  HandleInfo->SingleEntry.Process = Process;
355 
356  /* Return success and 1 handle */
357  *NewProcessHandleCount = 1;
358  return STATUS_SUCCESS;
359  }
360  else if (HandleInfo->SingleEntry.Process == Process)
361  {
362  /* Busy entry, but same process */
363  *NewProcessHandleCount = ++HandleInfo->SingleEntry.HandleCount;
364  return STATUS_SUCCESS;
365  }
366  else
367  {
368  /* Insert a new entry */
369  FreeEntry = ObpInsertHandleCount(ObjectHeader);
370  if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
371  ASSERT(!FreeEntry->Process);
372  ASSERT(!FreeEntry->HandleCount);
373 
374  /* Fill it out */
375  FreeEntry->Process = Process;
376  FreeEntry->HandleCount = 1;
377 
378  /* Return success and 1 handle */
379  *NewProcessHandleCount = 1;
380  return STATUS_SUCCESS;
381  }
382  }
383 
384  /* We have a database instead */
385  HandleDatabase = HandleInfo->HandleCountDatabase;
386  if (HandleDatabase)
387  {
388  /* Get the entries and loop them */
389  i = HandleDatabase->CountEntries;
390  HandleEntry = &HandleDatabase->HandleCountEntries[0];
391  while (i)
392  {
393  /* Check if this is a match */
394  if (HandleEntry->Process == Process)
395  {
396  /* Found it, get the process handle count */
397  *NewProcessHandleCount = ++HandleEntry->HandleCount;
398  return STATUS_SUCCESS;
399  }
400  else if (!HandleEntry->HandleCount)
401  {
402  /* Found a free entry */
403  FreeEntry = HandleEntry;
404  }
405 
406  /* Keep looping */
407  HandleEntry++;
408  i--;
409  }
410 
411  /* Check if we couldn't find a free entry */
412  if (!FreeEntry)
413  {
414  /* Allocate one */
415  FreeEntry = ObpInsertHandleCount(ObjectHeader);
416  if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
417  ASSERT(!FreeEntry->Process);
418  ASSERT(!FreeEntry->HandleCount);
419  }
420 
421  /* Fill out the entry */
422  FreeEntry->Process = Process;
423  FreeEntry->HandleCount = 1;
424  *NewProcessHandleCount = 1;
425  }
426 
427  /* Return success if we got here */
428  return STATUS_SUCCESS;
429 }
430 
431 NTSTATUS
432 NTAPI
436 {
437  POBJECT_HEADER_QUOTA_INFO ObjectQuota;
438  ULONG PagedPoolCharge, NonPagedPoolCharge;
439 
440  /* Get quota information */
441  ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
442  *NewObject = FALSE;
443 
444  /* Check if this is a new object */
445  if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
446  {
447  /* Remove the flag */
448  ObjectHeader->Flags &= ~ OB_FLAG_CREATE_INFO;
449  if (ObjectQuota)
450  {
451  /* We have a quota, get the charges */
452  PagedPoolCharge = ObjectQuota->PagedPoolCharge;
453  NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
454  }
455  else
456  {
457  /* Get it from the object type */
458  PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
459  NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
460  }
461 
462  /* Charge the quota */
463  ObjectHeader->QuotaBlockCharged = (PVOID)1;
464  DPRINT("FIXME: Should charge: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
465 #if 0
466  PsChargeSharedPoolQuota(PsGetCurrentProcess(),
467  PagedPoolCharge,
468  NonPagedPoolCharge);
469 #endif
470 
471  /* Check if we don't have a quota block */
472  if (!ObjectHeader->QuotaBlockCharged) return STATUS_QUOTA_EXCEEDED;
473 
474  /* Now set the flag */
475  *NewObject = TRUE;
476  }
477 
478  /* Return success */
479  return STATUS_SUCCESS;
480 }
481 
482 NTSTATUS
483 NTAPI
485 {
487 
488  /* We're only interested if the object for this access state has an SD */
489  SecurityDescriptor = AccessState->SecurityDescriptor;
490  if (SecurityDescriptor)
491  {
492  /* Check if the SD has a system ACL but hasn't been granted access to get/set it */
493  if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
494  !(AccessState->PreviouslyGrantedAccess & ACCESS_SYSTEM_SECURITY))
495  {
496  /* We're gonna need access */
497  AccessState->RemainingDesiredAccess |= ACCESS_SYSTEM_SECURITY;
498  }
499  }
500 
501  /* This can't fail */
502  return STATUS_SUCCESS;
503 }
504 
505 /*++
506 * @name ObpDecrementHandleCount
507 *
508 * The ObpDecrementHandleCount routine <FILLMEIN>
509 *
510 * @param ObjectBody
511 * <FILLMEIN>.
512 *
513 * @param Process
514 * <FILLMEIN>.
515 *
516 * @param GrantedAccess
517 * <FILLMEIN>.
518 *
519 * @return None.
520 *
521 * @remarks None.
522 *
523 *--*/
524 VOID
525 NTAPI
530 {
531  POBJECT_HEADER ObjectHeader;
532  LONG SystemHandleCount, ProcessHandleCount;
533  LONG NewCount;
534  KIRQL CalloutIrql;
535  POBJECT_HEADER_HANDLE_INFO HandleInfo;
536  POBJECT_HANDLE_COUNT_ENTRY HandleEntry;
537  POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
538  ULONG i;
539  PAGED_CODE();
540 
541  /* Get the object type and header */
542  ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
544  "%s - Decrementing count for: %p. HC PC %lx %lx\n",
545  __FUNCTION__,
546  ObjectBody,
547  ObjectHeader->HandleCount,
548  ObjectHeader->PointerCount);
549 
550  /* Lock the object */
551  ObpAcquireObjectLock(ObjectHeader);
552 
553  /* Set default counts */
554  SystemHandleCount = ObjectHeader->HandleCount;
555  ProcessHandleCount = 0;
556 
557  /* Decrement the handle count */
558  NewCount = InterlockedDecrementSizeT(&ObjectHeader->HandleCount);
559 
560  /* Check if we're out of handles and this was an exclusive object */
561  if (!(NewCount) && (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
562  {
563  /* Clear the exclusive flag */
564  OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = NULL;
565  }
566 
567  /* Is the object type keeping track of handles? */
568  if (ObjectType->TypeInfo.MaintainHandleCount)
569  {
570  /* Get handle information */
571  HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
572 
573  /* Check if there's only a single entry */
574  if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
575  {
576  /* It should be us */
577  ASSERT(HandleInfo->SingleEntry.Process == Process);
578  ASSERT(HandleInfo->SingleEntry.HandleCount > 0);
579 
580  /* Get the handle counts */
582  HandleEntry = &HandleInfo->SingleEntry;
583  }
584  else
585  {
586  /* Otherwise, get the database */
587  HandleDatabase = HandleInfo->HandleCountDatabase;
588  if (HandleDatabase)
589  {
590  /* Get the entries and loop them */
591  i = HandleDatabase->CountEntries;
592  HandleEntry = &HandleDatabase->HandleCountEntries[0];
593  while (i)
594  {
595  /* Check if this is a match */
596  if ((HandleEntry->HandleCount) &&
597  (HandleEntry->Process == Process))
598  {
599  /* Found it, get the process handle count */
600  ProcessHandleCount = HandleEntry->HandleCount--;
601  break;
602  }
603 
604  /* Keep looping */
605  HandleEntry++;
606  i--;
607  }
608  }
609  else
610  {
611  /* No database, so no entry */
612  HandleEntry = NULL;
613  }
614  }
615 
616  /* Check if this is the last handle */
617  if (ProcessHandleCount == 1)
618  {
619  /* Then clear the entry */
620  HandleEntry->Process = NULL;
621  HandleEntry->HandleCount = 0;
622  }
623  }
624 
625  /* Release the lock */
626  ObpReleaseObjectLock(ObjectHeader);
627 
628  /* Check if we have a close procedure */
629  if (ObjectType->TypeInfo.CloseProcedure)
630  {
631  /* Call it */
632  ObpCalloutStart(&CalloutIrql);
633  ObjectType->TypeInfo.CloseProcedure(Process,
634  ObjectBody,
637  SystemHandleCount);
638  ObpCalloutEnd(CalloutIrql, "Close", ObjectType, ObjectBody);
639  }
640 
641  /* Check if we should delete the object */
642  ObpDeleteNameCheck(ObjectBody);
643 
644  /* Decrease the total number of handles for this type */
645  InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfHandles);
647  "%s - Decremented count for: %p. HC PC %lx %lx\n",
648  __FUNCTION__,
649  ObjectBody,
650  ObjectHeader->HandleCount,
651  ObjectHeader->PointerCount);
652 }
653 
654 /*++
655 * @name ObpCloseHandleTableEntry
656 *
657 * The ObpCloseHandleTableEntry routine <FILLMEIN>
658 *
659 * @param HandleTable
660 * <FILLMEIN>.
661 *
662 * @param HandleEntry
663 * <FILLMEIN>.
664 *
665 * @param Handle
666 * <FILLMEIN>.
667 *
668 * @param AccessMode
669 * <FILLMEIN>.
670 *
671 * @param IgnoreHandleProtection
672 * <FILLMEIN>.
673 *
674 * @return <FILLMEIN>.
675 *
676 * @remarks None.
677 *
678 *--*/
679 NTSTATUS
680 NTAPI
682  IN PHANDLE_TABLE_ENTRY HandleEntry,
683  IN HANDLE Handle,
685  IN BOOLEAN IgnoreHandleProtection)
686 {
687  PVOID Body;
689  POBJECT_HEADER ObjectHeader;
691  KIRQL CalloutIrql;
692  PAGED_CODE();
693 
694  /* Get the object data */
695  ObjectHeader = ObpGetHandleObject(HandleEntry);
696  ObjectType = ObjectHeader->Type;
697  Body = &ObjectHeader->Body;
698  GrantedAccess = HandleEntry->GrantedAccess;
700  "%s - Closing handle: %p for %p. HC PC %lx %lx\n",
701  __FUNCTION__,
702  Handle,
703  Body,
704  ObjectHeader->HandleCount,
705  ObjectHeader->PointerCount);
706 
707  /* Check if the object has an Okay To Close procedure */
708  if (ObjectType->TypeInfo.OkayToCloseProcedure)
709  {
710  /* Call it and check if it's not letting us close it */
711  ObpCalloutStart(&CalloutIrql);
712  if (!ObjectType->TypeInfo.OkayToCloseProcedure(PsGetCurrentProcess(),
713  Body,
714  Handle,
715  AccessMode))
716  {
717  /* Fail */
718  ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
721  }
722 
723  /* Success, validate callout retrn */
724  ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
725  }
726 
727  /* The callback allowed us to close it, but does the handle itself? */
728  if ((HandleEntry->GrantedAccess & ObpAccessProtectCloseBit) &&
729  !(IgnoreHandleProtection))
730  {
731  /* It doesn't, are we from user mode? */
732  if (AccessMode != KernelMode)
733  {
734  /* We are! Unlock the entry */
736 
737  /* Make sure we have a debug port */
738  if (PsGetCurrentProcess()->DebugPort)
739  {
740  /* Raise an exception */
742  }
743  else
744  {
745  /* Return the error instead */
747  }
748  }
749  else
750  {
751  /* Otherwise, bugcheck the OS */
752  KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 0, 0, 0);
753  }
754  }
755 
756  /* Destroy and unlock the handle entry */
757  ExDestroyHandle(HandleTable, Handle, HandleEntry);
758 
759  /* Now decrement the handle count */
763  ObjectType);
764 
765  /* Dereference the object as well */
766  ObDereferenceObject(Body);
767 
768  /* Return to caller */
770  "%s - Closed handle: %p for %p.\n",
771  __FUNCTION__,
772  Handle,
773  Body);
774  return STATUS_SUCCESS;
775 }
776 
777 /*++
778 * @name ObpIncrementHandleCount
779 *
780 * The ObpIncrementHandleCount routine <FILLMEIN>
781 *
782 * @param Object
783 * <FILLMEIN>.
784 *
785 * @param AccessState
786 * <FILLMEIN>.
787 *
788 * @param AccessMode
789 * <FILLMEIN>.
790 *
791 * @param HandleAttributes
792 * <FILLMEIN>.
793 *
794 * @param Process
795 * <FILLMEIN>.
796 *
797 * @param OpenReason
798 * <FILLMEIN>.
799 *
800 * @return <FILLMEIN>.
801 *
802 * @remarks None.
803 *
804 *--*/
805 NTSTATUS
806 NTAPI
812  IN OB_OPEN_REASON OpenReason)
813 {
814  POBJECT_HEADER ObjectHeader;
818  PEPROCESS ExclusiveProcess;
820  POBJECT_HEADER_CREATOR_INFO CreatorInfo;
821  KIRQL CalloutIrql;
823  ULONG Total;
824  POBJECT_HEADER_NAME_INFO NameInfo;
825  PAGED_CODE();
826 
827  /* Get the object header and type */
828  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
829  ObjectType = ObjectHeader->Type;
831  "%s - Incrementing count for: %p. Reason: %lx. HC PC %lx %lx\n",
832  __FUNCTION__,
833  Object,
834  OpenReason,
835  ObjectHeader->HandleCount,
836  ObjectHeader->PointerCount);
837 
838  /* Check if caller is forcing user mode */
840  {
841  /* Force it */
843  }
844  else
845  {
846  /* Keep original setting */
848  }
849 
850  /* Lock the object */
851  ObpAcquireObjectLock(ObjectHeader);
852 
853  /* Charge quota and remove the creator info flag */
855  if (!NT_SUCCESS(Status)) return Status;
856 
857  /* Check if the open is exclusive */
859  {
860  /* Check if the object allows this, or if the inherit flag was given */
861  if ((HandleAttributes & OBJ_INHERIT) ||
862  !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
863  {
864  /* Incorrect attempt */
866  goto Quickie;
867  }
868 
869  /* Check if we have access to it */
870  ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
871  if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
872  ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
873  {
874  /* This isn't the right process */
876  goto Quickie;
877  }
878 
879  /* Now you got exclusive access */
880  Exclusive = TRUE;
881  }
882  else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
883  (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader)))
884  {
885  /* Caller didn't want exclusive access, but the object is exclusive */
887  goto Quickie;
888  }
889 
890  /* Check for exclusive kernel object */
891  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
892  if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
893  (ProbeMode != KernelMode))
894  {
895  /* Caller is not kernel, but the object is kernel exclusive */
897  goto Quickie;
898  }
899 
900  /*
901  * Check if this is an object that went from 0 handles back to existence,
902  * but doesn't have an open procedure, only a close procedure. This means
903  * that it will never realize that the object is back alive, so we must
904  * fail the request.
905  */
906  if (!(ObjectHeader->HandleCount) &&
907  !(NewObject) &&
908  (ObjectType->TypeInfo.MaintainHandleCount) &&
909  !(ObjectType->TypeInfo.OpenProcedure) &&
910  (ObjectType->TypeInfo.CloseProcedure))
911  {
912  /* Fail */
914  goto Quickie;
915  }
916 
917  /* Check if we're opening an existing handle */
918  if ((OpenReason == ObOpenHandle) ||
919  ((OpenReason == ObDuplicateHandle) && (AccessState)))
920  {
921  /* Validate the caller's access to this object */
923  AccessState,
924  TRUE,
925  ProbeMode,
926  &Status))
927  {
928  /* Access was denied, so fail */
929  goto Quickie;
930  }
931  }
932  else if (OpenReason == ObCreateHandle)
933  {
934  /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
935  if (AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED)
936  {
937  /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
938  AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
939  AccessState->RemainingDesiredAccess |= GENERIC_ALL;
940  }
941 
942  /* Check if we have to map the GENERIC mask */
943  if (AccessState->RemainingDesiredAccess & GENERIC_ACCESS)
944  {
945  /* Map it to the correct access masks */
946  RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
947  &ObjectType->TypeInfo.GenericMapping);
948  }
949 
950  /* Check if the caller is trying to access system security */
951  if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY)
952  {
953  /* FIXME: TODO */
954  DPRINT1("ACCESS_SYSTEM_SECURITY not validated!\n");
955  }
956  }
957 
958  /* Check if this is an exclusive handle */
959  if (Exclusive)
960  {
961  /* Save the owner process */
962  OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
963  }
964 
965  /* Increase the handle count */
966  InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
967  ProcessHandleCount = 0;
968 
969  /* Check if we have a handle database */
970  if (ObjectType->TypeInfo.MaintainHandleCount)
971  {
972  /* Increment the handle database */
973  Status = ObpIncrementHandleDataBase(ObjectHeader,
974  Process,
976  if (!NT_SUCCESS(Status))
977  {
978  /* FIXME: This should never happen for now */
979  DPRINT1("Unhandled case\n");
980  ASSERT(FALSE);
981  goto Quickie;
982  }
983  }
984 
985  /* Release the lock */
986  ObpReleaseObjectLock(ObjectHeader);
987 
988  /* Check if we have an open procedure */
990  if (ObjectType->TypeInfo.OpenProcedure)
991  {
992  /* Call it */
993  ObpCalloutStart(&CalloutIrql);
994  Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
995  Process,
996  Object,
997  AccessState ?
998  AccessState->
1000  0,
1002  ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1003 
1004  /* Check if the open procedure failed */
1005  if (!NT_SUCCESS(Status))
1006  {
1007  /* FIXME: This should never happen for now */
1008  DPRINT1("Unhandled case\n");
1009  ASSERT(FALSE);
1010  return Status;
1011  }
1012  }
1013 
1014  /* Check if this is a create operation */
1015  if (OpenReason == ObCreateHandle)
1016  {
1017  /* Check if we have creator info */
1018  CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1019  if (CreatorInfo)
1020  {
1021  /* We do, acquire the lock */
1023 
1024  /* Insert us on the list */
1025  InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1026 
1027  /* Release the lock */
1029  }
1030  }
1031 
1032  /* Increase total number of handles */
1033  Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1034  if (Total > ObjectType->HighWaterNumberOfHandles)
1035  {
1036  /* Fixup count */
1037  ObjectType->HighWaterNumberOfHandles = Total;
1038  }
1039 
1040  /* Trace call and return */
1042  "%s - Incremented count for: %p. Reason: %lx HC PC %lx %lx\n",
1043  __FUNCTION__,
1044  Object,
1045  OpenReason,
1046  ObjectHeader->HandleCount,
1047  ObjectHeader->PointerCount);
1048  return Status;
1049 
1050 Quickie:
1051  /* Release lock and return */
1052  ObpReleaseObjectLock(ObjectHeader);
1053  return Status;
1054 }
1055 
1056 /*++
1057 * @name ObpIncrementUnnamedHandleCount
1058 *
1059 * The ObpIncrementUnnamedHandleCount routine <FILLMEIN>
1060 *
1061 * @param Object
1062 * <FILLMEIN>.
1063 *
1064 * @param AccessState
1065 * <FILLMEIN>.
1066 *
1067 * @param AccessMode
1068 * <FILLMEIN>.
1069 *
1070 * @param HandleAttributes
1071 * <FILLMEIN>.
1072 *
1073 * @param Process
1074 * <FILLMEIN>.
1075 *
1076 * @param OpenReason
1077 * <FILLMEIN>.
1078 *
1079 * @return <FILLMEIN>.
1080 *
1081 * @remarks None.
1082 *
1083 *--*/
1084 NTSTATUS
1085 NTAPI
1091 {
1092  POBJECT_HEADER ObjectHeader;
1095  NTSTATUS Status;
1096  PEPROCESS ExclusiveProcess;
1098  POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1099  KIRQL CalloutIrql;
1100  ULONG Total;
1101 
1102  /* Get the object header and type */
1103  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1104  ObjectType = ObjectHeader->Type;
1106  "%s - Incrementing count for: %p. UNNAMED. HC PC %lx %lx\n",
1107  __FUNCTION__,
1108  Object,
1109  ObjectHeader->HandleCount,
1110  ObjectHeader->PointerCount);
1111 
1112  /* Lock the object */
1113  ObpAcquireObjectLock(ObjectHeader);
1114 
1115  /* Charge quota and remove the creator info flag */
1117  if (!NT_SUCCESS(Status)) return Status;
1118 
1119  /* Check if the open is exclusive */
1121  {
1122  /* Check if the object allows this, or if the inherit flag was given */
1123  if ((HandleAttributes & OBJ_INHERIT) ||
1124  !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
1125  {
1126  /* Incorrect attempt */
1128  goto Quickie;
1129  }
1130 
1131  /* Check if we have access to it */
1132  ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
1133  if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
1134  ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
1135  {
1136  /* This isn't the right process */
1138  goto Quickie;
1139  }
1140 
1141  /* Now you got exclusive access */
1142  Exclusive = TRUE;
1143  }
1144  else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
1145  (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader)))
1146  {
1147  /* Caller didn't want exclusive access, but the object is exclusive */
1149  goto Quickie;
1150  }
1151 
1152  /*
1153  * Check if this is an object that went from 0 handles back to existence,
1154  * but doesn't have an open procedure, only a close procedure. This means
1155  * that it will never realize that the object is back alive, so we must
1156  * fail the request.
1157  */
1158  if (!(ObjectHeader->HandleCount) &&
1159  !(NewObject) &&
1160  (ObjectType->TypeInfo.MaintainHandleCount) &&
1161  !(ObjectType->TypeInfo.OpenProcedure) &&
1162  (ObjectType->TypeInfo.CloseProcedure))
1163  {
1164  /* Fail */
1166  goto Quickie;
1167  }
1168 
1169  /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
1171  {
1172  /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
1175  }
1176 
1177  /* Check if we have to map the GENERIC mask */
1179  {
1180  /* Map it to the correct access masks */
1182  &ObjectType->TypeInfo.GenericMapping);
1183  }
1184 
1185  /* Check if this is an exclusive handle */
1186  if (Exclusive)
1187  {
1188  /* Save the owner process */
1189  OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
1190  }
1191 
1192  /* Increase the handle count */
1193  InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
1194  ProcessHandleCount = 0;
1195 
1196  /* Check if we have a handle database */
1197  if (ObjectType->TypeInfo.MaintainHandleCount)
1198  {
1199  /* Increment the handle database */
1200  Status = ObpIncrementHandleDataBase(ObjectHeader,
1201  Process,
1203  if (!NT_SUCCESS(Status))
1204  {
1205  /* FIXME: This should never happen for now */
1206  DPRINT1("Unhandled case\n");
1207  ASSERT(FALSE);
1208  goto Quickie;
1209  }
1210  }
1211 
1212  /* Release the lock */
1213  ObpReleaseObjectLock(ObjectHeader);
1214 
1215  /* Check if we have an open procedure */
1217  if (ObjectType->TypeInfo.OpenProcedure)
1218  {
1219  /* Call it */
1220  ObpCalloutStart(&CalloutIrql);
1221  Status = ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
1222  Process,
1223  Object,
1224  *DesiredAccess,
1226  ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1227 
1228  /* Check if the open procedure failed */
1229  if (!NT_SUCCESS(Status))
1230  {
1231  /* FIXME: This should never happen for now */
1232  DPRINT1("Unhandled case\n");
1233  ASSERT(FALSE);
1234  return Status;
1235  }
1236  }
1237 
1238  /* Check if we have creator info */
1239  CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1240  if (CreatorInfo)
1241  {
1242  /* We do, acquire the lock */
1244 
1245  /* Insert us on the list */
1246  InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1247 
1248  /* Release the lock */
1250  }
1251 
1252  /* Increase total number of handles */
1253  Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1254  if (Total > ObjectType->HighWaterNumberOfHandles)
1255  {
1256  /* Fixup count */
1257  ObjectType->HighWaterNumberOfHandles = Total;
1258  }
1259 
1260  /* Trace call and return */
1262  "%s - Incremented count for: %p. UNNAMED HC PC %lx %lx\n",
1263  __FUNCTION__,
1264  Object,
1265  ObjectHeader->HandleCount,
1266  ObjectHeader->PointerCount);
1267  return Status;
1268 
1269 Quickie:
1270  /* Release lock and return */
1271  ObpReleaseObjectLock(ObjectHeader);
1272  return Status;
1273 }
1274 
1275 /*++
1276 * @name ObpCreateUnnamedHandle
1277 *
1278 * The ObpCreateUnnamedHandle routine <FILLMEIN>
1279 *
1280 * @param Object
1281 * <FILLMEIN>.
1282 *
1283 * @param DesiredAccess
1284 * <FILLMEIN>.
1285 *
1286 * @param AdditionalReferences
1287 * <FILLMEIN>.
1288 *
1289 * @param HandleAttributes
1290 * <FILLMEIN>.
1291 *
1292 * @param AccessMode
1293 * <FILLMEIN>.
1294 *
1295 * @param ReturnedObject
1296 * <FILLMEIN>.
1297 *
1298 * @param ReturnedHandle
1299 * <FILLMEIN>.
1300 *
1301 * @return <FILLMEIN>.
1302 *
1303 * @remarks None.
1304 *
1305 *--*/
1306 NTSTATUS
1307 NTAPI
1310  IN ULONG AdditionalReferences,
1313  OUT PVOID *ReturnedObject,
1314  OUT PHANDLE ReturnedHandle)
1315 {
1316  HANDLE_TABLE_ENTRY NewEntry;
1317  POBJECT_HEADER ObjectHeader;
1318  HANDLE Handle;
1320  BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1322  NTSTATUS Status;
1325  PAGED_CODE();
1326 
1327  /* Get the object header and type */
1328  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1329  ObjectType = ObjectHeader->Type;
1331  "%s - Creating handle for: %p. UNNAMED. HC PC %lx %lx\n",
1332  __FUNCTION__,
1333  Object,
1334  ObjectHeader->HandleCount,
1335  ObjectHeader->PointerCount);
1336 
1337  /* Save the object header */
1338  NewEntry.Object = ObjectHeader;
1339 
1340  /* Mask out the internal attributes */
1342 
1343  /* Check if this is a kernel handle */
1345  {
1346  /* Set the handle table */
1348  KernelHandle = TRUE;
1349 
1350  /* Check if we're not in the system process */
1352  {
1353  /* Attach to the system process */
1355  AttachedToProcess = TRUE;
1356  }
1357  }
1358  else
1359  {
1360  /* Get the current handle table */
1361  HandleTable = PsGetCurrentProcess()->ObjectTable;
1362  }
1363 
1364  /* Increment the handle count */
1366  &DesiredAccess,
1367  AccessMode,
1370  if (!NT_SUCCESS(Status))
1371  {
1372  /*
1373  * We failed (meaning security failure, according to NT Internals)
1374  * detach and return
1375  */
1376  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1377  return Status;
1378  }
1379 
1380  /* Remove what's not in the valid access mask */
1381  GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1383 
1384  /* Handle extra references */
1385  if (AdditionalReferences)
1386  {
1387  /* Add them to the header */
1389  AdditionalReferences);
1390  }
1391 
1392  /* Save the access mask */
1393  NewEntry.GrantedAccess = GrantedAccess;
1394 
1395  /*
1396  * Create the actual handle. We'll need to do this *after* calling
1397  * ObpIncrementHandleCount to make sure that Object Security is valid
1398  * (specified in Gl00my documentation on Ob)
1399  */
1401  "%s - Handle Properties: [%p-%lx-%lx]\n",
1402  __FUNCTION__,
1403  NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1404  Handle = ExCreateHandle(HandleTable, &NewEntry);
1405 
1406  /* Make sure we got a handle */
1407  if (Handle)
1408  {
1409  /* Check if this was a kernel handle */
1411 
1412  /* Return handle and object */
1413  *ReturnedHandle = Handle;
1414 
1415  /* Return the new object only if caller wanted it biased */
1416  if ((AdditionalReferences) && (ReturnedObject))
1417  {
1418  /* Return it */
1419  *ReturnedObject = Object;
1420  }
1421 
1422  /* Detach if needed */
1423  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1424 
1425  /* Trace and return */
1427  "%s - Returning Handle: %p HC PC %lx %lx\n",
1428  __FUNCTION__,
1429  Handle,
1430  ObjectHeader->HandleCount,
1431  ObjectHeader->PointerCount);
1432  return STATUS_SUCCESS;
1433  }
1434 
1435  /* Handle extra references */
1436  if (AdditionalReferences)
1437  {
1438  /* Dereference it as many times as required */
1440  -(LONG)AdditionalReferences);
1441  }
1442 
1443  /* Decrement the handle count and detach */
1444  ObpDecrementHandleCount(&ObjectHeader->Body,
1446  GrantedAccess,
1447  ObjectType);
1448 
1449  /* Detach and fail */
1450  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1452 }
1453 
1454 /*++
1455 * @name ObpCreateHandle
1456 *
1457 * The ObpCreateHandle routine <FILLMEIN>
1458 *
1459 * @param OpenReason
1460 * <FILLMEIN>.
1461 *
1462 * @param Object
1463 * <FILLMEIN>.
1464 *
1465 * @param Type
1466 * <FILLMEIN>.
1467 *
1468 * @param AccessState
1469 * <FILLMEIN>.
1470 *
1471 * @param AdditionalReferences
1472 * <FILLMEIN>.
1473 *
1474 * @param HandleAttributes
1475 * <FILLMEIN>.
1476 *
1477 * @param AccessMode
1478 * <FILLMEIN>.
1479 *
1480 * @param ReturnedObject
1481 * <FILLMEIN>.
1482 *
1483 * @param ReturnedHandle
1484 * <FILLMEIN>.
1485 *
1486 * @return <FILLMEIN>.
1487 *
1488 * @remarks Cleans up the Lookup Context on return.
1489 *
1490 *--*/
1491 NTSTATUS
1492 NTAPI
1494  IN PVOID Object,
1497  IN ULONG AdditionalReferences,
1501  OUT PVOID *ReturnedObject,
1502  OUT PHANDLE ReturnedHandle)
1503 {
1504  HANDLE_TABLE_ENTRY NewEntry;
1505  POBJECT_HEADER ObjectHeader;
1506  HANDLE Handle;
1508  BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1511  NTSTATUS Status;
1513  PAUX_ACCESS_DATA AuxData;
1514  PAGED_CODE();
1515 
1516  /* Get the object header and type */
1517  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1518  ObjectType = ObjectHeader->Type;
1520  "%s - Creating handle for: %p. Reason: %lx. HC PC %lx %lx\n",
1521  __FUNCTION__,
1522  Object,
1523  OpenReason,
1524  ObjectHeader->HandleCount,
1525  ObjectHeader->PointerCount);
1526 
1527  /* Check if the types match */
1528  if ((Type) && (ObjectType != Type))
1529  {
1530  /* They don't, cleanup */
1533  }
1534 
1535  /* Save the object header */
1536  NewEntry.Object = ObjectHeader;
1537 
1538  /* Check if this is a kernel handle */
1540  {
1541  /* Set the handle table */
1543  KernelHandle = TRUE;
1544 
1545  /* Check if we're not in the system process */
1547  {
1548  /* Attach to the system process */
1550  AttachedToProcess = TRUE;
1551  }
1552  }
1553  else
1554  {
1555  /* Get the current handle table */
1556  HandleTable = PsGetCurrentProcess()->ObjectTable;
1557  }
1558 
1559  /* Increment the handle count */
1561  AccessState,
1562  AccessMode,
1565  OpenReason);
1566  if (!NT_SUCCESS(Status))
1567  {
1568  /*
1569  * We failed (meaning security failure, according to NT Internals)
1570  * detach and return
1571  */
1573  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1574  return Status;
1575  }
1576 
1577  /* Check if we are doing audits on close */
1578  if (AccessState->GenerateOnClose)
1579  {
1580  /* Force the attribute on */
1582  }
1583 
1584  /* Mask out the internal attributes */
1586 
1587  /* Get the original desired access */
1588  DesiredAccess = AccessState->RemainingDesiredAccess |
1589  AccessState->PreviouslyGrantedAccess;
1590 
1591  /* Remove what's not in the valid access mask */
1592  GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1594 
1595  /* Update the value in the access state */
1596  AccessState->PreviouslyGrantedAccess = GrantedAccess;
1597 
1598  /* Get the auxiliary data */
1599  AuxData = AccessState->AuxData;
1600 
1601  /* Handle extra references */
1602  if (AdditionalReferences)
1603  {
1604  /* Add them to the header */
1606  AdditionalReferences);
1607  }
1608 
1609  /* Now we can release the object */
1611 
1612  /* Save the access mask */
1613  NewEntry.GrantedAccess = GrantedAccess;
1614 
1615  /*
1616  * Create the actual handle. We'll need to do this *after* calling
1617  * ObpIncrementHandleCount to make sure that Object Security is valid
1618  * (specified in Gl00my documentation on Ob)
1619  */
1621  "%s - Handle Properties: [%p-%lx-%lx]\n",
1622  __FUNCTION__,
1623  NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1624  Handle = ExCreateHandle(HandleTable, &NewEntry);
1625 
1626  /* Make sure we got a handle */
1627  if (Handle)
1628  {
1629  /* Check if this was a kernel handle */
1631 
1632  /* Return it */
1633  *ReturnedHandle = Handle;
1634 
1635  /* Check if we need to generate on audit */
1636  if (AccessState->GenerateAudit)
1637  {
1638  /* Audit the handle creation */
1639  //SeAuditHandleCreation(AccessState, Handle);
1640  }
1641 
1642  /* Check if this was a create */
1643  if (OpenReason == ObCreateHandle)
1644  {
1645  /* Check if we need to audit the privileges */
1646  if ((AuxData->PrivilegeSet) &&
1647  (AuxData->PrivilegeSet->PrivilegeCount))
1648  {
1649  /* Do the audit */
1650 #if 0
1652  &AccessState->
1654  GrantedAccess,
1655  AuxData->PrivilegeSet,
1656  TRUE,
1657  ExGetPreviousMode());
1658 #endif
1659  }
1660  }
1661 
1662  /* Return the new object only if caller wanted it biased */
1663  if ((AdditionalReferences) && (ReturnedObject))
1664  {
1665  /* Return it */
1666  *ReturnedObject = Object;
1667  }
1668 
1669  /* Detach if needed */
1670  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1671 
1672  /* Trace and return */
1674  "%s - Returning Handle: %p HC PC %lx %lx\n",
1675  __FUNCTION__,
1676  Handle,
1677  ObjectHeader->HandleCount,
1678  ObjectHeader->PointerCount);
1679  return STATUS_SUCCESS;
1680  }
1681 
1682  /* Decrement the handle count and detach */
1683  ObpDecrementHandleCount(&ObjectHeader->Body,
1685  GrantedAccess,
1686  ObjectType);
1687 
1688  /* Handle extra references */
1689  if (AdditionalReferences)
1690  {
1691  /* Check how many extra references were added */
1692  if (AdditionalReferences > 1)
1693  {
1694  /* Dereference it many times */
1696  -(LONG)(AdditionalReferences - 1));
1697  }
1698 
1699  /* Dereference the object one last time */
1701  }
1702 
1703  /* Detach if necessary and fail */
1704  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1706 }
1707 
1708 /*++
1709 * @name ObpCloseHandle
1710 *
1711 * The ObpCloseHandle routine <FILLMEIN>
1712 *
1713 * @param Handle
1714 * <FILLMEIN>.
1715 *
1716 * @param AccessMode
1717 * <FILLMEIN>.
1718 *
1719 * @return <FILLMEIN>.
1720 *
1721 * @remarks None.
1722 *
1723 *--*/
1724 NTSTATUS
1725 NTAPI
1728 {
1730  BOOLEAN AttachedToProcess = FALSE;
1732  PHANDLE_TABLE_ENTRY HandleTableEntry;
1733  NTSTATUS Status;
1735  PAGED_CODE();
1737  "%s - Closing handle: %p\n", __FUNCTION__, Handle);
1738 
1739  if (AccessMode == KernelMode && Handle == (HANDLE)-1)
1740  return STATUS_INVALID_HANDLE;
1741 
1742  /* Check if we're dealing with a kernel handle */
1744  {
1745  /* Use the kernel table and convert the handle */
1748 
1749  /* Check if we're not in the system process */
1751  {
1752  /* Attach to the system process */
1754  AttachedToProcess = TRUE;
1755  }
1756  }
1757  else
1758  {
1759  /* Use the process's handle table */
1760  HandleTable = Process->ObjectTable;
1761  }
1762 
1763  /* Enter a critical region to protect handle access */
1765 
1766  /* Get the handle entry */
1767  HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
1768  if (HandleTableEntry)
1769  {
1770  /* Now close the entry */
1772  HandleTableEntry,
1773  Handle,
1774  AccessMode,
1775  FALSE);
1776 
1777  /* We can quit the critical region now */
1779 
1780  /* Detach and return success */
1781  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1782  }
1783  else
1784  {
1785  /* We failed, quit the critical region */
1787 
1788  /* Detach */
1789  if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1790 
1791  /* Check if we have a valid handle that's not the process or thread */
1792  if ((Handle) &&
1793  (Handle != NtCurrentProcess()) &&
1794  (Handle != NtCurrentThread()))
1795  {
1796  /* Check if we came from user mode */
1797  if (AccessMode != KernelMode)
1798  {
1799  /* Check if we have no debug port */
1800  if (Process->DebugPort)
1801  {
1802  /* Make sure we're not attached */
1803  if (!KeIsAttachedProcess())
1804  {
1805  /* Raise an exception */
1807  }
1808  }
1809  }
1810  else
1811  {
1812  /* This is kernel mode. Check if we're exiting */
1814  (Process->Peb))
1815  {
1816  /* Check if the debugger is enabled */
1817  if (KdDebuggerEnabled)
1818  {
1819  /* Bugcheck */
1820  KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
1821  }
1822  }
1823  }
1824  }
1825 
1826  /* Set invalid status */
1828  }
1829 
1830  /* Return status */
1832  "%s - Closed handle: %p S: %lx\n",
1834  return Status;
1835 }
1836 
1837 /*++
1838 * @name ObpSetHandleAttributes
1839 *
1840 * The ObpSetHandleAttributes routine <FILLMEIN>
1841 *
1842 * @param HandleTableEntry
1843 * <FILLMEIN>.
1844 *
1845 * @param Context
1846 * <FILLMEIN>.
1847 *
1848 * @return <FILLMEIN>.
1849 *
1850 * @remarks None.
1851 *
1852 *--*/
1853 BOOLEAN
1854 NTAPI
1857 {
1859  POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1860 
1861  /* Check if making the handle inheritable */
1862  if (SetHandleInfo->Information.Inherit)
1863  {
1864  /* Check if inheriting is not supported for this object */
1865  if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1866  {
1867  /* Fail without changing anything */
1868  return FALSE;
1869  }
1870 
1871  /* Set the flag */
1872  HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1873  }
1874  else
1875  {
1876  /* Otherwise this implies we're removing the flag */
1877  HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1878  }
1879 
1880  /* Check if making the handle protected */
1881  if (SetHandleInfo->Information.ProtectFromClose)
1882  {
1883  /* Set the flag */
1884  HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1885  }
1886  else
1887  {
1888  /* Otherwise, remove it */
1889  HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1890  }
1891 
1892  /* Return success */
1893  return TRUE;
1894 }
1895 
1896 /*++
1897 * @name ObpCloseHandleCallback
1898 *
1899 * The ObpCloseHandleCallback routine <FILLMEIN>
1900 *
1901 * @param HandleTable
1902 * <FILLMEIN>.
1903 *
1904 * @param Object
1905 * <FILLMEIN>.
1906 *
1907 * @param GrantedAccess
1908 * <FILLMEIN>.
1909 *
1910 * @param Context
1911 * <FILLMEIN>.
1912 *
1913 * @return <FILLMEIN>.
1914 *
1915 * @remarks None.
1916 *
1917 *--*/
1918 BOOLEAN
1919 NTAPI
1921  IN HANDLE Handle,
1922  IN PVOID Context)
1923 {
1925 
1926  /* Simply decrement the handle count */
1927  ObpCloseHandleTableEntry(CloseContext->HandleTable,
1928  HandleTableEntry,
1929  Handle,
1930  CloseContext->AccessMode,
1931  TRUE);
1932  return TRUE;
1933 }
1934 
1935 /*++
1936 * @name ObpDuplicateHandleCallback
1937 *
1938 * The ObpDuplicateHandleCallback routine <FILLMEIN>
1939 *
1940 * @param HandleTable
1941 * <FILLMEIN>.
1942 *
1943 * @param HandleTableEntry
1944 * <FILLMEIN>.
1945 *
1946 * @param Context
1947 * <FILLMEIN>.
1948 *
1949 * @return <FILLMEIN>.
1950 *
1951 * @remarks None.
1952 *
1953 *--*/
1954 BOOLEAN
1955 NTAPI
1958  IN PHANDLE_TABLE_ENTRY OldEntry,
1959  IN PHANDLE_TABLE_ENTRY HandleTableEntry)
1960 {
1961  POBJECT_HEADER ObjectHeader;
1962  BOOLEAN Ret = FALSE;
1964  NTSTATUS Status;
1965  PAGED_CODE();
1966 
1967  /* Make sure that the handle is inheritable */
1968  Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0;
1969  if (Ret)
1970  {
1971  /* Get the object header */
1972  ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1973 
1974  /* Increment the pointer count */
1975  InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
1976 
1977  /* Release the handle lock */
1979 
1980  /* Setup the access state */
1981  AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess;
1982 
1983  /* Call the shared routine for incrementing handles */
1984  Status = ObpIncrementHandleCount(&ObjectHeader->Body,
1985  &AccessState,
1986  KernelMode,
1987  HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES,
1988  Process,
1989  ObInheritHandle);
1990  if (!NT_SUCCESS(Status))
1991  {
1992  /* Return failure */
1993  ObDereferenceObject(&ObjectHeader->Body);
1994  Ret = FALSE;
1995  }
1996  }
1997  else
1998  {
1999  /* Release the handle lock */
2001  }
2002 
2003  /* Return duplication result */
2004  return Ret;
2005 }
2006 
2007 /*++
2008 * @name ObClearProcessHandleTable
2009 *
2010 * The ObClearProcessHandleTable routine clears the handle table
2011 * of the given process.
2012 *
2013 * @param Process
2014 * The process of which the handle table should be cleared.
2015 *
2016 * @return None.
2017 *
2018 * @remarks None.
2019 *
2020 *--*/
2021 VOID
2022 NTAPI
2024 {
2028  BOOLEAN AttachedToProcess = FALSE;
2029 
2030  ASSERT(Process);
2031 
2032  /* Ensure the handle table doesn't go away while we use it */
2034  if (!HandleTable) return;
2035 
2036  /* Attach to the current process if needed */
2037  if (PsGetCurrentProcess() != Process)
2038  {
2040  AttachedToProcess = TRUE;
2041  }
2042 
2043  /* Enter a critical region */
2045 
2046  /* Fill out the context */
2047  Context.AccessMode = UserMode;
2048  Context.HandleTable = HandleTable;
2049 
2050  /* Sweep the handle table to close all handles */
2053  &Context);
2054 
2055  /* Leave the critical region */
2057 
2058  /* Detach if needed */
2059  if (AttachedToProcess)
2061 
2062  /* Let the handle table go */
2064 }
2065 
2066 /*++
2067 * @name ObInitProcess
2068 *
2069 * The ObInitProcess routine initializes the handle table for the process
2070 * to be initialized, by either creating a new one or duplicating it from
2071 * the parent process.
2072 *
2073 * @param Parent
2074 * A parent process (optional).
2075 *
2076 * @param Process
2077 * The process to initialize.
2078 *
2079 * @return Success or failure.
2080 *
2081 * @remarks None.
2082 *
2083 *--*/
2084 NTSTATUS
2085 NTAPI
2088 {
2089  PHANDLE_TABLE ParentTable, ObjectTable;
2090 
2091  /* Check for a parent */
2092  if (Parent)
2093  {
2094  /* Reference the parent's table */
2095  ParentTable = ObReferenceProcessHandleTable(Parent);
2096  if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2097 
2098  /* Duplicate it */
2099  ObjectTable = ExDupHandleTable(Process,
2100  ParentTable,
2102  OBJ_INHERIT);
2103  }
2104  else
2105  {
2106  /* Otherwise just create a new table */
2107  ParentTable = NULL;
2108  ObjectTable = ExCreateHandleTable(Process);
2109  }
2110 
2111  /* Make sure we have a table */
2112  if (ObjectTable)
2113  {
2114  /* Associate it */
2115  Process->ObjectTable = ObjectTable;
2116 
2117  /* Check for auditing */
2119  {
2120  /* FIXME: TODO */
2121  DPRINT1("Need auditing!\n");
2122  }
2123 
2124  /* Get rid of the old table now */
2125  if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2126 
2127  /* We are done */
2128  return STATUS_SUCCESS;
2129  }
2130  else
2131  {
2132  /* Fail */
2133  Process->ObjectTable = NULL;
2134  if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2136  }
2137 }
2138 
2139 /*++
2140 * @name ObKillProcess
2141 *
2142 * The ObKillProcess routine performs rundown operations on the process,
2143 * then clears and destroys its handle table.
2144 *
2145 * @param Process
2146 * The process to be killed.
2147 *
2148 * @return None.
2149 *
2150 * @remarks Called by the Object Manager cleanup code (kernel)
2151 * when a process is to be destroyed.
2152 *
2153 *--*/
2154 VOID
2155 NTAPI
2157 {
2160  BOOLEAN HardErrors;
2161  PAGED_CODE();
2162 
2163  /* Wait for process rundown and then complete it */
2164  ExWaitForRundownProtectionRelease(&Process->RundownProtect);
2165  ExRundownCompleted(&Process->RundownProtect);
2166 
2167  /* Get the object table */
2168  HandleTable = Process->ObjectTable;
2169  if (!HandleTable) return;
2170 
2171  /* Disable hard errors while we close handles */
2172  HardErrors = IoSetThreadHardErrorMode(FALSE);
2173 
2174  /* Enter a critical region */
2176 
2177  /* Fill out the context */
2178  Context.AccessMode = KernelMode;
2179  Context.HandleTable = HandleTable;
2180 
2181  /* Sweep the handle table to close all handles */
2184  &Context);
2185  ASSERT(HandleTable->HandleCount == 0);
2186 
2187  /* Leave the critical region */
2189 
2190  /* Re-enable hard errors */
2191  IoSetThreadHardErrorMode(HardErrors);
2192 
2193  /* Destroy the object table */
2194  Process->ObjectTable = NULL;
2196 }
2197 
2198 NTSTATUS
2199 NTAPI
2202  IN PEPROCESS TargetProcess OPTIONAL,
2206  IN ULONG Options,
2208 {
2209  HANDLE_TABLE_ENTRY NewHandleEntry;
2210  BOOLEAN AttachedToProcess = FALSE;
2211  PVOID SourceObject;
2212  POBJECT_HEADER ObjectHeader;
2214  HANDLE NewHandle;
2216  NTSTATUS Status;
2217  ACCESS_MASK TargetAccess, SourceAccess;
2220  AUX_ACCESS_DATA AuxData;
2223  ULONG AuditMask;
2225 
2226  PAGED_CODE();
2228  "%s - Duplicating handle: %p for %p into %p\n",
2229  __FUNCTION__,
2230  SourceHandle,
2231  SourceProcess,
2232  TargetProcess);
2233 
2234  /* Assume failure */
2235  if (TargetHandle) *TargetHandle = NULL;
2236 
2237  /* Check if we're not duplicating the same access */
2238  if (!(Options & DUPLICATE_SAME_ACCESS))
2239  {
2240  /* Validate the desired access */
2241  Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2242  if (!NT_SUCCESS(Status)) return Status;
2243  }
2244 
2245  /* Reference the object table */
2246  HandleTable = ObReferenceProcessHandleTable(SourceProcess);
2248 
2249  /* Reference the process object */
2251  SourceProcess,
2252  HandleTable,
2253  PreviousMode,
2254  &SourceObject,
2256  &AuditMask);
2257  if (!NT_SUCCESS(Status))
2258  {
2259  /* Fail */
2260  ObDereferenceProcessHandleTable(SourceProcess);
2261  return Status;
2262  }
2263  else
2264  {
2265  /* Check if we have to don't have to audit object close */
2266  if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2267  {
2268  /* Then there is no audit mask */
2269  AuditMask = 0;
2270  }
2271  }
2272 
2273  /* Check if there's no target process */
2274  if (!TargetProcess)
2275  {
2276  /* Check if the caller wanted actual duplication */
2278  {
2279  /* Invalid request */
2281  }
2282  else
2283  {
2284  /* Otherwise, do the attach */
2285  KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2286 
2287  /* Close the handle and detach */
2290  }
2291 
2292  /* Return */
2293  ObDereferenceProcessHandleTable(SourceProcess);
2294  ObDereferenceObject(SourceObject);
2295  return Status;
2296  }
2297 
2298  /* Create a kernel handle if asked, but only in the system process */
2299  if (PreviousMode == KernelMode &&
2301  TargetProcess == PsInitialSystemProcess)
2302  {
2303  KernelHandle = TRUE;
2304  }
2305 
2306  /* Get the target handle table */
2307  HandleTable = ObReferenceProcessHandleTable(TargetProcess);
2308  if (!HandleTable)
2309  {
2310  /* Check if the caller wanted us to close the handle */
2312  {
2313  /* Do the attach */
2314  KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2315 
2316  /* Close the handle and detach */
2319  }
2320 
2321  /* Return */
2322  ObDereferenceProcessHandleTable(SourceProcess);
2323  ObDereferenceObject(SourceObject);
2325  }
2326 
2327  /* Get the source access */
2328  SourceAccess = HandleInformation.GrantedAccess;
2329 
2330  /* Check if we're not in the target process */
2331  if (TargetProcess != PsGetCurrentProcess())
2332  {
2333  /* Attach to it */
2334  KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2335  AttachedToProcess = TRUE;
2336  }
2337 
2338  /* Check if we're duplicating the attributes */
2340  {
2341  /* Duplicate them */
2342  HandleAttributes = HandleInformation.HandleAttributes;
2343  }
2344  else
2345  {
2346  /* Don't allow caller to bypass auditing */
2347  HandleAttributes |= HandleInformation.HandleAttributes &
2349  }
2350 
2351  /* Check if we're duplicating the access */
2352  if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2353 
2354  /* Get object data */
2355  ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2356  ObjectType = ObjectHeader->Type;
2357 
2358  /* Fill out the entry */
2359  RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2360  NewHandleEntry.Object = ObjectHeader;
2361  NewHandleEntry.ObAttributes |= (HandleAttributes & OBJ_HANDLE_ATTRIBUTES);
2362 
2363  /* Check if we're using a generic mask */
2365  {
2366  /* Map it */
2368  &ObjectType->TypeInfo.GenericMapping);
2369  }
2370 
2371  /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2372  TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2374  NewHandleEntry.GrantedAccess = TargetAccess;
2375 
2376  /* Check if we're asking for new access */
2377  if (TargetAccess & ~SourceAccess)
2378  {
2379  /* We are. We need the security procedure to validate this */
2380  if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2381  {
2382  /* Use our built-in access state */
2385  &AuxData,
2386  TargetAccess,
2387  &ObjectType->TypeInfo.GenericMapping);
2388  }
2389  else
2390  {
2391  /* Otherwise we can't allow this privilege elevation */
2393  }
2394  }
2395  else
2396  {
2397  /* We don't need an access state */
2399  }
2400 
2401  /* Make sure the access state was created OK */
2402  if (NT_SUCCESS(Status))
2403  {
2404  /* Add a new handle */
2405  Status = ObpIncrementHandleCount(SourceObject,
2407  PreviousMode,
2411  }
2412 
2413  /* Check if we were attached */
2414  if (AttachedToProcess)
2415  {
2416  /* We can safely detach now */
2418  AttachedToProcess = FALSE;
2419  }
2420 
2421  /* Check if we have to close the source handle */
2423  {
2424  /* Attach and close */
2425  KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2428  }
2429 
2430  /* Check if we had an access state */
2432 
2433  /* Now check if incrementing actually failed */
2434  if (!NT_SUCCESS(Status))
2435  {
2436  /* Dereference handle tables */
2437  ObDereferenceProcessHandleTable(SourceProcess);
2438  ObDereferenceProcessHandleTable(TargetProcess);
2439 
2440  /* Dereference the source object */
2441  ObDereferenceObject(SourceObject);
2442  return Status;
2443  }
2444 
2445  if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2446  {
2447  NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2448  NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2449  }
2450 
2451  /* Now create the handle */
2452  NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2453  if (!NewHandle)
2454  {
2455  /* Undo the increment */
2456  ObpDecrementHandleCount(SourceObject,
2457  TargetProcess,
2458  TargetAccess,
2459  ObjectType);
2460 
2461  /* Deference the object and set failure status */
2462  ObDereferenceObject(SourceObject);
2464  }
2465 
2466  /* Mark it as a kernel handle if requested */
2467  if (KernelHandle)
2468  {
2469  NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2470  }
2471 
2472  /* Return the handle */
2473  if (TargetHandle) *TargetHandle = NewHandle;
2474 
2475  /* Dereference handle tables */
2476  ObDereferenceProcessHandleTable(SourceProcess);
2477  ObDereferenceProcessHandleTable(TargetProcess);
2478 
2479  /* Return status */
2481  "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2482  __FUNCTION__,
2483  NewHandle,
2484  SourceProcess,
2485  TargetProcess,
2486  SourceObject,
2487  ObjectHeader->PointerCount,
2488  ObjectHeader->HandleCount);
2489  return Status;
2490 }
2491 
2492 /* PUBLIC FUNCTIONS *********************************************************/
2493 
2494 /*++
2495 * @name ObOpenObjectByName
2496 * @implemented NT4
2497 *
2498 * The ObOpenObjectByName routine <FILLMEIN>
2499 *
2500 * @param ObjectAttributes
2501 * <FILLMEIN>.
2502 *
2503 * @param ObjectType
2504 * <FILLMEIN>.
2505 *
2506 * @param AccessMode
2507 * <FILLMEIN>.
2508 *
2509 * @param PassedAccessState
2510 * <FILLMEIN>.
2511 *
2512 * @param DesiredAccess
2513 * <FILLMEIN>.
2514 *
2515 * @param ParseContext
2516 * <FILLMEIN>.
2517 *
2518 * @param Handle
2519 * <FILLMEIN>.
2520 *
2521 * @return <FILLMEIN>.
2522 *
2523 * @remarks None.
2524 *
2525 *--*/
2526 NTSTATUS
2527 NTAPI
2533  IN OUT PVOID ParseContext,
2534  OUT PHANDLE Handle)
2535 {
2536  PVOID Object = NULL;
2538  NTSTATUS Status, Status2;
2539  POBJECT_HEADER ObjectHeader;
2541  OB_OPEN_REASON OpenReason;
2542  POB_TEMP_BUFFER TempBuffer;
2543  PAGED_CODE();
2544 
2545  /* Assume failure */
2546  *Handle = NULL;
2547 
2548  /* Check if we didn't get any Object Attributes */
2549  if (!ObjectAttributes)
2550  {
2551  /* Fail with special status code */
2552  return STATUS_INVALID_PARAMETER;
2553  }
2554 
2555  /* Allocate the temporary buffer */
2556  TempBuffer = ExAllocatePoolWithTag(NonPagedPool,
2557  sizeof(OB_TEMP_BUFFER),
2559  if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES;
2560 
2561  /* Capture all the info */
2563  AccessMode,
2564  AccessMode,
2565  TRUE,
2566  &TempBuffer->ObjectCreateInfo,
2567  &ObjectName);
2568  if (!NT_SUCCESS(Status))
2569  {
2570  /* Fail */
2572  return Status;
2573  }
2574 
2575  /* Check if we didn't get an access state */
2576  if (!PassedAccessState)
2577  {
2578  /* Try to get the generic mapping if we can */
2579  if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping;
2580 
2581  /* Use our built-in access state */
2582  PassedAccessState = &TempBuffer->LocalAccessState;
2584  &TempBuffer->AuxData,
2585  DesiredAccess,
2586  GenericMapping);
2587  if (!NT_SUCCESS(Status)) goto Quickie;
2588  }
2589 
2590  /* Get the security descriptor */
2591  if (TempBuffer->ObjectCreateInfo.SecurityDescriptor)
2592  {
2593  /* Save it in the access state */
2596  }
2597 
2598  /* Validate the access mask */
2600  if (!NT_SUCCESS(Status))
2601  {
2602  /* Cleanup after lookup */
2603  ObpReleaseLookupContext(&TempBuffer->LookupContext);
2604  goto Cleanup;
2605  }
2606 
2607  /* Now do the lookup */
2609  &ObjectName,
2610  TempBuffer->ObjectCreateInfo.Attributes,
2611  ObjectType,
2612  AccessMode,
2613  ParseContext,
2614  TempBuffer->ObjectCreateInfo.SecurityQos,
2615  NULL,
2617  &TempBuffer->LookupContext,
2618  &Object);
2619  if (!NT_SUCCESS(Status))
2620  {
2621  /* Cleanup after lookup */
2622  ObpReleaseLookupContext(&TempBuffer->LookupContext);
2623  goto Cleanup;
2624  }
2625 
2626  /* Check if this object has create information */
2627  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2628  if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
2629  {
2630  /* Then we are creating a new handle */
2631  OpenReason = ObCreateHandle;
2632 
2633  /* Check if we still have create info */
2634  if (ObjectHeader->ObjectCreateInfo)
2635  {
2636  /* Free it */
2637  ObpFreeObjectCreateInformation(ObjectHeader->
2638  ObjectCreateInfo);
2639  ObjectHeader->ObjectCreateInfo = NULL;
2640  }
2641  }
2642  else
2643  {
2644  /* Otherwise, we are merely opening it */
2645  OpenReason = ObOpenHandle;
2646  }
2647 
2648  /* Check if we have invalid object attributes */
2649  if (ObjectHeader->Type->TypeInfo.InvalidAttributes &
2650  TempBuffer->ObjectCreateInfo.Attributes)
2651  {
2652  /* Set failure code */
2654 
2655  /* Cleanup after lookup */
2656  ObpReleaseLookupContext(&TempBuffer->LookupContext);
2657 
2658  /* Dereference the object */
2660  }
2661  else
2662  {
2663  /* Create the actual handle now */
2664  Status2 = ObpCreateHandle(OpenReason,
2665  Object,
2666  ObjectType,
2668  0,
2669  TempBuffer->ObjectCreateInfo.Attributes,
2670  &TempBuffer->LookupContext,
2671  AccessMode,
2672  NULL,
2673  Handle);
2674  if (!NT_SUCCESS(Status2))
2675  {
2677  Status = Status2;
2678  }
2679  }
2680 
2681 Cleanup:
2682  /* Delete the access state */
2683  if (PassedAccessState == &TempBuffer->LocalAccessState)
2684  {
2686  }
2687 
2688 Quickie:
2689  /* Release the object attributes and temporary buffer */
2693 
2694  /* Return status */
2696  "%s - returning Object %p with PC S: %lx %lx\n",
2697  __FUNCTION__,
2698  Object,
2699  Object ? OBJECT_TO_OBJECT_HEADER(Object)->PointerCount : -1,
2700  Status);
2701  return Status;
2702 }
2703 
2704 /*++
2705 * @name ObOpenObjectByPointer
2706 * @implemented NT4
2707 *
2708 * The ObOpenObjectByPointer routine <FILLMEIN>
2709 *
2710 * @param Object
2711 * <FILLMEIN>.
2712 *
2713 * @param HandleAttributes
2714 * <FILLMEIN>.
2715 *
2716 * @param PassedAccessState
2717 * <FILLMEIN>.
2718 *
2719 * @param DesiredAccess
2720 * <FILLMEIN>.
2721 *
2722 * @param ObjectType
2723 * <FILLMEIN>.
2724 *
2725 * @param AccessMode
2726 * <FILLMEIN>.
2727 *
2728 * @param Handle
2729 * <FILLMEIN>.
2730 *
2731 * @return <FILLMEIN>.
2732 *
2733 * @remarks None.
2734 *
2735 *--*/
2736 NTSTATUS
2737 NTAPI
2744  OUT PHANDLE Handle)
2745 {
2747  NTSTATUS Status;
2749  AUX_ACCESS_DATA AuxData;
2750  PAGED_CODE();
2751 
2752  /* Assume failure */
2753  *Handle = NULL;
2754 
2755  /* Reference the object */
2757  0,
2758  ObjectType,
2759  AccessMode);
2760  if (!NT_SUCCESS(Status)) return Status;
2761 
2762  /* Get the Header Info */
2764 
2765  /* Check if we didn't get an access state */
2766  if (!PassedAccessState)
2767  {
2768  /* Use our built-in access state */
2771  &AuxData,
2772  DesiredAccess,
2773  &Header->Type->TypeInfo.GenericMapping);
2774  if (!NT_SUCCESS(Status))
2775  {
2776  /* Fail */
2778  return Status;
2779  }
2780  }
2781 
2782  /* Check if we have invalid object attributes */
2783  if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
2784  {
2785  /* Delete the access state */
2787  {
2789  }
2790 
2791  /* Dereference the object */
2793  return STATUS_INVALID_PARAMETER;
2794  }
2795 
2796  /* Create the handle */
2798  Object,
2799  ObjectType,
2801  0,
2803  NULL,
2804  AccessMode,
2805  NULL,
2806  Handle);
2808 
2809  /* Delete the access state */
2811  {
2813  }
2814 
2815  /* Return */
2817  "%s - returning Object with PC S: %lx %lx\n",
2818  __FUNCTION__,
2819  OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
2820  Status);
2821  return Status;
2822 }
2823 
2824 /*++
2825 * @name ObFindHandleForObject
2826 * @implemented NT4
2827 *
2828 * The ObFindHandleForObject routine <FILLMEIN>
2829 *
2830 * @param Process
2831 * <FILLMEIN>.
2832 *
2833 * @param Object
2834 * <FILLMEIN>.
2835 *
2836 * @param ObjectType
2837 * <FILLMEIN>.
2838 *
2839 * @param HandleInformation
2840 * <FILLMEIN>.
2841 *
2842 * @param HandleReturn
2843 * <FILLMEIN>.
2844 *
2845 * @return <FILLMEIN>.
2846 *
2847 * @remarks None.
2848 *
2849 *--*/
2850 BOOLEAN
2851 NTAPI
2853  IN PVOID Object,
2856  OUT PHANDLE Handle)
2857 {
2858  OBP_FIND_HANDLE_DATA FindData;
2859  BOOLEAN Result = FALSE;
2860  PVOID ObjectTable;
2861 
2862  /* Make sure we have an object table */
2863  ObjectTable = ObReferenceProcessHandleTable(Process);
2864  if (ObjectTable)
2865  {
2866  /* Check if we have an object */
2867  if (Object)
2868  {
2869  /* Set its header */
2871  }
2872  else
2873  {
2874  /* Otherwise, no object to match*/
2875  FindData.ObjectHeader = NULL;
2876  }
2877 
2878  /* Set other information */
2879  FindData.ObjectType = ObjectType;
2881 
2882  /* Enumerate the handle table */
2883  if (ExEnumHandleTable(Process->ObjectTable,
2885  &FindData,
2886  Handle))
2887  {
2888  /* Set success */
2889  Result = TRUE;
2890  }
2891 
2892  /* Let go of the table */
2894  }
2895 
2896  /* Return the result */
2897  return Result;
2898 }
2899 
2900 /*++
2901 * @name ObInsertObject
2902 * @implemented NT4
2903 *
2904 * The ObInsertObject routine <FILLMEIN>
2905 *
2906 * @param Object
2907 * <FILLMEIN>.
2908 *
2909 * @param PassedAccessState
2910 * <FILLMEIN>.
2911 *
2912 * @param DesiredAccess
2913 * <FILLMEIN>.
2914 *
2915 * @param AdditionalReferences
2916 * <FILLMEIN>.
2917 *
2918 * @param ReferencedObject
2919 * <FILLMEIN>.
2920 *
2921 * @param Handle
2922 * <FILLMEIN>.
2923 *
2924 * @return <FILLMEIN>.
2925 *
2926 * @remarks None.
2927 *
2928 *--*/
2929 NTSTATUS
2930 NTAPI
2936  OUT PHANDLE Handle)
2937 {
2938  POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2939  POBJECT_HEADER ObjectHeader;
2942  PVOID InsertObject;
2943  PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
2944  BOOLEAN SdAllocated = FALSE;
2945  POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2947  ACCESS_STATE LocalAccessState;
2948  AUX_ACCESS_DATA AuxData;
2949  OB_OPEN_REASON OpenReason;
2951  NTSTATUS Status = STATUS_SUCCESS, RealStatus;
2952  BOOLEAN IsNewObject;
2953  PAGED_CODE();
2954 
2955  /* Get the Header */
2956  ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2957 
2958  /* Detect invalid insert */
2959  if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO))
2960  {
2961  /* Display warning and break into debugger */
2962  DPRINT1("OB: Attempting to insert existing object %p\n", Object);
2963  DbgBreakPoint();
2964 
2965  /* Allow debugger to continue */
2967  return STATUS_INVALID_PARAMETER;
2968  }
2969 
2970  /* Get the create and name info, as well as the object type */
2971  ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
2972  ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
2973  ObjectType = ObjectHeader->Type;
2974  ObjectName = NULL;
2975 
2976  /* Check if this is an named object */
2977  if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
2978  {
2979  /* Get the object name */
2980  ObjectName = &ObjectNameInfo->Name;
2981  }
2982 
2983  /* Sanity check */
2984  ASSERT((Handle) ||
2985  ((ObjectPointerBias == 0) &&
2986  (ObjectName == NULL) &&
2987  (ObjectType->TypeInfo.SecurityRequired) &&
2988  (NewObject == NULL)));
2989 
2990  /* Check if the object is unnamed and also doesn't have security */
2992  if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName))
2993  {
2994  /* Assume failure */
2995  *Handle = NULL;
2996  ObjectHeader->ObjectCreateInfo = NULL;
2997 
2998  /* Create the handle */
3000  DesiredAccess,
3001  ObjectPointerBias + 1,
3002  ObjectCreateInfo->Attributes,
3003  PreviousMode,
3004  NewObject,
3005  Handle);
3006 
3007  /* Free the create information */
3008  ObpFreeObjectCreateInformation(ObjectCreateInfo);
3009 
3010  /* Release the object name information */
3011  ObpDereferenceNameInfo(ObjectNameInfo);
3012 
3013  /* Remove the extra keep-alive reference */
3015 
3016  /* Return */
3018  "%s - returning Object with PC S: %lx %lx\n",
3019  __FUNCTION__,
3020  ObjectHeader->PointerCount,
3021  Status);
3022  return Status;
3023  }
3024 
3025  /* Check if we didn't get an access state */
3026  if (!AccessState)
3027  {
3028  /* Use our built-in access state */
3029  AccessState = &LocalAccessState;
3030  Status = SeCreateAccessState(&LocalAccessState,
3031  &AuxData,
3032  DesiredAccess,
3033  &ObjectType->TypeInfo.GenericMapping);
3034  if (!NT_SUCCESS(Status))
3035  {
3036  /* Fail */
3037  ObpDereferenceNameInfo(ObjectNameInfo);
3039  return Status;
3040  }
3041  }
3042 
3043  /* Save the security descriptor */
3044  AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;
3045 
3046  /* Validate the access mask */
3048  if (!NT_SUCCESS(Status))
3049  {
3050  /* Fail */
3051  ObpDereferenceNameInfo(ObjectNameInfo);
3053  return Status;
3054  }
3055 
3056  /* Setup a lookup context */
3058  InsertObject = Object;
3059  OpenReason = ObCreateHandle;
3060 
3061  /* Check if the object is named */
3062  if (ObjectName)
3063  {
3064  /* Look it up */
3065  Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory,
3066  ObjectName,
3067  ObjectCreateInfo->Attributes,
3068  ObjectType,
3069  (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ?
3070  KernelMode : UserMode,
3071  ObjectCreateInfo->ParseContext,
3072  ObjectCreateInfo->SecurityQos,
3073  Object,
3074  AccessState,
3075  &Context,
3076  &InsertObject);
3077 
3078  /* Check if we found an object that doesn't match the one requested */
3079  if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject))
3080  {
3081  /* This means we're opening an object, not creating a new one */
3082  OpenReason = ObOpenHandle;
3083 
3084  /* Make sure the caller said it's OK to do this */
3085  if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
3086  {
3087  /* He did, but did he want this type? */
3088  if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type)
3089  {
3090  /* Wrong type, so fail */
3092  }
3093  else
3094  {
3095  /* Right type, so warn */
3097  }
3098  }
3099  else
3100  {
3101  /* Check if this was a symbolic link */
3102  if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
3104  {
3105  /* Dereference it */
3106  ObDereferenceObject(InsertObject);
3107  }
3108 
3109  /* Caller wanted to create a new object, fail */
3111  }
3112  }
3113 
3114  /* Check if anything until now failed */
3115  if (!NT_SUCCESS(Status))
3116  {
3117  /* Cleanup after lookup */
3119 
3120  /* Remove query reference that we added */
3121  ObpDereferenceNameInfo(ObjectNameInfo);
3122 
3123  /* Dereference the object and delete the access state */
3125  if (AccessState == &LocalAccessState)
3126  {
3127  /* We used a local one; delete it */
3129  }
3130 
3131  /* Return failure code */
3132  return Status;
3133  }
3134  else
3135  {
3136  /* Check if this is a symbolic link */
3138  {
3139  /* Create the internal name */
3141  }
3142  }
3143  }
3144 
3145  /* Now check if this object is being created */
3146  if (InsertObject == Object)
3147  {
3148  /* Check if it's named or forces security */
3149  if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired))
3150  {
3151  /* Make sure it's inserted into an object directory */
3152  if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
3153  {
3154  /* Get the current descriptor */
3155  ObGetObjectSecurity(ObjectNameInfo->Directory,
3156  &ParentDescriptor,
3157  &SdAllocated);
3158  }
3159 
3160  /* Now assign it */
3162  ParentDescriptor,
3163  Object,
3164  ObjectType);
3165 
3166  /* Check if we captured one */
3167  if (ParentDescriptor)
3168  {
3169  /* We did, release it */
3170  ObReleaseObjectSecurity(ParentDescriptor, SdAllocated);
3171  }
3172  else if (NT_SUCCESS(Status))
3173  {
3174  /* Other we didn't, but we were able to use the current SD */
3176  ObjectCreateInfo->ProbeMode,
3177  TRUE);
3178 
3179  /* Clear the current one */
3180  AccessState->SecurityDescriptor =
3181  ObjectCreateInfo->SecurityDescriptor = NULL;
3182  }
3183  }
3184 
3185  /* Check if anything until now failed */
3186  if (!NT_SUCCESS(Status))
3187  {
3188  /* Check if the directory was added */
3189  if (Context.DirectoryLocked)
3190  {
3191  /* Weird case where we need to do a manual delete */
3192  DPRINT1("Unhandled path\n");
3193  ASSERT(FALSE);
3194  }
3195 
3196  /* Cleanup the lookup */
3198 
3199  /* Remove query reference that we added */
3200  ObpDereferenceNameInfo(ObjectNameInfo);
3201 
3202  /* Dereference the object and delete the access state */
3204  if (AccessState == &LocalAccessState)
3205  {
3206  /* We used a local one; delete it */
3208  }
3209 
3210  /* Return failure code */
3211  ASSERT(FALSE);
3212  return Status;
3213  }
3214  }
3215 
3216  /* Save the actual status until here */
3217  RealStatus = Status;
3218 
3219  /* Check if caller wants us to create a handle */
3220  ObjectHeader->ObjectCreateInfo = NULL;
3221  if (Handle)
3222  {
3223  /* Create the handle */
3224  Status = ObpCreateHandle(OpenReason,
3225  InsertObject,
3226  NULL,
3227  AccessState,
3228  ObjectPointerBias + 1,
3229  ObjectCreateInfo->Attributes,
3230  &Context,
3231  PreviousMode,
3232  NewObject,
3233  Handle);
3234  if (!NT_SUCCESS(Status))
3235  {
3236  /* If the object had a name, backout everything */
3238 
3239  /* Return the status of the failure */
3240  *Handle = NULL;
3241  RealStatus = Status;
3242  }
3243 
3244  /* Remove a query reference */
3245  ObpDereferenceNameInfo(ObjectNameInfo);
3246 
3247  /* Remove the extra keep-alive reference */
3249  }
3250  else
3251  {
3252  /* Otherwise, lock the object */
3253  ObpAcquireObjectLock(ObjectHeader);
3254 
3255  /* And charge quota for the process to make it appear as used */
3256  RealStatus = ObpChargeQuotaForObject(ObjectHeader,
3257  ObjectType,
3258  &IsNewObject);
3259 
3260  /* Release the lock */
3261  ObpReleaseObjectLock(ObjectHeader);
3262 
3263  /* Check if we failed and dereference the object if so */
3264  if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
3265  }
3266 
3267  /* We can delete the Create Info now */
3268  ObpFreeObjectCreateInformation(ObjectCreateInfo);
3269 
3270  /* Check if we created our own access state and delete it if so */
3271  if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState);
3272 
3273  /* Return status code */
3275  "%s - returning Object with PC RS/S: %lx %lx %lx\n",
3276  __FUNCTION__,
3277  OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
3278  RealStatus, Status);
3279  return RealStatus;
3280 }
3281 
3282 /*++
3283 * @name ObSetHandleAttributes
3284 * @implemented NT5.1
3285 *
3286 * The ObSetHandleAttributes routine <FILLMEIN>
3287 *
3288 * @param Handle
3289 * <FILLMEIN>.
3290 *
3291 * @param HandleFlags
3292 * <FILLMEIN>.
3293 *
3294 * @param PreviousMode
3295 * <FILLMEIN>.
3296 *
3297 * @return <FILLMEIN>.
3298 *
3299 * @remarks None.
3300 *
3301 *--*/
3302 NTSTATUS
3303 NTAPI
3307 {
3308  OBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleAttributesContext;
3309  BOOLEAN Result, AttachedToSystemProcess = FALSE;
3312  PAGED_CODE();
3313 
3314  /* Check if this is a kernel handle */
3316  {
3317  /* Use the kernel table and convert the handle */
3320 
3321  /* Check if we're not in the system process */
3323  {
3324  /* Attach to the system process */
3326  AttachedToSystemProcess = TRUE;
3327  }
3328  }
3329  else
3330  {
3331  /* Get the current process' handle table */
3332  HandleTable = PsGetCurrentProcess()->ObjectTable;
3333  }
3334 
3335  /* Initialize the handle attribute context */
3336  SetHandleAttributesContext.PreviousMode = PreviousMode;
3337  SetHandleAttributesContext.Information = *HandleFlags;
3338 
3339  /* Invoke the ObpSetHandleAttributes callback */
3341  Handle,
3343  (ULONG_PTR)&SetHandleAttributesContext);
3344 
3345  /* Did we attach to the system process? */
3346  if (AttachedToSystemProcess)
3347  {
3348  /* Detach from it */
3350  }
3351 
3352  /* Return the result as an NTSTATUS value */
3354 }
3355 
3356 /*++
3357 * @name ObCloseHandle
3358 * @implemented NT5.1
3359 *
3360 * The ObCloseHandle routine <FILLMEIN>
3361 *
3362 * @param Handle
3363 * <FILLMEIN>.
3364 *
3365 * @param AccessMode
3366 * <FILLMEIN>.
3367 *
3368 * @return <FILLMEIN>.
3369 *
3370 * @remarks None.
3371 *
3372 *--*/
3373 NTSTATUS
3374 NTAPI
3377 {
3378  /* Call the internal API */
3379  return ObpCloseHandle(Handle, AccessMode);
3380 }
3381 
3382 /*++
3383 * @name NtClose
3384 * @implemented NT4
3385 *
3386 * The NtClose routine <FILLMEIN>
3387 *
3388 * @param Handle
3389 * <FILLMEIN>.
3390 *
3391 * @return <FILLMEIN>.
3392 *
3393 * @remarks None.
3394 *
3395 *--*/
3396 NTSTATUS
3397 NTAPI
3399 {
3400  /* Call the internal API */
3402 }
3403 
3404 NTSTATUS
3405 NTAPI
3406 NtDuplicateObject(IN HANDLE SourceProcessHandle,
3412  IN ULONG Options)
3413 {
3414  PEPROCESS SourceProcess, TargetProcess, Target;
3415  HANDLE hTarget;
3417  NTSTATUS Status;
3419  "%s - Duplicating handle: %p for %p into %p.\n",
3420  __FUNCTION__,
3421  SourceHandle,
3422  SourceProcessHandle,
3424 
3425  /* Check if we have a target handle */
3426  if ((TargetHandle) && (PreviousMode != KernelMode))
3427  {
3428  /* Enter SEH */
3429  _SEH2_TRY
3430  {
3431  /* Probe the handle and assume failure */
3433  *TargetHandle = NULL;
3434  }
3436  {
3437  /* Return the exception code */
3439  }
3440  _SEH2_END;
3441  }
3442 
3443  /* Now reference the input handle */
3444  Status = ObReferenceObjectByHandle(SourceProcessHandle,
3446  PsProcessType,
3447  PreviousMode,
3448  (PVOID*)&SourceProcess,
3449  NULL);
3450  if (!NT_SUCCESS(Status)) return Status;
3451 
3452  /* Check if got a target handle */
3453  if (TargetProcessHandle)
3454  {
3455  /* Now reference the output handle */
3458  PsProcessType,
3459  PreviousMode,
3460  (PVOID*)&TargetProcess,
3461  NULL);
3462  if (NT_SUCCESS(Status))
3463  {
3464  /* Use this target process */
3465  Target = TargetProcess;
3466  }
3467  else
3468  {
3469  /* No target process */
3470  Target = NULL;
3471  }
3472  }
3473  else
3474  {
3475  /* No target process */
3477  Target = NULL;
3478  }
3479 
3480  /* Call the internal routine */
3481  Status = ObDuplicateObject(SourceProcess,
3482  SourceHandle,
3483  Target,
3484  &hTarget,
3485  DesiredAccess,
3487  Options,
3488  PreviousMode);
3489 
3490  /* Check if the caller wanted the return handle */
3491  if (TargetHandle)
3492  {
3493  /* Protect the write to user mode */
3494  _SEH2_TRY
3495  {
3496  /* Write the new handle */
3497  *TargetHandle = hTarget;
3498  }
3500  {
3501  /* Otherwise, get the exception code */
3503  }
3504  _SEH2_END;
3505  }
3506 
3507  /* Dereference the processes */
3509  "%s - Duplicated handle: %p into %p S %lx\n",
3510  __FUNCTION__,
3511  hTarget,
3513  Status);
3515  ObDereferenceObject(SourceProcess);
3516  return Status;
3517 }
3518 
3519 BOOLEAN
3520 NTAPI
3522 {
3523  /* Use the inlined version. We know we are in kernel mode. */
3525 }
3526 
3527 /* EOF */
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2528
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
PPRIVILEGE_SET PrivilegeSet
Definition: setypes.h:234
POBJECT_HEADER ObjectHeader
Definition: ob.h:118
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define TAG_OB_TEMP_STORAGE
Definition: ob.h:155
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ObjectType
Definition: metafile.c:80
NTSTATUS NTAPI ObAssignSecurity(IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PVOID Object, IN POBJECT_TYPE Type)
Definition: obsecure.c:550
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:429
#define IN
Definition: typedefs.h:39
#define SE_SACL_PRESENT
Definition: setypes.h:788
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:222
#define DUPLICATE_CLOSE_SOURCE
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define GENERIC_ALL
Definition: nt_native.h:92
PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:28
KAPC_STATE
Definition: ketypes.h:1280
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information
Definition: ob.h:107
#define STATUS_QUOTA_EXCEEDED
Definition: ntstatus.h:304
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:948
POBJECT_TYPE ObjectType
Definition: ob.h:119
LONG_PTR HandleCount
Definition: obtypes.h:490
KPROCESSOR_MODE PreviousMode
Definition: ob.h:106
NTKERNELAPI VOID FASTCALL ExRundownCompleted(_Out_ PEX_RUNDOWN_REF RunRef)
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI ObSetHandleAttributes(IN HANDLE Handle, IN POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: obhandle.c:3304
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2852
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:458
HANDLE KernelHandle
Definition: legacy.c:24
ULONG_PTR ObAttributes
Definition: extypes.h:600
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI ObIsKernelHandle(IN HANDLE Handle)
Definition: obhandle.c:3521
#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
OBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: ob.h:159
NTSTATUS NTAPI ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, IN POBJECT_TYPE ObjectType, OUT PBOOLEAN NewObject)
Definition: obhandle.c:433
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
Definition: handle.c:1010
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
VOID NTAPI ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, IN PVOID DestroyHandleProcedure OPTIONAL)
Definition: handle.c:927
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
#define NtCurrentThread()
#define ExAcquireRundownProtection
Definition: ex.h:133
UNICODE_STRING Name
Definition: obtypes.h:433
#define GENERIC_ACCESS
Definition: wlx.c:26
_Inout_opt_ PACCESS_STATE PassedAccessState
Definition: obfuncs.h:71
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:103
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
_Must_inspect_result_ _In_ _In_ ULONG ProbeMode
Definition: mmfuncs.h:561
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:69
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
NTSTATUS NTAPI ObpIncrementUnnamedHandleCount(IN PVOID Object, IN PACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process)
Definition: obhandle.c:1086
ULONG NTAPI ObGetProcessHandleCount(IN PEPROCESS Process)
Definition: obhandle.c:58
GENERIC_MAPPING GenericMapping
Definition: setypes.h:235
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:728
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
VOID NTAPI SeDeleteAccessState(_In_ PACCESS_STATE AccessState)
Deletes an allocated access state from the memory.
Definition: access.c:668
#define InsertTailList(ListHead, Entry)
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2738
NTSTATUS NTAPI ObpCreateHandle(IN OB_OPEN_REASON OpenReason, IN PVOID Object, IN POBJECT_TYPE Type OPTIONAL, IN PACCESS_STATE AccessState, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN POBP_LOOKUP_CONTEXT Context, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1493
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:887
#define OBJ_OPENIF
Definition: winternl.h:229
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
BOOLEAN NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
Definition: handle.c:1153
KPROCESSOR_MODE ProbeMode
Definition: obtypes.h:340
PHANDLE_TABLE HandleTable
Definition: ob.h:112
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS NTAPI SeCreateAccessState(_Inout_ PACCESS_STATE AccessState, _In_ PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
Creates an access state.
Definition: access.c:639
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
struct _OBJECT_HANDLE_COUNT_ENTRY OBJECT_HANDLE_COUNT_ENTRY
HANDLE NTAPI ExCreateHandle(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:791
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define OBJ_PROTECT_CLOSE
#define OBJ_AUDIT_OBJECT_CLOSE
Definition: ob.h:51
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
#define DUPLICATE_SAME_ACCESS
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
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI DbgBreakPoint(VOID)
Definition: Header.h:8
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:220
struct _OBP_CLOSE_HANDLE_CONTEXT * POBP_CLOSE_HANDLE_CONTEXT
long LONG
Definition: pedump.c:60
#define PROCESS_DUP_HANDLE
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
#define PsGetCurrentProcess
Definition: psfuncs.h:17
Definition: extypes.h:595
VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated)
Definition: obsecure.c:709
NTSTATUS NTAPI ObpIncrementHandleCount(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
Definition: obhandle.c:807
unsigned char BOOLEAN
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
#define ObpGetHandleObject(x)
Definition: ob.h:86
POBJECT_HANDLE_INFORMATION HandleInformation
Definition: ob.h:120
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:344
ULONG HandleCount
Definition: obtypes.h:445
VOID NTAPI ObpDecrementHandleCount(IN PVOID ObjectBody, IN PEPROCESS Process, IN ACCESS_MASK GrantedAccess, IN POBJECT_TYPE ObjectType)
Definition: obhandle.c:526
BOOLEAN NTAPI ObpSetHandleAttributes(IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, IN ULONG_PTR Context)
Definition: obhandle.c:1855
UCHAR Flags
Definition: obtypes.h:497
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease(_Inout_ PEX_RUNDOWN_REF RunRef)
void * PVOID
Definition: retypes.h:9
#define OB_FLAG_EXCLUSIVE
Definition: obtypes.h:100
NTSTATUS NTAPI ObpCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:1726
$ULONG PrivilegeCount
Definition: setypes.h:86
NTSTATUS NTAPI ObGetObjectSecurity(IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated)
Definition: obsecure.c:611
#define NtCurrentProcess()
Definition: nt_native.h:1657
struct _EPROCESS * Process
Definition: obtypes.h:444
PHANDLE_TABLE NTAPI ExDupHandleTable(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, IN ULONG_PTR Mask)
Definition: handle.c:1036
Status
Definition: gdiplustypes.h:24
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:122
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
BOOLEAN NTAPI ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:213
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
#define ObMarkHandleAsKernelHandle(Handle)
Definition: ob.h:80
NTSTATUS NTAPI ObpCreateUnnamedHandle(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1308
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:459
ACCESS_STATE LocalAccessState
Definition: ob.h:158
NTSTATUS NTAPI ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN IgnoreHandleProtection)
Definition: obhandle.c:681
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI ObpValidateAccessMask(IN PACCESS_STATE AccessState)
Definition: obhandle.c:484
#define OBJ_INHERIT
Definition: winternl.h:225
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
ULONG GrantedAccess
Definition: extypes.h:606
#define ObDereferenceObject
Definition: obfuncs.h:203
static OB_SECURITY_METHOD SeDefaultObjectMethod
Definition: ObTypes.c:139
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
Type
Definition: Type.h:6
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
NTSTATUS NTAPI ObInitProcess(IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Process)
Definition: obhandle.c:2086
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
PHANDLE_TABLE NTAPI ExCreateHandleTable(IN PEPROCESS Process OPTIONAL)
Definition: handle.c:765
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:40
_In_ HANDLE _In_opt_ HANDLE TargetProcessHandle
Definition: obfuncs.h:429
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
VOID NTAPI ObpCreateSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:334
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:97
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI ObpReferenceProcessObjectByHandle(IN HANDLE Handle, IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation, OUT PACCESS_MASK AuditMask)
Definition: obhandle.c:87
char * PBOOLEAN
Definition: retypes.h:11
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: obtypes.h:345
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
#define InterlockedDecrement
Definition: armddk.h:52
NTSTATUS NTAPI ObpIncrementHandleDataBase(IN POBJECT_HEADER ObjectHeader, IN PEPROCESS Process, IN OUT PULONG NewProcessHandleCount)
Definition: obhandle.c:335
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define OB_HANDLE_DEBUG
Definition: ob.h:17
VOID NTAPI SePrivilegeObjectAuditAlarm(_In_ HANDLE Handle, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE CurrentMode)
Raises an audit with alarm notification message when an object tries to acquire this privilege.
Definition: audit.c:1422
#define STATUS_HANDLE_NOT_CLOSABLE
Definition: ntstatus.h:697
VOID NTAPI ObClearProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:2023
KPROCESS Pcb
Definition: pstypes.h:1262
OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]
Definition: obtypes.h:451
BOOLEAN NTAPI ExEnumHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_ENUM_HANDLE_CALLBACK EnumHandleProcedure, IN OUT PVOID Context, OUT PHANDLE EnumHandle OPTIONAL)
Definition: handle.c:1235
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
static const WCHAR Cleanup[]
Definition: register.c:80
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
AUX_ACCESS_DATA AuxData
Definition: ob.h:161
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:98
enum _OB_OPEN_REASON OB_OPEN_REASON
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
NTSTATUS NTAPI KeRaiseUserException(IN NTSTATUS ExceptionCode)
Definition: except.c:397
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
BOOLEAN NTAPI ObCheckObjectAccess(IN PVOID Object, IN OUT PACCESS_STATE AccessState, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus)
Definition: obsecure.c:441
_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
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2931
Definition: obtypes.h:442
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define InterlockedIncrement
Definition: armddk.h:53
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
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
OBP_LOOKUP_CONTEXT LookupContext
Definition: ob.h:160
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:126
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1679
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
unsigned int * PULONG
Definition: retypes.h:1
LONG_PTR PointerCount
Definition: obtypes.h:487
#define NULL
Definition: types.h:112
VOID NTAPI ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context)
Definition: handle.c:1196
NTSTATUS NTAPI ObDuplicateObject(IN PEPROCESS SourceProcess, IN HANDLE SourceHandle, IN PEPROCESS TargetProcess OPTIONAL, IN PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options, IN KPROCESSOR_MODE PreviousMode)
Definition: obhandle.c:2200
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define TAG_OB_HANDLE
Definition: obhandle.c:22
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE Handle
Definition: extypes.h:390
struct tagContext Context
Definition: acpixf.h:1034
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3406
#define OUT
Definition: typedefs.h:40
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK PreviouslyGrantedAccess
Definition: sefuncs.h:13
#define ObpAccessProtectCloseBit
Definition: ob.h:59
unsigned int ULONG
Definition: retypes.h:1
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
BOOLEAN NTAPI ObpCloseHandleCallback(IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:1920
PVOID Object
Definition: extypes.h:599
BOOLEAN NTAPI ObpDuplicateHandleCallback(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY OldEntry, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: obhandle.c:1956
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID NTAPI ObKillProcess(IN PEPROCESS Process)
Definition: obhandle.c:2156
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153
#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:78
#define DPRINT
Definition: sndvol32.h:71
POBJECT_TYPE Type
Definition: obtypes.h:493
#define OBJ_HANDLE_ATTRIBUTES
Definition: ob.h:52
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:13
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG _Out_opt_ PVOID * NewObject
Definition: obfuncs.h:71
#define OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(h)
Definition: obtypes.h:131
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301
VOID NTAPI ObDereferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:50
#define __FUNCTION__
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
signed int * PLONG
Definition: retypes.h:5
POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader)
Definition: obhandle.c:261
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:429
POBJECT_TYPE PsProcessType
Definition: process.c:20
ULONG ACCESS_MASK
Definition: nt_native.h:40
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:500
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
KPROCESSOR_MODE AccessMode
Definition: ob.h:113
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG ObjectPointerBias
Definition: obfuncs.h:71
struct _OBJECT_HANDLE_COUNT_DATABASE OBJECT_HANDLE_COUNT_DATABASE
NTSTATUS NTAPI ObpLookupObjectName(IN HANDLE RootHandle OPTIONAL, IN OUT PUNICODE_STRING ObjectName, IN ULONG Attributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, IN PVOID InsertObject OPTIONAL, IN OUT PACCESS_STATE AccessState, OUT POBP_LOOKUP_CONTEXT LookupContext, OUT PVOID *FoundObject)
Definition: obname.c:446
#define HandleToLong(h)
Definition: basetsd.h:80
#define PAGED_CODE()
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68