3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: ntoskrnl/ob/handle.c
24 * PURPOSE: Managing handles
25 * PROGRAMMER: David Welch (welch@cwcom.net)
30 /* INCLUDES ****************************************************************/
34 #include <internal/debug.h>
36 #define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \
37 ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
38 EX_HANDLE_ENTRY_AUDITONCLOSE)))
39 #define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->u1.Object) & \
40 ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
41 EX_HANDLE_ENTRY_AUDITONCLOSE)))
43 #define GENERIC_ANY (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
45 /* FUNCTIONS ***************************************************************/
49 ObKillProcess(PEPROCESS Process
)
51 ObDeleteHandleTable(Process
);
55 ObpDecrementHandleCount(PVOID ObjectBody
)
57 POBJECT_HEADER ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
58 LONG NewHandleCount
= InterlockedDecrement(&ObjectHeader
->HandleCount
);
60 if ((ObjectHeader
->ObjectType
!= NULL
) &&
61 (ObjectHeader
->ObjectType
->Close
!= NULL
))
63 /* the handle count should be decremented but we pass the previous value
65 ObjectHeader
->ObjectType
->Close(ObjectBody
, NewHandleCount
+ 1);
68 if(NewHandleCount
== 0)
70 ObDereferenceObject(ObjectBody
);
76 ObpQueryHandleAttributes(HANDLE Handle
,
77 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
80 PHANDLE_TABLE_ENTRY HandleTableEntry
;
81 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
85 DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle
);
87 KeEnterCriticalRegion();
89 Process
= PsGetCurrentProcess();
91 HandleTableEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
93 if (HandleTableEntry
== NULL
)
95 KeLeaveCriticalRegion();
96 return STATUS_INVALID_HANDLE
;
99 HandleInfo
->Inherit
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
100 HandleInfo
->ProtectFromClose
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
) != 0;
102 ExUnlockHandleTableEntry(Process
->ObjectTable
,
105 KeLeaveCriticalRegion();
107 return STATUS_SUCCESS
;
112 ObpSetHandleAttributes(HANDLE Handle
,
113 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
116 PHANDLE_TABLE_ENTRY HandleTableEntry
;
117 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
121 DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle
);
123 Process
= PsGetCurrentProcess();
125 KeEnterCriticalRegion();
127 HandleTableEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
129 if (HandleTableEntry
== NULL
)
131 KeLeaveCriticalRegion();
132 return STATUS_INVALID_HANDLE
;
135 if (HandleInfo
->Inherit
)
136 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
138 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
140 if (HandleInfo
->ProtectFromClose
)
141 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
143 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
145 /* FIXME: Do we need to set anything in the object header??? */
147 ExUnlockHandleTableEntry(Process
->ObjectTable
,
150 KeLeaveCriticalRegion();
152 return STATUS_SUCCESS
;
157 ObDuplicateObject(PEPROCESS SourceProcess
,
158 PEPROCESS TargetProcess
,
160 PHANDLE TargetHandle
,
161 ACCESS_MASK DesiredAccess
,
162 BOOLEAN InheritHandle
,
165 PHANDLE_TABLE_ENTRY SourceHandleEntry
;
166 HANDLE_TABLE_ENTRY NewHandleEntry
;
168 POBJECT_HEADER ObjectHeader
;
170 LONG ExSourceHandle
= HANDLE_TO_EX_HANDLE(SourceHandle
);
171 ULONG NewHandleCount
;
175 KeEnterCriticalRegion();
177 SourceHandleEntry
= ExMapHandleToPointer(SourceProcess
->ObjectTable
,
179 if (SourceHandleEntry
== NULL
)
181 KeLeaveCriticalRegion();
182 return STATUS_INVALID_HANDLE
;
185 ObjectHeader
= EX_HTE_TO_HDR(SourceHandleEntry
);
186 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
188 NewHandleEntry
.u1
.Object
= SourceHandleEntry
->u1
.Object
;
190 NewHandleEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
192 NewHandleEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
193 NewHandleEntry
.u2
.GrantedAccess
= ((Options
& DUPLICATE_SAME_ACCESS
) ?
194 SourceHandleEntry
->u2
.GrantedAccess
:
196 if (Options
& DUPLICATE_SAME_ACCESS
)
198 NewHandleEntry
.u2
.GrantedAccess
= SourceHandleEntry
->u2
.GrantedAccess
;
202 if (DesiredAccess
& GENERIC_ANY
)
204 RtlMapGenericMask(&DesiredAccess
,
205 ObjectHeader
->ObjectType
->Mapping
);
207 NewHandleEntry
.u2
.GrantedAccess
= DesiredAccess
;
210 /* reference the object so it doesn't get deleted after releasing the lock
211 and before creating a new handle for it */
212 ObReferenceObject(ObjectBody
);
214 /* increment the handle count of the object, it should always be >= 2 because
215 we're holding a handle lock to this object! if the new handle count was
216 1 here, we're in big trouble... it would've been safe to increment and
217 check the handle count without using interlocked functions because the
218 entry is locked, which means the handle count can't change. */
219 NewHandleCount
= InterlockedIncrement(&ObjectHeader
->HandleCount
);
220 ASSERT(NewHandleCount
>= 2);
222 ExUnlockHandleTableEntry(SourceProcess
->ObjectTable
,
225 KeLeaveCriticalRegion();
227 /* attempt to create the new handle */
228 ExTargetHandle
= ExCreateHandle(TargetProcess
->ObjectTable
,
230 if (ExTargetHandle
!= EX_INVALID_HANDLE
)
232 if (Options
& DUPLICATE_CLOSE_SOURCE
)
234 ObDeleteHandle(SourceProcess
,
238 ObDereferenceObject(ObjectBody
);
240 *TargetHandle
= EX_HANDLE_TO_HANDLE(ExTargetHandle
);
242 return STATUS_SUCCESS
;
246 /* decrement the handle count we previously incremented, but don't call the
247 closing procedure because we're not closing a handle! */
248 if(InterlockedDecrement(&ObjectHeader
->HandleCount
) == 0)
250 ObDereferenceObject(ObjectBody
);
253 ObDereferenceObject(ObjectBody
);
254 return STATUS_UNSUCCESSFUL
;
262 NtDuplicateObject (IN HANDLE SourceProcessHandle
,
263 IN HANDLE SourceHandle
,
264 IN HANDLE TargetProcessHandle
,
265 OUT PHANDLE TargetHandle
,
266 IN ACCESS_MASK DesiredAccess
,
267 IN BOOLEAN InheritHandle
,
270 * FUNCTION: Copies a handle from one process space to another
272 * SourceProcessHandle = The source process owning the handle. The
273 * source process should have opened
274 * the SourceHandle with PROCESS_DUP_HANDLE
276 * SourceHandle = The handle to the object.
277 * TargetProcessHandle = The destination process owning the handle
278 * TargetHandle (OUT) = Caller should supply storage for the
280 * DesiredAccess = The desired access to the handle.
281 * InheritHandle = Indicates wheter the new handle will be inheritable
283 * Options = Specifies special actions upon duplicating the handle.
284 * Can be one of the values DUPLICATE_CLOSE_SOURCE |
285 * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
286 * that the source handle should be closed after duplicating.
287 * DUPLICATE_SAME_ACCESS specifies to ignore the
288 * DesiredAccess paramter and just grant the same access to
291 * REMARKS: This function maps to the win32 DuplicateHandle.
294 PEPROCESS SourceProcess
;
295 PEPROCESS TargetProcess
;
297 KPROCESSOR_MODE PreviousMode
;
298 NTSTATUS Status
= STATUS_SUCCESS
;
302 PreviousMode
= ExGetPreviousMode();
304 if(PreviousMode
!= KernelMode
)
308 ProbeForWrite(TargetHandle
,
314 Status
= _SEH_GetExceptionCode();
318 if(!NT_SUCCESS(Status
))
324 Status
= ObReferenceObjectByHandle(SourceProcessHandle
,
328 (PVOID
*)&SourceProcess
,
330 if (!NT_SUCCESS(Status
))
335 Status
= ObReferenceObjectByHandle(TargetProcessHandle
,
339 (PVOID
*)&TargetProcess
,
341 if (!NT_SUCCESS(Status
))
343 ObDereferenceObject(SourceProcess
);
347 /* Check for magic handle first */
348 if (SourceHandle
== NtCurrentThread() ||
349 SourceHandle
== NtCurrentProcess())
352 POBJECT_TYPE ObjectType
;
354 ObjectType
= (SourceHandle
== NtCurrentThread()) ? PsThreadType
: PsProcessType
;
356 Status
= ObReferenceObjectByHandle(SourceHandle
,
362 if(NT_SUCCESS(Status
))
364 if (Options
& DUPLICATE_SAME_ACCESS
)
366 /* grant all access rights */
367 DesiredAccess
= ((ObjectType
== PsThreadType
) ? THREAD_ALL_ACCESS
: PROCESS_ALL_ACCESS
);
371 if (DesiredAccess
& GENERIC_ANY
)
373 RtlMapGenericMask(&DesiredAccess
,
374 ObjectType
->Mapping
);
377 Status
= ObCreateHandle(TargetProcess
,
383 ObDereferenceObject(ObjectBody
);
385 if (Options
& DUPLICATE_CLOSE_SOURCE
)
387 ObDeleteHandle(SourceProcess
,
394 Status
= ObDuplicateObject(SourceProcess
,
403 ObDereferenceObject(TargetProcess
);
404 ObDereferenceObject(SourceProcess
);
406 if(NT_SUCCESS(Status
))
410 *TargetHandle
= hTarget
;
414 Status
= _SEH_GetExceptionCode();
423 DeleteHandleCallback(PHANDLE_TABLE HandleTable
,
428 POBJECT_HEADER ObjectHeader
;
433 ObjectHeader
= EX_OBJ_TO_HDR(Object
);
434 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
436 ObpDecrementHandleCount(ObjectBody
);
439 VOID
ObDeleteHandleTable(PEPROCESS Process
)
441 * FUNCTION: Deletes the handle table associated with a process
446 ExDestroyHandleTable(Process
->ObjectTable
,
447 DeleteHandleCallback
,
451 static BOOLEAN STDCALL
452 DuplicateHandleCallback(PHANDLE_TABLE HandleTable
,
453 PHANDLE_TABLE_ENTRY HandleTableEntry
,
456 POBJECT_HEADER ObjectHeader
;
461 Ret
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
464 ObjectHeader
= EX_HTE_TO_HDR(HandleTableEntry
);
465 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
467 ObReferenceObjectByPointer(HEADER_TO_BODY(ObjectHeader
),
477 VOID
ObCreateHandleTable(PEPROCESS Parent
,
481 * FUNCTION: Creates a handle table for a process
483 * Parent = Parent process (or NULL if this is the first process)
484 * Inherit = True if the process should inherit its parent's handles
485 * Process = Process whose handle table is to be created
490 DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
491 Parent
,Inherit
,Process
);
494 Process
->ObjectTable
= ExDupHandleTable(Process
,
495 DuplicateHandleCallback
,
497 Parent
->ObjectTable
);
501 Process
->ObjectTable
= ExCreateHandleTable(Process
);
507 ObDeleteHandle(PEPROCESS Process
,
510 PHANDLE_TABLE_ENTRY HandleEntry
;
512 POBJECT_HEADER ObjectHeader
;
513 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
517 DPRINT("ObDeleteHandle(Handle %x)\n",Handle
);
519 KeEnterCriticalRegion();
521 HandleEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
523 if(HandleEntry
!= NULL
)
525 if(HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
)
527 ExUnlockHandleTableEntry(Process
->ObjectTable
,
530 KeLeaveCriticalRegion();
532 return STATUS_HANDLE_NOT_CLOSABLE
;
535 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
536 Body
= HEADER_TO_BODY(ObjectHeader
);
538 ObpDecrementHandleCount(Body
);
540 /* destroy and unlock the handle entry */
541 ExDestroyHandleByEntry(Process
->ObjectTable
,
545 KeLeaveCriticalRegion();
547 return STATUS_SUCCESS
;
549 KeLeaveCriticalRegion();
550 return STATUS_INVALID_HANDLE
;
555 ObCreateHandle(PEPROCESS Process
,
557 ACCESS_MASK GrantedAccess
,
559 PHANDLE HandleReturn
)
561 * FUNCTION: Add a handle referencing an object
563 * obj = Object body that the handle should refer to
564 * RETURNS: The created handle
565 * NOTE: The handle is valid only in the context of the current process
568 HANDLE_TABLE_ENTRY NewEntry
;
569 POBJECT_HEADER ObjectHeader
;
574 DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process
,ObjectBody
);
579 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
581 ASSERT((ULONG_PTR
)ObjectHeader
& EX_HANDLE_ENTRY_LOCKED
);
583 if (GrantedAccess
& MAXIMUM_ALLOWED
)
585 GrantedAccess
&= ~MAXIMUM_ALLOWED
;
586 GrantedAccess
|= GENERIC_ALL
;
589 if (GrantedAccess
& GENERIC_ANY
)
591 RtlMapGenericMask(&GrantedAccess
,
592 ObjectHeader
->ObjectType
->Mapping
);
595 NewEntry
.u1
.Object
= ObjectHeader
;
597 NewEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
599 NewEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
600 NewEntry
.u2
.GrantedAccess
= GrantedAccess
;
602 ExHandle
= ExCreateHandle(Process
->ObjectTable
,
604 DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader
, *HandleReturn
, Process
->ObjectTable
);
605 if(ExHandle
!= EX_INVALID_HANDLE
)
607 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
609 ObReferenceObjectByPointer(ObjectBody
,
615 *HandleReturn
= EX_HANDLE_TO_HANDLE(ExHandle
);
617 return STATUS_SUCCESS
;
620 return STATUS_UNSUCCESSFUL
;
628 ObQueryObjectAuditingByHandle(IN HANDLE Handle
,
629 OUT PBOOLEAN GenerateOnClose
)
631 PHANDLE_TABLE_ENTRY HandleEntry
;
633 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
637 DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle
);
639 Process
= PsGetCurrentProcess();
641 KeEnterCriticalRegion();
643 HandleEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
645 if(HandleEntry
!= NULL
)
647 *GenerateOnClose
= (HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_AUDITONCLOSE
) != 0;
649 ExUnlockHandleTableEntry(Process
->ObjectTable
,
652 KeLeaveCriticalRegion();
654 return STATUS_SUCCESS
;
657 KeLeaveCriticalRegion();
659 return STATUS_INVALID_HANDLE
;
664 * FUNCTION: Increments the reference count for an object and returns a
665 * pointer to its body
667 * Handle = Handle for the object
668 * DesiredAccess = Desired access to the object
671 * Object (OUT) = Points to the object body on return
672 * HandleInformation (OUT) = Contains information about the handle
679 ObReferenceObjectByHandle(HANDLE Handle
,
680 ACCESS_MASK DesiredAccess
,
681 POBJECT_TYPE ObjectType
,
682 KPROCESSOR_MODE AccessMode
,
684 POBJECT_HANDLE_INFORMATION HandleInformation
)
686 PHANDLE_TABLE_ENTRY HandleEntry
;
687 POBJECT_HEADER ObjectHeader
;
689 ACCESS_MASK GrantedAccess
;
692 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
696 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
697 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
698 ObjectType
,AccessMode
,Object
);
701 * Handle special handle names
703 if (Handle
== NtCurrentProcess() &&
704 (ObjectType
== PsProcessType
|| ObjectType
== NULL
))
706 Status
= ObReferenceObjectByPointer(PsGetCurrentProcess(),
710 if (! NT_SUCCESS(Status
))
715 if (HandleInformation
!= NULL
)
717 HandleInformation
->HandleAttributes
= 0;
718 HandleInformation
->GrantedAccess
= PROCESS_ALL_ACCESS
;
721 *Object
= PsGetCurrentProcess();
722 DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
723 return STATUS_SUCCESS
;
725 else if (Handle
== NtCurrentProcess())
728 return(STATUS_OBJECT_TYPE_MISMATCH
);
731 if (Handle
== NtCurrentThread() &&
732 (ObjectType
== PsThreadType
|| ObjectType
== NULL
))
734 Status
= ObReferenceObjectByPointer(PsGetCurrentThread(),
738 if (! NT_SUCCESS(Status
))
743 if (HandleInformation
!= NULL
)
745 HandleInformation
->HandleAttributes
= 0;
746 HandleInformation
->GrantedAccess
= THREAD_ALL_ACCESS
;
749 *Object
= PsGetCurrentThread();
751 return STATUS_SUCCESS
;
753 else if (Handle
== NtCurrentThread())
756 return(STATUS_OBJECT_TYPE_MISMATCH
);
759 /* desire as much access rights as possible */
760 if (DesiredAccess
& MAXIMUM_ALLOWED
)
762 DesiredAccess
&= ~MAXIMUM_ALLOWED
;
763 DesiredAccess
|= GENERIC_ALL
;
766 KeEnterCriticalRegion();
768 HandleEntry
= ExMapHandleToPointer(PsGetCurrentProcess()->ObjectTable
,
770 if (HandleEntry
== NULL
)
772 KeLeaveCriticalRegion();
773 DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle
);
774 return(STATUS_INVALID_HANDLE
);
777 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
778 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
780 DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader
, PsGetCurrentProcess()->ObjectTable
);
782 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
784 DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType
->TypeName
, ObjectHeader
->ObjectType
? &ObjectHeader
->ObjectType
->TypeName
: NULL
, Handle
);
786 ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable
,
789 KeLeaveCriticalRegion();
791 return(STATUS_OBJECT_TYPE_MISMATCH
);
794 /* map the generic access masks if the caller asks for generic access */
795 if (DesiredAccess
& GENERIC_ANY
)
797 RtlMapGenericMask(&DesiredAccess
,
798 BODY_TO_HEADER(ObjectBody
)->ObjectType
->Mapping
);
801 GrantedAccess
= HandleEntry
->u2
.GrantedAccess
;
803 /* Unless running as KernelMode, deny access if caller desires more access
804 rights than the handle can grant */
805 if(AccessMode
!= KernelMode
&& (~GrantedAccess
& DesiredAccess
))
807 ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable
,
810 KeLeaveCriticalRegion();
812 DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess
, ~GrantedAccess
, DesiredAccess
, ~GrantedAccess
& DesiredAccess
);
814 return(STATUS_ACCESS_DENIED
);
817 ObReferenceObjectByPointer(ObjectBody
,
821 Attributes
= HandleEntry
->u1
.ObAttributes
& (EX_HANDLE_ENTRY_PROTECTFROMCLOSE
|
822 EX_HANDLE_ENTRY_INHERITABLE
|
823 EX_HANDLE_ENTRY_AUDITONCLOSE
);
825 ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable
,
828 KeLeaveCriticalRegion();
830 if (HandleInformation
!= NULL
)
832 HandleInformation
->HandleAttributes
= Attributes
;
833 HandleInformation
->GrantedAccess
= GrantedAccess
;
836 *Object
= ObjectBody
;
838 return(STATUS_SUCCESS
);
842 /**********************************************************************
847 * Closes a handle reference to an object.
859 NtClose(IN HANDLE Handle
)
865 Status
= ObDeleteHandle(PsGetCurrentProcess(),
867 if (!NT_SUCCESS(Status
))
869 if(((PEPROCESS
)(KeGetCurrentThread()->ApcState
.Process
))->ExceptionPort
)
870 KeRaiseUserException(Status
);
874 return(STATUS_SUCCESS
);
882 ObInsertObject(IN PVOID Object
,
883 IN PACCESS_STATE PassedAccessState OPTIONAL
,
884 IN ACCESS_MASK DesiredAccess
,
885 IN ULONG AdditionalReferences
,
886 OUT PVOID
* ReferencedObject OPTIONAL
,
889 POBJECT_HEADER ObjectHeader
;
894 Access
= DesiredAccess
;
895 ObjectHeader
= BODY_TO_HEADER(Object
);
897 return(ObCreateHandle(PsGetCurrentProcess(),
900 ObjectHeader
->Inherit
,
906 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable
)
908 return HandleTable
->HandleCount
;
912 * FUNCTION: Searches the handle table of a specified process whether it contains a
913 * valid handle to the Object we're looking for. If not, it'll create one.
916 * The parameters of this function is basically a mixture of some of the parameters
917 * of ObReferenceObjectByHandle() and ObReferenceObjectByPointer(). A little thinking
918 * about what this function does (by it's name) makes clear what parameters it requires.
919 * For example the AccessMode parameter of ObReferenceObjectByHandle/Pointer() is not
920 * required at all as it only has influence on the object security. This function doesn't
921 * want to get access to an object, it just looks for a valid handle and if it can't find
922 * one, it'll just create one. It wouldn't make sense to check for security again as the
923 * caller already has a pointer to the object.
925 * A test on an XP machine shows that this prototype appears to be correct.
928 * Process = This parameter simply describes in which handle table we're looking
929 * for a handle to the object.
930 * Object = The object pointer that we're looking for
931 * ObjectType = Just a sanity check as ObReferenceObjectByHandle() and
932 * ObReferenceObjectByPointer() provides.
933 * HandleInformation = This one has to be the opposite meaning of the usage in
934 * ObReferenceObjectByHandle(). If we actually found a valid
935 * handle in the table, we need to check against the information
936 * provided so we make sure this handle has all access rights
937 * (and attributes?!) we need. If they don't match, we can't
938 * use this handle and keep looking because the caller is likely
939 * to depend on these access rights.
940 * HandleReturn = The last parameter is the same as in ObCreateHandle(). If we could
941 * find a suitable handle in the handle table, return this handle, if
942 * not, we'll just create one using ObCreateHandle() with all access
943 * rights the caller needs.
950 ObFindHandleForObject(IN PEPROCESS Process
,
952 IN POBJECT_TYPE ObjectType
,
953 IN POBJECT_HANDLE_INFORMATION HandleInformation
,
954 OUT PHANDLE HandleReturn
)
957 return STATUS_UNSUCCESSFUL
;
961 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi
,
968 // pshi->HandleValue;
971 This will never work with ROS! M$, I guess uses 0 -> 65535.
972 Ros uses 0 -> 4294967295!
975 P
= (ULONG
) Process
->UniqueProcessId
;
976 pshi
->UniqueProcessId
= (USHORT
) P
;
978 // KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
980 // pshi->GrantedAccess;
982 // pshi->ObjectTypeIndex;
983 // pshi->HandleAttributes;
985 // KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );