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