Windows: SetDispositionInfo vs Link Count
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
index 6ee14cd..a127059 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
@@ -55,15 +55,13 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                   IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(LibDeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
-    ULONG ulRequestType = 0;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
-    PFILE_OBJECT pFileObject;
     BOOLEAN bReleaseMain = FALSE;
-    LONG lLength;
+    LONG lLength = 0;
     FILE_INFORMATION_CLASS stFileInformationClass;
     GUID stAuthGroup;
     PVOID pBuffer;
@@ -82,10 +80,10 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
-                          Irp);
+                          "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
+                          Irp));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
@@ -94,25 +92,49 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
         pBuffer = Irp->AssociatedIrp.SystemBuffer;
 
-        RtlZeroMemory( &stAuthGroup,
-                       sizeof( GUID));
+        if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            RtlZeroMemory( &stAuthGroup,
+                           sizeof( GUID));
 
-        AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
-                                 (ULONGLONG)PsGetCurrentThreadId(),
-                                  &stAuthGroup);
+            AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
+                                     (ULONGLONG)PsGetCurrentThreadId(),
+                                     &stAuthGroup);
+
+            ntStatus = AFSVerifyEntry( &stAuthGroup,
+                                      pCcb->DirectoryCB,
+                                      FALSE);
+
+            if ( NT_SUCCESS( ntStatus))
+            {
 
-        AFSVerifyEntry( &stAuthGroup,
-                        pCcb->DirectoryCB);
+               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
+            {
+
+                ntStatus = STATUS_SUCCESS;
+            }
+        }
 
         //
         // Grab the main shared right off the bat
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
+                      "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
                       &pFcb->NPFcb->Resource,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireShared( &pFcb->NPFcb->Resource,
                           TRUE);
@@ -126,9 +148,9 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
+                          "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
 
             ntStatus = AFSProcessShareQueryInfo( Irp,
                                                  pFcb,
@@ -138,9 +160,9 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         }
         else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
         {
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryFileInfo request against PIOCtl Fcb\n");
+                          "AFSQueryFileInfo request against PIOCtl Fcb\n"));
 
             ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
                                                   pFcb,
@@ -152,9 +174,9 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
 
         else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
         {
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryFileInfo request against Invalid Fcb\n");
+                          "AFSQueryFileInfo request against Invalid Fcb\n"));
 
             try_return( ntStatus = STATUS_ACCESS_DENIED);
         }
@@ -223,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,
@@ -245,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,
@@ -441,24 +465,24 @@ try_exit:
                 pCcb->DirectoryCB != NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               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,
-                              ntStatus);
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
+                              ntStatus));
             }
         }
     }
     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSQueryFileInfo\n");
+                      "EXCEPTION - AFSQueryFileInfo\n"));
 
         AFSDumpTraceFilesFnc();
 
@@ -494,12 +518,11 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                 IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(LibDeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
-    BOOLEAN bCompleteRequest = TRUE;
     FILE_INFORMATION_CLASS FileInformationClass;
     BOOLEAN bCanQueueRequest = FALSE;
     PFILE_OBJECT pFileObject = NULL;
@@ -518,10 +541,10 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
-                          Irp);
+                          "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
+                          Irp));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
@@ -533,11 +556,11 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         // Grab the Fcb EXCL
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
+                      "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->Resource,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireExcl( &pFcb->NPFcb->Resource,
                         TRUE);
@@ -551,18 +574,18 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
+                          "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
+                          "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
 
             ntStatus = AFSProcessShareSetInfo( Irp,
                                                pFcb,
@@ -571,13 +594,14 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             try_return( ntStatus);
         }
 
-        if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
+       if( FileInformationClass != FilePositionInformation &&
+           BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetFileInfo Request failed due to read only volume\n",
-                          Irp);
+                          Irp));
 
             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
         }
@@ -585,9 +609,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
             FileInformationClass != FileDispositionInformation)
         {
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetFileInfo request against Invalid Fcb\n");
+                          "AFSSetFileInfo request against Invalid Fcb\n"));
 
             try_return( ntStatus = STATUS_ACCESS_DENIED);
         }
@@ -609,9 +633,10 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         RtlZeroMemory( &stParentFileId,
                        sizeof( AFSFileID));
 
-        if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
+        if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
         {
-            stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
+
+            stParentFileId = pFcb->ObjectInformation->ParentFileId;
         }
 
         //
@@ -624,10 +649,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             case FileBasicInformation:
             {
 
-                bUpdateFileInfo = TRUE;
-
                 ntStatus = AFSSetBasicInfo( Irp,
-                                            pCcb->DirectoryCB);
+                                           pCcb->DirectoryCB,
+                                           &bUpdateFileInfo);
 
                 break;
             }
@@ -720,15 +744,15 @@ try_exit:
                 AFSUnwindFileInfo( pFcb,
                                    pCcb);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               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,
-                              ntStatus);
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
+                              ntStatus));
 
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
             }
@@ -741,24 +765,24 @@ try_exit:
                 pCcb->DirectoryCB != NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               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,
-                              ntStatus);
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
+                              ntStatus));
             }
         }
     }
     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSSetFileInfo\n");
+                      "EXCEPTION - AFSSetFileInfo\n"));
 
         AFSDumpTraceFilesFnc();
 
@@ -795,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;
@@ -833,6 +857,22 @@ AFSQueryBasicInfo( IN PIRP Irp,
 
             AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+            //
+            // Its a reparse point regardless of whether the file attributes
+            // can be retrieved for the target.
+            //
+
+            if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+
             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
                                                        DirectoryCB,
                                                        &uniParentPath,
@@ -841,17 +881,6 @@ AFSQueryBasicInfo( IN PIRP Irp,
                                                        &stFileInfo)))
             {
 
-                if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
-                {
-
-                    ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-                else
-                {
-
-                    ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-
                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                 {
 
@@ -864,13 +893,13 @@ AFSQueryBasicInfo( IN PIRP Irp,
         }
 
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       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,
-                      ulFileAttribs);
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
 
         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
@@ -893,11 +922,8 @@ AFSQueryBasicInfo( IN PIRP Irp,
         }
 
         *Length -= sizeof( FILE_BASIC_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -910,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);
@@ -928,10 +954,10 @@ AFSQueryStandardInfo( IN PIRP Irp,
         RtlZeroMemory( Buffer,
                        *Length);
 
-        Buffer->NumberOfLinks = 1;
+       Buffer->NumberOfLinks = DirectoryCB->ObjectInformation->Links;
         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
 
-        Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
+       Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
 
         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
 
@@ -954,6 +980,22 @@ AFSQueryStandardInfo( IN PIRP Irp,
 
             AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+            //
+            // Its a reparse point regardless of whether or not the
+            // file attributes can be retrieved.
+            //
+
+            if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+
             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
                                                        DirectoryCB,
                                                        &uniParentPath,
@@ -962,17 +1004,6 @@ AFSQueryStandardInfo( IN PIRP Irp,
                                                        &stFileInfo)))
             {
 
-                if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
-                {
-
-                    ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-                else
-                {
-
-                    ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-
                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                 {
 
@@ -984,22 +1015,19 @@ AFSQueryStandardInfo( IN PIRP Irp,
                               TRUE);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       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,
-                      ulFileAttribs);
+                      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;
@@ -1012,21 +1040,19 @@ AFSQueryInternalInfo( IN PIRP Irp,
                       IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    UNREFERENCED_PARAMETER(Irp);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
     {
 
-        Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
+        Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
 
-        Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
+        Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
 
         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1039,7 +1065,9 @@ AFSQueryEaInfo( IN PIRP Irp,
                 IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(DirectoryCB);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -1050,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;
@@ -1067,7 +1092,8 @@ AFSQueryPositionInfo( IN PIRP Irp,
                       IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    UNREFERENCED_PARAMETER(Fcb);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
 
     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
@@ -1079,95 +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)
-{
-
-    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)
-{
-
-    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)
-{
-
-    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;
@@ -1180,15 +1119,11 @@ AFSQueryNameInfo( IN PIRP Irp,
                   IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    ULONG ulCopyLength = 0;
-    ULONG cchCopied = 0;
+    UNREFERENCED_PARAMETER(DirectoryCB);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    BOOLEAN bAddLeadingSlash = FALSE;
-    BOOLEAN bAddTrailingSlash = FALSE;
-    USHORT usFullNameLength = 0;
 
     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
 
@@ -1197,119 +1132,16 @@ AFSQueryNameInfo( IN PIRP Irp,
     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
     {
 
-        RtlZeroMemory( Buffer,
-                       *Length);
-
-        if( pCcb->FullFileName.Length == 0 ||
-            pCcb->FullFileName.Buffer[ 0] != L'\\')
-        {
-            bAddLeadingSlash = TRUE;
-        }
-
-        if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
-            pCcb->FullFileName.Length > 0 &&
-            pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
-        {
-            bAddTrailingSlash = TRUE;
-        }
-
-        usFullNameLength = sizeof( WCHAR) +
-                                    AFSServerName.Length +
-                                    pCcb->FullFileName.Length;
-
-        if( bAddLeadingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( bAddTrailingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
-        {
-
-            ulCopyLength = (LONG)usFullNameLength;
-        }
-        else
-        {
-
-            ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
-
-            ntStatus = STATUS_BUFFER_OVERFLOW;
-        }
-
-        Buffer->FileNameLength = (ULONG)usFullNameLength;
-
-        *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
-
-        if( ulCopyLength > 0)
-        {
-
-            Buffer->FileName[ 0] = L'\\';
-            ulCopyLength -= sizeof( WCHAR);
-
-            *Length -= sizeof( WCHAR);
-            cchCopied += 1;
-
-            if( ulCopyLength >= AFSServerName.Length)
-            {
-
-                RtlCopyMemory( &Buffer->FileName[ 1],
-                               AFSServerName.Buffer,
-                               AFSServerName.Length);
+       RtlZeroMemory( Buffer,
+                      *Length);
 
-                ulCopyLength -= AFSServerName.Length;
-                *Length -= AFSServerName.Length;
-                cchCopied += AFSServerName.Length/sizeof( WCHAR);
+       *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
 
-                if ( ulCopyLength > 0 &&
-                     bAddLeadingSlash)
-                {
-
-                    Buffer->FileName[ cchCopied] = L'\\';
-
-                    ulCopyLength -= sizeof( WCHAR);
-                    *Length -= sizeof( WCHAR);
-                    cchCopied++;
-                }
-
-                if( ulCopyLength >= pCcb->FullFileName.Length)
-                {
-
-                    RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                                   pCcb->FullFileName.Buffer,
-                                   pCcb->FullFileName.Length);
-
-                    ulCopyLength -= pCcb->FullFileName.Length;
-                    *Length -= pCcb->FullFileName.Length;
-                    cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
-
-                    if( ulCopyLength > 0 &&
-                        bAddTrailingSlash)
-                    {
-                        Buffer->FileName[ cchCopied] = L'\\';
-
-                        *Length -= sizeof( WCHAR);
-                    }
-                }
-                else
-                {
-
-                    RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                                   pCcb->FullFileName.Buffer,
-                                   ulCopyLength);
-
-                    *Length -= ulCopyLength;
-                }
-            }
-        }
-    }
-    else
-    {
-
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = AFSGetFullFileName( pFcb,
+                                      pCcb,
+                                      &Buffer->FileNameLength,
+                                      Buffer->FileName,
+                                      Length);
     }
 
     return ntStatus;
@@ -1322,7 +1154,8 @@ AFSQueryShortNameInfo( IN PIRP Irp,
                        IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    UNREFERENCED_PARAMETER(Irp);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
 
     RtlZeroMemory( Buffer,
@@ -1415,7 +1248,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;
@@ -1453,6 +1286,22 @@ AFSQueryNetworkInfo( IN PIRP Irp,
 
             AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+            //
+            // Its a reparse point regardless of whether the file attributes
+            // can be retrieved for the target.
+            //
+
+            if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+
             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
                                                        DirectoryCB,
                                                        &uniParentPath,
@@ -1461,17 +1310,6 @@ AFSQueryNetworkInfo( IN PIRP Irp,
                                                        &stFileInfo)))
             {
 
-                if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
-                {
-
-                    ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-                else
-                {
-
-                    ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-
                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                 {
 
@@ -1483,13 +1321,13 @@ AFSQueryNetworkInfo( IN PIRP Irp,
                               TRUE);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       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,
-                      ulFileAttribs);
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
 
         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
@@ -1518,11 +1356,8 @@ AFSQueryNetworkInfo( IN PIRP Irp,
         }
 
         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
-    }
-    else
-    {
 
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = STATUS_SUCCESS;
     }
 
     return ntStatus;
@@ -1535,9 +1370,9 @@ AFSQueryStreamInfo( IN PIRP Irp,
                     IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
+    UNREFERENCED_PARAMETER(Irp);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     ULONG ulCopyLength = 0;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
     {
@@ -1605,8 +1440,7 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
                        IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
-    ULONG ulCopyLength = 0;
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
@@ -1644,6 +1478,22 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
 
             AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+            //
+            // Its a reparse point regardless of whether the file attributes
+            // can be retrieved for the target.
+            //
+
+            if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+
             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
                                                        DirectoryCB,
                                                        &uniParentPath,
@@ -1652,17 +1502,6 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
                                                        &stFileInfo)))
             {
 
-                if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
-                {
-
-                    ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-                else
-                {
-
-                    ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
-                }
-
                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                 {
 
@@ -1674,13 +1513,13 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
                               TRUE);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       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,
-                      ulFileAttribs);
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
 
         Buffer->FileAttributes = ulFileAttribs;
 
@@ -1700,10 +1539,16 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
             }
         }
 
-        if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
+        if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
         {
+
             Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
         }
+        else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
+        {
+
+            Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
+        }
 
         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
 
@@ -1720,9 +1565,9 @@ AFSQueryRemoteProtocolInfo( IN PIRP Irp,
                             IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
-    ULONG ulCopyLength = 0;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(DirectoryCB);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
 
     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
     {
@@ -1757,14 +1602,11 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
                           IN OUT PLONG Length)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    ULONG ulCopyLength = 0;
-    ULONG cchCopied = 0;
+    UNREFERENCED_PARAMETER(DirectoryCB);
+    NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    BOOLEAN bAddLeadingSlash = FALSE;
-    USHORT usFullNameLength = 0;
 
     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
 
@@ -1773,77 +1615,16 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
     {
 
-        RtlZeroMemory( Buffer,
-                       *Length);
-
-        if( pCcb->FullFileName.Length == 0 ||
-            pCcb->FullFileName.Buffer[ 0] != L'\\')
-        {
-            bAddLeadingSlash = TRUE;
-        }
-
-        usFullNameLength = pCcb->FullFileName.Length;
-
-        if( bAddLeadingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
-        {
-            ulCopyLength = (LONG)usFullNameLength;
-        }
-        else
-        {
-
-            ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
-
-            ntStatus = STATUS_BUFFER_OVERFLOW;
-        }
-
-        Buffer->FileNameLength = (ULONG)usFullNameLength;
-
-        *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
-
-        if( ulCopyLength > 0)
-        {
-
-            if( bAddLeadingSlash)
-            {
-
-                Buffer->FileName[ cchCopied] = L'\\';
-
-                ulCopyLength -= sizeof( WCHAR);
-                *Length -= sizeof( WCHAR);
-                cchCopied++;
-            }
-
-            if( ulCopyLength >= pCcb->FullFileName.Length)
-            {
+       RtlZeroMemory( Buffer,
+                      *Length);
 
-                RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                               pCcb->FullFileName.Buffer,
-                               pCcb->FullFileName.Length);
+       *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
 
-                ulCopyLength -= pCcb->FullFileName.Length;
-                *Length -= pCcb->FullFileName.Length;
-                cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
-            }
-            else
-            {
-
-                RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                               pCcb->FullFileName.Buffer,
-                               ulCopyLength);
-
-                *Length -= ulCopyLength;
-            }
-        }
-    }
-    else
-    {
-
-        ntStatus = STATUS_BUFFER_TOO_SMALL;
+       ntStatus = AFSGetFullFileName( pFcb,
+                                      pCcb,
+                                      &Buffer->FileNameLength,
+                                      Buffer->FileName,
+                                      Length);
     }
 
     return ntStatus;
@@ -1851,7 +1632,8 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
 
 NTSTATUS
 AFSSetBasicInfo( IN PIRP Irp,
-                 IN AFSDirectoryCB *DirectoryCB)
+                IN AFSDirectoryCB *DirectoryCB,
+                OUT BOOLEAN *bUpdateFileInfo)
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_BASIC_INFORMATION pBuffer;
@@ -1871,26 +1653,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.
+           //
 
-            pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+           if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                FILE_ATTRIBUTE_DIRECTORY) &&
+                BooleanFlagOn( pBuffer->FileAttributes,
+                               FILE_ATTRIBUTE_DIRECTORY))
+           {
 
-            DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+               try_return( ntStatus = STATUS_INVALID_PARAMETER);
+           }
 
-            ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+           //
+           // Save the original value
+           //
 
-            SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+           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;
+
+                   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;
@@ -1936,6 +1784,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;
@@ -1956,13 +1810,24 @@ AFSSetBasicInfo( IN PIRP Irp,
         if( ulNotifyFilter > 0)
         {
 
-            if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
+           *bUpdateFileInfo = TRUE;
+
+            if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
             {
 
-                AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
-                                                pCcb,
-                                                (ULONG)ulNotifyFilter,
-                                                (ULONG)FILE_ACTION_MODIFIED);
+                AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
+                                                                         &DirectoryCB->ObjectInformation->ParentFileId,
+                                                                         TRUE);
+
+                if ( pParentObjectInfo != NULL)
+                {
+                    AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+                                                    pCcb,
+                                                    (ULONG)ulNotifyFilter,
+                                                    (ULONG)FILE_ACTION_MODIFIED);
+
+                    AFSReleaseObjectInfo( &pParentObjectInfo);
+                }
             }
         }
 
@@ -2000,9 +1865,9 @@ AFSSetDispositionInfo( IN PIRP Irp,
         if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetDispositionInfo Attempt to delete root entry\n");
+                          "AFSSetDispositionInfo Attempt to delete root entry\n"));
 
             try_return( ntStatus = STATUS_CANNOT_DELETE);
         }
@@ -2014,10 +1879,10 @@ AFSSetDispositionInfo( IN PIRP Irp,
         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
-                          &DirectoryCB->NameInformation.FileName);
+                          &DirectoryCB->NameInformation.FileName));
 
             try_return( ntStatus = STATUS_CANNOT_DELETE);
         }
@@ -2036,11 +1901,11 @@ AFSSetDispositionInfo( IN PIRP Irp,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
                               &DirectoryCB->NameInformation.FileName,
-                              ntStatus);
+                              ntStatus));
 
                 try_return( ntStatus);
             }
@@ -2049,97 +1914,211 @@ AFSSetDispositionInfo( IN PIRP Irp,
             {
 
                 //
-                // Reduce the Link count in the object information block
-                // to correspond with the deletion of the directory entry.
-                //
-
-                pFcb->ObjectInformation->Links--;
-
-                //
                 // Check if this is a directory that there are not currently other opens
                 //
 
                 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
                                   &DirectoryCB->NameInformation.FileName,
-                                  pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
+                                  pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
 
                     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))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
-                                  &DirectoryCB->NameInformation.FileName);
+                                  &DirectoryCB->NameInformation.FileName));
 
                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
                 }
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
                               DirectoryCB,
-                              &DirectoryCB->NameInformation.FileName);
+                              &DirectoryCB->NameInformation.FileName));
 
                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
             }
             else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
             {
+                BOOLEAN bMmFlushed;
 
-                //
-                // Attempt to flush any outstanding data
-                //
+               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,
+                              PsGetCurrentThread()));
+
+                AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
+                                TRUE);
 
-                if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
-                                          MmFlushForDelete))
+               __try
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
-                                  &DirectoryCB->NameInformation.FileName);
+                    //
+                   // Attempt to flush any outstanding data
+                    //
 
-                    try_return( ntStatus = STATUS_CANNOT_DELETE);
+                   bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
+                                                     MmFlushForDelete);
+
+                   if ( bMmFlushed)
+                   {
+
+                       //
+                       // 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.
+                       //
+
+                       AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                     AFS_TRACE_LEVEL_VERBOSE,
+                                     "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
+                                     DirectoryCB,
+                                     &DirectoryCB->NameInformation.FileName));
+
+                       SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+
+                       //
+                       // Purge the cache as well
+                       //
+
+                       if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                        {
+
+                           if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
+                                                      NULL,
+                                                      0,
+                                                      TRUE))
+                           {
+
+                               SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                           }
+                        }
+                    }
                 }
+               __except( EXCEPTION_EXECUTE_HANDLER)
+               {
 
-                //
-                // 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.
-                //
+                   bMmFlushed = FALSE;
+
+                   ntStatus = GetExceptionCode();
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                   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 Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
-                              DirectoryCB,
-                              &DirectoryCB->NameInformation.FileName);
+                              "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                              &pFcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread()));
 
-                SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+                AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
 
-                //
-                // Purge the cache as well
-                //
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
+                             &pFcb->NPFcb->Resource,
+                             PsGetCurrentThread()));
 
-                if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+               AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+                if ( !bMmFlushed)
                 {
 
-                    if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
-                                               NULL,
-                                               0,
-                                               TRUE))
-                    {
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_ERROR,
+                                  "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
+                                  &DirectoryCB->NameInformation.FileName));
 
-                        SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
-                    }
+                    try_return( ntStatus = STATUS_CANNOT_DELETE);
                 }
             }
+            else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
+                     pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
+                     pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
+                     pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
+            {
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
+                              DirectoryCB,
+                              &DirectoryCB->NameInformation.FileName));
+
+                SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+            }
         }
         else
         {
@@ -2168,17 +2147,15 @@ AFSSetFileLinkInfo( IN PIRP Irp)
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    IO_STATUS_BLOCK stIoSb = {0,0};
     PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
     PFILE_OBJECT pSrcFileObj = NULL;
     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
-    AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
+    AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
-    AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
+    AFSObjectInfoCB *pSrcObject = NULL;
     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
     UNICODE_STRING uniSourceName, uniTargetName;
     UNICODE_STRING uniFullTargetName, uniTargetParentName;
-    UNICODE_STRING uniShortName;
     BOOLEAN bCommonParent = FALSE;
     AFSDirectoryCB *pTargetDirEntry = NULL;
     AFSDirectoryCB *pNewTargetDirEntry = NULL;
@@ -2186,7 +2163,6 @@ AFSSetFileLinkInfo( IN PIRP Irp)
     BOOLEAN bTargetEntryExists = FALSE;
     LONG lCount;
     BOOLEAN bReleaseTargetDirLock = FALSE;
-    AFSFileID stNewFid;
     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
 
     __Enter
@@ -2198,7 +2174,26 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
 
         pSrcObject = pSrcFcb->ObjectInformation;
-        pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
+
+        if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        {
+
+            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;
 
@@ -2209,9 +2204,9 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n");
+                          "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
 
             try_return( ntStatus = STATUS_INVALID_PARAMETER);
         }
@@ -2234,10 +2229,10 @@ AFSSetFileLinkInfo( IN PIRP Irp)
                 // error.
                 //
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
             }
@@ -2271,11 +2266,11 @@ AFSSetFileLinkInfo( IN PIRP Irp)
                     // will be moved to.  Must obtain the TargetParentObject.
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSSetFileLinkInfo Attempt to link  %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
-                                  &uniFullTargetName);
+                                  &uniFullTargetName));
 
                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
                 }
@@ -2333,10 +2328,10 @@ AFSSetFileLinkInfo( IN PIRP Irp)
             if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
                 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
             }
@@ -2389,38 +2384,39 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         if( pTargetDirEntry != NULL)
         {
 
-            ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
+            ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
+                    AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
 
             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
                           pSrcCcb,
-                          lCount);
+                          lCount));
 
             ASSERT( lCount >= 0);
 
             if( !pFileLinkInfo->ReplaceIfExists)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
-                              &pTargetDirEntry->NameInformation.FileName);
+                              &pTargetDirEntry->NameInformation.FileName));
 
                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
             }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetFileLinkInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
+                          "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
-                          pTargetDirEntry->DirOpenReferenceCount);
+                          lCount));
 
             //
             // Pull the directory entry from the parent
@@ -2434,9 +2430,9 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         }
         else
         {
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetFileLinkInfo Target does NOT exist, normal linking\n");
+                          "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
         }
 
         //
@@ -2444,31 +2440,36 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         // request to the service.
         //
 
-        ntStatus = AFSNotifyHardLink( pSrcFcb->ObjectInformation,
+        ntStatus = AFSNotifyHardLink( pSrcObject,
                                       &pSrcCcb->AuthGroup,
-                                      pSrcFcb->ObjectInformation->ParentObjectInformation,
+                                      pSrcParentObject,
                                       pTargetDcb->ObjectInformation,
                                       pSrcCcb->DirectoryCB,
                                       &uniTargetName,
                                       pFileLinkInfo->ReplaceIfExists,
                                       &pNewTargetDirEntry);
 
-        if( !NT_SUCCESS( ntStatus))
+        if( ntStatus != STATUS_REPARSE &&
+            !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
                           &uniTargetName,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
 
-        AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
-                                pNewTargetDirEntry,
-                                TRUE);
+        if ( ntStatus != STATUS_REPARSE)
+        {
+
+            AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
+                                    pNewTargetDirEntry,
+                                    TRUE);
+        }
 
         //
         // Send notification for the target link file
@@ -2485,7 +2486,7 @@ AFSSetFileLinkInfo( IN PIRP Irp)
             ulNotificationAction = FILE_ACTION_ADDED;
         }
 
-        AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
+        AFSFsRtlNotifyFullReportChange( pTargetParentObject,
                                         pSrcCcb,
                                         (ULONG)ulNotifyFilter,
                                         (ULONG)ulNotificationAction);
@@ -2498,7 +2499,7 @@ AFSSetFileLinkInfo( IN PIRP Irp)
             if( bTargetEntryExists)
             {
 
-                AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
+                AFSInsertDirectoryNode( pTargetParentObject,
                                         pTargetDirEntry,
                                         FALSE);
             }
@@ -2507,15 +2508,39 @@ AFSSetFileLinkInfo( IN PIRP Irp)
         if( pTargetDirEntry != NULL)
         {
 
+            //
+            // Release DirOpenReferenceCount obtained above
+            //
+
             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
                           pSrcCcb,
-                          lCount);
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        if( pNewTargetDirEntry != NULL)
+        {
+
+            //
+            // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
+            //
+
+            lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pNewTargetDirEntry->NameInformation.FileName,
+                          pNewTargetDirEntry,
+                          pSrcCcb,
+                          lCount));
 
             ASSERT( lCount >= 0);
         }
@@ -2525,6 +2550,19 @@ AFSSetFileLinkInfo( IN PIRP Irp)
 
             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
+
+        if ( pSrcParentObject != NULL)
+        {
+
+            AFSReleaseObjectInfo( &pSrcParentObject);
+        }
+
+        //
+        // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
+        // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
+        //
+
+        pTargetParentObject = NULL;
     }
 
     return ntStatus;
@@ -2537,7 +2575,6 @@ AFSSetRenameInfo( IN PIRP Irp)
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    IO_STATUS_BLOCK stIoSb = {0,0};
     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
@@ -2550,9 +2587,9 @@ AFSSetRenameInfo( IN PIRP Irp)
     AFSDirectoryCB *pTargetDirEntry = NULL;
     ULONG ulTargetCRC = 0;
     BOOLEAN bTargetEntryExists = FALSE;
-    AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
+    AFSObjectInfoCB *pSrcObject = NULL;
     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
-    AFSFileID stNewFid, stTmpTargetFid;
+    AFSFileID stNewFid;
     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
     UNICODE_STRING uniFullTargetName;
     BOOLEAN bCommonParent = FALSE;
@@ -2573,7 +2610,26 @@ AFSSetRenameInfo( IN PIRP Irp)
         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
 
         pSrcObject = pSrcFcb->ObjectInformation;
-        pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
+
+        if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        {
+
+            pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
+                                                  &pSrcObject->ParentFileId,
+                                                  TRUE);
+        }
+
+        if( pSrcParentObject == NULL)
+        {
+
+            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);
+        }
 
         //
         // Perform some basic checks to ensure FS integrity
@@ -2586,9 +2642,9 @@ AFSSetRenameInfo( IN PIRP Irp)
             // Can't rename the root directory
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetRenameInfo Attempt to rename root entry\n");
+                          "AFSSetRenameInfo Attempt to rename root entry\n"));
 
             try_return( ntStatus = STATUS_INVALID_PARAMETER);
         }
@@ -2600,13 +2656,13 @@ 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)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
                 try_return( ntStatus = STATUS_ACCESS_DENIED);
             }
@@ -2632,9 +2688,9 @@ AFSSetRenameInfo( IN PIRP Irp)
             if ( pRenameInfo->RootDirectory)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n");
+                              "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
 
                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
             }
@@ -2668,11 +2724,11 @@ AFSSetRenameInfo( IN PIRP Irp)
                     // will be moved to.  Must obtain the TargetParentObject.
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
-                                  &uniFullTargetName);
+                                  &uniFullTargetName));
 
                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
                 }
@@ -2733,10 +2789,10 @@ AFSSetRenameInfo( IN PIRP Irp)
         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
-                          &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                          &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
         }
@@ -2798,39 +2854,83 @@ AFSSetRenameInfo( IN PIRP Irp)
         if( pTargetDirEntry != NULL)
         {
 
-            ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
+            ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
+                    AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
 
             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
                           pSrcCcb,
-                          lCount);
+                          lCount));
 
             ASSERT( lCount >= 0);
 
+           //
+           // Need to acquire the ObjectInfoLock while checking for the Fcb OpenRefCount so we don't race with
+           // a tear down worker thread on the Fcb
+           //
+
+           AFSAcquireShared( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                             TRUE);
+
+           //
+           // Check there are no current opens on the target
+           //
+
+           if( BooleanFlagOn( pTargetDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY) ||
+               ( pTargetDirEntry->ObjectInformation->Fcb != NULL &&
+                 pTargetDirEntry->ObjectInformation->Fcb->OpenReferenceCount != 0))
+           {
+
+               //
+               // Return the correct error code
+               //
+
+               if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
+               {
+                   ntStatus = STATUS_DELETE_PENDING;
+               }
+               else
+               {
+                   ntStatus = STATUS_ACCESS_DENIED;
+               }
+
+               AFSReleaseResource( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSSetRenameInfo Attempt to rename %s Target %wZ Status %08lX\n",
+                             BooleanFlagOn( pTargetDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY)?"ReadOnly":"Open",
+                             &pTargetDirEntry->NameInformation.FileName,
+                             ntStatus));
+
+               try_return( ntStatus);
+           }
+
+           AFSReleaseResource( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
             if( !bReplaceIfExists)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
-                              &pTargetDirEntry->NameInformation.FileName);
+                              &pTargetDirEntry->NameInformation.FileName));
 
                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
             }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
+                          "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
-                          pTargetDirEntry->DirOpenReferenceCount);
+                          lCount));
 
             //
             // Pull the directory entry from the parent
@@ -2844,9 +2944,9 @@ AFSSetRenameInfo( IN PIRP Irp)
         }
         else
         {
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetRenameInfo Target does NOT exist, normal rename\n");
+                          "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
         }
 
         //
@@ -2855,7 +2955,7 @@ AFSSetRenameInfo( IN PIRP Irp)
         // same parent we do not pull the node from the enumeration list
         //
 
-        AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
+        AFSRemoveDirNodeFromParent( pSrcParentObject,
                                     pSrcCcb->DirectoryCB,
                                     !bCommonParent);
 
@@ -2864,9 +2964,9 @@ AFSSetRenameInfo( IN PIRP Irp)
         // request to the service.
         //
 
-        ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
+        ntStatus = AFSNotifyRename( pSrcObject,
                                     &pSrcCcb->AuthGroup,
-                                    pSrcFcb->ObjectInformation->ParentObjectInformation,
+                                    pSrcParentObject,
                                     pTargetDcb->ObjectInformation,
                                     pSrcCcb->DirectoryCB,
                                     &uniTargetName,
@@ -2879,16 +2979,16 @@ AFSSetRenameInfo( IN PIRP Irp)
             // Attempt to re-insert the directory entry
             //
 
-            AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
+            AFSInsertDirectoryNode( pSrcParentObject,
                                     pSrcCcb->DirectoryCB,
                                     !bCommonParent);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
                           &uniTargetName,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -2897,7 +2997,7 @@ AFSSetRenameInfo( IN PIRP Irp)
         // Set the notification up for the source file
         //
 
-        if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
+        if( pSrcParentObject == pTargetParentObject &&
             !bTargetEntryExists)
         {
 
@@ -2909,7 +3009,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;
@@ -2920,7 +3020,7 @@ AFSSetRenameInfo( IN PIRP Irp)
             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
         }
 
-        AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
+        AFSFsRtlNotifyFullReportChange( pSrcParentObject,
                                         pSrcCcb,
                                         (ULONG)ulNotifyFilter,
                                         (ULONG)ulNotificationAction);
@@ -2939,16 +3039,16 @@ AFSSetRenameInfo( IN PIRP Irp)
             // Attempt to re-insert the directory entry
             //
 
-            AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
+            AFSInsertDirectoryNode( pSrcParentObject,
                                     pSrcCcb->DirectoryCB,
                                     !bCommonParent);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
                           &uniTargetName,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -3029,11 +3129,11 @@ AFSSetRenameInfo( IN PIRP Irp)
             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
                                                                                            TRUE);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
                           &uniShortName,
-                          &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                          &pSrcCcb->DirectoryCB->NameInformation.FileName));
         }
         else
         {
@@ -3063,18 +3163,48 @@ AFSSetRenameInfo( IN PIRP Irp)
         // Update the parent pointer in the source object if they are different
         //
 
-        if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
+        if( pSrcParentObject != pTargetParentObject)
         {
 
-            lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+            lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
 
-            lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
+            lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
 
             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
 
             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
 
-            pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
+
+            //
+            // Guaranteed to be in the same volume
+            //
+
+            AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
+                            TRUE);
+
+            lCount = AFSObjectInfoIncrement( pTargetParentObject,
+                                             AFS_OBJECT_REFERENCE_CHILD);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
+                          pTargetParentObject,
+                          lCount));
+
+            lCount = AFSObjectInfoDecrement( pSrcParentObject,
+                                             AFS_OBJECT_REFERENCE_CHILD);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
+                          pSrcParentObject,
+                          lCount));
+
+            pSrcObject->ParentFileId = pTargetParentObject->FileId;
+
+            SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+
+            AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
 
             ulNotificationAction = FILE_ACTION_ADDED;
         }
@@ -3088,7 +3218,7 @@ AFSSetRenameInfo( IN PIRP Irp)
         // Now update the notification for the target file
         //
 
-        AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
+        AFSFsRtlNotifyFullReportChange( pTargetParentObject,
                                         pSrcCcb,
                                         (ULONG)ulNotifyFilter,
                                         (ULONG)ulNotificationAction);
@@ -3101,11 +3231,11 @@ AFSSetRenameInfo( IN PIRP Irp)
         if( bTargetEntryExists)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
                           pTargetDirEntry,
-                          &pTargetDirEntry->NameInformation.FileName);
+                          &pTargetDirEntry->NameInformation.FileName));
 
             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
@@ -3119,55 +3249,134 @@ AFSSetRenameInfo( IN PIRP Irp)
             {
 
                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
-
-                AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
-                                TRUE);
-
-                //
-                // Close the section in the event it was mapped
-                //
-
-                if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
-                                           TRUE))
-                {
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
-                                  &pTargetDirEntry->NameInformation.FileName);
-                }
-
-                AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
             }
 
             ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
 
             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
                           pSrcCcb,
-                          lCount);
+                          lCount));
 
             ASSERT( lCount >= 0);
 
-            if( lCount == 0)
+            if( lCount == 0 &&
+                pTargetDirEntry->NameArrayReferenceCount <= 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
                               pTargetDirEntry,
-                              &pTargetDirEntry->NameInformation.FileName);
+                              &pTargetDirEntry->NameInformation.FileName));
 
                 AFSDeleteDirEntry( pTargetParentObject,
-                                   pTargetDirEntry);
+                                   &pTargetDirEntry);
             }
 
             pTargetDirEntry = NULL;
+
+            if ( pTargetFcb != NULL)
+            {
+
+                //
+                // Do not hold TreeLocks across the MmForceSectionClosed() call as
+                // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
+                //
+
+                if( bReleaseTargetDirLock)
+                {
+                    AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                    bReleaseTargetDirLock = FALSE;
+                }
+
+                if( bReleaseSourceDirLock)
+                {
+
+                    AFSReleaseResource( pSourceDirLock);
+
+                    bReleaseSourceDirLock = FALSE;
+                }
+
+                //
+                // MmForceSectionClosed() can eventually call back into AFSCleanup
+                // which will need to acquire Fcb->Resource exclusively.  Failure
+                // to obtain it here before holding the SectionObjectResource will
+                // permit the locks to be obtained out of order risking a deadlock.
+                //
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
+                              &pTargetFcb->NPFcb->Resource,
+                              PsGetCurrentThread()));
+
+                AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
+                                TRUE);
+
+               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,
+                              PsGetCurrentThread()));
+
+                AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
+                                TRUE);
+
+               __try
+               {
+
+                   //
+                   // 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()))
+                {
+
+                   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|AFS_SUBSYSTEM_SECTION_OBJECT,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                              &pTargetFcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread()));
+
+                AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
+                              &pTargetFcb->NPFcb->Resource,
+                              PsGetCurrentThread()));
+
+                AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
+            }
         }
 
 try_exit:
@@ -3177,7 +3386,10 @@ try_exit:
 
             if( bTargetEntryExists)
             {
-                AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
+
+                ASSERT( pTargetParentObject != NULL);
+
+                AFSInsertDirectoryNode( pTargetParentObject,
                                         pTargetDirEntry,
                                         FALSE);
             }
@@ -3188,32 +3400,47 @@ try_exit:
 
             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pTargetDirEntry->NameInformation.FileName,
                           pTargetDirEntry,
                           pSrcCcb,
-                          lCount);
+                          lCount));
 
             ASSERT( lCount >= 0);
         }
 
         if( bReleaseTargetDirLock)
         {
+
             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
 
         if( bReleaseSourceDirLock)
         {
+
             AFSReleaseResource( pSourceDirLock);
         }
-    }
 
-    if ( bDereferenceTargetParentObject)
-    {
+        if ( bDereferenceTargetParentObject)
+        {
+
+            ObDereferenceObject( pTargetParentFileObj);
+        }
+
+        if ( pSrcParentObject != NULL)
+        {
+
+            AFSReleaseObjectInfo( &pSrcParentObject);
+        }
+
+        //
+        // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
+        // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
+        //
 
-        ObDereferenceObject( pTargetParentFileObj);
+        pTargetParentObject = NULL;
     }
 
     return ntStatus;
@@ -3223,6 +3450,7 @@ NTSTATUS
 AFSSetPositionInfo( IN PIRP Irp,
                     IN AFSDirectoryCB *DirectoryCB)
 {
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_POSITION_INFORMATION pBuffer;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
@@ -3238,11 +3466,13 @@ NTSTATUS
 AFSSetAllocationInfo( IN PIRP Irp,
                       IN AFSDirectoryCB *DirectoryCB)
 {
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_ALLOCATION_INFORMATION pBuffer;
     BOOLEAN bReleasePaging = FALSE;
     BOOLEAN bTellCc = FALSE;
     BOOLEAN bTellService = FALSE;
+    BOOLEAN bUserMapped = FALSE;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
     AFSFcb *pFcb = NULL;
@@ -3272,26 +3502,67 @@ AFSSetAllocationInfo( IN PIRP Irp,
 
     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
     {
+
+       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,
+                      PsGetCurrentThread()));
+
+        AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
+                        TRUE);
+
+       __try
+       {
+
+           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,
+                      PsGetCurrentThread()));
+
+        AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
+
         //
         // Truncating the file
         //
-        if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
-                                   &pBuffer->AllocationSize))
+        if ( bUserMapped)
         {
 
             ntStatus = STATUS_USER_MAPPED_FILE ;
         }
         else
         {
+
             //
             // If this is a truncation we need to grab the paging IO resource.
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
+                          "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->PagingResource,
-                          PsGetCurrentThread());
+                          PsGetCurrentThread()));
 
             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
                             TRUE);
@@ -3336,11 +3607,11 @@ AFSSetAllocationInfo( IN PIRP Irp,
         // Tell Cc if allocation is increased.
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
+                      "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->PagingResource,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
                         TRUE);
@@ -3367,7 +3638,10 @@ AFSSetAllocationInfo( IN PIRP Irp,
     //
     if (bTellService)
     {
-        ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
+
+        ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
+
+        ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
                                              pFcb->ObjectInformation,
                                              &pCcb->AuthGroup);
     }
@@ -3394,6 +3668,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
     {
@@ -3423,6 +3702,7 @@ NTSTATUS
 AFSSetEndOfFileInfo( IN PIRP Irp,
                      IN AFSDirectoryCB *DirectoryCB)
 {
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_END_OF_FILE_INFORMATION pBuffer;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
@@ -3433,6 +3713,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
     BOOLEAN bModified = FALSE;
     BOOLEAN bReleasePaging = FALSE;
     BOOLEAN bTruncated = FALSE;
+    BOOLEAN bUserMapped = FALSE;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
 
@@ -3453,9 +3734,48 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
         {
 
+           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,
+                          PsGetCurrentThread()));
+
+            AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
+                            TRUE);
+
+           __try
+           {
+
+               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,
+                          PsGetCurrentThread()));
+
+            AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
+
             // Truncating the file
-            if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
-                                       &pBuffer->EndOfFile))
+            if ( bUserMapped)
             {
 
                 ntStatus = STATUS_USER_MAPPED_FILE;
@@ -3467,11 +3787,11 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                 // If this is a truncation we need to grab the paging
                 // IO resource.
                 //
-                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
+                             "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                               &pFcb->NPFcb->PagingResource,
-                              PsGetCurrentThread());
+                              PsGetCurrentThread()));
 
                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
                                 TRUE);
@@ -3516,11 +3836,11 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
             // If this is a truncation we need to grab the paging
             // IO resource.
             //
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
+                         "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->PagingResource,
-                          PsGetCurrentThread());
+                          PsGetCurrentThread()));
 
             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
                             TRUE);
@@ -3564,7 +3884,9 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
         // Tell the server
         //
 
-        ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
+        ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
+
+        ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
                                              pFcb->ObjectInformation,
                                              &pCcb->AuthGroup);
 
@@ -3585,6 +3907,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
         {
@@ -3614,9 +3941,9 @@ AFSProcessShareSetInfo( IN IRP *Irp,
                         IN AFSCcb *Ccb)
 {
 
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    ULONG ulOutputBufferLen = 0, ulInputBufferLen;
     FILE_INFORMATION_CLASS ulFileInformationClass;
     void *pPipeInfo = NULL;
 
@@ -3624,11 +3951,11 @@ AFSProcessShareSetInfo( IN IRP *Irp,
     {
         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
                       &Ccb->DirectoryCB->NameInformation.FileName,
-                      ulFileInformationClass);
+                      ulFileInformationClass));
 
         pPipeInfo = AFSLockSystemBuffer( Irp,
                                          pIrpSp->Parameters.SetFile.Length);
@@ -3636,10 +3963,10 @@ AFSProcessShareSetInfo( IN IRP *Irp,
         if( pPipeInfo == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
-                          &Ccb->DirectoryCB->NameInformation.FileName);
+                          &Ccb->DirectoryCB->NameInformation.FileName));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -3656,20 +3983,20 @@ AFSProcessShareSetInfo( IN IRP *Irp,
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
                           &Ccb->DirectoryCB->NameInformation.FileName,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
                       &Ccb->DirectoryCB->NameInformation.FileName,
-                      ulFileInformationClass);
+                      ulFileInformationClass));
 
 try_exit:
 
@@ -3685,9 +4012,9 @@ AFSProcessShareQueryInfo( IN IRP *Irp,
                           IN AFSCcb *Ccb)
 {
 
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    ULONG ulOutputBufferLen = 0, ulInputBufferLen;
     FILE_INFORMATION_CLASS ulFileInformationClass;
     void *pPipeInfo = NULL;
 
@@ -3696,11 +4023,11 @@ AFSProcessShareQueryInfo( IN IRP *Irp,
 
         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
                       &Ccb->DirectoryCB->NameInformation.FileName,
-                      ulFileInformationClass);
+                      ulFileInformationClass));
 
         pPipeInfo = AFSLockSystemBuffer( Irp,
                                          pIrpSp->Parameters.QueryFile.Length);
@@ -3708,10 +4035,10 @@ AFSProcessShareQueryInfo( IN IRP *Irp,
         if( pPipeInfo == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
-                          &Ccb->DirectoryCB->NameInformation.FileName);
+                          &Ccb->DirectoryCB->NameInformation.FileName));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -3729,20 +4056,20 @@ AFSProcessShareQueryInfo( IN IRP *Irp,
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
                           &Ccb->DirectoryCB->NameInformation.FileName,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
                       &Ccb->DirectoryCB->NameInformation.FileName,
-                      ulFileInformationClass);
+                      ulFileInformationClass));
 
 try_exit:
 
@@ -3759,6 +4086,8 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                            IN OUT LONG *Length)
 {
 
+    UNREFERENCED_PARAMETER(Fcb);
+    UNREFERENCED_PARAMETER(Ccb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
     FILE_INFORMATION_CLASS ulFileInformationClass;
@@ -3774,9 +4103,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             case FileBasicInformation:
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
+                              "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
 
                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
                 {
@@ -3801,9 +4130,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             case FileStandardInformation:
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
+                              "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
 
                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
                 {
@@ -3836,9 +4165,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
                 UNICODE_STRING uniName;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
+                              "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
 
                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
@@ -3916,10 +4245,10 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                             uniName.Buffer = pNameInfo->FileName;
                         }
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
-                                      &uniName);
+                                      &uniName));
                     }
                 }
 
@@ -3931,9 +4260,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
 
                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n");
+                              "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
 
                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
                 {
@@ -3957,9 +4286,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
 
                 break;
             }
@@ -3968,9 +4297,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
 
                 break;
             }
@@ -3979,9 +4308,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
 
                 break;
             }
@@ -3990,9 +4319,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4001,9 +4330,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4012,9 +4341,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4023,9 +4352,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4034,9 +4363,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4045,9 +4374,9 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n");
+                              "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
 
                 break;
             }
@@ -4056,20 +4385,20 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             {
                 ntStatus = STATUS_INVALID_PARAMETER;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
-                              ulFileInformationClass);
+                              ulFileInformationClass));
 
                 break;
             }
         }
     }
 
-    AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+    AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
-                  ntStatus);
+                  ntStatus));
 
     return ntStatus;
 }