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