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