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 assert_irql(PASSIVE_LEVEL
);
134 DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
135 if (ObjectAttributes
!= NULL
&&
136 ObjectAttributes
->ObjectName
!= NULL
)
138 DPRINT("ObjectAttributes->ObjectName->Buffer %w\n",
139 ObjectAttributes
->ObjectName
->Buffer
);
142 if (ObjectAttributes
!= NULL
&&
143 ObjectAttributes
->ObjectName
!= NULL
)
145 ObFindObject(ObjectAttributes
,
150 Header
= (POBJECT_HEADER
)ExAllocatePool(NonPagedPool
,
151 OBJECT_ALLOC_SIZE(Type
));
152 ObInitializeObject(Header
,
157 if (Header
->ObjectType
!= NULL
&&
158 Header
->ObjectType
->Create
!= NULL
)
160 Status
= Header
->ObjectType
->Create(HEADER_TO_BODY(Header
),
164 if (!NT_SUCCESS(Status
))
169 return(HEADER_TO_BODY(Header
));
172 NTSTATUS
ObReferenceObjectByPointer(PVOID ObjectBody
,
173 ACCESS_MASK DesiredAccess
,
174 POBJECT_TYPE ObjectType
,
175 KPROCESSOR_MODE AccessMode
)
177 * FUNCTION: Increments the pointer reference count for a given object
179 * ObjectBody = Object's body
180 * DesiredAccess = Desired access to the object
181 * ObjectType = Points to the object type structure
182 * AccessMode = Type of access check to perform
186 POBJECT_HEADER ObjectHeader
;
188 DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n",
189 ObjectBody
,ObjectType
);
191 ObjectHeader
= BODY_TO_HEADER(ObjectBody
);
193 if (ObjectType
!= NULL
&& ObjectHeader
->ObjectType
!= ObjectType
)
195 DPRINT("Failed (type was %x %w)\n",ObjectHeader
->ObjectType
,
196 ObjectHeader
->ObjectType
->TypeName
.Buffer
);
197 return(STATUS_UNSUCCESSFUL
);
200 ObjectHeader
->RefCount
++;
202 return(STATUS_SUCCESS
);
205 NTSTATUS
ObPerformRetentionChecks(POBJECT_HEADER Header
)
207 DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
208 Header
,Header
->RefCount
,Header
->HandleCount
);
210 if (Header
->RefCount
< 0 || Header
->HandleCount
< 0)
212 DbgPrint("Object %x/%x has invalid reference or handle count\n",
213 Header
,HEADER_TO_BODY(Header
));
217 if (Header
->RefCount
== 0 && Header
->HandleCount
== 0 &&
220 if (Header
->ObjectType
!= NULL
&&
221 Header
->ObjectType
->Delete
!= NULL
)
223 Header
->ObjectType
->Delete(HEADER_TO_BODY(Header
));
225 if (Header
->Name
.Buffer
!= NULL
)
227 ObRemoveEntry(Header
);
229 DPRINT("ObPerformRetentionChecks() = Freeing object\n");
232 return(STATUS_SUCCESS
);
235 ULONG
ObGetReferenceCount(PVOID ObjectBody
)
237 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
239 return(Header
->RefCount
);
242 VOID
ObDereferenceObject(PVOID ObjectBody
)
244 * FUNCTION: Decrements a given object's reference count and performs
247 * ObjectBody = Body of the object
250 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
252 DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody
,
257 ObPerformRetentionChecks(Header
);