1 /* $Id: namespc.c,v 1.33 2002/09/07 15:13:04 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/namespc.c
6 * PURPOSE: Manages the system namespace
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES ***************************************************************/
17 #include <internal/debug.h>
20 /* GLOBALS ****************************************************************/
22 POBJECT_TYPE ObDirectoryType
= NULL
;
23 POBJECT_TYPE ObTypeObjectType
= NULL
;
25 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
27 static GENERIC_MAPPING ObpDirectoryMapping
= {
28 STANDARD_RIGHTS_READ
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
29 STANDARD_RIGHTS_WRITE
|DIRECTORY_CREATE_OBJECT
|DIRECTORY_CREATE_SUBDIRECTORY
,
30 STANDARD_RIGHTS_EXECUTE
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
31 DIRECTORY_ALL_ACCESS
};
33 static GENERIC_MAPPING ObpTypeMapping
= {
35 STANDARD_RIGHTS_WRITE
,
36 STANDARD_RIGHTS_EXECUTE
,
39 /* FUNCTIONS **************************************************************/
42 ObReferenceObjectByName(PUNICODE_STRING ObjectPath
,
44 PACCESS_STATE PassedAccessState
,
45 ACCESS_MASK DesiredAccess
,
46 POBJECT_TYPE ObjectType
,
47 KPROCESSOR_MODE AccessMode
,
52 UNICODE_STRING RemainingPath
;
53 OBJECT_ATTRIBUTES ObjectAttributes
;
56 InitializeObjectAttributes(&ObjectAttributes
,
61 Status
= ObFindObject(&ObjectAttributes
,
65 if (!NT_SUCCESS(Status
))
70 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath
.Buffer
, Object
);
72 if (RemainingPath
.Buffer
!= NULL
|| Object
== NULL
)
75 DPRINT("Object %p\n", Object
);
77 RtlFreeUnicodeString (&RemainingPath
);
78 return(STATUS_UNSUCCESSFUL
);
81 RtlFreeUnicodeString (&RemainingPath
);
82 return(STATUS_SUCCESS
);
86 /**********************************************************************
91 * Obtain a handle to an existing object.
113 ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes
,
114 IN POBJECT_TYPE ObjectType
,
115 IN OUT PVOID ParseContext
,
116 IN KPROCESSOR_MODE AccessMode
,
117 IN ACCESS_MASK DesiredAccess
,
118 IN PACCESS_STATE PassedAccessState
,
121 UNICODE_STRING RemainingPath
;
125 DPRINT("ObOpenObjectByName()\n");
127 Status
= ObFindObject(ObjectAttributes
,
131 if (!NT_SUCCESS(Status
))
136 if (RemainingPath
.Buffer
!= NULL
||
139 RtlFreeUnicodeString(&RemainingPath
);
140 return STATUS_UNSUCCESSFUL
;
143 Status
= ObCreateHandle(PsGetCurrentProcess(),
149 ObDereferenceObject(Object
);
150 RtlFreeUnicodeString(&RemainingPath
);
157 ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent
,
158 POBJECT_HEADER Header
,
161 * FUNCTION: Add an entry to a namespace directory
163 * Parent = directory to add in
164 * Header = Header of the object to add the entry for
165 * Name = Name to give the entry
170 RtlCreateUnicodeString(&Header
->Name
, Name
);
171 Header
->Parent
= Parent
;
173 KeAcquireSpinLock(&Parent
->Lock
, &oldlvl
);
174 InsertTailList(&Parent
->head
, &Header
->Entry
);
175 KeReleaseSpinLock(&Parent
->Lock
, oldlvl
);
179 ObpRemoveEntryDirectory(POBJECT_HEADER Header
)
181 * FUNCTION: Remove an entry from a namespace directory
183 * Header = Header of the object to remove
188 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header
);
190 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
191 RemoveEntryList(&(Header
->Entry
));
192 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);
196 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
200 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
201 POBJECT_HEADER current_obj
;
203 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject
, Name
);
207 return(DirectoryObject
);
209 if (Name
[0]=='.' && Name
[1]==0)
211 return(DirectoryObject
);
213 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
215 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
217 while (current
!=(&(DirectoryObject
->head
)))
219 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
220 DPRINT("Scanning %S %S\n",current_obj
->Name
.Buffer
, Name
);
221 if (Attributes
& OBJ_CASE_INSENSITIVE
)
223 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
225 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
226 return(HEADER_TO_BODY(current_obj
));
231 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
233 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
234 return(HEADER_TO_BODY(current_obj
));
237 current
= current
->Flink
;
239 DPRINT("%s() = NULL\n",__FUNCTION__
);
244 ObpParseDirectory(PVOID Object
,
246 PUNICODE_STRING FullPath
,
253 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
260 return STATUS_UNSUCCESSFUL
;
263 end
= wcschr((*Path
)+1, '\\');
269 FoundObject
= ObpFindEntryDirectory(Object
, (*Path
)+1, Attributes
);
271 if (FoundObject
== NULL
)
277 return STATUS_UNSUCCESSFUL
;
280 ObReferenceObjectByPointer(FoundObject
,
281 STANDARD_RIGHTS_REQUIRED
,
295 *NextObject
= FoundObject
;
297 return STATUS_SUCCESS
;
301 ObpCreateDirectory(PVOID ObjectBody
,
304 POBJECT_ATTRIBUTES ObjectAttributes
)
306 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
308 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
309 ObjectBody
, Parent
, RemainingPath
);
311 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
313 return(STATUS_UNSUCCESSFUL
);
316 InitializeListHead(&DirectoryObject
->head
);
317 KeInitializeSpinLock(&DirectoryObject
->Lock
);
319 return(STATUS_SUCCESS
);
326 * FUNCTION: Initialize the object manager namespace
329 OBJECT_ATTRIBUTES ObjectAttributes
;
332 /* create 'directory' object type */
333 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
335 ObDirectoryType
->Tag
= TAG('D', 'I', 'R', 'T');
336 ObDirectoryType
->TotalObjects
= 0;
337 ObDirectoryType
->TotalHandles
= 0;
338 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
339 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
340 ObDirectoryType
->PagedPoolCharge
= 0;
341 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
342 ObDirectoryType
->Mapping
= &ObpDirectoryMapping
;
343 ObDirectoryType
->Dump
= NULL
;
344 ObDirectoryType
->Open
= NULL
;
345 ObDirectoryType
->Close
= NULL
;
346 ObDirectoryType
->Delete
= NULL
;
347 ObDirectoryType
->Parse
= ObpParseDirectory
;
348 ObDirectoryType
->Security
= NULL
;
349 ObDirectoryType
->QueryName
= NULL
;
350 ObDirectoryType
->OkayToClose
= NULL
;
351 ObDirectoryType
->Create
= ObpCreateDirectory
;
352 ObDirectoryType
->DuplicationNotify
= NULL
;
354 RtlInitUnicodeStringFromLiteral(&ObDirectoryType
->TypeName
,
357 /* create 'type' object type*/
358 ObTypeObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
360 ObTypeObjectType
->Tag
= TAG('T', 'y', 'p', 'T');
361 ObTypeObjectType
->TotalObjects
= 0;
362 ObTypeObjectType
->TotalHandles
= 0;
363 ObTypeObjectType
->MaxObjects
= ULONG_MAX
;
364 ObTypeObjectType
->MaxHandles
= ULONG_MAX
;
365 ObTypeObjectType
->PagedPoolCharge
= 0;
366 ObTypeObjectType
->NonpagedPoolCharge
= sizeof(TYPE_OBJECT
);
367 ObTypeObjectType
->Mapping
= &ObpTypeMapping
;
368 ObTypeObjectType
->Dump
= NULL
;
369 ObTypeObjectType
->Open
= NULL
;
370 ObTypeObjectType
->Close
= NULL
;
371 ObTypeObjectType
->Delete
= NULL
;
372 ObTypeObjectType
->Parse
= NULL
;
373 ObTypeObjectType
->Security
= NULL
;
374 ObTypeObjectType
->QueryName
= NULL
;
375 ObTypeObjectType
->OkayToClose
= NULL
;
376 ObTypeObjectType
->Create
= NULL
;
377 ObTypeObjectType
->DuplicationNotify
= NULL
;
379 RtlInitUnicodeStringFromLiteral(&ObTypeObjectType
->TypeName
,
382 /* create root directory */
383 ObRosCreateObject(NULL
,
384 STANDARD_RIGHTS_REQUIRED
,
387 (PVOID
*)&NameSpaceRoot
);
389 /* create '\ObjectTypes' directory */
390 RtlInitUnicodeStringFromLiteral(&Name
,
392 InitializeObjectAttributes(&ObjectAttributes
,
397 ObRosCreateObject(NULL
,
398 STANDARD_RIGHTS_REQUIRED
,
403 ObpCreateTypeObject(ObDirectoryType
);
404 ObpCreateTypeObject(ObTypeObjectType
);
409 ObpCreateTypeObject(POBJECT_TYPE ObjectType
)
411 OBJECT_ATTRIBUTES ObjectAttributes
;
412 WCHAR NameString
[120];
413 PTYPE_OBJECT TypeObject
= NULL
;
417 DPRINT("ObjectType: %wZ\n", &ObjectType
->TypeName
);
418 wcscpy(NameString
, L
"\\ObjectTypes\\");
419 wcscat(NameString
, ObjectType
->TypeName
.Buffer
);
420 RtlInitUnicodeString(&Name
,
423 InitializeObjectAttributes(&ObjectAttributes
,
428 Status
= ObRosCreateObject(NULL
,
429 STANDARD_RIGHTS_REQUIRED
,
432 (PVOID
*)&TypeObject
);
433 if (NT_SUCCESS(Status
))
435 TypeObject
->ObjectType
= ObjectType
;
438 return(STATUS_SUCCESS
);