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;
TRUE);
ntStatus = AFSVerifyEntry( AuthGroup,
- pDirEntry);
+ pDirEntry,
+ FALSE);
AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
//
ntStatus = AFSVerifyEntry( AuthGroup,
- pDirEntry);
+ pDirEntry,
+ FALSE);
AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
pDirEntry = AFSBackupEntry( pNameArray);
+ pCurrentObject = pDirEntry->ObjectInformation;
+
//
// Increment our reference on this dir entry
//
pDirEntry = pCurrentVolume->DirectoryCB;
+ pCurrentObject = pDirEntry->ObjectInformation;
+
//
// Reference the new dir entry
//
pDirEntry = pCurrentVolume->DirectoryCB;
+ pCurrentObject = pDirEntry->ObjectInformation;
+
lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
case AFS_FILE_TYPE_DFSLINK:
{
- if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
+ if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL) &&
+ uniRemainingPath.Length == 0)
{
//
// system for it to reevaluate it
//
- if( FileObject != NULL)
+ if( FileObject != NULL ||
+ TargetName != NULL)
{
ntStatus = AFSProcessDFSLink( pDirEntry,
FileObject,
&uniRemainingPath,
- AuthGroup);
+ AuthGroup,
+ TargetName);
}
else
{
try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
}
+ pCurrentObject = pDirEntry->ObjectInformation;
+
lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
pDirEntry = NULL;
+ pCurrentObject = NULL;
+
uniSearchName = uniComponentName;
while( pDirEntry == NULL)
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
FileObject,
&uniSearchName,
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique));
+ pParentDirEntry->ObjectInformation->FileId.Cell,
+ pParentDirEntry->ObjectInformation->FileId.Volume,
+ pParentDirEntry->ObjectInformation->FileId.Vnode,
+ pParentDirEntry->ObjectInformation->FileId.Unique));
}
else
{
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
FileObject,
&uniSearchName,
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique));
+ pParentDirEntry->ObjectInformation->FileId.Cell,
+ pParentDirEntry->ObjectInformation->FileId.Volume,
+ pParentDirEntry->ObjectInformation->FileId.Vnode,
+ pParentDirEntry->ObjectInformation->FileId.Unique));
//
// Pass back the directory entries
// Is more than one link entry for this node then fail the lookup request
//
+ pCurrentObject = pDirEntry->ObjectInformation;
+
if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
pDirEntry->CaseInsensitiveList.fLink != NULL)
{
// revalidate the parent and search again.
//
+ pCurrentObject = pDirEntry->ObjectInformation;
+
if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
{
TRUE);
ntStatus = AFSVerifyEntry( AuthGroup,
- pParentDirEntry);
+ pParentDirEntry,
+ FALSE);
AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
pDirEntry = NULL;
+ pCurrentObject = NULL;
+
continue;
}
// If we have a dirEntry for this component, perform some basic validation on it
//
- if( pDirEntry != NULL &&
- BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
+ if( pDirEntry != NULL)
{
pCurrentObject = pDirEntry->ObjectInformation;
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
- FileObject,
- &pDirEntry->NameInformation.FileName,
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique));
-
- //
- // This entry was deleted through the invalidation call back so perform cleanup
- // on the entry
- //
-
- if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+ if (BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
{
- pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
- &pCurrentObject->ParentFileId,
- FALSE);
- }
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ FileObject,
+ &pDirEntry->NameInformation.FileName,
+ pCurrentObject->FileId.Cell,
+ pCurrentObject->FileId.Volume,
+ pCurrentObject->FileId.Vnode,
+ pCurrentObject->FileId.Unique));
- ASSERT( pParentObjectInfo != NULL);
+ //
+ // This entry was deleted through the invalidation call back so perform cleanup
+ // on the entry
+ //
- AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
+ if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+ {
- AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
+ pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
+ &pCurrentObject->ParentFileId,
+ FALSE);
+ }
- lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+ ASSERT( pParentObjectInfo != NULL);
- AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
- &pDirEntry->NameInformation.FileName,
- pDirEntry,
- NULL,
- lCount));
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
- ASSERT( lCount >= 0);
+ AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
- if( lCount == 0 &&
- pDirEntry->NameArrayReferenceCount <= 0)
- {
+ lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
+ "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+ &pDirEntry->NameInformation.FileName,
pDirEntry,
- pCurrentObject,
- &pDirEntry->NameInformation.FileName));
+ NULL,
+ lCount));
- //
- // Remove and delete the directory entry from the parent list
- //
+ ASSERT( lCount >= 0);
- AFSDeleteDirEntry( pParentObjectInfo,
- &pDirEntry);
+ if( lCount == 0 &&
+ pDirEntry->NameArrayReferenceCount <= 0)
+ {
- AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
- TRUE);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
+ pDirEntry,
+ pCurrentObject,
+ &pDirEntry->NameInformation.FileName));
- if( pCurrentObject->ObjectReferenceCount <= 0)
- {
+ //
+ // Remove and delete the directory entry from the parent list
+ //
- if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
+ AFSDeleteDirEntry( pParentObjectInfo,
+ &pDirEntry);
+
+ AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ if( pCurrentObject->ObjectReferenceCount <= 0)
{
- AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Removing object %p from volume tree\n",
- pCurrentObject));
+ if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
+ {
- AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
- &pCurrentObject->TreeEntry);
+ AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry Removing object %p from volume tree\n",
+ pCurrentObject));
- ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
+ AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
+ &pCurrentObject->TreeEntry);
+
+ ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
+ }
}
+
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
}
+ else
+ {
- AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- }
- else
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
+ pDirEntry,
+ &pDirEntry->NameInformation.FileName));
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
- pDirEntry,
- &pDirEntry->NameInformation.FileName));
+ SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
- SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
+ AFSRemoveNameEntry( pParentObjectInfo,
+ pDirEntry);
+ }
- AFSRemoveNameEntry( pParentObjectInfo,
- pDirEntry);
- }
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
- AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
- AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
+ //
+ // We deleted the dir entry so check if there is any remaining portion
+ // of the name to process.
+ //
- AFSReleaseObjectInfo( &pParentObjectInfo);
+ if( uniRemainingPath.Length > 0)
+ {
- //
- // We deleted the dir entry so check if there is any remaining portion
- // of the name to process.
- //
+ ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
- if( uniRemainingPath.Length > 0)
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
+ FileObject,
+ &uniComponentName,
+ pParentObjectInfo->FileId.Cell,
+ pParentObjectInfo->FileId.Volume,
+ pParentObjectInfo->FileId.Vnode,
+ pParentObjectInfo->FileId.Unique));
- ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
+ AFSReleaseObjectInfo( &pParentObjectInfo);
+ }
+ else
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
- FileObject,
- &uniComponentName,
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique));
- }
- else
- {
+ ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
- ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
+ FileObject,
+ &uniComponentName,
+ pParentObjectInfo->FileId.Cell,
+ pParentObjectInfo->FileId.Volume,
+ pParentObjectInfo->FileId.Vnode,
+ pParentObjectInfo->FileId.Unique));
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
- FileObject,
- &uniComponentName,
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique));
+ AFSReleaseObjectInfo( &pParentObjectInfo);
- //
- // Pass back the directory entries
- //
+ //
+ // Pass back the directory entries
+ //
- *OutParentDirectoryCB = pParentDirEntry;
+ *OutParentDirectoryCB = pParentDirEntry;
- pParentDirEntry = NULL;
+ pParentDirEntry = NULL;
- *OutDirectoryCB = NULL;
+ *OutDirectoryCB = NULL;
- *OutVolumeCB = pCurrentVolume;
+ *OutVolumeCB = pCurrentVolume;
- *OutVolumeReferenceReason = VolumeReferenceReason;
+ *OutVolumeReferenceReason = VolumeReferenceReason;
- bReleaseCurrentVolume = FALSE;
+ bReleaseCurrentVolume = FALSE;
- if( ComponentName != NULL)
- {
+ if( ComponentName != NULL)
+ {
- *ComponentName = uniComponentName;
- }
+ *ComponentName = uniComponentName;
+ }
- *RootPathName = uniFullPathName;
+ *RootPathName = uniFullPathName;
+ }
}
}
ParentObjectInfo->FileId.Unique));
ntStatus = AFSVerifyEntry( AuthGroup,
- ParentDirCB);
+ ParentDirCB,
+ FALSE);
if( !NT_SUCCESS( ntStatus))
{
AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSDeletepDirEntry Deleting dir entry in parent %p Entry %p object %p %wZ RefCount %d\n",
+ "AFSDeleteDirEntry Deleting dir entry in parent %p Entry %p object %p %wZ RefCount %d\n",
ParentObjectInfo,
pDirEntry,
pDirEntry->ObjectInformation,
// Dereference the object for this dir entry
//
+ AFSAcquireShared( pDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoDecrement( pDirEntry->ObjectInformation,
AFS_OBJECT_REFERENCE_DIRENTRY);
AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSDeletepDirEntry Decrement count on object %p Cnt %d\n",
+ "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
pDirEntry->ObjectInformation,
lCount));
+
+ AFSReleaseResource( pDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
}
ExDeleteResourceLite( &pDirEntry->NonPaged->Lock);
AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSDeletepDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
+ "AFSDeleteDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
pDirEntry));
AFSExFreePoolWithTag( pDirEntry, AFS_DIR_ENTRY_TAG);
return ntStatus;
}
-NTSTATUS
-AFSParseName( IN PIRP Irp,
- IN GUID *AuthGroup,
- OUT PUNICODE_STRING FileName,
- OUT PUNICODE_STRING ParsedFileName,
- OUT PUNICODE_STRING RootFileName,
- OUT ULONG *ParseFlags,
- OUT AFSVolumeCB **VolumeCB,
- OUT AFSDirectoryCB **ParentDirectoryCB,
- OUT AFSNameArrayHdr **NameArray)
+static NTSTATUS
+AFSParseRelatedName( IN PIRP Irp,
+ IN GUID *AuthGroup,
+ OUT PUNICODE_STRING FileName,
+ OUT PUNICODE_STRING ParsedFileName,
+ OUT PUNICODE_STRING RootFileName,
+ OUT ULONG *ParseFlags,
+ OUT AFSVolumeCB **VolumeCB,
+ OUT AFSDirectoryCB **ParentDirectoryCB,
+ OUT AFSNameArrayHdr **NameArray)
{
-
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
- UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
- ULONG ulCRC = 0;
- AFSDirectoryCB *pDirEntry = NULL;
- USHORT usIndex = 0, usDriveIndex = 0;
AFSCcb *pRelatedCcb = NULL;
- AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
+ AFSFcb *pRelatedFcb = NULL;
+ AFSNameArrayHdr *pRelatedNameArray = NULL;
+ UNICODE_STRING uniFullName;
+ AFSDirectoryCB *pDirEntry = NULL;
+ AFSNameArrayHdr *pNameArray = NULL;
USHORT usComponentIndex = 0;
USHORT usComponentLength = 0;
AFSVolumeCB *pVolumeCB = NULL;
- AFSFcb *pRelatedFcb = NULL;
- BOOLEAN bReleaseTreeLock = FALSE;
- BOOLEAN bIsAllShare = FALSE;
- LONG lCount;
+ LONG lCount;
- __Enter
- {
+ __Enter
+ {
- //
- // Indicate we are opening a root ...
- //
+ pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
- *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
+ pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
- *ParentDirectoryCB = NULL;
+ pRelatedNameArray = pRelatedCcb->NameArray;
- if( pIrpSp->FileObject->RelatedFileObject != NULL)
- {
+ uniFullName = pIrpSp->FileObject->FileName;
- pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
+ ASSERT( pRelatedFcb != NULL);
- pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
+ //
+ // On error, FileName indicates the path on which the failure occurred.
+ //
- pRelatedNameArray = pRelatedCcb->NameArray;
+ *FileName = pRelatedCcb->FullFileName;
- uniFullName = pIrpSp->FileObject->FileName;
+ //
+ // No wild cards in the name
+ //
- ASSERT( pRelatedFcb != NULL);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE_2,
+ "AFSParseRelatedName (%p) %wZ FID %08lX-%08lX-%08lX-%08lX %wZ\n",
+ Irp,
+ &pRelatedCcb->DirectoryCB->NameInformation.FileName,
+ pRelatedFcb->ObjectInformation->FileId.Cell,
+ pRelatedFcb->ObjectInformation->FileId.Volume,
+ pRelatedFcb->ObjectInformation->FileId.Vnode,
+ pRelatedFcb->ObjectInformation->FileId.Unique,
+ &pRelatedCcb->FullFileName));
- //
- // No wild cards in the name
- //
+ if( FsRtlDoesNameContainWildCards( &pRelatedCcb->FullFileName))
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE_2,
- "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
- Irp,
- &pRelatedCcb->DirectoryCB->NameInformation.FileName,
- pRelatedFcb->ObjectInformation->FileId.Cell,
- pRelatedFcb->ObjectInformation->FileId.Volume,
- pRelatedFcb->ObjectInformation->FileId.Vnode,
- pRelatedFcb->ObjectInformation->FileId.Unique,
- &uniFullName));
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSParseNameRelated (%p) Component %wZ contains wild cards\n",
+ Irp,
+ &pRelatedCcb->FullFileName));
- if( FsRtlDoesNameContainWildCards( &uniFullName))
- {
+ try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
+ }
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSParseName (%p) Component %wZ contains wild cards\n",
- Irp,
- &uniFullName));
+ pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
- try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
- }
+ pDirEntry = pRelatedCcb->DirectoryCB;
- pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
+ //
+ // Grab the root node while checking state
+ //
- pDirEntry = pRelatedCcb->DirectoryCB;
+ AFSAcquireShared( pVolumeCB->VolumeLock,
+ TRUE);
- *FileName = pIrpSp->FileObject->FileName;
+ if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
+ BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
+ {
- //
- // Grab the root node while checking state
- //
+ //
+ // The volume has been taken off line so fail the access
+ //
- AFSAcquireShared( pVolumeCB->VolumeLock,
- TRUE);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSParseNameRelated (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
+ Irp,
+ pVolumeCB->ObjectInformation.FileId.Cell,
+ pVolumeCB->ObjectInformation.FileId.Volume));
- if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
- BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
- {
+ AFSReleaseResource( pVolumeCB->VolumeLock);
- //
- // The volume has been taken off line so fail the access
- //
+ try_return( ntStatus = STATUS_DEVICE_NOT_READY);
+ }
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
- Irp,
- pVolumeCB->ObjectInformation.FileId.Cell,
- pVolumeCB->ObjectInformation.FileId.Volume));
+ if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Verifying root of volume %08lX:%08lX\n",
+ Irp,
+ pVolumeCB->ObjectInformation.FileId.Cell,
+ pVolumeCB->ObjectInformation.FileId.Volume));
- try_return( ntStatus = STATUS_DEVICE_NOT_READY);
- }
+ ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
+ pVolumeCB);
- if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
- {
+ if( !NT_SUCCESS( ntStatus))
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
- Irp,
- pVolumeCB->ObjectInformation.FileId.Cell,
- pVolumeCB->ObjectInformation.FileId.Volume));
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSParseNameRelated (%p) Failed verification of root Status %08lX\n",
+ Irp,
+ ntStatus));
- ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
- pVolumeCB);
+ AFSReleaseResource( pVolumeCB->VolumeLock);
- if( !NT_SUCCESS( ntStatus))
- {
+ try_return( ntStatus);
+ }
+ }
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSParseName (%p) Failed verification of root Status %08lX\n",
- Irp,
- ntStatus));
+ AFSReleaseResource( pVolumeCB->VolumeLock);
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
- try_return( ntStatus);
- }
- }
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry->ObjectInformation->FileId.Cell,
+ pDirEntry->ObjectInformation->FileId.Volume,
+ pDirEntry->ObjectInformation->FileId.Vnode,
+ pDirEntry->ObjectInformation->FileId.Unique));
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ //
+ // Directory TreeLock should be exclusively held
+ //
- if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
- {
+ AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
- Irp,
- &pDirEntry->NameInformation.FileName,
- pDirEntry->ObjectInformation->FileId.Cell,
- pDirEntry->ObjectInformation->FileId.Volume,
- pDirEntry->ObjectInformation->FileId.Vnode,
- pDirEntry->ObjectInformation->FileId.Unique));
+ ntStatus = AFSVerifyEntry( AuthGroup,
+ pDirEntry,
+ FALSE);
- //
- // Directory TreeLock should be exclusively held
- //
+ AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
- AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
+ if( !NT_SUCCESS( ntStatus))
+ {
- ntStatus = AFSVerifyEntry( AuthGroup,
- pDirEntry);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry->ObjectInformation->FileId.Cell,
+ pDirEntry->ObjectInformation->FileId.Volume,
+ pDirEntry->ObjectInformation->FileId.Vnode,
+ pDirEntry->ObjectInformation->FileId.Unique,
+ ntStatus));
- AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ try_return( ntStatus);
+ }
+ }
- if( !NT_SUCCESS( ntStatus))
- {
+ //
+ // Create our full path name buffer
+ //
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
- Irp,
- &pDirEntry->NameInformation.FileName,
- pDirEntry->ObjectInformation->FileId.Cell,
- pDirEntry->ObjectInformation->FileId.Volume,
- pDirEntry->ObjectInformation->FileId.Vnode,
- pDirEntry->ObjectInformation->FileId.Unique,
- ntStatus));
+ uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length
+ + sizeof( WCHAR) + pIrpSp->FileObject->FileName.Length
+ + sizeof( WCHAR);
- try_return( ntStatus);
- }
- }
+ uniFullName.Length = 0;
- //
- // Create our full path name buffer
- //
+ uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+ uniFullName.MaximumLength,
+ AFS_NAME_BUFFER_THREE_TAG);
- uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
- sizeof( WCHAR) +
- pIrpSp->FileObject->FileName.Length +
- sizeof( WCHAR);
+ if( uniFullName.Buffer == NULL)
+ {
- uniFullName.Length = 0;
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSParseNameRelated (%p) Failed to allocate full name buffer\n",
+ Irp));
- uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
- uniFullName.MaximumLength,
- AFS_NAME_BUFFER_THREE_TAG);
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
- if( uniFullName.Buffer == NULL)
- {
+ SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSParseName (%p) Failed to allocate full name buffer\n",
- Irp));
+ RtlZeroMemory( uniFullName.Buffer,
+ uniFullName.MaximumLength);
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ RtlCopyMemory( uniFullName.Buffer,
+ pRelatedCcb->FullFileName.Buffer,
+ pRelatedCcb->FullFileName.Length);
- RtlZeroMemory( uniFullName.Buffer,
- uniFullName.MaximumLength);
+ uniFullName.Length = pRelatedCcb->FullFileName.Length;
- RtlCopyMemory( uniFullName.Buffer,
- pRelatedCcb->FullFileName.Buffer,
- pRelatedCcb->FullFileName.Length);
+ usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
- uniFullName.Length = pRelatedCcb->FullFileName.Length;
+ usComponentLength = pIrpSp->FileObject->FileName.Length;
- usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
+ if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
+ pIrpSp->FileObject->FileName.Length > 0 &&
+ pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
+ pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
+ {
- usComponentLength = pIrpSp->FileObject->FileName.Length;
+ uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
- if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
- pIrpSp->FileObject->FileName.Length > 0 &&
- pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
- pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
- {
+ uniFullName.Length += sizeof( WCHAR);
- uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
+ usComponentLength += sizeof( WCHAR);
+ }
- uniFullName.Length += sizeof( WCHAR);
+ if( pIrpSp->FileObject->FileName.Length > 0)
+ {
- usComponentLength += sizeof( WCHAR);
- }
+ RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
+ pIrpSp->FileObject->FileName.Buffer,
+ pIrpSp->FileObject->FileName.Length);
- if( pIrpSp->FileObject->FileName.Length > 0)
- {
+ uniFullName.Length += pIrpSp->FileObject->FileName.Length;
+ }
- RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
- pIrpSp->FileObject->FileName.Buffer,
- pIrpSp->FileObject->FileName.Length);
+ *RootFileName = uniFullName;
- uniFullName.Length += pIrpSp->FileObject->FileName.Length;
- }
+ //
+ // We populate up to the current parent
+ //
- *RootFileName = uniFullName;
+ if( pRelatedNameArray == NULL)
+ {
- //
- // We populate up to the current parent
- //
+ //
+ // Init and populate our name array
+ //
- if( pRelatedNameArray == NULL)
- {
+ pNameArray = AFSInitNameArray( NULL,
+ 0);
- //
- // Init and populate our name array
- //
+ if( pNameArray == NULL)
+ {
- pNameArray = AFSInitNameArray( NULL,
- 0);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Failed to initialize name array\n",
+ Irp));
- if( pNameArray == NULL)
- {
+ AFSExFreePoolWithTag( uniFullName.Buffer, 0);
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Failed to initialize name array\n",
- Irp));
+ ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
- AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ ntStatus = AFSPopulateNameArray( pNameArray,
+ NULL,
+ pRelatedCcb->DirectoryCB);
+ }
+ else
+ {
- ntStatus = AFSPopulateNameArray( pNameArray,
- NULL,
- pRelatedCcb->DirectoryCB);
- }
- else
- {
+ //
+ // Init and populate our name array
+ //
- //
- // Init and populate our name array
- //
+ pNameArray = AFSInitNameArray( NULL,
+ pRelatedNameArray->MaxElementCount);
- pNameArray = AFSInitNameArray( NULL,
- pRelatedNameArray->MaxElementCount);
+ if( pNameArray == NULL)
+ {
- if( pNameArray == NULL)
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Failed to initialize name array\n",
+ Irp));
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Failed to initialize name array\n",
- Irp));
+ AFSExFreePoolWithTag( uniFullName.Buffer, 0);
- AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+ ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
- ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
- pRelatedNameArray,
- pRelatedCcb->DirectoryCB);
- }
+ ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
+ pRelatedNameArray,
+ pRelatedCcb->DirectoryCB);
+ }
- if( !NT_SUCCESS( ntStatus))
- {
+ if( !NT_SUCCESS( ntStatus))
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName (%p) Failed to populate name array\n",
- Irp));
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated (%p) Failed to populate name array\n",
+ Irp));
- AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+ AFSExFreePoolWithTag( uniFullName.Buffer, 0);
- try_return( ntStatus);
- }
+ ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
- ParsedFileName->Length = usComponentLength;
- ParsedFileName->MaximumLength = uniFullName.MaximumLength;
+ try_return( ntStatus);
+ }
- ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
+ ParsedFileName->Length = usComponentLength;
- //
- // Indicate to caller that RootFileName must be freed
- //
+ ParsedFileName->MaximumLength = uniFullName.MaximumLength;
- SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
+ ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
- *NameArray = pNameArray;
+ *NameArray = pNameArray;
- //
- // Increment our volume reference count
- //
+ //
+ // Increment our volume reference count
+ //
- lCount = AFSVolumeIncrement( pVolumeCB,
- AFS_VOLUME_REFERENCE_PARSE_NAME);
+ lCount = AFSVolumeIncrement( pVolumeCB,
+ AFS_VOLUME_REFERENCE_PARSE_NAME);
- AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSParseName Increment count on volume %p Cnt %d\n",
- pVolumeCB,
- lCount));
+ AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseNameRelated Increment count on volume %p Cnt %d\n",
+ pVolumeCB,
+ lCount));
- *VolumeCB = pVolumeCB;
+ *VolumeCB = pVolumeCB;
- *ParentDirectoryCB = pDirEntry;
+ *ParentDirectoryCB = pDirEntry;
- AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE_2,
- "AFSParseName (%p) Returning full name %wZ\n",
- Irp,
- &uniFullName));
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE_2,
+ "AFSParseNameRelated (%p) Returning full name %wZ\n",
+ Irp,
+ &uniFullName));
- try_return( ntStatus);
+ try_return( ntStatus);
+
+try_exit:
+
+ if( NT_SUCCESS( ntStatus))
+ {
+
+ if( *ParentDirectoryCB != NULL)
+ {
+
+ lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSParseRelatedName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+ &(*ParentDirectoryCB)->NameInformation.FileName,
+ (*ParentDirectoryCB),
+ NULL,
+ lCount));
+ }
+ }
+
+ if( *VolumeCB != NULL)
+ {
+ ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
+ }
+
+ if( ntStatus != STATUS_SUCCESS)
+ {
+
+ if( pNameArray != NULL)
+ {
+
+ AFSFreeNameArray( pNameArray);
+ }
+ }
+ }
+
+ return ntStatus;
+}
+
+NTSTATUS
+AFSParseName( IN PIRP Irp,
+ IN GUID *AuthGroup,
+ OUT PUNICODE_STRING FileName,
+ OUT PUNICODE_STRING ParsedFileName,
+ OUT PUNICODE_STRING RootFileName,
+ OUT ULONG *ParseFlags,
+ OUT AFSVolumeCB **VolumeCB,
+ OUT AFSDirectoryCB **ParentDirectoryCB,
+ OUT AFSNameArrayHdr **NameArray)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+ AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+ UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
+ ULONG ulCRC = 0;
+ AFSDirectoryCB *pDirEntry = NULL;
+ USHORT usIndex = 0, usDriveIndex = 0;
+ AFSNameArrayHdr *pNameArray = NULL;
+ USHORT usComponentIndex = 0;
+ USHORT usComponentLength = 0;
+ AFSVolumeCB *pVolumeCB = NULL;
+ BOOLEAN bReleaseTreeLock = FALSE;
+ BOOLEAN bIsAllShare = FALSE;
+ LONG lCount;
+
+ __Enter
+ {
+
+ if( pIrpSp->FileObject->RelatedFileObject != NULL)
+ {
+
+ return AFSParseRelatedName( Irp, AuthGroup, FileName,
+ ParsedFileName, RootFileName,
+ ParseFlags, VolumeCB,
+ ParentDirectoryCB, NameArray);
}
- //
- // No wild cards in the name
- //
+ //
+ // Indicate we are opening a root ...
+ //
+
+ *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
+
+ *ParentDirectoryCB = NULL;
+
+ //
+ // On error, FileName indicates the path on which the failure occurred
+ //
+
+ *FileName = pIrpSp->FileObject->FileName;
+
+ //
+ // No wild cards in the name
+ //
uniFullName = pIrpSp->FileObject->FileName;
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)
+ {
+
+ //
+ // original FileObject buffer was not allocated by AFS
+ //
- AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+ ExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+ }
+
+ FileObject->FileName = uniReparseName;
}
+ else
+ {
- FileObject->FileName = uniReparseName;
+ *TargetName = uniReparseName;
+ }
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
return ntStatus;
}
+
+NTSTATUS
+AFSGetFullFileName( IN AFSFcb *Fcb,
+ IN AFSCcb *Ccb,
+ OUT ULONG *FileNameLength,
+ OUT WCHAR *FileName,
+ IN OUT LONG *RemainingLength)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ ULONG ulCopyLength = 0;
+ ULONG cchCopied = 0;
+ BOOLEAN bAddTrailingSlash = FALSE;
+ USHORT usFullNameLength = 0;
+
+ __Enter
+ {
+
+ //
+ // Add a trailing slash for anything which is of the form \server\share
+ //
+
+ if( ( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY ||
+ Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT) &&
+ Ccb->FullFileName.Length > sizeof( WCHAR) &&
+ Ccb->FullFileName.Buffer[ (Ccb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
+ AFSIsShareName( &Ccb->FullFileName))
+ {
+ bAddTrailingSlash = TRUE;
+ }
+
+ usFullNameLength = sizeof( WCHAR) +
+ AFSServerName.Length +
+ Ccb->FullFileName.Length;
+
+ if( bAddTrailingSlash)
+ {
+ usFullNameLength += sizeof( WCHAR);
+ }
+
+ if( *RemainingLength >= (LONG)usFullNameLength)
+ {
+ ulCopyLength = (LONG)usFullNameLength;
+ }
+ else
+ {
+
+ ulCopyLength = *RemainingLength;
+
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+
+ *FileNameLength = (ULONG)usFullNameLength;
+
+ if( ulCopyLength > 0)
+ {
+
+ FileName[ 0] = L'\\';
+ ulCopyLength -= sizeof( WCHAR);
+
+ *RemainingLength -= sizeof( WCHAR);
+ cchCopied += 1;
+
+ if( ulCopyLength >= AFSServerName.Length)
+ {
+
+ RtlCopyMemory( &FileName[ 1],
+ AFSServerName.Buffer,
+ AFSServerName.Length);
+
+ ulCopyLength -= AFSServerName.Length;
+ *RemainingLength -= AFSServerName.Length;
+ cchCopied += AFSServerName.Length/sizeof( WCHAR);
+
+ if( ulCopyLength >= Ccb->FullFileName.Length)
+ {
+
+ RtlCopyMemory( &FileName[ cchCopied],
+ Ccb->FullFileName.Buffer,
+ Ccb->FullFileName.Length);
+
+ ulCopyLength -= Ccb->FullFileName.Length;
+ *RemainingLength -= Ccb->FullFileName.Length;
+ cchCopied += Ccb->FullFileName.Length/sizeof( WCHAR);
+
+ if( ulCopyLength > 0 &&
+ bAddTrailingSlash)
+ {
+ FileName[ cchCopied] = L'\\';
+
+ *RemainingLength -= sizeof( WCHAR);
+ }
+ }
+ else
+ {
+
+ RtlCopyMemory( &FileName[ cchCopied],
+ Ccb->FullFileName.Buffer,
+ ulCopyLength);
+
+ *RemainingLength -= ulCopyLength;
+ }
+ }
+ }
+ }
+
+ return ntStatus;
+}