1 /* $Id: dirobj.c,v 1.9 2000/10/22 16:36:52 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/dirobj.c
6 * PURPOSE: Interface functions to directory object
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES ***************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
19 #include <internal/debug.h>
22 /* FUNCTIONS **************************************************************/
25 /**********************************************************************
27 * NtOpenDirectoryObject
30 * Opens a namespace directory object.
33 * DirectoryHandle (OUT)
34 * Variable which receives the directory handle.
37 * Desired access to the directory.
40 * Structure describing the directory.
48 NTSTATUS STDCALL
NtOpenDirectoryObject(PHANDLE DirectoryHandle
,
49 ACCESS_MASK DesiredAccess
,
50 POBJECT_ATTRIBUTES ObjectAttributes
)
57 Status
= ObReferenceObjectByName(ObjectAttributes
->ObjectName
,
58 ObjectAttributes
->Attributes
,
65 if (!NT_SUCCESS(Status
))
70 Status
= ObCreateHandle(PsGetCurrentProcess(),
75 return STATUS_SUCCESS
;
79 /**********************************************************************
81 * NtQueryDirectoryObject
84 * Reads information from a namespace directory.
87 * DirObjInformation (OUT)
88 * Buffer to hold the data read.
91 * Size of the buffer in bytes.
94 * If TRUE then set ObjectIndex to the index of the
96 * If FALSE then set ObjectIndex to the number of
97 * objects in the directory.
100 * If TRUE start reading at index 0.
101 * If FALSE start reading at the index specified
105 * Zero based index into the directory, interpretation
106 * depends on IgnoreInputIndex and GetNextIndex.
109 * Caller supplied storage for the number of bytes
115 NTSTATUS STDCALL
NtQueryDirectoryObject (IN HANDLE DirObjHandle
,
116 OUT POBJDIR_INFORMATION
118 IN ULONG BufferLength
,
119 IN BOOLEAN GetNextIndex
,
120 IN BOOLEAN IgnoreInputIndex
,
121 IN OUT PULONG ObjectIndex
,
122 OUT PULONG DataWritten OPTIONAL
)
124 PDIRECTORY_OBJECT dir
= NULL
;
125 PLIST_ENTRY current_entry
;
126 POBJECT_HEADER current
;
133 DPRINT("NtQueryDirectoryObject(DirObjHandle %x)\n", DirObjHandle
);
135 Status
= ObReferenceObjectByHandle(DirObjHandle
,
141 if (!NT_SUCCESS(Status
))
147 * Optionally, skip over some entries at the start of the directory
149 if (!IgnoreInputIndex
)
153 EntriesToSkip
= *ObjectIndex
;
155 current_entry
= dir
->head
.Flink
;
157 while ((i
< EntriesToSkip
) && (current_entry
!= &dir
->head
))
159 current_entry
= current_entry
->Flink
;
165 current_entry
= dir
->head
.Flink
;
170 * Check if we have reached the end of the directory
172 if (current_entry
!= &dir
->head
)
175 return(STATUS_NO_MORE_ENTRIES
);
179 * Read the current entry into the buffer
181 FirstFree
= sizeof(OBJDIR_INFORMATION
);
183 current
= CONTAINING_RECORD(current_entry
, OBJECT_HEADER
, Entry
);
185 SpaceRequired
= (wcslen(current
->Name
.Buffer
) + 1) * 2;
186 SpaceRequired
= SpaceRequired
+
187 ((wcslen(current
->ObjectType
->TypeName
.Buffer
) + 1) * 2);
188 SpaceRequired
= SpaceRequired
+ sizeof(OBJDIR_INFORMATION
);
190 if (SpaceRequired
<= BufferLength
)
193 DirObjInformation
->ObjectName
.Length
=
194 current
->Name
.Length
;
195 DirObjInformation
->ObjectName
.MaximumLength
=
196 current
->Name
.Length
;
197 DirObjInformation
->ObjectName
.Buffer
=
198 (((PVOID
)DirObjInformation
) + FirstFree
);
199 FirstFree
= FirstFree
+ (wcslen(current
->Name
.Buffer
+ 1) * 2);
200 wcscpy(DirObjInformation
->ObjectName
.Buffer
,
201 current
->Name
.Buffer
);
203 DirObjInformation
->ObjectTypeName
.Length
=
204 current
->ObjectType
->TypeName
.Length
;
205 DirObjInformation
->ObjectTypeName
.MaximumLength
=
206 current
->ObjectType
->TypeName
.Length
;
207 DirObjInformation
->ObjectName
.Buffer
=
208 (((PVOID
)DirObjInformation
) + FirstFree
);
209 FirstFree
= FirstFree
+
210 (wcslen(current
->ObjectType
->TypeName
.Buffer
+ 1) * 2);
211 wcscpy(DirObjInformation
->ObjectTypeName
.Buffer
,
212 current
->ObjectType
->TypeName
.Buffer
);
214 *DataWritten
= SpaceRequired
;
215 Status
= STATUS_SUCCESS
;
219 Status
= STATUS_BUFFER_TOO_SMALL
;
223 * Store into ObjectIndex
227 *ObjectIndex
= i
+ 1;
232 current_entry
= dir
->head
.Flink
;
233 while (current_entry
!= (&dir
->head
))
235 current_entry
= current_entry
->Flink
;
241 return(STATUS_SUCCESS
);
245 /**********************************************************************
246 * NAME (EXPORTED as Zw)
247 * NtCreateDirectoryObject
250 * Creates or opens a directory object (a container for other
254 * DirectoryHandle (OUT)
255 * Caller supplied storage for the handle of the
259 * Access desired to the directory.
262 * Object attributes initialized with
263 * InitializeObjectAttributes.
268 NTSTATUS STDCALL
NtCreateDirectoryObject (PHANDLE DirectoryHandle
,
269 ACCESS_MASK DesiredAccess
,
270 POBJECT_ATTRIBUTES ObjectAttributes
)
272 PDIRECTORY_OBJECT dir
;
274 DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
275 "DesiredAccess %x, ObjectAttributes %x, "
276 "ObjectAttributes->ObjectName %S)\n",
277 DirectoryHandle
, DesiredAccess
, ObjectAttributes
,
278 ObjectAttributes
->ObjectName
);
280 dir
= ObCreateObject(DirectoryHandle
,
284 return(STATUS_SUCCESS
);