/*
* 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
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);
+ }
- pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+ //
+ // Save the original value
+ //
- DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+ pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
- ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+ 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;
+
+ SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+ }
+ }
+ else
+ {
+ //
+ // Reset the readonly flag.
+ //
- SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+ if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+ FILE_ATTRIBUTE_READONLY))
+ {
+
+ DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
+
+ 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))
{
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
{
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
{