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/objmgr.h>
16 #include <internal/string.h>
17 #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 void ObjNamespcInit(void)
53 * FUNCTION: Initialize the object manager namespace
58 ObInitializeObjectHeader(OBJTYP_DIRECTORY
,NULL
,&namespc_root
.hdr
);
59 InitializeListHead(&namespc_root
.head
);
61 RtlInitAnsiString(&ansi_str
,"Directory");
62 RtlAnsiStringToUnicodeString(&DirectoryObjectType
.TypeName
,&ansi_str
,
64 ObRegisterType(OBJTYP_DIRECTORY
,&DirectoryObjectType
);
67 NTSTATUS
ZwCreateDirectoryObject(PHANDLE DirectoryHandle
,
68 ACCESS_MASK DesiredAccess
,
69 POBJECT_ATTRIBUTES ObjectAttributes
)
71 * FUNCTION: Creates or opens a directory object (a container for other
74 * DirectoryHandle (OUT) = Caller supplied storage for the handle
76 * DesiredAccess = Access desired to the directory
77 * ObjectAttributes = Object attributes initialized with
78 * InitializeObjectAttributes
82 PDIRECTORY_OBJECT dir
;
84 dir
= ObGenericCreateObject(DirectoryHandle
,DesiredAccess
,ObjectAttributes
,
88 * Initialize the object body
90 InitializeListHead(&dir
->head
);
92 return(STATUS_SUCCESS
);
95 PWSTR
Rtlstrrchr(PUNICODE_STRING string
, WCHAR c
)
98 DPRINT("string->Length %d\n",string
->Length
);
99 for (i
=(string
->Length
-1);i
>=0;i
--)
101 if (string
->Buffer
[i
]==c
)
103 return(&string
->Buffer
[i
]);
109 VOID
InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes
,
110 PUNICODE_STRING ObjectName
,
112 HANDLE RootDirectory
,
113 PSECURITY_DESCRIPTOR SecurityDescriptor
)
115 * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a
116 * subsequent call to ZwCreateXXX or ZwOpenXXX
118 * InitializedAttributes (OUT) = Caller supplied storage for the
120 * ObjectName = Full path name for object
121 * Attributes = Attributes for the object
122 * RootDirectory = Where the object should be placed or NULL
123 * SecurityDescriptor = Ignored
126 * Either ObjectName is a fully qualified pathname or a path relative
132 PDIRECTORY_OBJECT parent_dir
;
134 DPRINT("InitalizeObjectAttributes(ObjectName %w)\n",ObjectName
->Buffer
);
136 if (RootDirectory
!=NULL
)
138 ObReferenceObjectByHandle(RootDirectory
,DIRECTORY_TRAVERSE
,NULL
,
139 UserMode
,(PVOID
*)&parent_dir
,NULL
);
143 parent_dir
= HEADER_TO_BODY((POBJECT_HEADER
)&namespc_root
);
146 ASSERT_IRQL(PASSIVE_LEVEL
);
148 path
.Buffer
= ExAllocatePool(NonPagedPool
,
149 ObjectName
->Length
*sizeof(WCHAR
));
150 path
.MaximumLength
= ObjectName
->Length
;
151 RtlCopyUnicodeString(&path
,ObjectName
);
154 * Seperate the path into the name of the object and the name of its
155 * direct parent directory
157 name
= Rtlstrrchr(&path
,'\\');
161 * Find the objects parent directory
163 DPRINT("parent_dir %x\n",&(parent_dir
->Type
));
164 parent_dir
=(PDIRECTORY_OBJECT
)ObLookupObject(parent_dir
,&path
);
165 if (parent_dir
==NULL
)
171 * Make sure the parent directory doesn't disappear
173 ObReferenceObjectByPointer(parent_dir
,DIRECTORY_CREATE_OBJECT
,NULL
,
176 InitializedAttributes
->Attributes
= Attributes
;
177 InitializedAttributes
->parent
= parent_dir
;
178 RtlInitUnicodeString(&InitializedAttributes
->name
,name
+1);
179 InitializedAttributes
->path
= path
;
182 int _wcscmp(wchar_t* str1
, wchar_t* str2
)
184 while ( (*str1
)==(*str2
) )
188 if ( (*str1
)==((wchar_t)0) && (*str1
)==((wchar_t)0) )
193 return( (*str1
) - (*str2
) );
196 static PVOID
ObDirLookup(PDIRECTORY_OBJECT dir
, PWSTR name
)
198 * FUNCTION: Looks up an entry within a namespace directory
200 * dir = Directory to lookup in
201 * name = Entry name to find
202 * RETURNS: A pointer to the object body if found
206 LIST_ENTRY
* current
= ((PDIRECTORY_OBJECT
)dir
)->head
.Flink
;
207 POBJECT_HEADER current_obj
;
208 DPRINT("ObDirLookup(dir %x, name %w\n",dir
,name
);
209 while (current
!=NULL
)
211 current_obj
= CONTAINING_RECORD(current
,OBJECT_HEADER
,entry
);
212 DPRINT("current_obj->name %w\n",current_obj
->name
.Buffer
);
213 if ( _wcscmp(current_obj
->name
.Buffer
, name
)==0)
217 current
= current
->Flink
;
223 VOID
ObCreateEntry(PDIRECTORY_OBJECT parent
,POBJECT_HEADER Object
)
225 * FUNCTION: Add an entry to a namespace directory
227 * parent = directory to add in
228 * name = Name to give the entry
229 * Object = Header of the object to add the entry for
232 DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent
,Object
,Object
->name
.Buffer
,
233 Object
->name
.Buffer
);
234 DPRINT("root type %d\n",namespc_root
.hdr
.Type
);
235 DPRINT("%x\n",&(namespc_root
.hdr
.Type
));
236 DPRINT("type %x\n",&(parent
->Type
));
237 DPRINT("type %x\n",&(BODY_TO_HEADER(parent
)->Type
));
238 DPRINT("type %d\n",parent
->Type
);
239 assert(parent
->Type
== OBJTYP_DIRECTORY
);
242 * Insert ourselves in our parents list
244 InsertTailList(&parent
->head
,&Object
->entry
);
247 wchar_t* _wcschr(wchar_t* str
, wchar_t ch
)
249 while ((*str
)!=((wchar_t)0))
260 PVOID
ObLookupObject(PDIRECTORY_OBJECT root
, PUNICODE_STRING _string
)
262 * FUNCTION: Lookup an object within the system namespc
264 * root = Directory to start lookup from
265 * _string = Pathname to lookup
266 * RETURNS: On success a pointer to the object body
272 PDIRECTORY_OBJECT current_dir
= root
;
273 POBJECT_HEADER current_hdr
;
276 DPRINT("root %x string %w\n",root
,_string
->Buffer
);
280 current_dir
= HEADER_TO_BODY(&(namespc_root
.hdr
));
286 if (_string
->Buffer
[0]==0)
288 DPRINT("current_dir %x\n",current_dir
);
289 DPRINT("type %d\n",current_dir
->Type
);
293 string
=(PWSTR
)ExAllocatePool(NonPagedPool
,(_string
->Length
+1)*2);
294 wcscpy(string
,_string
->Buffer
);
296 DPRINT("string = %w\n",string
);
300 printk("(%s:%d) Non absolute pathname passed to %s\n",__FILE__
,
301 __LINE__
,__FUNCTION__
);
306 DPRINT("current %w\n",current
);
307 next
= _wcschr(string
+1,'\\');
312 DPRINT("next %x\n",next
);
316 DPRINT("Scanning %w next %w current %x\n",current
,next
+1,
320 * Check the current object is a directory
322 if (current_dir
->Type
!=OBJTYP_DIRECTORY
)
324 printk("(%s:%d) Bad path component\n",__FILE__
,
331 * Lookup the next component of the path in the directory
333 current_hdr
=(PDIRECTORY_OBJECT
)ObDirLookup(current_dir
,current
);
334 if (current_hdr
==NULL
)
336 printk("(%s:%d) Path component not found\n",__FILE__
,
341 current_dir
= HEADER_TO_BODY(current_hdr
);
344 next
= _wcschr(next
+1,'\\');
351 DPRINT("current_dir %x current %x\n",current_dir
,current
);
352 DPRINT("current %w\n",current
);
353 current_hdr
= ObDirLookup(current_dir
,current
);
354 if (current_hdr
==NULL
)
359 DPRINT("Returning %x %x\n",current_hdr
,HEADER_TO_BODY(current_hdr
));
361 return(HEADER_TO_BODY(current_hdr
));