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 ***************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/io.h>
18 #include <internal/string.h>
21 #include <internal/debug.h>
23 /* GLOBALS ****************************************************************/
25 POBJECT_TYPE ObDirectoryType
= NULL
;
27 PDIRECTORY_OBJECT NameSpaceRoot
= NULL
;
29 /* FUNCTIONS **************************************************************/
31 NTSTATUS STDCALL
ObReferenceObjectByName(PUNICODE_STRING ObjectPath
,
33 PACCESS_STATE PassedAccessState
,
34 ACCESS_MASK DesiredAccess
,
35 POBJECT_TYPE ObjectType
,
36 KPROCESSOR_MODE AccessMode
,
41 UNICODE_STRING RemainingPath
;
42 OBJECT_ATTRIBUTES ObjectAttributes
;
45 InitializeObjectAttributes(&ObjectAttributes
,
50 Status
= ObFindObject(&ObjectAttributes
,
54 if (!NT_SUCCESS(Status
))
56 return(STATUS_UNSUCCESSFUL
);
59 if (RemainingPath
.Buffer
!= NULL
||
63 RtlFreeUnicodeString (&RemainingPath
);
64 return(STATUS_UNSUCCESSFUL
);
67 RtlFreeUnicodeString (&RemainingPath
);
68 return(STATUS_SUCCESS
);
71 VOID
ObAddEntryDirectory(PDIRECTORY_OBJECT Parent
,
75 * FUNCTION: Add an entry to a namespace directory
77 * parent = directory to add in
78 * name = Name to give the entry
79 * Object = Header of the object to add the entry for
83 POBJECT_HEADER Header
= BODY_TO_HEADER(Object
);
85 RtlInitUnicodeString(&Header
->Name
, wcsdup(Name
));
86 Header
->Parent
= Parent
;
88 KeAcquireSpinLock(&Parent
->Lock
, &oldlvl
);
89 InsertTailList(&Parent
->head
, &Header
->Entry
);
90 KeReleaseSpinLock(&Parent
->Lock
, oldlvl
);
93 PVOID
ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject
,
97 PLIST_ENTRY current
= DirectoryObject
->head
.Flink
;
98 POBJECT_HEADER current_obj
;
100 DPRINT("ObDirLookup(dir %x, name %S)\n",DirectoryObject
, Name
);
104 return(DirectoryObject
);
106 if (Name
[0]=='.' && Name
[1]==0)
108 return(DirectoryObject
);
110 if (Name
[0]=='.' && Name
[1]=='.' && Name
[2]==0)
112 return(BODY_TO_HEADER(DirectoryObject
)->Parent
);
114 while (current
!=(&(DirectoryObject
->head
)))
116 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,Entry
);
117 DPRINT("Scanning %S %S\n",current_obj
->Name
.Buffer
, Name
);
118 if (Attributes
& OBJ_CASE_INSENSITIVE
)
120 if (_wcsicmp(current_obj
->Name
.Buffer
, Name
)==0)
122 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
123 return(HEADER_TO_BODY(current_obj
));
128 if ( wcscmp(current_obj
->Name
.Buffer
, Name
)==0)
130 DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj
));
131 return(HEADER_TO_BODY(current_obj
));
134 current
= current
->Flink
;
136 DPRINT("%s() = NULL\n",__FUNCTION__
);
145 PUNICODE_STRING FullPath
,
147 POBJECT_TYPE ObjectType
153 DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
160 return STATUS_UNSUCCESSFUL
;
163 end
= wcschr((*Path
)+1, '\\');
169 FoundObject
= ObpFindEntryDirectory(Object
, (*Path
)+1, 0);
171 if (FoundObject
== NULL
)
177 return STATUS_UNSUCCESSFUL
;
180 ObReferenceObjectByPointer(FoundObject
,
181 STANDARD_RIGHTS_REQUIRED
,
195 *NextObject
= FoundObject
;
197 return STATUS_SUCCESS
;
200 NTSTATUS
ObpCreateDirectory(PVOID ObjectBody
,
203 POBJECT_ATTRIBUTES ObjectAttributes
)
205 PDIRECTORY_OBJECT DirectoryObject
= (PDIRECTORY_OBJECT
)ObjectBody
;
207 DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
208 ObjectBody
, Parent
, RemainingPath
);
210 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
212 return(STATUS_UNSUCCESSFUL
);
215 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
217 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+1);
219 InitializeListHead(&DirectoryObject
->head
);
220 KeInitializeSpinLock(&DirectoryObject
->Lock
);
221 return(STATUS_SUCCESS
);
226 * FUNCTION: Initialize the object manager namespace
229 ANSI_STRING AnsiString
;
231 ObDirectoryType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
233 ObDirectoryType
->TotalObjects
= 0;
234 ObDirectoryType
->TotalHandles
= 0;
235 ObDirectoryType
->MaxObjects
= ULONG_MAX
;
236 ObDirectoryType
->MaxHandles
= ULONG_MAX
;
237 ObDirectoryType
->PagedPoolCharge
= 0;
238 ObDirectoryType
->NonpagedPoolCharge
= sizeof(DIRECTORY_OBJECT
);
239 ObDirectoryType
->Dump
= NULL
;
240 ObDirectoryType
->Open
= NULL
;
241 ObDirectoryType
->Close
= NULL
;
242 ObDirectoryType
->Delete
= NULL
;
243 ObDirectoryType
->Parse
= ObpParseDirectory
;
244 ObDirectoryType
->Security
= NULL
;
245 ObDirectoryType
->QueryName
= NULL
;
246 ObDirectoryType
->OkayToClose
= NULL
;
247 ObDirectoryType
->Create
= ObpCreateDirectory
;
249 RtlInitAnsiString(&AnsiString
,"Directory");
250 RtlAnsiStringToUnicodeString(&ObDirectoryType
->TypeName
,
253 NameSpaceRoot
= ObCreateObject(NULL
,
254 STANDARD_RIGHTS_REQUIRED
,
259 VOID
ObRemoveEntry(POBJECT_HEADER Header
)
263 DPRINT("ObRemoveEntry(Header %x)\n",Header
);
265 KeAcquireSpinLock(&(Header
->Parent
->Lock
),&oldlvl
);
266 RemoveEntryList(&(Header
->Entry
));
267 KeReleaseSpinLock(&(Header
->Parent
->Lock
),oldlvl
);