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 ***************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/io.h>
18 #include <internal/pool.h>
21 #include <internal/debug.h>
23 /* GLOBALS ****************************************************************/
25 POBJECT_TYPE ObDirectoryType = NULL;
26 POBJECT_TYPE ObTypeObjectType = NULL;
28 PDIRECTORY_OBJECT NameSpaceRoot = NULL;
30 static GENERIC_MAPPING ObpDirectoryMapping = {
31 STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
32 STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY,
33 STANDARD_RIGHTS_EXECUTE|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
34 DIRECTORY_ALL_ACCESS};
36 static GENERIC_MAPPING ObpTypeMapping = {
38 STANDARD_RIGHTS_WRITE,
39 STANDARD_RIGHTS_EXECUTE,
42 /* FUNCTIONS **************************************************************/
47 ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
49 PACCESS_STATE PassedAccessState,
50 ACCESS_MASK DesiredAccess,
51 POBJECT_TYPE ObjectType,
52 KPROCESSOR_MODE AccessMode,
57 UNICODE_STRING RemainingPath;
58 OBJECT_ATTRIBUTES ObjectAttributes;
61 InitializeObjectAttributes(&ObjectAttributes,
66 Status = ObFindObject(&ObjectAttributes,
70 if (!NT_SUCCESS(Status))
75 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
77 if (RemainingPath.Buffer != NULL || Object == NULL)
80 DPRINT("Object %p\n", Object);
82 RtlFreeUnicodeString (&RemainingPath);
83 return(STATUS_UNSUCCESSFUL);
86 RtlFreeUnicodeString (&RemainingPath);
87 return(STATUS_SUCCESS);
91 /**********************************************************************
96 * Obtain a handle to an existing object.
118 ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
119 IN POBJECT_TYPE ObjectType,
120 IN OUT PVOID ParseContext,
121 IN KPROCESSOR_MODE AccessMode,
122 IN ACCESS_MASK DesiredAccess,
123 IN PACCESS_STATE PassedAccessState,
126 UNICODE_STRING RemainingPath;
130 DPRINT("ObOpenObjectByName()\n");
132 Status = ObFindObject(ObjectAttributes,
136 if (!NT_SUCCESS(Status))
141 if (RemainingPath.Buffer != NULL ||
144 RtlFreeUnicodeString(&RemainingPath);
145 return STATUS_UNSUCCESSFUL;
148 Status = ObCreateHandle(PsGetCurrentProcess(),
154 ObDereferenceObject(Object);
155 RtlFreeUnicodeString(&RemainingPath);
160 #endif /* LIBCAPTIVE */
163 ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
164 POBJECT_HEADER Header,
167 * FUNCTION: Add an entry to a namespace directory
169 * Parent = directory to add in
170 * Header = Header of the object to add the entry for
171 * Name = Name to give the entry
176 RtlCreateUnicodeString(&Header->Name, Name);
177 Header->Parent = Parent;
179 KeAcquireSpinLock(&Parent->Lock, &oldlvl);
180 InsertTailList(&Parent->head, &Header->Entry);
181 KeReleaseSpinLock(&Parent->Lock, oldlvl);
185 ObpRemoveEntryDirectory(POBJECT_HEADER Header)
187 * FUNCTION: Remove an entry from a namespace directory
189 * Header = Header of the object to remove
194 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
196 KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
197 RemoveEntryList(&(Header->Entry));
198 KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
202 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
206 PLIST_ENTRY current = DirectoryObject->head.Flink;
207 POBJECT_HEADER current_obj;
209 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
213 return(DirectoryObject);
215 if (Name[0]=='.' && Name[1]==0)
217 return(DirectoryObject);
219 if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
221 return(BODY_TO_HEADER(DirectoryObject)->Parent);
223 while (current!=(&(DirectoryObject->head)))
225 current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
226 DPRINT("Scanning %S %S\n",current_obj->Name.Buffer, Name);
227 if (Attributes & OBJ_CASE_INSENSITIVE)
229 if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
231 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
232 return(HEADER_TO_BODY(current_obj));
237 if ( wcscmp(current_obj->Name.Buffer, Name)==0)
239 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
240 return(HEADER_TO_BODY(current_obj));
243 current = current->Flink;
245 DPRINT("%s() = NULL\n",__FUNCTION__);
250 ObpParseDirectory(PVOID Object,
252 PUNICODE_STRING FullPath,
259 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
266 return STATUS_UNSUCCESSFUL;
269 end = wcschr((*Path)+1, '\\');
275 FoundObject = ObpFindEntryDirectory(Object, (*Path)+1, Attributes);
277 if (FoundObject == NULL)
283 return STATUS_UNSUCCESSFUL;
286 ObReferenceObjectByPointer(FoundObject,
287 STANDARD_RIGHTS_REQUIRED,
301 *NextObject = FoundObject;
303 return STATUS_SUCCESS;
307 ObpCreateDirectory(PVOID ObjectBody,
310 POBJECT_ATTRIBUTES ObjectAttributes)
312 PDIRECTORY_OBJECT DirectoryObject = (PDIRECTORY_OBJECT)ObjectBody;
314 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
315 ObjectBody, Parent, RemainingPath);
317 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
319 return(STATUS_UNSUCCESSFUL);
322 InitializeListHead(&DirectoryObject->head);
323 KeInitializeSpinLock(&DirectoryObject->Lock);
325 return(STATUS_SUCCESS);
332 * FUNCTION: Initialize the object manager namespace
335 OBJECT_ATTRIBUTES ObjectAttributes;
338 /* create 'directory' object type */
339 ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
341 ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
342 ObDirectoryType->TotalObjects = 0;
343 ObDirectoryType->TotalHandles = 0;
344 ObDirectoryType->MaxObjects = ULONG_MAX;
345 ObDirectoryType->MaxHandles = ULONG_MAX;
346 ObDirectoryType->PagedPoolCharge = 0;
347 ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
348 ObDirectoryType->Mapping = &ObpDirectoryMapping;
349 ObDirectoryType->Dump = NULL;
350 ObDirectoryType->Open = NULL;
351 ObDirectoryType->Close = NULL;
352 ObDirectoryType->Delete = NULL;
353 ObDirectoryType->Parse = ObpParseDirectory;
354 ObDirectoryType->Security = NULL;
355 ObDirectoryType->QueryName = NULL;
356 ObDirectoryType->OkayToClose = NULL;
357 ObDirectoryType->Create = ObpCreateDirectory;
358 ObDirectoryType->DuplicationNotify = NULL;
360 RtlInitUnicodeStringFromLiteral(&ObDirectoryType->TypeName,
361 REACTOS_UCS2(L"Directory"));
363 /* create 'type' object type*/
364 ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
366 ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T');
367 ObTypeObjectType->TotalObjects = 0;
368 ObTypeObjectType->TotalHandles = 0;
369 ObTypeObjectType->MaxObjects = ULONG_MAX;
370 ObTypeObjectType->MaxHandles = ULONG_MAX;
371 ObTypeObjectType->PagedPoolCharge = 0;
372 ObTypeObjectType->NonpagedPoolCharge = sizeof(TYPE_OBJECT);
373 ObTypeObjectType->Mapping = &ObpTypeMapping;
374 ObTypeObjectType->Dump = NULL;
375 ObTypeObjectType->Open = NULL;
376 ObTypeObjectType->Close = NULL;
377 ObTypeObjectType->Delete = NULL;
378 ObTypeObjectType->Parse = NULL;
379 ObTypeObjectType->Security = NULL;
380 ObTypeObjectType->QueryName = NULL;
381 ObTypeObjectType->OkayToClose = NULL;
382 ObTypeObjectType->Create = NULL;
383 ObTypeObjectType->DuplicationNotify = NULL;
385 RtlInitUnicodeStringFromLiteral(&ObTypeObjectType->TypeName,
386 REACTOS_UCS2(L"ObjectType"));
388 /* create root directory */
390 STANDARD_RIGHTS_REQUIRED,
393 (PVOID*)&NameSpaceRoot);
395 /* create '\ObjectTypes' directory */
396 RtlInitUnicodeStringFromLiteral(&Name,
397 REACTOS_UCS2(L"\\ObjectTypes"));
398 InitializeObjectAttributes(&ObjectAttributes,
404 STANDARD_RIGHTS_REQUIRED,
409 ObpCreateTypeObject(ObDirectoryType);
410 ObpCreateTypeObject(ObTypeObjectType);
415 ObpCreateTypeObject(POBJECT_TYPE ObjectType)
417 OBJECT_ATTRIBUTES ObjectAttributes;
418 WCHAR NameString[120];
419 PTYPE_OBJECT TypeObject = NULL;
423 DPRINT("ObjectType: %wZ\n", &ObjectType->TypeName);
424 wcscpy(NameString, REACTOS_UCS2(L"\\ObjectTypes\\"));
425 wcscat(NameString, ObjectType->TypeName.Buffer);
426 RtlInitUnicodeString(&Name,
429 InitializeObjectAttributes(&ObjectAttributes,
434 Status = ObCreateObject(NULL,
435 STANDARD_RIGHTS_REQUIRED,
438 (PVOID*)&TypeObject);
439 if (NT_SUCCESS(Status))
441 TypeObject->ObjectType = ObjectType;
444 return(STATUS_SUCCESS);