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.
19 /* $Id: handle.c,v 1.54 2003/10/21 21:46:02 ekohl Exp $
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 ****************************************************************/
32 #define NTOS_MODE_KERNEL
34 #include <internal/ob.h>
35 #include <internal/ps.h>
36 #include <internal/pool.h>
37 #include <internal/safe.h>
40 #include <internal/debug.h>
42 /* TYPES *******************************************************************/
45 * PURPOSE: Defines a handle
50 ACCESS_MASK GrantedAccess
;
51 } HANDLE_REP
, *PHANDLE_REP
;
53 #define HANDLE_BLOCK_ENTRIES ((PAGE_SIZE-sizeof(LIST_ENTRY))/sizeof(HANDLE_REP))
55 #define OB_HANDLE_FLAG_MASK 0x00000007
56 #define OB_HANDLE_FLAG_AUDIT 0x00000004
57 #define OB_HANDLE_FLAG_PROTECT 0x00000002
58 #define OB_HANDLE_FLAG_INHERIT 0x00000001
60 #define OB_POINTER_TO_ENTRY(Pointer) \
61 (PVOID)((ULONG_PTR)(Pointer) & ~OB_HANDLE_FLAG_MASK)
63 #define OB_ENTRY_TO_POINTER(Entry) \
64 (PVOID)((ULONG_PTR)(Entry) & ~OB_HANDLE_FLAG_MASK)
67 * PURPOSE: Defines a page's worth of handles
72 HANDLE_REP handles
[HANDLE_BLOCK_ENTRIES
];
73 } HANDLE_BLOCK
, *PHANDLE_BLOCK
;
76 /* GLOBALS *******************************************************************/
78 #define TAG_HANDLE_TABLE TAG('H', 'T', 'B', 'L')
80 /* FUNCTIONS ***************************************************************/
83 static PHANDLE_REP
ObpGetObjectByHandle(PHANDLE_TABLE HandleTable
, HANDLE h
)
85 * FUNCTION: Get the data structure for a handle
87 * Process = Process to get the handle for
89 * ARGUMENTS: A pointer to the information about the handle on success,
94 unsigned int handle
= (((unsigned int)h
) >> 2) - 1;
95 unsigned int count
=handle
/HANDLE_BLOCK_ENTRIES
;
96 HANDLE_BLOCK
* blk
= NULL
;
99 DPRINT("ObpGetObjectByHandle(HandleTable %x, h %x)\n",HandleTable
,h
);
101 current
= HandleTable
->ListHead
.Flink
;
102 DPRINT("current %x\n",current
);
104 for (i
=0;i
<count
;i
++)
106 current
= current
->Flink
;
107 if (current
== (&(HandleTable
->ListHead
)))
113 blk
= CONTAINING_RECORD(current
,HANDLE_BLOCK
,entry
);
114 DPRINT("object: %p\n",&(blk
->handles
[handle
%HANDLE_BLOCK_ENTRIES
]));
115 return(&(blk
->handles
[handle
%HANDLE_BLOCK_ENTRIES
]));
120 ObpQueryHandleAttributes(HANDLE Handle
,
121 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
125 PHANDLE_REP HandleRep
;
127 DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle
);
129 Process
= PsGetCurrentProcess();
131 KeAcquireSpinLock(&Process
->HandleTable
.ListLock
, &oldIrql
);
132 HandleRep
= ObpGetObjectByHandle(&Process
->HandleTable
,
134 if (HandleRep
== NULL
)
136 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
137 return STATUS_INVALID_HANDLE
;
140 HandleInfo
->Inherit
=
141 ((ULONG_PTR
)HandleRep
->ObjectBody
& OB_HANDLE_FLAG_INHERIT
);
142 HandleInfo
->ProtectFromClose
=
143 ((ULONG_PTR
)HandleRep
->ObjectBody
& OB_HANDLE_FLAG_PROTECT
);
145 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
147 return STATUS_SUCCESS
;
152 ObpSetHandleAttributes(HANDLE Handle
,
153 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
)
157 PHANDLE_REP HandleRep
;
159 DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle
);
161 Process
= PsGetCurrentProcess();
163 KeAcquireSpinLock(&Process
->HandleTable
.ListLock
, &oldIrql
);
164 HandleRep
= ObpGetObjectByHandle(&Process
->HandleTable
,
166 if (HandleRep
== NULL
)
168 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
169 return STATUS_INVALID_HANDLE
;
172 if (HandleInfo
->Inherit
)
173 HandleRep
->ObjectBody
= (PVOID
)((ULONG_PTR
)HandleRep
->ObjectBody
| OB_HANDLE_FLAG_INHERIT
);
175 HandleRep
->ObjectBody
= (PVOID
)((ULONG_PTR
)HandleRep
->ObjectBody
& ~OB_HANDLE_FLAG_INHERIT
);
177 if (HandleInfo
->ProtectFromClose
)
178 HandleRep
->ObjectBody
= (PVOID
)((ULONG_PTR
)HandleRep
->ObjectBody
| OB_HANDLE_FLAG_PROTECT
);
180 HandleRep
->ObjectBody
= (PVOID
)((ULONG_PTR
)HandleRep
->ObjectBody
& ~OB_HANDLE_FLAG_PROTECT
);
182 /* FIXME: Do we need to set anything in the object header??? */
184 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
186 return STATUS_SUCCESS
;
191 ObDuplicateObject(PEPROCESS SourceProcess
,
192 PEPROCESS TargetProcess
,
194 PHANDLE TargetHandle
,
195 ACCESS_MASK DesiredAccess
,
196 BOOLEAN InheritHandle
,
200 PHANDLE_REP SourceHandleRep
;
203 KeAcquireSpinLock(&SourceProcess
->HandleTable
.ListLock
, &oldIrql
);
204 SourceHandleRep
= ObpGetObjectByHandle(&SourceProcess
->HandleTable
,
206 if (SourceHandleRep
== NULL
)
208 KeReleaseSpinLock(&SourceProcess
->HandleTable
.ListLock
, oldIrql
);
209 return(STATUS_INVALID_HANDLE
);
211 ObjectBody
= OB_ENTRY_TO_POINTER(SourceHandleRep
->ObjectBody
);
212 ObReferenceObjectByPointer(ObjectBody
,
217 if (Options
& DUPLICATE_SAME_ACCESS
)
219 DesiredAccess
= SourceHandleRep
->GrantedAccess
;
222 KeReleaseSpinLock(&SourceProcess
->HandleTable
.ListLock
, oldIrql
);
223 ObCreateHandle(TargetProcess
,
229 if (Options
& DUPLICATE_CLOSE_SOURCE
)
231 ZwClose(SourceHandle
);
234 ObDereferenceObject(ObjectBody
);
235 return(STATUS_SUCCESS
);
242 NtDuplicateObject (IN HANDLE SourceProcessHandle
,
243 IN HANDLE SourceHandle
,
244 IN HANDLE TargetProcessHandle
,
245 OUT PHANDLE UnsafeTargetHandle
,
246 IN ACCESS_MASK DesiredAccess
,
247 IN BOOLEAN InheritHandle
,
250 * FUNCTION: Copies a handle from one process space to another
252 * SourceProcessHandle = The source process owning the handle. The
253 * source process should have opened
254 * the SourceHandle with PROCESS_DUP_HANDLE
256 * SourceHandle = The handle to the object.
257 * TargetProcessHandle = The destination process owning the handle
258 * TargetHandle (OUT) = Caller should supply storage for the
260 * DesiredAccess = The desired access to the handle.
261 * InheritHandle = Indicates wheter the new handle will be inheritable
263 * Options = Specifies special actions upon duplicating the handle.
264 * Can be one of the values DUPLICATE_CLOSE_SOURCE |
265 * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
266 * that the source handle should be closed after duplicating.
267 * DUPLICATE_SAME_ACCESS specifies to ignore the
268 * DesiredAccess paramter and just grant the same access to
271 * REMARKS: This function maps to the win32 DuplicateHandle.
274 PEPROCESS SourceProcess
;
275 PEPROCESS TargetProcess
;
276 PHANDLE_REP SourceHandleRep
;
282 ASSERT_IRQL(PASSIVE_LEVEL
);
284 Status
= ObReferenceObjectByHandle(SourceProcessHandle
,
288 (PVOID
*)&SourceProcess
,
290 if (!NT_SUCCESS(Status
))
294 Status
= ObReferenceObjectByHandle(TargetProcessHandle
,
298 (PVOID
*)&TargetProcess
,
300 if (!NT_SUCCESS(Status
))
302 ObDereferenceObject(SourceProcess
);
306 /* Check for magic handle first */
307 if (SourceHandle
== NtCurrentThread())
309 ObReferenceObjectByHandle(SourceHandle
,
316 ObCreateHandle(TargetProcess
,
324 KeAcquireSpinLock(&SourceProcess
->HandleTable
.ListLock
, &oldIrql
);
325 SourceHandleRep
= ObpGetObjectByHandle(&SourceProcess
->HandleTable
,
327 if (SourceHandleRep
== NULL
)
329 KeReleaseSpinLock(&SourceProcess
->HandleTable
.ListLock
, oldIrql
);
330 ObDereferenceObject(SourceProcess
);
331 ObDereferenceObject(TargetProcess
);
332 return(STATUS_INVALID_HANDLE
);
334 ObjectBody
= OB_ENTRY_TO_POINTER(SourceHandleRep
->ObjectBody
);
335 ObReferenceObjectByPointer(ObjectBody
,
340 if (Options
& DUPLICATE_SAME_ACCESS
)
342 DesiredAccess
= SourceHandleRep
->GrantedAccess
;
345 KeReleaseSpinLock(&SourceProcess
->HandleTable
.ListLock
, oldIrql
);
346 if (!((ULONG_PTR
)SourceHandleRep
->ObjectBody
& OB_HANDLE_FLAG_INHERIT
))
348 ObDereferenceObject(TargetProcess
);
349 ObDereferenceObject(SourceProcess
);
350 ObDereferenceObject(ObjectBody
);
351 return STATUS_INVALID_HANDLE
;
353 ObCreateHandle(TargetProcess
,
360 if (Options
& DUPLICATE_CLOSE_SOURCE
)
362 ZwClose(SourceHandle
);
365 ObDereferenceObject(TargetProcess
);
366 ObDereferenceObject(SourceProcess
);
367 ObDereferenceObject(ObjectBody
);
369 Status
= MmCopyToCaller(UnsafeTargetHandle
, &TargetHandle
, sizeof(HANDLE
));
370 if (!NT_SUCCESS(Status
))
375 return(STATUS_SUCCESS
);
378 VOID
ObCloseAllHandles(PEPROCESS Process
)
381 PHANDLE_TABLE HandleTable
;
382 PLIST_ENTRY current_entry
;
383 PHANDLE_BLOCK current
;
387 DPRINT("ObCloseAllHandles(Process %x)\n", Process
);
389 HandleTable
= &Process
->HandleTable
;
391 KeAcquireSpinLock(&HandleTable
->ListLock
, &oldIrql
);
393 current_entry
= HandleTable
->ListHead
.Flink
;
395 while (current_entry
!= &HandleTable
->ListHead
)
397 current
= CONTAINING_RECORD(current_entry
, HANDLE_BLOCK
, entry
);
399 for (i
= 0; i
< HANDLE_BLOCK_ENTRIES
; i
++)
401 ObjectBody
= OB_ENTRY_TO_POINTER(current
->handles
[i
].ObjectBody
);
403 if (ObjectBody
!= NULL
)
405 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
407 if (Header
->ObjectType
== PsProcessType
||
408 Header
->ObjectType
== PsThreadType
)
410 DPRINT("Deleting handle to %x\n", ObjectBody
);
413 ObReferenceObjectByPointer(ObjectBody
,
417 InterlockedDecrement(&Header
->HandleCount
);
418 current
->handles
[i
].ObjectBody
= NULL
;
420 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
421 if ((Header
->ObjectType
!= NULL
) &&
422 (Header
->ObjectType
->Close
!= NULL
))
424 Header
->ObjectType
->Close(ObjectBody
,
425 Header
->HandleCount
);
428 ObDereferenceObject(ObjectBody
);
429 KeAcquireSpinLock(&HandleTable
->ListLock
, &oldIrql
);
430 current_entry
= &HandleTable
->ListHead
;
435 current_entry
= current_entry
->Flink
;
437 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
438 DPRINT("ObCloseAllHandles() finished\n");
439 DPRINT("Type %x\n", BODY_TO_HEADER(Process
)->ObjectType
);
442 VOID
ObDeleteHandleTable(PEPROCESS Process
)
444 * FUNCTION: Deletes the handle table associated with a process
447 PLIST_ENTRY current
= NULL
;
448 PHANDLE_TABLE HandleTable
= NULL
;
450 ObCloseAllHandles(Process
);
452 HandleTable
= &Process
->HandleTable
;
453 current
= RemoveHeadList(&HandleTable
->ListHead
);
455 while (current
!= &HandleTable
->ListHead
)
457 HANDLE_BLOCK
* HandleBlock
= CONTAINING_RECORD(current
,
460 DPRINT("Freeing %x\n", HandleBlock
);
461 ExFreePool(HandleBlock
);
463 current
= RemoveHeadList(&HandleTable
->ListHead
);
468 VOID
ObCreateHandleTable(PEPROCESS Parent
,
472 * FUNCTION: Creates a handle table for a process
474 * Parent = Parent process (or NULL if this is the first process)
475 * Inherit = True if the process should inherit its parent's handles
476 * Process = Process whose handle table is to be created
479 PHANDLE_TABLE ParentHandleTable
, HandleTable
;
481 PLIST_ENTRY parent_current
;
483 PHANDLE_BLOCK current_block
, new_block
;
485 DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
486 Parent
,Inherit
,Process
);
488 InitializeListHead(&(Process
->HandleTable
.ListHead
));
489 KeInitializeSpinLock(&(Process
->HandleTable
.ListLock
));
493 ParentHandleTable
= &Parent
->HandleTable
;
494 HandleTable
= &Process
->HandleTable
;
496 KeAcquireSpinLock(&Parent
->HandleTable
.ListLock
, &oldIrql
);
497 KeAcquireSpinLockAtDpcLevel(&Process
->HandleTable
.ListLock
);
499 parent_current
= ParentHandleTable
->ListHead
.Flink
;
501 while (parent_current
!= &ParentHandleTable
->ListHead
)
503 current_block
= CONTAINING_RECORD(parent_current
,
506 new_block
= ExAllocatePoolWithTag(NonPagedPool
,
507 sizeof(HANDLE_BLOCK
),
509 if (new_block
== NULL
)
513 RtlZeroMemory(new_block
, sizeof(HANDLE_BLOCK
));
515 for (i
=0; i
<HANDLE_BLOCK_ENTRIES
; i
++)
517 if (current_block
->handles
[i
].ObjectBody
)
519 if ((ULONG_PTR
)current_block
->handles
[i
].ObjectBody
& OB_HANDLE_FLAG_INHERIT
)
521 new_block
->handles
[i
].ObjectBody
=
522 current_block
->handles
[i
].ObjectBody
;
523 new_block
->handles
[i
].GrantedAccess
=
524 current_block
->handles
[i
].GrantedAccess
;
525 InterlockedIncrement(&(BODY_TO_HEADER(OB_ENTRY_TO_POINTER(current_block
->handles
[i
].ObjectBody
))->HandleCount
));
529 InsertTailList(&Process
->HandleTable
.ListHead
, &new_block
->entry
);
530 parent_current
= parent_current
->Flink
;
532 KeReleaseSpinLockFromDpcLevel(&Process
->HandleTable
.ListLock
);
533 KeReleaseSpinLock(&Parent
->HandleTable
.ListLock
, oldIrql
);
539 ObDeleteHandle(PEPROCESS Process
,
546 PHANDLE_TABLE HandleTable
;
547 POBJECT_HEADER Header
;
549 DPRINT("ObDeleteHandle(Handle %x)\n",Handle
);
551 HandleTable
= &Process
->HandleTable
;
553 KeAcquireSpinLock(&HandleTable
->ListLock
, &oldIrql
);
555 Rep
= ObpGetObjectByHandle(HandleTable
, Handle
);
558 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
560 return STATUS_INVALID_HANDLE
;
563 if ((ULONG_PTR
)Rep
->ObjectBody
& OB_HANDLE_FLAG_PROTECT
)
565 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
567 return STATUS_HANDLE_NOT_CLOSABLE
;
570 Body
= OB_ENTRY_TO_POINTER(Rep
->ObjectBody
);
571 DPRINT("ObjectBody %x\n", Body
);
574 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
576 return STATUS_UNSUCCESSFUL
;
579 Header
= BODY_TO_HEADER(Body
);
580 ObReferenceObjectByPointer(Body
,
584 InterlockedDecrement(&Header
->HandleCount
);
585 Rep
->ObjectBody
= NULL
;
587 KeReleaseSpinLock(&HandleTable
->ListLock
, oldIrql
);
589 if ((Header
->ObjectType
!= NULL
) &&
590 (Header
->ObjectType
->Close
!= NULL
))
592 Header
->ObjectType
->Close(Body
, Header
->HandleCount
);
597 DPRINT("Finished ObDeleteHandle()\n");
599 return STATUS_SUCCESS
;
603 NTSTATUS
ObCreateHandle(PEPROCESS Process
,
605 ACCESS_MASK GrantedAccess
,
607 PHANDLE HandleReturn
)
609 * FUNCTION: Add a handle referencing an object
611 * obj = Object body that the handle should refer to
612 * RETURNS: The created handle
613 * NOTE: The handle is valid only in the context of the current process
617 unsigned int handle
=1;
619 HANDLE_BLOCK
* new_blk
= NULL
;
620 PHANDLE_TABLE HandleTable
;
623 DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process
,ObjectBody
);
627 if (ObjectBody
!= NULL
)
629 InterlockedIncrement(&(BODY_TO_HEADER(ObjectBody
)->HandleCount
));
631 HandleTable
= &Process
->HandleTable
;
632 KeAcquireSpinLock(&HandleTable
->ListLock
, &oldlvl
);
633 current
= HandleTable
->ListHead
.Flink
;
635 * Scan through the currently allocated handle blocks looking for a free
638 while (current
!= (&HandleTable
->ListHead
))
640 HANDLE_BLOCK
* blk
= CONTAINING_RECORD(current
,HANDLE_BLOCK
,entry
);
642 DPRINT("Current %x\n",current
);
644 for (i
=0;i
<HANDLE_BLOCK_ENTRIES
;i
++)
646 DPRINT("Considering slot %d containing %x\n",i
,blk
->handles
[i
]);
647 if (blk
->handles
[i
].ObjectBody
== NULL
)
649 blk
->handles
[i
].ObjectBody
= OB_POINTER_TO_ENTRY(ObjectBody
);
651 blk
->handles
[i
].ObjectBody
= (PVOID
)((ULONG_PTR
)blk
->handles
[i
].ObjectBody
| OB_HANDLE_FLAG_INHERIT
);
652 blk
->handles
[i
].GrantedAccess
= GrantedAccess
;
653 KeReleaseSpinLock(&HandleTable
->ListLock
, oldlvl
);
654 *HandleReturn
= (HANDLE
)((handle
+ i
) << 2);
655 return(STATUS_SUCCESS
);
659 handle
= handle
+ HANDLE_BLOCK_ENTRIES
;
660 current
= current
->Flink
;
664 * Add a new handle block to the end of the list
667 (HANDLE_BLOCK
*)ExAllocatePoolWithTag(NonPagedPool
,sizeof(HANDLE_BLOCK
),
671 *HandleReturn
= (PHANDLE
)NULL
;
672 return(STATUS_INSUFFICIENT_RESOURCES
);
674 RtlZeroMemory(new_blk
,sizeof(HANDLE_BLOCK
));
675 InsertTailList(&(Process
->HandleTable
.ListHead
),
677 new_blk
->handles
[0].ObjectBody
= OB_POINTER_TO_ENTRY(ObjectBody
);
679 new_blk
->handles
[0].ObjectBody
= (PVOID
)((ULONG_PTR
)new_blk
->handles
[0].ObjectBody
| OB_HANDLE_FLAG_INHERIT
);
680 new_blk
->handles
[0].GrantedAccess
= GrantedAccess
;
681 KeReleaseSpinLock(&HandleTable
->ListLock
, oldlvl
);
682 *HandleReturn
= (HANDLE
)(handle
<< 2);
683 return(STATUS_SUCCESS
);
691 ObQueryObjectAuditingByHandle(IN HANDLE Handle
,
692 OUT PBOOLEAN GenerateOnClose
)
696 PHANDLE_REP HandleRep
;
698 DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle
);
700 Process
= PsGetCurrentProcess();
702 KeAcquireSpinLock(&Process
->HandleTable
.ListLock
, &oldIrql
);
703 HandleRep
= ObpGetObjectByHandle(&Process
->HandleTable
,
705 if (HandleRep
== NULL
)
707 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
708 return STATUS_INVALID_HANDLE
;
711 *GenerateOnClose
= (BOOLEAN
)((ULONG_PTR
)HandleRep
->ObjectBody
| OB_HANDLE_FLAG_AUDIT
);
713 KeReleaseSpinLock(&Process
->HandleTable
.ListLock
, oldIrql
);
715 return STATUS_SUCCESS
;
723 ObReferenceObjectByHandle(HANDLE Handle
,
724 ACCESS_MASK DesiredAccess
,
725 POBJECT_TYPE ObjectType
,
726 KPROCESSOR_MODE AccessMode
,
728 POBJECT_HANDLE_INFORMATION HandleInformation
)
730 * FUNCTION: Increments the reference count for an object and returns a
731 * pointer to its body
733 * Handle = Handle for the object
734 * DesiredAccess = Desired access to the object
737 * Object (OUT) = Points to the object body on return
738 * HandleInformation (OUT) = Contains information about the handle
743 PHANDLE_REP HandleRep
;
744 POBJECT_HEADER ObjectHeader
;
747 ACCESS_MASK GrantedAccess
;
751 ASSERT_IRQL(PASSIVE_LEVEL
);
753 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
754 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
755 ObjectType
,AccessMode
,Object
);
758 * Handle special handle names
760 if (Handle
== NtCurrentProcess() &&
761 (ObjectType
== PsProcessType
|| ObjectType
== NULL
))
763 DPRINT("Reference from %x\n", ((PULONG
)&Handle
)[-1]);
765 Status
= ObReferenceObjectByPointer(PsGetCurrentProcess(),
769 if (! NT_SUCCESS(Status
))
774 if (HandleInformation
!= NULL
)
776 HandleInformation
->HandleAttributes
= 0; /* FIXME? */
777 HandleInformation
->GrantedAccess
= PROCESS_ALL_ACCESS
;
780 *Object
= PsGetCurrentProcess();
781 DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
782 return STATUS_SUCCESS
;
784 else if (Handle
== NtCurrentProcess())
787 return(STATUS_OBJECT_TYPE_MISMATCH
);
789 if (Handle
== NtCurrentThread() &&
790 (ObjectType
== PsThreadType
|| ObjectType
== NULL
))
792 Status
= ObReferenceObjectByPointer(PsGetCurrentThread(),
796 if (! NT_SUCCESS(Status
))
801 if (HandleInformation
!= NULL
)
803 HandleInformation
->HandleAttributes
= 0; /* FIXME? */
804 HandleInformation
->GrantedAccess
= THREAD_ALL_ACCESS
;
807 *Object
= PsGetCurrentThread();
809 return STATUS_SUCCESS
;
811 else if (Handle
== NtCurrentThread())
814 return(STATUS_OBJECT_TYPE_MISMATCH
);
817 KeAcquireSpinLock(&PsGetCurrentProcess()->HandleTable
.ListLock
,
819 HandleRep
= ObpGetObjectByHandle(&PsGetCurrentProcess()->HandleTable
,
821 if (HandleRep
== NULL
|| HandleRep
->ObjectBody
== 0)
823 KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable
.ListLock
,
825 return(STATUS_INVALID_HANDLE
);
827 ObjectBody
= OB_ENTRY_TO_POINTER(HandleRep
->ObjectBody
);
828 DPRINT("ObjectBody %p\n",ObjectBody
);
829 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
830 DPRINT("ObjectHeader->RefCount %lu\n",ObjectHeader
->RefCount
);
831 ObReferenceObjectByPointer(ObjectBody
,
835 Attributes
= (ULONG_PTR
)HandleRep
->ObjectBody
& OB_HANDLE_FLAG_MASK
;
836 GrantedAccess
= HandleRep
->GrantedAccess
;
837 KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable
.ListLock
,
840 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
841 DPRINT("ObjectHeader->RefCount %lu\n",ObjectHeader
->RefCount
);
843 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
846 return(STATUS_OBJECT_TYPE_MISMATCH
);
849 if (ObjectHeader
->ObjectType
== PsProcessType
)
851 DPRINT("Reference from %x\n", ((PULONG
)&Handle
)[-1]);
854 if (DesiredAccess
&& AccessMode
== UserMode
)
856 RtlMapGenericMask(&DesiredAccess
, ObjectHeader
->ObjectType
->Mapping
);
858 if (!(GrantedAccess
& DesiredAccess
) &&
859 !((~GrantedAccess
) & DesiredAccess
))
862 return(STATUS_ACCESS_DENIED
);
866 if (HandleInformation
!= NULL
)
868 HandleInformation
->HandleAttributes
= Attributes
;
869 HandleInformation
->GrantedAccess
= GrantedAccess
;
872 *Object
= ObjectBody
;
875 return(STATUS_SUCCESS
);
879 /**********************************************************************
884 * Closes a handle reference to an object.
896 NtClose(IN HANDLE Handle
)
899 POBJECT_HEADER Header
;
902 ASSERT_IRQL(PASSIVE_LEVEL
);
904 DPRINT("NtClose(Handle %x)\n",Handle
);
906 Status
= ObDeleteHandle(PsGetCurrentProcess(),
909 if (!NT_SUCCESS(Status
))
911 if(((PEPROCESS
)(KeGetCurrentThread()->ApcState
.Process
))->ExceptionPort
)
912 KeRaiseUserException(Status
);
916 Header
= BODY_TO_HEADER(ObjectBody
);
918 DPRINT("Dereferencing %x\n", ObjectBody
);
919 ObDereferenceObject(ObjectBody
);
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
;
939 Access
= DesiredAccess
;
940 ObjectHeader
= BODY_TO_HEADER(Object
);
942 RtlMapGenericMask(&Access
,
943 ObjectHeader
->ObjectType
->Mapping
);
945 return(ObCreateHandle(PsGetCurrentProcess(),
948 ObjectHeader
->Inherit
,