1 /* $Id: namespc.c,v 1.46 2004/07/17 20:34:42 ekohl 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 ***************************************************************/
15 #define NTOS_MODE_KERNEL
17 #include <internal/ob.h>
18 #include <internal/io.h>
19 #include <internal/pool.h>
20 #include <internal/se.h>
21 #include <rosrtl/string.h>
24 #include <internal/debug.h>
27 /* GLOBALS ****************************************************************/
29 POBJECT_TYPE ObDirectoryType
= NULL
;
30 POBJECT_TYPE ObTypeObjectType
= NULL
;
32 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
34 static GENERIC_MAPPING ObpDirectoryMapping
= {
35 STANDARD_RIGHTS_READ
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
36 STANDARD_RIGHTS_WRITE
|DIRECTORY_CREATE_OBJECT
|DIRECTORY_CREATE_SUBDIRECTORY
,
37 STANDARD_RIGHTS_EXECUTE
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
38 DIRECTORY_ALL_ACCESS
};
40 static GENERIC_MAPPING ObpTypeMapping
= {
42 STANDARD_RIGHTS_WRITE
,
43 STANDARD_RIGHTS_EXECUTE
,
46 /* FUNCTIONS **************************************************************/
52 ObReferenceObjectByName(PUNICODE_STRING ObjectPath
,
54 PACCESS_STATE PassedAccessState
,
55 ACCESS_MASK DesiredAccess
,
56 POBJECT_TYPE ObjectType
,
57 KPROCESSOR_MODE AccessMode
,
62 UNICODE_STRING RemainingPath
;
63 OBJECT_ATTRIBUTES ObjectAttributes
;
66 InitializeObjectAttributes(&ObjectAttributes
,
71 Status
= ObFindObject(&ObjectAttributes
,
75 if (!NT_SUCCESS(Status
))
80 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath
.Buffer
, Object
);
82 if (RemainingPath
.Buffer
!= NULL
|| Object
== NULL
)
85 DPRINT("Object %p\n", Object
);
87 RtlFreeUnicodeString (&RemainingPath
);
88 return(STATUS_UNSUCCESSFUL
);
91 RtlFreeUnicodeString (&RemainingPath
);
92 return(STATUS_SUCCESS
);
96 /**********************************************************************
101 * 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
))
145 DPRINT("ObFindObject() failed (Status %lx)\n", Status
);
149 if (RemainingPath
.Buffer
!= NULL
||
152 RtlFreeUnicodeString(&RemainingPath
);
153 return STATUS_UNSUCCESSFUL
;
156 Status
= ObCreateHandle(PsGetCurrentProcess(),
162 ObDereferenceObject(Object
);
163 RtlFreeUnicodeString(&RemainingPath
);
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
);
193 ObpRemoveEntryDirectory(POBJECT_HEADER Header
)
195 * FUNCTION: Remove an entry from a namespace directory
197 * Header = Header of the object to remove
202 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header
);
204 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
205 RemoveEntryList(&(Header
->Entry
));
206 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);
211 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
215 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
216 POBJECT_HEADER current_obj
;
218 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject
, Name
);
222 return(DirectoryObject
);
224 if (Name
[0]=='.' && Name
[1]==0)
226 return(DirectoryObject
);
228 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
230 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
232 while (current
!=(&(DirectoryObject
->head
)))
234 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
235 DPRINT(" Scanning: %S for: %S\n",current_obj
->Name
.Buffer
, Name
);
236 if (Attributes
& OBJ_CASE_INSENSITIVE
)
238 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
240 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
241 return(HEADER_TO_BODY(current_obj
));
246 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
248 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
249 return(HEADER_TO_BODY(current_obj
));
252 current
= current
->Flink
;
254 DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__
);
260 ObpParseDirectory(PVOID Object
,
262 PUNICODE_STRING FullPath
,
270 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
277 return STATUS_UNSUCCESSFUL
;
284 End
= wcschr(Start
, L
'\\');
290 FoundObject
= ObpFindEntryDirectory(Object
, Start
, Attributes
);
291 if (FoundObject
== NULL
)
297 return STATUS_UNSUCCESSFUL
;
300 ObReferenceObjectByPointer(FoundObject
,
301 STANDARD_RIGHTS_REQUIRED
,
315 *NextObject
= FoundObject
;
317 return STATUS_SUCCESS
;
322 ObpCreateDirectory(PVOID ObjectBody
,
325 POBJECT_ATTRIBUTES ObjectAttributes
)
327 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
329 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
330 ObjectBody
, Parent
, RemainingPath
);
332 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
334 return(STATUS_UNSUCCESSFUL
);
337 InitializeListHead(&DirectoryObject
->head
);
338 KeInitializeSpinLock(&DirectoryObject
->Lock
);
340 return(STATUS_SUCCESS
);
347 * FUNCTION: Initialize the object manager namespace
350 OBJECT_ATTRIBUTES ObjectAttributes
;
352 SECURITY_DESCRIPTOR SecurityDescriptor
;
354 /* Initialize the security descriptor cache */
357 /* create 'directory' object type */
358 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
360 ObDirectoryType
->Tag
= TAG('D', 'I', 'R', 'T');
361 ObDirectoryType
->TotalObjects
= 0;
362 ObDirectoryType
->TotalHandles
= 0;
363 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
364 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
365 ObDirectoryType
->PagedPoolCharge
= 0;
366 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
367 ObDirectoryType
->Mapping
= &ObpDirectoryMapping
;
368 ObDirectoryType
->Dump
= NULL
;
369 ObDirectoryType
->Open
= NULL
;
370 ObDirectoryType
->Close
= NULL
;
371 ObDirectoryType
->Delete
= NULL
;
372 ObDirectoryType
->Parse
= ObpParseDirectory
;
373 ObDirectoryType
->Security
= NULL
;
374 ObDirectoryType
->QueryName
= NULL
;
375 ObDirectoryType
->OkayToClose
= NULL
;
376 ObDirectoryType
->Create
= ObpCreateDirectory
;
377 ObDirectoryType
->DuplicationNotify
= NULL
;
379 RtlRosInitUnicodeStringFromLiteral(&ObDirectoryType
->TypeName
,
382 /* create 'type' object type*/
383 ObTypeObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
385 ObTypeObjectType
->Tag
= TAG('T', 'y', 'p', 'T');
386 ObTypeObjectType
->TotalObjects
= 0;
387 ObTypeObjectType
->TotalHandles
= 0;
388 ObTypeObjectType
->MaxObjects
= ULONG_MAX
;
389 ObTypeObjectType
->MaxHandles
= ULONG_MAX
;
390 ObTypeObjectType
->PagedPoolCharge
= 0;
391 ObTypeObjectType
->NonpagedPoolCharge
= sizeof(TYPE_OBJECT
);
392 ObTypeObjectType
->Mapping
= &ObpTypeMapping
;
393 ObTypeObjectType
->Dump
= NULL
;
394 ObTypeObjectType
->Open
= NULL
;
395 ObTypeObjectType
->Close
= NULL
;
396 ObTypeObjectType
->Delete
= NULL
;
397 ObTypeObjectType
->Parse
= NULL
;
398 ObTypeObjectType
->Security
= NULL
;
399 ObTypeObjectType
->QueryName
= NULL
;
400 ObTypeObjectType
->OkayToClose
= NULL
;
401 ObTypeObjectType
->Create
= NULL
;
402 ObTypeObjectType
->DuplicationNotify
= NULL
;
404 RtlRosInitUnicodeStringFromLiteral(&ObTypeObjectType
->TypeName
,
407 /* Create security descriptor */
408 RtlCreateSecurityDescriptor(&SecurityDescriptor
,
409 SECURITY_DESCRIPTOR_REVISION1
);
411 RtlSetOwnerSecurityDescriptor(&SecurityDescriptor
,
415 RtlSetGroupSecurityDescriptor(&SecurityDescriptor
,
419 RtlSetDaclSecurityDescriptor(&SecurityDescriptor
,
424 /* Create root directory */
425 InitializeObjectAttributes(&ObjectAttributes
,
429 &SecurityDescriptor
);
430 ObCreateObject(KernelMode
,
435 sizeof(DIRECTORY_OBJECT
),
438 (PVOID
*)&NameSpaceRoot
);
440 /* Create '\ObjectTypes' directory */
441 RtlRosInitUnicodeStringFromLiteral(&Name
,
443 InitializeObjectAttributes(&ObjectAttributes
,
447 &SecurityDescriptor
);
448 ObCreateObject(KernelMode
,
453 sizeof(DIRECTORY_OBJECT
),
458 ObpCreateTypeObject(ObDirectoryType
);
459 ObpCreateTypeObject(ObTypeObjectType
);
461 /* Create 'symbolic link' object type */
462 ObInitSymbolicLinkImplementation();
467 ObpCreateTypeObject(POBJECT_TYPE ObjectType
)
469 OBJECT_ATTRIBUTES ObjectAttributes
;
470 WCHAR NameString
[120];
471 PTYPE_OBJECT TypeObject
= NULL
;
475 DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType
->TypeName
);
476 wcscpy(NameString
, L
"\\ObjectTypes\\");
477 wcscat(NameString
, ObjectType
->TypeName
.Buffer
);
478 RtlInitUnicodeString(&Name
,
481 InitializeObjectAttributes(&ObjectAttributes
,
486 Status
= ObCreateObject(KernelMode
,
494 (PVOID
*)&TypeObject
);
495 if (NT_SUCCESS(Status
))
497 TypeObject
->ObjectType
= ObjectType
;
500 return(STATUS_SUCCESS
);