Windows: Fix AFSSetBasicInfo attribute processing
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
index fe93a6f..43e895b 100644 (file)
@@ -55,16 +55,15 @@ 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;
 
     __try
@@ -81,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);
         }
@@ -93,15 +92,49 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
         pBuffer = Irp->AssociatedIrp.SystemBuffer;
 
+        if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            RtlZeroMemory( &stAuthGroup,
+                           sizeof( GUID));
+
+            AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
+                                     (ULONGLONG)PsGetCurrentThreadId(),
+                                     &stAuthGroup);
+
+            ntStatus = AFSVerifyEntry( &stAuthGroup,
+                                      pCcb->DirectoryCB,
+                                      FALSE);
+
+            if ( NT_SUCCESS( ntStatus))
+            {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
+                             pFcb->ObjectInformation->FileId.Cell,
+                             pFcb->ObjectInformation->FileId.Volume,
+                             pFcb->ObjectInformation->FileId.Vnode,
+                             pFcb->ObjectInformation->FileId.Unique));
+
+                ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+            }
+            else
+            {
+
+                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);
@@ -115,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,
@@ -127,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,
@@ -139,6 +172,15 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             try_return( ntStatus);
         }
 
+        else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
+        {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSQueryFileInfo request against Invalid Fcb\n"));
+
+            try_return( ntStatus = STATUS_ACCESS_DENIED);
+        }
+
         //
         // Process the request
         //
@@ -316,6 +358,7 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                 break;
             }
 
+            case FileNormalizedNameInformation:
             case FileNameInformation:
             {
 
@@ -383,11 +426,22 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
                 break;
             }
 
-        default:
+            case FileNetworkPhysicalNameInformation:
+            {
+
+                ntStatus = AFSQueryPhysicalNameInfo( Irp,
+                                                     pCcb->DirectoryCB,
+                                                     (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
+                                                     &lLength);
 
-                ntStatus = STATUS_INVALID_PARAMETER;
+                break;
+            }
 
+            default:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
                 break;
+            }
         }
 
 try_exit:
@@ -409,24 +463,26 @@ 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( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSQueryFileInfo\n");
+                      "EXCEPTION - AFSQueryFileInfo\n"));
+
+        AFSDumpTraceFilesFnc();
 
         ntStatus = STATUS_UNSUCCESSFUL;
 
@@ -460,12 +516,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;
@@ -484,10 +539,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);
         }
@@ -499,11 +554,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);
@@ -517,18 +572,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,
@@ -537,13 +592,24 @@ 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);
+        }
+
+        if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
+            FileInformationClass != FileDispositionInformation)
+        {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetFileInfo request against Invalid Fcb\n"));
 
             try_return( ntStatus = STATUS_ACCESS_DENIED);
         }
@@ -565,9 +631,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;
         }
 
         //
@@ -580,10 +647,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             case FileBasicInformation:
             {
 
-                bUpdateFileInfo = TRUE;
-
                 ntStatus = AFSSetBasicInfo( Irp,
-                                            pCcb->DirectoryCB);
+                                           pCcb->DirectoryCB,
+                                           &bUpdateFileInfo);
 
                 break;
             }
@@ -617,7 +683,7 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             case FileLinkInformation:
             {
 
-                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+                ntStatus = AFSSetFileLinkInfo( Irp);
 
                 break;
             }
@@ -661,7 +727,7 @@ try_exit:
 
             ntStatus = AFSUpdateFileInformation( &stParentFileId,
                                                  pFcb->ObjectInformation,
-                                                 &pFcb->AuthGroup);
+                                                 &pCcb->AuthGroup);
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -676,15 +742,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);
             }
@@ -697,26 +763,34 @@ 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( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSSetFileInfo\n");
+                      "EXCEPTION - AFSSetFileInfo\n"));
+
+        AFSDumpTraceFilesFnc();
 
         ntStatus = STATUS_UNSUCCESSFUL;
+
+        if( bReleaseMain)
+        {
+
+            AFSReleaseResource( &pFcb->NPFcb->Resource);
+        }
     }
 
     AFSCompleteRequest( Irp,
@@ -745,6 +819,13 @@ AFSQueryBasicInfo( IN PIRP Irp,
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    ULONG ulFileAttribs = 0;
+    AFSFcb *pFcb = NULL;
+    AFSCcb *pCcb = NULL;
+    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSFileInfoCB stFileInfo;
+    AFSDirectoryCB *pParentDirectoryCB = NULL;
+    UNICODE_STRING uniParentPath;
 
     if( *Length >= sizeof( FILE_BASIC_INFORMATION))
     {
@@ -752,24 +833,88 @@ AFSQueryBasicInfo( IN PIRP Irp,
         RtlZeroMemory( Buffer,
                        *Length);
 
+        ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
+
+        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
+        if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
+        {
+
+            pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
+
+            AFSRetrieveParentPath( &pCcb->FullFileName,
+                                   &uniParentPath);
+
+            RtlZeroMemory( &stFileInfo,
+                           sizeof( AFSFileInfoCB));
+
+            //
+            // Can't hold the Fcb while evaluating the path, leads to lock inversion
+            //
+
+            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,
+                                                       pCcb->NameArray,
+                                                       &pCcb->AuthGroup,
+                                                       &stFileInfo)))
+            {
+
+                if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                {
+
+                    ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
+                }
+            }
+
+            AFSAcquireShared( &pFcb->NPFcb->Resource,
+                              TRUE);
+        }
+
+
+        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,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
+
         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
         Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
         Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
-        Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+        Buffer->FileAttributes = ulFileAttribs;
 
         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
-                 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
+            BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
         {
 
             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
             {
-
                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
             }
             else
             {
-
                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
             }
         }
@@ -793,13 +938,18 @@ AFSQueryStandardInfo( IN PIRP Irp,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSFileInfoCB stFileInformation;
+    AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSFileInfoCB stFileInfo;
+    AFSDirectoryCB *pParentDirectoryCB = NULL;
+    UNICODE_STRING uniParentPath;
+    ULONG ulFileAttribs = 0;
 
     if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
     {
 
+        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
 
         RtlZeroMemory( Buffer,
@@ -808,14 +958,73 @@ AFSQueryStandardInfo( IN PIRP Irp,
         Buffer->NumberOfLinks = 1;
         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
 
-        RtlZeroMemory( &stFileInformation,
-                       sizeof( AFSFileInfoCB));
-
         Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
 
         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
 
-        Buffer->Directory = BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
+        ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
+
+        if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
+        {
+
+            pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
+
+            AFSRetrieveParentPath( &pCcb->FullFileName,
+                                   &uniParentPath);
+
+            RtlZeroMemory( &stFileInfo,
+                           sizeof( AFSFileInfoCB));
+
+            //
+            // Can't hold the Fcb while evaluating the path, leads to lock inversion
+            //
+
+            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,
+                                                       pCcb->NameArray,
+                                                       &pCcb->AuthGroup,
+                                                       &stFileInfo)))
+            {
+
+                if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                {
+
+                    ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
+                }
+            }
+
+            AFSAcquireShared( &pFcb->NPFcb->Resource,
+                              TRUE);
+        }
+
+        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,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
+
+        Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
 
         *Length -= sizeof( FILE_STANDARD_INFORMATION);
     }
@@ -835,14 +1044,15 @@ AFSQueryInternalInfo( IN PIRP Irp,
                       IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     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);
     }
@@ -862,6 +1072,8 @@ AFSQueryEaInfo( IN PIRP Irp,
                 IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     RtlZeroMemory( Buffer,
@@ -890,6 +1102,7 @@ AFSQueryPositionInfo( IN PIRP Irp,
                       IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
 
@@ -919,6 +1132,8 @@ AFSQueryAccess( IN PIRP Irp,
                 IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
@@ -947,6 +1162,8 @@ AFSQueryMode( IN PIRP Irp,
               IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     if( *Length >= sizeof( FILE_MODE_INFORMATION))
@@ -975,6 +1192,8 @@ AFSQueryAlignment( IN PIRP Irp,
                    IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(Fcb);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
@@ -1003,6 +1222,7 @@ AFSQueryNameInfo( IN PIRP Irp,
                   IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     ULONG ulCopyLength = 0;
     ULONG cchCopied = 0;
@@ -1145,6 +1365,7 @@ AFSQueryShortNameInfo( IN PIRP Irp,
                        IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
     ULONG ulCopyLength = 0;
 
@@ -1240,6 +1461,13 @@ AFSQueryNetworkInfo( IN PIRP Irp,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    AFSFcb *pFcb = NULL;
+    AFSCcb *pCcb = NULL;
+    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSFileInfoCB stFileInfo;
+    AFSDirectoryCB *pParentDirectoryCB = NULL;
+    UNICODE_STRING uniParentPath;
+    ULONG ulFileAttribs = 0;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -1247,6 +1475,71 @@ AFSQueryNetworkInfo( IN PIRP Irp,
     if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
     {
 
+        ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
+
+        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
+        if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
+        {
+
+            pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
+
+            AFSRetrieveParentPath( &pCcb->FullFileName,
+                                   &uniParentPath);
+
+            RtlZeroMemory( &stFileInfo,
+                           sizeof( AFSFileInfoCB));
+
+            //
+            // Can't hold the Fcb while evaluating the path, leads to lock inversion
+            //
+
+            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,
+                                                       pCcb->NameArray,
+                                                       &pCcb->AuthGroup,
+                                                       &stFileInfo)))
+            {
+
+                if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                {
+
+                    ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
+                }
+            }
+
+            AFSAcquireShared( &pFcb->NPFcb->Resource,
+                              TRUE);
+        }
+
+        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,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
+
         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
         Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
@@ -1255,7 +1548,7 @@ AFSQueryNetworkInfo( IN PIRP Irp,
         Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
         Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
 
-        Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+        Buffer->FileAttributes = ulFileAttribs;
 
         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
@@ -1291,9 +1584,9 @@ AFSQueryStreamInfo( IN PIRP Irp,
                     IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
     ULONG ulCopyLength = 0;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
     {
@@ -1362,8 +1655,14 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
 {
 
     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
-    ULONG ulCopyLength = 0;
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    AFSFcb *pFcb = NULL;
+    AFSCcb *pCcb = NULL;
+    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSFileInfoCB stFileInfo;
+    AFSDirectoryCB *pParentDirectoryCB = NULL;
+    UNICODE_STRING uniParentPath;
+    ULONG ulFileAttribs = 0;
 
     if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
     {
@@ -1371,7 +1670,72 @@ AFSQueryAttribTagInfo( IN PIRP Irp,
         RtlZeroMemory( Buffer,
                        *Length);
 
-        Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+        ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
+
+        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
+        if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
+        {
+
+            pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
+
+            AFSRetrieveParentPath( &pCcb->FullFileName,
+                                   &uniParentPath);
+
+            RtlZeroMemory( &stFileInfo,
+                           sizeof( AFSFileInfoCB));
+
+            //
+            // Can't hold the Fcb while evaluating the path, leads to lock inversion
+            //
+
+            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,
+                                                       pCcb->NameArray,
+                                                       &pCcb->AuthGroup,
+                                                       &stFileInfo)))
+            {
+
+                if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                {
+
+                    ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
+                }
+            }
+
+            AFSAcquireShared( &pFcb->NPFcb->Resource,
+                              TRUE);
+        }
+
+        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,
+                      pFcb->ObjectInformation->FileType,
+                      pFcb->ObjectInformation->FileAttributes,
+                      ulFileAttribs));
+
+        Buffer->FileAttributes = ulFileAttribs;
 
         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
@@ -1389,9 +1753,15 @@ 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_OPENAFS_DFS;
+
+            Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
         }
 
         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
@@ -1409,9 +1779,9 @@ AFSQueryRemoteProtocolInfo( IN PIRP Irp,
                             IN OUT PLONG Length)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
-    ULONG ulCopyLength = 0;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
     {
@@ -1440,48 +1810,215 @@ AFSQueryRemoteProtocolInfo( IN PIRP Irp,
 }
 
 NTSTATUS
-AFSSetBasicInfo( IN PIRP Irp,
-                 IN AFSDirectoryCB *DirectoryCB)
+AFSQueryPhysicalNameInfo( IN PIRP Irp,
+                          IN AFSDirectoryCB *DirectoryCB,
+                          IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
+                          IN OUT PLONG Length)
 {
+
+    UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    PFILE_BASIC_INFORMATION pBuffer;
-    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    ULONG ulNotifyFilter = 0;
+    ULONG ulCopyLength = 0;
+    ULONG cchCopied = 0;
+    AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
+    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    BOOLEAN bAddLeadingSlash = FALSE;
+    USHORT usFullNameLength = 0;
 
-    __Enter
+    pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+
+    pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
+    if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
     {
 
-        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+        RtlZeroMemory( Buffer,
+                       *Length);
 
-        pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+        if( pCcb->FullFileName.Length == 0 ||
+            pCcb->FullFileName.Buffer[ 0] != L'\\')
+        {
+            bAddLeadingSlash = TRUE;
+        }
 
-        pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
+        usFullNameLength = pCcb->FullFileName.Length;
 
-        if( pBuffer->FileAttributes != (ULONGLONG)0)
+        if( bAddLeadingSlash)
         {
+            usFullNameLength += sizeof( WCHAR);
+        }
 
-            if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
-                BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
-            {
+        if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
+        {
+            ulCopyLength = (LONG)usFullNameLength;
+        }
+        else
+        {
 
-                try_return( ntStatus = STATUS_INVALID_PARAMETER);
-            }
+            ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
 
-            if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
-            {
+            ntStatus = STATUS_BUFFER_OVERFLOW;
+        }
 
-                pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
-            }
+        Buffer->FileNameLength = (ULONG)usFullNameLength;
 
-            pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+        *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
 
-            DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+        if( ulCopyLength > 0)
+        {
 
-            ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+            if( bAddLeadingSlash)
+            {
 
-            SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
-        }
+                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);
+            }
+            else
+            {
+
+                RtlCopyMemory( &Buffer->FileName[ cchCopied],
+                               pCcb->FullFileName.Buffer,
+                               ulCopyLength);
+
+                *Length -= ulCopyLength;
+            }
+        }
+    }
+    else
+    {
+
+        ntStatus = STATUS_BUFFER_TOO_SMALL;
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSSetBasicInfo( IN PIRP Irp,
+                IN AFSDirectoryCB *DirectoryCB,
+                OUT BOOLEAN *bUpdateFileInfo)
+{
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    PFILE_BASIC_INFORMATION pBuffer;
+    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    ULONG ulNotifyFilter = 0;
+    AFSCcb *pCcb = NULL;
+
+    __Enter
+    {
+
+        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
+        pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+        pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
+
+        if( pBuffer->FileAttributes != (ULONGLONG)0)
+        {
+
+           //
+           // 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.
+           //
+
+           if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                FILE_ATTRIBUTE_REPARSE_POINT) &&
+                BooleanFlagOn( pBuffer->FileAttributes,
+                               FILE_ATTRIBUTE_REPARSE_POINT))
+           {
+
+               try_return( ntStatus = STATUS_INVALID_PARAMETER);
+           }
+
+           //
+           // Make sure that the directory attribute is not modified.
+           // Fail if the D attribute is requested but it is not
+           // already a directory.  Otherwise, ignore it.
+           //
+
+           if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                FILE_ATTRIBUTE_DIRECTORY) &&
+                BooleanFlagOn( pBuffer->FileAttributes,
+                               FILE_ATTRIBUTE_DIRECTORY))
+           {
+
+               try_return( ntStatus = STATUS_INVALID_PARAMETER);
+           }
+
+           //
+           // Save the original value
+           //
+
+           pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+
+           if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
+           {
+
+               //
+               // Set the readonly flag.
+               //
+
+               if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                    FILE_ATTRIBUTE_READONLY))
+               {
+
+                   if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                   {
+
+                       DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
+                   }
+                   else
+                   {
+
+                       DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+                   }
+
+                   ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+                   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;
 
@@ -1546,13 +2083,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);
+                }
             }
         }
 
@@ -1590,9 +2138,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);
         }
@@ -1604,10 +2152,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);
         }
@@ -1620,16 +2168,17 @@ AFSSetDispositionInfo( IN PIRP Irp,
             //
 
             ntStatus = AFSNotifyDelete( DirectoryCB,
+                                        &pCcb->AuthGroup,
                                         TRUE);
 
             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);
             }
@@ -1638,72 +2187,218 @@ 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);
                 }
+
+                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
+            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);
 
-                if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
-                                          MmFlushForDelete))
+               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);
+
+               __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)
+               {
 
-                //
-                // Purge the cache as well
-                //
+                   bMmFlushed = FALSE;
+
+                   ntStatus = GetExceptionCode();
+
+                   AFSDbgTrace(( 0,
+                                 0,
+                                 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                 pFcb->ObjectInformation->FileId.Cell,
+                                 pFcb->ObjectInformation->FileId.Volume,
+                                 pFcb->ObjectInformation->FileId.Vnode,
+                                 pFcb->ObjectInformation->FileId.Unique,
+                                 ntStatus));
+               }
 
-                if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                              &pFcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread()));
+
+                AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
+                             &pFcb->NPFcb->Resource,
+                             PsGetCurrentThread()));
+
+               AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+                if ( !bMmFlushed)
                 {
 
-                    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));
+
+                    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)
+            {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
-                          DirectoryCB,
-                          &DirectoryCB->NameInformation.FileName);
+                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);
+                SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+            }
         }
         else
         {
@@ -1726,118 +2421,142 @@ try_exit:
 }
 
 NTSTATUS
-AFSSetRenameInfo( IN PIRP Irp)
+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};
-    AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
-    AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
-    PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
+    PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
+    PFILE_OBJECT pSrcFileObj = NULL;
     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
-    PFILE_RENAME_INFORMATION pRenameInfo = NULL;
-    UNICODE_STRING uniTargetName, uniSourceName;
-    BOOLEAN bReplaceIfExists = FALSE;
-    UNICODE_STRING uniShortName;
+    AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
+    AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
+    AFSObjectInfoCB *pSrcObject = NULL;
+    AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
+    UNICODE_STRING uniSourceName, uniTargetName;
+    UNICODE_STRING uniFullTargetName, uniTargetParentName;
+    BOOLEAN bCommonParent = FALSE;
     AFSDirectoryCB *pTargetDirEntry = NULL;
-    ULONG ulTargetCRC = 0;
+    AFSDirectoryCB *pNewTargetDirEntry = NULL;
+    ULONG ulTargetCRC;
     BOOLEAN bTargetEntryExists = FALSE;
-    AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
-    AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
-    AFSFileID stNewFid, stTmpTargetFid;
-    UNICODE_STRING uniTmpTargetName;
-    BOOLEAN bReplaceTmpTargetEntry = FALSE;
+    LONG lCount;
+    BOOLEAN bReleaseTargetDirLock = FALSE;
     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
-    UNICODE_STRING uniFullTargetPath;
-    BOOLEAN bCommonParent = FALSE;
-    ULONG oldFileIndex;
 
     __Enter
     {
 
-        bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
+        pSrcFileObj = pIrpSp->FileObject;
 
         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
 
         pSrcObject = pSrcFcb->ObjectInformation;
 
-        uniTmpTargetName.Length = 0;
-        uniTmpTargetName.MaximumLength = 0;
-        uniTmpTargetName.Buffer = NULL;
+        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;
 
         //
         // Perform some basic checks to ensure FS integrity
         //
 
-        if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
+        if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
         {
 
-            //
-            // 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");
+                          "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
 
             try_return( ntStatus = STATUS_INVALID_PARAMETER);
         }
 
-        if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
+        if( pTargetFileObj == NULL)
         {
 
-            //
-            // If there are any open children then fail the rename
-            //
-
-            if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
+            if ( pFileLinkInfo->RootDirectory)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                //
+                // The target directory is provided by HANDLE
+                // RootDirectory is only set when the target directory is not the same
+                // as the source directory.
+                //
+                // AFS only supports hard links within a single directory.
+                //
+                // The IOManager should translate any Handle to a FileObject for us.
+                // However, the failure to receive a FileObject is treated as a fatal
+                // error.
+                //
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                              "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
-                try_return( ntStatus = STATUS_ACCESS_DENIED);
+                try_return( ntStatus = STATUS_INVALID_PARAMETER);
             }
-        }
-        else
-        {
-
-            if( pSrcFcb->OpenHandleCount > 1)
+            else
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Attempt to rename directory with open references %wZ\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+                uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
 
-                try_return( ntStatus = STATUS_ACCESS_DENIED);
-            }
-        }
+                uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
 
-        //
-        // Resolve the target fileobject
-        //
+                AFSRetrieveFinalComponent( &uniFullTargetName,
+                                           &uniTargetName);
 
-        if( pTargetFileObj == NULL)
-        {
+                AFSRetrieveParentPath( &uniFullTargetName,
+                                       &uniTargetParentName);
 
-            //
-            // This is a simple rename. Here the target directory is the same as the source parent directory
-            // and the name is retrieved from the system buffer information
-            //
+                if ( uniTargetParentName.Length == 0)
+                {
+
+                    //
+                    // This is a simple rename. Here the target directory is the same as the source parent directory
+                    // and the name is retrieved from the system buffer information
+                    //
+
+                    pTargetParentObject = pSrcParentObject;
+                }
+                else
+                {
+                    //
+                    // uniTargetParentName contains the directory the renamed object
+                    // will be moved to.  Must obtain the TargetParentObject.
+                    //
 
-            pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+                    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));
 
-            pTargetParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
+                    try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
+                }
+            }
 
             pTargetDcb = pTargetParentObject->Fcb;
-
-            uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
-            uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
         }
         else
         {
@@ -1861,32 +2580,50 @@ AFSSetRenameInfo( IN PIRP Irp)
         }
 
         //
-        // We do not allow cross-volume renames to occur
+        // The quick check to see if they are self linking.
+        // Do the names match? Only do this where the parent directories are
+        // the same
         //
 
-        if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
+        if( pTargetParentObject == pSrcParentObject)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
-                          &pSrcCcb->DirectoryCB->NameInformation.FileName);
+            if( FsRtlAreNamesEqual( &uniTargetName,
+                                    &uniSourceName,
+                                    FALSE,
+                                    NULL))
+            {
+                try_return( ntStatus = STATUS_SUCCESS);
+            }
 
-            try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
+            bCommonParent = TRUE;
         }
+        else
+        {
 
-        //
-        // If the target exists be sure the ReplaceIfExists flag is set
-        //
+            //
+            // We do not allow cross-volume hard links
+            //
 
-        AFSAcquireShared( pTargetParentObject->VolumeCB->VolumeLock,
-                          TRUE);
+            if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
+            {
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
+
+                try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
+            }
+        }
 
         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
                                       FALSE);
 
-        AFSAcquireShared( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                          TRUE);
+        AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        bReleaseTargetDirLock = TRUE;
 
         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                         ulTargetCRC,
@@ -1907,9 +2644,10 @@ AFSSetRenameInfo( IN PIRP Irp)
                                               &pTargetDirEntry);
         }
 
-        if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
-                                                               NULL,
-                                                               NULL))
+        if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+             pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
+                                                                NULL,
+                                                                NULL))
         {
             //
             // Try the short name
@@ -1918,38 +2656,298 @@ AFSSetRenameInfo( IN PIRP Irp)
                                         ulTargetCRC,
                                         &pTargetDirEntry);
         }
+
         //
         // Increment our ref count on the dir entry
         //
 
         if( pTargetDirEntry != NULL)
         {
-            InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
-        }
-
-        AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-        if( pTargetDirEntry != NULL)
-        {
+            ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
+                    AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
 
-            if( !bReplaceIfExists)
-            {
+            lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-                AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
+            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));
+
+            ASSERT( lCount >= 0);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            if( !pFileLinkInfo->ReplaceIfExists)
+            {
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
+                              "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);
             }
 
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
+                          &pTargetDirEntry->NameInformation.FileName,
+                          pTargetDirEntry,
+                          lCount));
+
+            //
+            // Pull the directory entry from the parent
+            //
+
+            AFSRemoveDirNodeFromParent( pTargetParentObject,
+                                        pTargetDirEntry,
+                                        FALSE);
+
             bTargetEntryExists = TRUE;
         }
+        else
+        {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
+        }
+
+        //
+        // OK, this is a simple rename. Issue the rename
+        // request to the service.
+        //
+
+        ntStatus = AFSNotifyHardLink( pSrcObject,
+                                      &pSrcCcb->AuthGroup,
+                                      pSrcParentObject,
+                                      pTargetDcb->ObjectInformation,
+                                      pSrcCcb->DirectoryCB,
+                                      &uniTargetName,
+                                      pFileLinkInfo->ReplaceIfExists,
+                                      &pNewTargetDirEntry);
+
+        if( ntStatus != STATUS_REPARSE &&
+            !NT_SUCCESS( ntStatus))
+        {
+
+            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));
+
+            try_return( ntStatus);
+        }
+
+        if ( ntStatus != STATUS_REPARSE)
+        {
+
+            AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
+                                    pNewTargetDirEntry,
+                                    TRUE);
+        }
+
+        //
+        // Send notification for the target link file
+        //
+
+        if( bTargetEntryExists || pNewTargetDirEntry)
+        {
+
+            ulNotificationAction = FILE_ACTION_MODIFIED;
+        }
+        else
+        {
+
+            ulNotificationAction = FILE_ACTION_ADDED;
+        }
+
+        AFSFsRtlNotifyFullReportChange( pTargetParentObject,
+                                        pSrcCcb,
+                                        (ULONG)ulNotifyFilter,
+                                        (ULONG)ulNotificationAction);
+
+      try_exit:
+
+        if( !NT_SUCCESS( ntStatus))
+        {
+
+            if( bTargetEntryExists)
+            {
+
+                AFSInsertDirectoryNode( pTargetParentObject,
+                                        pTargetDirEntry,
+                                        FALSE);
+            }
+        }
+
+        if( pTargetDirEntry != NULL)
+        {
+
+            //
+            // Release DirOpenReferenceCount obtained above
+            //
+
+            lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
+
+            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));
+
+            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);
+        }
+
+        if( bReleaseTargetDirLock)
+        {
+
+            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;
+}
+
+NTSTATUS
+AFSSetRenameInfo( IN PIRP Irp)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
+    AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
+    PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
+    PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
+    PFILE_OBJECT pTargetParentFileObj = NULL;
+    PFILE_RENAME_INFORMATION pRenameInfo = NULL;
+    UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
+    BOOLEAN bReplaceIfExists = FALSE;
+    UNICODE_STRING uniShortName;
+    AFSDirectoryCB *pTargetDirEntry = NULL;
+    ULONG ulTargetCRC = 0;
+    BOOLEAN bTargetEntryExists = FALSE;
+    AFSObjectInfoCB *pSrcObject = NULL;
+    AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
+    AFSFileID stNewFid;
+    ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
+    UNICODE_STRING uniFullTargetName;
+    BOOLEAN bCommonParent = FALSE;
+    BOOLEAN bReleaseTargetDirLock = FALSE;
+    BOOLEAN bReleaseSourceDirLock = FALSE;
+    BOOLEAN bDereferenceTargetParentObject = FALSE;
+    PERESOURCE  pSourceDirLock = NULL;
+    LONG lCount;
+
+    __Enter
+    {
+
+        bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
+
+        pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+        pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
+        pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
+
+        pSrcObject = pSrcFcb->ObjectInformation;
+
+        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
+        //
+
+        if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
+        {
+
+            //
+            // Can't rename the root directory
+            //
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetRenameInfo Attempt to rename root entry\n"));
+
+            try_return( ntStatus = STATUS_INVALID_PARAMETER);
+        }
+
+        if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
+        {
+
+            //
+            // If there are any open children then fail the rename
+            //
+
+            if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
+            {
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
+                              &pSrcCcb->DirectoryCB->NameInformation.FileName));
+
+                try_return( ntStatus = STATUS_ACCESS_DENIED);
+            }
+        }
 
-        AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
 
         //
         // Extract off the final component name from the Fcb
@@ -1961,43 +2959,102 @@ AFSSetRenameInfo( IN PIRP Irp)
         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
 
         //
-        // The quick check to see if they are not really performing a rename
-        // Do the names match? Only do this where the parent directories are
-        // the same
+        // Resolve the target fileobject
         //
 
-        if( pTargetParentObject == pSrcFcb->ObjectInformation->ParentObjectInformation)
+        if( pTargetFileObj == NULL)
         {
 
-            bCommonParent = TRUE;
+            if ( pRenameInfo->RootDirectory)
+            {
 
-            if( FsRtlAreNamesEqual( &uniTargetName,
-                                    &uniSourceName,
-                                    TRUE,
-                                    NULL))
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
+
+                try_return( ntStatus = STATUS_INVALID_PARAMETER);
+            }
+            else
             {
 
-                //
-                // Check for case only rename
-                //
+                uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
+
+                uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
+
+                AFSRetrieveFinalComponent( &uniFullTargetName,
+                                           &uniTargetName);
 
-                if( !FsRtlAreNamesEqual( &uniTargetName,
-                                         &uniSourceName,
-                                         FALSE,
-                                         NULL))
+                AFSRetrieveParentPath( &uniFullTargetName,
+                                       &uniTargetParentName);
+
+                if ( uniTargetParentName.Length == 0)
                 {
 
                     //
-                    // Just move in the new case form of the name
+                    // This is a simple rename. Here the target directory is the same as the source parent directory
+                    // and the name is retrieved from the system buffer information
                     //
 
-                    RtlCopyMemory( pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer,
-                                   uniTargetName.Buffer,
-                                   uniTargetName.Length);
+                    pTargetParentObject = pSrcParentObject;
+                }
+                else
+                {
+                    //
+                    // uniTargetParentName contains the directory the renamed object
+                    // will be moved to.  Must obtain the TargetParentObject.
+                    //
+
+                    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));
+
+                    try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
                 }
+            }
+
+            pTargetDcb = pTargetParentObject->Fcb;
+        }
+        else
+        {
+
+            //
+            // So here we have the target directory taken from the targetfile object
+            //
+
+            pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
 
+            pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
+
+            pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
+
+            //
+            // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
+            // it is only the target component of the rename operation
+            //
+
+            uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
+        }
+
+        //
+        // The quick check to see if they are not really performing a rename
+        // Do the names match? Only do this where the parent directories are
+        // the same
+        //
+
+        if( pTargetParentObject == pSrcParentObject)
+        {
+
+            if( FsRtlAreNamesEqual( &uniTargetName,
+                                    &uniSourceName,
+                                    FALSE,
+                                    NULL))
+            {
                 try_return( ntStatus = STATUS_SUCCESS);
             }
+
+            bCommonParent = TRUE;
         }
         else
         {
@@ -2006,105 +3063,126 @@ AFSSetRenameInfo( IN PIRP Irp)
         }
 
         //
-        // If the target name exists then we need to 'move' the target before
-        // sending the rename to the service
+        // We do not allow cross-volume renames to occur
         //
 
-        if( bReplaceIfExists &&
-            pTargetDirEntry != NULL)
+        if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
         {
 
-            //
-            // What we will do is temporarily rename the file to a tmp file
-            // so we can back out if anything fails below
-            // First thing is to remove the original target from the parent
-            //
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
+                          &pSrcCcb->DirectoryCB->NameInformation.FileName));
 
-            AFSAcquireExcl( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                            TRUE);
+            try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
+        }
 
-            AFSRemoveDirNodeFromParent( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                        pTargetDirEntry,
-                                        TRUE);
+        ulTargetCRC = AFSGenerateCRC( &uniTargetName,
+                                      FALSE);
 
-            AFSReleaseResource( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+        AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
 
-            pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
+        bReleaseTargetDirLock = TRUE;
 
-            uniTmpTargetName.Length = 0;
-            uniTmpTargetName.MaximumLength = uniTargetName.Length + (4 * sizeof( WCHAR));
+        if( pTargetParentObject != pSrcParentObject)
+        {
+            AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                            TRUE);
 
-            uniTmpTargetName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                         uniTmpTargetName.MaximumLength,
-                                                                         AFS_GENERIC_MEMORY_11_TAG);
+            bReleaseSourceDirLock = TRUE;
 
-            if( uniTmpTargetName.Buffer == NULL)
-            {
+            pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
+        }
 
-                //
-                // Re-insert the entry
-                //
+        AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+                                        ulTargetCRC,
+                                        &pTargetDirEntry);
 
-                AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                        pTargetDirEntry,
-                                        TRUE);
+        if( pTargetDirEntry == NULL)
+        {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Failed tmp buffer allocation during rename of %wZ\n",
-                              &pSrcCcb->DirectoryCB->NameInformation.FileName);
+            //
+            // Missed so perform a case insensitive lookup
+            //
 
-                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-            }
+            ulTargetCRC = AFSGenerateCRC( &uniTargetName,
+                                          TRUE);
 
-            RtlZeroMemory( uniTmpTargetName.Buffer,
-                           uniTmpTargetName.MaximumLength);
+            AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
+                                              ulTargetCRC,
+                                              &pTargetDirEntry);
+        }
 
-            uniTmpTargetName.Length = uniTargetName.Length;
+        if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+             pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
+                                                               NULL,
+                                                               NULL))
+        {
+            //
+            // Try the short name
+            //
+            AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
+                                        ulTargetCRC,
+                                        &pTargetDirEntry);
+        }
 
-            RtlCopyMemory( uniTmpTargetName.Buffer,
-                           uniTargetName.Buffer,
-                           uniTmpTargetName.Length);
+        //
+        // Increment our ref count on the dir entry
+        //
 
-            RtlCopyMemory( &uniTmpTargetName.Buffer[ uniTmpTargetName.Length/sizeof( WCHAR)],
-                           L".tmp",
-                           4 * sizeof( WCHAR));
+        if( pTargetDirEntry != NULL)
+        {
 
-            uniTmpTargetName.Length += (4 * sizeof( WCHAR));
+            ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
+                    AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
 
-            ntStatus = AFSNotifyRename( pTargetDirEntry->ObjectInformation,
-                                        pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                        pTargetDcb->ObjectInformation,
-                                        pTargetDirEntry,
-                                        &uniTmpTargetName,
-                                        &stTmpTargetFid);
+            lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-            if( !NT_SUCCESS( ntStatus))
-            {
+            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));
 
-                //
-                // Re-insert the entry
-                //
+            ASSERT( lCount >= 0);
 
-                AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                        pTargetDirEntry,
-                                        TRUE);
+            if( !bReplaceIfExists)
+            {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Failed rename of %wZ to tmp %wZ Status %08lX\n",
+                              "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
-                              &uniTmpTargetName,
-                              ntStatus);
+                              &pTargetDirEntry->NameInformation.FileName));
 
-                try_return( ntStatus);
+                try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
             }
 
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
+                          &pTargetDirEntry->NameInformation.FileName,
+                          pTargetDirEntry,
+                          lCount));
+
             //
-            // Indicate we need to replace this entry if any failure occurs below
+            // Pull the directory entry from the parent
             //
 
-            bReplaceTmpTargetEntry = TRUE;
+            AFSRemoveDirNodeFromParent( pTargetParentObject,
+                                        pTargetDirEntry,
+                                        FALSE);
+
+            bTargetEntryExists = TRUE;
+        }
+        else
+        {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
         }
 
         //
@@ -2113,36 +3191,18 @@ AFSSetRenameInfo( IN PIRP Irp)
         // same parent we do not pull the node from the enumeration list
         //
 
-        AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                        TRUE);
-
-        AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
+        AFSRemoveDirNodeFromParent( pSrcParentObject,
                                     pSrcCcb->DirectoryCB,
                                     !bCommonParent);
 
-        AFSReleaseResource( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
-        oldFileIndex = pSrcCcb->DirectoryCB->FileIndex;
-        if( !bCommonParent)
-        {
-
-            //
-            // We always need to update the FileIndex since this entry will be put at the 'end'
-            // of the enumeraiton list. If we don't it will cause recursion ... We do this
-            // here to cover any failures which might occur below
-            //
-
-            pSrcCcb->DirectoryCB->FileIndex =
-                            (ULONG)InterlockedIncrement( &pTargetDcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
-        }
-
         //
         // OK, this is a simple rename. Issue the rename
         // request to the service.
         //
 
-        ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
-                                    pSrcFcb->ObjectInformation->ParentObjectInformation,
+        ntStatus = AFSNotifyRename( pSrcObject,
+                                    &pSrcCcb->AuthGroup,
+                                    pSrcParentObject,
                                     pTargetDcb->ObjectInformation,
                                     pSrcCcb->DirectoryCB,
                                     &uniTargetName,
@@ -2155,17 +3215,16 @@ AFSSetRenameInfo( IN PIRP Irp)
             // Attempt to re-insert the directory entry
             //
 
-            pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
-            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);
         }
@@ -2174,8 +3233,8 @@ AFSSetRenameInfo( IN PIRP Irp)
         // Set the notification up for the source file
         //
 
-        if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
-            !bReplaceTmpTargetEntry)
+        if( pSrcParentObject == pTargetParentObject &&
+            !bTargetEntryExists)
         {
 
             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
@@ -2186,7 +3245,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;
@@ -2197,7 +3256,7 @@ AFSSetRenameInfo( IN PIRP Irp)
             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
         }
 
-        AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
+        AFSFsRtlNotifyFullReportChange( pSrcParentObject,
                                         pSrcCcb,
                                         (ULONG)ulNotifyFilter,
                                         (ULONG)ulNotificationAction);
@@ -2216,17 +3275,16 @@ AFSSetRenameInfo( IN PIRP Irp)
             // Attempt to re-insert the directory entry
             //
 
-            pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
-            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);
         }
@@ -2239,13 +3297,13 @@ AFSSetRenameInfo( IN PIRP Irp)
                             &stNewFid))
         {
 
+            AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
+                            TRUE);
+
             //
             // Remove the old information entry
             //
 
-            AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
-                            TRUE);
-
             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
                                 &pSrcObject->TreeEntry);
 
@@ -2267,8 +3325,17 @@ AFSSetRenameInfo( IN PIRP Irp)
             else
             {
 
-                AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
-                                    &pSrcObject->TreeEntry);
+                if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
+                                                     &pSrcObject->TreeEntry)))
+                {
+
+                    //
+                    // Lost a race, an ObjectInfo object already exists for this FID.
+                    // Let this copy be garbage collected.
+                    //
+
+                    ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
+                }
             }
 
             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
@@ -2284,14 +3351,25 @@ AFSSetRenameInfo( IN PIRP Irp)
         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
                                                                                    TRUE);
 
-        if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0)
+        if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+            pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
+            !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
+                                     NULL,
+                                     NULL))
         {
 
             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
+            uniShortName.MaximumLength = uniShortName.Length;
             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
 
             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
                                                                                            TRUE);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
+                          &uniShortName,
+                          &pSrcCcb->DirectoryCB->NameInformation.FileName));
         }
         else
         {
@@ -2321,90 +3399,79 @@ 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)
         {
 
-            InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+            lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
 
-            InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
+            lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
 
-            InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
+            lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
 
-            InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
+            lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
 
-            pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
 
-            ulNotificationAction = FILE_ACTION_ADDED;
-        }
-        else
-        {
-
-            ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
-        }
+            //
+            // Guaranteed to be in the same volume
+            //
 
-        //
-        // Now update the notification for the target file
-        //
+            AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
+                            TRUE);
 
-        AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
-                                        pSrcCcb,
-                                        (ULONG)ulNotifyFilter,
-                                        (ULONG)ulNotificationAction);
+            lCount = AFSObjectInfoIncrement( pTargetParentObject,
+                                             AFS_OBJECT_REFERENCE_CHILD);
 
-        //
-        // If we performed the rename of the target because it existed, we now need to
-        // delete the tmp target we created above
-        //
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
+                          pTargetParentObject,
+                          lCount));
 
-        if( bReplaceTmpTargetEntry)
-        {
+            lCount = AFSObjectInfoDecrement( pSrcParentObject,
+                                             AFS_OBJECT_REFERENCE_CHILD);
 
-            RtlCopyMemory( &pTargetDirEntry->ObjectInformation->FileId,
-                           &stTmpTargetFid,
-                           sizeof( AFSFileID));
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
+                          pSrcParentObject,
+                          lCount));
 
-            //
-            // Update the name in the dir entry
-            //
+            pSrcObject->ParentFileId = pTargetParentObject->FileId;
 
-            ntStatus = AFSUpdateDirEntryName( pTargetDirEntry,
-                                              &uniTmpTargetName);
+            SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
 
-            if( !NT_SUCCESS( ntStatus))
-            {
+            AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSSetRenameInfo Failed update of target dir entry %wZ to tmp %wZ Status %08lX\n",
-                              &pTargetDirEntry->NameInformation.FileName,
-                              &uniTmpTargetName,
-                              ntStatus);
+            ulNotificationAction = FILE_ACTION_ADDED;
+        }
+        else
+        {
 
-                try_return( ntStatus);
-            }
+            ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
+        }
 
-            ntStatus = AFSNotifyDelete( pTargetDirEntry,
-                                        FALSE);
+        //
+        // Now update the notification for the target file
+        //
 
-            if( !NT_SUCCESS( ntStatus))
-            {
+        AFSFsRtlNotifyFullReportChange( pTargetParentObject,
+                                        pSrcCcb,
+                                        (ULONG)ulNotifyFilter,
+                                        (ULONG)ulNotificationAction);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSSetRenameInfo object deletion failure dir entry %p name %wZ to tmp %wZ\n",
-                              pTargetDirEntry,
-                              &pTargetDirEntry->NameInformation.FileName,
-                              &uniTmpTargetName);
+        //
+        // If we performed the rename of the target because it existed, we now need to
+        // delete the tmp target we created above
+        //
 
-                try_return( ntStatus);
-            }
+        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 to tmp %wZ\n",
+                          "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
                           pTargetDirEntry,
-                          &pTargetDirEntry->NameInformation.FileName,
-                          &uniTmpTargetName);
+                          &pTargetDirEntry->NameInformation.FileName));
 
             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
@@ -2414,146 +3481,202 @@ AFSSetRenameInfo( IN PIRP Irp)
 
             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
-                pTargetDirEntry->OpenReferenceCount > 1)
+                pTargetDirEntry->DirOpenReferenceCount > 1)
             {
 
                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
+            }
 
-                AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
-                                TRUE);
-
-                //
-                // Try and flush the cache map
-                //
+            ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
 
-                if( !MmFlushImageSection( &pTargetFcb->NPFcb->SectionObjectPointers,
-                                          MmFlushForDelete))
-                {
+            lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSSetRenameInfo Failed to flush section for deleted temp file %wZ\n",
-                                  &pTargetDirEntry->NameInformation.FileName);
-                }
+            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));
 
-                AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
-            }
+            ASSERT( lCount >= 0);
 
-            ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
+            if( lCount == 0 &&
+                pTargetDirEntry->NameArrayReferenceCount <= 0)
+            {
 
-            InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
+                              pTargetDirEntry,
+                              &pTargetDirEntry->NameInformation.FileName));
 
-            if( pTargetDirEntry->OpenReferenceCount == 0)
-            {
+                AFSDeleteDirEntry( pTargetParentObject,
+                                   &pTargetDirEntry);
+            }
 
-                SetFlag( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
+            pTargetDirEntry = NULL;
 
-                ASSERT( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE));
+            if ( pTargetFcb != NULL)
+            {
 
                 //
-                // Free up the name buffer if it was reallocated
+                // Do not hold TreeLocks across the MmForceSectionClosed() call as
+                // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
                 //
 
-                if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
+                if( bReleaseTargetDirLock)
                 {
+                    AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-                    AFSExFreePool( pTargetDirEntry->NameInformation.FileName.Buffer);
+                    bReleaseTargetDirLock = FALSE;
                 }
 
-                if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
+                if( bReleaseSourceDirLock)
                 {
 
-                    AFSExFreePool( pTargetDirEntry->NameInformation.TargetName.Buffer);
+                    AFSReleaseResource( pSourceDirLock);
+
+                    bReleaseSourceDirLock = FALSE;
                 }
 
                 //
-                // Dereference the object for this dir entry
+                // 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.
                 //
 
-                ASSERT( pTargetDirEntry->ObjectInformation->ObjectReferenceCount > 0);
+               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()));
 
-                InterlockedDecrement( &pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
+                AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
+                                TRUE);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSSetRenameInfo Decrement3 count on object %08lX Cnt %d\n",
-                              pTargetDirEntry->ObjectInformation,
-                              pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
+                              "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                              &pTargetFcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread()));
 
-                //
-                // Free up the dir entry
-                //
+                AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
+                                TRUE);
 
-                ExDeleteResourceLite( &pTargetDirEntry->NonPaged->Lock);
+               __try
+               {
 
-                AFSExFreePool( pTargetDirEntry->NonPaged);
+                   //
+                   // Close the section in the event it was mapped
+                   //
 
-                AFSExFreePool( pTargetDirEntry);
-            }
+                   if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
+                                              TRUE))
+                   {
 
-            pTargetDirEntry = NULL;
+                       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:
 
-
         if( !NT_SUCCESS( ntStatus))
         {
 
-            if( bReplaceTmpTargetEntry)
+            if( bTargetEntryExists)
             {
 
-                AFSNotifyRename( pTargetDirEntry->ObjectInformation,
-                                 pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                 pTargetDcb->ObjectInformation,
-                                 pTargetDirEntry,
-                                 &uniTargetName,
-                                 &stTmpTargetFid);
+                ASSERT( pTargetParentObject != NULL);
 
-                //
-                // Replace the target entry
-                //
+                AFSInsertDirectoryNode( pTargetParentObject,
+                                        pTargetDirEntry,
+                                        FALSE);
+            }
+        }
 
-                AFSAcquireExcl( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
-                                TRUE);
+        if( pTargetDirEntry != NULL)
+        {
 
-                if( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead == NULL)
-                {
+            lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
 
-                    pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead = &pTargetDirEntry->ObjectInformation->TreeEntry;
-                }
-                else
-                {
-                    AFSInsertHashEntry( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead,
-                                        &pTargetDirEntry->ObjectInformation->TreeEntry);
-                }
+            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));
 
-                AFSReleaseResource( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
+            ASSERT( lCount >= 0);
+        }
 
-                //
-                // We always need to update the FileIndex since this entry will be put at the 'end'
-                // of the enumeraiton list. If we don't it will cause recursion ...
-                //
+        if( bReleaseTargetDirLock)
+        {
 
-                pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
+            AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+        }
 
-                AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
-                                        pTargetDirEntry,
-                                        TRUE);
-            }
+        if( bReleaseSourceDirLock)
+        {
+
+            AFSReleaseResource( pSourceDirLock);
         }
 
-        if( pTargetDirEntry != NULL)
+        if ( bDereferenceTargetParentObject)
         {
 
-            InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
+            ObDereferenceObject( pTargetParentFileObj);
         }
 
-        if( uniTmpTargetName.Buffer != NULL)
+        if ( pSrcParentObject != NULL)
         {
 
-            AFSExFreePool( uniTmpTargetName.Buffer);
+            AFSReleaseObjectInfo( &pSrcParentObject);
         }
+
+        //
+        // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
+        // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
+        //
+
+        pTargetParentObject = NULL;
     }
 
     return ntStatus;
@@ -2563,6 +3686,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);
@@ -2578,11 +3702,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;
@@ -2612,31 +3738,80 @@ 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);
 
             bReleasePaging = TRUE;
 
+            //
+            // Must drop the Fcb Resource.  When changing the file size
+            // a deadlock can occur with Trend Micro's filter if the file
+            // size is set to zero.
+            //
+
+            AFSReleaseResource( &pFcb->NPFcb->Resource);
 
             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
 
@@ -2667,6 +3842,26 @@ AFSSetAllocationInfo( IN PIRP Irp,
         //
         // Tell Cc if allocation is increased.
         //
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+                      &pFcb->NPFcb->PagingResource,
+                      PsGetCurrentThread()));
+
+        AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
+                        TRUE);
+
+        bReleasePaging = TRUE;
+
+        //
+        // Must drop the Fcb Resource.  When changing the file size
+        // a deadlock can occur with Trend Micro's filter if the file
+        // size is set to zero.
+        //
+
+        AFSReleaseResource( &pFcb->NPFcb->Resource);
+
         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
 
         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
@@ -2679,9 +3874,12 @@ 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,
-                                             &pFcb->AuthGroup);
+                                             &pCcb->AuthGroup);
     }
 
     if (NT_SUCCESS(ntStatus))
@@ -2723,6 +3921,9 @@ AFSSetAllocationInfo( IN PIRP Irp,
     {
 
         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
+
+        AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                        TRUE);
     }
 
     return ntStatus;
@@ -2732,6 +3933,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);
@@ -2742,6 +3944,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
     BOOLEAN bModified = FALSE;
     BOOLEAN bReleasePaging = FALSE;
     BOOLEAN bTruncated = FALSE;
+    BOOLEAN bUserMapped = FALSE;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
 
@@ -2762,30 +3965,78 @@ 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;
             }
             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",
+                             "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                               &pFcb->NPFcb->PagingResource,
-                              PsGetCurrentThread());
+                              PsGetCurrentThread()));
 
                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
                                 TRUE);
 
                 bReleasePaging = TRUE;
 
+                //
+                // Must drop the Fcb Resource.  When changing the file size
+                // a deadlock can occur with Trend Micro's filter if the file
+                // size is set to zero.
+                //
+
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
 
                 pFcb->Header.FileSize = pBuffer->EndOfFile;
@@ -2807,10 +4058,34 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
         }
         else
         {
+
             //
             // extending the file, move EOF
             //
 
+            //
+            // If this is a truncation we need to grab the paging
+            // IO resource.
+            //
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                         "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+                          &pFcb->NPFcb->PagingResource,
+                          PsGetCurrentThread()));
+
+            AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
+                            TRUE);
+
+            bReleasePaging = TRUE;
+
+            //
+            // Must drop the Fcb Resource.  When changing the file size
+            // a deadlock can occur with Trend Micro's filter if the file
+            // size is set to zero.
+            //
+
+            AFSReleaseResource( &pFcb->NPFcb->Resource);
+
             pFcb->Header.FileSize = pBuffer->EndOfFile;
 
             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
@@ -2840,9 +4115,11 @@ 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,
-                                             &pFcb->AuthGroup);
+                                             &pCcb->AuthGroup);
 
         if( NT_SUCCESS(ntStatus))
         {
@@ -2876,6 +4153,9 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
     {
 
         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
+
+        AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                        TRUE);
     }
 
     return ntStatus;
@@ -2887,9 +4167,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;
 
@@ -2897,11 +4177,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);
@@ -2909,10 +4189,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);
         }
@@ -2929,20 +4209,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:
 
@@ -2958,9 +4238,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;
 
@@ -2969,11 +4249,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);
@@ -2981,10 +4261,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);
         }
@@ -3002,20 +4282,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:
 
@@ -3032,6 +4312,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;
@@ -3047,6 +4329,10 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             case FileBasicInformation:
             {
 
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
+
                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
                 {
                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
@@ -3055,13 +4341,13 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                     pBasic->LastAccessTime.QuadPart = 0;
                     pBasic->ChangeTime.QuadPart = 0;
                     pBasic->LastWriteTime.QuadPart = 0;
-                    pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
+                    pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
 
                     *Length -= sizeof( FILE_BASIC_INFORMATION);
                 }
                 else
                 {
-                    ntStatus = STATUS_BUFFER_OVERFLOW;
+                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                 }
 
                 break;
@@ -3070,26 +4356,31 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
             case FileStandardInformation:
             {
 
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
+
                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
                 {
                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
 
                     pStandard->NumberOfLinks = 1;
                     pStandard->DeletePending = 0;
-                    pStandard->AllocationSize.QuadPart = 4096;
-                    pStandard->EndOfFile.QuadPart = 4096;
+                    pStandard->AllocationSize.QuadPart = 0;
+                    pStandard->EndOfFile.QuadPart = 0;
                     pStandard->Directory = 0;
 
                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
                 }
                 else
                 {
-                    ntStatus = STATUS_BUFFER_OVERFLOW;
+                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                 }
 
                 break;
             }
 
+            case FileNormalizedNameInformation:
             case FileNameInformation:
             {
 
@@ -3100,6 +4391,10 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
                 UNICODE_STRING uniName;
 
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
+
                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
 
@@ -3176,10 +4471,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));
                     }
                 }
 
@@ -3191,6 +4486,10 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
 
                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
 
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
+
                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
                 {
 
@@ -3209,20 +4508,124 @@ AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
                 break;
             }
 
+            case FileAllInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileEaInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FilePositionInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileAlternateNameInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileNetworkOpenInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileStreamInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileAttributeTagInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileRemoteProtocolInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
+
+                break;
+            }
+
+            case FileNetworkPhysicalNameInformation:
+            {
+                ntStatus = STATUS_INVALID_PARAMETER;
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
+
+                break;
+            }
+
             default:
             {
                 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;
             }
         }
     }
 
+    AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
+                  AFS_TRACE_LEVEL_VERBOSE,
+                  "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
+                  ntStatus));
+
     return ntStatus;
 }