a71f8ed0799453277e507793d1764876a024e096
[reactos.git] / reactos / drivers / fs / cdfs / finfo.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: finfo.c,v 1.3 2002/07/20 00:57:15 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/fs/cdfs/dirctl.c
24 * PURPOSE: CDROM (ISO 9660) filesystem driver
25 * PROGRAMMER: Art Yerkes
26 * Eric Kohl
27 * UPDATE HISTORY:
28 */
29
30 /* INCLUDES *****************************************************************/
31
32 #include <ddk/ntddk.h>
33
34 #define NDEBUG
35 #include <debug.h>
36
37 #include "cdfs.h"
38
39
40 /* FUNCTIONS ****************************************************************/
41
42 static NTSTATUS
43 CdfsGetStandardInformation(PFCB Fcb,
44 PDEVICE_OBJECT DeviceObject,
45 PFILE_STANDARD_INFORMATION StandardInfo,
46 PULONG BufferLength)
47 /*
48 * FUNCTION: Retrieve the standard file information
49 */
50 {
51 DPRINT("CdfsGetStandardInformation() called\n");
52
53 if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
54 return STATUS_BUFFER_OVERFLOW;
55
56 /* PRECONDITION */
57 assert(StandardInfo != NULL);
58 assert(Fcb != NULL);
59
60 RtlZeroMemory(StandardInfo,
61 sizeof(FILE_STANDARD_INFORMATION));
62
63 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
64 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
65 StandardInfo->NumberOfLinks = 0;
66 StandardInfo->DeletePending = FALSE;
67 StandardInfo->Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
68
69 *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
70 return(STATUS_SUCCESS);
71 }
72
73
74 static NTSTATUS
75 CdfsGetPositionInformation(PFILE_OBJECT FileObject,
76 PFILE_POSITION_INFORMATION PositionInfo,
77 PULONG BufferLength)
78 {
79 DPRINT("CdfsGetPositionInformation() called\n");
80
81 if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
82 return STATUS_BUFFER_OVERFLOW;
83
84 PositionInfo->CurrentByteOffset.QuadPart =
85 FileObject->CurrentByteOffset.QuadPart;
86
87 DPRINT("Getting position %I64x\n",
88 PositionInfo->CurrentByteOffset.QuadPart);
89
90 *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
91 return(STATUS_SUCCESS);
92 }
93
94
95 static NTSTATUS
96 CdfsGetBasicInformation(PFILE_OBJECT FileObject,
97 PFCB Fcb,
98 PDEVICE_OBJECT DeviceObject,
99 PFILE_BASIC_INFORMATION BasicInfo,
100 PULONG BufferLength)
101 {
102 DPRINT("CdfsGetBasicInformation() called\n");
103
104 if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
105 return STATUS_BUFFER_OVERFLOW;
106
107 CdfsDateTimeToFileTime(Fcb,
108 &BasicInfo->CreationTime);
109 CdfsDateTimeToFileTime(Fcb,
110 &BasicInfo->LastAccessTime);
111 CdfsDateTimeToFileTime(Fcb,
112 &BasicInfo->LastWriteTime);
113 CdfsDateTimeToFileTime(Fcb,
114 &BasicInfo->ChangeTime);
115
116 CdfsFileFlagsToAttributes(Fcb,
117 &BasicInfo->FileAttributes);
118
119 *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
120
121 return(STATUS_SUCCESS);
122 }
123
124
125 static NTSTATUS
126 CdfsGetNameInformation(PFILE_OBJECT FileObject,
127 PFCB Fcb,
128 PDEVICE_OBJECT DeviceObject,
129 PFILE_NAME_INFORMATION NameInfo,
130 PULONG BufferLength)
131 /*
132 * FUNCTION: Retrieve the file name information
133 */
134 {
135 ULONG NameLength;
136
137 DPRINT("CdfsGetNameInformation() called\n");
138
139 assert(NameInfo != NULL);
140 assert(Fcb != NULL);
141
142 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
143 if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
144 return STATUS_BUFFER_OVERFLOW;
145
146 NameInfo->FileNameLength = NameLength;
147 memcpy(NameInfo->FileName,
148 Fcb->PathName,
149 NameLength + sizeof(WCHAR));
150
151 *BufferLength -=
152 (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
153
154 return STATUS_SUCCESS;
155 }
156
157
158 static NTSTATUS
159 CdfsGetInternalInformation(PFCB Fcb,
160 PFILE_INTERNAL_INFORMATION InternalInfo,
161 PULONG BufferLength)
162 {
163 DPRINT("CdfsGetInternalInformation() called\n");
164
165 assert(InternalInfo);
166 assert(Fcb);
167
168 if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
169 return(STATUS_BUFFER_OVERFLOW);
170
171 /* FIXME: get a real index, that can be used in a create operation */
172 InternalInfo->IndexNumber.QuadPart = 0;
173
174 *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
175
176 return(STATUS_SUCCESS);
177 }
178
179 static NTSTATUS
180 CdfsGetNetworkOpenInformation(PFCB Fcb,
181 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
182 PULONG BufferLength)
183 /*
184 * FUNCTION: Retrieve the file network open information
185 */
186 {
187 assert(NetworkInfo);
188 assert(Fcb);
189
190 if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
191 return(STATUS_BUFFER_OVERFLOW);
192
193 CdfsDateTimeToFileTime(Fcb,
194 &NetworkInfo->CreationTime);
195 CdfsDateTimeToFileTime(Fcb,
196 &NetworkInfo->LastAccessTime);
197 CdfsDateTimeToFileTime(Fcb,
198 &NetworkInfo->LastWriteTime);
199 CdfsDateTimeToFileTime(Fcb,
200 &NetworkInfo->ChangeTime);
201 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
202 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
203 CdfsFileFlagsToAttributes(Fcb,
204 &NetworkInfo->FileAttributes);
205
206 *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
207
208 return(STATUS_SUCCESS);
209 }
210
211
212 NTSTATUS STDCALL
213 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
214 PIRP Irp)
215 /*
216 * FUNCTION: Retrieve the specified file information
217 */
218 {
219 FILE_INFORMATION_CLASS FileInformationClass;
220 PIO_STACK_LOCATION Stack;
221 PFILE_OBJECT FileObject;
222 PFCB Fcb;
223 PVOID SystemBuffer;
224 ULONG BufferLength;
225
226 NTSTATUS Status = STATUS_SUCCESS;
227
228 DPRINT("CdfsQueryInformation() called\n");
229
230 Stack = IoGetCurrentIrpStackLocation(Irp);
231 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
232 FileObject = Stack->FileObject;
233 Fcb = FileObject->FsContext;
234
235 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
236 BufferLength = Stack->Parameters.QueryFile.Length;
237
238 switch (FileInformationClass)
239 {
240 case FileStandardInformation:
241 Status = CdfsGetStandardInformation(Fcb,
242 DeviceObject,
243 SystemBuffer,
244 &BufferLength);
245 break;
246
247 case FilePositionInformation:
248 Status = CdfsGetPositionInformation(FileObject,
249 SystemBuffer,
250 &BufferLength);
251 break;
252
253 case FileBasicInformation:
254 Status = CdfsGetBasicInformation(FileObject,
255 Fcb,
256 DeviceObject,
257 SystemBuffer,
258 &BufferLength);
259 break;
260
261 case FileNameInformation:
262 Status = CdfsGetNameInformation(FileObject,
263 Fcb,
264 DeviceObject,
265 SystemBuffer,
266 &BufferLength);
267 break;
268
269 case FileInternalInformation:
270 Status = CdfsGetInternalInformation(Fcb,
271 SystemBuffer,
272 &BufferLength);
273 break;
274
275 case FileNetworkOpenInformation:
276 Status = CdfsGetNetworkOpenInformation(Fcb,
277 SystemBuffer,
278 &BufferLength);
279 break;
280
281 case FileAlternateNameInformation:
282 case FileAllInformation:
283 Status = STATUS_NOT_IMPLEMENTED;
284 break;
285
286 default:
287 DPRINT("Unimplemented information class %u\n", FileInformationClass);
288 Status = STATUS_NOT_SUPPORTED;
289 }
290
291 Irp->IoStatus.Status = Status;
292 if (NT_SUCCESS(Status))
293 Irp->IoStatus.Information =
294 Stack->Parameters.QueryFile.Length - BufferLength;
295 else
296 Irp->IoStatus.Information = 0;
297
298 IoCompleteRequest(Irp, IO_NO_INCREMENT);
299
300 return(Status);
301 }
302
303 /* EOF */