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/objmgr.h>
17 #include <internal/string.h>
18 #include <internal/kernel.h>
21 #include <internal/debug.h>
23 /* GLOBALS ****************************************************************/
25 OBJECT_TYPE DirectoryObjectType
= {{0,0,NULL
},
30 sizeof(DEVICE_OBJECT
),
45 // DIRECTORY_OBJECT directory;
49 /* FUNCTIONS **************************************************************/
51 NTSTATUS
ZwOpenDirectoryObject(PHANDLE DirectoryHandle
,
52 ACCESS_MASK DesiredAccess
,
53 POBJECT_ATTRIBUTES ObjectAttributes
)
58 Status
= ObOpenObjectByName(ObjectAttributes
,&Object
);
59 if (!NT_SUCCESS(Status
))
64 if (BODY_TO_HEADER(Object
)->Type
!=OBJTYP_DIRECTORY
)
66 return(STATUS_UNSUCCESSFUL
);
69 *DirectoryHandle
= ObAddHandle(Object
);
70 return(STATUS_SUCCESS
);
73 NTSTATUS
ZwQueryDirectoryObject(IN HANDLE DirObjHandle
,
74 OUT POBJDIR_INFORMATION DirObjInformation
,
75 IN ULONG BufferLength
,
76 IN BOOLEAN GetNextIndex
,
77 IN BOOLEAN IgnoreInputIndex
,
78 IN OUT PULONG ObjectIndex
,
79 OUT PULONG DataWritten OPTIONAL
)
81 POBJECT_HEADER hdr
= ObGetObjectByHandle(DirObjHandle
);
82 PDIRECTORY_OBJECT dir
= (PDIRECTORY_OBJECT
)(HEADER_TO_BODY(hdr
));
83 PLIST_ENTRY current_entry
;
84 POBJECT_HEADER current
;
85 PWSTR outbuffer
= (PWSTR
)(ObjectIndex
);
87 current_entry
= dir
->head
.Flink
;
88 while (current_entry
!=NULL
)
90 current
= CONTAINING_RECORD(current_entry
,OBJECT_HEADER
,entry
);
91 if (BufferLength
< wstrlen(current
->name
.Buffer
))
93 return(STATUS_SUCCESS
);
95 BufferLength
= BufferLength
- wstrlen(current
->name
.Buffer
);
96 // wcscpy(outbuffer,current->name.Buffer);
97 outbuffer
= outbuffer
+ wstrlen(current
->name
.Buffer
);
98 current_entry
= current_entry
->Flink
;
100 return(STATUS_SUCCESS
);
104 NTSTATUS
ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes
,
108 DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",
109 ObjectAttributes
,Object
);
110 DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",
111 ObjectAttributes
->ObjectName
,ObjectAttributes
->ObjectName
->Buffer
);
113 *Object
= ObLookupObject(ObjectAttributes
->RootDirectory
,
114 ObjectAttributes
->ObjectName
->Buffer
);
115 DPRINT("*Object %x\n",*Object
);
118 return(STATUS_NO_SUCH_FILE
);
120 return(STATUS_SUCCESS
);
123 void ObjNamespcInit(void)
125 * FUNCTION: Initialize the object manager namespace
128 ANSI_STRING ansi_str
;
130 ObInitializeObjectHeader(OBJTYP_DIRECTORY
,NULL
,&namespc_root
.hdr
);
131 InitializeListHead(&namespc_root
.head
);
133 RtlInitAnsiString(&ansi_str
,"Directory");
134 RtlAnsiStringToUnicodeString(&DirectoryObjectType
.TypeName
,&ansi_str
,
136 ObRegisterType(OBJTYP_DIRECTORY
,&DirectoryObjectType
);
139 NTSTATUS
ZwCreateDirectoryObject(PHANDLE DirectoryHandle
,
140 ACCESS_MASK DesiredAccess
,
141 POBJECT_ATTRIBUTES ObjectAttributes
)
143 * FUNCTION: Creates or opens a directory object (a container for other
146 * DirectoryHandle (OUT) = Caller supplied storage for the handle
148 * DesiredAccess = Access desired to the directory
149 * ObjectAttributes = Object attributes initialized with
150 * InitializeObjectAttributes
154 PDIRECTORY_OBJECT dir
;
156 dir
= ObGenericCreateObject(DirectoryHandle
,DesiredAccess
,ObjectAttributes
,
160 * Initialize the object body
162 InitializeListHead(&dir
->head
);
164 return(STATUS_SUCCESS
);
167 VOID
InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes
,
168 PUNICODE_STRING ObjectName
,
170 HANDLE RootDirectory
,
171 PSECURITY_DESCRIPTOR SecurityDescriptor
)
173 * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a
174 * subsequent call to ZwCreateXXX or ZwOpenXXX
176 * InitializedAttributes (OUT) = Caller supplied storage for the
178 * ObjectName = Full path name for object
179 * Attributes = Attributes for the object
180 * RootDirectory = Where the object should be placed or NULL
181 * SecurityDescriptor = Ignored
184 * Either ObjectName is a fully qualified pathname or a path relative
188 DPRINT("InitializeObjectAttributes(InitializedAttributes %x "
189 "ObjectName %x Attributes %x RootDirectory %x)\n",
190 InitializedAttributes
,ObjectName
,Attributes
,RootDirectory
);
191 InitializedAttributes
->Length
=sizeof(OBJECT_ATTRIBUTES
);
192 InitializedAttributes
->RootDirectory
=RootDirectory
;
193 InitializedAttributes
->ObjectName
=ObjectName
;
194 InitializedAttributes
->Attributes
=Attributes
;
195 InitializedAttributes
->SecurityDescriptor
=SecurityDescriptor
;
196 InitializedAttributes
->SecurityQualityOfService
=NULL
;
199 static PVOID
ObDirLookup(PDIRECTORY_OBJECT dir
, PWSTR name
)
201 * FUNCTION: Looks up an entry within a namespace directory
203 * dir = Directory to lookup in
204 * name = Entry name to find
205 * RETURNS: A pointer to the object body if found
209 LIST_ENTRY
* current
= ((PDIRECTORY_OBJECT
)dir
)->head
.Flink
;
210 POBJECT_HEADER current_obj
;
211 DPRINT("ObDirLookup(dir %x, name %w)\n",dir
,name
);
214 return(BODY_TO_HEADER(dir
));
216 if (name
[0]=='.'&&name
[1]==0)
218 return(BODY_TO_HEADER(dir
));
220 if (name
[0]=='.'&&name
[1]=='.'&&name
[2]==0)
225 while (current
!=NULL
)
227 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,entry
);
228 if ( wcscmp(current_obj
->name
.Buffer
, name
)==0)
232 current
= current
->Flink
;
238 VOID
ObCreateEntry(PDIRECTORY_OBJECT parent
,POBJECT_HEADER Object
)
240 * FUNCTION: Add an entry to a namespace directory
242 * parent = directory to add in
243 * name = Name to give the entry
244 * Object = Header of the object to add the entry for
247 DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent
,Object
,Object
->name
.Buffer
,
248 Object
->name
.Buffer
);
249 DPRINT("root type %d\n",namespc_root
.hdr
.Type
);
250 DPRINT("%x\n",&(namespc_root
.hdr
.Type
));
251 DPRINT("type %x\n",&(parent
->Type
));
252 DPRINT("type %x\n",&(BODY_TO_HEADER(parent
)->Type
));
253 DPRINT("type %d\n",parent
->Type
);
254 assert(parent
->Type
== OBJTYP_DIRECTORY
);
257 * Insert ourselves in our parents list
259 InsertTailList(&parent
->head
,&Object
->entry
);
262 PVOID
ObLookupObject(HANDLE rooth
, PWSTR string
)
264 * FUNCTION: Lookup an object within the system namespc
266 * root = Directory to start lookup from
267 * _string = Pathname to lookup
268 * RETURNS: On success a pointer to the object body
274 PDIRECTORY_OBJECT current_dir
= NULL
;
275 POBJECT_HEADER current_hdr
;
277 DPRINT("root %x string %w\n",rooth
,string
);
281 current_dir
= HEADER_TO_BODY(&(namespc_root
.hdr
));
285 ObReferenceObjectByHandle(rooth
,DIRECTORY_TRAVERSE
,NULL
,
286 UserMode
,(PVOID
*)¤t_dir
,NULL
);
294 DPRINT("current_dir %x\n",current_dir
);
295 DPRINT("type %d\n",current_dir
->Type
);
299 DPRINT("string = %w\n",string
);
303 printk("(%s:%d) Non absolute pathname passed to %s\n",__FILE__
,
304 __LINE__
,__FUNCTION__
);
309 DPRINT("current %w\n",current
);
310 next
= wcschr(string
+1,'\\');
315 DPRINT("next %x\n",next
);
319 DPRINT("Scanning %w next %w current %x\n",current
,next
+1,
323 * Check the current object is a directory
325 if (current_dir
->Type
!=OBJTYP_DIRECTORY
)
327 printk("(%s:%d) Bad path component\n",__FILE__
,
334 * Lookup the next component of the path in the directory
336 current_hdr
=(PDIRECTORY_OBJECT
)ObDirLookup(current_dir
,current
);
337 if (current_hdr
==NULL
)
339 printk("(%s:%d) Path component not found\n",__FILE__
,
344 current_dir
= HEADER_TO_BODY(current_hdr
);
347 next
= wcschr(next
+1,'\\');
354 DPRINT("current_dir %x current %x\n",current_dir
,current
);
355 DPRINT("current %w\n",current
);
356 current_hdr
= ObDirLookup(current_dir
,current
);
357 if (current_hdr
==NULL
)
361 DPRINT("Returning %x %x\n",current_hdr
,HEADER_TO_BODY(current_hdr
));
362 return(HEADER_TO_BODY(current_hdr
));