/*
* Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
if ( NT_SUCCESS( ntStatus))
{
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
+ pFcb->ObjectInformation->FileId.Cell,
+ pFcb->ObjectInformation->FileId.Volume,
+ pFcb->ObjectInformation->FileId.Vnode,
+ pFcb->ObjectInformation->FileId.Unique));
+
ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
}
else
try_return( ntStatus);
}
- ntStatus = AFSQueryAccess( Irp,
- pFcb,
- &pAllInfo->AccessInformation,
- &lLength);
+ //
+ // We skip setting AccessInformation since this is set by the IO Mgr prior
+ // to sending this request to the file system
+ //
- if( !NT_SUCCESS( ntStatus))
+ if( lLength < sizeof( FILE_ACCESS_INFORMATION))
{
-
- try_return( ntStatus);
+ try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
}
+ lLength -= sizeof( FILE_ACCESS_INFORMATION);
+
ntStatus = AFSQueryPositionInfo( Irp,
pFcb,
&pAllInfo->PositionInformation,
try_return( ntStatus);
}
- ntStatus = AFSQueryMode( Irp,
- pFcb,
- &pAllInfo->ModeInformation,
- &lLength);
+ //
+ // We skip setting ModeInformation and AlignmentInformation since this is set by the IO Mgr prior
+ // to sending this request to the file system
+ //
- if( !NT_SUCCESS( ntStatus))
+ if( lLength < sizeof( FILE_MODE_INFORMATION))
{
-
- try_return( ntStatus);
+ try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
}
- ntStatus = AFSQueryAlignment( Irp,
- pFcb,
- &pAllInfo->AlignmentInformation,
- &lLength);
+ lLength -= sizeof( FILE_MODE_INFORMATION);
- if( !NT_SUCCESS( ntStatus))
+ if( lLength < sizeof( FILE_ALIGNMENT_INFORMATION))
{
-
- try_return( ntStatus);
+ try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
}
+ lLength -= sizeof( FILE_ALIGNMENT_INFORMATION);
+
+ //
+ // Populate the name information
+ //
+
ntStatus = AFSQueryNameInfo( Irp,
pCcb->DirectoryCB,
&pAllInfo->NameInformation,
try_return( ntStatus);
}
- if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
+ if( FileInformationClass != FilePositionInformation &&
+ BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
{
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
case FileBasicInformation:
{
- bUpdateFileInfo = TRUE;
-
ntStatus = AFSSetBasicInfo( Irp,
- pCcb->DirectoryCB);
+ pCcb->DirectoryCB,
+ &bUpdateFileInfo);
break;
}
}
NTSTATUS
-AFSQueryAccess( IN PIRP Irp,
- IN AFSFcb *Fcb,
- IN OUT PFILE_ACCESS_INFORMATION Buffer,
- IN OUT PLONG Length)
-{
-
- UNREFERENCED_PARAMETER(Irp);
- UNREFERENCED_PARAMETER(Fcb);
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
- {
-
- RtlZeroMemory( Buffer,
- *Length);
-
- Buffer->AccessFlags = 0;
-
- *Length -= sizeof( FILE_ACCESS_INFORMATION);
- }
- else
- {
-
- ntStatus = STATUS_BUFFER_TOO_SMALL;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-AFSQueryMode( IN PIRP Irp,
- IN AFSFcb *Fcb,
- IN OUT PFILE_MODE_INFORMATION Buffer,
- IN OUT PLONG Length)
-{
-
- UNREFERENCED_PARAMETER(Irp);
- UNREFERENCED_PARAMETER(Fcb);
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- if( *Length >= sizeof( FILE_MODE_INFORMATION))
- {
-
- RtlZeroMemory( Buffer,
- *Length);
-
- Buffer->Mode = 0;
-
- *Length -= sizeof( FILE_MODE_INFORMATION);
- }
- else
- {
-
- ntStatus = STATUS_BUFFER_TOO_SMALL;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-AFSQueryAlignment( IN PIRP Irp,
- IN AFSFcb *Fcb,
- IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
- IN OUT PLONG Length)
-{
-
- UNREFERENCED_PARAMETER(Irp);
- UNREFERENCED_PARAMETER(Fcb);
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
- {
-
- RtlZeroMemory( Buffer,
- *Length);
-
- Buffer->AlignmentRequirement = 1;
-
- *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
- }
- else
- {
-
- ntStatus = STATUS_BUFFER_TOO_SMALL;
- }
-
- return ntStatus;
-}
-
-NTSTATUS
AFSQueryNameInfo( IN PIRP Irp,
IN AFSDirectoryCB *DirectoryCB,
IN OUT PFILE_NAME_INFORMATION Buffer,
NTSTATUS
AFSSetBasicInfo( IN PIRP Irp,
- IN AFSDirectoryCB *DirectoryCB)
+ IN AFSDirectoryCB *DirectoryCB,
+ OUT BOOLEAN *bUpdateFileInfo)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_BASIC_INFORMATION pBuffer;
if( pBuffer->FileAttributes != (ULONGLONG)0)
{
- if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
- BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
- {
+ //
+ // Make sure that the reparse point attribute is not modified.
+ // Fail if the RP attribute is requested but it is not
+ // already a RP. Otherwise, ignore it.
+ //
- try_return( ntStatus = STATUS_INVALID_PARAMETER);
- }
+ if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+ FILE_ATTRIBUTE_REPARSE_POINT) &&
+ BooleanFlagOn( pBuffer->FileAttributes,
+ FILE_ATTRIBUTE_REPARSE_POINT))
+ {
- if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
- {
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
- pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- }
+ //
+ // Make sure that the directory attribute is not modified.
+ // Fail if the D attribute is requested but it is not
+ // already a directory. Otherwise, ignore it.
+ //
+
+ if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+ FILE_ATTRIBUTE_DIRECTORY) &&
+ BooleanFlagOn( pBuffer->FileAttributes,
+ FILE_ATTRIBUTE_DIRECTORY))
+ {
+
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
+
+ //
+ // Save the original value
+ //
+
+ pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+
+ if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
+ {
+
+ //
+ // Set the readonly flag.
+ //
+
+ if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+ FILE_ATTRIBUTE_READONLY))
+ {
+
+ if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+ {
+
+ DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
+ }
+ else
+ {
+
+ DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ }
+
+ ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
- pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+ SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+ }
+ }
+ else
+ {
+ //
+ // Reset the readonly flag.
+ //
- DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+ if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+ FILE_ATTRIBUTE_READONLY))
+ {
- ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+ DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
- SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+ if ( DirectoryCB->ObjectInformation->FileAttributes == 0)
+ {
+
+ DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL;
+ }
+
+ ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+ SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+ }
+ }
}
pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
+
+ SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
+
+ } else if ( pBuffer->LastWriteTime.QuadPart == (ULONGLONG)-1) {
+
+ SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
}
pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
if( ulNotifyFilter > 0)
{
+ *bUpdateFileInfo = TRUE;
+
if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
{
{
BOOLEAN bMmFlushed;
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
+ &pFcb->NPFcb->Resource,
+ PsGetCurrentThread()));
+
+ AFSAcquireExcl( &pFcb->NPFcb->Resource,
+ TRUE);
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
ntStatus));
}
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
+ &pFcb->NPFcb->Resource,
+ PsGetCurrentThread()));
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+
if ( !bMmFlushed)
{
// permit the locks to be obtained out of order risking a deadlock.
//
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
&pTargetFcb->NPFcb->Resource,
AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
TRUE);
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
&pTargetFcb->NPFcb->SectionObjectResource,
&uniTargetName));
}
}
- __except( EXCEPTION_EXECUTE_HANDLER)
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
{
ntStatus = GetExceptionCode();
ntStatus));
}
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
&pTargetFcb->NPFcb->SectionObjectResource,
if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
{
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
&pBuffer->AllocationSize);
}
- __except( EXCEPTION_EXECUTE_HANDLER)
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
{
bUserMapped = FALSE;
ntStatus));
}
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
CcSetFileSizes( pFileObject,
(PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
}
+
+ //
+ // Mark the file as modified so as to reflect the change into the last write on close.
+ //
+ SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
}
else
{
if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
{
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
&pBuffer->EndOfFile);
}
- __except( EXCEPTION_EXECUTE_HANDLER)
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
{
bUserMapped = FALSE;
ntStatus));
}
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
&pFcb->NPFcb->SectionObjectResource,
//
AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+ "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
&pFcb->NPFcb->PagingResource,
PsGetCurrentThread()));
//
AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+ "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
&pFcb->NPFcb->PagingResource,
PsGetCurrentThread()));
AFSTrimExtents( pFcb,
&pFcb->Header.FileSize);
}
+
+ //
+ // Mark the file as modified so as to reflect the change into the last write on close.
+ //
+ SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
}
else
{