560ad418a749dfa9a0b41d86620b8d2c8c9f56c2
[reactos.git] / reactos / ntoskrnl / ob / dirobj.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ob/dirobj.c
5 * PURPOSE: Interface functions to directory object
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * 22/05/98: Created
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include <wchar.h>
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
17 #include <internal/string.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22
23 /* FUNCTIONS **************************************************************/
24
25 NTSTATUS
26 NtOpenDirectoryObject (
27 PHANDLE DirectoryHandle,
28 ACCESS_MASK DesiredAccess,
29 POBJECT_ATTRIBUTES ObjectAttributes
30 )
31 /*
32 * FUNCTION: Opens a namespace directory object
33 * ARGUMENTS:
34 * DirectoryHandle (OUT) = Variable which receives the directory handle
35 * DesiredAccess = Desired access to the directory
36 * ObjectAttributes = Structure describing the directory
37 * RETURNS: Status
38 * NOTES: Undocumented
39 */
40 {
41 PVOID Object;
42 NTSTATUS Status;
43
44 *DirectoryHandle = 0;
45
46 Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
47 ObjectAttributes->Attributes,
48 NULL,
49 DesiredAccess,
50 ObDirectoryType,
51 UserMode,
52 NULL,
53 &Object);
54 if (!NT_SUCCESS(Status))
55 {
56 return(Status);
57 }
58
59 Status = ObCreateHandle(PsGetCurrentProcess(),
60 Object,
61 DesiredAccess,
62 FALSE,
63 DirectoryHandle);
64 return(STATUS_SUCCESS);
65 }
66
67
68 NTSTATUS
69 NtQueryDirectoryObject (
70 IN HANDLE DirObjHandle,
71 OUT POBJDIR_INFORMATION DirObjInformation,
72 IN ULONG BufferLength,
73 IN BOOLEAN GetNextIndex,
74 IN BOOLEAN IgnoreInputIndex,
75 IN OUT PULONG ObjectIndex,
76 OUT PULONG DataWritten OPTIONAL
77 )
78 /*
79 * FUNCTION: Reads information from a namespace directory
80 * ARGUMENTS:
81 * DirObjInformation (OUT) = Buffer to hold the data read
82 * BufferLength = Size of the buffer in bytes
83 * GetNextIndex = If TRUE then set ObjectIndex to the index of the
84 * next object
85 * If FALSE then set ObjectIndex to the number of
86 * objects in the directory
87 * IgnoreInputIndex = If TRUE start reading at index 0
88 * If FALSE start reading at the index specified
89 * by object index
90 * ObjectIndex = Zero based index into the directory, interpretation
91 * depends on IgnoreInputIndex and GetNextIndex
92 * DataWritten (OUT) = Caller supplied storage for the number of bytes
93 * written (or NULL)
94 * RETURNS: Status
95 */
96 {
97 PDIRECTORY_OBJECT dir = NULL;
98 ULONG EntriesToRead;
99 PLIST_ENTRY current_entry;
100 POBJECT_HEADER current;
101 ULONG i=0;
102 ULONG EntriesToSkip;
103 NTSTATUS Status;
104
105 DPRINT("NtQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);
106 DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));
107
108 // assert_irql(PASSIVE_LEVEL);
109
110 Status = ObReferenceObjectByHandle(DirObjHandle,
111 DIRECTORY_QUERY,
112 ObDirectoryType,
113 UserMode,
114 (PVOID*)&dir,
115 NULL);
116 if (Status != STATUS_SUCCESS)
117 {
118 return(Status);
119 }
120
121 EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);
122 *DataWritten = 0;
123
124 DPRINT("EntriesToRead %d\n",EntriesToRead);
125
126 current_entry = dir->head.Flink;
127
128 /*
129 * Optionally, skip over some entries at the start of the directory
130 */
131 if (!IgnoreInputIndex)
132 {
133 CHECKPOINT;
134
135 EntriesToSkip = *ObjectIndex;
136 while ( i<EntriesToSkip && current_entry!=NULL)
137 {
138 current_entry = current_entry->Flink;
139 }
140 }
141
142 DPRINT("DirObjInformation %x\n",DirObjInformation);
143
144 /*
145 * Read the maximum entries possible into the buffer
146 */
147 while ( i<EntriesToRead && current_entry!=(&(dir->head)))
148 {
149 current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
150 DPRINT("Scanning %w\n",current->Name.Buffer);
151 DirObjInformation[i].ObjectName.Buffer =
152 ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);
153 DirObjInformation[i].ObjectName.Length = current->Name.Length;
154 DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;
155 DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
156 DirObjInformation[i].ObjectName.Buffer);
157 RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
158 &(current->Name));
159 i++;
160 current_entry = current_entry->Flink;
161 (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);
162 CHECKPOINT;
163 }
164 CHECKPOINT;
165
166 /*
167 * Optionally, count the number of entries in the directory
168 */
169 if (GetNextIndex)
170 {
171 *ObjectIndex=i;
172 }
173 else
174 {
175 while ( current_entry!=(&(dir->head)) )
176 {
177 current_entry=current_entry->Flink;
178 i++;
179 }
180 *ObjectIndex=i;
181 }
182 return(STATUS_SUCCESS);
183 }
184
185
186 NTSTATUS
187 STDCALL
188 NtCreateDirectoryObject (
189 PHANDLE DirectoryHandle,
190 ACCESS_MASK DesiredAccess,
191 POBJECT_ATTRIBUTES ObjectAttributes
192 )
193 /*
194 * FUNCTION: Creates or opens a directory object (a container for other
195 * objects)
196 * ARGUMENTS:
197 * DirectoryHandle (OUT) = Caller supplied storage for the handle
198 * of the directory
199 * DesiredAccess = Access desired to the directory
200 * ObjectAttributes = Object attributes initialized with
201 * InitializeObjectAttributes
202 * RETURNS: Status
203 */
204 {
205 PDIRECTORY_OBJECT dir;
206
207 dir = ObCreateObject(DirectoryHandle,
208 DesiredAccess,
209 ObjectAttributes,
210 ObDirectoryType);
211 return(STATUS_SUCCESS);
212 }
213
214 VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
215 PUNICODE_STRING ObjectName,
216 ULONG Attributes,
217 HANDLE RootDirectory,
218 PSECURITY_DESCRIPTOR SecurityDescriptor)
219 /*
220 * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a
221 * subsequent call to ZwCreateXXX or ZwOpenXXX
222 * ARGUMENTS:
223 * InitializedAttributes (OUT) = Caller supplied storage for the
224 * object attributes
225 * ObjectName = Full path name for object
226 * Attributes = Attributes for the object
227 * RootDirectory = Where the object should be placed or NULL
228 * SecurityDescriptor = Ignored
229 *
230 * NOTE:
231 * Either ObjectName is a fully qualified pathname or a path relative
232 * to RootDirectory
233 */
234 {
235 DPRINT("InitializeObjectAttributes(InitializedAttributes %x "
236 "ObjectName %x Attributes %x RootDirectory %x)\n",
237 InitializedAttributes,ObjectName,Attributes,RootDirectory);
238 InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);
239 InitializedAttributes->RootDirectory=RootDirectory;
240 InitializedAttributes->ObjectName=ObjectName;
241 InitializedAttributes->Attributes=Attributes;
242 InitializedAttributes->SecurityDescriptor=SecurityDescriptor;
243 InitializedAttributes->SecurityQualityOfService=NULL;
244 }
245