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