[CDFS]
[reactos.git] / reactos / drivers / filesystems / cdfs / volinfo.c
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 FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM;
163 FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
164
165 DPRINT("FsdGetFsDeviceInformation() finished.\n");
166
167 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
168 DPRINT("BufferLength %lu\n", *BufferLength);
169
170 return STATUS_SUCCESS;
171 }
172
173
174 static
175 NTSTATUS
176 CdfsGetFsFullSizeInformation(
177 PDEVICE_OBJECT DeviceObject,
178 PFILE_FS_FULL_SIZE_INFORMATION FsSizeInfo,
179 PULONG BufferLength)
180 {
181 PDEVICE_EXTENSION DeviceExt;
182 NTSTATUS Status = STATUS_SUCCESS;
183
184 DPRINT("CdfsGetFsFullSizeInformation()\n");
185 DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
186
187 if (*BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION))
188 return STATUS_BUFFER_OVERFLOW;
189
190 DeviceExt = DeviceObject->DeviceExtension;
191
192 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize;
193 FsSizeInfo->CallerAvailableAllocationUnits.QuadPart = 0;
194 FsSizeInfo->ActualAvailableAllocationUnits.QuadPart = 0;
195 FsSizeInfo->SectorsPerAllocationUnit = 1;
196 FsSizeInfo->BytesPerSector = BLOCKSIZE;
197
198 DPRINT("Finished CdfsGetFsFullSizeInformation()\n");
199 if (NT_SUCCESS(Status))
200 *BufferLength -= sizeof(FILE_FS_FULL_SIZE_INFORMATION);
201
202 return Status;
203 }
204
205
206 NTSTATUS
207 NTAPI
208 CdfsQueryVolumeInformation(
209 PCDFS_IRP_CONTEXT IrpContext)
210 {
211 PIRP Irp;
212 PDEVICE_OBJECT DeviceObject;
213 FS_INFORMATION_CLASS FsInformationClass;
214 PIO_STACK_LOCATION Stack;
215 NTSTATUS Status = STATUS_SUCCESS;
216 PVOID SystemBuffer;
217 ULONG BufferLength;
218
219 DPRINT("CdfsQueryVolumeInformation() called\n");
220
221 ASSERT(IrpContext);
222
223 Irp = IrpContext->Irp;
224 DeviceObject = IrpContext->DeviceObject;
225 Stack = IrpContext->Stack;
226 FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
227 BufferLength = Stack->Parameters.QueryVolume.Length;
228 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
229
230 DPRINT("FsInformationClass %d\n", FsInformationClass);
231 DPRINT("SystemBuffer %p\n", SystemBuffer);
232
233 switch (FsInformationClass)
234 {
235 case FileFsVolumeInformation:
236 Status = CdfsGetFsVolumeInformation(DeviceObject,
237 SystemBuffer,
238 &BufferLength);
239 break;
240
241 case FileFsAttributeInformation:
242 Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
243 SystemBuffer,
244 &BufferLength);
245 break;
246
247 case FileFsSizeInformation:
248 Status = CdfsGetFsSizeInformation(DeviceObject,
249 SystemBuffer,
250 &BufferLength);
251 break;
252
253 case FileFsDeviceInformation:
254 Status = CdfsGetFsDeviceInformation(DeviceObject,
255 SystemBuffer,
256 &BufferLength);
257 break;
258
259 case FileFsFullSizeInformation:
260 Status = CdfsGetFsFullSizeInformation(DeviceObject,
261 SystemBuffer,
262 &BufferLength);
263 break;
264
265 default:
266 Status = STATUS_NOT_SUPPORTED;
267 }
268
269 if (NT_SUCCESS(Status))
270 Irp->IoStatus.Information =
271 Stack->Parameters.QueryVolume.Length - BufferLength;
272 else
273 Irp->IoStatus.Information = 0;
274
275 return Status;
276 }
277
278
279 NTSTATUS
280 NTAPI
281 CdfsSetVolumeInformation(
282 PCDFS_IRP_CONTEXT IrpContext)
283 {
284 DPRINT("CdfsSetVolumeInformation() called\n");
285
286 ASSERT(IrpContext);
287
288 IrpContext->Irp->IoStatus.Information = 0;
289
290 return STATUS_NOT_SUPPORTED;
291 }
292
293 /* EOF */