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