update for HEAD-2003091401
[reactos.git] / 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   ULONG LabelLength;
46
47   DPRINT("NtfsGetFsVolumeInformation() called\n");
48   DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
49   DPRINT("BufferLength %lu\n", *BufferLength);
50
51   DPRINT("Vpb %p\n", DeviceObject->Vpb);
52   LabelLength = DeviceObject->Vpb->VolumeLabelLength;
53
54   DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)));
55   DPRINT("LabelLength %lu\n", LabelLength);
56   DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
57
58   if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
59     return(STATUS_INFO_LENGTH_MISMATCH);
60
61   if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
62     return(STATUS_BUFFER_OVERFLOW);
63
64   /* valid entries */
65   FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
66   FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
67   wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
68
69   /* dummy entries */
70   FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
71   FsVolumeInfo->SupportsObjects = FALSE;
72
73   *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR));
74
75   DPRINT("BufferLength %lu\n", *BufferLength);
76   DPRINT("NtfsGetFsVolumeInformation() done\n");
77
78   return(STATUS_SUCCESS);
79 }
80
81
82 static 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 NTSTATUS
115 NtfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
116                          PFILE_FS_SIZE_INFORMATION FsSizeInfo,
117                          PULONG BufferLength)
118 {
119   PDEVICE_EXTENSION DeviceExt;
120   NTSTATUS Status = STATUS_SUCCESS;
121
122   DPRINT("NtfsGetFsSizeInformation()\n");
123   DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
124
125   if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
126     return(STATUS_BUFFER_OVERFLOW);
127
128   DeviceExt = DeviceObject->DeviceExtension;
129
130   FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
131   FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.SectorCount; /* ?? */
132   FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
133   FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
134
135   DPRINT("Finished NtfsGetFsSizeInformation()\n");
136   if (NT_SUCCESS(Status))
137     *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
138
139   return(Status);
140 }
141
142
143 static NTSTATUS
144 NtfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
145                            PULONG BufferLength)
146 {
147   DPRINT("NtfsGetFsDeviceInformation()\n");
148   DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
149   DPRINT("BufferLength %lu\n", *BufferLength);
150   DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
151
152   if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
153     return(STATUS_BUFFER_OVERFLOW);
154
155   FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
156   FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
157
158   DPRINT("NtfsGetFsDeviceInformation() finished.\n");
159
160   *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
161   DPRINT("BufferLength %lu\n", *BufferLength);
162
163   return(STATUS_SUCCESS);
164 }
165
166
167
168 NTSTATUS STDCALL
169 NtfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
170                            PIRP Irp)
171 {
172   FS_INFORMATION_CLASS FsInformationClass;
173   PIO_STACK_LOCATION Stack;
174   NTSTATUS Status = STATUS_SUCCESS;
175   PVOID SystemBuffer;
176   ULONG BufferLength;
177
178   DPRINT("NtfsQueryVolumeInformation() called\n");
179
180   Stack = IoGetCurrentIrpStackLocation(Irp);
181   FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
182   BufferLength = Stack->Parameters.QueryVolume.Length;
183   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
184
185   DPRINT("FsInformationClass %d\n", FsInformationClass);
186   DPRINT("SystemBuffer %x\n", SystemBuffer);
187
188   switch (FsInformationClass)
189     {
190       case FileFsVolumeInformation:
191         Status = NtfsGetFsVolumeInformation(DeviceObject,
192                                             SystemBuffer,
193                                             &BufferLength);
194         break;
195
196       case FileFsAttributeInformation:
197         Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
198                                                SystemBuffer,
199                                                &BufferLength);
200         break;
201
202       case FileFsSizeInformation:
203         Status = NtfsGetFsSizeInformation(DeviceObject,
204                                           SystemBuffer,
205                                           &BufferLength);
206         break;
207
208       case FileFsDeviceInformation:
209         Status = NtfsGetFsDeviceInformation(SystemBuffer,
210                                             &BufferLength);
211         break;
212
213       default:
214         Status = STATUS_NOT_SUPPORTED;
215     }
216
217   Irp->IoStatus.Status = Status;
218   if (NT_SUCCESS(Status))
219     Irp->IoStatus.Information =
220       Stack->Parameters.QueryVolume.Length - BufferLength;
221   else
222     Irp->IoStatus.Information = 0;
223   IoCompleteRequest(Irp, IO_NO_INCREMENT);
224
225   return(Status);
226 }
227
228
229 NTSTATUS STDCALL
230 NtfsSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
231                         PIRP Irp)
232 {
233   DPRINT("NtfsSetVolumeInformation() called\n");
234
235   Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
236   Irp->IoStatus.Information = 0;
237   IoCompleteRequest(Irp, IO_NO_INCREMENT);
238
239   return(STATUS_NOT_SUPPORTED);
240 }
241
242 /* EOF */