xref: /reactos/drivers/filesystems/cdfs/volinfo.c (revision c2c66aff)
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002, 2003 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 along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT:        See COPYING in the top level directory
21  * PROJECT:          ReactOS kernel
22  * FILE:             drivers/filesystems/cdfs/volume.c
23  * PURPOSE:          CDROM (ISO 9660) filesystem driver
24  * PROGRAMMER:       Art Yerkes
25  *                   Eric Kohl
26  */
27 
28 /* INCLUDES *****************************************************************/
29 
30 #include "cdfs.h"
31 
32 #define NDEBUG
33 #include <debug.h>
34 
35 /* FUNCTIONS ****************************************************************/
36 
37 static
38 NTSTATUS
39 CdfsGetFsVolumeInformation(
40     PDEVICE_OBJECT DeviceObject,
41     PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
42     PULONG BufferLength)
43 {
44     DPRINT("CdfsGetFsVolumeInformation() called\n");
45     DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
46     DPRINT("BufferLength %lu\n", *BufferLength);
47 
48     DPRINT("Vpb %p\n", DeviceObject->Vpb);
49 
50     DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength));
51     DPRINT("LabelLength %hu\n", DeviceObject->Vpb->VolumeLabelLength);
52     DPRINT("Label %.*S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel);
53 
54     if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
55         return STATUS_INFO_LENGTH_MISMATCH;
56 
57     if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
58         return STATUS_BUFFER_OVERFLOW;
59 
60     /* valid entries */
61     FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
62     FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
63     memcpy(FsVolumeInfo->VolumeLabel,
64            DeviceObject->Vpb->VolumeLabel,
65            DeviceObject->Vpb->VolumeLabelLength);
66 
67     /* dummy entries */
68     FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
69     FsVolumeInfo->SupportsObjects = FALSE;
70 
71     DPRINT("Finished FsdGetFsVolumeInformation()\n");
72 
73     *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
74 
75     DPRINT("BufferLength %lu\n", *BufferLength);
76 
77     return STATUS_SUCCESS;
78 }
79 
80 
81 static
82 NTSTATUS
83 CdfsGetFsAttributeInformation(
84     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     UNREFERENCED_PARAMETER(DeviceExt);
94 
95     if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
96         return STATUS_INFO_LENGTH_MISMATCH;
97 
98     if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
99         return STATUS_BUFFER_OVERFLOW;
100 
101     FsAttributeInfo->FileSystemAttributes =
102         FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_READ_ONLY_VOLUME;
103     FsAttributeInfo->MaximumComponentNameLength = 255;
104     FsAttributeInfo->FileSystemNameLength = 8;
105 
106     memcpy(FsAttributeInfo->FileSystemName, L"CDFS", 8);
107 
108     DPRINT("Finished FsdGetFsAttributeInformation()\n");
109 
110     *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
111     DPRINT("BufferLength %lu\n", *BufferLength);
112 
113     return STATUS_SUCCESS;
114 }
115 
116 
117 static NTSTATUS
118 CdfsGetFsSizeInformation(
119     PDEVICE_OBJECT DeviceObject,
120     PFILE_FS_SIZE_INFORMATION FsSizeInfo,
121     PULONG BufferLength)
122 {
123     PDEVICE_EXTENSION DeviceExt;
124     NTSTATUS Status = STATUS_SUCCESS;
125 
126     DPRINT("CdfsGetFsSizeInformation()\n");
127     DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
128 
129     if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
130         return STATUS_BUFFER_OVERFLOW;
131 
132     DeviceExt = DeviceObject->DeviceExtension;
133 
134     FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
135     FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize;
136     FsSizeInfo->SectorsPerAllocationUnit = 1;
137     FsSizeInfo->BytesPerSector = BLOCKSIZE;
138 
139     DPRINT("Finished FsdGetFsSizeInformation()\n");
140     if (NT_SUCCESS(Status))
141         *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
142 
143     return Status;
144 }
145 
146 
147 static
148 NTSTATUS
149 CdfsGetFsDeviceInformation(
150     PDEVICE_OBJECT DeviceObject,
151     PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
152     PULONG BufferLength)
153 {
154     DPRINT("CdfsGetFsDeviceInformation()\n");
155     DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
156     DPRINT("BufferLength %lu\n", *BufferLength);
157     DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
158 
159     if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
160         return STATUS_BUFFER_OVERFLOW;
161 
162     if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
163         FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM;
164     else
165         FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
166 
167     FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
168 
169     DPRINT("FsdGetFsDeviceInformation() finished.\n");
170 
171     *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
172     DPRINT("BufferLength %lu\n", *BufferLength);
173 
174     return STATUS_SUCCESS;
175 }
176 
177 
178 static
179 NTSTATUS
180 CdfsGetFsFullSizeInformation(
181     PDEVICE_OBJECT DeviceObject,
182     PFILE_FS_FULL_SIZE_INFORMATION FsSizeInfo,
183     PULONG BufferLength)
184 {
185     PDEVICE_EXTENSION DeviceExt;
186     NTSTATUS Status = STATUS_SUCCESS;
187 
188     DPRINT("CdfsGetFsFullSizeInformation()\n");
189     DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
190 
191     if (*BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION))
192         return STATUS_BUFFER_OVERFLOW;
193 
194     DeviceExt = DeviceObject->DeviceExtension;
195 
196     FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize;
197     FsSizeInfo->CallerAvailableAllocationUnits.QuadPart = 0;
198     FsSizeInfo->ActualAvailableAllocationUnits.QuadPart = 0;
199     FsSizeInfo->SectorsPerAllocationUnit = 1;
200     FsSizeInfo->BytesPerSector = BLOCKSIZE;
201 
202     DPRINT("Finished CdfsGetFsFullSizeInformation()\n");
203     if (NT_SUCCESS(Status))
204         *BufferLength -= sizeof(FILE_FS_FULL_SIZE_INFORMATION);
205 
206     return Status;
207 }
208 
209 
210 NTSTATUS
211 NTAPI
212 CdfsQueryVolumeInformation(
213     PCDFS_IRP_CONTEXT IrpContext)
214 {
215     PIRP Irp;
216     PDEVICE_OBJECT DeviceObject;
217     FS_INFORMATION_CLASS FsInformationClass;
218     PIO_STACK_LOCATION Stack;
219     NTSTATUS Status = STATUS_SUCCESS;
220     PVOID SystemBuffer;
221     ULONG BufferLength;
222 
223     DPRINT("CdfsQueryVolumeInformation() called\n");
224 
225     ASSERT(IrpContext);
226 
227     Irp = IrpContext->Irp;
228     DeviceObject = IrpContext->DeviceObject;
229     Stack = IrpContext->Stack;
230     FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
231     BufferLength = Stack->Parameters.QueryVolume.Length;
232     SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
233 
234     DPRINT("FsInformationClass %d\n", FsInformationClass);
235     DPRINT("SystemBuffer %p\n", SystemBuffer);
236 
237     switch (FsInformationClass)
238     {
239         case FileFsVolumeInformation:
240             Status = CdfsGetFsVolumeInformation(DeviceObject,
241                                                 SystemBuffer,
242                                                 &BufferLength);
243             break;
244 
245         case FileFsAttributeInformation:
246             Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
247                                                    SystemBuffer,
248                                                    &BufferLength);
249             break;
250 
251         case FileFsSizeInformation:
252             Status = CdfsGetFsSizeInformation(DeviceObject,
253                                               SystemBuffer,
254                                               &BufferLength);
255             break;
256 
257         case FileFsDeviceInformation:
258             Status = CdfsGetFsDeviceInformation(DeviceObject,
259                                                 SystemBuffer,
260                                                 &BufferLength);
261             break;
262 
263         case FileFsFullSizeInformation:
264             Status = CdfsGetFsFullSizeInformation(DeviceObject,
265                                                   SystemBuffer,
266                                                   &BufferLength);
267             break;
268 
269         default:
270             Status = STATUS_NOT_SUPPORTED;
271     }
272 
273     if (NT_SUCCESS(Status))
274         Irp->IoStatus.Information =
275         Stack->Parameters.QueryVolume.Length - BufferLength;
276     else
277         Irp->IoStatus.Information = 0;
278 
279     return Status;
280 }
281 
282 
283 NTSTATUS
284 NTAPI
285 CdfsSetVolumeInformation(
286     PCDFS_IRP_CONTEXT IrpContext)
287 {
288     DPRINT("CdfsSetVolumeInformation() called\n");
289 
290     ASSERT(IrpContext);
291 
292     IrpContext->Irp->IoStatus.Information = 0;
293 
294     return STATUS_NOT_SUPPORTED;
295 }
296 
297 /* EOF */
298