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 ***************************************************************/
53 ObKillProcess(PEPROCESS Process
)
55 ObDeleteHandleTable(Process
);
59 ObpDecrementHandleCount(PVOID ObjectBody
)
61 POBJECT_HEADER ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
62 LONG NewHandleCount
= InterlockedDecrement(&ObjectHeader
->HandleCount
);
64 if ((ObjectHeader
->ObjectType
!= NULL
) &&
65 (ObjectHeader
->ObjectType
->Close
!= NULL
))
67 /* the handle count should be decremented but we pass the previous value
69 ObjectHeader
->ObjectType
->Close(ObjectBody
, NewHandleCount
+ 1);
72 if(NewHandleCount
== 0)
74 ObDereferenceObject(ObjectBody
);
80 ObpQueryHandleAttributes(HANDLE Handle
,
81 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
83 PHANDLE_TABLE HandleTable
;
84 PHANDLE_TABLE_ENTRY HandleTableEntry
;
89 DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle
);
91 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
93 HandleTable
= ObpKernelHandleTable
;
94 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
98 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
99 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
102 KeEnterCriticalRegion();
104 HandleTableEntry
= ExMapHandleToPointer(HandleTable
,
106 if (HandleTableEntry
== NULL
)
108 KeLeaveCriticalRegion();
109 return STATUS_INVALID_HANDLE
;
112 HandleInfo
->Inherit
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
113 HandleInfo
->ProtectFromClose
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
) != 0;
115 ExUnlockHandleTableEntry(HandleTable
,
118 KeLeaveCriticalRegion();
120 return STATUS_SUCCESS
;
125 ObpSetHandleAttributes(HANDLE Handle
,
126 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
128 PHANDLE_TABLE HandleTable
;
129 PHANDLE_TABLE_ENTRY HandleTableEntry
;
134 DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle
);
136 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
138 HandleTable
= ObpKernelHandleTable
;
139 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
143 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
144 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
147 KeEnterCriticalRegion();
149 HandleTableEntry
= ExMapHandleToPointer(HandleTable
,
151 if (HandleTableEntry
== NULL
)
153 KeLeaveCriticalRegion();
154 return STATUS_INVALID_HANDLE
;
157 if (HandleInfo
->Inherit
)
158 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
160 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
162 if (HandleInfo
->ProtectFromClose
)
163 HandleTableEntry
->u1
.ObAttributes
|= EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
165 HandleTableEntry
->u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE
;
167 /* FIXME: Do we need to set anything in the object header??? */
169 ExUnlockHandleTableEntry(HandleTable
,
172 KeLeaveCriticalRegion();
174 return STATUS_SUCCESS
;
179 ObpDeleteHandle(PHANDLE_TABLE HandleTable
,
182 PHANDLE_TABLE_ENTRY HandleEntry
;
184 POBJECT_HEADER ObjectHeader
;
185 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
189 DPRINT("ObpDeleteHandle(Handle %x)\n",Handle
);
191 KeEnterCriticalRegion();
193 HandleEntry
= ExMapHandleToPointer(HandleTable
,
195 if(HandleEntry
!= NULL
)
197 if(HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_PROTECTFROMCLOSE
)
199 ExUnlockHandleTableEntry(HandleTable
,
202 KeLeaveCriticalRegion();
204 return STATUS_HANDLE_NOT_CLOSABLE
;
207 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
208 Body
= HEADER_TO_BODY(ObjectHeader
);
210 ObpDecrementHandleCount(Body
);
212 /* destroy and unlock the handle entry */
213 ExDestroyHandleByEntry(HandleTable
,
217 KeLeaveCriticalRegion();
219 return STATUS_SUCCESS
;
221 KeLeaveCriticalRegion();
222 return STATUS_INVALID_HANDLE
;
227 ObDuplicateObject(PEPROCESS SourceProcess
,
228 PEPROCESS TargetProcess
,
230 PHANDLE TargetHandle
,
231 ACCESS_MASK DesiredAccess
,
232 BOOLEAN InheritHandle
,
235 PHANDLE_TABLE SourceHandleTable
;
236 PHANDLE_TABLE_ENTRY SourceHandleEntry
;
237 HANDLE_TABLE_ENTRY NewHandleEntry
;
239 POBJECT_HEADER ObjectHeader
;
242 ULONG NewHandleCount
;
246 if(ObIsKernelHandle(SourceHandle
, ExGetPreviousMode()))
248 SourceHandleTable
= ObpKernelHandleTable
;
249 SourceHandle
= ObKernelHandleToHandle(SourceHandle
);
253 SourceHandleTable
= SourceProcess
->ObjectTable
;
256 ExSourceHandle
= HANDLE_TO_EX_HANDLE(SourceHandle
);
258 KeEnterCriticalRegion();
260 SourceHandleEntry
= ExMapHandleToPointer(SourceHandleTable
,
262 if (SourceHandleEntry
== NULL
)
264 KeLeaveCriticalRegion();
265 return STATUS_INVALID_HANDLE
;
268 ObjectHeader
= EX_HTE_TO_HDR(SourceHandleEntry
);
269 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
271 NewHandleEntry
.u1
.Object
= SourceHandleEntry
->u1
.Object
;
273 NewHandleEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
275 NewHandleEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
276 NewHandleEntry
.u2
.GrantedAccess
= ((Options
& DUPLICATE_SAME_ACCESS
) ?
277 SourceHandleEntry
->u2
.GrantedAccess
:
279 if (Options
& DUPLICATE_SAME_ACCESS
)
281 NewHandleEntry
.u2
.GrantedAccess
= SourceHandleEntry
->u2
.GrantedAccess
;
285 if (DesiredAccess
& GENERIC_ANY
)
287 RtlMapGenericMask(&DesiredAccess
,
288 ObjectHeader
->ObjectType
->Mapping
);
290 NewHandleEntry
.u2
.GrantedAccess
= DesiredAccess
;
293 /* reference the object so it doesn't get deleted after releasing the lock
294 and before creating a new handle for it */
295 ObReferenceObject(ObjectBody
);
297 /* increment the handle count of the object, it should always be >= 2 because
298 we're holding a handle lock to this object! if the new handle count was
299 1 here, we're in big trouble... it would've been safe to increment and
300 check the handle count without using interlocked functions because the
301 entry is locked, which means the handle count can't change. */
302 NewHandleCount
= InterlockedIncrement(&ObjectHeader
->HandleCount
);
303 ASSERT(NewHandleCount
>= 2);
305 ExUnlockHandleTableEntry(SourceHandleTable
,
308 KeLeaveCriticalRegion();
310 /* attempt to create the new handle */
311 ExTargetHandle
= ExCreateHandle(TargetProcess
->ObjectTable
,
313 if (ExTargetHandle
!= EX_INVALID_HANDLE
)
315 if (Options
& DUPLICATE_CLOSE_SOURCE
)
317 ObpDeleteHandle(SourceHandleTable
,
321 ObDereferenceObject(ObjectBody
);
323 *TargetHandle
= EX_HANDLE_TO_HANDLE(ExTargetHandle
);
325 return STATUS_SUCCESS
;
329 /* decrement the handle count we previously incremented, but don't call the
330 closing procedure because we're not closing a handle! */
331 if(InterlockedDecrement(&ObjectHeader
->HandleCount
) == 0)
333 ObDereferenceObject(ObjectBody
);
336 ObDereferenceObject(ObjectBody
);
337 return STATUS_UNSUCCESSFUL
;
345 NtDuplicateObject (IN HANDLE SourceProcessHandle
,
346 IN HANDLE SourceHandle
,
347 IN HANDLE TargetProcessHandle
,
348 OUT PHANDLE TargetHandle
,
349 IN ACCESS_MASK DesiredAccess
,
350 IN BOOLEAN InheritHandle
,
353 * FUNCTION: Copies a handle from one process space to another
355 * SourceProcessHandle = The source process owning the handle. The
356 * source process should have opened
357 * the SourceHandle with PROCESS_DUP_HANDLE
359 * SourceHandle = The handle to the object.
360 * TargetProcessHandle = The destination process owning the handle
361 * TargetHandle (OUT) = Caller should supply storage for the
363 * DesiredAccess = The desired access to the handle.
364 * InheritHandle = Indicates wheter the new handle will be inheritable
366 * Options = Specifies special actions upon duplicating the handle.
367 * Can be one of the values DUPLICATE_CLOSE_SOURCE |
368 * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
369 * that the source handle should be closed after duplicating.
370 * DUPLICATE_SAME_ACCESS specifies to ignore the
371 * DesiredAccess paramter and just grant the same access to
374 * REMARKS: This function maps to the win32 DuplicateHandle.
377 PEPROCESS SourceProcess
;
378 PEPROCESS TargetProcess
;
380 KPROCESSOR_MODE PreviousMode
;
381 NTSTATUS Status
= STATUS_SUCCESS
;
385 PreviousMode
= ExGetPreviousMode();
387 if(PreviousMode
!= KernelMode
)
391 ProbeForWrite(TargetHandle
,
397 Status
= _SEH_GetExceptionCode();
401 if(!NT_SUCCESS(Status
))
407 Status
= ObReferenceObjectByHandle(SourceProcessHandle
,
411 (PVOID
*)&SourceProcess
,
413 if (!NT_SUCCESS(Status
))
418 Status
= ObReferenceObjectByHandle(TargetProcessHandle
,
422 (PVOID
*)&TargetProcess
,
424 if (!NT_SUCCESS(Status
))
426 ObDereferenceObject(SourceProcess
);
430 /* Check for magic handle first */
431 if (SourceHandle
== NtCurrentThread() ||
432 SourceHandle
== NtCurrentProcess())
435 POBJECT_TYPE ObjectType
;
437 ObjectType
= (SourceHandle
== NtCurrentThread()) ? PsThreadType
: PsProcessType
;
439 Status
= ObReferenceObjectByHandle(SourceHandle
,
445 if(NT_SUCCESS(Status
))
447 if (Options
& DUPLICATE_SAME_ACCESS
)
449 /* grant all access rights */
450 DesiredAccess
= ((ObjectType
== PsThreadType
) ? THREAD_ALL_ACCESS
: PROCESS_ALL_ACCESS
);
454 if (DesiredAccess
& GENERIC_ANY
)
456 RtlMapGenericMask(&DesiredAccess
,
457 ObjectType
->Mapping
);
460 Status
= ObCreateHandle(TargetProcess
,
466 ObDereferenceObject(ObjectBody
);
468 if (Options
& DUPLICATE_CLOSE_SOURCE
)
470 ObpDeleteHandle(SourceProcess
->ObjectTable
,
477 Status
= ObDuplicateObject(SourceProcess
,
486 ObDereferenceObject(TargetProcess
);
487 ObDereferenceObject(SourceProcess
);
489 if(NT_SUCCESS(Status
))
493 *TargetHandle
= hTarget
;
497 Status
= _SEH_GetExceptionCode();
506 DeleteHandleCallback(PHANDLE_TABLE HandleTable
,
511 POBJECT_HEADER ObjectHeader
;
516 ObjectHeader
= EX_OBJ_TO_HDR(Object
);
517 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
519 ObpDecrementHandleCount(ObjectBody
);
522 VOID
ObDeleteHandleTable(PEPROCESS Process
)
524 * FUNCTION: Deletes the handle table associated with a process
529 ExDestroyHandleTable(Process
->ObjectTable
,
530 DeleteHandleCallback
,
534 static BOOLEAN STDCALL
535 DuplicateHandleCallback(PHANDLE_TABLE HandleTable
,
536 PHANDLE_TABLE_ENTRY HandleTableEntry
,
539 POBJECT_HEADER ObjectHeader
;
544 Ret
= (HandleTableEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_INHERITABLE
) != 0;
547 ObjectHeader
= EX_HTE_TO_HDR(HandleTableEntry
);
548 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
550 ObReferenceObject(HEADER_TO_BODY(ObjectHeader
));
557 VOID
ObCreateHandleTable(PEPROCESS Parent
,
561 * FUNCTION: Creates a handle table for a process
563 * Parent = Parent process (or NULL if this is the first process)
564 * Inherit = True if the process should inherit its parent's handles
565 * Process = Process whose handle table is to be created
570 DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
571 Parent
,Inherit
,Process
);
574 Process
->ObjectTable
= ExDupHandleTable(Process
,
575 DuplicateHandleCallback
,
577 Parent
->ObjectTable
);
581 Process
->ObjectTable
= ExCreateHandleTable(Process
);
587 ObCreateHandle(PEPROCESS Process
,
589 ACCESS_MASK GrantedAccess
,
591 PHANDLE HandleReturn
)
593 * FUNCTION: Add a handle referencing an object
595 * obj = Object body that the handle should refer to
596 * RETURNS: The created handle
597 * NOTE: The handle is valid only in the context of the current process
600 HANDLE_TABLE_ENTRY NewEntry
;
601 POBJECT_HEADER ObjectHeader
;
606 DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process
,ObjectBody
);
611 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
613 ASSERT((ULONG_PTR
)ObjectHeader
& EX_HANDLE_ENTRY_LOCKED
);
615 if (GrantedAccess
& MAXIMUM_ALLOWED
)
617 GrantedAccess
&= ~MAXIMUM_ALLOWED
;
618 GrantedAccess
|= GENERIC_ALL
;
621 if (GrantedAccess
& GENERIC_ANY
)
623 RtlMapGenericMask(&GrantedAccess
,
624 ObjectHeader
->ObjectType
->Mapping
);
627 NewEntry
.u1
.Object
= ObjectHeader
;
629 NewEntry
.u1
.ObAttributes
|= EX_HANDLE_ENTRY_INHERITABLE
;
631 NewEntry
.u1
.ObAttributes
&= ~EX_HANDLE_ENTRY_INHERITABLE
;
632 NewEntry
.u2
.GrantedAccess
= GrantedAccess
;
634 ExHandle
= ExCreateHandle(Process
->ObjectTable
,
636 DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader
, *HandleReturn
, Process
->ObjectTable
);
637 if(ExHandle
!= EX_INVALID_HANDLE
)
639 if(InterlockedIncrement(&ObjectHeader
->HandleCount
) == 1)
641 ObReferenceObjectByPointer(ObjectBody
,
647 *HandleReturn
= EX_HANDLE_TO_HANDLE(ExHandle
);
649 return STATUS_SUCCESS
;
652 return STATUS_UNSUCCESSFUL
;
660 ObQueryObjectAuditingByHandle(IN HANDLE Handle
,
661 OUT PBOOLEAN GenerateOnClose
)
663 PHANDLE_TABLE_ENTRY HandleEntry
;
665 LONG ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
669 DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle
);
671 Process
= PsGetCurrentProcess();
673 KeEnterCriticalRegion();
675 HandleEntry
= ExMapHandleToPointer(Process
->ObjectTable
,
677 if(HandleEntry
!= NULL
)
679 *GenerateOnClose
= (HandleEntry
->u1
.ObAttributes
& EX_HANDLE_ENTRY_AUDITONCLOSE
) != 0;
681 ExUnlockHandleTableEntry(Process
->ObjectTable
,
684 KeLeaveCriticalRegion();
686 return STATUS_SUCCESS
;
689 KeLeaveCriticalRegion();
691 return STATUS_INVALID_HANDLE
;
696 * FUNCTION: Increments the reference count for an object and returns a
697 * pointer to its body
699 * Handle = Handle for the object
700 * DesiredAccess = Desired access to the object
703 * Object (OUT) = Points to the object body on return
704 * HandleInformation (OUT) = Contains information about the handle
711 ObReferenceObjectByHandle(HANDLE Handle
,
712 ACCESS_MASK DesiredAccess
,
713 POBJECT_TYPE ObjectType
,
714 KPROCESSOR_MODE AccessMode
,
716 POBJECT_HANDLE_INFORMATION HandleInformation
)
718 PHANDLE_TABLE_ENTRY HandleEntry
;
719 POBJECT_HEADER ObjectHeader
;
720 PHANDLE_TABLE HandleTable
;
722 ACCESS_MASK GrantedAccess
;
728 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
729 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
730 ObjectType
,AccessMode
,Object
);
733 * Handle special handle names
735 if (Handle
== NtCurrentProcess() &&
736 (ObjectType
== PsProcessType
|| ObjectType
== NULL
))
738 PEPROCESS CurrentProcess
= PsGetCurrentProcess();
740 ObReferenceObject(CurrentProcess
);
742 if (HandleInformation
!= NULL
)
744 HandleInformation
->HandleAttributes
= 0;
745 HandleInformation
->GrantedAccess
= PROCESS_ALL_ACCESS
;
748 *Object
= CurrentProcess
;
749 DPRINT("Referencing current process %x\n", CurrentProcess
);
750 return STATUS_SUCCESS
;
752 else if (Handle
== NtCurrentProcess())
755 return(STATUS_OBJECT_TYPE_MISMATCH
);
758 if (Handle
== NtCurrentThread() &&
759 (ObjectType
== PsThreadType
|| ObjectType
== NULL
))
761 PETHREAD CurrentThread
= PsGetCurrentThread();
763 ObReferenceObject(CurrentThread
);
765 if (HandleInformation
!= NULL
)
767 HandleInformation
->HandleAttributes
= 0;
768 HandleInformation
->GrantedAccess
= THREAD_ALL_ACCESS
;
771 *Object
= CurrentThread
;
773 return STATUS_SUCCESS
;
775 else if (Handle
== NtCurrentThread())
778 return(STATUS_OBJECT_TYPE_MISMATCH
);
781 /* desire as much access rights as possible */
782 if (DesiredAccess
& MAXIMUM_ALLOWED
)
784 DesiredAccess
&= ~MAXIMUM_ALLOWED
;
785 DesiredAccess
|= GENERIC_ALL
;
788 if(ObIsKernelHandle(Handle
, AccessMode
))
790 HandleTable
= ObpKernelHandleTable
;
791 ExHandle
= HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle
));
795 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
796 ExHandle
= HANDLE_TO_EX_HANDLE(Handle
);
799 KeEnterCriticalRegion();
801 HandleEntry
= ExMapHandleToPointer(HandleTable
,
803 if (HandleEntry
== NULL
)
805 KeLeaveCriticalRegion();
806 DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle
);
807 return(STATUS_INVALID_HANDLE
);
810 ObjectHeader
= EX_HTE_TO_HDR(HandleEntry
);
811 ObjectBody
= HEADER_TO_BODY(ObjectHeader
);
813 DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader
, HandleTable
);
815 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
817 DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType
->TypeName
, ObjectHeader
->ObjectType
? &ObjectHeader
->ObjectType
->TypeName
: NULL
, Handle
);
819 ExUnlockHandleTableEntry(HandleTable
,
822 KeLeaveCriticalRegion();
824 return(STATUS_OBJECT_TYPE_MISMATCH
);
827 /* map the generic access masks if the caller asks for generic access */
828 if (DesiredAccess
& GENERIC_ANY
)
830 RtlMapGenericMask(&DesiredAccess
,
831 BODY_TO_HEADER(ObjectBody
)->ObjectType
->Mapping
);
834 GrantedAccess
= HandleEntry
->u2
.GrantedAccess
;
836 /* Unless running as KernelMode, deny access if caller desires more access
837 rights than the handle can grant */
838 if(AccessMode
!= KernelMode
&& (~GrantedAccess
& DesiredAccess
))
840 ExUnlockHandleTableEntry(HandleTable
,
843 KeLeaveCriticalRegion();
845 DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess
, ~GrantedAccess
, DesiredAccess
, ~GrantedAccess
& DesiredAccess
);
847 return(STATUS_ACCESS_DENIED
);
850 ObReferenceObject(ObjectBody
);
852 Attributes
= HandleEntry
->u1
.ObAttributes
& (EX_HANDLE_ENTRY_PROTECTFROMCLOSE
|
853 EX_HANDLE_ENTRY_INHERITABLE
|
854 EX_HANDLE_ENTRY_AUDITONCLOSE
);
856 ExUnlockHandleTableEntry(HandleTable
,
859 KeLeaveCriticalRegion();
861 if (HandleInformation
!= NULL
)
863 HandleInformation
->HandleAttributes
= Attributes
;
864 HandleInformation
->GrantedAccess
= GrantedAccess
;
867 *Object
= ObjectBody
;
869 return(STATUS_SUCCESS
);
873 /**********************************************************************
878 * Closes a handle reference to an object.
890 NtClose(IN HANDLE Handle
)
892 PHANDLE_TABLE HandleTable
;
897 if(ObIsKernelHandle(Handle
, ExGetPreviousMode()))
899 HandleTable
= ObpKernelHandleTable
;
900 Handle
= ObKernelHandleToHandle(Handle
);
904 HandleTable
= PsGetCurrentProcess()->ObjectTable
;
907 Status
= ObpDeleteHandle(HandleTable
,
909 if (!NT_SUCCESS(Status
))
911 if((ExGetPreviousMode() != KernelMode
) &&
912 (PsGetCurrentProcess()->ExceptionPort
))
914 KeRaiseUserException(Status
);
919 return(STATUS_SUCCESS
);
927 ObInsertObject(IN PVOID Object
,
928 IN PACCESS_STATE PassedAccessState OPTIONAL
,
929 IN ACCESS_MASK DesiredAccess
,
930 IN ULONG AdditionalReferences
,
931 OUT PVOID
* ReferencedObject OPTIONAL
,
934 POBJECT_HEADER ObjectHeader
;
939 Access
= DesiredAccess
;
940 ObjectHeader
= BODY_TO_HEADER(Object
);
942 return(ObCreateHandle(PsGetCurrentProcess(),
945 ObjectHeader
->Inherit
,
951 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable
)
953 return HandleTable
->HandleCount
;
957 * FUNCTION: Searches the handle table of a specified process whether it contains a
958 * valid handle to the Object we're looking for. If not, it'll create one.
961 * The parameters of this function is basically a mixture of some of the parameters
962 * of ObReferenceObjectByHandle() and ObReferenceObjectByPointer(). A little thinking
963 * about what this function does (by it's name) makes clear what parameters it requires.
964 * For example the AccessMode parameter of ObReferenceObjectByHandle/Pointer() is not
965 * required at all as it only has influence on the object security. This function doesn't
966 * want to get access to an object, it just looks for a valid handle and if it can't find
967 * one, it'll just create one. It wouldn't make sense to check for security again as the
968 * caller already has a pointer to the object.
970 * A test on an XP machine shows that this prototype appears to be correct.
973 * Process = This parameter simply describes in which handle table we're looking
974 * for a handle to the object.
975 * Object = The object pointer that we're looking for
976 * ObjectType = Just a sanity check as ObReferenceObjectByHandle() and
977 * ObReferenceObjectByPointer() provides.
978 * HandleInformation = This one has to be the opposite meaning of the usage in
979 * ObReferenceObjectByHandle(). If we actually found a valid
980 * handle in the table, we need to check against the information
981 * provided so we make sure this handle has all access rights
982 * (and attributes?!) we need. If they don't match, we can't
983 * use this handle and keep looking because the caller is likely
984 * to depend on these access rights.
985 * HandleReturn = The last parameter is the same as in ObCreateHandle(). If we could
986 * find a suitable handle in the handle table, return this handle, if
987 * not, we'll just create one using ObCreateHandle() with all access
988 * rights the caller needs.
995 ObFindHandleForObject(IN PEPROCESS Process
,
997 IN POBJECT_TYPE ObjectType
,
998 IN POBJECT_HANDLE_INFORMATION HandleInformation
,
999 OUT PHANDLE HandleReturn
)
1002 return STATUS_UNSUCCESSFUL
;
1006 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi
,
1013 // pshi->HandleValue;
1016 This will never work with ROS! M$, I guess uses 0 -> 65535.
1017 Ros uses 0 -> 4294967295!
1020 P
= (ULONG
) Process
->UniqueProcessId
;
1021 pshi
->UniqueProcessId
= (USHORT
) P
;
1023 // KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
1025 // pshi->GrantedAccess;
1027 // pshi->ObjectTypeIndex;
1028 // pshi->HandleAttributes;
1030 // KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );