1 /* $Id: namespc.c,v 1.38 2003/06/07 12:23:14 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 ***************************************************************/
15 #define NTOS_MODE_KERNEL
17 #include <internal/ob.h>
18 #include <internal/io.h>
19 #include <internal/pool.h>
22 #include <internal/debug.h>
25 /* GLOBALS ****************************************************************/
27 POBJECT_TYPE ObDirectoryType
= NULL
;
28 POBJECT_TYPE ObTypeObjectType
= NULL
;
30 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
32 static GENERIC_MAPPING ObpDirectoryMapping
= {
33 STANDARD_RIGHTS_READ
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
34 STANDARD_RIGHTS_WRITE
|DIRECTORY_CREATE_OBJECT
|DIRECTORY_CREATE_SUBDIRECTORY
,
35 STANDARD_RIGHTS_EXECUTE
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
36 DIRECTORY_ALL_ACCESS
};
38 static GENERIC_MAPPING ObpTypeMapping
= {
40 STANDARD_RIGHTS_WRITE
,
41 STANDARD_RIGHTS_EXECUTE
,
44 /* 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
))
138 DPRINT("ObFindObject() failed (Status %lx)\n", Status
);
142 if (RemainingPath
.Buffer
!= NULL
||
145 RtlFreeUnicodeString(&RemainingPath
);
146 return STATUS_UNSUCCESSFUL
;
149 Status
= ObCreateHandle(PsGetCurrentProcess(),
155 ObDereferenceObject(Object
);
156 RtlFreeUnicodeString(&RemainingPath
);
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
);
186 ObpRemoveEntryDirectory(POBJECT_HEADER Header
)
188 * FUNCTION: Remove an entry from a namespace directory
190 * Header = Header of the object to remove
195 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header
);
197 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
198 RemoveEntryList(&(Header
->Entry
));
199 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);
204 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
208 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
209 POBJECT_HEADER current_obj
;
211 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject
, Name
);
215 return(DirectoryObject
);
217 if (Name
[0]=='.' && Name
[1]==0)
219 return(DirectoryObject
);
221 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
223 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
225 while (current
!=(&(DirectoryObject
->head
)))
227 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
228 DPRINT(" Scanning: %S for: %S\n",current_obj
->Name
.Buffer
, Name
);
229 if (Attributes
& OBJ_CASE_INSENSITIVE
)
231 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
233 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
234 return(HEADER_TO_BODY(current_obj
));
239 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
241 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
242 return(HEADER_TO_BODY(current_obj
));
245 current
= current
->Flink
;
247 DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__
);
253 ObpParseDirectory(PVOID Object
,
255 PUNICODE_STRING FullPath
,
263 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
270 return STATUS_UNSUCCESSFUL
;
277 End
= wcschr(Start
, L
'\\');
283 FoundObject
= ObpFindEntryDirectory(Object
, Start
, Attributes
);
284 if (FoundObject
== NULL
)
290 return STATUS_UNSUCCESSFUL
;
293 ObReferenceObjectByPointer(FoundObject
,
294 STANDARD_RIGHTS_REQUIRED
,
308 *NextObject
= FoundObject
;
310 return STATUS_SUCCESS
;
315 ObpCreateDirectory(PVOID ObjectBody
,
318 POBJECT_ATTRIBUTES ObjectAttributes
)
320 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
322 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
323 ObjectBody
, Parent
, RemainingPath
);
325 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
327 return(STATUS_UNSUCCESSFUL
);
330 InitializeListHead(&DirectoryObject
->head
);
331 KeInitializeSpinLock(&DirectoryObject
->Lock
);
333 return(STATUS_SUCCESS
);
340 * FUNCTION: Initialize the object manager namespace
343 OBJECT_ATTRIBUTES ObjectAttributes
;
346 /* create 'directory' object type */
347 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
349 ObDirectoryType
->Tag
= TAG('D', 'I', 'R', 'T');
350 ObDirectoryType
->TotalObjects
= 0;
351 ObDirectoryType
->TotalHandles
= 0;
352 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
353 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
354 ObDirectoryType
->PagedPoolCharge
= 0;
355 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
356 ObDirectoryType
->Mapping
= &ObpDirectoryMapping
;
357 ObDirectoryType
->Dump
= NULL
;
358 ObDirectoryType
->Open
= NULL
;
359 ObDirectoryType
->Close
= NULL
;
360 ObDirectoryType
->Delete
= NULL
;
361 ObDirectoryType
->Parse
= ObpParseDirectory
;
362 ObDirectoryType
->Security
= NULL
;
363 ObDirectoryType
->QueryName
= NULL
;
364 ObDirectoryType
->OkayToClose
= NULL
;
365 ObDirectoryType
->Create
= ObpCreateDirectory
;
366 ObDirectoryType
->DuplicationNotify
= NULL
;
368 RtlInitUnicodeStringFromLiteral(&ObDirectoryType
->TypeName
,
371 /* create 'type' object type*/
372 ObTypeObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
374 ObTypeObjectType
->Tag
= TAG('T', 'y', 'p', 'T');
375 ObTypeObjectType
->TotalObjects
= 0;
376 ObTypeObjectType
->TotalHandles
= 0;
377 ObTypeObjectType
->MaxObjects
= ULONG_MAX
;
378 ObTypeObjectType
->MaxHandles
= ULONG_MAX
;
379 ObTypeObjectType
->PagedPoolCharge
= 0;
380 ObTypeObjectType
->NonpagedPoolCharge
= sizeof(TYPE_OBJECT
);
381 ObTypeObjectType
->Mapping
= &ObpTypeMapping
;
382 ObTypeObjectType
->Dump
= NULL
;
383 ObTypeObjectType
->Open
= NULL
;
384 ObTypeObjectType
->Close
= NULL
;
385 ObTypeObjectType
->Delete
= NULL
;
386 ObTypeObjectType
->Parse
= NULL
;
387 ObTypeObjectType
->Security
= NULL
;
388 ObTypeObjectType
->QueryName
= NULL
;
389 ObTypeObjectType
->OkayToClose
= NULL
;
390 ObTypeObjectType
->Create
= NULL
;
391 ObTypeObjectType
->DuplicationNotify
= NULL
;
393 RtlInitUnicodeStringFromLiteral(&ObTypeObjectType
->TypeName
,
396 /* create root directory */
397 ObRosCreateObject(NULL
,
398 STANDARD_RIGHTS_REQUIRED
,
401 (PVOID
*)&NameSpaceRoot
);
403 /* create '\ObjectTypes' directory */
404 RtlInitUnicodeStringFromLiteral(&Name
,
406 InitializeObjectAttributes(&ObjectAttributes
,
411 ObRosCreateObject(NULL
,
412 STANDARD_RIGHTS_REQUIRED
,
417 ObpCreateTypeObject(ObDirectoryType
);
418 ObpCreateTypeObject(ObTypeObjectType
);
420 /* Create 'symbolic link' object type */
421 ObInitSymbolicLinkImplementation();
426 ObpCreateTypeObject(POBJECT_TYPE ObjectType
)
428 OBJECT_ATTRIBUTES ObjectAttributes
;
429 WCHAR NameString
[120];
430 PTYPE_OBJECT TypeObject
= NULL
;
434 DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType
->TypeName
);
435 wcscpy(NameString
, L
"\\ObjectTypes\\");
436 wcscat(NameString
, ObjectType
->TypeName
.Buffer
);
437 RtlInitUnicodeString(&Name
,
440 InitializeObjectAttributes(&ObjectAttributes
,
445 Status
= ObRosCreateObject(NULL
,
446 STANDARD_RIGHTS_REQUIRED
,
449 (PVOID
*)&TypeObject
);
450 if (NT_SUCCESS(Status
))
452 TypeObject
->ObjectType
= ObjectType
;
455 return(STATUS_SUCCESS
);