Windows: FileInfo too small INFO_LENGTH_MISMATCH
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
index 39103e7..2eb6c73 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -103,11 +103,20 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                                      &stAuthGroup);
 
             ntStatus = AFSVerifyEntry( &stAuthGroup,
-                                       pCcb->DirectoryCB);
+                                      pCcb->DirectoryCB,
+                                      FALSE);
 
             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
@@ -236,16 +245,17 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                     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 = STATUS_INFO_LENGTH_MISMATCH);
+               }
 
-                    try_return( ntStatus);
-                }
+               lLength -= sizeof( FILE_ACCESS_INFORMATION);
 
                 ntStatus = AFSQueryPositionInfo( Irp,
                                                  pFcb,
@@ -258,27 +268,28 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                     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 = STATUS_INFO_LENGTH_MISMATCH);
+               }
 
-                    try_return( ntStatus);
-                }
+               lLength -= sizeof( FILE_MODE_INFORMATION);
 
-                ntStatus = AFSQueryAlignment( Irp,
-                                              pFcb,
-                                              &pAllInfo->AlignmentInformation,
-                                              &lLength);
+               if( lLength < sizeof( FILE_ALIGNMENT_INFORMATION))
+               {
+                   try_return( ntStatus = STATUS_INFO_LENGTH_MISMATCH);
+               }
 
-                if( !NT_SUCCESS( ntStatus))
-                {
+               lLength -= sizeof( FILE_ALIGNMENT_INFORMATION);
 
-                    try_return( ntStatus);
-                }
+               //
+               // Populate the name information
+               //
 
                 ntStatus = AFSQueryNameInfo( Irp,
                                              pCcb->DirectoryCB,
@@ -458,10 +469,10 @@ try_exit:
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               &pCcb->DirectoryCB->NameInformation.FileName,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
                               ntStatus));
             }
         }
@@ -583,7 +594,8 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             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,
@@ -637,10 +649,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             case FileBasicInformation:
             {
 
-                bUpdateFileInfo = TRUE;
-
                 ntStatus = AFSSetBasicInfo( Irp,
-                                            pCcb->DirectoryCB);
+                                           pCcb->DirectoryCB,
+                                           &bUpdateFileInfo);
 
                 break;
             }
@@ -737,10 +748,10 @@ try_exit:
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               &pCcb->DirectoryCB->NameInformation.FileName,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
                               ntStatus));
 
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
@@ -758,10 +769,10 @@ try_exit:
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               &pCcb->DirectoryCB->NameInformation.FileName,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
-                              pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
                               ntStatus));
             }
         }
@@ -808,7 +819,7 @@ AFSQueryBasicInfo( IN PIRP Irp,
                    IN OUT PFILE_BASIC_INFORMATION Buffer,
                    IN OUT PLONG Length)
 {
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     ULONG ulFileAttribs = 0;
     AFSFcb *pFcb = NULL;
@@ -886,8 +897,8 @@ AFSQueryBasicInfo( IN PIRP Irp,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
                       &pCcb->DirectoryCB->NameInformation.FileName,
-                      pCcb->DirectoryCB->ObjectInformation->FileType,
-                      pCcb->DirectoryCB->ObjectInformation->FileAttributes,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
                       ulFileAttribs));
 
         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
@@ -911,11 +922,8 @@ AFSQueryBasicInfo( IN PIRP Irp,
         }
 
         *Length -= sizeof( FILE_BASIC_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -928,7 +936,7 @@ AFSQueryStandardInfo( IN PIRP Irp,
                       IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
@@ -1011,18 +1019,15 @@ AFSQueryStandardInfo( IN PIRP Irp,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
                       &pCcb->DirectoryCB->NameInformation.FileName,
-                      pCcb->DirectoryCB->ObjectInformation->FileType,
-                      pCcb->DirectoryCB->ObjectInformation->FileAttributes,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
                       ulFileAttribs));
 
         Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
 
         *Length -= sizeof( FILE_STANDARD_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1036,7 +1041,7 @@ AFSQueryInternalInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(Irp);
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
     {
@@ -1046,11 +1051,8 @@ AFSQueryInternalInfo( IN PIRP Irp,
         Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
 
         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1065,7 +1067,7 @@ AFSQueryEaInfo( IN PIRP Irp,
 
     UNREFERENCED_PARAMETER(Irp);
     UNREFERENCED_PARAMETER(DirectoryCB);
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -1076,11 +1078,8 @@ AFSQueryEaInfo( IN PIRP Irp,
         Buffer->EaSize = 0;
 
         *Length -= sizeof( FILE_EA_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1094,7 +1093,7 @@ AFSQueryPositionInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(Fcb);
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
 
     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
@@ -1106,101 +1105,8 @@ AFSQueryPositionInfo( IN PIRP Irp,
         Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
 
         *Length -= sizeof( FILE_POSITION_INFORMATION);
-    }
-    else
-    {
-
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
-    }
-
-    return ntStatus;
-}
-
-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;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1214,7 +1120,7 @@ AFSQueryNameInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(DirectoryCB);
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
     ULONG cchCopied = 0;
     AFSFcb *pFcb = NULL;
@@ -1265,6 +1171,8 @@ AFSQueryNameInfo( IN PIRP Irp,
         {
 
             ulCopyLength = (LONG)usFullNameLength;
+
+           ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -1340,11 +1248,6 @@ AFSQueryNameInfo( IN PIRP Irp,
             }
         }
     }
-    else
-    {
-
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
-    }
 
     return ntStatus;
 }
@@ -1357,7 +1260,7 @@ AFSQueryShortNameInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(Irp);
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
 
     RtlZeroMemory( Buffer,
@@ -1450,7 +1353,7 @@ AFSQueryNetworkInfo( IN PIRP Irp,
                      IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
@@ -1527,8 +1430,8 @@ AFSQueryNetworkInfo( IN PIRP Irp,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
                       &pCcb->DirectoryCB->NameInformation.FileName,
-                      pCcb->DirectoryCB->ObjectInformation->FileType,
-                      pCcb->DirectoryCB->ObjectInformation->FileAttributes,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
                       ulFileAttribs));
 
         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
@@ -1558,11 +1461,8 @@ AFSQueryNetworkInfo( IN PIRP Irp,
         }
 
         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1576,7 +1476,7 @@ AFSQueryStreamInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(Irp);
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
 
     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
@@ -1645,7 +1545,7 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
                        IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
@@ -1722,8 +1622,8 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
                       &pCcb->DirectoryCB->NameInformation.FileName,
-                      pCcb->DirectoryCB->ObjectInformation->FileType,
-                      pCcb->DirectoryCB->ObjectInformation->FileAttributes,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
                       ulFileAttribs));
 
         Buffer->FileAttributes = ulFileAttribs;
@@ -1772,7 +1672,7 @@ AFSQueryRemoteProtocolInfo( IN PIRP Irp,
 
     UNREFERENCED_PARAMETER(Irp);
     UNREFERENCED_PARAMETER(DirectoryCB);
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
     {
@@ -1808,7 +1708,7 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
 {
 
     UNREFERENCED_PARAMETER(DirectoryCB);
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
     ULONG cchCopied = 0;
     AFSFcb *pFcb = NULL;
@@ -1843,6 +1743,8 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
         {
             ulCopyLength = (LONG)usFullNameLength;
+
+           ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -1891,18 +1793,14 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
             }
         }
     }
-    else
-    {
-
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
-    }
 
     return ntStatus;
 }
 
 NTSTATUS
 AFSSetBasicInfo( IN PIRP Irp,
-                 IN AFSDirectoryCB *DirectoryCB)
+                IN AFSDirectoryCB *DirectoryCB,
+                OUT BOOLEAN *bUpdateFileInfo)
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_BASIC_INFORMATION pBuffer;
@@ -1922,26 +1820,92 @@ AFSSetBasicInfo( IN PIRP Irp,
         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))
+               {
 
-            pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+                   if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                   {
 
-            DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+                       DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
+                   }
+                   else
+                   {
 
-            ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+                       DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+                   }
 
-            SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+                   ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+                   SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+               }
+           }
+           else
+           {
+               //
+               // Reset the readonly flag.
+               //
+
+               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;
@@ -1987,6 +1951,12 @@ AFSSetBasicInfo( IN PIRP Irp,
             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;
@@ -2007,11 +1977,14 @@ AFSSetBasicInfo( IN PIRP Irp,
         if( ulNotifyFilter > 0)
         {
 
+           *bUpdateFileInfo = TRUE;
+
             if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
             {
 
                 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
-                                                                         &DirectoryCB->ObjectInformation->ParentFileId);
+                                                                         &DirectoryCB->ObjectInformation->ParentFileId,
+                                                                         TRUE);
 
                 if ( pParentObjectInfo != NULL)
                 {
@@ -2130,6 +2103,52 @@ AFSSetDispositionInfo( IN PIRP Irp,
                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
                 }
 
+                //
+                // Make sure the directory is enumerated before checking to see if it is empty.
+                //
+
+                if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
+                {
+
+                    AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
+                    if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
+                    {
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                      pFcb->ObjectInformation->FileId.Cell,
+                                      pFcb->ObjectInformation->FileId.Volume,
+                                      pFcb->ObjectInformation->FileId.Vnode,
+                                      pFcb->ObjectInformation->FileId.Unique));
+
+                        ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
+                                                          pFcb->ObjectInformation,
+                                                          TRUE);
+
+                        if( !NT_SUCCESS( ntStatus))
+                        {
+
+                            AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_ERROR,
+                                          "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                          pFcb->ObjectInformation->FileId.Cell,
+                                          pFcb->ObjectInformation->FileId.Volume,
+                                          pFcb->ObjectInformation->FileId.Vnode,
+                                          pFcb->ObjectInformation->FileId.Unique,
+                                          ntStatus));
+
+                            try_return( ntStatus);
+                        }
+                    }
+
+                    AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                }
+
                 if( !AFSIsDirectoryEmptyForDelete( pFcb))
                 {
 
@@ -2153,7 +2172,16 @@ AFSSetDispositionInfo( IN PIRP Irp,
             {
                 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,
@@ -2162,49 +2190,69 @@ AFSSetDispositionInfo( IN PIRP Irp,
                 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
                                 TRUE);
 
-                //
-                // Attempt to flush any outstanding data
-                //
-
-                bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
-                                                  MmFlushForDelete);
-
-                if ( bMmFlushed)
+               __try
                 {
 
                     //
-                    // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
-                    // deadlock with Trend Micro's Enterprise anti-virus product
-                    // which attempts to open the file which is being deleted.
+                   // Attempt to flush any outstanding data
                     //
 
-                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
-                                  DirectoryCB,
-                                  &DirectoryCB->NameInformation.FileName));
+                   bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
+                                                     MmFlushForDelete);
 
-                    SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+                   if ( bMmFlushed)
+                   {
 
-                    //
-                    // Purge the cache as well
-                    //
+                       //
+                       // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
+                       // deadlock with Trend Micro's Enterprise anti-virus product
+                       // which attempts to open the file which is being deleted.
+                       //
 
-                    if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
-                    {
+                       AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                     AFS_TRACE_LEVEL_VERBOSE,
+                                     "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
+                                     DirectoryCB,
+                                     &DirectoryCB->NameInformation.FileName));
 
-                        if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
-                                                   NULL,
-                                                   0,
-                                                   TRUE))
+                       SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+
+                       //
+                       // Purge the cache as well
+                       //
+
+                       if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                         {
 
-                            SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                           if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
+                                                      NULL,
+                                                      0,
+                                                      TRUE))
+                           {
+
+                               SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                           }
                         }
                     }
                 }
+               __except( EXCEPTION_EXECUTE_HANDLER)
+               {
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                   bMmFlushed = FALSE;
+
+                   ntStatus = GetExceptionCode();
+
+                   AFSDbgTrace(( 0,
+                                 0,
+                                 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                 pFcb->ObjectInformation->FileId.Cell,
+                                 pFcb->ObjectInformation->FileId.Volume,
+                                 pFcb->ObjectInformation->FileId.Vnode,
+                                 pFcb->ObjectInformation->FileId.Unique,
+                                 ntStatus));
+               }
+
+               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,
@@ -2212,6 +2260,14 @@ AFSSetDispositionInfo( IN PIRP Irp,
 
                 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)
                 {
 
@@ -2293,11 +2349,24 @@ AFSSetFileLinkInfo( IN PIRP Irp)
 
         pSrcObject = pSrcFcb->ObjectInformation;
 
-        if ( BooleanFlagOn( pSrcFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
         {
 
-            pSrcParentObject = AFSFindObjectInfo( pSrcFcb->ObjectInformation->VolumeCB,
-                                                  &pSrcFcb->ObjectInformation->ParentFileId);
+            pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
+                                                  &pSrcObject->ParentFileId,
+                                                  TRUE);
+        }
+
+        if( pSrcParentObject == NULL)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
+
+            ASSERT( FALSE);
+
+            try_return( ntStatus = STATUS_INVALID_PARAMETER);
         }
 
         pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
@@ -2545,7 +2614,7 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         // request to the service.
         //
 
-        ntStatus = AFSNotifyHardLink( pSrcFcb->ObjectInformation,
+        ntStatus = AFSNotifyHardLink( pSrcObject,
                                       &pSrcCcb->AuthGroup,
                                       pSrcParentObject,
                                       pTargetDcb->ObjectInformation,
@@ -2716,11 +2785,24 @@ AFSSetRenameInfo( IN PIRP Irp)
 
         pSrcObject = pSrcFcb->ObjectInformation;
 
-        if ( BooleanFlagOn( pSrcFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        {
+
+            pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
+                                                  &pSrcObject->ParentFileId,
+                                                  TRUE);
+        }
+
+        if( pSrcParentObject == NULL)
         {
 
-            pSrcParentObject = AFSFindObjectInfo( pSrcFcb->ObjectInformation->VolumeCB,
-                                                  &pSrcFcb->ObjectInformation->ParentFileId);
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
+
+            ASSERT( FALSE);
+
+            try_return( ntStatus = STATUS_INVALID_PARAMETER);
         }
 
         //
@@ -2748,7 +2830,7 @@ AFSSetRenameInfo( IN PIRP Irp)
             // If there are any open children then fail the rename
             //
 
-            if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
+            if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
             {
 
                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -3012,7 +3094,7 @@ AFSSetRenameInfo( IN PIRP Irp)
         // request to the service.
         //
 
-        ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
+        ntStatus = AFSNotifyRename( pSrcObject,
                                     &pSrcCcb->AuthGroup,
                                     pSrcParentObject,
                                     pTargetDcb->ObjectInformation,
@@ -3057,7 +3139,7 @@ AFSSetRenameInfo( IN PIRP Irp)
             ulNotificationAction = FILE_ACTION_REMOVED;
         }
 
-        if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+        if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
         {
 
             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
@@ -3222,6 +3304,14 @@ AFSSetRenameInfo( IN PIRP Irp)
 
             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
 
+
+            //
+            // Guaranteed to be in the same volume
+            //
+
+            AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
+                            TRUE);
+
             lCount = AFSObjectInfoIncrement( pTargetParentObject,
                                              AFS_OBJECT_REFERENCE_CHILD);
 
@@ -3240,11 +3330,11 @@ AFSSetRenameInfo( IN PIRP Irp)
                           pSrcParentObject,
                           lCount));
 
-            pSrcCcb->DirectoryCB->ObjectInformation->ParentFileId = pTargetParentObject->FileId;
+            pSrcObject->ParentFileId = pTargetParentObject->FileId;
 
-            SetFlag( pSrcCcb->DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+            SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
 
-            pSrcParentObject = pTargetParentObject;
+            AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
 
             ulNotificationAction = FILE_ACTION_ADDED;
         }
@@ -3316,7 +3406,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                               &pTargetDirEntry->NameInformation.FileName));
 
                 AFSDeleteDirEntry( pTargetParentObject,
-                                   pTargetDirEntry);
+                                   &pTargetDirEntry);
             }
 
             pTargetDirEntry = NULL;
@@ -3351,7 +3441,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                 // 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,
@@ -3360,7 +3450,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                 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,
@@ -3369,21 +3459,39 @@ AFSSetRenameInfo( IN PIRP Irp)
                 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
                                 TRUE);
 
-                //
-                // Close the section in the event it was mapped
-                //
+               __try
+               {
 
-                if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
-                                           TRUE))
+                   //
+                   // Close the section in the event it was mapped
+                   //
+
+                   if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
+                                              TRUE))
+                   {
+
+                       AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                     AFS_TRACE_LEVEL_ERROR,
+                                     "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
+                                     &uniTargetName));
+                   }
+               }
+               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
                 {
 
-                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
-                                  &uniTargetName));
+                   ntStatus = GetExceptionCode();
+
+                   AFSDbgTrace(( 0,
+                                 0,
+                                 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                 pTargetFcb->ObjectInformation->FileId.Cell,
+                                 pTargetFcb->ObjectInformation->FileId.Volume,
+                                 pTargetFcb->ObjectInformation->FileId.Vnode,
+                                 pTargetFcb->ObjectInformation->FileId.Unique,
+                                 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,
@@ -3525,7 +3633,7 @@ AFSSetAllocationInfo( IN PIRP Irp,
     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,
@@ -3534,10 +3642,30 @@ AFSSetAllocationInfo( IN PIRP Irp,
         AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
                         TRUE);
 
-        bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
-                                             &pBuffer->AllocationSize);
+       __try
+       {
 
-        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+           bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
+                                                &pBuffer->AllocationSize);
+       }
+       __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+       {
+
+           bUserMapped = FALSE;
+
+           ntStatus = GetExceptionCode();
+
+           AFSDbgTrace(( 0,
+                         0,
+                         "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                         pFcb->ObjectInformation->FileId.Cell,
+                         pFcb->ObjectInformation->FileId.Volume,
+                         pFcb->ObjectInformation->FileId.Vnode,
+                         pFcb->ObjectInformation->FileId.Unique,
+                         ntStatus));
+       }
+
+       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,
@@ -3670,6 +3798,11 @@ AFSSetAllocationInfo( IN PIRP Irp,
             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
     {
@@ -3731,7 +3864,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
         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,
@@ -3740,10 +3873,30 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
             AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
                             TRUE);
 
-            bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
-                                                 &pBuffer->EndOfFile);
+           __try
+           {
 
-            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
+                                                    &pBuffer->EndOfFile);
+           }
+           __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+           {
+
+               bUserMapped = FALSE;
+
+               ntStatus = GetExceptionCode();
+
+               AFSDbgTrace(( 0,
+                             0,
+                             "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                             pFcb->ObjectInformation->FileId.Cell,
+                             pFcb->ObjectInformation->FileId.Volume,
+                             pFcb->ObjectInformation->FileId.Vnode,
+                             pFcb->ObjectInformation->FileId.Unique,
+                             ntStatus));
+           }
+
+           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,
@@ -3766,7 +3919,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                 //
                 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()));
 
@@ -3815,7 +3968,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
             //
             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()));
 
@@ -3884,6 +4037,11 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                 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
         {