:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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$
20  *
21  * COPYRIGHT:        See COPYING in the top level directory
22  * PROJECT:          ReactOS kernel
23  * FILE:             services/fs/cdfs/finfo.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   RtlCopyMemory(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
180 static NTSTATUS
181 CdfsGetNetworkOpenInformation(PFCB Fcb,
182                               PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
183                               PULONG BufferLength)
184 /*
185  * FUNCTION: Retrieve the file network open information
186  */
187 {
188   assert(NetworkInfo);
189   assert(Fcb);
190
191   if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
192     return(STATUS_BUFFER_OVERFLOW);
193
194   CdfsDateTimeToFileTime(Fcb,
195                          &NetworkInfo->CreationTime);
196   CdfsDateTimeToFileTime(Fcb,
197                          &NetworkInfo->LastAccessTime);
198   CdfsDateTimeToFileTime(Fcb,
199                          &NetworkInfo->LastWriteTime);
200   CdfsDateTimeToFileTime(Fcb,
201                          &NetworkInfo->ChangeTime);
202   NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
203   NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
204   CdfsFileFlagsToAttributes(Fcb,
205                             &NetworkInfo->FileAttributes);
206
207   *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
208
209   return(STATUS_SUCCESS);
210 }
211
212
213 static NTSTATUS
214 CdfsGetAllInformation(PFILE_OBJECT FileObject,
215                       PFCB Fcb,
216                       PFILE_ALL_INFORMATION Info,
217                       PULONG BufferLength)
218 /*
219  * FUNCTION: Retrieve the all file information
220  */
221 {
222   ULONG NameLength;
223
224   assert(Info);
225   assert(Fcb);
226
227   NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
228   if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength)
229     return(STATUS_BUFFER_OVERFLOW);
230
231   /* Basic Information */
232   CdfsDateTimeToFileTime(Fcb,
233                          &Info->BasicInformation.CreationTime);
234   CdfsDateTimeToFileTime(Fcb,
235                          &Info->BasicInformation.LastAccessTime);
236   CdfsDateTimeToFileTime(Fcb,
237                          &Info->BasicInformation.LastWriteTime);
238   CdfsDateTimeToFileTime(Fcb,
239                          &Info->BasicInformation.ChangeTime);
240   CdfsFileFlagsToAttributes(Fcb,
241                             &Info->BasicInformation.FileAttributes);
242
243   /* Standard Information */
244   Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
245   Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
246   Info->StandardInformation.NumberOfLinks = 0;
247   Info->StandardInformation.DeletePending = FALSE;
248   Info->StandardInformation.Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
249
250   /* Internal Information */
251   /* FIXME: get a real index, that can be used in a create operation */
252   Info->InternalInformation.IndexNumber.QuadPart = 0;
253
254   /* EA Information */
255   Info->EaInformation.EaSize = 0;
256
257   /* Access Information */
258   /* The IO-Manager adds this information */
259
260   /* Position Information */
261   Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
262
263   /* Mode Information */
264   /* The IO-Manager adds this information */
265
266   /* Alignment Information */
267   /* The IO-Manager adds this information */
268
269   /* Name Information */
270   Info->NameInformation.FileNameLength = NameLength;
271   RtlCopyMemory(Info->NameInformation.FileName,
272                 Fcb->PathName,
273                 NameLength + sizeof(WCHAR));
274
275   *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
276
277   return STATUS_SUCCESS;
278 }
279
280 static NTSTATUS
281 CdfsSetPositionInformation(PFILE_OBJECT FileObject,
282                            PFILE_POSITION_INFORMATION PositionInfo)
283 {
284   DPRINT ("CdfsSetPositionInformation()\n");
285
286   DPRINT ("PositionInfo %x\n", PositionInfo);
287   DPRINT ("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
288   memcpy (&FileObject->CurrentByteOffset, &PositionInfo->CurrentByteOffset,
289           sizeof (LARGE_INTEGER));
290
291   return (STATUS_SUCCESS);
292 }
293
294 NTSTATUS STDCALL
295 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
296                      PIRP Irp)
297 /*
298  * FUNCTION: Retrieve the specified file information
299  */
300 {
301   FILE_INFORMATION_CLASS FileInformationClass;
302   PIO_STACK_LOCATION Stack;
303   PFILE_OBJECT FileObject;
304   PFCB Fcb;
305   PVOID SystemBuffer;
306   ULONG BufferLength;
307
308   NTSTATUS Status = STATUS_SUCCESS;
309
310   DPRINT("CdfsQueryInformation() called\n");
311
312   Stack = IoGetCurrentIrpStackLocation(Irp);
313   FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
314   FileObject = Stack->FileObject;
315   Fcb = FileObject->FsContext;
316
317   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
318   BufferLength = Stack->Parameters.QueryFile.Length;
319
320   switch (FileInformationClass)
321     {
322       case FileStandardInformation:
323         Status = CdfsGetStandardInformation(Fcb,
324                                             DeviceObject,
325                                             SystemBuffer,
326                                             &BufferLength);
327         break;
328
329       case FilePositionInformation:
330         Status = CdfsGetPositionInformation(FileObject,
331                                             SystemBuffer,
332                                             &BufferLength);
333         break;
334
335       case FileBasicInformation:
336         Status = CdfsGetBasicInformation(FileObject,
337                                          Fcb,
338                                          DeviceObject,
339                                          SystemBuffer,
340                                          &BufferLength);
341         break;
342
343       case FileNameInformation:
344         Status = CdfsGetNameInformation(FileObject,
345                                         Fcb,
346                                         DeviceObject,
347                                         SystemBuffer,
348                                         &BufferLength);
349         break;
350
351       case FileInternalInformation:
352         Status = CdfsGetInternalInformation(Fcb,
353                                             SystemBuffer,
354                                             &BufferLength);
355         break;
356
357       case FileNetworkOpenInformation:
358         Status = CdfsGetNetworkOpenInformation(Fcb,
359                                                SystemBuffer,
360                                                &BufferLength);
361         break;
362
363       case FileAllInformation:
364         Status = CdfsGetAllInformation(FileObject,
365                                        Fcb,
366                                        SystemBuffer,
367                                        &BufferLength);
368         break;
369
370       case FileAlternateNameInformation:
371         Status = STATUS_NOT_IMPLEMENTED;
372         break;
373
374       default:
375         DPRINT("Unimplemented information class %u\n", FileInformationClass);
376         Status = STATUS_NOT_SUPPORTED;
377     }
378
379   Irp->IoStatus.Status = Status;
380   if (NT_SUCCESS(Status))
381     Irp->IoStatus.Information =
382       Stack->Parameters.QueryFile.Length - BufferLength;
383   else
384     Irp->IoStatus.Information = 0;
385
386   IoCompleteRequest(Irp, IO_NO_INCREMENT);
387
388   return(Status);
389 }
390
391 NTSTATUS STDCALL
392 CdfsSetInformation(PDEVICE_OBJECT DeviceObject,
393                    PIRP Irp)
394 /*
395  * FUNCTION: Retrieve the specified file information
396  */
397 {
398   FILE_INFORMATION_CLASS FileInformationClass;
399   PIO_STACK_LOCATION Stack;
400   PFILE_OBJECT FileObject;
401   PFCB Fcb;
402   PVOID SystemBuffer;
403
404   NTSTATUS Status = STATUS_SUCCESS;
405
406   DPRINT1("CdfsSetInformation() called\n");
407
408   Stack = IoGetCurrentIrpStackLocation(Irp);
409   FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
410   FileObject = Stack->FileObject;
411   Fcb = FileObject->FsContext;
412
413   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
414
415   switch (FileInformationClass)
416     {
417     case FilePositionInformation:
418       Status = CdfsSetPositionInformation(FileObject,
419                                           SystemBuffer);
420       break;
421     case FileBasicInformation:
422     case FileRenameInformation:
423       Status = STATUS_NOT_IMPLEMENTED;
424       break;
425     default:
426       Status = STATUS_NOT_SUPPORTED;
427     }
428
429   Irp->IoStatus.Status = Status;
430   Irp->IoStatus.Information = 0;
431
432   IoCompleteRequest(Irp, IO_NO_INCREMENT);
433
434   return(Status);
435 }
436
437 /* EOF */