1 /* $Id: namespc.c,v 1.28 2002/02/19 00:09:24 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 #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
;
27 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
29 static GENERIC_MAPPING ObpDirectoryMapping
= {
30 STANDARD_RIGHTS_READ
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
31 STANDARD_RIGHTS_WRITE
|DIRECTORY_CREATE_OBJECT
|DIRECTORY_CREATE_SUBDIRECTORY
,
32 STANDARD_RIGHTS_EXECUTE
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
33 DIRECTORY_ALL_ACCESS
};
35 /* FUNCTIONS **************************************************************/
38 ObReferenceObjectByName(PUNICODE_STRING ObjectPath
,
40 PACCESS_STATE PassedAccessState
,
41 ACCESS_MASK DesiredAccess
,
42 POBJECT_TYPE ObjectType
,
43 KPROCESSOR_MODE AccessMode
,
48 UNICODE_STRING RemainingPath
;
49 OBJECT_ATTRIBUTES ObjectAttributes
;
52 InitializeObjectAttributes(&ObjectAttributes
,
57 Status
= ObFindObject(&ObjectAttributes
,
61 if (!NT_SUCCESS(Status
))
66 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath
.Buffer
, Object
);
68 if (RemainingPath
.Buffer
!= NULL
|| Object
== NULL
)
71 DPRINT("Object %p\n", Object
);
73 RtlFreeUnicodeString (&RemainingPath
);
74 return(STATUS_UNSUCCESSFUL
);
77 RtlFreeUnicodeString (&RemainingPath
);
78 return(STATUS_SUCCESS
);
82 /**********************************************************************
87 * Obtain a handle to an existing object.
109 ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes
,
110 POBJECT_TYPE ObjectType
,
112 KPROCESSOR_MODE AccessMode
,
113 ACCESS_MASK DesiredAccess
,
114 PACCESS_STATE PassedAccessState
,
117 UNICODE_STRING RemainingPath
;
121 DPRINT("ObOpenObjectByName()\n");
123 Status
= ObFindObject(ObjectAttributes
,
127 if (!NT_SUCCESS(Status
))
132 if (RemainingPath
.Buffer
!= NULL
||
135 RtlFreeUnicodeString(&RemainingPath
);
136 return STATUS_UNSUCCESSFUL
;
139 Status
= ObCreateHandle(PsGetCurrentProcess(),
145 ObDereferenceObject(Object
);
146 RtlFreeUnicodeString(&RemainingPath
);
153 ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent
,
154 POBJECT_HEADER Header
,
157 * FUNCTION: Add an entry to a namespace directory
159 * Parent = directory to add in
160 * Header = Header of the object to add the entry for
161 * Name = Name to give the entry
166 RtlCreateUnicodeString(&Header
->Name
, Name
);
167 Header
->Parent
= Parent
;
169 KeAcquireSpinLock(&Parent
->Lock
, &oldlvl
);
170 InsertTailList(&Parent
->head
, &Header
->Entry
);
171 KeReleaseSpinLock(&Parent
->Lock
, oldlvl
);
175 ObpRemoveEntryDirectory(POBJECT_HEADER Header
)
177 * FUNCTION: Remove an entry from a namespace directory
179 * Header = Header of the object to remove
184 DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header
);
186 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
187 RemoveEntryList(&(Header
->Entry
));
188 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);
192 ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
196 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
197 POBJECT_HEADER current_obj
;
199 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject
, Name
);
203 return(DirectoryObject
);
205 if (Name
[0]=='.' && Name
[1]==0)
207 return(DirectoryObject
);
209 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
211 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
213 while (current
!=(&(DirectoryObject
->head
)))
215 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
216 DPRINT("Scanning %S %S\n",current_obj
->Name
.Buffer
, Name
);
217 if (Attributes
& OBJ_CASE_INSENSITIVE
)
219 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
221 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
222 return(HEADER_TO_BODY(current_obj
));
227 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
229 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
230 return(HEADER_TO_BODY(current_obj
));
233 current
= current
->Flink
;
235 DPRINT("%s() = NULL\n",__FUNCTION__
);
240 ObpParseDirectory(PVOID Object
,
242 PUNICODE_STRING FullPath
,
244 POBJECT_TYPE ObjectType
,
250 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
257 return STATUS_UNSUCCESSFUL
;
260 end
= wcschr((*Path
)+1, '\\');
266 FoundObject
= ObpFindEntryDirectory(Object
, (*Path
)+1, Attributes
);
268 if (FoundObject
== NULL
)
274 return STATUS_UNSUCCESSFUL
;
277 ObReferenceObjectByPointer(FoundObject
,
278 STANDARD_RIGHTS_REQUIRED
,
292 *NextObject
= FoundObject
;
294 return STATUS_SUCCESS
;
298 ObpCreateDirectory(PVOID ObjectBody
,
301 POBJECT_ATTRIBUTES ObjectAttributes
)
303 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
305 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
306 ObjectBody
, Parent
, RemainingPath
);
308 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
310 return(STATUS_UNSUCCESSFUL
);
313 InitializeListHead(&DirectoryObject
->head
);
314 KeInitializeSpinLock(&DirectoryObject
->Lock
);
316 return(STATUS_SUCCESS
);
321 * FUNCTION: Initialize the object manager namespace
324 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
326 ObDirectoryType
->Tag
= TAG('D', 'I', 'R', 'T');
327 ObDirectoryType
->TotalObjects
= 0;
328 ObDirectoryType
->TotalHandles
= 0;
329 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
330 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
331 ObDirectoryType
->PagedPoolCharge
= 0;
332 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
333 ObDirectoryType
->Mapping
= &ObpDirectoryMapping
;
334 ObDirectoryType
->Dump
= NULL
;
335 ObDirectoryType
->Open
= NULL
;
336 ObDirectoryType
->Close
= NULL
;
337 ObDirectoryType
->Delete
= NULL
;
338 ObDirectoryType
->Parse
= ObpParseDirectory
;
339 ObDirectoryType
->Security
= NULL
;
340 ObDirectoryType
->QueryName
= NULL
;
341 ObDirectoryType
->OkayToClose
= NULL
;
342 ObDirectoryType
->Create
= ObpCreateDirectory
;
343 ObDirectoryType
->DuplicationNotify
= NULL
;
345 RtlInitUnicodeString(&ObDirectoryType
->TypeName
,
349 STANDARD_RIGHTS_REQUIRED
,
352 (PVOID
*)&NameSpaceRoot
);