&NewVolumeReferenceReason,
&pNewParentDirectoryCB,
&pDirectoryCB,
- &uniComponentName);
+ &uniComponentName,
+ NULL);
if ( pNewVolumeCB != NULL)
{
&NewVolumeReferenceReason,
&pNewParentDirectoryCB,
&pDirectoryCB,
- &uniComponentName);
+ &uniComponentName,
+ NULL);
if ( ntStatus == STATUS_SUCCESS ||
ntStatus == STATUS_OBJECT_NAME_NOT_FOUND ||
&NewVolumeReferenceReason,
&pNewParentDirectoryCB,
&pDirectoryCB,
- &uniComponentName);
+ &uniComponentName,
+ NULL);
}
}
else
UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
ULONG ulNameDifference = 0;
LONG lCount;
+ UNICODE_STRING uniDFSTargetName;
__Enter
{
- //
+ uniDFSTargetName.Length = 0;
+ uniDFSTargetName.MaximumLength = 0;
+ uniDFSTargetName.Buffer = NULL;
+
+ //
// Retrieve a target name for the entry
//
&NewVolumeReferenceReason,
&pNewParentDirEntry,
&pDirectoryEntry,
- NULL);
+ NULL,
+ &uniDFSTargetName);
if ( pNewVolumeCB != NULL)
{
pNewParentDirEntry = NULL;
- if( !NT_SUCCESS( ntStatus) ||
- ntStatus == STATUS_REPARSE)
+ if( !NT_SUCCESS( ntStatus))
+ {
+ try_return( ntStatus);
+ }
+
+ //
+ // If the status is STATUS_REPARSE then attempt to retrieve the attributes from the target name returned
+ //
+
+ if( ntStatus == STATUS_REPARSE)
{
+ ntStatus = AFSRetrieveTargetFileInfo( &uniDFSTargetName,
+ FileInfo);
+
try_return( ntStatus);
}
AFSExFreePoolWithTag( pwchBuffer, 0);
}
+
+ if ( uniDFSTargetName.Buffer != NULL)
+ {
+
+ AFSExFreePoolWithTag( uniDFSTargetName.Buffer,
+ AFS_REPARSE_NAME_TAG);
+ }
}
return ntStatus;
&VolumeReferenceReason,
&pNewParentDirEntry,
&pDirectoryEntry,
- NULL);
+ NULL,
+ NULL);
if ( pNewVolumeCB != NULL)
{
&NewVolumeReferenceReason,
&pNewParentDirEntry,
&pDirectoryEntry,
- NULL);
+ NULL,
+ NULL);
if ( pNewVolumeCB != NULL)
{
return bIgnoreReparsePoint;
}
+
+NTSTATUS
+AFSRetrieveTargetFileInfo( IN PUNICODE_STRING TargetName,
+ OUT AFSFileInfoCB *FileInfo)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ OBJECT_ATTRIBUTES stObjectAttribs;
+ HANDLE hFile = NULL;
+ IO_STATUS_BLOCK stIoStatus;
+ FILE_NETWORK_OPEN_INFORMATION stFileInfo;
+
+ __Enter
+ {
+
+ InitializeObjectAttributes( &stObjectAttribs,
+ TargetName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ ntStatus = ZwCreateFile( &hFile,
+ FILE_READ_ATTRIBUTES,
+ &stObjectAttribs,
+ &stIoStatus,
+ NULL,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ try_return( ntStatus);
+ }
+
+ ntStatus = ZwQueryInformationFile( hFile,
+ &stIoStatus,
+ &stFileInfo,
+ sizeof( FILE_NETWORK_OPEN_INFORMATION),
+ FileNetworkOpenInformation);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ try_return( ntStatus);
+ }
+
+ FileInfo->FileAttributes = stFileInfo.FileAttributes;
+
+ FileInfo->AllocationSize = stFileInfo.AllocationSize;
+
+ FileInfo->EndOfFile = stFileInfo.EndOfFile;
+
+ FileInfo->CreationTime = stFileInfo.CreationTime;
+
+ FileInfo->LastAccessTime = stFileInfo.LastAccessTime;
+
+ FileInfo->LastWriteTime = stFileInfo.LastWriteTime;
+
+ FileInfo->ChangeTime = stFileInfo.ChangeTime;
+
+try_exit:
+
+ if( hFile != NULL)
+ {
+ ZwClose( hFile);
+ }
+ }
+
+ return ntStatus;
+}
OUT LONG *OutVolumeReferenceReason,
OUT AFSDirectoryCB **OutParentDirectoryCB,
OUT AFSDirectoryCB **OutDirectoryCB,
- OUT PUNICODE_STRING ComponentName)
+ OUT PUNICODE_STRING ComponentName,
+ OUT PUNICODE_STRING TargetName)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// system for it to reevaluate it
//
- if( FileObject != NULL)
+ if( FileObject != NULL ||
+ TargetName != NULL)
{
ntStatus = AFSProcessDFSLink( pDirEntry,
FileObject,
&uniRemainingPath,
- AuthGroup);
+ AuthGroup,
+ TargetName);
}
else
{
AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
IN PFILE_OBJECT FileObject,
IN UNICODE_STRING *RemainingPath,
- IN GUID *AuthGroup)
+ IN GUID *AuthGroup,
+ OUT PUNICODE_STRING TargetName)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
__Enter
{
- //
+ if ( FileObject != NULL && TargetName != NULL ||
+ FileObject == NULL && TargetName == NULL)
+ {
+
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
+
+ //
// Build up the name to reparse
//
}
//
- // Allocate the reparse buffer
- //
+ // Allocate the reparse buffer (from FS because might be returned in FileObject)
+ //
uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
uniReparseName.MaximumLength,
uniReparseName.Length += RemainingPath->Length;
}
- //
- // Update the name in the file object
- //
-
- if( FileObject->FileName.Buffer != NULL)
+ if( FileObject != NULL)
{
+ //
+ // Update the name in the file object
+ //
+
+ if( FileObject->FileName.Buffer != NULL)
+ {
- AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+ //
+ // original FileObject buffer was not allocated by AFS
+ //
+
+ ExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+ }
+
+ FileObject->FileName = uniReparseName;
}
+ else
+ {
- FileObject->FileName = uniReparseName;
+ *TargetName = uniReparseName;
+ }
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
OUT LONG *OutVolumeReferenceReason,
OUT AFSDirectoryCB **OutParentDirectoryCB,
OUT AFSDirectoryCB **OutDirectoryCB,
- OUT PUNICODE_STRING ComponentName);
+ OUT PUNICODE_STRING ComponentName,
+ OUT PUNICODE_STRING TargetName);
NTSTATUS
AFSCreateDirEntry( IN GUID *AuthGroup,
NTSTATUS
AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
IN PFILE_OBJECT FileObject,
- IN UNICODE_STRING *RemainingPath,
- IN GUID *AuthGroup);
+ IN PUNICODE_STRING RemainingPath,
+ IN GUID *AuthGroup,
+ OUT PUNICODE_STRING TargetName);
//
// AFSNetworkProviderSupport.cpp
BOOLEAN
AFSIgnoreReparsePointToFile( void);
+NTSTATUS
+AFSRetrieveTargetFileInfo( IN PUNICODE_STRING TargetName,
+ OUT AFSFileInfoCB *FileInfo);
+
//
// AFSNameArray.cpp Prototypes
//