2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ob/namespc.c
5 * PURPOSE: Manages the system namespace
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES ***************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
19 #include <internal/debug.h>
21 /* GLOBALS ****************************************************************/
23 POBJECT_TYPE ObDirectoryType
= NULL
;
25 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
27 static GENERIC_MAPPING ObpDirectoryMapping
= {
28 STANDARD_RIGHTS_READ
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
29 STANDARD_RIGHTS_WRITE
|DIRECTORY_CREATE_OBJECT
|DIRECTORY_CREATE_SUBDIRECTORY
,
30 STANDARD_RIGHTS_EXECUTE
|DIRECTORY_QUERY
|DIRECTORY_TRAVERSE
,
31 DIRECTORY_ALL_ACCESS
};
33 /* FUNCTIONS **************************************************************/
36 ObReferenceObjectByName(PUNICODE_STRING ObjectPath
,
38 PACCESS_STATE PassedAccessState
,
39 ACCESS_MASK DesiredAccess
,
40 POBJECT_TYPE ObjectType
,
41 KPROCESSOR_MODE AccessMode
,
46 UNICODE_STRING RemainingPath
;
47 OBJECT_ATTRIBUTES ObjectAttributes
;
50 InitializeObjectAttributes(&ObjectAttributes
,
55 Status
= ObFindObject(&ObjectAttributes
,
59 if (!NT_SUCCESS(Status
))
64 DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath
.Buffer
, Object
);
66 if (RemainingPath
.Buffer
!= NULL
|| Object
== NULL
)
69 DPRINT("Object %p\n", Object
);
71 RtlFreeUnicodeString (&RemainingPath
);
72 return(STATUS_UNSUCCESSFUL
);
75 RtlFreeUnicodeString (&RemainingPath
);
76 return(STATUS_SUCCESS
);
80 /**********************************************************************
85 * Obtain a handle to an existing object.
107 ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes
,
108 POBJECT_TYPE ObjectType
,
110 KPROCESSOR_MODE AccessMode
,
111 ACCESS_MASK DesiredAccess
,
112 PACCESS_STATE PassedAccessState
,
115 UNICODE_STRING RemainingPath
;
119 DPRINT("ObOpenObjectByName()\n");
121 Status
= ObFindObject(ObjectAttributes
,
125 if (!NT_SUCCESS(Status
))
130 if (RemainingPath
.Buffer
!= NULL
||
133 RtlFreeUnicodeString(&RemainingPath
);
134 return STATUS_UNSUCCESSFUL
;
137 Status
= ObCreateHandle(PsGetCurrentProcess(),
143 ObDereferenceObject(Object
);
144 RtlFreeUnicodeString(&RemainingPath
);
150 VOID STDCALL
ObAddEntryDirectory(PDIRECTORY_OBJECT Parent
,
154 * FUNCTION: Add an entry to a namespace directory
156 * parent = directory to add in
157 * name = Name to give the entry
158 * Object = Header of the object to add the entry for
162 POBJECT_HEADER Header
= BODY_TO_HEADER(Object
);
164 RtlCreateUnicodeString(&Header
->Name
, Name
);
165 Header
->Parent
= Parent
;
167 KeAcquireSpinLock(&Parent
->Lock
, &oldlvl
);
168 InsertTailList(&Parent
->head
, &Header
->Entry
);
169 KeReleaseSpinLock(&Parent
->Lock
, oldlvl
);
172 PVOID
ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
176 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
177 POBJECT_HEADER current_obj
;
179 DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject
, Name
);
183 return(DirectoryObject
);
185 if (Name
[0]=='.' && Name
[1]==0)
187 return(DirectoryObject
);
189 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
191 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
193 while (current
!=(&(DirectoryObject
->head
)))
195 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
196 DPRINT("Scanning %S %S\n",current_obj
->Name
.Buffer
, Name
);
197 if (Attributes
& OBJ_CASE_INSENSITIVE
)
199 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
201 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
202 return(HEADER_TO_BODY(current_obj
));
207 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
209 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
210 return(HEADER_TO_BODY(current_obj
));
213 current
= current
->Flink
;
215 DPRINT("%s() = NULL\n",__FUNCTION__
);
223 PUNICODE_STRING FullPath
,
225 POBJECT_TYPE ObjectType
231 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
238 return STATUS_UNSUCCESSFUL
;
241 end
= wcschr((*Path
)+1, '\\');
247 FoundObject
= ObpFindEntryDirectory(Object
, (*Path
)+1, 0);
249 if (FoundObject
== NULL
)
255 return STATUS_UNSUCCESSFUL
;
258 ObReferenceObjectByPointer(FoundObject
,
259 STANDARD_RIGHTS_REQUIRED
,
273 *NextObject
= FoundObject
;
275 return STATUS_SUCCESS
;
278 NTSTATUS
ObpCreateDirectory(PVOID ObjectBody
,
281 POBJECT_ATTRIBUTES ObjectAttributes
)
283 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
285 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
286 ObjectBody
, Parent
, RemainingPath
);
288 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
290 return(STATUS_UNSUCCESSFUL
);
293 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
295 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+1);
297 InitializeListHead(&DirectoryObject
->head
);
298 KeInitializeSpinLock(&DirectoryObject
->Lock
);
299 return(STATUS_SUCCESS
);
304 * FUNCTION: Initialize the object manager namespace
307 ANSI_STRING AnsiString
;
309 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
311 ObDirectoryType
->TotalObjects
= 0;
312 ObDirectoryType
->TotalHandles
= 0;
313 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
314 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
315 ObDirectoryType
->PagedPoolCharge
= 0;
316 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
317 ObDirectoryType
->Mapping
= &ObpDirectoryMapping
;
318 ObDirectoryType
->Dump
= NULL
;
319 ObDirectoryType
->Open
= NULL
;
320 ObDirectoryType
->Close
= NULL
;
321 ObDirectoryType
->Delete
= NULL
;
322 ObDirectoryType
->Parse
= ObpParseDirectory
;
323 ObDirectoryType
->Security
= NULL
;
324 ObDirectoryType
->QueryName
= NULL
;
325 ObDirectoryType
->OkayToClose
= NULL
;
326 ObDirectoryType
->Create
= ObpCreateDirectory
;
328 RtlInitAnsiString(&AnsiString
,"Directory");
329 RtlAnsiStringToUnicodeString(&ObDirectoryType
->TypeName
,
332 NameSpaceRoot
= ObCreateObject(NULL
,
333 STANDARD_RIGHTS_REQUIRED
,
338 VOID
ObRemoveEntry(POBJECT_HEADER Header
)
342 DPRINT("ObRemoveEntry(Header %x)\n",Header
);
344 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
345 RemoveEntryList(&(Header
->Entry
));
346 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);