2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GNU GPLv3 as published by the Free Software Foundation
4 * FILE: drivers/filesystems/fastfat/finfo.c
5 * PURPOSE: File Information support routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS ****************************************************************/
18 FatiQueryBasicInformation(IN PFAT_IRP_CONTEXT IrpContext
,
20 IN PFILE_OBJECT FileObject
,
21 IN OUT PFILE_BASIC_INFORMATION Buffer
,
25 RtlZeroMemory(Buffer
, sizeof(FILE_BASIC_INFORMATION
));
27 /* Deduct the written length */
28 *Length
-= sizeof(FILE_BASIC_INFORMATION
);
30 /* Check if it's a dir or a file */
31 if (FatNodeType(Fcb
) == FAT_NTC_FCB
)
33 // FIXME: Read dirent and get times from there
34 Buffer
->LastAccessTime
.QuadPart
= 0;
35 Buffer
->CreationTime
.QuadPart
= 0;
36 Buffer
->LastWriteTime
.QuadPart
= 0;
40 // FIXME: May not be really correct
41 Buffer
->FileAttributes
= 0;
42 DPRINT1("Basic info of a directory '%wZ' is requested!\n", &Fcb
->FullFileName
);
46 /* If attribute is 0, set normal */
47 if (Buffer
->FileAttributes
== 0)
48 Buffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
53 FatiQueryStandardInformation(IN PFAT_IRP_CONTEXT IrpContext
,
55 IN PFILE_OBJECT FileObject
,
56 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
60 RtlZeroMemory(Buffer
, sizeof(FILE_STANDARD_INFORMATION
));
62 /* Deduct the written length */
63 *Length
-= sizeof(FILE_STANDARD_INFORMATION
);
65 Buffer
->NumberOfLinks
= 1;
66 Buffer
->DeletePending
= FALSE
; // FIXME
68 /* Check if it's a dir or a file */
69 if (FatNodeType(Fcb
) == FAT_NTC_FCB
)
71 Buffer
->Directory
= FALSE
;
73 Buffer
->EndOfFile
.LowPart
= Fcb
->FatHandle
->Filesize
;
74 Buffer
->AllocationSize
= Buffer
->EndOfFile
;
75 DPRINT("Filesize %d, chain length %d\n", Fcb
->FatHandle
->Filesize
, Fcb
->FatHandle
->iChainLength
);
79 Buffer
->Directory
= TRUE
;
85 FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext
,
87 IN PFILE_OBJECT FileObject
,
88 IN OUT PFILE_INTERNAL_INFORMATION Buffer
,
96 FatiQueryNameInformation(IN PFAT_IRP_CONTEXT IrpContext
,
98 IN PFILE_OBJECT FileObject
,
99 IN OUT PFILE_NAME_INFORMATION Buffer
,
104 BOOLEAN Overflow
= FALSE
;
106 /* Deduct the minimum written length */
107 *Length
-= FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]);
109 /* Build full name if needed */
110 if (!Fcb
->FullFileName
.Buffer
)
112 FatSetFullFileNameInFcb(IrpContext
, Fcb
);
115 DPRINT("FullFileName %wZ\n", &Fcb
->FullFileName
);
117 if (*Length
< Fcb
->FullFileName
.Length
- Trim
)
119 /* Buffer can't fit all data */
125 /* Deduct the amount of bytes we are going to write */
126 ByteSize
= Fcb
->FullFileName
.Length
- Trim
;
131 RtlCopyMemory(Buffer
->FileName
,
132 Fcb
->FullFileName
.Buffer
,
136 Buffer
->FileNameLength
= Fcb
->FullFileName
.Length
- Trim
;
138 /* Is this a shortname query? */
141 /* Yes, not supported atm */
145 /* Indicate overflow by passing -1 as the length */
146 if (Overflow
) *Length
= -1;
151 FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext
,
154 PFILE_OBJECT FileObject
;
155 PIO_STACK_LOCATION IrpSp
;
156 FILE_INFORMATION_CLASS InfoClass
;
157 TYPE_OF_OPEN FileType
;
163 BOOLEAN VcbLocked
= FALSE
, FcbLocked
= FALSE
;
164 NTSTATUS Status
= STATUS_SUCCESS
;
166 /* Get IRP stack location */
167 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
169 /* Get the file object */
170 FileObject
= IrpSp
->FileObject
;
172 /* Copy variables to something with shorter names */
173 InfoClass
= IrpSp
->Parameters
.QueryFile
.FileInformationClass
;
174 Length
= IrpSp
->Parameters
.QueryFile
.Length
;
175 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
177 DPRINT("FatiQueryInformation\n", 0);
178 DPRINT("\tIrp = %08lx\n", Irp
);
179 DPRINT("\tLength = %08lx\n", Length
);
180 DPRINT("\tFileInformationClass = %08lx\n", InfoClass
);
181 DPRINT("\tBuffer = %08lx\n", Buffer
);
183 FileType
= FatDecodeFileObject(FileObject
, &Vcb
, &Fcb
, &Ccb
);
185 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb
, Fcb
, Ccb
, FileType
);
187 /* Acquire VCB lock */
188 if (InfoClass
== FileNameInformation
||
189 InfoClass
== FileAllInformation
)
191 if (!FatAcquireExclusiveVcb(IrpContext
, Vcb
))
196 /* Remember we locked the VCB */
200 /* Acquire FCB lock */
201 // FIXME: If not paging file
202 if (!FatAcquireSharedFcb(IrpContext
, Fcb
))
210 case FileBasicInformation
:
211 FatiQueryBasicInformation(IrpContext
, Fcb
, FileObject
, Buffer
, &Length
);
213 case FileStandardInformation
:
214 FatiQueryStandardInformation(IrpContext
, Fcb
, FileObject
, Buffer
, &Length
);
216 case FileInternalInformation
:
217 FatiQueryInternalInformation(IrpContext
, Fcb
, FileObject
, Buffer
, &Length
);
219 case FileNameInformation
:
220 FatiQueryNameInformation(IrpContext
, Fcb
, FileObject
, Buffer
, &Length
);
223 DPRINT1("Unimplemented information class %d requested\n", InfoClass
);
224 Status
= STATUS_INVALID_PARAMETER
;
227 /* Check for buffer overflow */
230 Status
= STATUS_BUFFER_OVERFLOW
;
234 /* Set IoStatus.Information to amount of filled bytes */
235 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryFile
.Length
- Length
;
237 /* Release FCB locks */
238 if (FcbLocked
) FatReleaseFcb(IrpContext
, Fcb
);
239 if (VcbLocked
) FatReleaseVcb(IrpContext
, Vcb
);
241 /* Complete request and return status */
242 FatCompleteRequest(IrpContext
, Irp
, Status
);
248 FatQueryInformation(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
251 BOOLEAN TopLevel
, CanWait
;
252 PFAT_IRP_CONTEXT IrpContext
;
256 Status
= STATUS_INVALID_DEVICE_REQUEST
;
258 /* Get CanWait flag */
259 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
!= NULL
)
260 CanWait
= IoIsOperationSynchronous(Irp
);
262 /* Enter FsRtl critical region */
263 FsRtlEnterFileSystem();
265 /* Set Top Level IRP if not set */
266 if (IoGetTopLevelIrp() == NULL
)
268 IoSetTopLevelIrp(Irp
);
272 /* Build an irp context */
273 IrpContext
= FatBuildIrpContext(Irp
, CanWait
);
275 /* Perform the actual read */
276 Status
= FatiQueryInformation(IrpContext
, Irp
);
278 /* Restore top level Irp */
279 if (TopLevel
) IoSetTopLevelIrp(NULL
);
281 /* Leave FsRtl critical region */
282 FsRtlExitFileSystem();
289 FatSetInformation(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
291 DPRINT1("FatSetInformation()\n");
292 return STATUS_NOT_IMPLEMENTED
;