2 * FFS File System Driver for Windows
8 * Lee Jae-Hong, http://www.pyrasis.com
19 extern PFFS_GLOBAL FFSGlobal
;
25 #pragma alloc_text(PAGE, FFSQueryInformation)
26 #pragma alloc_text(PAGE, FFSSetInformation)
27 #pragma alloc_text(PAGE, FFSExpandFile)
28 #pragma alloc_text(PAGE, FFSTruncateFile)
29 #pragma alloc_text(PAGE, FFSSetDispositionInfo)
30 #pragma alloc_text(PAGE, FFSSetRenameInfo)
31 #pragma alloc_text(PAGE, FFSDeleteFile)
35 __drv_mustHoldCriticalRegion
38 IN PFFS_IRP_CONTEXT IrpContext
)
40 PDEVICE_OBJECT DeviceObject
;
41 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
42 PFILE_OBJECT FileObject
;
47 PIO_STACK_LOCATION IoStackLocation
;
48 FILE_INFORMATION_CLASS FileInformationClass
;
51 BOOLEAN FcbResourceAcquired
= FALSE
;
57 ASSERT(IrpContext
!= NULL
);
59 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
60 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
62 DeviceObject
= IrpContext
->DeviceObject
;
65 // This request is not allowed on the main device object
67 if (DeviceObject
== FFSGlobal
->DeviceObject
)
69 Status
= STATUS_INVALID_DEVICE_REQUEST
;
73 FileObject
= IrpContext
->FileObject
;
75 Vcb
= (PFFS_VCB
)DeviceObject
->DeviceExtension
;
79 Fcb
= (PFFS_FCB
)FileObject
->FsContext
;
84 // This request is not allowed on volumes
86 if (Fcb
->Identifier
.Type
== FFSVCB
)
88 Status
= STATUS_INVALID_PARAMETER
;
92 ASSERT((Fcb
->Identifier
.Type
== FFSFCB
) &&
93 (Fcb
->Identifier
.Size
== sizeof(FFS_FCB
)));
95 if (!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) &&
96 !FlagOn(Fcb->Flags, FCB_PAGE_FILE))
99 if (!ExAcquireResourceSharedLite(
101 IrpContext
->IsSynchronous
))
103 Status
= STATUS_PENDING
;
107 FcbResourceAcquired
= TRUE
;
110 Ccb
= (PFFS_CCB
)FileObject
->FsContext2
;
114 ASSERT((Ccb
->Identifier
.Type
== FFSCCB
) &&
115 (Ccb
->Identifier
.Size
== sizeof(FFS_CCB
)));
117 Irp
= IrpContext
->Irp
;
119 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
121 FileInformationClass
=
122 IoStackLocation
->Parameters
.QueryFile
.FileInformationClass
;
124 Length
= IoStackLocation
->Parameters
.QueryFile
.Length
;
126 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
128 RtlZeroMemory(Buffer
, Length
);
130 switch (FileInformationClass
)
132 case FileBasicInformation
:
134 PFILE_BASIC_INFORMATION FileBasicInformation
;
136 if (Length
< sizeof(FILE_BASIC_INFORMATION
))
138 Status
= STATUS_INFO_LENGTH_MISMATCH
;
142 FileBasicInformation
= (PFILE_BASIC_INFORMATION
)Buffer
;
146 FileBasicInformation
->CreationTime
= FFSSysTime(Fcb
->dinode1
->di_ctime
);
148 FileBasicInformation
->LastAccessTime
= FFSSysTime(Fcb
->dinode1
->di_atime
);
150 FileBasicInformation
->LastWriteTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
152 FileBasicInformation
->ChangeTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
156 FileBasicInformation
->CreationTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_ctime
);
158 FileBasicInformation
->LastAccessTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_atime
);
160 FileBasicInformation
->LastWriteTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
162 FileBasicInformation
->ChangeTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
165 FileBasicInformation
->FileAttributes
= Fcb
->FFSMcb
->FileAttr
;
167 Irp
->IoStatus
.Information
= sizeof(FILE_BASIC_INFORMATION
);
168 Status
= STATUS_SUCCESS
;
172 #if (_WIN32_WINNT >= 0x0500)
174 case FileAttributeTagInformation
:
176 PFILE_ATTRIBUTE_TAG_INFORMATION FATI
;
178 if (Length
< sizeof(FILE_ATTRIBUTE_TAG_INFORMATION
))
180 Status
= STATUS_INFO_LENGTH_MISMATCH
;
184 FATI
= (PFILE_ATTRIBUTE_TAG_INFORMATION
) Buffer
;
186 FATI
->FileAttributes
= Fcb
->FFSMcb
->FileAttr
;
187 FATI
->ReparseTag
= 0;
189 Irp
->IoStatus
.Information
= sizeof(FILE_ATTRIBUTE_TAG_INFORMATION
);
190 Status
= STATUS_SUCCESS
;
193 #endif // (_WIN32_WINNT >= 0x0500)
195 case FileStandardInformation
:
197 PFILE_STANDARD_INFORMATION FileStandardInformation
;
199 if (Length
< sizeof(FILE_STANDARD_INFORMATION
))
201 Status
= STATUS_INFO_LENGTH_MISMATCH
;
205 FileStandardInformation
= (PFILE_STANDARD_INFORMATION
)Buffer
;
209 FileStandardInformation
->AllocationSize
.QuadPart
=
210 (LONGLONG
)(Fcb
->dinode1
->di_size
);
212 FileStandardInformation
->EndOfFile
.QuadPart
=
213 (LONGLONG
)(Fcb
->dinode1
->di_size
);
215 FileStandardInformation
->NumberOfLinks
= Fcb
->dinode1
->di_nlink
;
219 FileStandardInformation
->AllocationSize
.QuadPart
=
220 (LONGLONG
)(Fcb
->dinode2
->di_size
);
222 FileStandardInformation
->EndOfFile
.QuadPart
=
223 (LONGLONG
)(Fcb
->dinode2
->di_size
);
225 FileStandardInformation
->NumberOfLinks
= Fcb
->dinode2
->di_nlink
;
228 if (IsFlagOn(Fcb
->Vcb
->Flags
, VCB_READ_ONLY
))
229 FileStandardInformation
->DeletePending
= FALSE
;
231 FileStandardInformation
->DeletePending
= IsFlagOn(Fcb
->Flags
, FCB_DELETE_PENDING
);
233 if (Fcb
->FFSMcb
->FileAttr
& FILE_ATTRIBUTE_DIRECTORY
)
235 FileStandardInformation
->Directory
= TRUE
;
239 FileStandardInformation
->Directory
= FALSE
;
242 Irp
->IoStatus
.Information
= sizeof(FILE_STANDARD_INFORMATION
);
243 Status
= STATUS_SUCCESS
;
247 case FileInternalInformation
:
249 PFILE_INTERNAL_INFORMATION FileInternalInformation
;
251 if (Length
< sizeof(FILE_INTERNAL_INFORMATION
))
253 Status
= STATUS_INFO_LENGTH_MISMATCH
;
257 FileInternalInformation
= (PFILE_INTERNAL_INFORMATION
)Buffer
;
259 // The "inode number"
260 FileInternalInformation
->IndexNumber
.QuadPart
= (LONGLONG
)Fcb
->FFSMcb
->Inode
;
262 Irp
->IoStatus
.Information
= sizeof(FILE_INTERNAL_INFORMATION
);
263 Status
= STATUS_SUCCESS
;
267 case FileEaInformation
:
269 PFILE_EA_INFORMATION FileEaInformation
;
271 if (Length
< sizeof(FILE_EA_INFORMATION
))
273 Status
= STATUS_INFO_LENGTH_MISMATCH
;
277 FileEaInformation
= (PFILE_EA_INFORMATION
)Buffer
;
279 // Romfs doesn't have any extended attributes
280 FileEaInformation
->EaSize
= 0;
282 Irp
->IoStatus
.Information
= sizeof(FILE_EA_INFORMATION
);
283 Status
= STATUS_SUCCESS
;
287 case FileNameInformation
:
289 PFILE_NAME_INFORMATION FileNameInformation
;
291 if (Length
< sizeof(FILE_NAME_INFORMATION
) +
292 Fcb
->FFSMcb
->ShortName
.Length
- sizeof(WCHAR
))
294 Status
= STATUS_INFO_LENGTH_MISMATCH
;
298 FileNameInformation
= (PFILE_NAME_INFORMATION
)Buffer
;
300 FileNameInformation
->FileNameLength
= Fcb
->FFSMcb
->ShortName
.Length
;
303 FileNameInformation
->FileName
,
304 Fcb
->FFSMcb
->ShortName
.Buffer
,
305 Fcb
->FFSMcb
->ShortName
.Length
);
307 Irp
->IoStatus
.Information
= sizeof(FILE_NAME_INFORMATION
) +
308 Fcb
->FFSMcb
->ShortName
.Length
- sizeof(WCHAR
);
309 Status
= STATUS_SUCCESS
;
313 case FilePositionInformation
:
315 PFILE_POSITION_INFORMATION FilePositionInformation
;
317 if (Length
< sizeof(FILE_POSITION_INFORMATION
))
319 Status
= STATUS_INFO_LENGTH_MISMATCH
;
323 FilePositionInformation
= (PFILE_POSITION_INFORMATION
)Buffer
;
325 FilePositionInformation
->CurrentByteOffset
=
326 FileObject
->CurrentByteOffset
;
328 Irp
->IoStatus
.Information
= sizeof(FILE_POSITION_INFORMATION
);
329 Status
= STATUS_SUCCESS
;
333 case FileAllInformation
:
335 PFILE_ALL_INFORMATION FileAllInformation
;
336 PFILE_BASIC_INFORMATION FileBasicInformation
;
337 PFILE_STANDARD_INFORMATION FileStandardInformation
;
338 PFILE_INTERNAL_INFORMATION FileInternalInformation
;
339 PFILE_EA_INFORMATION FileEaInformation
;
340 PFILE_POSITION_INFORMATION FilePositionInformation
;
341 PFILE_NAME_INFORMATION FileNameInformation
;
343 if (Length
< sizeof(FILE_ALL_INFORMATION
))
345 Status
= STATUS_INFO_LENGTH_MISMATCH
;
349 FileAllInformation
= (PFILE_ALL_INFORMATION
)Buffer
;
351 FileBasicInformation
=
352 &FileAllInformation
->BasicInformation
;
354 FileStandardInformation
=
355 &FileAllInformation
->StandardInformation
;
357 FileInternalInformation
=
358 &FileAllInformation
->InternalInformation
;
361 &FileAllInformation
->EaInformation
;
363 FilePositionInformation
=
364 &FileAllInformation
->PositionInformation
;
366 FileNameInformation
=
367 &FileAllInformation
->NameInformation
;
371 FileBasicInformation
->CreationTime
= FFSSysTime(Fcb
->dinode1
->di_ctime
);
373 FileBasicInformation
->LastAccessTime
= FFSSysTime(Fcb
->dinode1
->di_atime
);
375 FileBasicInformation
->LastWriteTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
377 FileBasicInformation
->ChangeTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
379 FileBasicInformation
->FileAttributes
= Fcb
->FFSMcb
->FileAttr
;
381 FileStandardInformation
->AllocationSize
.QuadPart
=
382 (LONGLONG
)(Fcb
->dinode1
->di_size
);
384 FileStandardInformation
->EndOfFile
.QuadPart
=
385 (LONGLONG
)(Fcb
->dinode1
->di_size
);
387 FileStandardInformation
->NumberOfLinks
= Fcb
->dinode1
->di_nlink
;
391 FileBasicInformation
->CreationTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_ctime
);
393 FileBasicInformation
->LastAccessTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_atime
);
395 FileBasicInformation
->LastWriteTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
397 FileBasicInformation
->ChangeTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
399 FileBasicInformation
->FileAttributes
= Fcb
->FFSMcb
->FileAttr
;
401 FileStandardInformation
->AllocationSize
.QuadPart
=
402 (LONGLONG
)(Fcb
->dinode2
->di_size
);
404 FileStandardInformation
->EndOfFile
.QuadPart
=
405 (LONGLONG
)(Fcb
->dinode2
->di_size
);
407 FileStandardInformation
->NumberOfLinks
= Fcb
->dinode2
->di_nlink
;
410 if (IsFlagOn(Fcb
->Vcb
->Flags
, VCB_READ_ONLY
))
411 FileStandardInformation
->DeletePending
= FALSE
;
413 FileStandardInformation
->DeletePending
= IsFlagOn(Fcb
->Flags
, FCB_DELETE_PENDING
);
415 if (FlagOn(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
))
417 FileStandardInformation
->Directory
= TRUE
;
421 FileStandardInformation
->Directory
= FALSE
;
424 // The "inode number"
425 FileInternalInformation
->IndexNumber
.QuadPart
= (LONGLONG
)Fcb
->FFSMcb
->Inode
;
427 // Romfs doesn't have any extended attributes
428 FileEaInformation
->EaSize
= 0;
430 FilePositionInformation
->CurrentByteOffset
=
431 FileObject
->CurrentByteOffset
;
433 if (Length
< sizeof(FILE_ALL_INFORMATION
) +
434 Fcb
->FFSMcb
->ShortName
.Length
- sizeof(WCHAR
))
436 Irp
->IoStatus
.Information
= sizeof(FILE_ALL_INFORMATION
);
437 Status
= STATUS_BUFFER_OVERFLOW
;
441 FileNameInformation
->FileNameLength
= Fcb
->FFSMcb
->ShortName
.Length
;
444 FileNameInformation
->FileName
,
445 Fcb
->FFSMcb
->ShortName
.Buffer
,
446 Fcb
->FFSMcb
->ShortName
.Length
);
448 Irp
->IoStatus
.Information
= sizeof(FILE_ALL_INFORMATION
) +
449 Fcb
->FFSMcb
->ShortName
.Length
- sizeof(WCHAR
);
450 Status
= STATUS_SUCCESS
;
455 case FileAlternateNameInformation:
457 // TODO: Handle FileAlternateNameInformation
459 // Here we would like to use RtlGenerate8dot3Name but I don't
460 // know how to use the argument PGENERATE_NAME_CONTEXT
464 case FileNetworkOpenInformation
:
466 PFILE_NETWORK_OPEN_INFORMATION FileNetworkOpenInformation
;
468 if (Length
< sizeof(FILE_NETWORK_OPEN_INFORMATION
))
470 Status
= STATUS_INFO_LENGTH_MISMATCH
;
474 FileNetworkOpenInformation
=
475 (PFILE_NETWORK_OPEN_INFORMATION
)Buffer
;
479 FileNetworkOpenInformation
->CreationTime
= FFSSysTime(Fcb
->dinode1
->di_ctime
);
481 FileNetworkOpenInformation
->LastAccessTime
= FFSSysTime(Fcb
->dinode1
->di_atime
);
483 FileNetworkOpenInformation
->LastWriteTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
485 FileNetworkOpenInformation
->ChangeTime
= FFSSysTime(Fcb
->dinode1
->di_mtime
);
487 FileNetworkOpenInformation
->AllocationSize
.QuadPart
=
488 (LONGLONG
)(Fcb
->dinode1
->di_size
);
490 FileNetworkOpenInformation
->EndOfFile
.QuadPart
=
491 (LONGLONG
)(Fcb
->dinode1
->di_size
);
495 FileNetworkOpenInformation
->CreationTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_ctime
);
497 FileNetworkOpenInformation
->LastAccessTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_atime
);
499 FileNetworkOpenInformation
->LastWriteTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
501 FileNetworkOpenInformation
->ChangeTime
= FFSSysTime((ULONG
)Fcb
->dinode2
->di_mtime
);
503 FileNetworkOpenInformation
->AllocationSize
.QuadPart
=
504 (LONGLONG
)(Fcb
->dinode2
->di_size
);
506 FileNetworkOpenInformation
->EndOfFile
.QuadPart
=
507 (LONGLONG
)(Fcb
->dinode2
->di_size
);
510 FileNetworkOpenInformation
->FileAttributes
=
511 Fcb
->FFSMcb
->FileAttr
;
513 Irp
->IoStatus
.Information
=
514 sizeof(FILE_NETWORK_OPEN_INFORMATION
);
515 Status
= STATUS_SUCCESS
;
520 Status
= STATUS_INVALID_INFO_CLASS
;
525 if (FcbResourceAcquired
)
527 ExReleaseResourceForThreadLite(
529 ExGetCurrentResourceThread());
532 if (!IrpContext
->ExceptionInProgress
)
534 if (Status
== STATUS_PENDING
)
536 FFSQueueRequest(IrpContext
);
540 FFSCompleteIrpContext(IrpContext
, Status
);
549 __drv_mustHoldCriticalRegion
552 IN PFFS_IRP_CONTEXT IrpContext
)
554 PDEVICE_OBJECT DeviceObject
;
555 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
557 PFILE_OBJECT FileObject
;
561 PIO_STACK_LOCATION IoStackLocation
;
562 FILE_INFORMATION_CLASS FileInformationClass
;
564 ULONG NotifyFilter
= 0;
568 BOOLEAN FcbMainResourceAcquired
= FALSE
;
570 BOOLEAN VcbResourceAcquired
= FALSE
;
571 BOOLEAN FcbPagingIoResourceAcquired
= FALSE
;
577 ASSERT(IrpContext
!= NULL
);
579 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
580 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
582 DeviceObject
= IrpContext
->DeviceObject
;
585 // This request is not allowed on the main device object
587 if (DeviceObject
== FFSGlobal
->DeviceObject
)
589 Status
= STATUS_INVALID_DEVICE_REQUEST
;
593 Vcb
= (PFFS_VCB
)DeviceObject
->DeviceExtension
;
597 ASSERT((Vcb
->Identifier
.Type
== FFSVCB
) &&
598 (Vcb
->Identifier
.Size
== sizeof(FFS_VCB
)));
600 ASSERT(IsMounted(Vcb
));
602 FileObject
= IrpContext
->FileObject
;
604 Fcb
= (PFFS_FCB
)FileObject
->FsContext
;
609 // This request is not allowed on volumes
611 if (Fcb
->Identifier
.Type
== FFSVCB
)
615 Status
= STATUS_INVALID_PARAMETER
;
619 ASSERT((Fcb
->Identifier
.Type
== FFSFCB
) &&
620 (Fcb
->Identifier
.Size
== sizeof(FFS_FCB
)));
622 if (IsFlagOn(Fcb
->Flags
, FCB_FILE_DELETED
))
624 Status
= STATUS_FILE_DELETED
;
628 Ccb
= (PFFS_CCB
)FileObject
->FsContext2
;
632 ASSERT((Ccb
->Identifier
.Type
== FFSCCB
) &&
633 (Ccb
->Identifier
.Size
== sizeof(FFS_CCB
)));
635 Irp
= IrpContext
->Irp
;
637 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
639 FileInformationClass
=
640 IoStackLocation
->Parameters
.SetFile
.FileInformationClass
;
642 Length
= IoStackLocation
->Parameters
.SetFile
.Length
;
644 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
646 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
))
648 if (FileInformationClass
== FileDispositionInformation
||
649 FileInformationClass
== FileRenameInformation
||
650 FileInformationClass
== FileLinkInformation
)
653 #pragma prefast( suppress: 28137, "by design" )
655 if (!ExAcquireResourceExclusiveLite(
657 IrpContext
->IsSynchronous
))
659 Status
= STATUS_PENDING
;
663 VcbResourceAcquired
= TRUE
;
666 else if (!FlagOn(Fcb
->Flags
, FCB_PAGE_FILE
))
669 #pragma prefast( suppress: 28137, "by design" )
671 if (!ExAcquireResourceExclusiveLite(
673 IrpContext
->IsSynchronous
))
675 Status
= STATUS_PENDING
;
679 FcbMainResourceAcquired
= TRUE
;
682 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
))
684 if (FileInformationClass
!= FilePositionInformation
)
686 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
691 if (FileInformationClass
== FileDispositionInformation
||
692 FileInformationClass
== FileRenameInformation
||
693 FileInformationClass
== FileLinkInformation
||
694 FileInformationClass
== FileAllocationInformation
||
695 FileInformationClass
== FileEndOfFileInformation
)
698 #pragma prefast( suppress: 28137, "by design" )
700 if (!ExAcquireResourceExclusiveLite(
701 &Fcb
->PagingIoResource
,
702 IrpContext
->IsSynchronous
))
704 Status
= STATUS_PENDING
;
708 FcbPagingIoResourceAcquired
= TRUE
;
712 if (FileInformationClass != FileDispositionInformation
713 && FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
715 Status = STATUS_DELETE_PENDING;
720 switch (FileInformationClass
)
725 case FileBasicInformation
:
727 PFILE_BASIC_INFORMATION FBI
= (PFILE_BASIC_INFORMATION
)Buffer
;
731 PFFSv1_INODE dinode1
= Fcb
->dinode1
;
733 if(FBI
->CreationTime
.QuadPart
)
735 dinode1
->di_ctime
= (ULONG
)(FFSInodeTime(FBI
->CreationTime
));
738 if(FBI
->LastAccessTime
.QuadPart
)
740 dinode1
->di_atime
= (ULONG
)(FFSInodeTime(FBI
->LastAccessTime
));
743 if(FBI
->LastWriteTime
.QuadPart
)
745 dinode1
->di_mtime
= (ULONG
)(FFSInodeTime(FBI
->LastWriteTime
));
748 if (IsFlagOn(FBI
->FileAttributes
, FILE_ATTRIBUTE_READONLY
))
750 FFSSetReadOnly(Fcb
->dinode1
->di_mode
);
751 SetFlag(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
755 FFSSetWritable(Fcb
->dinode1
->di_mode
);
756 ClearFlag(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
759 if(FFSv1SaveInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, dinode1
))
761 Status
= STATUS_SUCCESS
;
764 if (FBI
->FileAttributes
& FILE_ATTRIBUTE_TEMPORARY
)
766 SetFlag(FileObject
->Flags
, FO_TEMPORARY_FILE
);
770 ClearFlag(FileObject
->Flags
, FO_TEMPORARY_FILE
);
775 PFFSv2_INODE dinode2
= Fcb
->dinode2
;
777 if(FBI
->CreationTime
.QuadPart
)
779 dinode2
->di_ctime
= (ULONG
)(FFSInodeTime(FBI
->CreationTime
));
782 if(FBI
->LastAccessTime
.QuadPart
)
784 dinode2
->di_atime
= (ULONG
)(FFSInodeTime(FBI
->LastAccessTime
));
787 if(FBI
->LastWriteTime
.QuadPart
)
789 dinode2
->di_mtime
= (ULONG
)(FFSInodeTime(FBI
->LastWriteTime
));
792 if (IsFlagOn(FBI
->FileAttributes
, FILE_ATTRIBUTE_READONLY
))
794 FFSSetReadOnly(Fcb
->dinode2
->di_mode
);
795 SetFlag(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
799 FFSSetWritable(Fcb
->dinode2
->di_mode
);
800 ClearFlag(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
803 if(FFSv2SaveInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, dinode2
))
805 Status
= STATUS_SUCCESS
;
808 if (FBI
->FileAttributes
& FILE_ATTRIBUTE_TEMPORARY
)
810 SetFlag(FileObject
->Flags
, FO_TEMPORARY_FILE
);
814 ClearFlag(FileObject
->Flags
, FO_TEMPORARY_FILE
);
818 NotifyFilter
= FILE_NOTIFY_CHANGE_ATTRIBUTES
|
819 FILE_NOTIFY_CHANGE_CREATION
|
820 FILE_NOTIFY_CHANGE_LAST_ACCESS
|
821 FILE_NOTIFY_CHANGE_LAST_WRITE
;
823 Status
= STATUS_SUCCESS
;
827 case FileAllocationInformation
:
829 PFILE_ALLOCATION_INFORMATION FAI
= (PFILE_ALLOCATION_INFORMATION
)Buffer
;
831 if (FlagOn(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
))
833 Status
= STATUS_INVALID_DEVICE_REQUEST
;
837 if (FAI
->AllocationSize
.QuadPart
==
838 Fcb
->Header
.AllocationSize
.QuadPart
)
840 Status
= STATUS_SUCCESS
;
842 else if (FAI
->AllocationSize
.QuadPart
>
843 Fcb
->Header
.AllocationSize
.QuadPart
)
845 if(FFSExpandFile(IrpContext
,
847 &(FAI
->AllocationSize
)))
849 if (FFSv1SaveInode(IrpContext
,
854 Status
= STATUS_SUCCESS
;
859 Status
= STATUS_INSUFFICIENT_RESOURCES
;
864 if (MmCanFileBeTruncated(&(Fcb
->SectionObject
), &(FAI
->AllocationSize
)))
866 LARGE_INTEGER EndOfFile
;
868 EndOfFile
.QuadPart
= FAI
->AllocationSize
.QuadPart
+
869 (LONGLONG
)(Vcb
->BlockSize
- 1);
871 if(FFSTruncateFile(IrpContext
, Vcb
, Fcb
, &(EndOfFile
)))
873 if (FAI
->AllocationSize
.QuadPart
<
874 Fcb
->Header
.FileSize
.QuadPart
)
876 Fcb
->Header
.FileSize
.QuadPart
=
877 FAI
->AllocationSize
.QuadPart
;
880 FFSv1SaveInode(IrpContext
,
885 Status
= STATUS_SUCCESS
;
890 Status
= STATUS_USER_MAPPED_FILE
;
895 if (NT_SUCCESS(Status
))
897 CcSetFileSizes(FileObject
,
898 (PCC_FILE_SIZES
)(&(Fcb
->Header
.AllocationSize
)));
899 SetFlag(FileObject
->Flags
, FO_FILE_MODIFIED
);
901 NotifyFilter
= FILE_NOTIFY_CHANGE_SIZE
|
902 FILE_NOTIFY_CHANGE_LAST_WRITE
;
909 case FileEndOfFileInformation
:
911 PFILE_END_OF_FILE_INFORMATION FEOFI
= (PFILE_END_OF_FILE_INFORMATION
) Buffer
;
913 BOOLEAN CacheInitialized
= FALSE
;
915 if (IsDirectory(Fcb
))
917 Status
= STATUS_INVALID_DEVICE_REQUEST
;
921 if (FEOFI
->EndOfFile
.HighPart
!= 0)
923 Status
= STATUS_INVALID_PARAMETER
;
928 if (IoStackLocation
->Parameters
.SetFile
.AdvanceOnly
)
930 Status
= STATUS_SUCCESS
;
934 if ((FileObject
->SectionObjectPointer
->DataSectionObject
!= NULL
) &&
935 (FileObject
->SectionObjectPointer
->SharedCacheMap
== NULL
) &&
936 !FlagOn(Irp
->Flags
, IRP_PAGING_IO
)) {
938 ASSERT(!FlagOn(FileObject
->Flags
, FO_CLEANUP_COMPLETE
));
940 CcInitializeCacheMap(
942 (PCC_FILE_SIZES
)&(Fcb
->Header
.AllocationSize
),
944 &(FFSGlobal
->CacheManagerNoOpCallbacks
),
947 CacheInitialized
= TRUE
;
950 if (FEOFI
->EndOfFile
.QuadPart
==
951 Fcb
->Header
.AllocationSize
.QuadPart
)
953 Status
= STATUS_SUCCESS
;
955 else if (FEOFI
->EndOfFile
.QuadPart
>
956 Fcb
->Header
.AllocationSize
.QuadPart
)
958 LARGE_INTEGER FileSize
= Fcb
->Header
.FileSize
;
960 if(FFSExpandFile(IrpContext
, Vcb
, Fcb
, &(FEOFI
->EndOfFile
)))
963 Fcb
->Header
.FileSize
.QuadPart
=
964 FEOFI
->EndOfFile
.QuadPart
;
965 Fcb
->dinode1
->di_size
= (ULONG
)FEOFI
->EndOfFile
.QuadPart
;
966 Fcb
->Header
.ValidDataLength
.QuadPart
=
967 (LONGLONG
)(0x7fffffffffffffff);
970 if (FFSv1SaveInode(IrpContext
,
975 Status
= STATUS_SUCCESS
;
980 Status
= STATUS_INSUFFICIENT_RESOURCES
;
984 if (NT_SUCCESS(Status
))
986 CcSetFileSizes(FileObject
,
987 (PCC_FILE_SIZES
)(&(Fcb
->Header
.AllocationSize
)));
989 SetFlag(FileObject
->Flags
, FO_FILE_MODIFIED
);
991 FFSZeroHoles(IrpContext
,
994 Fcb
->Header
.AllocationSize
.QuadPart
-
997 NotifyFilter
= FILE_NOTIFY_CHANGE_SIZE
|
998 FILE_NOTIFY_CHANGE_LAST_WRITE
;
1004 if (MmCanFileBeTruncated(&(Fcb
->SectionObject
), &(FEOFI
->EndOfFile
)))
1006 LARGE_INTEGER EndOfFile
= FEOFI
->EndOfFile
;
1008 EndOfFile
.QuadPart
= EndOfFile
.QuadPart
+
1009 (LONGLONG
)(Vcb
->BlockSize
- 1);
1011 if(FFSTruncateFile(IrpContext
, Vcb
, Fcb
, &(EndOfFile
)))
1013 Fcb
->Header
.FileSize
.QuadPart
=
1014 FEOFI
->EndOfFile
.QuadPart
;
1015 Fcb
->dinode1
->di_size
= (ULONG
)FEOFI
->EndOfFile
.QuadPart
;
1017 FFSv1SaveInode(IrpContext
,
1022 Status
= STATUS_SUCCESS
;
1027 Status
= STATUS_USER_MAPPED_FILE
;
1031 if (NT_SUCCESS(Status
))
1033 CcSetFileSizes(FileObject
,
1034 (PCC_FILE_SIZES
)(&(Fcb
->Header
.AllocationSize
)));
1036 SetFlag(FileObject
->Flags
, FO_FILE_MODIFIED
);
1038 NotifyFilter
= FILE_NOTIFY_CHANGE_SIZE
|
1039 FILE_NOTIFY_CHANGE_LAST_WRITE
;
1047 case FileDispositionInformation
:
1049 PFILE_DISPOSITION_INFORMATION FDI
= (PFILE_DISPOSITION_INFORMATION
)Buffer
;
1051 Status
= FFSSetDispositionInfo(IrpContext
, Vcb
, Fcb
, FDI
->DeleteFile
);
1056 case FileRenameInformation
:
1058 Status
= FFSSetRenameInfo(IrpContext
, Vcb
, Fcb
);
1063 #endif // !FFS_READ_ONLY
1066 // This is the only set file information request supported on read
1067 // only file systems
1069 case FilePositionInformation
:
1071 PFILE_POSITION_INFORMATION FilePositionInformation
;
1073 if (Length
< sizeof(FILE_POSITION_INFORMATION
))
1075 Status
= STATUS_INVALID_PARAMETER
;
1079 FilePositionInformation
= (PFILE_POSITION_INFORMATION
) Buffer
;
1081 if ((FlagOn(FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
)) &&
1082 (FilePositionInformation
->CurrentByteOffset
.LowPart
&
1083 DeviceObject
->AlignmentRequirement
))
1085 Status
= STATUS_INVALID_PARAMETER
;
1089 FileObject
->CurrentByteOffset
=
1090 FilePositionInformation
->CurrentByteOffset
;
1092 Status
= STATUS_SUCCESS
;
1099 Status
= STATUS_INVALID_INFO_CLASS
;
1105 if (FcbPagingIoResourceAcquired
)
1107 ExReleaseResourceForThreadLite(
1108 &Fcb
->PagingIoResource
,
1109 ExGetCurrentResourceThread());
1112 if (NT_SUCCESS(Status
) && (NotifyFilter
!= 0))
1114 FFSNotifyReportChange(
1119 FILE_ACTION_MODIFIED
);
1123 if (FcbMainResourceAcquired
)
1125 ExReleaseResourceForThreadLite(
1127 ExGetCurrentResourceThread());
1130 if (VcbResourceAcquired
)
1132 ExReleaseResourceForThreadLite(
1134 ExGetCurrentResourceThread());
1137 if (!IrpContext
->ExceptionInProgress
)
1139 if (Status
== STATUS_PENDING
)
1141 FFSQueueRequest(IrpContext
);
1145 FFSCompleteIrpContext(IrpContext
, Status
);
1157 PFFS_IRP_CONTEXT IrpContext
,
1160 PLARGE_INTEGER AllocationSize
)
1163 BOOLEAN bRet
= TRUE
;
1167 if (AllocationSize
->QuadPart
<= Fcb
->Header
.AllocationSize
.QuadPart
)
1172 if (((LONGLONG
)SUPER_BLOCK
->fs_size
- (LONGLONG
)SUPER_BLOCK
->fs_dsize
) * Vcb
->BlockSize
<=
1173 (AllocationSize
->QuadPart
- Fcb
->Header
.AllocationSize
.QuadPart
))
1175 FFSPrint((DBG_ERROR
, "FFSExpandFile: There is no enough disk space available.\n"));
1179 while (bRet
&& (AllocationSize
->QuadPart
> Fcb
->Header
.AllocationSize
.QuadPart
))
1181 bRet
= FFSExpandInode(IrpContext
, Vcb
, Fcb
, &dwRet
);
1190 PFFS_IRP_CONTEXT IrpContext
,
1193 PLARGE_INTEGER AllocationSize
)
1195 BOOLEAN bRet
= TRUE
;
1199 while (bRet
&& (AllocationSize
->QuadPart
<
1200 Fcb
->Header
.AllocationSize
.QuadPart
))
1202 bRet
= FFSTruncateInode(IrpContext
, Vcb
, Fcb
);
1210 FFSSetDispositionInfo(
1211 PFFS_IRP_CONTEXT IrpContext
,
1216 PIRP Irp
= IrpContext
->Irp
;
1217 PIO_STACK_LOCATION IrpSp
;
1221 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1223 FFSPrint((DBG_INFO
, "FFSSetDispositionInfo: bDelete=%x\n", bDelete
));
1227 FFSPrint((DBG_INFO
, "FFSSetDispositionInformation: MmFlushImageSection on %s.\n",
1228 Fcb
->AnsiFileName
.Buffer
));
1230 if (!MmFlushImageSection(&Fcb
->SectionObject
,
1233 return STATUS_CANNOT_DELETE
;
1236 if (Fcb
->FFSMcb
->Inode
== FFS_ROOT_INO
)
1238 return STATUS_CANNOT_DELETE
;
1241 if (IsDirectory(Fcb
))
1243 if (!FFSIsDirectoryEmpty(Vcb
, Fcb
))
1245 return STATUS_DIRECTORY_NOT_EMPTY
;
1249 SetFlag(Fcb
->Flags
, FCB_DELETE_PENDING
);
1250 IrpSp
->FileObject
->DeletePending
= TRUE
;
1252 if (IsDirectory(Fcb
))
1254 FsRtlNotifyFullChangeDirectory(Vcb
->NotifySync
,
1268 ClearFlag(Fcb
->Flags
, FCB_DELETE_PENDING
);
1269 IrpSp
->FileObject
->DeletePending
= FALSE
;
1272 return STATUS_SUCCESS
;
1276 __drv_mustHoldCriticalRegion
1279 PFFS_IRP_CONTEXT IrpContext
,
1287 FFSv1_INODE dinode1
;
1289 UNICODE_STRING FileName
;
1294 PIO_STACK_LOCATION IrpSp
;
1296 PFILE_OBJECT FileObject
;
1297 PFILE_OBJECT TargetObject
;
1298 BOOLEAN ReplaceIfExists
;
1300 BOOLEAN bMove
= FALSE
;
1302 PFILE_RENAME_INFORMATION FRI
;
1306 if (Fcb
->FFSMcb
->Inode
== FFS_ROOT_INO
)
1308 Status
= STATUS_INVALID_PARAMETER
;
1312 Irp
= IrpContext
->Irp
;
1313 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1315 FileObject
= IrpSp
->FileObject
;
1316 TargetObject
= IrpSp
->Parameters
.SetFile
.FileObject
;
1317 ReplaceIfExists
= IrpSp
->Parameters
.SetFile
.ReplaceIfExists
;
1319 FRI
= (PFILE_RENAME_INFORMATION
)Irp
->AssociatedIrp
.SystemBuffer
;
1321 if (TargetObject
== NULL
)
1323 UNICODE_STRING NewName
;
1325 NewName
.Buffer
= FRI
->FileName
;
1326 NewName
.MaximumLength
= NewName
.Length
= (USHORT
)FRI
->FileNameLength
;
1328 while (NewName
.Length
> 0 && NewName
.Buffer
[NewName
.Length
/ 2 - 1] == L
'\\')
1330 NewName
.Buffer
[NewName
.Length
/ 2 - 1] = 0;
1331 NewName
.Length
-= 2;
1334 while (NewName
.Length
> 0 && NewName
.Buffer
[NewName
.Length
/ 2 - 1] != L
'\\')
1336 NewName
.Length
-= 2;
1339 NewName
.Buffer
= (USHORT
*)((UCHAR
*)NewName
.Buffer
+ NewName
.Length
);
1340 NewName
.Length
= (USHORT
)(FRI
->FileNameLength
- NewName
.Length
);
1345 TargetMcb
= Fcb
->FFSMcb
->Parent
;
1347 if (FileName
.Length
>= FFS_NAME_LEN
*sizeof(USHORT
))
1349 Status
= STATUS_OBJECT_NAME_INVALID
;
1355 TargetDcb
= (PFFS_FCB
)(TargetObject
->FsContext
);
1357 if (!TargetDcb
|| TargetDcb
->Vcb
!= Vcb
)
1361 Status
= STATUS_INVALID_PARAMETER
;
1365 TargetMcb
= TargetDcb
->FFSMcb
;
1367 FileName
= TargetObject
->FileName
;
1370 if (FsRtlDoesNameContainWildCards(&FileName
))
1372 Status
= STATUS_OBJECT_NAME_INVALID
;
1376 if (TargetMcb
->Inode
== Fcb
->FFSMcb
->Parent
->Inode
)
1378 if (FsRtlAreNamesEqual(&FileName
,
1379 &(Fcb
->FFSMcb
->ShortName
),
1383 Status
= STATUS_SUCCESS
;
1392 TargetDcb
= TargetMcb
->FFSFcb
;
1395 TargetDcb
= FFSCreateFcbFromMcb(Vcb
, TargetMcb
);
1397 if ((TargetMcb
->Inode
!= Fcb
->FFSMcb
->Parent
->Inode
) &&
1398 (Fcb
->FFSMcb
->Parent
->FFSFcb
== NULL
))
1400 FFSCreateFcbFromMcb(Vcb
, Fcb
->FFSMcb
->Parent
);
1403 if (!TargetDcb
|| !(Fcb
->FFSMcb
->Parent
->FFSFcb
))
1405 Status
= STATUS_UNSUCCESSFUL
;
1411 Status
= FFSv1LookupFileName(
1418 if (NT_SUCCESS(Status
))
1420 if ((!ReplaceIfExists
) ||
1421 (IsFlagOn(Mcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
)) ||
1422 (IsFlagOn(Mcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
)))
1424 Status
= STATUS_OBJECT_NAME_COLLISION
;
1428 if (ReplaceIfExists
)
1430 Status
= STATUS_NOT_IMPLEMENTED
;
1435 if (IsDirectory(Fcb
))
1438 Status
= FFSRemoveEntry(IrpContext
, Vcb
,
1439 Fcb
->FFSMcb
->Parent
->FFSFcb
,
1441 Fcb
->FFSMcb
->Inode
);
1443 if (!NT_SUCCESS(Status
))
1450 Status
= FFSAddEntry(IrpContext
, Vcb
,
1456 if (!NT_SUCCESS(Status
))
1460 FFSAddEntry(IrpContext
, Vcb
,
1461 Fcb
->FFSMcb
->Parent
->FFSFcb
,
1464 &Fcb
->FFSMcb
->ShortName
);
1469 if(!FFSv1SaveInode(IrpContext
,
1472 TargetDcb
->dinode1
))
1474 Status
= STATUS_UNSUCCESSFUL
;
1481 if(!FFSv1SaveInode(IrpContext
,
1483 Fcb
->FFSMcb
->Parent
->Inode
,
1484 Fcb
->FFSMcb
->Parent
->FFSFcb
->dinode1
))
1486 Status
= STATUS_UNSUCCESSFUL
;
1493 Status
= FFSSetParentEntry(IrpContext
, Vcb
, Fcb
,
1494 Fcb
->FFSMcb
->Parent
->Inode
,
1495 TargetDcb
->FFSMcb
->Inode
);
1498 if (!NT_SUCCESS(Status
))
1506 Status
= FFSRemoveEntry(IrpContext
, Vcb
,
1507 Fcb
->FFSMcb
->Parent
->FFSFcb
,
1509 Fcb
->FFSMcb
->Inode
);
1510 if (!NT_SUCCESS(Status
))
1516 Status
= FFSAddEntry(IrpContext
,
1522 if (!NT_SUCCESS(Status
))
1526 FFSAddEntry(IrpContext
, Vcb
,
1527 Fcb
->FFSMcb
->Parent
->FFSFcb
,
1530 &Fcb
->FFSMcb
->ShortName
);
1536 if (NT_SUCCESS(Status
))
1538 if (Fcb
->FFSMcb
->ShortName
.MaximumLength
< (FileName
.Length
+ 2))
1540 ExFreePool(Fcb
->FFSMcb
->ShortName
.Buffer
);
1541 Fcb
->FFSMcb
->ShortName
.Buffer
=
1542 ExAllocatePoolWithTag(PagedPool
, FileName
.Length
+ 2, FFS_POOL_TAG
);
1544 if (!Fcb
->FFSMcb
->ShortName
.Buffer
)
1546 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1550 Fcb
->FFSMcb
->ShortName
.MaximumLength
= FileName
.Length
+ 2;
1554 RtlZeroMemory(Fcb
->FFSMcb
->ShortName
.Buffer
,
1555 Fcb
->FFSMcb
->ShortName
.MaximumLength
);
1557 RtlCopyMemory(Fcb
->FFSMcb
->ShortName
.Buffer
,
1558 FileName
.Buffer
, FileName
.Length
);
1560 Fcb
->FFSMcb
->ShortName
.Length
= FileName
.Length
;
1565 Fcb
->AnsiFileName
.Length
= (USHORT
)
1566 RtlxUnicodeStringToOemSize(&FileName
);
1568 if (Fcb
->AnsiFileName
.MaximumLength
< FileName
.Length
)
1570 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
1572 Fcb
->AnsiFileName
.Buffer
=
1573 ExAllocatePoolWithTag(PagedPool
, Fcb
->AnsiFileName
.Length
+ 1, FFS_POOL_TAG
);
1575 if (!Fcb
->AnsiFileName
.Buffer
)
1577 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1581 RtlZeroMemory(Fcb
->AnsiFileName
.Buffer
,
1582 Fcb
->AnsiFileName
.Length
+ 1);
1583 Fcb
->AnsiFileName
.MaximumLength
=
1584 Fcb
->AnsiFileName
.Length
+ 1;
1587 FFSUnicodeToOEM(&(Fcb
->AnsiFileName
),
1594 FFSNotifyReportChange(
1599 FILE_NOTIFY_CHANGE_DIR_NAME
:
1600 FILE_NOTIFY_CHANGE_FILE_NAME
),
1601 FILE_ACTION_REMOVED
);
1606 FFSNotifyReportChange(
1611 FILE_NOTIFY_CHANGE_DIR_NAME
:
1612 FILE_NOTIFY_CHANGE_FILE_NAME
),
1613 FILE_ACTION_RENAMED_OLD_NAME
);
1617 FFSDeleteMcbNode(Vcb
, Fcb
->FFSMcb
->Parent
, Fcb
->FFSMcb
);
1618 FFSAddMcbNode(Vcb
, TargetMcb
, Fcb
->FFSMcb
);
1622 FFSNotifyReportChange(
1627 FILE_NOTIFY_CHANGE_DIR_NAME
:
1628 FILE_NOTIFY_CHANGE_FILE_NAME
),
1633 FFSNotifyReportChange(
1638 FILE_NOTIFY_CHANGE_DIR_NAME
:
1639 FILE_NOTIFY_CHANGE_FILE_NAME
),
1640 FILE_ACTION_RENAMED_NEW_NAME
);
1651 __drv_mustHoldCriticalRegion
1654 PFFS_IRP_CONTEXT IrpContext
,
1658 BOOLEAN bRet
= FALSE
;
1659 LARGE_INTEGER AllocationSize
;
1660 PFFS_FCB Dcb
= NULL
;
1666 FFSPrint((DBG_INFO
, "FFSDeleteFile: File %S (%xh) will be deleted!\n",
1667 Fcb
->FFSMcb
->ShortName
.Buffer
, Fcb
->FFSMcb
->Inode
));
1669 if (IsFlagOn(Fcb
->Flags
, FCB_FILE_DELETED
))
1674 if (FlagOn(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
))
1676 if (!FFSIsDirectoryEmpty(Vcb
, Fcb
))
1678 ClearFlag(Fcb
->Flags
, FCB_DELETE_PENDING
);
1684 FFSPrint((DBG_INFO
, "FFSDeleteFile: FFSSB->S_FREE_BLOCKS = %xh .\n",
1685 Vcb
->ffs_super_block
->fs_size
- Vcb
->ffs_super_block
->fs_dsize
));
1687 Status
= STATUS_UNSUCCESSFUL
;
1690 if (Fcb
->FFSMcb
->Parent
->FFSFcb
)
1692 Status
= FFSRemoveEntry(
1694 Fcb
->FFSMcb
->Parent
->FFSFcb
,
1695 (FlagOn(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
) ?
1697 Fcb
->FFSMcb
->Inode
);
1701 Dcb
= FFSCreateFcbFromMcb(Vcb
, Fcb
->FFSMcb
->Parent
);
1704 Status
= FFSRemoveEntry(
1705 IrpContext
, Vcb
, Dcb
,
1706 (FlagOn(Fcb
->FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
) ?
1708 Fcb
->FFSMcb
->Inode
);
1713 if (NT_SUCCESS(Status
))
1715 Fcb
->dinode1
->di_nlink
--;
1717 if (IsDirectory(Fcb
))
1719 if (Fcb
->dinode1
->di_nlink
< 2)
1726 if (Fcb
->dinode1
->di_nlink
== 0)
1736 AllocationSize
.QuadPart
= (LONGLONG
)0;
1737 bRet
= FFSTruncateFile(IrpContext
, Vcb
, Fcb
, &AllocationSize
);
1740 // Update the inode's data length . It should be ZERO if succeeds.
1743 if (Fcb
->dinode1
->di_size
> Fcb
->Header
.AllocationSize
.LowPart
)
1745 Fcb
->dinode1
->di_size
= Fcb
->Header
.AllocationSize
.LowPart
;
1748 Fcb
->Header
.FileSize
.QuadPart
= (LONGLONG
) Fcb
->dinode1
->di_size
;
1753 LARGE_INTEGER SysTime
;
1754 KeQuerySystemTime(&SysTime
);
1756 /*Fcb->dinode->di_dtime = FFSInodeTime(SysTime); XXX */
1758 FFSv1SaveInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, Fcb
->dinode1
);
1761 if (IsDirectory(Fcb
))
1763 bRet
= FFSFreeInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, DT_DIR
);
1767 bRet
= FFSFreeInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, DT_REG
);
1770 SetFlag(Fcb
->Flags
, FCB_FILE_DELETED
);
1771 FFSDeleteMcbNode(Vcb
, Fcb
->FFSMcb
->Parent
, Fcb
->FFSMcb
);
1775 FFSv1SaveInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, Fcb
->dinode1
);
1780 FFSv1SaveInode(IrpContext
, Vcb
, Fcb
->FFSMcb
->Inode
, Fcb
->dinode1
);
1783 FFSPrint((DBG_INFO
, "FFSDeleteFile: Succeed... FFSSB->S_FREE_BLOCKS = %xh .\n",
1784 Vcb
->ffs_super_block
->fs_size
- Vcb
->ffs_super_block
->fs_dsize
));
1789 #endif // !FFS_READ_ONLY