migrate substitution keywords to SVN
[reactos.git] / reactos / drivers / fs / 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/fs/ntfs/volume.c
24 * PURPOSE: NTFS filesystem driver
25 * PROGRAMMER: Eric Kohl
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 #include "ntfs.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 static NTSTATUS
41 NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
42 PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
43 PULONG BufferLength)
44 {
45 DPRINT("NtfsGetFsVolumeInformation() called\n");
46 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
47 DPRINT("BufferLength %lu\n", *BufferLength);
48
49 DPRINT("Vpb %p\n", DeviceObject->Vpb);
50
51 DPRINT("Required length %lu\n",
52 sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
53 DPRINT("LabelLength %hu\n",
54 DeviceObject->Vpb->VolumeLabelLength);
55 DPRINT("Label %*.S\n",
56 DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
57 DeviceObject->Vpb->VolumeLabel);
58
59 if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
60 return STATUS_INFO_LENGTH_MISMATCH;
61
62 if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
63 return STATUS_BUFFER_OVERFLOW;
64
65 /* valid entries */
66 FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
67 FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
68 memcpy(FsVolumeInfo->VolumeLabel,
69 DeviceObject->Vpb->VolumeLabel,
70 DeviceObject->Vpb->VolumeLabelLength);
71
72 /* dummy entries */
73 FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
74 FsVolumeInfo->SupportsObjects = FALSE;
75
76 *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
77
78 DPRINT("BufferLength %lu\n", *BufferLength);
79 DPRINT("NtfsGetFsVolumeInformation() done\n");
80
81 return STATUS_SUCCESS;
82 }
83
84
85 static NTSTATUS
86 NtfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
87 PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
88 PULONG BufferLength)
89 {
90 DPRINT("NtfsGetFsAttributeInformation()\n");
91 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
92 DPRINT("BufferLength %lu\n", *BufferLength);
93 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
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;
103 FsAttributeInfo->MaximumComponentNameLength = 255;
104 FsAttributeInfo->FileSystemNameLength = 8;
105
106 memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
107
108 DPRINT("Finished NtfsGetFsAttributeInformation()\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 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 NTSTATUS
147 NtfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
148 PULONG BufferLength)
149 {
150 DPRINT("NtfsGetFsDeviceInformation()\n");
151 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
152 DPRINT("BufferLength %lu\n", *BufferLength);
153 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
154
155 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
156 return(STATUS_BUFFER_OVERFLOW);
157
158 FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
159 FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
160
161 DPRINT("NtfsGetFsDeviceInformation() finished.\n");
162
163 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
164 DPRINT("BufferLength %lu\n", *BufferLength);
165
166 return(STATUS_SUCCESS);
167 }
168
169
170
171 NTSTATUS STDCALL
172 NtfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
173 PIRP Irp)
174 {
175 FS_INFORMATION_CLASS FsInformationClass;
176 PIO_STACK_LOCATION Stack;
177 NTSTATUS Status = STATUS_SUCCESS;
178 PVOID SystemBuffer;
179 ULONG BufferLength;
180
181 DPRINT("NtfsQueryVolumeInformation() called\n");
182
183 Stack = IoGetCurrentIrpStackLocation(Irp);
184 FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
185 BufferLength = Stack->Parameters.QueryVolume.Length;
186 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
187
188 DPRINT("FsInformationClass %d\n", FsInformationClass);
189 DPRINT("SystemBuffer %x\n", SystemBuffer);
190
191 switch (FsInformationClass)
192 {
193 case FileFsVolumeInformation:
194 Status = NtfsGetFsVolumeInformation(DeviceObject,
195 SystemBuffer,
196 &BufferLength);
197 break;
198
199 case FileFsAttributeInformation:
200 Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
201 SystemBuffer,
202 &BufferLength);
203 break;
204
205 case FileFsSizeInformation:
206 Status = NtfsGetFsSizeInformation(DeviceObject,
207 SystemBuffer,
208 &BufferLength);
209 break;
210
211 case FileFsDeviceInformation:
212 Status = NtfsGetFsDeviceInformation(SystemBuffer,
213 &BufferLength);
214 break;
215
216 default:
217 Status = STATUS_NOT_SUPPORTED;
218 }
219
220 Irp->IoStatus.Status = Status;
221 if (NT_SUCCESS(Status))
222 Irp->IoStatus.Information =
223 Stack->Parameters.QueryVolume.Length - BufferLength;
224 else
225 Irp->IoStatus.Information = 0;
226 IoCompleteRequest(Irp, IO_NO_INCREMENT);
227
228 return(Status);
229 }
230
231
232 NTSTATUS STDCALL
233 NtfsSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
234 PIRP Irp)
235 {
236 DPRINT("NtfsSetVolumeInformation() called\n");
237
238 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
239 Irp->IoStatus.Information = 0;
240 IoCompleteRequest(Irp, IO_NO_INCREMENT);
241
242 return(STATUS_NOT_SUPPORTED);
243 }
244
245 /* EOF */