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 *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/string.h>
17 #include <internal/id.h>
20 #include <internal/debug.h>
22 /* FUNCTIONS ************************************************************/
24 VOID
ObInitializeObject(POBJECT_HEADER ObjectHeader
,
26 ACCESS_MASK DesiredAccess
,
28 POBJECT_ATTRIBUTES ObjectAttributes
)
30 ObjectHeader
->HandleCount
= 1;
31 ObjectHeader
->RefCount
= 1;
32 ObjectHeader
->ObjectType
= Type
;
33 ObjectHeader
->Permanent
= FALSE
;
34 RtlInitUnicodeString(&(ObjectHeader
->Name
),NULL
);
37 ObCreateHandle(PsGetCurrentProcess(),
38 HEADER_TO_BODY(ObjectHeader
),
45 NTSTATUS
ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes
,
46 PVOID
* ReturnedObject
,
51 POBJECT_HEADER CurrentHeader
;
56 DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
57 "RemainingPath %x)\n",ObjectAttributes
,ReturnedObject
,RemainingPath
);
58 DPRINT("ObjectAttributes->ObjectName->Buffer %x\n",
59 ObjectAttributes
->ObjectName
->Buffer
);
61 if (ObjectAttributes
->RootDirectory
== NULL
)
63 ObReferenceObjectByPointer(NameSpaceRoot
,
67 CurrentObject
= NameSpaceRoot
;
71 Status
= ObReferenceObjectByHandle(ObjectAttributes
->RootDirectory
,
77 if (!NT_SUCCESS(Status
))
83 Path
= ObjectAttributes
->ObjectName
->Buffer
;
87 *ReturnedObject
= CurrentObject
;
88 return(STATUS_SUCCESS
);
93 return(STATUS_UNSUCCESSFUL
);
100 DPRINT("current %w\n",current
);
101 CurrentHeader
= BODY_TO_HEADER(CurrentObject
);
102 if (CurrentHeader
->ObjectType
->Parse
== NULL
)
106 NextObject
= CurrentHeader
->ObjectType
->Parse(CurrentObject
,
108 if (NextObject
== NULL
)
112 ObDereferenceObject(CurrentObject
);
113 CurrentObject
= NextObject
;
116 *RemainingPath
= current
;
117 *ReturnedObject
= CurrentObject
;
119 return(STATUS_SUCCESS
);
122 PVOID
ObCreateObject(PHANDLE Handle
,
123 ACCESS_MASK DesiredAccess
,
124 POBJECT_ATTRIBUTES ObjectAttributes
,
128 PWSTR RemainingPath
= NULL
;
129 POBJECT_HEADER Header
;
132 DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
133 if (ObjectAttributes
!= NULL
&&
134 ObjectAttributes
->ObjectName
!= NULL
)
136 DPRINT("ObjectAttributes->ObjectName->Buffer %w\n",
137 ObjectAttributes
->ObjectName
->Buffer
);
140 if (ObjectAttributes
!= NULL
&&
141 ObjectAttributes
->ObjectName
!= NULL
)
143 ObFindObject(ObjectAttributes
,
148 Header
= (POBJECT_HEADER
)ExAllocatePool(NonPagedPool
,
149 OBJECT_ALLOC_SIZE(Type
));
150 ObInitializeObject(Header
,
155 if (Header
->ObjectType
!= NULL
&&
156 Header
->ObjectType
->Create
!= NULL
)
158 Status
= Header
->ObjectType
->Create(HEADER_TO_BODY(Header
),
162 if (!NT_SUCCESS(Status
))
167 return(HEADER_TO_BODY(Header
));
170 NTSTATUS
ObReferenceObjectByPointer(PVOID ObjectBody
,
171 ACCESS_MASK DesiredAccess
,
172 POBJECT_TYPE ObjectType
,
173 KPROCESSOR_MODE AccessMode
)
175 * FUNCTION: Increments the pointer reference count for a given object
177 * ObjectBody = Object's body
178 * DesiredAccess = Desired access to the object
179 * ObjectType = Points to the object type structure
180 * AccessMode = Type of access check to perform
184 POBJECT_HEADER ObjectHeader
;
186 DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n",
187 ObjectBody
,ObjectType
);
189 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
191 if (ObjectType
!= NULL
&& ObjectHeader
->ObjectType
!= ObjectType
)
193 DPRINT("Failed (type was %x %w)\n",ObjectHeader
->ObjectType
,
194 ObjectHeader
->ObjectType
->TypeName
.Buffer
);
195 return(STATUS_UNSUCCESSFUL
);
198 ObjectHeader
->RefCount
++;
200 return(STATUS_SUCCESS
);
203 NTSTATUS
ObPerformRetentionChecks(POBJECT_HEADER Header
)
205 DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
206 Header
,Header
->RefCount
,Header
->HandleCount
);
208 if (Header
->RefCount
< 0 || Header
->HandleCount
< 0)
210 DbgPrint("Object %x/%x has invalid reference or handle count\n",
211 Header
,HEADER_TO_BODY(Header
));
215 if (Header
->RefCount
== 0 && Header
->HandleCount
== 0 &&
218 if (Header
->ObjectType
!= NULL
&&
219 Header
->ObjectType
->Delete
!= NULL
)
221 Header
->ObjectType
->Delete(HEADER_TO_BODY(Header
));
223 if (Header
->Name
.Buffer
!= NULL
)
225 ObRemoveEntry(Header
);
227 DPRINT("ObPerformRetentionChecks() = Freeing object\n");
230 return(STATUS_SUCCESS
);
233 ULONG
ObGetReferenceCount(PVOID ObjectBody
)
235 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
237 return(Header
->RefCount
);
240 VOID
ObDereferenceObject(PVOID ObjectBody
)
242 * FUNCTION: Decrements a given object's reference count and performs
245 * ObjectBody = Body of the object
248 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
250 DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody
,
255 ObPerformRetentionChecks(Header
);