Removed obsolete linux header files
[reactos.git] / reactos / ntoskrnl / ob / dirobj.c
1 /* $Id: dirobj.c,v 1.9 2000/10/22 16:36:52 ekohl Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 22/05/98: Created
10 */
11
12 /* INCLUDES ***************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21
22 /* FUNCTIONS **************************************************************/
23
24
25 /**********************************************************************
26 * NAME EXPORTED
27 * NtOpenDirectoryObject
28 *
29 * DESCRIPTION
30 * Opens a namespace directory object.
31 *
32 * ARGUMENTS
33 * DirectoryHandle (OUT)
34 * Variable which receives the directory handle.
35 *
36 * DesiredAccess
37 * Desired access to the directory.
38 *
39 * ObjectAttributes
40 * Structure describing the directory.
41 *
42 * RETURN VALUE
43 * Status.
44 *
45 * NOTES
46 * Undocumented.
47 */
48 NTSTATUS STDCALL NtOpenDirectoryObject(PHANDLE DirectoryHandle,
49 ACCESS_MASK DesiredAccess,
50 POBJECT_ATTRIBUTES ObjectAttributes)
51 {
52 PVOID Object;
53 NTSTATUS Status;
54
55 *DirectoryHandle = 0;
56
57 Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
58 ObjectAttributes->Attributes,
59 NULL,
60 DesiredAccess,
61 ObDirectoryType,
62 UserMode,
63 NULL,
64 &Object);
65 if (!NT_SUCCESS(Status))
66 {
67 return Status;
68 }
69
70 Status = ObCreateHandle(PsGetCurrentProcess(),
71 Object,
72 DesiredAccess,
73 FALSE,
74 DirectoryHandle);
75 return STATUS_SUCCESS;
76 }
77
78
79 /**********************************************************************
80 * NAME EXPORTED
81 * NtQueryDirectoryObject
82 *
83 * DESCRIPTION
84 * Reads information from a namespace directory.
85 *
86 * ARGUMENTS
87 * DirObjInformation (OUT)
88 * Buffer to hold the data read.
89 *
90 * BufferLength
91 * Size of the buffer in bytes.
92 *
93 * GetNextIndex
94 * If TRUE then set ObjectIndex to the index of the
95 * next object.
96 * If FALSE then set ObjectIndex to the number of
97 * objects in the directory.
98 *
99 * IgnoreInputIndex
100 * If TRUE start reading at index 0.
101 * If FALSE start reading at the index specified
102 * by object index.
103 *
104 * ObjectIndex
105 * Zero based index into the directory, interpretation
106 * depends on IgnoreInputIndex and GetNextIndex.
107 *
108 * DataWritten (OUT)
109 * Caller supplied storage for the number of bytes
110 * written (or NULL).
111 *
112 * RETURN VALUE
113 * Status.
114 */
115 NTSTATUS STDCALL NtQueryDirectoryObject (IN HANDLE DirObjHandle,
116 OUT POBJDIR_INFORMATION
117 DirObjInformation,
118 IN ULONG BufferLength,
119 IN BOOLEAN GetNextIndex,
120 IN BOOLEAN IgnoreInputIndex,
121 IN OUT PULONG ObjectIndex,
122 OUT PULONG DataWritten OPTIONAL)
123 {
124 PDIRECTORY_OBJECT dir = NULL;
125 PLIST_ENTRY current_entry;
126 POBJECT_HEADER current;
127 ULONG i = 0;
128 ULONG EntriesToSkip;
129 NTSTATUS Status;
130 ULONG SpaceRequired;
131 ULONG FirstFree;
132
133 DPRINT("NtQueryDirectoryObject(DirObjHandle %x)\n", DirObjHandle);
134
135 Status = ObReferenceObjectByHandle(DirObjHandle,
136 DIRECTORY_QUERY,
137 ObDirectoryType,
138 UserMode,
139 (PVOID*)&dir,
140 NULL);
141 if (!NT_SUCCESS(Status))
142 {
143 return(Status);
144 }
145
146 /*
147 * Optionally, skip over some entries at the start of the directory
148 */
149 if (!IgnoreInputIndex)
150 {
151 CHECKPOINT;
152
153 EntriesToSkip = *ObjectIndex;
154 i = 0;
155 current_entry = dir->head.Flink;
156
157 while ((i < EntriesToSkip) && (current_entry != &dir->head))
158 {
159 current_entry = current_entry->Flink;
160 i++;
161 }
162 }
163 else
164 {
165 current_entry = dir->head.Flink;
166 i = 0;
167 }
168
169 /*
170 * Check if we have reached the end of the directory
171 */
172 if (current_entry != &dir->head)
173 {
174 *DataWritten = 0;
175 return(STATUS_NO_MORE_ENTRIES);
176 }
177
178 /*
179 * Read the current entry into the buffer
180 */
181 FirstFree = sizeof(OBJDIR_INFORMATION);
182
183 current = CONTAINING_RECORD(current_entry, OBJECT_HEADER, Entry);
184
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);
189
190 if (SpaceRequired <= BufferLength)
191 {
192
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);
202
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);
213
214 *DataWritten = SpaceRequired;
215 Status = STATUS_SUCCESS;
216 }
217 else
218 {
219 Status = STATUS_BUFFER_TOO_SMALL;
220 }
221
222 /*
223 * Store into ObjectIndex
224 */
225 if (GetNextIndex)
226 {
227 *ObjectIndex = i + 1;
228 }
229 else
230 {
231 i = 0;
232 current_entry = dir->head.Flink;
233 while (current_entry != (&dir->head))
234 {
235 current_entry = current_entry->Flink;
236 i++;
237 }
238 *ObjectIndex = i;
239 }
240
241 return(STATUS_SUCCESS);
242 }
243
244
245 /**********************************************************************
246 * NAME (EXPORTED as Zw)
247 * NtCreateDirectoryObject
248 *
249 * DESCRIPTION
250 * Creates or opens a directory object (a container for other
251 * objects).
252 *
253 * ARGUMENTS
254 * DirectoryHandle (OUT)
255 * Caller supplied storage for the handle of the
256 * directory.
257 *
258 * DesiredAccess
259 * Access desired to the directory.
260 *
261 * ObjectAttributes
262 * Object attributes initialized with
263 * InitializeObjectAttributes.
264 *
265 * RETURN VALUE
266 * Status.
267 */
268 NTSTATUS STDCALL NtCreateDirectoryObject (PHANDLE DirectoryHandle,
269 ACCESS_MASK DesiredAccess,
270 POBJECT_ATTRIBUTES ObjectAttributes)
271 {
272 PDIRECTORY_OBJECT dir;
273
274 DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
275 "DesiredAccess %x, ObjectAttributes %x, "
276 "ObjectAttributes->ObjectName %S)\n",
277 DirectoryHandle, DesiredAccess, ObjectAttributes,
278 ObjectAttributes->ObjectName);
279
280 dir = ObCreateObject(DirectoryHandle,
281 DesiredAccess,
282 ObjectAttributes,
283 ObDirectoryType);
284 return(STATUS_SUCCESS);
285 }
286
287 /* EOF */