[NTFS]
[reactos.git] / 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 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 */