1 /* $Id: object.c,v 1.23 2000/05/09 21:30:06 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/object.c
6 * PURPOSE: Implements generic object managment functions
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/string.h>
18 #include <internal/ps.h>
19 #include <internal/id.h>
20 #include <internal/ke.h>
23 #include <internal/debug.h>
25 /* FUNCTIONS ************************************************************/
27 /**********************************************************************
37 VOID
ObInitializeObject(POBJECT_HEADER ObjectHeader
,
39 ACCESS_MASK DesiredAccess
,
41 POBJECT_ATTRIBUTES ObjectAttributes
)
43 ObjectHeader
->HandleCount
= 0;
44 ObjectHeader
->RefCount
= 1;
45 ObjectHeader
->ObjectType
= Type
;
46 if (ObjectAttributes
!= NULL
&&
47 ObjectAttributes
->Attributes
& OBJ_PERMANENT
)
49 ObjectHeader
->Permanent
= TRUE
;
53 ObjectHeader
->Permanent
= FALSE
;
55 RtlInitUnicodeString(&(ObjectHeader
->Name
),NULL
);
58 ObCreateHandle(PsGetCurrentProcess(),
59 HEADER_TO_BODY(ObjectHeader
),
67 /**********************************************************************
77 NTSTATUS
ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes
,
78 PVOID
* ReturnedObject
,
83 POBJECT_HEADER CurrentHeader
;
88 DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
89 "RemainingPath %x)\n",ObjectAttributes
,ReturnedObject
,RemainingPath
);
90 DPRINT("ObjectAttributes->ObjectName->Buffer %x\n",
91 ObjectAttributes
->ObjectName
->Buffer
);
93 if (ObjectAttributes
->RootDirectory
== NULL
)
95 ObReferenceObjectByPointer(NameSpaceRoot
,
99 CurrentObject
= NameSpaceRoot
;
103 Status
= ObReferenceObjectByHandle(ObjectAttributes
->RootDirectory
,
109 if (!NT_SUCCESS(Status
))
115 Path
= ObjectAttributes
->ObjectName
->Buffer
;
119 *ReturnedObject
= CurrentObject
;
120 return(STATUS_SUCCESS
);
125 return(STATUS_UNSUCCESSFUL
);
132 DPRINT("current %S\n",current
);
133 CurrentHeader
= BODY_TO_HEADER(CurrentObject
);
134 if (CurrentHeader
->ObjectType
->Parse
== NULL
)
136 DPRINT("Current object can't parse\n");
139 NextObject
= CurrentHeader
->ObjectType
->Parse(CurrentObject
,
141 if (NextObject
== NULL
)
145 ObDereferenceObject(CurrentObject
);
146 CurrentObject
= NextObject
;
149 *RemainingPath
= current
;
150 *ReturnedObject
= CurrentObject
;
152 return(STATUS_SUCCESS
);
156 /**********************************************************************
166 PVOID STDCALL
ObCreateObject(PHANDLE Handle
,
167 ACCESS_MASK DesiredAccess
,
168 POBJECT_ATTRIBUTES ObjectAttributes
,
172 PWSTR RemainingPath
= NULL
;
173 POBJECT_HEADER Header
;
176 assert_irql(APC_LEVEL
);
178 DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
179 if (ObjectAttributes
!= NULL
&&
180 ObjectAttributes
->ObjectName
!= NULL
)
182 DPRINT("ObjectAttributes->ObjectName->Buffer %S\n",
183 ObjectAttributes
->ObjectName
->Buffer
);
186 if (ObjectAttributes
!= NULL
&&
187 ObjectAttributes
->ObjectName
!= NULL
)
189 ObFindObject(ObjectAttributes
,
194 Header
= (POBJECT_HEADER
)ExAllocatePool(NonPagedPool
,
195 OBJECT_ALLOC_SIZE(Type
));
196 ObInitializeObject(Header
,
201 if (Header
->ObjectType
!= NULL
&&
202 Header
->ObjectType
->Create
!= NULL
)
204 DPRINT("Calling %x\n", Header
->ObjectType
);
205 DPRINT("Calling %x\n", Header
->ObjectType
->Create
);
206 Status
= Header
->ObjectType
->Create(HEADER_TO_BODY(Header
),
210 if (!NT_SUCCESS(Status
))
212 ObDereferenceObject( Parent
);
213 RtlFreeUnicodeString( &Header
->Name
);
214 ExFreePool( Header
);
218 return(HEADER_TO_BODY(Header
));
221 NTSTATUS STDCALL
ObReferenceObjectByPointer(PVOID ObjectBody
,
222 ACCESS_MASK DesiredAccess
,
223 POBJECT_TYPE ObjectType
,
224 KPROCESSOR_MODE AccessMode
)
226 * FUNCTION: Increments the pointer reference count for a given object
228 * ObjectBody = Object's body
229 * DesiredAccess = Desired access to the object
230 * ObjectType = Points to the object type structure
231 * AccessMode = Type of access check to perform
235 POBJECT_HEADER ObjectHeader
;
237 // DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n",
238 // ObjectBody,ObjectType);
240 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
242 if (ObjectType
!= NULL
&& ObjectHeader
->ObjectType
!= ObjectType
)
244 DPRINT("Failed %x (type was %x %S) should %x\n",
246 ObjectHeader
->ObjectType
,
247 ObjectHeader
->ObjectType
->TypeName
.Buffer
,
250 return(STATUS_UNSUCCESSFUL
);
252 if (ObjectHeader
->ObjectType
== PsProcessType
)
254 DPRINT("Ref p 0x%x refcount %d type %x ",
255 ObjectBody
, ObjectHeader
->RefCount
, PsProcessType
);
256 DPRINT("eip %x\n", ((PULONG
)&ObjectBody
)[-1]);
258 if (ObjectHeader
->ObjectType
== PsThreadType
)
260 DPRINT("Deref t 0x%x with refcount %d type %x ",
261 ObjectBody
, ObjectHeader
->RefCount
, PsThreadType
);
262 DPRINT("eip %x\n", ((PULONG
)&ObjectBody
)[-1]);
265 ObjectHeader
->RefCount
++;
267 return(STATUS_SUCCESS
);
270 NTSTATUS
ObPerformRetentionChecks(POBJECT_HEADER Header
)
272 // DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
273 // Header,Header->RefCount,Header->HandleCount);
275 if (Header
->RefCount
< 0)
277 DbgPrint("Object %x/%x has invalid reference count (%d)\n",
278 Header
, HEADER_TO_BODY(Header
), Header
->RefCount
);
281 if (Header
->HandleCount
< 0)
283 DbgPrint("Object %x/%x has invalid handle count (%d)\n",
284 Header
, HEADER_TO_BODY(Header
), Header
->HandleCount
);
288 if (Header
->RefCount
== 0 && Header
->HandleCount
== 0 &&
291 if (Header
->ObjectType
!= NULL
&&
292 Header
->ObjectType
->Delete
!= NULL
)
294 Header
->ObjectType
->Delete(HEADER_TO_BODY(Header
));
296 if (Header
->Name
.Buffer
!= NULL
)
298 ObRemoveEntry(Header
);
299 RtlFreeUnicodeString( &Header
->Name
);
301 DPRINT("ObPerformRetentionChecks() = Freeing object\n");
304 return(STATUS_SUCCESS
);
307 ULONG
ObGetReferenceCount(PVOID ObjectBody
)
309 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
311 return(Header
->RefCount
);
314 ULONG
ObGetHandleCount(PVOID ObjectBody
)
316 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
318 return(Header
->HandleCount
);
322 /**********************************************************************
324 * @ObfReferenceObject@0
327 * Increments a given object's reference count and performs
332 * Body of the object.
335 * The current value of the reference counter.
337 ULONG FASTCALL
ObfReferenceObject(PVOID ObjectBody
)
339 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
340 ULONG ReferenceCount
;
342 ReferenceCount
= Header
->RefCount
++;
344 ObPerformRetentionChecks (Header
);
346 return(ReferenceCount
);
350 VOID FASTCALL
ObfDereferenceObject (PVOID ObjectBody
)
352 * FUNCTION: Decrements a given object's reference count and performs
355 * ObjectBody = Body of the object
358 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
359 extern POBJECT_TYPE PsProcessType
;
361 // DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody,
362 // Header->RefCount);
364 if (Header
->ObjectType
== PsProcessType
)
366 DPRINT("Deref p 0x%x with refcount %d type %x ",
367 ObjectBody
, Header
->RefCount
, PsProcessType
);
368 DPRINT("eip %x\n", ((PULONG
)&ObjectBody
)[-1]);
370 if (Header
->ObjectType
== PsThreadType
)
372 DPRINT("Deref t 0x%x with refcount %d type %x ",
373 ObjectBody
, Header
->RefCount
, PsThreadType
);
374 DPRINT("eip %x\n", ((PULONG
)&ObjectBody
)[-1]);
379 ObPerformRetentionChecks(Header
);
383 VOID STDCALL
ObDereferenceObject (PVOID ObjectBody
)
385 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
386 extern POBJECT_TYPE PsProcessType
;
388 if (Header
->ObjectType
== PsProcessType
)
390 DPRINT("Deref p 0x%x with refcount %d type %x ",
391 ObjectBody
, Header
->RefCount
, PsProcessType
);
392 DPRINT("eip %x\n", ((PULONG
)&ObjectBody
)[-1]);
395 ObfDereferenceObject (ObjectBody
);