This commit was generated by cvs2svn to compensate for changes in r30,
[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 <wstring.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 UNICODE_STRING ObjectName;
41 PWSTR path;
42 PWSTR name;
43 PDIRECTORY_OBJECT parent;
44
45 DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
46 "ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,ObjectAttributes,
47 Type);
48
49 /*
50 * Allocate the object body and header
51 */
52 hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));
53 if (hdr==NULL)
54 {
55 return(NULL);
56 }
57
58 /*
59 * If unnamed then initalize
60 */
61 if (ObjectAttributes==NULL)
62 {
63 ObInitializeObjectHeader(Type,NULL,hdr);
64 *Handle = ObAddHandle(HEADER_TO_BODY(hdr));
65 return(HEADER_TO_BODY(hdr));
66 }
67
68 /*
69 * Copy the object name into a buffer
70 */
71 DPRINT("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);
72 DPRINT("ObjectAttributes->ObjectName->Length %d\n",
73 ObjectAttributes->ObjectName->Length);
74 ObjectName.MaximumLength = ObjectAttributes->ObjectName->Length;
75 ObjectName.Buffer = ExAllocatePool(NonPagedPool,
76 ((ObjectAttributes->ObjectName->Length+1)*2));
77 if (ObjectName.Buffer==NULL)
78 {
79 return(NULL);
80 }
81 RtlCopyUnicodeString(&ObjectName,ObjectAttributes->ObjectName);
82
83 /*
84 * Seperate the name into a path and name
85 */
86 name = wcsrchr(ObjectName.Buffer,'\\');
87 if (name==NULL)
88 {
89 name=ObjectName.Buffer;
90 path=NULL;
91 }
92 else
93 {
94 path=ObjectName.Buffer;
95 *name=0;
96 name=name+1;
97 }
98
99 hdr->Parent = ObLookupObject(ObjectAttributes->RootDirectory,path);
100
101 /*
102 * Initialize the object header
103 */
104 ObInitializeObjectHeader(Type,name,hdr);
105 ObCreateEntry(hdr->Parent,hdr);
106
107 DPRINT("Handle %x\n",Handle);
108 *Handle = ObAddHandle(HEADER_TO_BODY(hdr));
109
110 return(HEADER_TO_BODY(hdr));
111 }
112
113 ULONG ObSizeOf(CSHORT Type)
114 {
115 DPRINT("ObSizeOf(Type %d)\n",Type);
116 DPRINT("ObSizeOf() Returning %d\n",ObjectTypes[Type]->PagedPoolCharge);
117 return(ObjectTypes[Type]->PagedPoolCharge);
118 }
119
120 VOID ObRegisterType(CSHORT id, POBJECT_TYPE type)
121 /*
122 * FUNCTION: Registers a new type of object
123 * ARGUMENTS:
124 * typ = Pointer to the type definition to register
125 */
126 {
127 DPRINT("ObRegisterType(id %d, type %x)\n",id,type);
128 ObjectTypes[id]=type;
129 }
130
131 VOID ObInitializeObjectHeader(CSHORT id, PWSTR name,
132 POBJECT_HEADER obj)
133 /*
134 * FUNCTION: Creates a new object
135 * ARGUMENT:
136 * id = Identifier for the type of object
137 * obj = Pointer to the header of the object
138 */
139 {
140 PWSTR temp_name;
141
142 if (name!=NULL)
143 {
144 DPRINT("ObInitializeObjectHeader(id %d name %w obj %x)\n",id,
145 name,obj);
146 }
147 else
148 {
149 DPRINT("ObInitializeObjectHeader(id %d name %x obj %x)\n",id,
150 name,obj);
151 }
152
153 obj->HandleCount = 0;
154 obj->RefCount = 0;
155 obj->Type = id;
156 if (name==NULL)
157 {
158 obj->name.Length=0;
159 obj->name.Buffer=NULL;
160 }
161 else
162 {
163 DPRINT("name %w\n",name);
164 obj->name.MaximumLength = wstrlen(name);
165 obj->name.Buffer = ExAllocatePool(NonPagedPool,
166 (obj->name.MaximumLength+1)*2);
167 DPRINT("name %w\n",name);
168 RtlInitUnicodeString(&obj->name,name);
169 DPRINT("name %w\n",obj->name.Buffer);
170 }
171 }
172
173
174 NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
175 ACCESS_MASK DesiredAccess,
176 POBJECT_TYPE ObjectType,
177 KPROCESSOR_MODE AccessMode)
178 /*
179 * FUNCTION: Increments the pointer reference count for a given object
180 * ARGUMENTS:
181 * ObjectBody = Object's body
182 * DesiredAccess = Desired access to the object
183 * ObjectType = Points to the object type structure
184 * AccessMode = Type of access check to perform
185 * RETURNS: Status
186 */
187 {
188 POBJECT_HEADER Object;
189
190 DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);
191
192 Object = BODY_TO_HEADER(ObjectBody);
193 Object->RefCount++;
194 return(STATUS_SUCCESS);
195 }
196
197 VOID ObDereferenceObject(PVOID ObjectBody)
198 /*
199 * FUNCTION: Decrements a given object's reference count and performs
200 * retention checks
201 * ARGUMENTS:
202 * ObjectBody = Body of the object
203 */
204 {
205 POBJECT_HEADER Object = BODY_TO_HEADER(ObjectBody);
206 Object->RefCount--;
207 }
208
209 NTSTATUS ZwClose(HANDLE Handle)
210 /*
211 * FUNCTION: Closes a handle reference to an object
212 * ARGUMENTS:
213 * Handle = handle to close
214 * RETURNS: Status
215 */
216 {
217 PVOID ObjectBody;
218
219 assert_irql(PASSIVE_LEVEL);
220
221 ObjectBody = ObGetObjectByHandle(Handle);
222 if (ObjectBody == NULL)
223 {
224 return(STATUS_INVALID_HANDLE);
225 }
226 ObDereferenceObject(ObjectBody);
227 return(STATUS_SUCCESS);
228 }
229
230 NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
231 ACCESS_MASK DesiredAccess,
232 POBJECT_TYPE ObjectType,
233 KPROCESSOR_MODE AccessMode,
234 PVOID* Object,
235 POBJECT_HANDLE_INFORMATION
236 HandleInformationPtr
237 )
238 /*
239 * FUNCTION: Increments the reference count for an object and returns a
240 * pointer to its body
241 * ARGUMENTS:
242 * Handle = Handle for the object
243 * DesiredAccess = Desired access to the object
244 * ObjectType
245 * AccessMode
246 * Object (OUT) = Points to the object body on return
247 * HandleInformation (OUT) = Contains information about the handle
248 * on return
249 * RETURNS: Status
250 */
251 {
252 PVOID ObjectBody;
253
254 ASSERT_IRQL(PASSIVE_LEVEL);
255 assert(HandleInformationPtr==NULL);
256 assert(Object!=NULL);
257 assert(Handle!=NULL);
258
259 ObjectBody = ObGetObjectByHandle(Handle);
260 if (ObjectBody == NULL)
261 {
262 return(STATUS_INVALID_HANDLE);
263 }
264 return(ObReferenceObjectByPointer(ObjectBody,DesiredAccess,
265 ObjectType,AccessMode));
266 }