Initial revision
[reactos.git] / reactos / ntoskrnl / ob / object.c
1 /*
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)
7 * UPDATE HISTORY:
8 * 10/06/98: Created
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/objmgr.h>
15 #include <internal/kernel.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20 /* GLOBALS ****************************************************************/
21
22 /*
23 * List of pointers to object types
24 */
25 static POBJECT_TYPE ObjectTypes[OBJTYP_MAX]={NULL,};
26
27 /* FUNCTIONS ************************************************************/
28
29 NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)
30 {
31 UNIMPLEMENTED;
32 }
33
34 PVOID ObGenericCreateObject(PHANDLE Handle,
35 ACCESS_MASK DesiredAccess,
36 POBJECT_ATTRIBUTES ObjectAttributes,
37 CSHORT Type)
38 {
39 POBJECT_HEADER hdr = NULL;
40
41 DPRINT("ObGenericCreateObject(Handle %x ObjectAttributes %x Type %x)\n",
42 Handle,ObjectAttributes,Type);
43
44 /*
45 * Allocate the object body and header
46 */
47 hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));
48 if (hdr==NULL)
49 {
50 return(NULL);
51 }
52
53 /*
54 * Initialize the object header
55 */
56 if (ObjectAttributes!=NULL)
57 {
58 ObInitializeObjectHeader(Type,&ObjectAttributes->name,hdr);
59 }
60 else
61 {
62 ObInitializeObjectHeader(Type,NULL,hdr);
63 }
64
65 // DPRINT("ObjectAttributes->parent->Type %d\n",
66 // ObjectAttributes->parent->Type);
67 if (ObjectAttributes!=NULL)
68 {
69 /*
70 * Add the object to its parent directory
71 */
72 DPRINT("hdr->name.Buffer %x\n",hdr->name.Buffer);
73 ObCreateEntry(ObjectAttributes->parent,hdr);
74 }
75
76 DPRINT("Handle %x\n",Handle);
77 *Handle = ObAddHandle(HEADER_TO_BODY(hdr));
78
79 return(HEADER_TO_BODY(hdr));
80 }
81
82 ULONG ObSizeOf(CSHORT Type)
83 {
84 return(ObjectTypes[Type]->PagedPoolCharge);
85 }
86
87 VOID ObRegisterType(CSHORT id, POBJECT_TYPE type)
88 /*
89 * FUNCTION: Registers a new type of object
90 * ARGUMENTS:
91 * typ = Pointer to the type definition to register
92 */
93 {
94 DPRINT("ObRegisterType(id %d, type %x)\n",id,type);
95 ObjectTypes[id]=type;
96 }
97
98 VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
99 POBJECT_HEADER obj)
100 /*
101 * FUNCTION: Creates a new object
102 * ARGUMENT:
103 * id = Identifier for the type of object
104 * obj = Pointer to the header of the object
105 */
106 {
107 if (name!=NULL)
108 {
109 DPRINT("ObInitializeObjectHeader(id %d name %w obj %x)\n",id,
110 name->Buffer,obj);
111 }
112 else
113 {
114 DPRINT("ObInitializeObjectHeader(id %d name %x obj %x)\n",id,
115 name,obj);
116 }
117
118 obj->HandleCount = 0;
119 obj->RefCount = 0;
120 obj->Type = id;
121 if (name==NULL)
122 {
123 obj->name.Length=0;
124 obj->name.Buffer=NULL;
125 }
126 else
127 {
128 obj->name.Length = 0;
129 obj->name.MaximumLength = name->Length;
130 obj->name.Buffer = ExAllocatePool(NonPagedPool,
131 (name->Length+1)*sizeof(WCHAR));
132 DPRINT("obj->name.Buffer %x\n",obj->name.Buffer);
133 RtlCopyUnicodeString(&obj->name,name);
134 DPRINT("obj->name.Buffer %x\n",obj->name.Buffer);
135 }
136 }
137
138
139 NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
140 ACCESS_MASK DesiredAccess,
141 POBJECT_TYPE ObjectType,
142 KPROCESSOR_MODE AccessMode)
143 /*
144 * FUNCTION: Increments the pointer reference count for a given object
145 * ARGUMENTS:
146 * ObjectBody = Object's body
147 * DesiredAccess = Desired access to the object
148 * ObjectType = Points to the object type structure
149 * AccessMode = Type of access check to perform
150 * RETURNS: Status
151 */
152 {
153 POBJECT_HEADER Object = BODY_TO_HEADER(ObjectBody);
154
155 DPRINT("ObReferenceObjectByPointer(%x %x)\n",ObjectBody,Object);
156
157 Object->RefCount++;
158 return(STATUS_SUCCESS);
159 }
160
161 VOID ObDereferenceObject(PVOID ObjectBody)
162 /*
163 * FUNCTION: Decrements a given object's reference count and performs
164 * retention checks
165 * ARGUMENTS:
166 * ObjectBody = Body of the object
167 */
168 {
169 POBJECT_HEADER Object = BODY_TO_HEADER(ObjectBody);
170 Object->RefCount--;
171 }
172
173 NTSTATUS ZwClose(HANDLE Handle)
174 /*
175 * FUNCTION: Closes a handle reference to an object
176 * ARGUMENTS:
177 * Handle = handle to close
178 * RETURNS: Status
179 */
180 {
181 PVOID ObjectBody;
182
183 ASSERT_IRQL(PASSIVE_LEVEL);
184
185 ObjectBody = ObGetObjectByHandle(Handle);
186 if (ObjectBody == NULL)
187 {
188 return(STATUS_INVALID_HANDLE);
189 }
190 ObDereferenceObject(ObjectBody);
191 return(STATUS_SUCCESS);
192 }
193
194 NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
195 ACCESS_MASK DesiredAccess,
196 POBJECT_TYPE ObjectType,
197 KPROCESSOR_MODE AccessMode,
198 PVOID* Object,
199 POBJECT_HANDLE_INFORMATION
200 HandleInformationPtr
201 )
202 /*
203 * FUNCTION: Increments the reference count for an object and returns a
204 * pointer to its body
205 * ARGUMENTS:
206 * Handle = Handle for the object
207 * DesiredAccess = Desired access to the object
208 * ObjectType
209 * AccessMode
210 * Object (OUT) = Points to the object body on return
211 * HandleInformation (OUT) = Contains information about the handle
212 * on return
213 * RETURNS: Status
214 */
215 {
216 PVOID ObjectBody;
217
218 ASSERT_IRQL(PASSIVE_LEVEL);
219 assert(HandleInformation==NULL);
220 assert(Object!=NULL);
221 assert(Handle!=NULL);
222
223 ObjectBody = ObGetObjectByHandle(Handle);
224 if (ObjectBody == NULL)
225 {
226 return(STATUS_INVALID_HANDLE);
227 }
228 return(ObReferenceObjectByPointer(ObjectBody,DesiredAccess,
229 ObjectType,AccessMode));
230 }