some __stdcall fixes in ntoskrnl and ntdll
[reactos.git] / reactos / ntoskrnl / ob / dirobj.c
1 /* $Id: dirobj.c,v 1.5 1999/08/29 06:59:10 ea 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 <wchar.h>
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/io.h>
18 #include <internal/string.h>
19
20 #define NDEBUG
21 #include <internal/debug.h>
22
23
24 /* FUNCTIONS **************************************************************/
25
26
27 /**********************************************************************
28 * NAME EXPORTED
29 * NtOpenDirectoryObject
30 *
31 * DESCRIPTION
32 * Opens a namespace directory object.
33 *
34 * ARGUMENTS
35 * DirectoryHandle (OUT)
36 * Variable which receives the directory handle.
37 *
38 * DesiredAccess
39 * Desired access to the directory.
40 *
41 * ObjectAttributes
42 * Structure describing the directory.
43 *
44 * RETURN VALUE
45 * Status.
46 *
47 * NOTES
48 * Undocumented.
49 */
50 NTSTATUS
51 STDCALL
52 NtOpenDirectoryObject (
53 PHANDLE DirectoryHandle,
54 ACCESS_MASK DesiredAccess,
55 POBJECT_ATTRIBUTES ObjectAttributes
56 )
57 {
58 PVOID Object;
59 NTSTATUS Status;
60
61 *DirectoryHandle = 0;
62
63 Status = ObReferenceObjectByName(
64 ObjectAttributes->ObjectName,
65 ObjectAttributes->Attributes,
66 NULL,
67 DesiredAccess,
68 ObDirectoryType,
69 UserMode,
70 NULL,
71 & Object
72 );
73 if (!NT_SUCCESS(Status))
74 {
75 return Status;
76 }
77
78 Status = ObCreateHandle(
79 PsGetCurrentProcess(),
80 Object,
81 DesiredAccess,
82 FALSE,
83 DirectoryHandle
84 );
85 return STATUS_SUCCESS;
86 }
87
88
89 /**********************************************************************
90 * NAME EXPORTED
91 * NtQueryDirectoryObject
92 *
93 * DESCRIPTION
94 * Reads information from a namespace directory.
95 *
96 * ARGUMENTS
97 * DirObjInformation (OUT)
98 * Buffer to hold the data read.
99 *
100 * BufferLength
101 * Size of the buffer in bytes.
102 *
103 * GetNextIndex
104 * If TRUE then set ObjectIndex to the index of the
105 * next object.
106 * If FALSE then set ObjectIndex to the number of
107 * objects in the directory.
108 *
109 * IgnoreInputIndex
110 * If TRUE start reading at index 0.
111 * If FALSE start reading at the index specified
112 * by object index.
113 *
114 * ObjectIndex
115 * Zero based index into the directory, interpretation
116 * depends on IgnoreInputIndex and GetNextIndex.
117 *
118 * DataWritten (OUT)
119 * Caller supplied storage for the number of bytes
120 * written (or NULL).
121 *
122 * RETURN VALUE
123 * Status.
124 */
125 NTSTATUS
126 STDCALL
127 NtQueryDirectoryObject (
128 IN HANDLE DirObjHandle,
129 OUT POBJDIR_INFORMATION DirObjInformation,
130 IN ULONG BufferLength,
131 IN BOOLEAN GetNextIndex,
132 IN BOOLEAN IgnoreInputIndex,
133 IN OUT PULONG ObjectIndex,
134 OUT PULONG DataWritten OPTIONAL
135 )
136 {
137 PDIRECTORY_OBJECT dir = NULL;
138 ULONG EntriesToRead;
139 PLIST_ENTRY current_entry;
140 POBJECT_HEADER current;
141 ULONG i=0;
142 ULONG EntriesToSkip;
143 NTSTATUS Status;
144
145
146 DPRINT(
147 "NtQueryDirectoryObject(DirObjHandle %x)\n",
148 DirObjHandle
149 );
150 DPRINT(
151 "dir %x namespc_root %x\n",
152 dir,
153 HEADER_TO_BODY(&(namespc_root.hdr))
154 );
155
156 // assert_irql(PASSIVE_LEVEL);
157
158 Status = ObReferenceObjectByHandle(
159 DirObjHandle,
160 DIRECTORY_QUERY,
161 ObDirectoryType,
162 UserMode,
163 (PVOID *) & dir,
164 NULL
165 );
166 if (Status != STATUS_SUCCESS)
167 {
168 return Status;
169 }
170
171 EntriesToRead = BufferLength / sizeof (OBJDIR_INFORMATION);
172 *DataWritten = 0;
173
174 DPRINT("EntriesToRead %d\n",EntriesToRead);
175
176 current_entry = dir->head.Flink;
177
178 /*
179 * Optionally, skip over some entries at the start of the directory
180 */
181 if (!IgnoreInputIndex)
182 {
183 CHECKPOINT;
184
185 EntriesToSkip = *ObjectIndex;
186 while ( (i < EntriesToSkip) && (current_entry != NULL))
187 {
188 current_entry = current_entry->Flink;
189 }
190 }
191
192 DPRINT("DirObjInformation %x\n",DirObjInformation);
193
194 /*
195 * Read the maximum entries possible into the buffer
196 */
197 while ( (i < EntriesToRead) && (current_entry != (&(dir->head))))
198 {
199 current = CONTAINING_RECORD(
200 current_entry,
201 OBJECT_HEADER,
202 Entry
203 );
204 DPRINT(
205 "Scanning %w\n",
206 current->Name.Buffer
207 );
208
209 DirObjInformation[i].ObjectName.Buffer =
210 ExAllocatePool(
211 NonPagedPool,
212 (current->Name.Length + 1) * 2
213 );
214 DirObjInformation[i].ObjectName.Length =
215 current->Name.Length;
216 DirObjInformation[i].ObjectName.MaximumLength =
217 current->Name.Length;
218
219 DPRINT(
220 "DirObjInformation[i].ObjectName.Buffer %x\n",
221 DirObjInformation[i].ObjectName.Buffer
222 );
223
224 RtlCopyUnicodeString(
225 & DirObjInformation[i].ObjectName,
226 & (current->Name)
227 );
228 i++;
229 current_entry = current_entry->Flink;
230 (*DataWritten) = (*DataWritten) + sizeof (OBJDIR_INFORMATION);
231
232 CHECKPOINT;
233 }
234 CHECKPOINT;
235
236 /*
237 * Optionally, count the number of entries in the directory
238 */
239 if (GetNextIndex)
240 {
241 *ObjectIndex = i;
242 }
243 else
244 {
245 while ( current_entry != (&(dir->head)) )
246 {
247 current_entry = current_entry->Flink;
248 i++;
249 }
250 *ObjectIndex = i;
251 }
252 return STATUS_SUCCESS;
253 }
254
255
256 /**********************************************************************
257 * NAME (EXPORTED as Zw)
258 * NtCreateDirectoryObject
259 *
260 * DESCRIPTION
261 * Creates or opens a directory object (a container for other
262 * objects).
263 *
264 * ARGUMENTS
265 * DirectoryHandle (OUT)
266 * Caller supplied storage for the handle of the
267 * directory.
268 *
269 * DesiredAccess
270 * Access desired to the directory.
271 *
272 * ObjectAttributes
273 * Object attributes initialized with
274 * InitializeObjectAttributes.
275 *
276 * RETURN VALUE
277 * Status.
278 */
279 NTSTATUS
280 STDCALL
281 NtCreateDirectoryObject (
282 PHANDLE DirectoryHandle,
283 ACCESS_MASK DesiredAccess,
284 POBJECT_ATTRIBUTES ObjectAttributes
285 )
286 {
287 PDIRECTORY_OBJECT dir;
288
289 dir = ObCreateObject(
290 DirectoryHandle,
291 DesiredAccess,
292 ObjectAttributes,
293 ObDirectoryType
294 );
295 return STATUS_SUCCESS;
296 }
297
298
299 /**********************************************************************
300 * NAME (MACRO in DDK)
301 * InitializeObjectAttributes
302 *
303 * DESCRIPTION
304 * Sets up a parameter of type OBJECT_ATTRIBUTES for a
305 * subsequent call to ZwCreateXXX or ZwOpenXXX.
306 *
307 * ARGUMENTS
308 * InitializedAttributes (OUT)
309 * Caller supplied storage for the object attributes.
310 *
311 * ObjectName
312 * Full path name for object.
313 *
314 * Attributes
315 * Attributes for the object.
316 *
317 * RootDirectory
318 * Where the object should be placed or NULL.
319 *
320 * SecurityDescriptor
321 * Ignored.
322 *
323 * NOTE
324 * Either ObjectName is a fully qualified pathname or a path
325 * relative to RootDirectory.
326 */
327 VOID
328 InitializeObjectAttributes (
329 POBJECT_ATTRIBUTES InitializedAttributes,
330 PUNICODE_STRING ObjectName,
331 ULONG Attributes,
332 HANDLE RootDirectory,
333 PSECURITY_DESCRIPTOR SecurityDescriptor
334 )
335 {
336 DPRINT(
337 "InitializeObjectAttributes(InitializedAttributes %x "
338 "ObjectName %x Attributes %x RootDirectory %x)\n",
339 InitializedAttributes,
340 ObjectName,
341 Attributes,
342 RootDirectory
343 );
344 InitializedAttributes->Length =
345 sizeof (OBJECT_ATTRIBUTES);
346 InitializedAttributes->RootDirectory =
347 RootDirectory;
348 InitializedAttributes->ObjectName =
349 ObjectName;
350 InitializedAttributes->Attributes =
351 Attributes;
352 InitializedAttributes->SecurityDescriptor =
353 SecurityDescriptor;
354 InitializedAttributes->SecurityQualityOfService =
355 NULL;
356 }
357
358
359 /* EOF */