:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / cdfs / volinfo.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/vfat/volume.c
24  * PURPOSE:          CDROM (ISO 9660) filesystem driver
25  * PROGRAMMER:       Art Yerkes
26  */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 #include "cdfs.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 static NTSTATUS
41 CdfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
42                            PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
43                            PULONG BufferLength)
44 {
45   ULONG LabelLength;
46
47   DPRINT("CdfsGetFsVolumeInformation() called\n");
48   DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
49   DPRINT("BufferLength %lu\n", *BufferLength);
50
51   DPRINT("Vpb %p\n", DeviceObject->Vpb);
52   LabelLength = DeviceObject->Vpb->VolumeLabelLength;
53
54   DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)));
55   DPRINT("LabelLength %lu\n", LabelLength);
56   DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
57
58   if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
59     return STATUS_INFO_LENGTH_MISMATCH;
60
61   if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
62     return STATUS_BUFFER_OVERFLOW;
63
64   /* valid entries */
65   FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
66   FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
67   wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
68
69   /* dummy entries */
70   FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
71   FsVolumeInfo->SupportsObjects = FALSE;
72
73   DPRINT("Finished FsdGetFsVolumeInformation()\n");
74
75   *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR));
76
77   DPRINT("BufferLength %lu\n", *BufferLength);
78
79   return(STATUS_SUCCESS);
80 }
81
82
83 static NTSTATUS
84 CdfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
85                               PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
86                               PULONG BufferLength)
87 {
88   DPRINT("CdfsGetFsAttributeInformation()\n");
89   DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
90   DPRINT("BufferLength %lu\n", *BufferLength);
91   DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
92
93   if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
94     return STATUS_INFO_LENGTH_MISMATCH;
95
96   if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
97     return STATUS_BUFFER_OVERFLOW;
98
99   FsAttributeInfo->FileSystemAttributes =
100     FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
101   FsAttributeInfo->MaximumComponentNameLength = 255;
102   FsAttributeInfo->FileSystemNameLength = 8;
103
104   memcpy(FsAttributeInfo->FileSystemName, L"CDFS", 8);
105
106   DPRINT("Finished FsdGetFsAttributeInformation()\n");
107
108   *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
109   DPRINT("BufferLength %lu\n", *BufferLength);
110
111   return(STATUS_SUCCESS);
112 }
113
114
115 static NTSTATUS
116 CdfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
117                          PFILE_FS_SIZE_INFORMATION FsSizeInfo,
118                          PULONG BufferLength)
119 {
120   PDEVICE_EXTENSION DeviceExt;
121   NTSTATUS Status = STATUS_SUCCESS;
122
123   DPRINT("CdfsGetFsSizeInformation()\n");
124   DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
125
126   if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
127     return(STATUS_BUFFER_OVERFLOW);
128
129   DeviceExt = DeviceObject->DeviceExtension;
130
131   FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
132   FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize;
133   FsSizeInfo->SectorsPerAllocationUnit = 1;
134   FsSizeInfo->BytesPerSector = BLOCKSIZE;
135
136   DPRINT("Finished FsdGetFsSizeInformation()\n");
137   if (NT_SUCCESS(Status))
138     *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
139
140   return(Status);
141 }
142
143
144 static NTSTATUS
145 CdfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
146                            PULONG BufferLength)
147 {
148   DPRINT("CdfsGetFsDeviceInformation()\n");
149   DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
150   DPRINT("BufferLength %lu\n", *BufferLength);
151   DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
152
153   if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
154     return(STATUS_BUFFER_OVERFLOW);
155
156   FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM;
157   FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
158
159   DPRINT("FsdGetFsDeviceInformation() finished.\n");
160
161   *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
162   DPRINT("BufferLength %lu\n", *BufferLength);
163
164   return(STATUS_SUCCESS);
165 }
166
167
168
169 NTSTATUS STDCALL
170 CdfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
171                            PIRP Irp)
172 {
173   FS_INFORMATION_CLASS FsInformationClass;
174   PIO_STACK_LOCATION Stack;
175   NTSTATUS Status = STATUS_SUCCESS;
176   PVOID SystemBuffer;
177   ULONG BufferLength;
178
179   DPRINT("CdfsQueryVolumeInformation() called\n");
180
181   Stack = IoGetCurrentIrpStackLocation(Irp);
182   FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
183   BufferLength = Stack->Parameters.QueryVolume.Length;
184   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
185
186   DPRINT("FsInformationClass %d\n", FsInformationClass);
187   DPRINT("SystemBuffer %x\n", SystemBuffer);
188
189   switch (FsInformationClass)
190     {
191       case FileFsVolumeInformation:
192         Status = CdfsGetFsVolumeInformation(DeviceObject,
193                                             SystemBuffer,
194                                             &BufferLength);
195         break;
196
197       case FileFsAttributeInformation:
198         Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
199                                                SystemBuffer,
200                                                &BufferLength);
201         break;
202
203       case FileFsSizeInformation:
204         Status = CdfsGetFsSizeInformation(DeviceObject,
205                                           SystemBuffer,
206                                           &BufferLength);
207         break;
208
209       case FileFsDeviceInformation:
210         Status = CdfsGetFsDeviceInformation(SystemBuffer,
211                                             &BufferLength);
212         break;
213
214       default:
215         Status = STATUS_NOT_SUPPORTED;
216     }
217
218   Irp->IoStatus.Status = Status;
219   if (NT_SUCCESS(Status))
220     Irp->IoStatus.Information =
221       Stack->Parameters.QueryVolume.Length - BufferLength;
222   else
223     Irp->IoStatus.Information = 0;
224   IoCompleteRequest(Irp, IO_NO_INCREMENT);
225
226   return(Status);
227 }
228
229
230 NTSTATUS STDCALL
231 CdfsSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
232                         PIRP Irp)
233 {
234   DPRINT("CdfsSetVolumeInformation() called\n");
235
236   Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
237   Irp->IoStatus.Information = 0;
238   IoCompleteRequest(Irp, IO_NO_INCREMENT);
239
240   return(STATUS_NOT_SUPPORTED);
241 }
242
243 /* EOF */