3 * Copyright (C) 2002 ReactOS Team
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.
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.
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.
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/dirctl.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMERS: Eric Kohl
24 * Hervé Poussineau (hpoussin@reactos.org)
27 /* INCLUDES *****************************************************************/
34 /* FUNCTIONS ****************************************************************/
37 * FUNCTION: Retrieve the standard file information
41 NtfsGetStandardInformation(PNTFS_FCB Fcb
,
42 PDEVICE_OBJECT DeviceObject
,
43 PFILE_STANDARD_INFORMATION StandardInfo
,
46 UNREFERENCED_PARAMETER(DeviceObject
);
48 DPRINT1("NtfsGetStandardInformation(%p, %p, %p, %p)\n", Fcb
, DeviceObject
, StandardInfo
, BufferLength
);
50 if (*BufferLength
< sizeof(FILE_STANDARD_INFORMATION
))
51 return STATUS_BUFFER_OVERFLOW
;
54 ASSERT(StandardInfo
!= NULL
);
57 RtlZeroMemory(StandardInfo
,
58 sizeof(FILE_STANDARD_INFORMATION
));
60 StandardInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
61 StandardInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
62 StandardInfo
->NumberOfLinks
= 0; /* FIXME */
63 StandardInfo
->DeletePending
= FALSE
;
64 StandardInfo
->Directory
= NtfsFCBIsDirectory(Fcb
);
66 *BufferLength
-= sizeof(FILE_STANDARD_INFORMATION
);
68 return STATUS_SUCCESS
;
74 NtfsGetPositionInformation(PFILE_OBJECT FileObject
,
75 PFILE_POSITION_INFORMATION PositionInfo
,
78 DPRINT1("NtfsGetPositionInformation(%p, %p, %p)\n", FileObject
, PositionInfo
, BufferLength
);
80 if (*BufferLength
< sizeof(FILE_POSITION_INFORMATION
))
81 return STATUS_BUFFER_OVERFLOW
;
83 PositionInfo
->CurrentByteOffset
.QuadPart
= FileObject
->CurrentByteOffset
.QuadPart
;
85 DPRINT("Getting position %I64x\n",
86 PositionInfo
->CurrentByteOffset
.QuadPart
);
88 *BufferLength
-= sizeof(FILE_POSITION_INFORMATION
);
90 return STATUS_SUCCESS
;
96 NtfsGetBasicInformation(PFILE_OBJECT FileObject
,
98 PDEVICE_OBJECT DeviceObject
,
99 PFILE_BASIC_INFORMATION BasicInfo
,
102 PFILENAME_ATTRIBUTE FileName
= &Fcb
->Entry
;
104 DPRINT1("NtfsGetBasicInformation(%p, %p, %p, %p, %p)\n", FileObject
, Fcb
, DeviceObject
, BasicInfo
, BufferLength
);
106 if (*BufferLength
< sizeof(FILE_BASIC_INFORMATION
))
107 return STATUS_BUFFER_OVERFLOW
;
109 BasicInfo
->CreationTime
.QuadPart
= FileName
->CreationTime
;
110 BasicInfo
->LastAccessTime
.QuadPart
= FileName
->LastAccessTime
;
111 BasicInfo
->LastWriteTime
.QuadPart
= FileName
->LastWriteTime
;
112 BasicInfo
->ChangeTime
.QuadPart
= FileName
->ChangeTime
;
114 NtfsFileFlagsToAttributes(FileName
->FileAttributes
, &BasicInfo
->FileAttributes
);
116 *BufferLength
-= sizeof(FILE_BASIC_INFORMATION
);
118 return STATUS_SUCCESS
;
123 * FUNCTION: Retrieve the file name information
127 NtfsGetNameInformation(PFILE_OBJECT FileObject
,
129 PDEVICE_OBJECT DeviceObject
,
130 PFILE_NAME_INFORMATION NameInfo
,
135 UNREFERENCED_PARAMETER(FileObject
);
136 UNREFERENCED_PARAMETER(DeviceObject
);
138 DPRINT1("NtfsGetNameInformation(%p, %p, %p, %p, %p)\n", FileObject
, Fcb
, DeviceObject
, NameInfo
, BufferLength
);
140 ASSERT(NameInfo
!= NULL
);
143 /* If buffer can't hold at least the file name length, bail out */
144 if (*BufferLength
< (ULONG
)FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
145 return STATUS_BUFFER_OVERFLOW
;
147 /* Save file name length, and as much file len, as buffer length allows */
148 NameInfo
->FileNameLength
= wcslen(Fcb
->PathName
) * sizeof(WCHAR
);
150 /* Calculate amount of bytes to copy not to overflow the buffer */
151 BytesToCopy
= min(NameInfo
->FileNameLength
,
152 *BufferLength
- FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]));
154 /* Fill in the bytes */
155 RtlCopyMemory(NameInfo
->FileName
, Fcb
->PathName
, BytesToCopy
);
157 /* Check if we could write more but are not able to */
158 if (*BufferLength
< NameInfo
->FileNameLength
+ (ULONG
)FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
160 /* Return number of bytes written */
161 *BufferLength
-= FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + BytesToCopy
;
162 return STATUS_BUFFER_OVERFLOW
;
165 /* We filled up as many bytes, as needed */
166 *BufferLength
-= (FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + NameInfo
->FileNameLength
);
168 return STATUS_SUCCESS
;
174 NtfsGetInternalInformation(PNTFS_FCB Fcb
,
175 PFILE_INTERNAL_INFORMATION InternalInfo
,
178 DPRINT1("NtfsGetInternalInformation(%p, %p, %p)\n", Fcb
, InternalInfo
, BufferLength
);
180 ASSERT(InternalInfo
);
183 if (*BufferLength
< sizeof(FILE_INTERNAL_INFORMATION
))
184 return STATUS_BUFFER_OVERFLOW
;
186 /* FIXME: get a real index, that can be used in a create operation */
187 InternalInfo
->IndexNumber
.QuadPart
= 0;
189 *BufferLength
-= sizeof(FILE_INTERNAL_INFORMATION
);
191 return STATUS_SUCCESS
;
196 NtfsGetNetworkOpenInformation(PNTFS_FCB Fcb
,
197 PDEVICE_EXTENSION DeviceExt
,
198 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo
,
201 PFILENAME_ATTRIBUTE FileName
= &Fcb
->Entry
;
203 DPRINT1("NtfsGetNetworkOpenInformation(%p, %p, %p, %p)\n", Fcb
, DeviceExt
, NetworkInfo
, BufferLength
);
205 if (*BufferLength
< sizeof(FILE_NETWORK_OPEN_INFORMATION
))
206 return(STATUS_BUFFER_OVERFLOW
);
208 NetworkInfo
->CreationTime
.QuadPart
= FileName
->CreationTime
;
209 NetworkInfo
->LastAccessTime
.QuadPart
= FileName
->LastAccessTime
;
210 NetworkInfo
->LastWriteTime
.QuadPart
= FileName
->LastWriteTime
;
211 NetworkInfo
->ChangeTime
.QuadPart
= FileName
->ChangeTime
;
213 NetworkInfo
->EndOfFile
.QuadPart
= FileName
->AllocatedSize
;
214 NetworkInfo
->AllocationSize
.QuadPart
= ROUND_UP(FileName
->AllocatedSize
, DeviceExt
->NtfsInfo
.BytesPerCluster
);
216 NtfsFileFlagsToAttributes(FileName
->FileAttributes
, &NetworkInfo
->FileAttributes
);
218 *BufferLength
-= sizeof(FILE_NETWORK_OPEN_INFORMATION
);
219 return STATUS_SUCCESS
;
223 * FUNCTION: Retrieve the specified file information
227 NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject
,
230 FILE_INFORMATION_CLASS FileInformationClass
;
231 PIO_STACK_LOCATION Stack
;
232 PFILE_OBJECT FileObject
;
236 NTSTATUS Status
= STATUS_SUCCESS
;
238 DPRINT1("NtfsQueryInformation(%p, %p)\n", DeviceObject
, Irp
);
240 Stack
= IoGetCurrentIrpStackLocation(Irp
);
241 FileInformationClass
= Stack
->Parameters
.QueryFile
.FileInformationClass
;
242 FileObject
= Stack
->FileObject
;
243 Fcb
= FileObject
->FsContext
;
245 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
246 BufferLength
= Stack
->Parameters
.QueryFile
.Length
;
248 switch (FileInformationClass
)
250 case FileStandardInformation
:
251 Status
= NtfsGetStandardInformation(Fcb
,
257 case FilePositionInformation
:
258 Status
= NtfsGetPositionInformation(FileObject
,
263 case FileBasicInformation
:
264 Status
= NtfsGetBasicInformation(FileObject
,
271 case FileNameInformation
:
272 Status
= NtfsGetNameInformation(FileObject
,
279 case FileInternalInformation
:
280 Status
= NtfsGetInternalInformation(Fcb
,
285 case FileNetworkOpenInformation
:
286 Status
= NtfsGetNetworkOpenInformation(Fcb
,
287 DeviceObject
->DeviceExtension
,
292 case FileAlternateNameInformation
:
293 case FileAllInformation
:
294 DPRINT1("Unimplemented information class %u\n", FileInformationClass
);
295 Status
= STATUS_NOT_IMPLEMENTED
;
299 DPRINT1("Unimplemented information class %u\n", FileInformationClass
);
300 Status
= STATUS_INVALID_PARAMETER
;
303 Irp
->IoStatus
.Status
= Status
;
305 if (NT_SUCCESS(Status
))
306 Irp
->IoStatus
.Information
=
307 Stack
->Parameters
.QueryFile
.Length
- BufferLength
;
309 Irp
->IoStatus
.Information
= 0;
311 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);