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@mcmail.com)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
18 #include <internal/debug.h>
20 /* FUNCTIONS ************************************************************/
22 NTSTATUS STDCALL
NtSetInformationObject(IN HANDLE ObjectHandle
,
23 IN CINT ObjectInformationClass
,
24 IN PVOID ObjectInformation
,
27 return(ZwSetInformationObject(ObjectHandle
,
28 ObjectInformationClass
,
33 NTSTATUS STDCALL
ZwSetInformationObject(IN HANDLE ObjectHandle
,
34 IN CINT ObjectInformationClass
,
35 IN PVOID ObjectInformation
,
41 NTSTATUS STDCALL
NtQueryObject(IN HANDLE ObjectHandle
,
42 IN CINT ObjectInformationClass
,
43 OUT PVOID ObjectInformation
,
45 OUT PULONG ResultLength
)
47 return(ZwQueryObject(ObjectHandle
,
48 ObjectInformationClass
,
54 NTSTATUS STDCALL
ZwQueryObject(IN HANDLE ObjectHandle
,
55 IN CINT ObjectInformationClass
,
56 OUT PVOID ObjectInformation
,
58 OUT PULONG ResultLength
)
63 NTSTATUS
NtMakeTemporaryObject(HANDLE Handle
)
65 return(ZwMakeTemporaryObject(Handle
));
68 NTSTATUS
ZwMakeTemporaryObject(HANDLE Handle
)
72 POBJECT_HEADER ObjectHeader
;
74 Status
= ObReferenceObjectByHandle(Handle
,
80 if (Status
!= STATUS_SUCCESS
)
85 ObjectHeader
= BODY_TO_HEADER(Object
);
86 ObjectHeader
->Permanent
= FALSE
;
88 ObDereferenceObject(Object
);
90 return(STATUS_SUCCESS
);
93 PVOID
ObGenericCreateObject(PHANDLE Handle
,
94 ACCESS_MASK DesiredAccess
,
95 POBJECT_ATTRIBUTES ObjectAttributes
,
98 POBJECT_HEADER hdr
= NULL
;
99 UNICODE_STRING ObjectName
;
104 DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
105 "ObjectAttributes %x, Type %x)\n",Handle
,DesiredAccess
,
106 ObjectAttributes
,Type
);
109 * Allocate the object body and header
111 hdr
=(POBJECT_HEADER
)ExAllocatePool(NonPagedPool
,OBJECT_ALLOC_SIZE(Type
));
118 * If unnamed then initalize
120 if (ObjectAttributes
==NULL
)
122 ObInitializeObjectHeader(Type
,NULL
,hdr
);
125 *Handle
= ObInsertHandle(KeGetCurrentProcess(),
130 return(HEADER_TO_BODY(hdr
));
134 * Copy the object name into a buffer
136 DPRINT("ObjectAttributes->ObjectName %x\n",ObjectAttributes
->ObjectName
);
137 DPRINT("ObjectAttributes->ObjectName->Length %d\n",
138 ObjectAttributes
->ObjectName
->Length
);
139 ObjectName
.MaximumLength
= ObjectAttributes
->ObjectName
->Length
;
140 ObjectName
.Buffer
= ExAllocatePool(NonPagedPool
,
141 ((ObjectAttributes
->ObjectName
->Length
+1)*2));
142 if (ObjectName
.Buffer
==NULL
)
146 RtlCopyUnicodeString(&ObjectName
,ObjectAttributes
->ObjectName
);
149 * Seperate the name into a path and name
151 name
= wcsrchr(ObjectName
.Buffer
,'\\');
154 name
=ObjectName
.Buffer
;
159 path
=ObjectName
.Buffer
;
164 ObLookupObject(ObjectAttributes
->RootDirectory
,path
,
165 &hdr
->Parent
,&Ignored
, 0L);
168 * Initialize the object header
170 ObInitializeObjectHeader(Type
,name
,hdr
);
171 ObCreateEntry(hdr
->Parent
,hdr
);
173 DPRINT("Handle %x\n",Handle
);
176 *Handle
= ObInsertHandle(KeGetCurrentProcess(),
182 return(HEADER_TO_BODY(hdr
));
185 VOID
ObInitializeObjectHeader(POBJECT_TYPE Type
, PWSTR name
,
186 POBJECT_HEADER ObjectHeader
)
188 * FUNCTION: Creates a new object
190 * id = Identifier for the type of object
191 * obj = Pointer to the header of the object
196 DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type
,
199 ObjectHeader
->HandleCount
= 0;
200 ObjectHeader
->RefCount
= 0;
201 ObjectHeader
->ObjectType
= Type
;
202 ObjectHeader
->Permanent
= FALSE
;
205 ObjectHeader
->Name
.Length
=0;
206 ObjectHeader
->Name
.Buffer
=NULL
;
210 ObjectHeader
->Name
.MaximumLength
= wstrlen(name
);
211 ObjectHeader
->Name
.Buffer
= ExAllocatePool(NonPagedPool
,
212 (ObjectHeader
->Name
.MaximumLength
+1)*2);
213 RtlInitUnicodeString(&ObjectHeader
->Name
,name
);
218 NTSTATUS
ObReferenceObjectByPointer(PVOID ObjectBody
,
219 ACCESS_MASK DesiredAccess
,
220 POBJECT_TYPE ObjectType
,
221 KPROCESSOR_MODE AccessMode
)
223 * FUNCTION: Increments the pointer reference count for a given object
225 * ObjectBody = Object's body
226 * DesiredAccess = Desired access to the object
227 * ObjectType = Points to the object type structure
228 * AccessMode = Type of access check to perform
232 POBJECT_HEADER Object
;
234 DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody
);
236 Object
= BODY_TO_HEADER(ObjectBody
);
238 return(STATUS_SUCCESS
);
241 NTSTATUS
ObPerformRetentionChecks(POBJECT_HEADER Header
)
243 if (Header
->RefCount
== 0 && Header
->HandleCount
== 0 &&
246 ObRemoveEntry(Header
);
249 return(STATUS_SUCCESS
);
252 VOID
ObDereferenceObject(PVOID ObjectBody
)
254 * FUNCTION: Decrements a given object's reference count and performs
257 * ObjectBody = Body of the object
260 POBJECT_HEADER Header
= BODY_TO_HEADER(ObjectBody
);
262 ObPerformRetentionChecks(Header
);
266 NTSTATUS
NtClose(HANDLE Handle
)
268 return(ZwClose(Handle
));
271 NTSTATUS
ZwClose(HANDLE Handle
)
273 * FUNCTION: Closes a handle reference to an object
275 * Handle = handle to close
280 POBJECT_HEADER Header
;
281 PHANDLE_REP HandleRep
;
283 assert_irql(PASSIVE_LEVEL
);
285 HandleRep
= ObTranslateHandle(KeGetCurrentProcess(),Handle
);
286 if (HandleRep
== NULL
)
288 return(STATUS_INVALID_HANDLE
);
290 ObjectBody
= HandleRep
->ObjectBody
;
292 HandleRep
->ObjectBody
= NULL
;
294 Header
= BODY_TO_HEADER(ObjectBody
);
296 Header
->HandleCount
--;
297 ObPerformRetentionChecks(Header
);
299 return(STATUS_SUCCESS
);
302 NTSTATUS
ObReferenceObjectByHandle(HANDLE Handle
,
303 ACCESS_MASK DesiredAccess
,
304 POBJECT_TYPE ObjectType
,
305 KPROCESSOR_MODE AccessMode
,
307 POBJECT_HANDLE_INFORMATION
311 * FUNCTION: Increments the reference count for an object and returns a
312 * pointer to its body
314 * Handle = Handle for the object
315 * DesiredAccess = Desired access to the object
318 * Object (OUT) = Points to the object body on return
319 * HandleInformation (OUT) = Contains information about the handle
324 PHANDLE_REP HandleRep
;
325 POBJECT_HEADER ObjectHeader
;
327 ASSERT_IRQL(PASSIVE_LEVEL
);
329 DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
330 "ObjectType %x, AccessMode %d, Object %x)\n",Handle
,DesiredAccess
,
331 ObjectType
,AccessMode
,Object
);
333 if (Handle
== NtCurrentProcess())
335 *Object
= PsGetCurrentProcess();
336 return(STATUS_SUCCESS
);
338 if (Handle
== NtCurrentThread())
340 *Object
= PsGetCurrentThread();
341 return(STATUS_SUCCESS
);
344 HandleRep
= ObTranslateHandle(KeGetCurrentProcess(),Handle
);
345 if (HandleRep
== NULL
|| HandleRep
->ObjectBody
== NULL
)
347 return(STATUS_INVALID_HANDLE
);
350 ObjectHeader
= BODY_TO_HEADER(HandleRep
->ObjectBody
);
352 if (ObjectType
!= NULL
&& ObjectType
!= ObjectHeader
->ObjectType
)
354 return(STATUS_UNSUCCESSFUL
);
357 if (!(HandleRep
->GrantedAccess
& DesiredAccess
))
359 return(STATUS_ACCESS_DENIED
);
362 ObjectHeader
->RefCount
++;
364 *Object
= HandleRep
->ObjectBody
;
366 return(STATUS_SUCCESS
);