23#define BugCheckFileId (FAT_BUG_CHECK_FILEINFO)
29#define Dbg (DEBUG_TRACE_FILEINFO)
113FatSetDispositionInfo (
138FatSetAllocationInfo (
157FatSetValidDataLengthInfo (
175#pragma alloc_text(PAGE, FatCommonQueryInformation)
176#pragma alloc_text(PAGE, FatCommonSetInformation)
177#pragma alloc_text(PAGE, FatFsdQueryInformation)
178#pragma alloc_text(PAGE, FatFsdSetInformation)
179#pragma alloc_text(PAGE, FatQueryBasicInfo)
180#pragma alloc_text(PAGE, FatQueryEaInfo)
181#pragma alloc_text(PAGE, FatQueryInternalInfo)
182#pragma alloc_text(PAGE, FatQueryNameInfo)
183#pragma alloc_text(PAGE, FatQueryNetworkInfo)
184#pragma alloc_text(PAGE, FatQueryShortNameInfo)
185#pragma alloc_text(PAGE, FatQueryPositionInfo)
186#pragma alloc_text(PAGE, FatQueryStandardInfo)
187#pragma alloc_text(PAGE, FatSetAllocationInfo)
188#pragma alloc_text(PAGE, FatSetBasicInfo)
189#pragma alloc_text(PAGE, FatSetDispositionInfo)
190#pragma alloc_text(PAGE, FatSetEndOfFileInfo)
191#pragma alloc_text(PAGE, FatSetValidDataLengthInfo)
192#pragma alloc_text(PAGE, FatSetPositionInfo)
193#pragma alloc_text(PAGE, FatSetRenameInfo)
194#pragma alloc_text(PAGE, FatDeleteFile)
195#pragma alloc_text(PAGE, FatRenameEAs)
203FatFsdQueryInformation (
250 Status = FatCommonQueryInformation( IrpContext,
Irp );
284FatFsdSetInformation (
331 Status = FatCommonSetInformation( IrpContext,
Irp );
363FatCommonQueryInformation (
428 Buffer =
Irp->AssociatedIrp.SystemBuffer;
501 if (!FatAcquireSharedFcb( IrpContext,
Fcb )) {
520 FatVerifyFcb( IrpContext,
Fcb );
586#if (NTDDI_VERSION >= NTDDI_VISTA)
615 "FATQueryFile, Illegal TypeOfOpen = %08lx\n",
663FatCommonSetInformation (
831#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
856 if (!FatAcquireExclusiveFcb( IrpContext,
Fcb )) {
877 FatVerifyFcb( IrpContext,
Fcb );
1013 if ( IrpContext !=
NULL ) {
1105 &
Buffer->LastWriteTime );
1131 if (
Buffer->FileAttributes == 0) {
1156FatQueryStandardInfo (
1197 Buffer->NumberOfLinks = 1;
1210 FatLookupFileAllocationSize( IrpContext,
Fcb );
1370 FatGetDirentFromFcbOrDcb( IrpContext,
1381 FatGetEaLength( IrpContext,
1540 FatSetFullFileNameInFcb( IrpContext,
Fcb );
1589 if (*Length < Fcb->FullFileName.Length - TrimLength) {
1616 if (TrimLength != 0) {
1619 WCHAR ShortNameBuffer[12];
1629 ShortName.MaximumLength =
sizeof(ShortNameBuffer);
1633#pragma prefast( suppress:28931, "needed for debug build" )
1719 WCHAR ShortNameBuffer[12];
1731 ShortName.MaximumLength =
sizeof(ShortNameBuffer);
1737#pragma prefast( suppress:28931, "needed for debug build" )
1786FatQueryNetworkInfo (
1846 &
Buffer->LastWriteTime );
1872 if (
Buffer->FileAttributes == 0) {
1886 FatLookupFileAllocationSize( IrpContext,
Fcb );
1889 Buffer->AllocationSize.QuadPart =
Fcb->
Header.AllocationSize.QuadPart;
1953 UCHAR CreationMSec = 0;
1963#if (NTDDI_VERSION >= NTDDI_WIN8)
1977 Buffer =
Irp->AssociatedIrp.SystemBuffer;
1991 if (
Buffer->LastWriteTime.QuadPart == -1) {
1994 Buffer->LastWriteTime.QuadPart = 0;
1997 if (
Buffer->LastAccessTime.QuadPart == -1) {
2000 Buffer->LastAccessTime.QuadPart = 0;
2003 if (
Buffer->CreationTime.QuadPart == -1) {
2006 Buffer->CreationTime.QuadPart = 0;
2019 &FatLocalDecThirtyOne1979 );
2022 &FatLocalJanOne1980 );
2030 FatGetDirentFromFcbOrDcb( IrpContext,
2041 LargeCreationTime =
Buffer->CreationTime;
2047 if ( !FatNtTimeToFatTime( IrpContext,
2062 LargeCreationTime = FatLocalJanOne1980;
2077 ModifyCreation =
TRUE;
2086 LargeLastAccessTime =
Buffer->LastAccessTime;
2092 if ( !FatNtTimeToFatTime( IrpContext,
2093 &LargeLastAccessTime,
2107 LargeLastAccessTime = FatLocalJanOne1980;
2116 LastAccessDate = LastAccessTime.
Date;
2117 ModifyLastAccess =
TRUE;
2124 if (
Buffer->LastWriteTime.QuadPart != 0) {
2131 if (ModifyLastAccess &&
2132 (
Buffer->LastWriteTime.QuadPart ==
Buffer->LastAccessTime.QuadPart)) {
2134 ModifyLastWrite =
TRUE;
2135 LastWriteTime = LastAccessTime;
2136 LargeLastWriteTime = LargeLastAccessTime;
2140 LargeLastWriteTime =
Buffer->LastWriteTime;
2146 if ( !FatNtTimeToFatTime( IrpContext,
2147 &LargeLastWriteTime,
2162 LargeLastWriteTime = FatLocalJanOne1980;
2171 ModifyLastWrite =
TRUE;
2180 if (
Buffer->FileAttributes != 0) {
2202 DebugTrace(0,
Dbg,
"Attempt to set dir attribute on file\n", 0);
2257#if (NTDDI_VERSION >= NTDDI_WIN8)
2258 ModifiedAttributes =
TRUE;
2263 if ( ModifyCreation ) {
2272 Dirent->CreationMSec = CreationMSec;
2294 if ( ModifyLastAccess ) {
2302 Dirent->LastAccessDate = LastAccessDate;
2331 if ( ModifyLastWrite ) {
2380 Dirent->FirstClusterOfFileHi =
2391 FatSetDirtyBcb( IrpContext, DirentBcb,
Fcb->
Vcb,
TRUE );
2394#if (NTDDI_VERSION >= NTDDI_WIN8)
2401 (ModifyLastAccess ||
2403 ModifiedAttributes)) {
2406 IrpContext->OriginatingIrp,
2407 OPLOCK_FLAG_PARENT_OBJECT,
2433FatSetDispositionInfo (
2472 Buffer =
Irp->AssociatedIrp.SystemBuffer;
2479 if (
Buffer->DeleteFile) {
2497 MmFlushForDelete )) {
2499 DebugTrace(-1,
Dbg,
"Cannot delete user mapped image\n", 0);
2518 DebugTrace(-1,
Dbg,
"User wants to delete a directory\n", 0);
2524 if ( !FatIsDirectoryEmpty(IrpContext,
Fcb) ) {
2549 BytesToMap =
Vcb->AllocationSupport.FatIndexBitSize == 12 ?
2558 (
PVOID *)&LocalBuffer );
2582 TmpChar = LocalBuffer[0];
2583 LocalBuffer[0] = TmpChar;
2588 Vcb->Bpb.BytesPerSector );
2602 DbgDoit( IrpContext->PinCount -= 1 );
2623 FatGetDirentFromFcbOrDcb( IrpContext,
2683 DebugTrace(-1,
Dbg,
"FatSetDispositionInfo -> STATUS_SUCCESS\n", 0);
2737 BOOLEAN RenamedAcrossDirectories;
2749 UCHAR OemNameBuffer[24*2];
2755 PBCB TargetDirentBcb;
2777 ULONG BytesInFirstPage = 0;
2778 ULONG DirentsInFirstPage = 0;
2779 ULONG DirentsRequired = 0;
2780 ULONG NewOffset = 0;
2781 ULONG NotifyAction = 0;
2782 ULONG SecondPageOffset = 0;
2783 ULONG ShortDirentOffset = 0;
2784 ULONG TargetDirentOffset = 0;
2785 ULONG TargetLfnOffset = 0;
2803 WCHAR UniTunneledShortNameBuffer[12];
2805 WCHAR UniTunneledLongNameBuffer[26];
2808 ULONG TunneledDataSize;
2825 CaseOnlyRename =
FALSE;
2826 ContinueWithRename =
FALSE;
2827 DeleteSourceDirent =
FALSE;
2828 DeleteTarget =
FALSE;
2829 NewDirentFromPool =
FALSE;
2830 RenamedAcrossDirectories =
FALSE;
2833 NewDirentBcb =
NULL;
2834 OldDirentBcb =
NULL;
2835 SecondPageBcb =
NULL;
2836 TargetDirentBcb =
NULL;
2838 NewOemName.Length = 0;
2839 NewOemName.MaximumLength = 24;
2840 NewOemName.Buffer = (
PCHAR)&OemNameBuffer[0];
2842 OldOemName.Length = 0;
2843 OldOemName.MaximumLength = 24;
2844 OldOemName.Buffer = (
PCHAR)&OemNameBuffer[24];
2850 NewUpcasedName.
Length = 0;
2852 NewUpcasedName.
Buffer = &UnicodeBuffer[0];
2858 OldUpcasedName.
Length = 0;
2870 UniTunneledShortName.
Length = 0;
2871 UniTunneledShortName.
MaximumLength =
sizeof(UniTunneledShortNameBuffer);
2872 UniTunneledShortName.
Buffer = &UniTunneledShortNameBuffer[0];
2874 UniTunneledLongName.
Length = 0;
2875 UniTunneledLongName.
MaximumLength =
sizeof(UniTunneledLongNameBuffer);
2876 UniTunneledLongName.
Buffer = &UniTunneledLongNameBuffer[0];
2885 OldOemName.Length );
2930 PFCB BatchOplockFcb;
2931 ULONG BatchOplockCount;
2940 BatchOplockFcb =
NULL;
2941 BatchOplockCount = 0;
2962#if (NTDDI_VERSION >= NTDDI_WIN7)
2968 BatchOplockCount += 1;
2969 if ( BatchOplockFcb ==
NULL ) {
2971 BatchOplockFcb = TempFcb;
2986 if ( BatchOplockFcb !=
NULL ) {
2988 if ( (
Irp->IoStatus.Information != 0) &&
2989 (BatchOplockCount >=
Irp->IoStatus.Information) ) {
2998 Irp->IoStatus.Information = BatchOplockCount;
3031 FatPurgeReferencedFileObjects( IrpContext,
Fcb,
Flush );
3044 FatAcquireExclusiveFcb( IrpContext, TempFcb );
3062 if (TargetFileObject ==
NULL) {
3072 Buffer =
Irp->AssociatedIrp.SystemBuffer;
3105 (TargetVcb !=
Vcb)) {
3132 FatGetUnicodeNameFromFcb( IrpContext,
Fcb, &OldName );
3171 CaseOnlyRename =
TRUE;
3176 RenamedAcrossDirectories =
TRUE;
3197 NewOemName.Length = 0;
3202 NewOemName.Length = 0;
3213 &UniTunneledShortName,
3214 &UniTunneledLongName,
3216 &TunneledCreationTime );
3225 if ((NewOemName.Length == 0) ||
3242 if (UniTunneledLongName.
Length &&
3243 !FatLfnDirentExists(IrpContext,
TargetDcb, &UniTunneledLongName, &TargetLfn)) {
3255 DirentsRequired = 1;
3271 if (NewOemName.Length == 0) {
3283 UsingTunneledLfn =
FALSE;
3286 if (!CaseOnlyRename) {
3293 if (NewOemName.Length != 0) {
3310 FatLocateDirent( IrpContext,
3317 (
PVBO)&TargetDirentOffset,
3322 if (TargetDirent !=
NULL) {
3331 if ((!ReplaceIfExists) ||
3357 Links = Links->
Flink;
3362 MmFlushForDelete))) {
3406 TargetLfnOffset = TargetDirentOffset -
3410 DeleteTarget =
TRUE;
3428 NewOffset = FatCreateNewDirent( IrpContext,
3433 DeleteSourceDirent =
TRUE;
3440 ContinueWithRename =
TRUE;
3446 if (!ContinueWithRename) {
3462 if (!ContinueWithRename) {
3480 if (!RenamedAcrossDirectories && !DeleteTarget) {
3503 FatGetDirentFromFcbOrDcb( IrpContext,
Fcb,
FALSE, &OldDirent, &OldDirentBcb );
3521 InvalidateFcbOnRaise =
TRUE;
3527 if (DeleteSourceDirent) {
3538 FatDeleteFile( IrpContext,
3556 FatSelectNames( IrpContext,
3561 (HaveTunneledInformation ? &UniTunneledShortName :
NULL),
3583 FatPrepareWriteDirectoryFile( IrpContext,
3591 (
PVOID *)&NewDirent,
3609 BytesInFirstPage = SecondPageOffset - NewOffset;
3611 DirentsInFirstPage = BytesInFirstPage /
sizeof(
DIRENT);
3613 FatPrepareWriteDirectoryFile( IrpContext,
3621 (
PVOID *)&SecondPageDirent,
3629 FirstPageDirent = NewDirent;
3632 DirentsRequired *
sizeof(
DIRENT),
3635 NewDirentFromPool =
TRUE;
3642 ShortDirent = NewDirent + DirentsRequired - 1;
3643 ShortDirentOffset = NewOffset + (DirentsRequired - 1) *
sizeof(
DIRENT);
3659 (HaveTunneledInformation ? &TunneledCreationTime :
NULL) );
3661 if (HaveTunneledInformation) {
3679 if (NewDirentFromPool) {
3681 RtlCopyMemory( FirstPageDirent, NewDirent, BytesInFirstPage );
3684 NewDirent + DirentsInFirstPage,
3685 DirentsRequired*
sizeof(
DIRENT) - BytesInFirstPage );
3687 ShortDirent = SecondPageDirent +
3688 (DirentsRequired - DirentsInFirstPage) - 1;
3754#if (NTDDI_VERSION >= NTDDI_WIN8)
3762 IrpContext->OriginatingIrp,
3763 OPLOCK_FLAG_PARENT_OBJECT,
3773 if (RenamedAcrossDirectories) {
3775#if (NTDDI_VERSION >= NTDDI_WIN8)
3783 IrpContext->OriginatingIrp,
3784 OPLOCK_FLAG_PARENT_OBJECT,
3802 DirectoryFileObject = OldParentDcb->
Specific.
Dcb.DirectoryFile;
3814 FatPrepareWriteDirectoryFile( IrpContext,
3822 (
PVOID *)&DotDotDirent,
3830 DotDotDirent->FirstClusterOfFile = (
USHORT)
3836 DotDotDirent->FirstClusterOfFileHi = (
USHORT)
3865 InvalidateFcbOnRaise =
FALSE;
3904 }
else if (RenamedAcrossDirectories) {
3933 Dirent.ExtendedAttributes != 0) {
3935 FatRenameEAs( IrpContext,
3937 Dirent.ExtendedAttributes,
3957 if (UniTunneledLongName.
Buffer != UniTunneledLongNameBuffer) {
3966 if (NewDirentFromPool) {
3978 if (DirectoryFileObject) {
3980 DebugTrace(0,
Dbg,
"Uninitialize our parent Stream Cache Map\n", 0);
4043 Buffer =
Irp->AssociatedIrp.SystemBuffer;
4059 DebugTrace(0,
Dbg,
"Cannot set position due to aligment conflict\n", 0);
4089FatSetAllocationInfo (
4123 ULONG NewAllocationSize = 0;
4124 ULONG HeaderSize = 0;
4129 ULONG OriginalFileSize = 0;
4130 ULONG OriginalValidDataLength = 0;
4131 ULONG OriginalValidDataToDisk = 0;
4135 Buffer =
Irp->AssociatedIrp.SystemBuffer;
4137 NewAllocationSize =
Buffer->AllocationSize.LowPart;
4139 DebugTrace(+1,
Dbg,
"FatSetAllocationInfo.. to %08lx\n", NewAllocationSize);
4147 DebugTrace(-1,
Dbg,
"Cannot change allocation of a directory\n", 0);
4171 FatLookupFileAllocationSize( IrpContext,
Fcb );
4180 if ((
FileObject->SectionObjectPointer->DataSectionObject !=
NULL) &&
4196 CacheMapInitialized =
TRUE;
4217 if (NewAllocationSize+HeaderSize >
Fcb->
Header.AllocationSize.LowPart) {
4219 FatAddFileAllocation( IrpContext,
Fcb,
FileObject, NewAllocationSize+HeaderSize);
4228 if (
Fcb->
Header.FileSize.LowPart > NewAllocationSize+HeaderSize ) {
4250 &
Buffer->AllocationSize )) {
4255 FileSizeTruncated =
TRUE;
4257 OriginalFileSize =
Fcb->
Header.FileSize.LowPart;
4258 OriginalValidDataLength =
Fcb->
Header.ValidDataLength.LowPart;
4262 ResourceAcquired =
TRUE;
4264 Fcb->
Header.FileSize.LowPart = NewAllocationSize;
4286 FatTruncateFileAllocation( IrpContext,
Fcb, NewAllocationSize+HeaderSize );
4292 if ( FileSizeTruncated ) {
4324 FileSizeTruncated =
FALSE;
4326 FatSetFileSizeInDirent( IrpContext,
Fcb,
NULL );
4346 Fcb->
Header.FileSize.LowPart = OriginalFileSize;
4347 Fcb->
Header.ValidDataLength.LowPart = OriginalValidDataLength;
4362 if (CacheMapInitialized) {
4367 if (ResourceAcquired) {
4387FatSetEndOfFileInfo (
4426 ULONG InitialFileSize = 0;
4427 ULONG InitialValidDataLength = 0;
4428 ULONG InitialValidDataToDisk = 0;
4439 Buffer =
Irp->AssociatedIrp.SystemBuffer;
4449 DebugTrace(0,
Dbg,
"Cannot change size of a directory\n", 0);
4477 FatLookupFileAllocationSize( IrpContext,
Fcb );
4486 if ((
FileObject->SectionObjectPointer->DataSectionObject !=
NULL) &&
4517 CacheMapInitialized =
TRUE;
4558 FatGetDirentFromFcbOrDcb( IrpContext,
4569 FatSetDirtyBcb( IrpContext, DirentBcb,
Fcb->
Vcb,
TRUE );
4590 DebugTrace(0,
Dbg,
"Cannot set size on deleted file.\n", 0);
4620 if ( NewFileSize < Fcb->
Header.FileSize.LowPart ) {
4661 InitialFileSize =
Fcb->
Header.FileSize.LowPart;
4662 InitialValidDataLength =
Fcb->
Header.ValidDataLength.LowPart;
4664 UnwindFileSizes =
TRUE;
4692 FatSetFileSizeInDirent( IrpContext,
Fcb,
NULL );
4734 Fcb->
Header.FileSize.LowPart = InitialFileSize;
4735 Fcb->
Header.ValidDataLength.LowPart = InitialValidDataLength;
4757 FatSetFileSizeInDirentNoRaise( IrpContext,
Fcb,
NULL );
4761 if (CacheMapInitialized) {
4766 if ( ResourceAcquired ) {
4784FatSetValidDataLengthInfo (
4823 ULONG NewValidDataLength;
4832 Buffer =
Irp->AssociatedIrp.SystemBuffer;
4851 DebugTrace(0,
Dbg,
"Cannot change VDL of a directory\n", 0);
4869 NewValidDataLength =
Buffer->ValidDataLength.LowPart;
4875 if ((NewValidDataLength < Fcb->
Header.ValidDataLength.LowPart) ||
4876 (NewValidDataLength >
Fcb->
Header.FileSize.LowPart)) {
4887 &
Buffer->ValidDataLength )) {
4896 if (
FileObject->SectionObjectPointer->DataSectionObject !=
NULL) {
4921 Fcb->
Header.ValidDataLength.LowPart = NewValidDataLength;
4924 DebugTrace(0,
Dbg,
"New VDL is 0x%08lx.\n", NewValidDataLength);
4954 if (ResourceAcquired) {
5008 FatGetEaFile( IrpContext,
5022 if (
Vcb->VirtualEaFile !=
NULL) {
5109 Links = Links->
Flink) {
5122#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
5145 Fcb->
Header.ValidDataLength.QuadPart = 0;
5176 FatTruncateFileAllocation( IrpContext,
Fcb, 0 );
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
#define CcGetFileSizePointer(FO)
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define IRP_CONTEXT_FLAG_WAIT
#define _Requires_lock_held_(lock)
#define NT_SUCCESS(StatCode)
#define FILE_ATTRIBUTE_NORMAL
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING Lfn
_In_ PIO_STACK_LOCATION IrpSp
VOID FatSetFullNameInFcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ PUNICODE_STRING FinalName)
EA_SET_HEADER * PEA_SET_HEADER
#define FAT_DIRENT_ATTR_READ_ONLY
#define FatReservedBytes(B)
#define FAT_DIRENT_ATTR_DIRECTORY
#define FatBytesPerFat(B)
VOID FatQueryInternalInfo(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_INTERNAL_INFORMATION Buffer, IN OUT PLONG Length)
VOID FatQueryPositionInfo(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN OUT PFILE_POSITION_INFORMATION Buffer, IN OUT PLONG Length)