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; }
BOOL FASTCALL UserIsEnteredExclusive(VOID) { return ExIsResourceAcquiredExclusiveLite(&UserLock); }
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; }
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; }
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; }
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; }