Esempio n. 1
0
FORCEINLINE
NTSTATUS
QueueingSecondaryRequest(
	IN	PSECONDARY			Secondary,
	IN	PSECONDARY_REQUEST	SecondaryRequest
	)
{
	NTSTATUS	status;


	ASSERT( SecondaryRequest->ListEntry.Flink == SecondaryRequest->ListEntry.Blink );

	if (SecondaryRequest->RequestType == SECONDARY_REQ_SEND_MESSAGE)
		ASSERT( FlagOn(Secondary->Flags, SECONDARY_FLAG_RECONNECTING) || ExIsResourceAcquiredExclusiveLite(&Secondary->SessionResource) );

	ExAcquireFastMutex( &Secondary->FastMutex );

	if (FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) &&
		!FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) {

		ExInterlockedInsertTailList( &Secondary->RequestQueue,
									 &SecondaryRequest->ListEntry,
									 &Secondary->RequestQSpinLock );

		KeSetEvent( &Secondary->RequestEvent, IO_DISK_INCREMENT, FALSE );
		status = STATUS_SUCCESS;

	} else {

		status = STATUS_UNSUCCESSFUL;
	}

	ExReleaseFastMutex( &Secondary->FastMutex );

	if (status == STATUS_UNSUCCESSFUL) {
	
		SecondaryRequest->ExecuteStatus = STATUS_IO_DEVICE_ERROR;

		if (SecondaryRequest->Synchronous == TRUE)
			KeSetEvent( &SecondaryRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
		else
			DereferenceSecondaryRequest( SecondaryRequest );
	}

	return status;
}
NTSTATUS
SecondaryRecoverySessionStart (
	IN  PSECONDARY		Secondary,
	IN  PIRP_CONTEXT	IrpContext
	)
{
	NTSTATUS			status;
	OBJECT_ATTRIBUTES	objectAttributes;
	LARGE_INTEGER		timeOut;

	if (Secondary->RecoveryThreadHandle)
		return STATUS_SUCCESS;

	ASSERT( ExIsResourceAcquiredExclusiveLite(&Secondary->VolDo->RecoveryResource) && 
			ExIsResourceAcquiredExclusiveLite(&Secondary->VolDo->Resource) );

	ASSERT( NtfsIsTopLevelRequest(IrpContext) || 
		NtfsIsTopLevelNtfs( IrpContext) && NtfsGetTopLevelContext()->SavedTopLevelIrp == (PIRP)FSRTL_FSP_TOP_LEVEL_IRP ||
			FlagOn(IrpContext->State, IRP_CONTEXT_STATE_IN_FSP) );

	if (IrpContext->OriginatingIrp)
		PrintIrp( Dbg2, "SecondaryRecoverySessionStart", NULL, IrpContext->OriginatingIrp );

	if (FlagOn(Secondary->VolDo->NdasNtfsFlags, NDAS_NTFS_DEVICE_FLAG_SHUTDOWN)) {

		//DebugTrace( 0, Dbg2, ("SecondaryToPrimary NDAS_NTFS_DEVICE_FLAG_SHUTDOWN\n") ); 
		//DbgPrint( "SecondaryToPrimary NDAS_NTFS_DEVICE_FLAG_SHUTDOWN\n" ); 

		NtfsRaiseStatus( IrpContext, STATUS_TOO_LATE, NULL, NULL );
	}

	InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

	status = PsCreateSystemThread( &Secondary->RecoveryThreadHandle,
								   THREAD_ALL_ACCESS,
								   &objectAttributes,
								   NULL,
								   NULL,
								   SecondaryRecoveryThreadProc,
								   Secondary );

	if (!NT_SUCCESS(status)) {
		
		return status;
	}

	timeOut.QuadPart = -NDASNTFS_TIME_OUT;		
	
	status = KeWaitForSingleObject( &Secondary->RecoveryReadyEvent,
									Executive,
									KernelMode,
									FALSE,
									&timeOut );

	if (status != STATUS_SUCCESS) {
	
		return status;
	}

	KeClearEvent( &Secondary->RecoveryReadyEvent );

	if (IrpContext->OriginatingIrp)
		PrintIrp( Dbg2, "SecondaryRecoverySessionStart returned", NULL, IrpContext->OriginatingIrp );

	return status;
}
NTSTATUS
SecondaryRecoverySession (
	IN  PSECONDARY		Secondary
	)
{
	NTSTATUS			status;
	LONG				slotIndex;

	LARGE_INTEGER		timeOut;
	OBJECT_ATTRIBUTES	objectAttributes;

	ULONG				reconnectionTry;
    PLIST_ENTRY			ccblistEntry;
	BOOLEAN				isLocalAddress;


	SetFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

	ASSERT( FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ); 
	ASSERT( Secondary->ThreadHandle );

	ASSERT( IsListEmpty(&Secondary->RequestQueue) );

	for (slotIndex=0; slotIndex < Secondary->Thread.SessionContext.SessionSlotCount; slotIndex++) {

		ASSERT( Secondary->Thread.SessionSlot[slotIndex] == NULL );
	}	

	if (Secondary->ThreadHandle) {

		ASSERT( Secondary->ThreadObject );
		
		timeOut.QuadPart = -NDASNTFS_TIME_OUT;
		status = KeWaitForSingleObject( Secondary->ThreadObject,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );

		if(status != STATUS_SUCCESS) {

			ASSERT( NDASNTFS_BUG );
			return status;
		}

		DebugTrace( 0, Dbg2, ("Secondary_Stop: thread stoped\n") );

		ObDereferenceObject( Secondary->ThreadObject );

		Secondary->ThreadHandle = 0;
		Secondary->ThreadObject = 0;

		RtlZeroMemory( &Secondary->Thread.Flags, sizeof(SECONDARY) - FIELD_OFFSET(SECONDARY, Thread.Flags) );
	}

	for (status = STATUS_UNSUCCESSFUL, reconnectionTry = 0; reconnectionTry < MAX_RECONNECTION_TRY; reconnectionTry++) {

		if (FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_TARGET_DEVICE_STOPPED)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_FLAG_SHUTDOWN)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (FlagOn(Secondary->VolDo->NdasNtfsFlags, NDAS_NTFS_DEVICE_FLAG_SHUTDOWN)) {

			//DebugTrace( 0, Dbg2, ("SecondaryToPrimary NDAS_NTFS_DEVICE_FLAG_SHUTDOWN\n") ); 
			//DbgPrint( "SecondaryToPrimary NDAS_NTFS_DEVICE_FLAG_SHUTDOWN\n" ); 

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (Secondary->VolDo->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY) {

			status = STATUS_SUCCESS;

		} else {

			status = ((PVOLUME_DEVICE_OBJECT) NdasNtfsFileSystemDeviceObject)->
						NdfsCallback.SecondaryToPrimary( Secondary->VolDo->Vcb.Vpb->RealDevice, TRUE );

			if (status == STATUS_NO_SUCH_DEVICE) {

				NDAS_ASSERT( FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_TARGET_DEVICE_STOPPED) );
				ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

				return STATUS_UNSUCCESSFUL;
			}
		}


		//NtfsDebugTraceLevel = 0;

		DebugTrace( 0, Dbg2, ("SecondaryToPrimary status = %x\n", status) ); 

		if (status == STATUS_SUCCESS) {

			PVCB				vcb = &Secondary->VolDo->Vcb;
			TOP_LEVEL_CONTEXT	topLevelContext;
			PTOP_LEVEL_CONTEXT	threadTopLevelContext;
			PIRP_CONTEXT		tempIrpContext = NULL;

			SetFlag( Secondary->Flags, SECONDARY_FLAG_CLEANUP_VOLUME );

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&NtfsData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&NtfsData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->Resource) );	


			DebugTrace( 0, Dbg2, ("Vcb->State = %X\n", vcb->VcbState) );
			DebugTrace( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );

			tempIrpContext = NULL;

			threadTopLevelContext = NtfsInitializeTopLevelIrp( &topLevelContext, TRUE, FALSE );
			ASSERT( threadTopLevelContext == &topLevelContext );

			NtfsInitializeIrpContext( NULL, TRUE, &tempIrpContext );
            NtfsUpdateIrpContextWithTopLevel( tempIrpContext, threadTopLevelContext );

			SetFlag( tempIrpContext->NdasNtfsFlags, NDAS_NTFS_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
			ASSERT( FlagOn(tempIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL) );
						
			tempIrpContext->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
			tempIrpContext->MinorFunction = IRP_MN_MOUNT_VOLUME;
			tempIrpContext->Vcb			  = vcb;

			try {
			
				status = CleanUpVcb( tempIrpContext, vcb );
			
			} finally {
                
				NtfsCompleteRequest( tempIrpContext, NULL, 0 );
				ASSERT( IoGetTopLevelIrp() != (PIRP) &topLevelContext );
				tempIrpContext = NULL;
			}

			ASSERT( status == STATUS_SUCCESS );
			ASSERT( FlagOn(vcb->VcbState, VCB_STATE_MOUNT_COMPLETED) );

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&NtfsData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&NtfsData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->Resource) );	

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_CLEANUP_VOLUME );


			DebugTrace( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );
			DebugTrace( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace( 0, Dbg2, ("Vcb->CloseCount = %d\n", vcb->CloseCount) );

			Secondary->VolDo->NetdiskEnableMode = NETDISK_SECONDARY2PRIMARY; 

			tempIrpContext = NULL;

			threadTopLevelContext = NtfsInitializeTopLevelIrp( &topLevelContext, TRUE, FALSE );
			ASSERT( threadTopLevelContext == &topLevelContext );

			NtfsInitializeIrpContext( NULL, TRUE, &tempIrpContext );
            NtfsUpdateIrpContextWithTopLevel( tempIrpContext, threadTopLevelContext );

			ASSERT( FlagOn(tempIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL) );
			
			//tempIrpContext->TopLevelIrpContext->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
			//tempIrpContext->TopLevelIrpContext->MinorFunction = IRP_MN_MOUNT_VOLUME;
			
			tempIrpContext->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
			tempIrpContext->MinorFunction = IRP_MN_MOUNT_VOLUME;
			tempIrpContext->Vcb			  = vcb;

			try {
			
				status = NdasNtfsMountVolume( tempIrpContext, vcb );
			
			} finally {
                
				NtfsCompleteRequest( tempIrpContext, NULL, 0 );
				ASSERT( IoGetTopLevelIrp() != (PIRP) &topLevelContext );
				tempIrpContext = NULL;
			}

			NDAS_ASSERT( status == STATUS_SUCCESS );

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&NtfsData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&NtfsData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->Resource) );	

			DebugTrace( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );
			DebugTrace( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace( 0, Dbg2, ("Vcb->CloseCount = %d\n", vcb->CloseCount) );

			if (vcb->MftScb) {
			
				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->MftScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->MftScb->Header.Resource) );	
			}

			if (vcb->Mft2Scb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->Mft2Scb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->Mft2Scb->Header.Resource) );	
			}

			if (vcb->LogFileScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->LogFileScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->LogFileScb->Header.Resource) );			
			}

			if (vcb->VolumeDasdScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->VolumeDasdScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->VolumeDasdScb->Header.Resource) );			
			}

			if (vcb->AttributeDefTableScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->AttributeDefTableScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->AttributeDefTableScb->Header.Resource) );			
			}

			if (vcb->UpcaseTableScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->UpcaseTableScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->UpcaseTableScb->Header.Resource) );			
			}

			if (vcb->RootIndexScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->RootIndexScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->RootIndexScb->Header.Resource) );			
			}

			if (vcb->BitmapScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->BitmapScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->BitmapScb->Header.Resource) );			
			}

			if (vcb->BadClusterFileScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->BadClusterFileScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->BadClusterFileScb->Header.Resource) );		
			}

			if (vcb->MftBitmapScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->MftBitmapScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->MftBitmapScb->Header.Resource) );			
			}

			if (vcb->SecurityDescriptorStream) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityDescriptorStream->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityDescriptorStream->Header.Resource) );			
			}

			if (vcb->UsnJournal) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->UsnJournal->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->UsnJournal->Header.Resource) );			
			}

			if (vcb->ExtendDirectory) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->ExtendDirectory->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->ExtendDirectory->Header.Resource) );			
			}

			if (vcb->SecurityDescriptorHashIndex) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityDescriptorHashIndex->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityDescriptorHashIndex->Header.Resource) );			
			}

			if (vcb->SecurityIdIndex) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityIdIndex->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityIdIndex->Header.Resource) );			
			}
		}

		Secondary->NumberOfPrimaryAddress = 0;

		status = ((PVOLUME_DEVICE_OBJECT) NdasNtfsFileSystemDeviceObject)->
						NdfsCallback.QueryPrimaryAddress( &Secondary->VolDo->NetdiskPartitionInformation, 
														  Secondary->PrimaryAddressList, 
														  &Secondary->NumberOfPrimaryAddress, 
														  &isLocalAddress );

		DebugTrace2( 0, Dbg2, ("RecoverySession: QueryPrimaryAddress status = %X\n", status) );

		if (status == STATUS_SUCCESS && !(Secondary->VolDo->NetdiskEnableMode == NETDISK_SECONDARY && isLocalAddress)) {

			LONG i;

			NDAS_ASSERT( Secondary->NumberOfPrimaryAddress );

			for (i = 0; i < Secondary->NumberOfPrimaryAddress; i++) {

				DebugTrace2( 0, Dbg, 
							   ("RecoverySession: Secondary = %p Found PrimaryAddress[%d] :%02x:%02x:%02x:%02x:%02x:%02x/%d\n",
							    Secondary, i,
								Secondary->PrimaryAddressList[i].Node[0], Secondary->PrimaryAddressList[i].Node[1],
								Secondary->PrimaryAddressList[i].Node[2], Secondary->PrimaryAddressList[i].Node[3],
								Secondary->PrimaryAddressList[i].Node[4], Secondary->PrimaryAddressList[i].Node[5],
								NTOHS(Secondary->PrimaryAddressList[i].Port)) );
			}
		
		} else {

			continue;
		}	

		KeInitializeEvent( &Secondary->ReadyEvent, NotificationEvent, FALSE );
		KeInitializeEvent( &Secondary->RequestEvent, NotificationEvent, FALSE );

		InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

		status = PsCreateSystemThread( &Secondary->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   SecondaryThreadProc,
									   Secondary );

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASNTFS_UNEXPECTED );
			break;
		}

		status = ObReferenceObjectByHandle( Secondary->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&Secondary->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASNTFS_INSUFFICIENT_RESOURCES );
			break;
		}

		timeOut.QuadPart = -NDASNTFS_TIME_OUT;
		status = KeWaitForSingleObject( &Secondary->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );

		if(status != STATUS_SUCCESS) {

			ASSERT( NDASNTFS_BUG );
			break;
		}

		KeClearEvent( &Secondary->ReadyEvent );

		InterlockedIncrement( &Secondary->SessionId );	

		ExAcquireFastMutex( &Secondary->FastMutex );

		if (!FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) || FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) {

			ExReleaseFastMutex( &Secondary->FastMutex );

			if(Secondary->Thread.SessionStatus == STATUS_DISK_CORRUPT_ERROR) {

				status = STATUS_SUCCESS;
				break;
			}

			timeOut.QuadPart = -NDASNTFS_TIME_OUT;
			status = KeWaitForSingleObject( Secondary->ThreadObject,
											Executive,
											KernelMode,
											FALSE,
											&timeOut );

			if(status != STATUS_SUCCESS) {

				ASSERT( NDASNTFS_BUG );
				return status;
			}

			DebugTrace( 0, Dbg, ("Secondary_Stop: thread stoped\n") );

			ObDereferenceObject( Secondary->ThreadObject );

			Secondary->ThreadHandle = 0;
			Secondary->ThreadObject = 0;

			RtlZeroMemory( &Secondary->Thread.Flags, sizeof(SECONDARY) - FIELD_OFFSET(SECONDARY, Thread.Flags) );

			continue;
		} 

		ExReleaseFastMutex( &Secondary->FastMutex );

		status = STATUS_SUCCESS;

		DebugTrace( 0, Dbg2, ("SessionRecovery Success Secondary = %p\n", Secondary) );

		break;
	}
Esempio n. 4
0
BOOL FASTCALL UserIsEnteredExclusive(VOID)
{
    return ExIsResourceAcquiredExclusiveLite(&UserLock);
}
Esempio n. 5
0
NTSTATUS
NdFatSecondaryCommonWrite (
	IN PIRP_CONTEXT IrpContext,
	IN PIRP			Irp
	)
{
	NTSTATUS					status;

	PVOLUME_DEVICE_OBJECT		volDo = CONTAINING_RECORD( IrpContext->Vcb, VOLUME_DEVICE_OBJECT, Vcb );
	BOOLEAN						secondarySessionResourceAcquired = FALSE;
	
	PIO_STACK_LOCATION			irpSp = IoGetCurrentIrpStackLocation( Irp );
	PFILE_OBJECT				fileObject = irpSp->FileObject;

	struct Write				write;
	
	PSECONDARY_REQUEST			secondaryRequest = NULL;
	PNDFS_REQUEST_HEADER		ndfsRequestHeader;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	PNDFS_WINXP_REPLY_HEADER	ndfsWinxpReplytHeader;

	LARGE_INTEGER				timeOut;

	TYPE_OF_OPEN				typeOfOpen;
	PVCB						vcb;
	PFCB						fcb;
	PCCB						ccb;
	BOOLEAN						fcbAcquired = FALSE;


	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	typeOfOpen = FatDecodeFileObject( fileObject, &vcb, &fcb, &ccb );

	ASSERT( typeOfOpen == UserFileOpen );

	if (FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_UNOPENED)) {

		/*if (FlagOn( fcb->FcbState, FCB_STATE_FILE_DELETED )) {
	
			ASSERT( FALSE );
			FatRaiseStatus( IrpContext, STATUS_FILE_DELETED, NULL, NULL );
					
		} else */{
					
			ASSERT( FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_CORRUPTED) );
			
			return STATUS_FILE_CORRUPT_ERROR;
		}
	}

	if (irpSp->Parameters.Write.ByteOffset.QuadPart == FILE_WRITE_TO_END_OF_FILE && 
		irpSp->Parameters.Write.ByteOffset.HighPart == -1) {

		write.ByteOffset = fcb->Header.FileSize;

	} else {

		write.ByteOffset = irpSp->Parameters.Write.ByteOffset;
	}

	write.Key		= 0;
	write.Length	= irpSp->Parameters.Write.Length;

	if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
		
		ASSERT( (write.ByteOffset.QuadPart + write.Length) <= 
				((fcb->Header.AllocationSize.QuadPart + PAGE_SIZE - 1) & ~((LONGLONG) (PAGE_SIZE-1))) );

		return STATUS_SUCCESS;
	}

	ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); 
	//ASSERT( !FlagOn( IrpContext->State, IRP_CONTEXT_STATE_LAZY_WRITE ) );

	if ( (write.ByteOffset.QuadPart + write.Length) <= fcb->Header.FileSize.LowPart) {

		return STATUS_SUCCESS;
	}

	if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

		return STATUS_PENDING;

		ASSERT( FALSE );
		DebugTrace2( 0, Dbg, ("Can't wait in NdFatSecondaryCommonWrite\n") );

		status = FatFsdPostRequest( IrpContext, Irp );

		DebugTrace2( -1, Dbg2, ("NdFatSecondaryCommonWrite:  FatFsdPostRequest -> %08lx\n", status) );
		return status;
	}

		DebugTrace2( 0, Dbg, ("write.ByteOffset.QuadPart + write.Length > fcb->Header.AllocationSize.QuadPart = %d "
								 "ExIsResourceAcquiredSharedLite(fcb->Header.Resource) = %d\n",
							   ((write.ByteOffset.QuadPart + write.Length) > fcb->Header.AllocationSize.QuadPart),
							   ExIsResourceAcquiredSharedLite(fcb->Header.Resource)) );

	if ((write.ByteOffset.QuadPart + write.Length) > fcb->Header.AllocationSize.QuadPart) {

		FatAcquireExclusiveFcb( IrpContext, fcb );
		fcbAcquired = TRUE;
	
	} 	

	try {

		secondarySessionResourceAcquired 
			= SecondaryAcquireResourceExclusiveLite( IrpContext, 
													 &volDo->Secondary->SessionResource, 
													 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

		if (FlagOn(volDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

			PrintIrp( Dbg, "SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED", NULL, IrpContext->OriginatingIrp );
			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );	
		}


		secondaryRequest = ALLOC_WINXP_SECONDARY_REQUEST( volDo->Secondary, 
														  IRP_MJ_SET_INFORMATION,
														  volDo->Secondary->Thread.SessionContext.SecondaryMaxDataSize );

		if (secondaryRequest == NULL) {

			FatRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
		}

		ndfsRequestHeader = &secondaryRequest->NdfsRequestHeader;
		INITIALIZE_NDFS_REQUEST_HEADER(	ndfsRequestHeader, NDFS_COMMAND_EXECUTE, volDo->Secondary, IRP_MJ_SET_INFORMATION, 0 );

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
		ASSERT( ndfsWinxpRequestHeader == (PNDFS_WINXP_REQUEST_HEADER)secondaryRequest->NdfsRequestData );

		//ndfsWinxpRequestHeader->IrpTag   = (_U32)Irp;
		ndfsWinxpRequestHeader->IrpMajorFunction = IRP_MJ_SET_INFORMATION;
		ndfsWinxpRequestHeader->IrpMinorFunction = 0;

		ndfsWinxpRequestHeader->FileHandle = ccb->PrimaryFileHandle;

		ndfsWinxpRequestHeader->IrpFlags   = 0;
		ndfsWinxpRequestHeader->IrpSpFlags = 0;

		ndfsWinxpRequestHeader->SetFile.FileHandle				= 0;
		ndfsWinxpRequestHeader->SetFile.Length					= sizeof( FILE_END_OF_FILE_INFORMATION );
		ndfsWinxpRequestHeader->SetFile.FileInformationClass	= FileEndOfFileInformation;

		ndfsWinxpRequestHeader->SetFile.EndOfFileInformation.EndOfFile = write.ByteOffset.QuadPart + write.Length;


		secondaryRequest->RequestType = SECONDARY_REQ_SEND_MESSAGE;
		QueueingSecondaryRequest( volDo->Secondary, secondaryRequest );

		timeOut.QuadPart = -NDFAT_TIME_OUT;
		status = KeWaitForSingleObject( &secondaryRequest->CompleteEvent, Executive, KernelMode, FALSE, &timeOut );
		
		if (status != STATUS_SUCCESS) {

			secondaryRequest = NULL;
			status = STATUS_IO_DEVICE_ERROR;
			leave;
		}

		KeClearEvent( &secondaryRequest->CompleteEvent );

		if (secondaryRequest->ExecuteStatus != STATUS_SUCCESS) {

			if (IrpContext->OriginatingIrp)
				PrintIrp( Dbg2, "secondaryRequest->ExecuteStatus != STATUS_SUCCESS", NULL, IrpContext->OriginatingIrp );
			DebugTrace2( 0, Dbg2, ("secondaryRequest->ExecuteStatus != STATUS_SUCCESS file = %s, line = %d\n", __FILE__, __LINE__) );

			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
		}

		ndfsWinxpReplytHeader = (PNDFS_WINXP_REPLY_HEADER)secondaryRequest->NdfsReplyData;
		status = ndfsWinxpReplytHeader->Status;
		Irp->IoStatus.Information = write.Length;

		if (ndfsWinxpReplytHeader->Status != STATUS_SUCCESS) {

			DebugTrace2( 0, Dbg2, ("NdNtfsSecondaryCommonWrite: ndfsWinxpReplytHeader->Status = %x\n", ndfsWinxpReplytHeader->Status) );
			ASSERT( ndfsWinxpReplytHeader->Information == 0 );
		
		} else
			ASSERT( ndfsWinxpReplytHeader->FileInformationSet );
	
		if (ndfsWinxpReplytHeader->FileInformationSet) {

			PNDFS_FAT_MCB_ENTRY	mcbEntry;
			ULONG			index;

			BOOLEAN			lookupResut;
			VBO				vcn;
			LBO				lcn;
			//LBO			startingLcn;
			ULONG			clusterCount;

			//DbgPrint( "w ndfsWinxpReplytHeader->FileSize = %x\n", ndfsWinxpReplytHeader->FileSize );

			if (ndfsWinxpReplytHeader->AllocationSize != fcb->Header.AllocationSize.QuadPart) {

				ASSERT( ExIsResourceAcquiredExclusiveLite(fcb->Header.Resource) );

				ASSERT( ndfsWinxpReplytHeader->AllocationSize > fcb->Header.AllocationSize.QuadPart );

				mcbEntry = (PNDFS_FAT_MCB_ENTRY)( ndfsWinxpReplytHeader+1 );

				for (index=0, vcn=0; index < ndfsWinxpReplytHeader->NumberOfMcbEntry; index++, mcbEntry++) {

					lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );
					
					if (lookupResut == TRUE && vcn < fcb->Header.AllocationSize.QuadPart) {

						ASSERT( lookupResut == TRUE );
						//ASSERT( startingLcn == lcn );
						ASSERT( vcn == mcbEntry->Vcn );
						ASSERT( lcn == (((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector) );
						ASSERT( clusterCount <= mcbEntry->ClusterCount );

						if (clusterCount < mcbEntry->ClusterCount) {

							FatAddMcbEntry ( vcb, 
											 &fcb->Mcb, 
											 (VBO)mcbEntry->Vcn, 
											 ((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector, 
											 (ULONG)mcbEntry->ClusterCount );

							lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );

							ASSERT( lookupResut == TRUE );
							//ASSERT( startingLcn == lcn );
							ASSERT( vcn == mcbEntry->Vcn );
							ASSERT( lcn == (((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector) );
							ASSERT( clusterCount == mcbEntry->ClusterCount );
						}
					
					} else { 

						ASSERT( lookupResut == FALSE || lcn == 0 );

						FatAddMcbEntry ( vcb, 
										 &fcb->Mcb, 
										 (VBO)mcbEntry->Vcn, 
										 ((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector, 
										 (ULONG)mcbEntry->ClusterCount );
					}

					vcn += (ULONG)mcbEntry->ClusterCount;
				}

				ASSERT( vcn == ndfsWinxpReplytHeader->AllocationSize );

				fcb->Header.AllocationSize.QuadPart = ndfsWinxpReplytHeader->AllocationSize;
				SetFlag( fcb->FcbState, FCB_STATE_TRUNCATE_ON_CLOSE );		

				if (CcIsFileCached(fileObject)) {

					ASSERT( fileObject->SectionObjectPointer->SharedCacheMap != NULL );
					CcSetFileSizes( fileObject, (PCC_FILE_SIZES)&fcb->Header.AllocationSize );
				}
			}

			DebugTrace2(0, Dbg, ("write scb->Header.FileSize.LowPart = %I64x, scb->Header.ValidDataLength.QuadPart = %I64x\n", 
								 fcb->Header.FileSize.LowPart, fcb->Header.ValidDataLength.QuadPart) );

		}

#if DBG
		{
			BOOLEAN			lookupResut;
			VBO				vcn;
			LBO				lcn;
			//LCN				startingLcn;
			ULONG			clusterCount;

			vcn = 0;
			while (1) {

				lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );
				if (lookupResut == FALSE || lcn == 0)
					break;

				vcn += clusterCount;
			}

			ASSERT( vcn == fcb->Header.AllocationSize.QuadPart );
		}

#endif

	} finally {
	
		if (secondarySessionResourceAcquired == TRUE)
				SecondaryReleaseResourceLite( IrpContext, &volDo->Secondary->SessionResource );

		if (fcbAcquired) {
             FatReleaseFcb( IrpContext, fcb );
        }

		if (secondaryRequest)
			DereferenceSecondaryRequest( secondaryRequest );
	}
			
	return status;
}
Esempio n. 6
0
BOOLEAN
FatIsCurrentOperationSynchedForDcbTeardown (
    IN PIRP_CONTEXT IrpContext,
    IN PDCB Dcb
    )
{
    PIRP Irp = IrpContext->OriginatingIrp;
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation( Irp ) ;
    PFILE_OBJECT FileObject = Stack->FileObject;
    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

    PFILE_OBJECT ToCheck[3];
    ULONG Index = 0;

    PAGED_CODE();
    
    //
    //  While mounting, we're OK without having to own anything.
    //
    
    if (Stack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
        Stack->MinorFunction == IRP_MN_MOUNT_VOLUME) {

        return TRUE;
    }
    
    //
    //  With the Vcb held, the close path is blocked out.
    //
    
    if (ExIsResourceAcquiredSharedLite( &Dcb->Vcb->Resource ) ||
        ExIsResourceAcquiredExclusiveLite( &Dcb->Vcb->Resource )) {

        return TRUE;
    }
    
    //
    //  Accept this assertion at face value.  It comes from GetDirentForFcbOrDcb,
    //  and is reliable.
    //
    
    if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_PARENT_BY_CHILD )) {

        return TRUE;
    }

    //
    //  Determine which fileobjects are around on this operation.
    //

    if (Stack->MajorFunction == IRP_MJ_SET_INFORMATION &&
        Stack->Parameters.SetFile.FileObject) {

        ToCheck[Index++] = Stack->Parameters.SetFile.FileObject;
    }

    if (Stack->FileObject) {
        
        ToCheck[Index++] = Stack->FileObject;
    }

    ToCheck[Index] = NULL;
    
    //
    //  If the fileobjects we have are for this dcb or a child of it, we are
    //  also guaranteed that this dcb isn't going anywhere (even without
    //  the Vcb).
    //
    
    for (Index = 0; ToCheck[Index] != NULL; Index++) {
    
        (VOID) FatDecodeFileObject( ToCheck[Index], &Vcb, &Fcb, &Ccb );

        while ( Fcb ) {
    
            if (Fcb == Dcb) {
    
                return TRUE;
            }
    
            Fcb = Fcb->ParentDcb;
        }
    }

    return FatDisableParentCheck;
}
Esempio n. 7
0
NTSTATUS
SecondaryRecoverySession (
	IN  PSECONDARY		Secondary
	)
{
	NTSTATUS			status;
	LONG				slotIndex;

	LARGE_INTEGER		timeOut;
	OBJECT_ATTRIBUTES	objectAttributes;

	ULONG				reconnectionTry;
    PLIST_ENTRY			ccblistEntry;
	BOOLEAN				isLocalAddress;


	DebugTrace2( 0, Dbg2, ("SecondaryRecoverySession: Called Secondary = %p\n", Secondary) );

	SetFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

	ASSERT( FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ); 
	ASSERT( Secondary->ThreadHandle );

	ASSERT( IsListEmpty(&Secondary->RequestQueue) );

	for (slotIndex=0; slotIndex < Secondary->Thread.SessionContext.SessionSlotCount; slotIndex++) {

		ASSERT( Secondary->Thread.SessionSlot[slotIndex] == NULL );
	}

	if (Secondary->ThreadHandle) {

		ASSERT( Secondary->ThreadObject );
		
		timeOut.QuadPart = -NDASFAT_TIME_OUT;
		status = KeWaitForSingleObject( Secondary->ThreadObject,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );

		if (status != STATUS_SUCCESS) {

			NDASFAT_ASSERT( FALSE );

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return status;
		}

		DebugTrace2( 0, Dbg2, ("Secondary_Stop: thread stoped\n") );

		ObDereferenceObject( Secondary->ThreadObject );

		Secondary->ThreadHandle = 0;
		Secondary->ThreadObject = 0;

		RtlZeroMemory( &Secondary->Thread.Flags, sizeof(SECONDARY) - FIELD_OFFSET(SECONDARY, Thread.Flags) );
	}

	for (status = STATUS_UNSUCCESSFUL, reconnectionTry = 0; reconnectionTry < MAX_RECONNECTION_TRY; reconnectionTry++) {

		if (FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_FLAG_LOCKED)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_FLAG_SHUTDOWN)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_FLAG_SHUTDOWN)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (FlagOn(Secondary->VolDo->NdasFatFlags, ND_FAT_DEVICE_FLAG_SHUTDOWN)) {

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );
			return STATUS_UNSUCCESSFUL;
		}

		if (Secondary->VolDo->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY) {
			
			status = STATUS_SUCCESS;
		
		} else {

			status = ((PVOLUME_DEVICE_OBJECT) FatData.DiskFileSystemDeviceObject)->
						NdfsCallback.SecondaryToPrimary( Secondary->VolDo->Vcb.Vpb->RealDevice, TRUE );

			if (status == STATUS_NO_SUCH_DEVICE) {

				NDASFAT_ASSERT( FlagOn(Secondary->VolDo->Vcb.VcbState, VCB_STATE_FLAG_LOCKED) );
				ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

				return STATUS_UNSUCCESSFUL;
			}
		}

		//FatDebugTraceLevel = 0;

		DebugTrace2( 0, Dbg2, ("SecondaryToPrimary status = %x\n", status) ); 

#if 0
		if (queryResult == TRUE) {
			
			BOOLEAN	result0, result1;
		    IRP_CONTEXT IrpContext;
		
			ASSERT( Secondary->VolDo->Vcb.VirtualVolumeFile );
			result0 = CcPurgeCacheSection( &Secondary->VolDo->Vcb.SectionObjectPointers,
										   NULL,
										   0,
										   FALSE );
			ASSERT( Secondary->VolDo->Vcb.RootDcb->Specific.Dcb.DirectoryFile );
			result1 = CcPurgeCacheSection( &Secondary->VolDo->Vcb.RootDcb->NonPaged->SectionObjectPointers,
										   NULL,
										   0,
										   FALSE );
		
			ASSERT( result0 == TRUE );
			ASSERT( result1 == TRUE );

			ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
		    RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) );
            SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
			FatTearDownAllocationSupport ( &IrpContext, &Secondary->VolDo->Vcb );
   			FatSetupAllocationSupport( &IrpContext, &Secondary->VolDo->Vcb );
			FatCheckDirtyBit( &IrpContext, &Secondary->VolDo->Vcb );

	        ASSERT( IrpContext.Repinned.Bcb[0] == NULL );
	        FatUnpinRepinnedBcbs( &IrpContext );
    
			Secondary->VolDo->NetdiskEnableMode = NETDISK_SECONDARY2PRIMARY; 
			Secondary->VolDo->SecondaryState = CONNECT_TO_LOCAL_STATE;
		}
#endif

		if (status == STATUS_SUCCESS) {

			PVCB				vcb = &Secondary->VolDo->Vcb;
#if 0
			TOP_LEVEL_CONTEXT	topLevelContext;
			PTOP_LEVEL_CONTEXT	threadTopLevelContext;
#endif
			IRP_CONTEXT			tempIrpContext2;
			PIRP_CONTEXT		tempIrpContext = NULL;

			SetFlag( Secondary->Flags, SECONDARY_FLAG_CLEANUP_VOLUME );

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&FatData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&FatData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->SecondaryResource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->SecondaryResource) );	


			//FatReleaseAllResources( IrpContext );

			//ObReferenceObject( vcb->TargetDeviceObject );

			DebugTrace2( 0, Dbg2, ("Vcb->State = %X\n", vcb->VcbState) );
			DebugTrace2( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace2( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );

			tempIrpContext = NULL;

#if 0
			threadTopLevelContext = FatInitializeTopLevelIrp( &topLevelContext, TRUE, FALSE );
			ASSERT( threadTopLevelContext == &topLevelContext );

			FatInitializeIrpContext( NULL, TRUE, &tempIrpContext );
            FatUpdateIrpContextWithTopLevel( tempIrpContext, threadTopLevelContext );
			
			ASSERT( FlagOn(tempIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL) );
#endif
			tempIrpContext = &tempIrpContext2;

			RtlZeroMemory( tempIrpContext, sizeof(IRP_CONTEXT) );
			SetFlag( tempIrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
			SetFlag( tempIrpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
		
			tempIrpContext->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
			tempIrpContext->MinorFunction = IRP_MN_MOUNT_VOLUME;
			tempIrpContext->Vcb			  = vcb;

			ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

			try {
			
				status = STATUS_UNSUCCESSFUL;
				status = CleanUpVcb( tempIrpContext, vcb );
			
			} finally {
                
				//FatCompleteRequest( tempIrpContext, NULL, 0 );
				//ASSERT( IoGetTopLevelIrp() != (PIRP) &topLevelContext );
				tempIrpContext = NULL;
			}

			ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

			ASSERT( status == STATUS_SUCCESS );
			//ASSERT( FlagOn(vcb->VcbState, VCB_STATE_MOUNT_COMPLETED) );
			ASSERT( FlagOn(Secondary->VolDo->NdasFatFlags, ND_FAT_DEVICE_FLAG_MOUNTED) );
			ASSERT( !ExIsResourceAcquiredExclusiveLite(&FatData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&FatData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->SecondaryResource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->SecondaryResource) );	

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_CLEANUP_VOLUME );


			DebugTrace2( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );
			DebugTrace2( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace2( 0, Dbg2, ("Vcb->CloseCount = %d\n", vcb->OpenFileCount) );

#if 0
			tempIrpContext = NULL;

			threadTopLevelContext = FatInitializeTopLevelIrp( &topLevelContext, TRUE, FALSE );
			ASSERT( threadTopLevelContext == &topLevelContext );

			FatInitializeIrpContext( NULL, TRUE, &tempIrpContext );
            FatUpdateIrpContextWithTopLevel( tempIrpContext, threadTopLevelContext );

			ASSERT( FlagOn(tempIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL) );
#endif

			Secondary->VolDo->NetdiskEnableMode = NETDISK_SECONDARY2PRIMARY; 

			tempIrpContext = &tempIrpContext2;

			RtlZeroMemory( tempIrpContext, sizeof(IRP_CONTEXT) );
			SetFlag( tempIrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
			SetFlag( tempIrpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
			
			tempIrpContext->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
			tempIrpContext->MinorFunction = IRP_MN_MOUNT_VOLUME;
			tempIrpContext->Vcb			  = vcb;
			
			SetFlag( Secondary->Flags, SECONDARY_FLAG_REMOUNT_VOLUME );

			try {
			
				status = STATUS_UNSUCCESSFUL;

				status = NdasFatMountVolume( tempIrpContext, vcb->TargetDeviceObject, vcb->Vpb, NULL );
			
			} finally {
                
				//FatCompleteRequest( tempIrpContext, NULL, 0 );
				//ASSERT( IoGetTopLevelIrp() != (PIRP) &topLevelContext );
				tempIrpContext = NULL;
			}

			//ObDereferenceObject( vcb->TargetDeviceObject );

			//FatDebugTraceLevel = 0xFFFFFFFFFFFFFFFF;
			//FatDebugTraceLevel |= DEBUG_TRACE_CREATE;

			ClearFlag( Secondary->Flags, SECONDARY_FLAG_REMOUNT_VOLUME );

			ASSERT( status == STATUS_SUCCESS );

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&FatData.Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&FatData.Resource) );	

			ASSERT( !ExIsResourceAcquiredExclusiveLite(&vcb->Resource) );			
			ASSERT( !ExIsResourceAcquiredSharedLite(&vcb->Resource) );	

			DebugTrace2( 0, Dbg2, ("Vcb->TargetDeviceObject->ReferenceCount = %X\n", vcb->TargetDeviceObject->ReferenceCount) );
			DebugTrace2( 0, Dbg2, ("Vcb->Vpb->ReferenceCount = %X\n", vcb->Vpb->ReferenceCount) );
			DebugTrace2( 0, Dbg2, ("Vcb->CloseCount = %d\n", vcb->OpenFileCount) );

#if 0

			if (vcb->MftScb) {
			
				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->MftScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->MftScb->Header.Resource) );	
			}

			if (vcb->Mft2Scb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->Mft2Scb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->Mft2Scb->Header.Resource) );	
			}

			if (vcb->LogFileScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->LogFileScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->LogFileScb->Header.Resource) );			
			}

			if (vcb->VolumeDasdScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->VolumeDasdScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->VolumeDasdScb->Header.Resource) );			
			}

			if (vcb->AttributeDefTableScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->AttributeDefTableScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->AttributeDefTableScb->Header.Resource) );			
			}

			if (vcb->UpcaseTableScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->UpcaseTableScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->UpcaseTableScb->Header.Resource) );			
			}

			if (vcb->RootIndexScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->RootIndexScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->RootIndexScb->Header.Resource) );			
			}

			if (vcb->BitmapScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->BitmapScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->BitmapScb->Header.Resource) );			
			}

			if (vcb->BadClusterFileScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->BadClusterFileScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->BadClusterFileScb->Header.Resource) );		
			}

			if (vcb->MftBitmapScb) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->MftBitmapScb->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->MftBitmapScb->Header.Resource) );			
			}

			if (vcb->SecurityDescriptorStream) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityDescriptorStream->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityDescriptorStream->Header.Resource) );			
			}

			if (vcb->UsnJournal) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->UsnJournal->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->UsnJournal->Header.Resource) );			
			}

			if (vcb->ExtendDirectory) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->ExtendDirectory->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->ExtendDirectory->Header.Resource) );			
			}

			if (vcb->SecurityDescriptorHashIndex) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityDescriptorHashIndex->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityDescriptorHashIndex->Header.Resource) );			
			}

			if (vcb->SecurityIdIndex) {

				ASSERT( !ExIsResourceAcquiredExclusiveLite(vcb->SecurityIdIndex->Header.Resource) );			
				ASSERT( !ExIsResourceAcquiredSharedLite(vcb->SecurityIdIndex->Header.Resource) );			
			}
#endif
		}


		status = ((PVOLUME_DEVICE_OBJECT) FatData.DiskFileSystemDeviceObject)->
						NdfsCallback.QueryPrimaryAddress( &Secondary->VolDo->NetdiskPartitionInformation, &Secondary->PrimaryAddress, &isLocalAddress );

		DebugTrace2( 0, Dbg2, ("RecoverSession: LfsTable_QueryPrimaryAddress status = %X\n", status) );
	
		if (status == STATUS_SUCCESS && !(Secondary->VolDo->NetdiskEnableMode == NETDISK_SECONDARY && isLocalAddress)) {

			DebugTrace2( 0, Dbg, ("SecondaryRecoverySessionStart: Found PrimaryAddress :%02x:%02x:%02x:%02x:%02x:%02x/%d\n",
								  Secondary->PrimaryAddress.Node[0],
								  Secondary->PrimaryAddress.Node[1],
								  Secondary->PrimaryAddress.Node[2],
								  Secondary->PrimaryAddress.Node[3],
								  Secondary->PrimaryAddress.Node[4],
								  Secondary->PrimaryAddress.Node[5],
								  NTOHS(Secondary->PrimaryAddress.Port)) );
		
		} else {

			//ASSERT( FALSE );
			continue;
		}	

		KeInitializeEvent( &Secondary->ReadyEvent, NotificationEvent, FALSE );
		KeInitializeEvent( &Secondary->RequestEvent, NotificationEvent, FALSE );

		InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

		status = PsCreateSystemThread( &Secondary->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   SecondaryThreadProc,
									   Secondary );

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASFAT_UNEXPECTED );
			break;
		}

		status = ObReferenceObjectByHandle( Secondary->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&Secondary->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			ASSERT (NDASFAT_INSUFFICIENT_RESOURCES );
			break;
		}

		timeOut.QuadPart = -NDASFAT_TIME_OUT;
		status = KeWaitForSingleObject( &Secondary->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );

		if (status != STATUS_SUCCESS) {

			ASSERT( NDASFAT_BUG );
			break;
		}

		KeClearEvent( &Secondary->ReadyEvent );

		InterlockedIncrement( &Secondary->SessionId );	

		ExAcquireFastMutex( &Secondary->FastMutex );

		if (!FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) || FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) {

			ExReleaseFastMutex( &Secondary->FastMutex );

			if (Secondary->Thread.SessionStatus == STATUS_DISK_CORRUPT_ERROR) {

				status = STATUS_SUCCESS;
				break;
			}

			timeOut.QuadPart = -NDASFAT_TIME_OUT;
			status = KeWaitForSingleObject( Secondary->ThreadObject,
											Executive,
											KernelMode,
											FALSE,
											&timeOut );

			if (status != STATUS_SUCCESS) {

				ASSERT( NDASFAT_BUG );
				return status;
			}

			DebugTrace2( 0, Dbg, ("Secondary_Stop: thread stoped\n") );

			ObDereferenceObject( Secondary->ThreadObject );

			Secondary->ThreadHandle = 0;
			Secondary->ThreadObject = 0;

			RtlZeroMemory( &Secondary->Thread.Flags, sizeof(SECONDARY) - FIELD_OFFSET(SECONDARY, Thread.Flags) );

			continue;
		} 

		ExReleaseFastMutex( &Secondary->FastMutex );

		status = STATUS_SUCCESS;

		DebugTrace2( 0, Dbg2, ("SecondaryRecoverySession Success Secondary = %p\n", Secondary) );

		break;
	}
Esempio n. 8
0
NTSTATUS
CmpDoFileSetSize(
    PHHIVE      Hive,
    ULONG       FileType,
    ULONG       FileSize,
    ULONG       OldFileSize
    )
/*++

Routine Description:

    This routine sets the size of a file.  It must not return until
    the size is guaranteed.

    It is environment specific.

    Must be running in the context of the cmp worker thread.

Arguments:

    Hive - Hive we are doing I/O for

    FileType - which supporting file to use

    FileSize - 32 bit value to set the file's size to

    OldFileSize - old file size, in order to determine if this is a shrink;
                - ignored if file type is not primary, or hive doesn't use 
                the mapped views technique

Return Value:

    FALSE if failure
    TRUE if success

--*/
{
    PCMHIVE                         CmHive;
    HANDLE                          FileHandle;
    NTSTATUS                        Status;
    FILE_END_OF_FILE_INFORMATION    FileInfo;
    IO_STATUS_BLOCK                 IoStatus;
    BOOLEAN                         oldFlag;
    LARGE_INTEGER                   FileOffset;         // where the mapping starts

    ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);

    CmHive = (PCMHIVE)Hive;
    FileHandle = CmHive->FileHandles[FileType];
    if (FileHandle == NULL) {
        return TRUE;
    }

    //
    // disable hard error popups, to avoid self deadlock on bogus devices
    //
    oldFlag = IoSetThreadHardErrorMode(FALSE);

    FileInfo.EndOfFile.HighPart = 0L;
    if( FileType == HFILE_TYPE_PRIMARY ) {
        FileInfo.EndOfFile.LowPart  = ROUND_UP(FileSize, CM_FILE_GROW_INCREMENT);
    } else {
        FileInfo.EndOfFile.LowPart  = FileSize;
    }

    ASSERT_PASSIVE_LEVEL();

    Status = ZwSetInformationFile(
                FileHandle,
                &IoStatus,
                (PVOID)&FileInfo,
                sizeof(FILE_END_OF_FILE_INFORMATION),
                FileEndOfFileInformation
                );

    if (NT_SUCCESS(Status)) {
        ASSERT(IoStatus.Status == Status);
    } else {
        
        //
        // set debugging info
        //
        CmRegistryIODebug.Action = CmpIoFileSetSize;
        CmRegistryIODebug.Handle = FileHandle;
        CmRegistryIODebug.Status = Status;
#if DBG
        DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"CmpFileSetSize:\tHandle=%08lx  OldLength = %08lx NewLength=%08lx  \n", 
                                                        FileHandle, OldFileSize, FileSize);
#endif
        if( (Status == STATUS_DISK_FULL) && ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) ) {
            DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Disk is full while attempting to grow file %lx; will flush upon lock release\n",FileHandle);
            CmpFlushOnLockRelease = TRUE;;
        }
    }

    //
    // restore hard error popups mode
    //
    IoSetThreadHardErrorMode(oldFlag);
    

    //
    // purge
    //
    if( HiveWritesThroughCache(Hive,FileType) && (OldFileSize > FileSize)) {
        //
        // first we have to unmap any possible mapped views in the last 256K window
        // to avoid deadlock on CcWaitOnActiveCount inside CcPurgeCacheSection call below
        //
        ULONG   Offset = FileSize & (~(_256K - 1));
        //
        // we are not allowed to shrink in shared mode.
        //
	    ASSERT_HIVE_WRITER_LOCK_OWNED((PCMHIVE)Hive);

        while( Offset < OldFileSize ) {
            CmpUnmapCmViewSurroundingOffset((PCMHIVE)Hive,Offset);
            Offset += CM_VIEW_SIZE;
        }

        //
        // we need to take extra precaution here and unmap the very last view too
        //
        
        FileOffset.HighPart = 0;
        FileOffset.LowPart = FileSize;
        //
        // This is a shrink; Inform cache manager of the change of the size
        //
        CcPurgeCacheSection( ((PCMHIVE)Hive)->FileObject->SectionObjectPointer, (PLARGE_INTEGER)(((ULONG_PTR)(&FileOffset)) + 1), 
                            OldFileSize - FileSize, FALSE );

        //
        // Flush out this view to clear out the Cc dirty hints
        //
        CcFlushCache( ((PCMHIVE)Hive)->FileObject->SectionObjectPointer, (PLARGE_INTEGER)(((ULONG_PTR)(&FileOffset)) + 1),/*we are private writers*/
                            OldFileSize - FileSize,NULL);

    }
    
    return Status;
}