1 /* $Id: finfo.c,v 1.37 2004/08/28 22:19:12 navaraf Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: drivers/fs/vfat/finfo.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
22 /* FUNCTIONS ****************************************************************/
25 VfatGetStandardInformation(PVFATFCB FCB
,
26 PFILE_STANDARD_INFORMATION StandardInfo
,
29 * FUNCTION: Retrieve the standard file information
33 if (*BufferLength
< sizeof(FILE_STANDARD_INFORMATION
))
34 return STATUS_BUFFER_OVERFLOW
;
37 assert (StandardInfo
!= NULL
);
40 if (vfatFCBIsDirectory(FCB
))
42 StandardInfo
->AllocationSize
.QuadPart
= 0LL;
43 StandardInfo
->EndOfFile
.QuadPart
= 0LL;
44 StandardInfo
->Directory
= TRUE
;
48 StandardInfo
->AllocationSize
= FCB
->RFCB
.AllocationSize
;
49 StandardInfo
->EndOfFile
= FCB
->RFCB
.FileSize
;
50 StandardInfo
->Directory
= FALSE
;
52 StandardInfo
->NumberOfLinks
= 0;
53 StandardInfo
->DeletePending
= FCB
->Flags
& FCB_DELETE_PENDING
? TRUE
: FALSE
;
55 *BufferLength
-= sizeof(FILE_STANDARD_INFORMATION
);
56 return(STATUS_SUCCESS
);
60 VfatSetPositionInformation(PFILE_OBJECT FileObject
,
61 PFILE_POSITION_INFORMATION PositionInfo
)
63 DPRINT ("FsdSetPositionInformation()\n");
65 DPRINT ("PositionInfo %x\n", PositionInfo
);
66 DPRINT ("Setting position %d\n", PositionInfo
->CurrentByteOffset
.u
.LowPart
);
67 memcpy (&FileObject
->CurrentByteOffset
, &PositionInfo
->CurrentByteOffset
,
68 sizeof (LARGE_INTEGER
));
70 return (STATUS_SUCCESS
);
74 VfatGetPositionInformation(PFILE_OBJECT FileObject
,
76 PDEVICE_OBJECT DeviceObject
,
77 PFILE_POSITION_INFORMATION PositionInfo
,
80 DPRINT ("VfatGetPositionInformation()\n");
82 if (*BufferLength
< sizeof(FILE_POSITION_INFORMATION
))
83 return STATUS_BUFFER_OVERFLOW
;
85 PositionInfo
->CurrentByteOffset
.QuadPart
=
86 FileObject
->CurrentByteOffset
.QuadPart
;
88 DPRINT("Getting position %I64x\n",
89 PositionInfo
->CurrentByteOffset
.QuadPart
);
91 *BufferLength
-= sizeof(FILE_POSITION_INFORMATION
);
92 return(STATUS_SUCCESS
);
96 VfatSetBasicInformation(PFILE_OBJECT FileObject
,
98 PDEVICE_EXTENSION DeviceExt
,
99 PFILE_BASIC_INFORMATION BasicInfo
)
101 DPRINT("VfatSetBasicInformation()\n");
103 assert (NULL
!= FileObject
);
104 assert (NULL
!= FCB
);
105 assert (NULL
!= DeviceExt
);
106 assert (NULL
!= BasicInfo
);
107 /* Check volume label bit */
108 assert(0 == (FCB
->entry
.Attrib
& 0x08));
110 FsdFileTimeToDosDateTime((TIME
*)&(BasicInfo
->CreationTime
),
111 &(FCB
->entry
.CreationDate
),
112 &(FCB
->entry
.CreationTime
));
113 FsdFileTimeToDosDateTime((TIME
*)&(BasicInfo
->LastAccessTime
),
114 &(FCB
->entry
.AccessDate
),
116 FsdFileTimeToDosDateTime((TIME
*)&(BasicInfo
->LastWriteTime
),
117 &(FCB
->entry
.UpdateDate
),
118 &(FCB
->entry
.UpdateTime
));
120 FCB
->entry
.Attrib
= (unsigned char)((FCB
->entry
.Attrib
&
121 (FILE_ATTRIBUTE_DIRECTORY
| 0x48)) |
122 (BasicInfo
->FileAttributes
&
123 (FILE_ATTRIBUTE_ARCHIVE
|
124 FILE_ATTRIBUTE_SYSTEM
|
125 FILE_ATTRIBUTE_HIDDEN
|
126 FILE_ATTRIBUTE_READONLY
)));
127 DPRINT("Setting attributes 0x%02x\n", FCB
->entry
.Attrib
);
129 VfatUpdateEntry(FCB
);
131 return(STATUS_SUCCESS
);
135 VfatGetBasicInformation(PFILE_OBJECT FileObject
,
137 PDEVICE_OBJECT DeviceObject
,
138 PFILE_BASIC_INFORMATION BasicInfo
,
141 DPRINT("VfatGetBasicInformation()\n");
143 if (*BufferLength
< sizeof(FILE_BASIC_INFORMATION
))
144 return STATUS_BUFFER_OVERFLOW
;
146 FsdDosDateTimeToFileTime(FCB
->entry
.CreationDate
,
147 FCB
->entry
.CreationTime
,
148 (TIME
*)&BasicInfo
->CreationTime
);
149 FsdDosDateTimeToFileTime(FCB
->entry
.AccessDate
,
151 (TIME
*)&BasicInfo
->LastAccessTime
);
152 FsdDosDateTimeToFileTime(FCB
->entry
.UpdateDate
,
153 FCB
->entry
.UpdateTime
,
154 (TIME
*)&BasicInfo
->LastWriteTime
);
155 BasicInfo
->ChangeTime
= BasicInfo
->LastWriteTime
;
157 BasicInfo
->FileAttributes
= FCB
->entry
.Attrib
& 0x3f;
158 /* Synthesize FILE_ATTRIBUTE_NORMAL */
159 if (0 == (BasicInfo
->FileAttributes
& (FILE_ATTRIBUTE_DIRECTORY
|
160 FILE_ATTRIBUTE_ARCHIVE
|
161 FILE_ATTRIBUTE_SYSTEM
|
162 FILE_ATTRIBUTE_HIDDEN
|
163 FILE_ATTRIBUTE_READONLY
)))
165 BasicInfo
->FileAttributes
|= FILE_ATTRIBUTE_NORMAL
;
167 DPRINT("Getting attributes 0x%02x\n", BasicInfo
->FileAttributes
);
169 *BufferLength
-= sizeof(FILE_BASIC_INFORMATION
);
170 return(STATUS_SUCCESS
);
175 VfatSetDispositionInformation(PFILE_OBJECT FileObject
,
177 PDEVICE_OBJECT DeviceObject
,
178 PFILE_DISPOSITION_INFORMATION DispositionInfo
)
180 NTSTATUS Status
= STATUS_SUCCESS
;
182 PDEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
184 DPRINT ("FsdSetDispositionInformation()\n");
186 assert (DeviceExt
!= NULL
);
187 assert (DeviceExt
->FatInfo
.BytesPerCluster
!= 0);
188 assert (FCB
!= NULL
);
190 if (FCB
->entry
.Attrib
& FILE_ATTRIBUTE_READONLY
)
192 return STATUS_CANNOT_DELETE
;
195 if (vfatFCBIsRoot(FCB
) ||
196 (FCB
->LongNameU
.Length
== sizeof(WCHAR
) && FCB
->LongNameU
.Buffer
[0] == L
'.') ||
197 (FCB
->LongNameU
.Length
== 2 * sizeof(WCHAR
) && FCB
->LongNameU
.Buffer
[0] == L
'.' && FCB
->LongNameU
.Buffer
[1] == L
'.'))
199 // we cannot delete a '.', '..' or the root directory
200 return STATUS_ACCESS_DENIED
;
203 if (DispositionInfo
->DoDeleteFile
)
205 if (MmFlushImageSection (FileObject
->SectionObjectPointer
, MmFlushForDelete
))
207 if (FCB
->RefCount
> 1)
209 DPRINT1("%d %x\n", FCB
->RefCount
, CcGetFileObjectFromSectionPtrs(FileObject
->SectionObjectPointer
));
210 Status
= STATUS_ACCESS_DENIED
;
214 FCB
->Flags
|= FCB_DELETE_PENDING
;
215 FileObject
->DeletePending
= TRUE
;
220 DPRINT("MmFlushImageSection returned FALSE\n");
221 Status
= STATUS_CANNOT_DELETE
;
223 if (NT_SUCCESS(Status
) && vfatFCBIsDirectory(FCB
))
225 if (!VfatIsDirectoryEmpty(FCB
))
227 Status
= STATUS_DIRECTORY_NOT_EMPTY
;
228 FCB
->Flags
&= ~FCB_DELETE_PENDING
;
229 FileObject
->DeletePending
= FALSE
;
233 Status
= STATUS_SUCCESS
;
239 FileObject
->DeletePending
= FALSE
;
245 VfatGetNameInformation(PFILE_OBJECT FileObject
,
247 PDEVICE_OBJECT DeviceObject
,
248 PFILE_NAME_INFORMATION NameInfo
,
251 * FUNCTION: Retrieve the file name information
255 assert (NameInfo
!= NULL
);
256 assert (FCB
!= NULL
);
258 if (*BufferLength
< sizeof(FILE_NAME_INFORMATION
) + FCB
->PathNameU
.Length
+ sizeof(WCHAR
))
259 return STATUS_BUFFER_OVERFLOW
;
261 NameInfo
->FileNameLength
= FCB
->PathNameU
.Length
;
262 memcpy(NameInfo
->FileName
, FCB
->PathNameU
.Buffer
, FCB
->PathNameU
.Length
);
263 NameInfo
->FileName
[FCB
->PathNameU
.Length
/ sizeof(WCHAR
)] = 0;
265 *BufferLength
-= (sizeof(FILE_NAME_INFORMATION
) + FCB
->PathNameU
.Length
+ sizeof(WCHAR
));
267 return STATUS_SUCCESS
;
271 VfatGetInternalInformation(PVFATFCB Fcb
,
272 PFILE_INTERNAL_INFORMATION InternalInfo
,
275 assert (InternalInfo
);
278 if (*BufferLength
< sizeof(FILE_INTERNAL_INFORMATION
))
279 return STATUS_BUFFER_OVERFLOW
;
280 // FIXME: get a real index, that can be used in a create operation
281 InternalInfo
->IndexNumber
.QuadPart
= 0;
282 *BufferLength
-= sizeof(FILE_INTERNAL_INFORMATION
);
283 return STATUS_SUCCESS
;
288 VfatGetNetworkOpenInformation(PVFATFCB Fcb
,
289 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo
,
292 * FUNCTION: Retrieve the file network open information
295 assert (NetworkInfo
);
298 if (*BufferLength
< sizeof(FILE_NETWORK_OPEN_INFORMATION
))
299 return(STATUS_BUFFER_OVERFLOW
);
301 FsdDosDateTimeToFileTime(Fcb
->entry
.CreationDate
,
302 Fcb
->entry
.CreationTime
,
303 &NetworkInfo
->CreationTime
);
304 FsdDosDateTimeToFileTime(Fcb
->entry
.AccessDate
,
306 &NetworkInfo
->LastAccessTime
);
307 FsdDosDateTimeToFileTime(Fcb
->entry
.UpdateDate
,
308 Fcb
->entry
.UpdateTime
,
309 &NetworkInfo
->LastWriteTime
);
310 NetworkInfo
->ChangeTime
= NetworkInfo
->LastWriteTime
;
311 if (vfatFCBIsDirectory(Fcb
))
313 NetworkInfo
->EndOfFile
.QuadPart
= 0L;
314 NetworkInfo
->AllocationSize
.QuadPart
= 0L;
318 NetworkInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
319 NetworkInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
321 NetworkInfo
->FileAttributes
= Fcb
->entry
.Attrib
& 0x3f;
323 *BufferLength
-= sizeof(FILE_NETWORK_OPEN_INFORMATION
);
324 return STATUS_SUCCESS
;
329 VfatGetAllInformation(PFILE_OBJECT FileObject
,
331 PFILE_ALL_INFORMATION Info
,
334 * FUNCTION: Retrieve the all file information
341 if (*BufferLength
< sizeof(FILE_ALL_INFORMATION
) + Fcb
->PathNameU
.Length
+ sizeof(WCHAR
))
342 return(STATUS_BUFFER_OVERFLOW
);
344 /* Basic Information */
345 FsdDosDateTimeToFileTime(Fcb
->entry
.CreationDate
,
346 Fcb
->entry
.CreationTime
,
347 (TIME
*)&Info
->BasicInformation
.CreationTime
);
348 FsdDosDateTimeToFileTime(Fcb
->entry
.AccessDate
,
350 (TIME
*)&Info
->BasicInformation
.LastAccessTime
);
351 FsdDosDateTimeToFileTime(Fcb
->entry
.UpdateDate
,
352 Fcb
->entry
.UpdateTime
,
353 (TIME
*)&Info
->BasicInformation
.LastWriteTime
);
354 Info
->BasicInformation
.ChangeTime
= Info
->BasicInformation
.LastWriteTime
;
355 Info
->BasicInformation
.FileAttributes
= Fcb
->entry
.Attrib
& 0x3f;
357 /* Standard Information */
358 if (vfatFCBIsDirectory(Fcb
))
360 Info
->StandardInformation
.AllocationSize
.QuadPart
= 0LL;
361 Info
->StandardInformation
.EndOfFile
.QuadPart
= 0LL;
362 Info
->StandardInformation
.Directory
= TRUE
;
366 Info
->StandardInformation
.AllocationSize
= Fcb
->RFCB
.AllocationSize
;
367 Info
->StandardInformation
.EndOfFile
= Fcb
->RFCB
.FileSize
;
368 Info
->StandardInformation
.Directory
= FALSE
;
370 Info
->StandardInformation
.NumberOfLinks
= 0;
371 Info
->StandardInformation
.DeletePending
= Fcb
->Flags
& FCB_DELETE_PENDING
? TRUE
: FALSE
;
373 /* Internal Information */
374 /* FIXME: get a real index, that can be used in a create operation */
375 Info
->InternalInformation
.IndexNumber
.QuadPart
= 0;
378 Info
->EaInformation
.EaSize
= 0;
380 /* Access Information */
381 /* The IO-Manager adds this information */
383 /* Position Information */
384 Info
->PositionInformation
.CurrentByteOffset
.QuadPart
= FileObject
->CurrentByteOffset
.QuadPart
;
386 /* Mode Information */
387 /* The IO-Manager adds this information */
389 /* Alignment Information */
390 /* The IO-Manager adds this information */
392 /* Name Information */
393 Info
->NameInformation
.FileNameLength
= Fcb
->PathNameU
.Length
;
394 RtlCopyMemory(Info
->NameInformation
.FileName
, Fcb
->PathNameU
.Buffer
, Fcb
->PathNameU
.Length
);
395 Info
->NameInformation
.FileName
[Fcb
->PathNameU
.Length
/ sizeof(WCHAR
)] = 0;
397 *BufferLength
-= (sizeof(FILE_ALL_INFORMATION
) + Fcb
->PathNameU
.Length
+ sizeof(WCHAR
));
399 return STATUS_SUCCESS
;
402 VOID
UpdateFileSize(PFILE_OBJECT FileObject
, PVFATFCB Fcb
, ULONG Size
, ULONG ClusterSize
)
406 Fcb
->RFCB
.AllocationSize
.QuadPart
= ROUND_UP(Size
, ClusterSize
);
410 Fcb
->RFCB
.AllocationSize
.QuadPart
= (LONGLONG
)0;
412 if (!vfatFCBIsDirectory(Fcb
))
414 Fcb
->entry
.FileSize
= Size
;
416 Fcb
->RFCB
.FileSize
.QuadPart
= Size
;
417 Fcb
->RFCB
.ValidDataLength
.QuadPart
= Size
;
419 if (FileObject
->SectionObjectPointer
->SharedCacheMap
!= NULL
)
421 CcSetFileSizes(FileObject
, (PCC_FILE_SIZES
)&Fcb
->RFCB
.AllocationSize
);
426 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject
,
428 PDEVICE_EXTENSION DeviceExt
,
429 PLARGE_INTEGER AllocationSize
)
432 ULONG Cluster
, FirstCluster
;
435 ULONG ClusterSize
= DeviceExt
->FatInfo
.BytesPerCluster
;
436 ULONG NewSize
= AllocationSize
->u
.LowPart
;
438 BOOL AllocSizeChanged
= FALSE
;
440 DPRINT("VfatSetAllocationSizeInformation()\n");
442 OldSize
= Fcb
->entry
.FileSize
;
443 if (AllocationSize
->u
.HighPart
> 0)
445 return STATUS_INVALID_PARAMETER
;
447 if (OldSize
== NewSize
)
449 return(STATUS_SUCCESS
);
452 FirstCluster
= vfatDirEntryGetFirstCluster (DeviceExt
, &Fcb
->entry
);
454 if (NewSize
> Fcb
->RFCB
.AllocationSize
.u
.LowPart
)
456 AllocSizeChanged
= TRUE
;
457 if (FirstCluster
== 0)
459 Fcb
->LastCluster
= Fcb
->LastOffset
= 0;
460 Status
= NextCluster (DeviceExt
, FirstCluster
, &FirstCluster
, TRUE
);
461 if (!NT_SUCCESS(Status
))
463 DPRINT1("NextCluster failed. Status = %x\n", Status
);
466 if (FirstCluster
== 0xffffffff)
468 return STATUS_DISK_FULL
;
470 Status
= OffsetToCluster(DeviceExt
, FirstCluster
,
471 ROUND_DOWN(NewSize
- 1, ClusterSize
),
473 if (NCluster
== 0xffffffff || !NT_SUCCESS(Status
))
476 NCluster
= Cluster
= FirstCluster
;
477 Status
= STATUS_SUCCESS
;
478 while (NT_SUCCESS(Status
) && Cluster
!= 0xffffffff && Cluster
> 1)
480 Status
= NextCluster (DeviceExt
, FirstCluster
, &NCluster
, FALSE
);
481 WriteCluster (DeviceExt
, Cluster
, 0);
484 return STATUS_DISK_FULL
;
486 Fcb
->entry
.FirstCluster
= (unsigned short)(FirstCluster
& 0x0000FFFF);
487 Fcb
->entry
.FirstClusterHigh
= (unsigned short)((FirstCluster
& 0xFFFF0000) >> 16);
491 if (Fcb
->LastCluster
> 0 &&
492 (Fcb
->RFCB
.AllocationSize
.u
.LowPart
- ClusterSize
) > Fcb
->LastOffset
)
494 Status
= OffsetToCluster(DeviceExt
, Fcb
->LastCluster
,
495 Fcb
->RFCB
.AllocationSize
.u
.LowPart
-
496 ClusterSize
- Fcb
->LastOffset
,
501 Status
= OffsetToCluster(DeviceExt
, FirstCluster
,
502 Fcb
->RFCB
.AllocationSize
.u
.LowPart
- ClusterSize
,
506 Fcb
->LastCluster
= Cluster
;
507 Fcb
->LastOffset
= Fcb
->RFCB
.AllocationSize
.u
.LowPart
- ClusterSize
;
509 /* FIXME: Check status */
510 /* Cluster points now to the last cluster within the chain */
511 Status
= OffsetToCluster(DeviceExt
, FirstCluster
,
512 ROUND_DOWN(NewSize
- 1, ClusterSize
),
514 if (NCluster
== 0xffffffff || !NT_SUCCESS(Status
))
518 Status
= NextCluster (DeviceExt
, FirstCluster
, &NCluster
, FALSE
);
519 WriteCluster(DeviceExt
, Cluster
, 0xffffffff);
521 while (NT_SUCCESS(Status
) && Cluster
!= 0xffffffff && Cluster
> 1)
523 Status
= NextCluster (DeviceExt
, FirstCluster
, &NCluster
, FALSE
);
524 WriteCluster (DeviceExt
, Cluster
, 0);
527 return STATUS_DISK_FULL
;
530 UpdateFileSize(FileObject
, Fcb
, NewSize
, ClusterSize
);
532 else if (NewSize
+ ClusterSize
<= Fcb
->RFCB
.AllocationSize
.u
.LowPart
)
534 AllocSizeChanged
= TRUE
;
535 /* FIXME: Use the cached cluster/offset better way. */
536 Fcb
->LastCluster
= Fcb
->LastCluster
= 0;
537 UpdateFileSize(FileObject
, Fcb
, NewSize
, ClusterSize
);
540 Status
= OffsetToCluster(DeviceExt
, FirstCluster
,
541 ROUND_DOWN(NewSize
- 1, ClusterSize
),
545 Status
= NextCluster (DeviceExt
, FirstCluster
, &NCluster
, FALSE
);
546 WriteCluster(DeviceExt
, Cluster
, 0xffffffff);
551 Fcb
->entry
.FirstCluster
= 0;
552 Fcb
->entry
.FirstClusterHigh
= 0;
554 NCluster
= Cluster
= FirstCluster
;
555 Status
= STATUS_SUCCESS
;
557 while (NT_SUCCESS(Status
) && 0xffffffff != Cluster
&& Cluster
> 1)
559 Status
= NextCluster (DeviceExt
, FirstCluster
, &NCluster
, FALSE
);
560 WriteCluster (DeviceExt
, Cluster
, 0);
566 UpdateFileSize(FileObject
, Fcb
, NewSize
, ClusterSize
);
568 /* Update the on-disk directory entry */
569 Fcb
->Flags
|= FCB_IS_DIRTY
;
570 if (AllocSizeChanged
)
572 VfatUpdateEntry(Fcb
);
574 return STATUS_SUCCESS
;
577 NTSTATUS
VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext
)
579 * FUNCTION: Retrieve the specified file information
582 FILE_INFORMATION_CLASS FileInformationClass
;
585 NTSTATUS RC
= STATUS_SUCCESS
;
593 FileInformationClass
= IrpContext
->Stack
->Parameters
.QueryFile
.FileInformationClass
;
594 FCB
= (PVFATFCB
) IrpContext
->FileObject
->FsContext
;
596 SystemBuffer
= IrpContext
->Irp
->AssociatedIrp
.SystemBuffer
;
597 BufferLength
= IrpContext
->Stack
->Parameters
.QueryFile
.Length
;
599 if (!(FCB
->Flags
& FCB_IS_PAGE_FILE
))
601 if (!ExAcquireResourceSharedLite(&FCB
->MainResource
,
602 (BOOLEAN
)(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
)))
604 return VfatQueueRequest (IrpContext
);
609 switch (FileInformationClass
)
611 case FileStandardInformation
:
612 RC
= VfatGetStandardInformation(FCB
,
616 case FilePositionInformation
:
617 RC
= VfatGetPositionInformation(IrpContext
->FileObject
,
619 IrpContext
->DeviceObject
,
623 case FileBasicInformation
:
624 RC
= VfatGetBasicInformation(IrpContext
->FileObject
,
626 IrpContext
->DeviceObject
,
630 case FileNameInformation
:
631 RC
= VfatGetNameInformation(IrpContext
->FileObject
,
633 IrpContext
->DeviceObject
,
637 case FileInternalInformation
:
638 RC
= VfatGetInternalInformation(FCB
,
642 case FileNetworkOpenInformation
:
643 RC
= VfatGetNetworkOpenInformation(FCB
,
647 case FileAllInformation
:
648 RC
= VfatGetAllInformation(IrpContext
->FileObject
,
654 case FileAlternateNameInformation
:
655 RC
= STATUS_NOT_IMPLEMENTED
;
658 RC
= STATUS_NOT_SUPPORTED
;
661 if (!(FCB
->Flags
& FCB_IS_PAGE_FILE
))
663 ExReleaseResourceLite(&FCB
->MainResource
);
665 IrpContext
->Irp
->IoStatus
.Status
= RC
;
667 IrpContext
->Irp
->IoStatus
.Information
=
668 IrpContext
->Stack
->Parameters
.QueryFile
.Length
- BufferLength
;
670 IrpContext
->Irp
->IoStatus
.Information
= 0;
671 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
672 VfatFreeIrpContext(IrpContext
);
677 NTSTATUS
VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext
)
679 * FUNCTION: Retrieve the specified file information
682 FILE_INFORMATION_CLASS FileInformationClass
;
684 NTSTATUS RC
= STATUS_SUCCESS
;
686 BOOL CanWait
= IrpContext
->Flags
& IRPCONTEXT_CANWAIT
;
691 DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext
);
694 FileInformationClass
=
695 IrpContext
->Stack
->Parameters
.SetFile
.FileInformationClass
;
696 FCB
= (PVFATFCB
) IrpContext
->FileObject
->FsContext
;
697 SystemBuffer
= IrpContext
->Irp
->AssociatedIrp
.SystemBuffer
;
699 DPRINT("FileInformationClass %d\n", FileInformationClass
);
700 DPRINT("SystemBuffer %x\n", SystemBuffer
);
702 if (!(FCB
->Flags
& FCB_IS_PAGE_FILE
))
704 if (!ExAcquireResourceExclusiveLite(&FCB
->MainResource
,
707 return(VfatQueueRequest (IrpContext
));
711 switch (FileInformationClass
)
713 case FilePositionInformation
:
714 RC
= VfatSetPositionInformation(IrpContext
->FileObject
,
717 case FileDispositionInformation
:
718 RC
= VfatSetDispositionInformation(IrpContext
->FileObject
,
720 IrpContext
->DeviceObject
,
723 case FileAllocationInformation
:
724 case FileEndOfFileInformation
:
725 RC
= VfatSetAllocationSizeInformation(IrpContext
->FileObject
,
727 IrpContext
->DeviceExt
,
728 (PLARGE_INTEGER
)SystemBuffer
);
730 case FileBasicInformation
:
731 RC
= VfatSetBasicInformation(IrpContext
->FileObject
,
733 IrpContext
->DeviceExt
,
736 case FileRenameInformation
:
737 RC
= STATUS_NOT_IMPLEMENTED
;
740 RC
= STATUS_NOT_SUPPORTED
;
743 if (!(FCB
->Flags
& FCB_IS_PAGE_FILE
))
745 ExReleaseResourceLite(&FCB
->MainResource
);
748 IrpContext
->Irp
->IoStatus
.Status
= RC
;
749 IrpContext
->Irp
->IoStatus
.Information
= 0;
750 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
751 VfatFreeIrpContext(IrpContext
);