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 ***************************************************************/
19 #include <ddk/ntddk.h>
20 #include <internal/ob.h>
21 #include <internal/io.h>
22 #include <internal/pool.h>
25 #include <internal/debug.h>
29 /* GLOBALS ****************************************************************/
31 POBJECT_TYPE ObDirectoryType = NULL;
32 POBJECT_TYPE ObTypeObjectType = NULL;
34 PDIRECTORY_OBJECT NameSpaceRoot = NULL;
36 static GENERIC_MAPPING ObpDirectoryMapping = {
37 STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
38 STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY,
39 STANDARD_RIGHTS_EXECUTE|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
40 DIRECTORY_ALL_ACCESS};
42 static GENERIC_MAPPING ObpTypeMapping = {
44 STANDARD_RIGHTS_WRITE,
45 STANDARD_RIGHTS_EXECUTE,
48 /* FUNCTIONS **************************************************************/
54 ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
56 PACCESS_STATE PassedAccessState,
57 ACCESS_MASK DesiredAccess,
58 POBJECT_TYPE ObjectType,
59 KPROCESSOR_MODE AccessMode,
64 UNICODE_STRING RemainingPath;
65 OBJECT_ATTRIBUTES ObjectAttributes;
68 InitializeObjectAttributes(&ObjectAttributes,
73 Status = ObFindObject(&ObjectAttributes,
77 if (!NT_SUCCESS(Status))
82 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
84 if (RemainingPath.Buffer != NULL || Object == NULL)
87 DPRINT("Object %p\n", Object);
89 RtlFreeUnicodeString (&RemainingPath);
90 return(STATUS_UNSUCCESSFUL);
93 RtlFreeUnicodeString (&RemainingPath);
94 return(STATUS_SUCCESS);
96 #endif // WIN32_REGDBG
98 /**********************************************************************
103 * Obtain a handle to an existing object.
125 ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
126 IN POBJECT_TYPE ObjectType,
127 IN OUT PVOID ParseContext,
128 IN KPROCESSOR_MODE AccessMode,
129 IN ACCESS_MASK DesiredAccess,
130 IN PACCESS_STATE PassedAccessState,
133 UNICODE_STRING RemainingPath;
137 DPRINT("ObOpenObjectByName(...)\n");
139 Status = ObFindObject(ObjectAttributes,
143 if (!NT_SUCCESS(Status))
148 if (RemainingPath.Buffer != NULL ||
151 RtlFreeUnicodeString(&RemainingPath);
152 return STATUS_UNSUCCESSFUL;
155 Status = ObCreateHandle(PsGetCurrentProcess(),
161 ObDereferenceObject(Object);
162 RtlFreeUnicodeString(&RemainingPath);
167 #endif /* LIBCAPTIVE */
170 ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
171 POBJECT_HEADER Header,
174 * FUNCTION: Add an entry to a namespace directory
176 * Parent = directory to add in
177 * Header = Header of the object to add the entry for
178 * Name = Name to give the entry
183 RtlCreateUnicodeString(&Header->Name, Name);
184 Header->Parent = Parent;
186 KeAcquireSpinLock(&Parent->Lock, &oldlvl);
187 InsertTailList(&Parent->head, &Header->Entry);
188 KeReleaseSpinLock(&Parent->Lock, oldlvl);
192 ObpRemoveEntryDirectory(POBJECT_HEADER Header)
194 * FUNCTION: Remove an entry from a namespace directory
196 * Header = Header of the object to remove
201 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
203 KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
204 RemoveEntryList(&(Header->Entry));
205 KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
209 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
213 PLIST_ENTRY current = DirectoryObject->head.Flink;
214 POBJECT_HEADER current_obj;
216 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
220 return(DirectoryObject);
222 if (Name[0]=='.' && Name[1]==0)
224 return(DirectoryObject);
226 if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
228 return(BODY_TO_HEADER(DirectoryObject)->Parent);
230 while (current!=(&(DirectoryObject->head)))
232 current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
233 DPRINT(" Scanning: %S for: %S\n",current_obj->Name.Buffer, Name);
234 if (Attributes & OBJ_CASE_INSENSITIVE)
236 if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
238 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
239 return(HEADER_TO_BODY(current_obj));
244 if ( wcscmp(current_obj->Name.Buffer, Name)==0)
246 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
247 return(HEADER_TO_BODY(current_obj));
250 current = current->Flink;
252 DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__);
257 ObpParseDirectory(PVOID Object,
259 PUNICODE_STRING FullPath,
266 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
273 return STATUS_UNSUCCESSFUL;
276 end = wcschr((*Path)+1, '\\');
282 FoundObject = ObpFindEntryDirectory(Object, (*Path)+1, Attributes);
284 if (FoundObject == NULL)
290 return STATUS_UNSUCCESSFUL;
293 ObReferenceObjectByPointer(FoundObject,
294 STANDARD_RIGHTS_REQUIRED,
308 *NextObject = FoundObject;
310 return STATUS_SUCCESS;
314 ObpCreateDirectory(PVOID ObjectBody,
317 POBJECT_ATTRIBUTES ObjectAttributes)
319 PDIRECTORY_OBJECT DirectoryObject = (PDIRECTORY_OBJECT)ObjectBody;
321 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
322 ObjectBody, Parent, RemainingPath);
324 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
326 return(STATUS_UNSUCCESSFUL);
329 InitializeListHead(&DirectoryObject->head);
330 KeInitializeSpinLock(&DirectoryObject->Lock);
332 return(STATUS_SUCCESS);
339 * FUNCTION: Initialize the object manager namespace
342 OBJECT_ATTRIBUTES ObjectAttributes;
345 /* create 'directory' object type */
346 ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
348 ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
349 ObDirectoryType->TotalObjects = 0;
350 ObDirectoryType->TotalHandles = 0;
351 ObDirectoryType->MaxObjects = ULONG_MAX;
352 ObDirectoryType->MaxHandles = ULONG_MAX;
353 ObDirectoryType->PagedPoolCharge = 0;
354 ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
355 ObDirectoryType->Mapping = &ObpDirectoryMapping;
356 ObDirectoryType->Dump = NULL;
357 ObDirectoryType->Open = NULL;
358 ObDirectoryType->Close = NULL;
359 ObDirectoryType->Delete = NULL;
360 ObDirectoryType->Parse = ObpParseDirectory;
361 ObDirectoryType->Security = NULL;
362 ObDirectoryType->QueryName = NULL;
363 ObDirectoryType->OkayToClose = NULL;
364 ObDirectoryType->Create = ObpCreateDirectory;
365 ObDirectoryType->DuplicationNotify = NULL;
367 RtlInitUnicodeStringFromLiteral(&ObDirectoryType->TypeName,
368 REACTOS_UCS2(L"Directory"));
370 /* create 'type' object type*/
371 ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
373 ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T');
374 ObTypeObjectType->TotalObjects = 0;
375 ObTypeObjectType->TotalHandles = 0;
376 ObTypeObjectType->MaxObjects = ULONG_MAX;
377 ObTypeObjectType->MaxHandles = ULONG_MAX;
378 ObTypeObjectType->PagedPoolCharge = 0;
379 ObTypeObjectType->NonpagedPoolCharge = sizeof(TYPE_OBJECT);
380 ObTypeObjectType->Mapping = &ObpTypeMapping;
381 ObTypeObjectType->Dump = NULL;
382 ObTypeObjectType->Open = NULL;
383 ObTypeObjectType->Close = NULL;
384 ObTypeObjectType->Delete = NULL;
385 ObTypeObjectType->Parse = NULL;
386 ObTypeObjectType->Security = NULL;
387 ObTypeObjectType->QueryName = NULL;
388 ObTypeObjectType->OkayToClose = NULL;
389 ObTypeObjectType->Create = NULL;
390 ObTypeObjectType->DuplicationNotify = NULL;
392 RtlInitUnicodeStringFromLiteral(&ObTypeObjectType->TypeName,
393 REACTOS_UCS2(L"ObjectType"));
395 /* create root directory */
397 STANDARD_RIGHTS_REQUIRED,
400 (PVOID*)&NameSpaceRoot);
402 /* create '\ObjectTypes' directory */
403 RtlInitUnicodeStringFromLiteral(&Name,
404 REACTOS_UCS2(L"\\ObjectTypes"));
405 InitializeObjectAttributes(&ObjectAttributes,
411 STANDARD_RIGHTS_REQUIRED,
416 ObpCreateTypeObject(ObDirectoryType);
417 ObpCreateTypeObject(ObTypeObjectType);
422 ObpCreateTypeObject(POBJECT_TYPE ObjectType)
424 OBJECT_ATTRIBUTES ObjectAttributes;
425 WCHAR NameString[120];
426 PTYPE_OBJECT TypeObject = NULL;
430 DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType->TypeName);
431 wcscpy(NameString, REACTOS_UCS2(L"\\ObjectTypes\\"));
432 wcscat(NameString, ObjectType->TypeName.Buffer);
433 RtlInitUnicodeString(&Name,
436 InitializeObjectAttributes(&ObjectAttributes,
441 Status = ObCreateObject(NULL,
442 STANDARD_RIGHTS_REQUIRED,
445 (PVOID*)&TypeObject);
446 if (NT_SUCCESS(Status))
448 TypeObject->ObjectType = ObjectType;
451 return(STATUS_SUCCESS);