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
//
RtlZeroMemory( uniFullPathName.Buffer,
uniFullPathName.MaximumLength);
- RtlCopyMemory( uniFullPathName.Buffer,
- ParentPathName->Buffer,
- ParentPathName->Length);
+ if ( ParentPathName->Length > 0)
+ {
- uniFullPathName.Length = ParentPathName->Length;
+ RtlCopyMemory( uniFullPathName.Buffer,
+ ParentPathName->Buffer,
+ ParentPathName->Length);
- if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
- DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
- {
+ uniFullPathName.Length = ParentPathName->Length;
- uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
+ if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
+ DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
+ {
- uniFullPathName.Length += sizeof( WCHAR);
- }
+ uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
+
+ uniFullPathName.Length += sizeof( WCHAR);
+ }
+ }
- RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
+ RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
DirectoryCB->NameInformation.TargetName.Buffer,
DirectoryCB->NameInformation.TargetName.Length);
&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)
{
// If the final character is a \, jump over it
//
- if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
+ if( ParentPath->Length >= sizeof( WCHAR)
+ && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
{
ParentPath->Length -= sizeof( WCHAR);
}
- while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
+ while( ParentPath->Length >= sizeof( WCHAR)
+ && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
{
ParentPath->Length -= sizeof( WCHAR);
}
// And the separator
//
- ParentPath->Length -= sizeof( WCHAR);
+ if ( ParentPath->Length >= sizeof( WCHAR))
+ {
+ ParentPath->Length -= sizeof( WCHAR);
+ }
return;
}
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;
+}
+
+BOOLEAN
+AFSIsShareName( IN UNICODE_STRING *FileName)
+{
+
+ BOOLEAN bIsShareName = TRUE;
+ USHORT usIndex = 1; // Skip the first \
+
+ //
+ // A share name will be of the form \Share so only a single \ at the beginning
+ //
+
+ while( usIndex < FileName->Length/sizeof( WCHAR))
+ {
+
+ if( FileName->Buffer[ usIndex] == L'\\')
+ {
+ bIsShareName = FALSE;
+ break;
+ }
+
+ usIndex++;
+ }
+
+ return bIsShareName;
+}
\ No newline at end of file