return ntStatus;
}
+
+NTSTATUS
+AFSNotifyHardLink( IN AFSObjectInfoCB *ObjectInfo,
+ IN GUID *AuthGroup,
+ IN AFSObjectInfoCB *ParentObjectInfo,
+ IN AFSObjectInfoCB *TargetParentObjectInfo,
+ IN AFSDirectoryCB *SourceDirectoryCB,
+ IN UNICODE_STRING *TargetName,
+ IN BOOLEAN bReplaceIfExists,
+ OUT AFSDirectoryCB **TargetDirectoryCB)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSFileHardLinkCB *pHardLinkCB = NULL;
+ AFSFileHardLinkResultCB *pResultCB = NULL;
+ ULONG ulResultLen = 0;
+ AFSDirectoryCB *pDirNode = NULL;
+ ULONG ulCRC = 0;
+ BOOLEAN bReleaseParentLock = FALSE, bReleaseTargetParentLock = FALSE;
+ AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+
+ __Enter
+ {
+
+ //
+ // Init the control block for the request
+ //
+
+ pHardLinkCB = (AFSFileHardLinkCB *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_HARDLINK_REQUEST_TAG);
+
+ if( pHardLinkCB == NULL)
+ {
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory( pHardLinkCB,
+ PAGE_SIZE);
+
+ pHardLinkCB->SourceParentId = ParentObjectInfo->FileId;
+
+ pHardLinkCB->TargetParentId = TargetParentObjectInfo->FileId;
+
+ pHardLinkCB->TargetNameLength = TargetName->Length;
+
+ RtlCopyMemory( pHardLinkCB->TargetName,
+ TargetName->Buffer,
+ TargetName->Length);
+
+ pHardLinkCB->bReplaceIfExists = bReplaceIfExists;
+
+ //
+ // Use the same buffer for the result control block
+ //
+
+ pResultCB = (AFSFileHardLinkResultCB *)pHardLinkCB;
+
+ ulResultLen = PAGE_SIZE;
+
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_HARDLINK_FILE,
+ AFS_REQUEST_FLAG_SYNCHRONOUS,
+ AuthGroup,
+ &SourceDirectoryCB->NameInformation.FileName,
+ &ObjectInfo->FileId,
+ pHardLinkCB,
+ sizeof( AFSFileHardLinkCB) + TargetName->Length,
+ pResultCB,
+ &ulResultLen);
+
+ if( ntStatus != STATUS_SUCCESS)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNotifyHardLink failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique,
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+
+ //
+ // Update the information from the returned data
+ //
+
+ if ( ParentObjectInfo != TargetParentObjectInfo)
+ {
+
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ bReleaseParentLock = TRUE;
+
+ if ( ParentObjectInfo->DataVersion.QuadPart == pResultCB->SourceParentDataVersion.QuadPart - 1)
+ {
+
+ ParentObjectInfo->DataVersion = pResultCB->SourceParentDataVersion;
+ }
+ else
+ {
+
+ SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ }
+
+ AFSAcquireExcl( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ bReleaseTargetParentLock = TRUE;
+
+ if ( TargetParentObjectInfo->DataVersion.QuadPart == pResultCB->TargetParentDataVersion.QuadPart - 1)
+ {
+
+ TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
+ }
+ else
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSNotifyHardLink Raced with an invalidate call and a re-enumeration for entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version (%08lX:%08lX != %08lX:%08lX - 1)\n",
+ TargetName,
+ TargetParentObjectInfo->FileId.Cell,
+ TargetParentObjectInfo->FileId.Volume,
+ TargetParentObjectInfo->FileId.Vnode,
+ TargetParentObjectInfo->FileId.Unique,
+ TargetParentObjectInfo->DataVersion.HighPart,
+ TargetParentObjectInfo->DataVersion.LowPart,
+ pResultCB->TargetParentDataVersion.HighPart,
+ pResultCB->TargetParentDataVersion.LowPart);
+
+ //
+ // We raced so go and lookup the directory entry in the parent
+ //
+
+ ulCRC = AFSGenerateCRC( TargetName,
+ FALSE);
+
+ AFSLocateCaseSensitiveDirEntry( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ ulCRC,
+ &pDirNode);
+
+ if( pDirNode != NULL)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Located dir entry %p for file %wZ\n",
+ pDirNode,
+ TargetName);
+
+ if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
+ &pResultCB->DirEnum.FileId))
+ {
+
+ InterlockedIncrement( &pDirNode->OpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Increment count on %wZ DE %p Cnt %d\n",
+ &pDirNode->NameInformation.FileName,
+ pDirNode,
+ pDirNode->OpenReferenceCount);
+
+ AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus = STATUS_REPARSE);
+ }
+ else
+ {
+
+ //
+ // We found an entry that matches the desired name but it is not the
+ // same as the one that was created for us by the file server.
+ //
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNotifyHardLink Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
+ TargetName,
+ pDirNode,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ if( pDirNode->OpenReferenceCount == 0)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ AFSDeleteDirEntry( TargetParentObjectInfo,
+ pDirNode);
+ }
+ else
+ {
+
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ AFSRemoveNameEntry( TargetParentObjectInfo,
+ pDirNode);
+ }
+
+ pDirNode = NULL;
+ }
+ }
+
+ //
+ // We are unsure of our current data so set the verify flag. It may already be set
+ // but no big deal to reset it
+ //
+
+ SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ //
+ // Create the hard link entry
+ //
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Creating new entry %wZ\n",
+ TargetName);
+
+ //
+ // Initialize the directory entry
+ //
+
+ pDirNode = AFSInitDirEntry( TargetParentObjectInfo,
+ TargetName,
+ NULL,
+ &pResultCB->DirEnum,
+ (ULONG)InterlockedIncrement( &TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
+
+ if( pDirNode == NULL)
+ {
+
+ SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ //
+ // Init the short name if we have one
+ //
+
+ if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+ pResultCB->DirEnum.ShortNameLength > 0)
+ {
+
+ UNICODE_STRING uniShortName;
+
+ pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
+
+ RtlCopyMemory( pDirNode->NameInformation.ShortName,
+ pResultCB->DirEnum.ShortName,
+ pDirNode->NameInformation.ShortNameLength);
+
+ //
+ // Generate the short name index
+ //
+
+ uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
+ uniShortName.Buffer = pDirNode->NameInformation.ShortName;
+
+ pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
+ TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Initialized short name %wZ for DE %p for %wZ\n",
+ &uniShortName,
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
+ else
+ {
+ //
+ // No short name or short names are disabled
+ //
+
+ pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
+ }
+
+ if ( !BooleanFlagOn( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ //
+ // Update the target parent data version
+ //
+
+ TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
+ TargetName,
+ TargetParentObjectInfo->FileId.Cell,
+ TargetParentObjectInfo->FileId.Volume,
+ TargetParentObjectInfo->FileId.Vnode,
+ TargetParentObjectInfo->FileId.Unique,
+ TargetParentObjectInfo->DataVersion.QuadPart);
+ }
+
+try_exit:
+
+ if ( bReleaseTargetParentLock)
+ {
+
+ AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
+ if ( bReleaseParentLock)
+ {
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
+ if( pHardLinkCB != NULL)
+ {
+
+ AFSExFreePoolWithTag( pHardLinkCB, AFS_HARDLINK_REQUEST_TAG);
+ }
+
+ if ( TargetDirectoryCB)
+ {
+
+ *TargetDirectoryCB = pDirNode;
+ }
+ }
+
+ return ntStatus;
+}
+
+
+
NTSTATUS
AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
IN GUID *AuthGroup,
case FileLinkInformation:
{
- ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ ntStatus = AFSSetFileLinkInfo( Irp);
break;
}
{
//
+ // 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
//
}
NTSTATUS
+AFSSetFileLinkInfo( IN PIRP Irp)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+ PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+ IO_STATUS_BLOCK stIoSb = {0,0};
+ PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
+ PFILE_OBJECT pSrcFileObj = NULL;
+ PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
+ AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
+ AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
+ AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
+ AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
+ UNICODE_STRING uniSourceName, uniTargetName;
+ UNICODE_STRING uniFullTargetName, uniTargetParentName;
+ UNICODE_STRING uniShortName;
+ BOOLEAN bCommonParent = FALSE;
+ AFSDirectoryCB *pTargetDirEntry = NULL;
+ AFSDirectoryCB *pNewTargetDirEntry = NULL;
+ ULONG ulTargetCRC;
+ BOOLEAN bTargetEntryExists = FALSE;
+ LONG lCount;
+ BOOLEAN bReleaseTargetDirLock = FALSE;
+ AFSFileID stNewFid;
+ ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
+
+ __Enter
+ {
+
+ pSrcFileObj = pIrpSp->FileObject;
+
+ pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
+ pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
+
+ pSrcObject = pSrcFcb->ObjectInformation;
+ pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
+
+ pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ //
+ // Perform some basic checks to ensure FS integrity
+ //
+
+ if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n");
+
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
+
+ if( pTargetFileObj == NULL)
+ {
+
+ if ( pFileLinkInfo->RootDirectory)
+ {
+
+ //
+ // 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.
+ //
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
+ &pSrcCcb->DirectoryCB->NameInformation.FileName);
+
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+
+ uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
+
+ uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
+
+ AFSRetrieveFinalComponent( &uniFullTargetName,
+ &uniTargetName);
+
+ AFSRetrieveParentPath( &uniFullTargetName,
+ &uniTargetParentName);
+
+ 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.
+ //
+
+ AFSDbgLogMsg( 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);
+
+ 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 self linking.
+ // 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
+ {
+
+ //
+ // We do not allow cross-volume hard links
+ //
+
+ if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
+ {
+
+ AFSDbgLogMsg( 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);
+
+ AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ bReleaseTargetDirLock = TRUE;
+
+ AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ ulTargetCRC,
+ &pTargetDirEntry);
+
+ if( pTargetDirEntry == NULL)
+ {
+
+ //
+ // Missed so perform a case insensitive lookup
+ //
+
+ ulTargetCRC = AFSGenerateCRC( &uniTargetName,
+ TRUE);
+
+ AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
+ ulTargetCRC,
+ &pTargetDirEntry);
+ }
+
+ 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);
+ }
+
+ //
+ // Increment our ref count on the dir entry
+ //
+
+ if( pTargetDirEntry != NULL)
+ {
+
+ ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
+
+ lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
+
+ if( !pFileLinkInfo->ReplaceIfExists)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
+ &pSrcCcb->DirectoryCB->NameInformation.FileName,
+ &pTargetDirEntry->NameInformation.FileName);
+
+ try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
+ }
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSSetFileLinkInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
+ &pTargetDirEntry->NameInformation.FileName,
+ pTargetDirEntry,
+ pTargetDirEntry->OpenReferenceCount);
+
+ //
+ // Pull the directory entry from the parent
+ //
+
+ AFSRemoveDirNodeFromParent( pTargetParentObject,
+ pTargetDirEntry,
+ FALSE);
+
+ bTargetEntryExists = TRUE;
+ }
+ else
+ {
+ AFSDbgLogMsg( 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( pSrcFcb->ObjectInformation,
+ &pSrcCcb->AuthGroup,
+ pSrcFcb->ObjectInformation->ParentObjectInformation,
+ pTargetDcb->ObjectInformation,
+ pSrcCcb->DirectoryCB,
+ &uniTargetName,
+ pFileLinkInfo->ReplaceIfExists,
+ &pNewTargetDirEntry);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( 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);
+ }
+
+ 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->ParentObjectInformation,
+ pSrcCcb,
+ (ULONG)ulNotifyFilter,
+ (ULONG)ulNotificationAction);
+
+ try_exit:
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ if( bTargetEntryExists)
+ {
+
+ AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
+ pTargetDirEntry,
+ FALSE);
+ }
+ }
+
+ if( pTargetDirEntry != NULL)
+ {
+
+ lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
+ }
+
+ if( bReleaseTargetDirLock)
+ {
+
+ AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+ }
+
+ return ntStatus;
+}
+
+NTSTATUS
AFSSetRenameInfo( IN PIRP Irp)
{
}
}
+
//
// Extract off the final component name from the Fcb
//
try_exit:
-
if( !NT_SUCCESS( ntStatus))
{