* Sync to trunk r63845.
[reactos.git] / drivers / filesystems / ntfs / 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/volume.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMER: Eric Kohl
24 */
25
26 /* INCLUDES *****************************************************************/
27
28 #include "ntfs.h"
29
30 #define NDEBUG
31 #include <debug.h>
32
33 /* FUNCTIONS ****************************************************************/
34
35 static
36 NTSTATUS
37 NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
38 PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
39 PULONG BufferLength)
40 {
41 DPRINT("NtfsGetFsVolumeInformation() called\n");
42 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
43 DPRINT("BufferLength %lu\n", *BufferLength);
44
45 DPRINT("Vpb %p\n", DeviceObject->Vpb);
46
47 DPRINT("Required length %lu\n",
48 sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
49 DPRINT("LabelLength %hu\n",
50 DeviceObject->Vpb->VolumeLabelLength);
51 DPRINT("Label %*.S\n",
52 DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
53 DeviceObject->Vpb->VolumeLabel);
54
55 if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
56 return STATUS_INFO_LENGTH_MISMATCH;
57
58 if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
59 return STATUS_BUFFER_OVERFLOW;
60
61 /* valid entries */
62 FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
63 FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
64 memcpy(FsVolumeInfo->VolumeLabel,
65 DeviceObject->Vpb->VolumeLabel,
66 DeviceObject->Vpb->VolumeLabelLength);
67
68 /* dummy entries */
69 FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
70 FsVolumeInfo->SupportsObjects = FALSE;
71
72 *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
73
74 DPRINT("BufferLength %lu\n", *BufferLength);
75 DPRINT("NtfsGetFsVolumeInformation() done\n");
76
77 return STATUS_SUCCESS;
78 }
79
80
81 static
82 NTSTATUS
83 NtfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
84 PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
85 PULONG BufferLength)
86 {
87 UNREFERENCED_PARAMETER(DeviceExt);
88
89 DPRINT("NtfsGetFsAttributeInformation()\n");
90 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
91 DPRINT("BufferLength %lu\n", *BufferLength);
92 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
93
94 if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
95 return STATUS_INFO_LENGTH_MISMATCH;
96
97 if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
98 return STATUS_BUFFER_OVERFLOW;
99
100 FsAttributeInfo->FileSystemAttributes =
101 FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
102 FsAttributeInfo->MaximumComponentNameLength = 255;
103 FsAttributeInfo->FileSystemNameLength = 8;
104
105 memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
106
107 DPRINT("Finished NtfsGetFsAttributeInformation()\n");
108
109 *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
110 DPRINT("BufferLength %lu\n", *BufferLength);
111
112 return STATUS_SUCCESS;
113 }
114
115
116 static
117 NTSTATUS
118 NtfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
119 PFILE_FS_SIZE_INFORMATION FsSizeInfo,
120 PULONG BufferLength)
121 {
122 PDEVICE_EXTENSION DeviceExt;
123 NTSTATUS Status = STATUS_SUCCESS;
124
125 DPRINT("NtfsGetFsSizeInformation()\n");
126 DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
127
128 if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
129 return STATUS_BUFFER_OVERFLOW;
130
131 DeviceExt = DeviceObject->DeviceExtension;
132
133 FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
134 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.SectorCount; /* ?? */
135 FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
136 FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
137
138 DPRINT("Finished NtfsGetFsSizeInformation()\n");
139 if (NT_SUCCESS(Status))
140 *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
141
142 return Status;
143 }
144
145
146 static
147 NTSTATUS
148 NtfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
149 PULONG BufferLength)
150 {
151 DPRINT("NtfsGetFsDeviceInformation()\n");
152 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
153 DPRINT("BufferLength %lu\n", *BufferLength);
154 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
155
156 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
157 return STATUS_BUFFER_OVERFLOW;
158
159 FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
160 FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
161
162 DPRINT("NtfsGetFsDeviceInformation() finished.\n");
163
164 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
165 DPRINT("BufferLength %lu\n", *BufferLength);
166
167 return STATUS_SUCCESS;
168 }
169
170
171 NTSTATUS
172 NtfsQueryVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
173 {
174 PIRP Irp;
175 PDEVICE_OBJECT DeviceObject;
176 FS_INFORMATION_CLASS FsInformationClass;
177 PIO_STACK_LOCATION Stack;
178 NTSTATUS Status = STATUS_SUCCESS;
179 PVOID SystemBuffer;
180 ULONG BufferLength;
181
182 DPRINT("NtfsQueryVolumeInformation() called\n");
183
184 ASSERT(IrpContext);
185
186 Irp = IrpContext->Irp;
187 DeviceObject = IrpContext->DeviceObject;
188 Stack = IoGetCurrentIrpStackLocation(Irp);
189 FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
190 BufferLength = Stack->Parameters.QueryVolume.Length;
191 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
192 RtlZeroMemory(SystemBuffer, BufferLength);
193
194 DPRINT("FsInformationClass %d\n", FsInformationClass);
195 DPRINT("SystemBuffer %p\n", SystemBuffer);
196
197 switch (FsInformationClass)
198 {
199 case FileFsVolumeInformation:
200 Status = NtfsGetFsVolumeInformation(DeviceObject,
201 SystemBuffer,
202 &BufferLength);
203 break;
204
205 case FileFsAttributeInformation:
206 Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
207 SystemBuffer,
208 &BufferLength);
209 break;
210
211 case FileFsSizeInformation:
212 Status = NtfsGetFsSizeInformation(DeviceObject,
213 SystemBuffer,
214 &BufferLength);
215 break;
216
217 case FileFsDeviceInformation:
218 Status = NtfsGetFsDeviceInformation(SystemBuffer,
219 &BufferLength);
220 break;
221
222 default:
223 Status = STATUS_NOT_SUPPORTED;
224 }
225
226 if (NT_SUCCESS(Status))
227 Irp->IoStatus.Information =
228 Stack->Parameters.QueryVolume.Length - BufferLength;
229 else
230 Irp->IoStatus.Information = 0;
231
232 return Status;
233 }
234
235
236 NTSTATUS
237 NtfsSetVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
238 {
239 PIRP Irp;
240
241 DPRINT("NtfsSetVolumeInformation() called\n");
242
243 ASSERT(IrpContext);
244
245 Irp = IrpContext->Irp;
246 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
247 Irp->IoStatus.Information = 0;
248
249 return STATUS_NOT_SUPPORTED;
250 }
251
252 /* EOF */