2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ob/object.c
5 * PURPOSE: Implements generic object managment functions
6 * PROGRAMMER: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
19 #include <internal/debug.h>
21 /* FUNCTIONS ************************************************************/
23 VOID
ObInitializeObject(POBJECT_HEADER ObjectHeader
,
25 ACCESS_MASK DesiredAccess
,
27 POBJECT_ATTRIBUTES ObjectAttributes
)
29 ObjectHeader
->HandleCount
= 1;
30 ObjectHeader
->RefCount
= 1;
31 ObjectHeader
->ObjectType
= Type
;
32 ObjectHeader
->Permanent
= FALSE
;
33 RtlInitUnicodeString(&(ObjectHeader
->Name
),NULL
);
36 *Handle
= ObInsertHandle(KeGetCurrentProcess(),
37 HEADER_TO_BODY(ObjectHeader
),
43 NTSTATUS
ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes
,
44 PVOID
* ReturnedObject
,
49 POBJECT_HEADER CurrentHeader
;
54 DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
55 "RemainingPath %x)\n",ObjectAttributes
,ReturnedObject
,RemainingPath
);
56 DPRINT("ObjectAttributes->ObjectName->Buffer %x\n",
57 ObjectAttributes
->ObjectName
->Buffer
);
59 if (ObjectAttributes
->RootDirectory
== NULL
)
61 ObReferenceObjectByPointer(NameSpaceRoot
,
65 CurrentObject
= NameSpaceRoot
;
69 Status
= ObReferenceObjectByHandle(ObjectAttributes
->RootDirectory
,
75 if (!NT_SUCCESS(Status
))
81 Path
= ObjectAttributes
->ObjectName
->Buffer
;
85 *ReturnedObject
= CurrentObject
;
86 return(STATUS_SUCCESS
);
91 return(STATUS_UNSUCCESSFUL
);
98 DPRINT("current %w\n",current
);
99 CurrentHeader
= BODY_TO_HEADER(CurrentObject
);
100 if (CurrentHeader
->ObjectType
->Parse
== NULL
)
104 NextObject
= CurrentHeader
->ObjectType
->Parse(CurrentObject
,
106 if (NextObject
== NULL
)
110 ObDereferenceObject(CurrentObject
);
111 CurrentObject
= NextObject
;
114 *RemainingPath
= current
;
115 *ReturnedObject
= CurrentObject
;
117 return(STATUS_SUCCESS
);
120 PVOID
ObCreateObject(PHANDLE Handle
,
121 ACCESS_MASK DesiredAccess
,
122 POBJECT_ATTRIBUTES ObjectAttributes
,
126 PWSTR RemainingPath
= NULL
;
127 POBJECT_HEADER Header
;
130 DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
131 if (ObjectAttributes
!= NULL
&&
132 ObjectAttributes
->ObjectName
!= NULL
)
134 DPRINT("ObjectAttributes->ObjectName->Buffer %w\n",
135 ObjectAttributes
->ObjectName
->Buffer
);
138 if (ObjectAttributes
!= NULL
&&
139 ObjectAttributes
->ObjectName
!= NULL
)
141 ObFindObject(ObjectAttributes
,
146 Header
= (POBJECT_HEADER
)ExAllocatePool(NonPagedPool
,
147 OBJECT_ALLOC_SIZE(Type
));
148 ObInitializeObject(Header
,
153 if (Header
->ObjectType
!= NULL
&&
154 Header
->ObjectType
->Create
!= NULL
)
156 Status
= Header
->ObjectType
->Create(HEADER_TO_BODY(Header
),
160 if (!NT_SUCCESS(Status
))
165 return(HEADER_TO_BODY(Header
));
168 NTSTATUS
ObReferenceObjectByPointer(PVOID ObjectBody
,
169 ACCESS_MASK DesiredAccess
,
170 POBJECT_TYPE ObjectType
,
171 KPROCESSOR_MODE AccessMode
)
173 * FUNCTION: Increments the pointer reference count for a given object
175 * ObjectBody = Object's body
176 * DesiredAccess = Desired access to the object
177 * ObjectType = Points to the object type structure
178 * AccessMode = Type of access check to perform
182 POBJECT_HEADER ObjectHeader
;
184 DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n",
185 ObjectBody
,ObjectType
);
187 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
189 if (ObjectType
!= NULL
&& ObjectHeader
->ObjectType
!= ObjectType
)
191 DPRINT("Failed (type was %x %w)\n",ObjectHeader
->ObjectType
,
192 ObjectHeader
->ObjectType
->TypeName
.Buffer
);
193 return(STATUS_UNSUCCESSFUL
);
196 ObjectHeader
->RefCount
++;
197 return(STATUS_SUCCESS
);
200 NTSTATUS
ObPerformRetentionChecks(POBJECT_HEADER Header
)
202 DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
203 Header
,Header
->RefCount
,Header
->HandleCount
);
205 if (Header
->RefCount
< 0 || Header
->HandleCount
< 0)
210 if (Header
->RefCount
== 0 && Header
->HandleCount
== 0 &&
213 if (Header
->ObjectType
!= NULL
&&
214 Header
->ObjectType
->Delete
!= NULL
)
216 Header
->ObjectType
->Delete(HEADER_TO_BODY(Header
));
218 if (Header
->Name
.Buffer
!= NULL
)
220 ObRemoveEntry(Header
);
222 DPRINT("ObPerformRetentionChecks() = Freeing object\n");
225 return(STATUS_SUCCESS
);
228 VOID
ObDereferenceObject(PVOID ObjectBody
)
230 * FUNCTION: Decrements a given object's reference count and performs
233 * ObjectBody = Body of the object
236 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
238 DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody
,
242 ObPerformRetentionChecks(Header
);
245 NTSTATUS
ObReferenceObjectByHandle(HANDLE Handle
,
246 ACCESS_MASK DesiredAccess
,
247 POBJECT_TYPE ObjectType
,
248 KPROCESSOR_MODE AccessMode
,
250 POBJECT_HANDLE_INFORMATION
251 HandleInformationPtr
)
253 * FUNCTION: Increments the reference count for an object and returns a
254 * pointer to its body
256 * Handle = Handle for the object
257 * DesiredAccess = Desired access to the object
260 * Object (OUT) = Points to the object body on return
261 * HandleInformation (OUT) = Contains information about the handle
266 PHANDLE_REP HandleRep
;
267 POBJECT_HEADER ObjectHeader
;
269 ASSERT_IRQL(PASSIVE_LEVEL
);
271 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
272 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
273 ObjectType
,AccessMode
,Object
);
275 if (Handle
== NtCurrentProcess())
277 *Object
= PsGetCurrentProcess();
278 return(STATUS_SUCCESS
);
280 if (Handle
== NtCurrentThread())
282 *Object
= PsGetCurrentThread();
283 return(STATUS_SUCCESS
);
286 HandleRep
= ObTranslateHandle(KeGetCurrentProcess(),Handle
);
287 if (HandleRep
== NULL
|| HandleRep
->ObjectBody
== NULL
)
289 return(STATUS_INVALID_HANDLE
);
292 ObjectHeader
= BODY_TO_HEADER(HandleRep
->ObjectBody
);
294 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
296 return(STATUS_UNSUCCESSFUL
);
299 if (!(HandleRep
->GrantedAccess
& DesiredAccess
))
301 return(STATUS_ACCESS_DENIED
);
304 ObjectHeader
->RefCount
++;
306 *Object
= HandleRep
->ObjectBody
;
308 return(STATUS_SUCCESS
);