ULONG ulParseFlags = 0;
GUID stAuthGroup;
ULONG ulNameProcessingFlags = 0;
+ BOOLEAN bOpenedReparsePoint = FALSE;
__Enter
{
}
//
- // We have our root node shared
+ // We have a reference on the root volume
//
bReleaseVolume = TRUE;
try_return( ntStatus);
}
- if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT) &&
- pDirectoryCB != NULL &&
- !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
+ if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ Type %08lX\n",
- Irp,
- &uniFileName,
- pDirectoryCB->ObjectInformation->FileType);
+ if( pDirectoryCB == NULL ||
+ !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
+ Irp,
+ &uniFileName,
+ pDirectoryCB,
+ pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
+ }
+ else
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
+ Irp,
+ &uniFileName,
+ pDirectoryCB->ObjectInformation->FileType);
+
+ bOpenedReparsePoint = TRUE;
+ }
}
//
// fail with collision
//
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
- &pDirectoryCB->NameInformation.FileName,
- ntStatus);
-
if( pDirectoryCB != NULL)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
+ &pDirectoryCB->NameInformation.FileName,
+ ntStatus);
+
InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
else
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCommonCreate Object name collision on create Status %08lX\n",
+ ntStatus);
+
InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
&pParentDirectoryCB->NameInformation.FileName,
ntStatus);
}
- else
- {
-
- //
- // Reference the new dir entry
- //
-
- InterlockedIncrement( &pCcb->DirectoryCB->OpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCreate Increment (Create) count on %wZ DE %p Ccb %p Cnt %d\n",
- &pCcb->DirectoryCB->NameInformation.FileName,
- pCcb->DirectoryCB,
- pCcb,
- pCcb->DirectoryCB->OpenReferenceCount);
- }
//
// Dereference the parent entry
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSCommonCreate Failed to open root (2) Status %08lX\n",
+ "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
+ pVolumeCB->ObjectInformation.FileId.Cell,
+ pVolumeCB->ObjectInformation.FileId.Volume,
ntStatus);
InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
if( pCcb != NULL)
{
+ RtlCopyMemory( &pCcb->AuthGroup,
+ &stAuthGroup,
+ sizeof( GUID));
+
//
// If we have a substitute name, then use it
//
}
}
+ if( bOpenedReparsePoint)
+ {
+ SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
- RtlCopyMemory( &pFcb->AuthGroup,
- &stAuthGroup,
- sizeof( GUID));
-
//
// For files perform additional processing
//
//
KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
+
+ if( pCcb != NULL)
+ {
+ AFSInsertCcb( pFcb,
+ pCcb);
+ }
}
else
{
"AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
pVolumeCB,
pVolumeCB->VolumeReferenceCount);
-
- AFSReleaseResource( pVolumeCB->VolumeLock);
}
//
if( !NT_SUCCESS( ntStatus))
{
+ UNICODE_STRING uniGUID;
+
+ uniGUID.Length = 0;
+ uniGUID.MaximumLength = 0;
+ uniGUID.Buffer = NULL;
+
+ if( AuthGroup != NULL)
+ {
+ RtlStringFromGUID( *AuthGroup,
+ &uniGUID);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSOpenRoot (%08lX) Failed to open file in service Status %08lX\n",
+ "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
Irp,
+ VolumeCB->ObjectInformation.FileId.Cell,
+ VolumeCB->ObjectInformation.FileId.Volume,
+ &uniGUID,
ntStatus);
+ if( AuthGroup != NULL)
+ {
+ RtlFreeUnicodeString( &uniGUID);
+ }
+
try_return( ntStatus);
}
(*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
+ (*Ccb)->GrantedAccess = *pDesiredAccess;
+
//
// OK, update the share access on the fileobject
//
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
*Ccb = NULL;
}
"AFSProcessCreate Request failed due to read only volume %wZ\n",
FullFileName);
- try_return( ntStatus = STATUS_ACCESS_DENIED);
+ try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
}
pParentObjectInfo = ParentDirCB->ObjectInformation;
pObjectInfo = pDirEntry->ObjectInformation;
+ if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
+ pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique);
+
+ ntStatus = AFSEvaluateNode( AuthGroup,
+ pDirEntry);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique,
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+
+ ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
+ }
+
//
// We may have raced and the Fcb is already created
//
(*Ccb)->DirectoryCB = pDirEntry;
+ (*Ccb)->GrantedAccess = *pDesiredAccess;
+
//
// If this is a file, update the headers filesizes.
//
AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
*Ccb,
- (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
- (ULONG)FILE_ACTION_ADDED);
+ (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+ (ULONG)FILE_ACTION_ADDED);
(*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
}
AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
*Ccb,
- (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
- (ULONG)FILE_ACTION_ADDED);
+ (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
+ (ULONG)FILE_ACTION_ADDED);
}
else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
(*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
- (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
+ (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
+ (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
{
//
AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
*Ccb,
- (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
- (ULONG)FILE_ACTION_ADDED);
+ (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
+ (ULONG)FILE_ACTION_ADDED);
}
//
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
- *Fcb,
- (*Fcb)->OpenReferenceCount);
+ *Fcb,
+ (*Fcb)->OpenReferenceCount);
InterlockedIncrement( &(*Fcb)->OpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
- (*Fcb),
- (*Fcb)->OpenHandleCount);
+ (*Fcb),
+ (*Fcb)->OpenHandleCount);
//
// Increment the open reference and handle on the parent node
if( bFileCreated)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
+ pDirEntry,
+ pParentObjectInfo,
+ ntStatus);
+
//
// Remove the dir entry from the parent
//
AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
- AFSDeleteDirEntry( pParentObjectInfo,
- pDirEntry);
+ SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
+
+ //
+ // Decrement the reference added during initialization of the DE
+ //
+
+ InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry,
+ pDirEntry->OpenReferenceCount);
+
+ //
+ // Pull the directory entry from the parent
+ //
+
+ AFSRemoveDirNodeFromParent( pParentObjectInfo,
+ pDirEntry,
+ FALSE); // Leave it in the enum list so the worker cleans it up
+
+ AFSNotifyDelete( pDirEntry,
+ AuthGroup,
+ FALSE);
+
+ //
+ // Tag the parent as needing verification
+ //
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
}
if( bAllocatedFcb)
(*Ccb)->DirectoryCB = ParentDirectoryCB;
+ (*Ccb)->GrantedAccess = *pDesiredAccess;
+
if( TargetDirectoryCB != NULL &&
FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
TargetName,
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
}
*Ccb = NULL;
ULONG ulResultLen = 0;
AFSObjectInfoCB *pParentObjectInfo = NULL;
AFSObjectInfoCB *pObjectInfo = NULL;
+ ULONG ulFileAccess = 0;
+ AFSFileAccessReleaseCB stReleaseFileAccess;
__Enter
{
{
ntStatus = AFSNotifyDelete( DirectoryCB,
+ AuthGroup,
TRUE);
if( !NT_SUCCESS( ntStatus))
}
else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
- pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
+ pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
+ pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
{
}
stOpenCB.ShareAccess = usShareAccess;
+ stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
+
+ stOpenCB.Identifier = (ULONGLONG)pFileObject;
+
stOpenResultCB.GrantedAccess = 0;
ulResultLen = sizeof( AFSFileOpenResultCB);
}
//
+ // Save the granted access in case we need to release it below
+ //
+
+ ulFileAccess = stOpenResultCB.FileAccess;
+
+ //
// Check if there is a conflict
//
(*Ccb)->DirectoryCB = DirectoryCB;
+ (*Ccb)->FileAccess = ulFileAccess;
+
+ (*Ccb)->GrantedAccess = *pDesiredAccess;
+
//
// Perform the access check on the target if this is a mount point or symlink
//
if( !NT_SUCCESS( ntStatus))
{
+ if ( ulFileAccess > 0)
+ {
+
+ stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
+
+ stReleaseFileAccess.FileAccess = ulFileAccess;
+
+ stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
+
+ AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
+ AFS_REQUEST_FLAG_SYNCHRONOUS,
+ AuthGroup,
+ &DirectoryCB->NameInformation.FileName,
+ &pObjectInfo->FileId,
+ (void *)&stReleaseFileAccess,
+ sizeof( AFSFileAccessReleaseCB),
+ NULL,
+ NULL);
+ }
+
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
}
*Ccb = NULL;
Irp,
&DirectoryCB->NameInformation.FileName);
- try_return( ntStatus = STATUS_ACCESS_DENIED);
+ try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
}
pParentObjectInfo = ParentDirCB->ObjectInformation;
(*Ccb)->DirectoryCB = DirectoryCB;
+ (*Ccb)->GrantedAccess = *pDesiredAccess;
+
//
// Need to purge any data currently in the cache
//
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
}
*Ccb = NULL;
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
*Ccb = NULL;
}
if( bAllocatedCcb)
{
- AFSRemoveCcb( *Ccb);
+ AFSRemoveCcb( NULL,
+ *Ccb);
*Ccb = NULL;
}