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 /* GLOBALS *****************************************************************/
47 PHANDLE_TABLE ObpKernelHandleTable
= NULL
;
49 /* FUNCTIONS ***************************************************************/
52 ObpDecrementHandleCount(PVOID ObjectBody
)
54 POBJECT_HEADER ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
55 LONG NewHandleCount
= InterlockedDecrement(&ObjectHeader
->HandleCount
);
57 if ((ObjectHeader
->ObjectType
!= NULL
) &&
58 (ObjectHeader
->ObjectType
->Close
!= NULL
))
60 /* the handle count should be decremented but we pass the previous value
62 ObjectHeader
->ObjectType
->Close(ObjectBody
, NewHandleCount
+ 1);
65 if(NewHandleCount
== 0)
67 if(ObjectHeader
->Parent
!= NULL
&& !ObjectHeader
->Permanent
)
69 /* delete the object from the namespace when the last handle got closed.
70 Only do this if it's actually been inserted into the namespace and
71 if it's not a permanent object. */
72 ObpRemoveEntryDirectory(ObjectHeader
);
75 /* remove the keep-alive reference */
76 ObDereferenceObject(ObjectBody
);
82 ObpQueryHandleAttributes(HANDLE Handle
,
83 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
85 PHANDLE_TABLE HandleTable
;
86 PHANDLE_TABLE_ENTRY HandleTableEntry
;
91 DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle
);
93 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
95 HandleTable
= ObpKernelHandleTable
;
96 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
100 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
101 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
104 KeEnterCriticalRegion();
106 HandleTableEntry
= ExMapHandleToPointer(HandleTable
,
108 if (HandleTableEntry
== NULL
)
110 KeLeaveCriticalRegion();
111 return STATUS_INVALID_HANDLE
;
114 HandleInfo
->Inherit
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
115 HandleInfo
->ProtectFromClose
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
) != 0;
117 ExUnlockHandleTableEntry(HandleTable
,
120 KeLeaveCriticalRegion();
122 return STATUS_SUCCESS
;
127 ObpSetHandleAttributes(HANDLE Handle
,
128 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
130 PHANDLE_TABLE HandleTable
;
131 PHANDLE_TABLE_ENTRY HandleTableEntry
;
136 DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle
);
138 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
140 HandleTable
= ObpKernelHandleTable
;
141 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
145 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
146 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
149 KeEnterCriticalRegion();
151 HandleTableEntry
= ExMapHandleToPointer(HandleTable
,
153 if (HandleTableEntry
== NULL
)
155 KeLeaveCriticalRegion();
156 return STATUS_INVALID_HANDLE
;
159 if (HandleInfo
->Inherit
)
160 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
162 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
164 if (HandleInfo
->ProtectFromClose
)
165 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
167 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
169 /* FIXME: Do we need to set anything in the object header??? */
171 ExUnlockHandleTableEntry(HandleTable
,
174 KeLeaveCriticalRegion();
176 return STATUS_SUCCESS
;
181 ObpDeleteHandle(PHANDLE_TABLE HandleTable
,
184 PHANDLE_TABLE_ENTRY HandleEntry
;
186 POBJECT_HEADER ObjectHeader
;
187 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
191 DPRINT("ObpDeleteHandle(Handle %x)\n",Handle
);
193 KeEnterCriticalRegion();
195 HandleEntry
= ExMapHandleToPointer(HandleTable
,
197 if(HandleEntry
!= NULL
)
199 if(HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
)
201 ExUnlockHandleTableEntry(HandleTable
,
204 KeLeaveCriticalRegion();
206 return STATUS_HANDLE_NOT_CLOSABLE
;
209 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
210 Body
= HEADER_TO_BODY(ObjectHeader
);
212 ObpDecrementHandleCount(Body
);
214 /* destroy and unlock the handle entry */
215 ExDestroyHandleByEntry(HandleTable
,
219 KeLeaveCriticalRegion();
221 return STATUS_SUCCESS
;
223 KeLeaveCriticalRegion();
224 return STATUS_INVALID_HANDLE
;
229 ObDuplicateObject(PEPROCESS SourceProcess
,
230 PEPROCESS TargetProcess
,
232 PHANDLE TargetHandle
,
233 ACCESS_MASK DesiredAccess
,
234 BOOLEAN InheritHandle
,
237 PHANDLE_TABLE SourceHandleTable
;
238 PHANDLE_TABLE_ENTRY SourceHandleEntry
;
239 HANDLE_TABLE_ENTRY NewHandleEntry
;
241 POBJECT_HEADER ObjectHeader
;
244 ULONG NewHandleCount
;
248 if(ObIsKernelHandle(SourceHandle
, ExGetPreviousMode()))
250 SourceHandleTable
= ObpKernelHandleTable
;
251 SourceHandle
= ObKernelHandleToHandle(SourceHandle
);
255 SourceHandleTable
= SourceProcess
->ObjectTable
;
258 ExSourceHandle
= HANDLE_TO_EX_HANDLE(SourceHandle
);
260 KeEnterCriticalRegion();
262 SourceHandleEntry
= ExMapHandleToPointer(SourceHandleTable
,
264 if (SourceHandleEntry
== NULL
)
266 KeLeaveCriticalRegion();
267 return STATUS_INVALID_HANDLE
;
270 ObjectHeader
= EX_HTE_TO_HDR(SourceHandleEntry
);
271 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
273 NewHandleEntry
.u1
.Object
= SourceHandleEntry
->u1
.Object
;
275 NewHandleEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
277 NewHandleEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
278 NewHandleEntry
.u2
.GrantedAccess
= ((Options
& DUPLICATE_SAME_ACCESS
) ?
279 SourceHandleEntry
->u2
.GrantedAccess
:
281 if (Options
& DUPLICATE_SAME_ACCESS
)
283 NewHandleEntry
.u2
.GrantedAccess
= SourceHandleEntry
->u2
.GrantedAccess
;
287 if (DesiredAccess
& GENERIC_ANY
)
289 RtlMapGenericMask(&DesiredAccess
,
290 ObjectHeader
->ObjectType
->Mapping
);
292 NewHandleEntry
.u2
.GrantedAccess
= DesiredAccess
;
295 /* reference the object so it doesn't get deleted after releasing the lock
296 and before creating a new handle for it */
297 ObReferenceObject(ObjectBody
);
299 /* increment the handle count of the object, it should always be >= 2 because
300 we're holding a handle lock to this object! if the new handle count was
301 1 here, we're in big trouble... it would've been safe to increment and
302 check the handle count without using interlocked functions because the
303 entry is locked, which means the handle count can't change. */
304 NewHandleCount
= InterlockedIncrement(&ObjectHeader
->HandleCount
);
305 ASSERT(NewHandleCount
>= 2);
307 ExUnlockHandleTableEntry(SourceHandleTable
,
310 KeLeaveCriticalRegion();
312 /* attempt to create the new handle */
313 ExTargetHandle
= ExCreateHandle(TargetProcess
->ObjectTable
,
315 if (ExTargetHandle
!= EX_INVALID_HANDLE
)
317 if (Options
& DUPLICATE_CLOSE_SOURCE
)
319 ObpDeleteHandle(SourceHandleTable
,
323 ObDereferenceObject(ObjectBody
);
325 *TargetHandle
= EX_HANDLE_TO_HANDLE(ExTargetHandle
);
327 return STATUS_SUCCESS
;
331 /* decrement the handle count we previously incremented, but don't call the
332 closing procedure because we're not closing a handle! */
333 if(InterlockedDecrement(&ObjectHeader
->HandleCount
) == 0)
335 ObDereferenceObject(ObjectBody
);
338 ObDereferenceObject(ObjectBody
);
339 return STATUS_UNSUCCESSFUL
;
347 NtDuplicateObject (IN HANDLE SourceProcessHandle
,
348 IN HANDLE SourceHandle
,
349 IN HANDLE TargetProcessHandle
,
350 OUT PHANDLE TargetHandle
,
351 IN ACCESS_MASK DesiredAccess
,
352 IN BOOLEAN InheritHandle
,
355 * FUNCTION: Copies a handle from one process space to another
357 * SourceProcessHandle = The source process owning the handle. The
358 * source process should have opened
359 * the SourceHandle with PROCESS_DUP_HANDLE
361 * SourceHandle = The handle to the object.
362 * TargetProcessHandle = The destination process owning the handle
363 * TargetHandle (OUT) = Caller should supply storage for the
365 * DesiredAccess = The desired access to the handle.
366 * InheritHandle = Indicates wheter the new handle will be inheritable
368 * Options = Specifies special actions upon duplicating the handle.
369 * Can be one of the values DUPLICATE_CLOSE_SOURCE |
370 * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
371 * that the source handle should be closed after duplicating.
372 * DUPLICATE_SAME_ACCESS specifies to ignore the
373 * DesiredAccess paramter and just grant the same access to
376 * REMARKS: This function maps to the win32 DuplicateHandle.
379 PEPROCESS SourceProcess
;
380 PEPROCESS TargetProcess
;
382 KPROCESSOR_MODE PreviousMode
;
383 NTSTATUS Status
= STATUS_SUCCESS
;
387 PreviousMode
= ExGetPreviousMode();
389 if(PreviousMode
!= KernelMode
)
393 ProbeForWrite(TargetHandle
,
399 Status
= _SEH_GetExceptionCode();
403 if(!NT_SUCCESS(Status
))
409 Status
= ObReferenceObjectByHandle(SourceProcessHandle
,
413 (PVOID
*)&SourceProcess
,
415 if (!NT_SUCCESS(Status
))
420 Status
= ObReferenceObjectByHandle(TargetProcessHandle
,
424 (PVOID
*)&TargetProcess
,
426 if (!NT_SUCCESS(Status
))
428 ObDereferenceObject(SourceProcess
);
432 /* Check for magic handle first */
433 if (SourceHandle
== NtCurrentThread() ||
434 SourceHandle
== NtCurrentProcess())
437 POBJECT_TYPE ObjectType
;
439 ObjectType
= (SourceHandle
== NtCurrentThread()) ? PsThreadType
: PsProcessType
;
441 Status
= ObReferenceObjectByHandle(SourceHandle
,
447 if(NT_SUCCESS(Status
))
449 if (Options
& DUPLICATE_SAME_ACCESS
)
451 /* grant all access rights */
452 DesiredAccess
= ((ObjectType
== PsThreadType
) ? THREAD_ALL_ACCESS
: PROCESS_ALL_ACCESS
);
456 if (DesiredAccess
& GENERIC_ANY
)
458 RtlMapGenericMask(&DesiredAccess
,
459 ObjectType
->Mapping
);
462 Status
= ObCreateHandle(TargetProcess
,
468 ObDereferenceObject(ObjectBody
);
470 if (Options
& DUPLICATE_CLOSE_SOURCE
)
472 ObpDeleteHandle(SourceProcess
->ObjectTable
,
479 Status
= ObDuplicateObject(SourceProcess
,
488 ObDereferenceObject(TargetProcess
);
489 ObDereferenceObject(SourceProcess
);
491 if(NT_SUCCESS(Status
))
495 *TargetHandle
= hTarget
;
499 Status
= _SEH_GetExceptionCode();
508 DeleteHandleCallback(PHANDLE_TABLE HandleTable
,
513 POBJECT_HEADER ObjectHeader
;
518 ObjectHeader
= EX_OBJ_TO_HDR(Object
);
519 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
521 ObpDecrementHandleCount(ObjectBody
);
524 static BOOLEAN STDCALL
525 DuplicateHandleCallback(PHANDLE_TABLE HandleTable
,
526 PHANDLE_TABLE_ENTRY HandleTableEntry
,
529 POBJECT_HEADER ObjectHeader
;
534 Ret
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
537 ObjectHeader
= EX_HTE_TO_HDR(HandleTableEntry
);
538 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
540 ObReferenceObject(HEADER_TO_BODY(ObjectHeader
));
547 VOID
ObCreateHandleTable(PEPROCESS Parent
,
551 * FUNCTION: Creates a handle table for a process
553 * Parent = Parent process (or NULL if this is the first process)
554 * Inherit = True if the process should inherit its parent's handles
555 * Process = Process whose handle table is to be created
560 DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
561 Parent
,Inherit
,Process
);
564 Process
->ObjectTable
= ExDupHandleTable(Process
,
565 DuplicateHandleCallback
,
567 Parent
->ObjectTable
);
571 Process
->ObjectTable
= ExCreateHandleTable(Process
);
578 ObKillProcess(PEPROCESS Process
)
582 ExDestroyHandleTable(Process
->ObjectTable
,
583 DeleteHandleCallback
,
589 ObCreateHandle(PEPROCESS Process
,
591 ACCESS_MASK GrantedAccess
,
593 PHANDLE HandleReturn
)
595 * FUNCTION: Add a handle referencing an object
597 * obj = Object body that the handle should refer to
598 * RETURNS: The created handle
599 * NOTE: The handle is valid only in the context of the current process
602 HANDLE_TABLE_ENTRY NewEntry
;
603 POBJECT_HEADER ObjectHeader
;
608 DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process
,ObjectBody
);
613 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
615 ASSERT((ULONG_PTR
)ObjectHeader
& EX_HANDLE_ENTRY_LOCKED
);
617 if (GrantedAccess
& MAXIMUM_ALLOWED
)
619 GrantedAccess
&= ~MAXIMUM_ALLOWED
;
620 GrantedAccess
|= GENERIC_ALL
;
623 if (GrantedAccess
& GENERIC_ANY
)
625 RtlMapGenericMask(&GrantedAccess
,
626 ObjectHeader
->ObjectType
->Mapping
);
629 NewEntry
.u1
.Object
= ObjectHeader
;
631 NewEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
633 NewEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
634 NewEntry
.u2
.GrantedAccess
= GrantedAccess
;
636 ExHandle
= ExCreateHandle(Process
->ObjectTable
,
638 DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader
, *HandleReturn
, Process
->ObjectTable
);
639 if(ExHandle
!= EX_INVALID_HANDLE
)
641 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
643 ObReferenceObjectByPointer(ObjectBody
,
649 *HandleReturn
= EX_HANDLE_TO_HANDLE(ExHandle
);
651 return STATUS_SUCCESS
;
654 return STATUS_UNSUCCESSFUL
;
662 ObQueryObjectAuditingByHandle(IN HANDLE Handle
,
663 OUT PBOOLEAN GenerateOnClose
)
665 PHANDLE_TABLE_ENTRY HandleEntry
;
667 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
671 DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle
);
673 Process
= PsGetCurrentProcess();
675 KeEnterCriticalRegion();
677 HandleEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
679 if(HandleEntry
!= NULL
)
681 *GenerateOnClose
= (HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_AUDITONCLOSE
) != 0;
683 ExUnlockHandleTableEntry(Process
->ObjectTable
,
686 KeLeaveCriticalRegion();
688 return STATUS_SUCCESS
;
691 KeLeaveCriticalRegion();
693 return STATUS_INVALID_HANDLE
;
698 * FUNCTION: Increments the reference count for an object and returns a
699 * pointer to its body
701 * Handle = Handle for the object
702 * DesiredAccess = Desired access to the object
705 * Object (OUT) = Points to the object body on return
706 * HandleInformation (OUT) = Contains information about the handle
713 ObReferenceObjectByHandle(HANDLE Handle
,
714 ACCESS_MASK DesiredAccess
,
715 POBJECT_TYPE ObjectType
,
716 KPROCESSOR_MODE AccessMode
,
718 POBJECT_HANDLE_INFORMATION HandleInformation
)
720 PHANDLE_TABLE_ENTRY HandleEntry
;
721 POBJECT_HEADER ObjectHeader
;
722 PHANDLE_TABLE HandleTable
;
724 ACCESS_MASK GrantedAccess
;
730 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
731 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
732 ObjectType
,AccessMode
,Object
);
735 * Handle special handle names
737 if (Handle
== NtCurrentProcess() &&
738 (ObjectType
== PsProcessType
|| ObjectType
== NULL
))
740 PEPROCESS CurrentProcess
= PsGetCurrentProcess();
742 ObReferenceObject(CurrentProcess
);
744 if (HandleInformation
!= NULL
)
746 HandleInformation
->HandleAttributes
= 0;
747 HandleInformation
->GrantedAccess
= PROCESS_ALL_ACCESS
;
750 *Object
= CurrentProcess
;
751 DPRINT("Referencing current process %x\n", CurrentProcess
);
752 return STATUS_SUCCESS
;
754 else if (Handle
== NtCurrentProcess())
757 return(STATUS_OBJECT_TYPE_MISMATCH
);
760 if (Handle
== NtCurrentThread() &&
761 (ObjectType
== PsThreadType
|| ObjectType
== NULL
))
763 PETHREAD CurrentThread
= PsGetCurrentThread();
765 ObReferenceObject(CurrentThread
);
767 if (HandleInformation
!= NULL
)
769 HandleInformation
->HandleAttributes
= 0;
770 HandleInformation
->GrantedAccess
= THREAD_ALL_ACCESS
;
773 *Object
= CurrentThread
;
775 return STATUS_SUCCESS
;
777 else if (Handle
== NtCurrentThread())
780 return(STATUS_OBJECT_TYPE_MISMATCH
);
783 /* desire as much access rights as possible */
784 if (DesiredAccess
& MAXIMUM_ALLOWED
)
786 DesiredAccess
&= ~MAXIMUM_ALLOWED
;
787 DesiredAccess
|= GENERIC_ALL
;
790 if(ObIsKernelHandle(Handle
, AccessMode
))
792 HandleTable
= ObpKernelHandleTable
;
793 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
797 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
798 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
801 KeEnterCriticalRegion();
803 HandleEntry
= ExMapHandleToPointer(HandleTable
,
805 if (HandleEntry
== NULL
)
807 KeLeaveCriticalRegion();
808 DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle
);
809 return(STATUS_INVALID_HANDLE
);
812 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
813 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
815 DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader
, HandleTable
);
817 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
819 DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType
->TypeName
, ObjectHeader
->ObjectType
? &ObjectHeader
->ObjectType
->TypeName
: NULL
, Handle
);
821 ExUnlockHandleTableEntry(HandleTable
,
824 KeLeaveCriticalRegion();
826 return(STATUS_OBJECT_TYPE_MISMATCH
);
829 /* map the generic access masks if the caller asks for generic access */
830 if (DesiredAccess
& GENERIC_ANY
)
832 RtlMapGenericMask(&DesiredAccess
,
833 BODY_TO_HEADER(ObjectBody
)->ObjectType
->Mapping
);
836 GrantedAccess
= HandleEntry
->u2
.GrantedAccess
;
838 /* Unless running as KernelMode, deny access if caller desires more access
839 rights than the handle can grant */
840 if(AccessMode
!= KernelMode
&& (~GrantedAccess
& DesiredAccess
))
842 ExUnlockHandleTableEntry(HandleTable
,
845 KeLeaveCriticalRegion();
847 DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess
, ~GrantedAccess
, DesiredAccess
, ~GrantedAccess
& DesiredAccess
);
849 return(STATUS_ACCESS_DENIED
);
852 ObReferenceObject(ObjectBody
);
854 Attributes
= HandleEntry
->u1
.ObAttributes
& (EX_HANDLE_ENTRY_PROTECTFROMCLOSE
|
855 EX_HANDLE_ENTRY_INHERITABLE
|
856 EX_HANDLE_ENTRY_AUDITONCLOSE
);
858 ExUnlockHandleTableEntry(HandleTable
,
861 KeLeaveCriticalRegion();
863 if (HandleInformation
!= NULL
)
865 HandleInformation
->HandleAttributes
= Attributes
;
866 HandleInformation
->GrantedAccess
= GrantedAccess
;
869 *Object
= ObjectBody
;
871 return(STATUS_SUCCESS
);
875 /**********************************************************************
880 * Closes a handle reference to an object.
892 NtClose(IN HANDLE Handle
)
894 PHANDLE_TABLE HandleTable
;
899 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
901 HandleTable
= ObpKernelHandleTable
;
902 Handle
= ObKernelHandleToHandle(Handle
);
906 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
909 Status
= ObpDeleteHandle(HandleTable
,
911 if (!NT_SUCCESS(Status
))
913 if((ExGetPreviousMode() != KernelMode
) &&
914 (PsGetCurrentProcess()->ExceptionPort
))
916 KeRaiseUserException(Status
);
921 return(STATUS_SUCCESS
);
929 ObInsertObject(IN PVOID Object
,
930 IN PACCESS_STATE PassedAccessState OPTIONAL
,
931 IN ACCESS_MASK DesiredAccess
,
932 IN ULONG AdditionalReferences
,
933 OUT PVOID
* ReferencedObject OPTIONAL
,
936 POBJECT_HEADER ObjectHeader
;
941 Access
= DesiredAccess
;
942 ObjectHeader
= BODY_TO_HEADER(Object
);
944 return(ObCreateHandle(PsGetCurrentProcess(),
947 ObjectHeader
->Inherit
,
953 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable
)
955 return HandleTable
->HandleCount
;
959 * FUNCTION: Searches the handle table of a specified process whether it contains a
960 * valid handle to the Object we're looking for. If not, it'll create one.
963 * The parameters of this function is basically a mixture of some of the parameters
964 * of ObReferenceObjectByHandle() and ObReferenceObjectByPointer(). A little thinking
965 * about what this function does (by it's name) makes clear what parameters it requires.
966 * For example the AccessMode parameter of ObReferenceObjectByHandle/Pointer() is not
967 * required at all as it only has influence on the object security. This function doesn't
968 * want to get access to an object, it just looks for a valid handle and if it can't find
969 * one, it'll just create one. It wouldn't make sense to check for security again as the
970 * caller already has a pointer to the object.
972 * A test on an XP machine shows that this prototype appears to be correct.
975 * Process = This parameter simply describes in which handle table we're looking
976 * for a handle to the object.
977 * Object = The object pointer that we're looking for
978 * ObjectType = Just a sanity check as ObReferenceObjectByHandle() and
979 * ObReferenceObjectByPointer() provides.
980 * HandleInformation = This one has to be the opposite meaning of the usage in
981 * ObReferenceObjectByHandle(). If we actually found a valid
982 * handle in the table, we need to check against the information
983 * provided so we make sure this handle has all access rights
984 * (and attributes?!) we need. If they don't match, we can't
985 * use this handle and keep looking because the caller is likely
986 * to depend on these access rights.
987 * HandleReturn = The last parameter is the same as in ObCreateHandle(). If we could
988 * find a suitable handle in the handle table, return this handle, if
989 * not, we'll just create one using ObCreateHandle() with all access
990 * rights the caller needs.
997 ObFindHandleForObject(IN PEPROCESS Process
,
999 IN POBJECT_TYPE ObjectType
,
1000 IN POBJECT_HANDLE_INFORMATION HandleInformation
,
1001 OUT PHANDLE HandleReturn
)
1004 return STATUS_UNSUCCESSFUL
;
1008 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi
,
1015 // pshi->HandleValue;
1018 This will never work with ROS! M$, I guess uses 0 -> 65535.
1019 Ros uses 0 -> 4294967295!
1022 P
= (ULONG
) Process
->UniqueProcessId
;
1023 pshi
->UniqueProcessId
= (USHORT
) P
;
1025 // KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
1027 // pshi->GrantedAccess;
1029 // pshi->ObjectTypeIndex;
1030 // pshi->HandleAttributes;
1032 // KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );