Beispiel #1
0
VOID
NtfsReleaseVolumeFromClose (
    IN PVOID OpaqueVcb
    )

/*++

Routine Description:

    The address of this routine is specified when creating a CacheMap for
    a file.  It is subsequently called by the Lazy Writer after its
    performing closes on the file.

Arguments:

    Vcb - The Vcb which was specified as a close context parameter for this
          routine.

Return Value:

    None

--*/

{
    PVCB Vcb = (PVCB)OpaqueVcb;

    ASSERT_VCB(Vcb);

    PAGED_CODE();

    NtfsReleaseVcb( NULL, Vcb );

    return;
}
Beispiel #2
0
BOOLEAN
NtfsAcquireVolumeForClose (
    IN PVOID OpaqueVcb,
    IN BOOLEAN Wait
    )

/*++

Routine Description:

    The address of this routine is specified when creating a CacheMap for
    a file.  It is subsequently called by the Lazy Writer prior to its
    performing closes to the file.  This callback is necessary to
    avoid deadlocks with the Lazy Writer.  (Note that normal closes
    acquire the Vcb, and then call the Cache Manager, who must acquire
    some of his internal structures.  If the Lazy Writer could not call
    this routine first, and were to issue a write after locking Caching
    data structures, then a deadlock could occur.)

Arguments:

    Vcb - The Vcb which was specified as a close context parameter for this
          routine.

    Wait - TRUE if the caller is willing to block.

Return Value:

    FALSE - if Wait was specified as FALSE and blocking would have
            been required.  The Fcb is not acquired.

    TRUE - if the Vcb has been acquired

--*/

{
    PVCB Vcb = (PVCB)OpaqueVcb;

    ASSERT_VCB(Vcb);

    PAGED_CODE();

    //
    //  Do the code of acquire exclusive Vcb but without the IrpContext
    //

    if (ExAcquireResourceExclusive( &Vcb->Resource, Wait )) {

        return TRUE;
    }

    return FALSE;
}
NTSTATUS
XixFsWriteFileInfoFromFcb(
	IN PXIFS_FCB pFCB,
	IN BOOLEAN	Waitable,
	IN uint8 *	Buffer,
	IN uint32	BufferSize
)
{
	NTSTATUS RC = STATUS_SUCCESS;
	uint64			FileId = 0;
	PXIFS_VCB					pVCB = NULL;

	PAGED_CODE();

	ASSERT_FCB(pFCB);
	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);

	ASSERT(Waitable == TRUE);
	ASSERT(BufferSize >= XIDISK_FILE_HEADER_LOT_SIZE);


	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter XixFsWriteFileInfoFromFcb\n"));

	try{
		RC = XixFsRawWriteLotAndFileHeader(
				pVCB->TargetDeviceObject,
				pVCB->LotSize,
				pFCB->LotNumber,
				Buffer,
				XIDISK_FILE_HEADER_LOT_SIZE,
				pVCB->SectorSize
				);
				
		if(!NT_SUCCESS(RC)){
			DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
						("Fail Write File Data(%I64d).\n", pFCB->LotNumber));
			try_return (RC);
		}	
		

	}finally{

	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit XixFsWriteFileInfoFromFcb Status(0x%x)\n", RC));

	return RC;
}
Beispiel #4
0
BOOLEAN
NtfsAcquireSharedVcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN BOOLEAN RaiseOnCantWait
    )

/*++

Routine Description:

    This routine acquires shared access to the Vcb.

    This routine will raise if it cannot acquire the resource and wait
    in the IrpContext is false.

Arguments:

    Vcb - Supplies the Vcb to acquire

    RaiseOnCantWait - Indicates if we should raise on an acquisition error
        or simply return a BOOLEAN indicating that we couldn't get the
        resource.

Return Value:

    None.

--*/

{
    ASSERT_IRP_CONTEXT(IrpContext);
    ASSERT_VCB(Vcb);

    PAGED_CODE();

    if (ExAcquireResourceShared( &Vcb->Resource, BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT))) {

        return TRUE;
    }

    if (RaiseOnCantWait) {

        NtfsRaiseStatus( IrpContext, STATUS_CANT_WAIT, NULL, NULL );

    } else {

        return FALSE;
    }
}
Beispiel #5
0
ULONG
UdfLookupPsnOfExtent (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN USHORT Reference,
    IN ULONG Lbn,
    IN ULONG Len
    )

/*++

Routine Description:

    This routine maps the input logical block extent on a given partition to
    a starting physical sector.  It doubles as a bounds checker - if the routine
    does not raise, the caller is guaranteed that the extent lies within the
    partition.

Arguments:

    Vcb - Vcb of logical volume

    Reference - Partition reference to use in the mapping

    Lbn - Logical block number

    Len - Length of extent in bytes

Return Value:

    ULONG physical sector number

--*/

{
    PPCB Pcb = Vcb->Pcb;
    ULONG Psn;

    PBCB Bcb;
    LARGE_INTEGER Offset;
    PULONG MappedLbn;

    PAGED_CODE();

    //
    //  Check inputs
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );
    ASSERT_PCB( Pcb );

    DebugTrace(( +1, Dbg, "UdfLookupPsnOfExtent, [%04x/%08x, +%08x)\n", Reference, Lbn, Len ));

    if (Reference < Pcb->Partitions) {

        while (TRUE) {

            switch (Pcb->Partition[Reference].Type) {

                case Physical:

                    //
                    //  Check that the input extent lies inside the partition.  Calculate the
                    //  Lbn of the last block and see that it is interior.
                    //

                    if (SectorsFromBlocks( Vcb, Lbn ) + SectorsFromBytes( Vcb, Len ) >
                        Pcb->Partition[Reference].Physical.Length) {

                        goto NoGood;
                    }

                    Psn = Pcb->Partition[Reference].Physical.Start + SectorsFromBlocks( Vcb, Lbn );

                    DebugTrace(( -1, Dbg, "UdfLookupPsnOfExtent -> %08x\n", Psn ));
                    return Psn;

                case Virtual:

                    //
                    //  Bounds check.  Per UDF 2.00 2.3.10 and implied in UDF 1.50, virtual
                    //  extent lengths cannot be greater than one block in size.
                    //

                    if (Lbn + BlocksFromBytes( Vcb, Len ) > Pcb->Partition[Reference].Virtual.Length ||
                        Len > BlockSize( Vcb )) {

                        goto NoGood;
                    }

                    try {

                        //
                        //  Calculate the location of the mapping element in the VAT
                        //  and retrieve.
                        //

                        Offset.QuadPart = Lbn * sizeof(ULONG);

                        CcMapData( Vcb->VatFcb->FileObject,
                                   &Offset,
                                   sizeof(ULONG),
                                   TRUE,
                                   &Bcb,
                                   &MappedLbn );

                        //
                        //  Now rewrite the inputs in terms of the virtual mapping.  We
                        //  will reloop to perform the logical -> physical mapping.
                        //

                        DebugTrace(( 0, Dbg,
                                     "UdfLookupPsnOfExtent, Mapping V %04x/%08x -> L %04x/%08x\n",
                                     Reference,
                                     Lbn,
                                     Pcb->Partition[Reference].Virtual.RelatedReference,
                                     *MappedLbn ));

                        Lbn = *MappedLbn;
                        Reference = Pcb->Partition[Reference].Virtual.RelatedReference;

                    } finally {

                        DebugUnwind( UdfLookupPsnOfExtent );

                        UdfUnpinData( IrpContext, &Bcb );
                    }

                    //
                    //  An Lbn of ~0 in the VAT is defined to indicate that the sector is unused,
                    //  so we should never see such a thing.
                    //

                    if (Lbn == ~0) {

                        goto NoGood;
                    }

                    break;

                default:

                    ASSERT(FALSE);
                    break;
            }
        }
    }

    NoGood:

    //
    //  Some people have misinterpreted a partition number to equal a
    //  partition reference, or perhaps this is just corrupt media.
    //

    UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
}
Beispiel #6
0
NTSTATUS
NtfsQueryFsSizeInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PFILE_FS_SIZE_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine implements the query size information call

Arguments:

    Vcb - Supplies the Vcb being queried

    Buffer - Supplies a pointer to the output buffer where the information
        is to be returned

    Length - Supplies the length of the buffer in byte.  This variable
        upon return recieves the remaining bytes free in the buffer

Return Value:

    NTSTATUS - Returns the status for the query

--*/

{
    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );

    PAGED_CODE();

    DebugTrace( 0, Dbg, ("NtfsQueryFsSizeInfo...\n") );

    //
    //  Make sure the buffer is large enough and zero it out
    //

    if (*Length < sizeof(FILE_FS_SIZE_INFORMATION)) {

        return STATUS_BUFFER_OVERFLOW;
    }

    RtlZeroMemory( Buffer, sizeof(FILE_FS_SIZE_INFORMATION) );

    //
    //  Check if we need to rescan the bitmap.  Don't try this
    //  if we have started to teardown the volume.
    //

    if (FlagOn( Vcb->VcbState, VCB_STATE_RELOAD_FREE_CLUSTERS ) &&
        FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED )) {

        //
        //  Acquire the volume bitmap shared to rescan the bitmap.
        //

        NtfsAcquireExclusiveScb( IrpContext, Vcb->BitmapScb );

        try {

            NtfsScanEntireBitmap( IrpContext, Vcb, FALSE );

        } finally {

            NtfsReleaseScb( IrpContext, Vcb->BitmapScb );
        }
    }
Beispiel #7
0
NTSTATUS
NtfsQueryFsVolumeInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PFILE_FS_VOLUME_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine implements the query volume info call

Arguments:

    Vcb - Supplies the Vcb being queried

    Buffer - Supplies a pointer to the output buffer where the information
        is to be returned

    Length - Supplies the length of the buffer in byte.  This variable
        upon return recieves the remaining bytes free in the buffer

Return Value:

    NTSTATUS - Returns the status for the query

--*/

{
    NTSTATUS Status;

    ULONG BytesToCopy;

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );

    PAGED_CODE();

    DebugTrace( 0, Dbg, ("NtfsQueryFsVolumeInfo...\n") );

    //
    //  Get the volume creation time from the Vcb.
    //

    Buffer->VolumeCreationTime.QuadPart = Vcb->VolumeCreationTime;

    //
    //  Fill in the serial number and indicate that we support objects
    //

    Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
    Buffer->SupportsObjects = TRUE;

    Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;

    //
    //  Update the length field with how much we have filled in so far.
    //

    *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);

    //
    //  See how many bytes of volume label we can copy
    //

    if (*Length >= (ULONG)Vcb->Vpb->VolumeLabelLength) {

        Status = STATUS_SUCCESS;

        BytesToCopy = Vcb->Vpb->VolumeLabelLength;

    } else {

        Status = STATUS_BUFFER_OVERFLOW;

        BytesToCopy = *Length;
    }

    //
    //  Copy over the volume label (if there is one).
    //

    RtlCopyMemory( &Buffer->VolumeLabel[0],
                   &Vcb->Vpb->VolumeLabel[0],
                   BytesToCopy);

    //
    //  Update the buffer length by the amount we copied.
    //

    *Length -= BytesToCopy;

    return Status;
}
Beispiel #8
0
NTSTATUS
xixfs_CommonClose(
    IN PXIXFS_IRPCONTEXT pIrpContext
)
{
    NTSTATUS				RC = STATUS_SUCCESS;
    PXIXFS_FCB				pFCB = NULL;
    PXIXFS_CCB				pCCB = NULL;
    PXIXFS_VCB				pVCB = NULL;
    PFILE_OBJECT			pFileObject = NULL;
    PIRP					pIrp = NULL;
    PIO_STACK_LOCATION		pIrpSp = NULL;
    BOOLEAN					OpenVCB = FALSE;
    BOOLEAN					PotentialVCBUnmount = FALSE;
    BOOLEAN					CanWait = FALSE;
    BOOLEAN					ForceDismount = FALSE;
    BOOLEAN					bUserReference = FALSE;
    TYPE_OF_OPEN			TypeOfOpen = UnopenedFileObject;
    BOOLEAN					bVcbAcq = FALSE;

    PAGED_CODE();
    DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
               ("Enter xixfs_CommonClose IrpContext(%p)\n", pIrpContext));



    ASSERT_IRPCONTEXT(pIrpContext);
    pIrp = pIrpContext->Irp;
    ASSERT(pIrp);


    // check if open request is releated to file system CDO
    {
        PDEVICE_OBJECT	DeviceObject = pIrpContext->TargetDeviceObject;
        ASSERT(DeviceObject);

        if (DeviceObject == XiGlobalData.XifsControlDeviceObject) {
            RC = STATUS_SUCCESS;
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                       ("CDO Device Close DevObj(%p).\n", DeviceObject));
            xixfs_CompleteRequest(pIrpContext,RC,0);
            return(RC);
        }

    }

    if(pIrpContext->VCB == NULL) {

        DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_CLOSE,
                   ("pIrpContext->VCB == NULL.\n"));
        RC = STATUS_SUCCESS;
        xixfs_CompleteRequest(pIrpContext, RC, 0);
        return RC;
    }


    CanWait = XIXCORE_TEST_FLAGS(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    ASSERT(pIrpSp);

    pFileObject = pIrpSp->FileObject;
    ASSERT(pFileObject);

    TypeOfOpen = xixfs_DecodeFileObject(pFileObject, &pFCB, &pCCB);





    if(TypeOfOpen == UnopenedFileObject) {
        DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                   ("TypeOfOpen <= StreamFileOpen.\n"));
        xixfs_CompleteRequest(pIrpContext, STATUS_SUCCESS, 0);
        return STATUS_SUCCESS;
    }


    if(TypeOfOpen == UserVolumeOpen) {
        ForceDismount = XIXCORE_TEST_FLAGS( pCCB->CCBFlags, XIXFSD_CCB_DISMOUNT_ON_CLOSE);
        if(ForceDismount) {
            if(!CanWait) {
                DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                           ("Force Dismount with Non Waitable Context.\n"));

                RC = xixfs_PostRequest(pIrpContext, pIrp);
                return RC;
            }
        }
    }


    DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL,
               ("!!!!Close  pCCB(%p) FileObject(%p)\n", pCCB, pFileObject));


    ASSERT_FCB(pFCB);
    pVCB = pFCB->PtrVCB;
    ASSERT_VCB(pVCB);

    if( (pVCB->VCBCleanup == 0)
            && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED) )
    {
        if(!CanWait) {
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                       ("Force Dismount with Non Waitable Context.\n"));

            RC = xixfs_PostRequest(pIrpContext, pIrp);
            return RC;
        }
    }




    //
    //  Clean up any CCB associated with this open.
    //

    try {




        if( ((TypeOfOpen == UserDirectoryOpen) || (TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserVolumeOpen))
                && (pCCB != NULL)
          ) {
            bUserReference = TRUE;
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_CCB),
                       ("XifsdCommonClose Delete CCB (%x)\n", pCCB));

            // Test
            //XifsdLockFcb(NULL, pFCB);
            //RemoveEntryList(&pCCB->LinkToFCB);
            //XifsdUnlockFcb(NULL, pFCB);

            xixfs_FreeCCB( pCCB );
        }




        DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB),
                   ("XifsdCommonClose GenINFO Fcb LotNumber(%I64d)  TypeOfOpen (%ld) Fcb %d/%d  Vcb %d/%d \n",
                    pFCB->XixcoreFcb.LotNumber,
                    TypeOfOpen,
                    pFCB->FCBReference,
                    pFCB->FCBUserReference,
                    pVCB->VCBReference,
                    pVCB->VCBUserReference));




        /*
        if(CanWait){
        	if(TypeOfOpen == UserFileOpen){

        		if(pFCB->FCBCleanup == 0){
        			if(pFCB->SectionObject.DataSectionObject != NULL)
        			{
        				CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

        				CcPurgeCacheSection( &(pFCB->SectionObject),
        													NULL,
        													0,
        													FALSE
        													);
        			}


        			if(XIXCORE_TEST_FLAGS(pFCB->FCBFlags,XIXCORE_FCB_MODIFIED_FILE)){
        				xixfs_LastUpdateFileFromFCB(pFCB);

        			}
        		}
        	}
        }
        */


        if((pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_MOUNTED)
                && ((TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserDirectoryOpen))
                && (pFCB != pVCB->RootDirFCB))
        {

            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                       ("XifsdCommonClose Destroy FCB (%x)\n", pFCB));

            DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB),
                       ("XifsdCommonClose, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                        pVCB->VCBReference,
                        pVCB->VCBUserReference,
                        pFCB->FCBReference,
                        pFCB->FCBUserReference ));

            xixfs_TryClose(CanWait, bUserReference, pFCB);

            RC = STATUS_SUCCESS;
            try_return(RC);


        } else {

            if( ((pVCB->VCBCleanup == 0) || ForceDismount)
                    && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED))
            {


                if(ForceDismount) {
                    FsRtlNotifyVolumeEvent(pFileObject, FSRTL_VOLUME_DISMOUNT);

                }

                if( ((pVCB->VCBCleanup == 0) || ForceDismount)
                        && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED))
                {

                    PotentialVCBUnmount = TRUE;
                    if(bVcbAcq)XifsdReleaseVcb(TRUE,pVCB);
                    XifsdAcquireGData(pIrpContext);

                    DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_RESOURCE),
                               ("XifsdCommonClose Acquire exclusive GData(%p)\n", &XiGlobalData.DataResource));

                    bVcbAcq = XifsdAcquireVcbExclusive(TRUE,pVCB, FALSE);

                    DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_VCB|DEBUG_TARGET_RESOURCE),
                               ("XifsdCommonClose Acquire exclusive VCBResource(%p)\n", pVCB->VCBResource));
                }

            }



            if(PotentialVCBUnmount && bVcbAcq) {
                if(!xixfs_CheckForDismount(pIrpContext, pVCB, TRUE)) {
                    bVcbAcq = FALSE;
                    RC = STATUS_SUCCESS;
                    try_return(RC);

                }
            }

            RC = xixfs_TryClose(CanWait, bUserReference, pFCB);

            if(NT_SUCCESS(RC)) {
                if(PotentialVCBUnmount && bVcbAcq) {
                    if(!xixfs_CheckForDismount(pIrpContext, pVCB, FALSE)) {
                        bVcbAcq = FALSE;
                        RC = STATUS_SUCCESS;
                        try_return(RC);

                    }
                }
            }

            RC = STATUS_SUCCESS;

        }


        ;
    }
    finally{
        if(bVcbAcq) {
            XifsdReleaseVcb(TRUE, pVCB);
        }

        if(PotentialVCBUnmount) {
            XifsdReleaseGData(pIrpContext);
            PotentialVCBUnmount = FALSE;
        }

    }

    xixfs_CompleteRequest(pIrpContext, RC, 0);

    DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
               ("Exit xixfs_CommonClose \n"));
    return RC;
}
Beispiel #9
0
NTSTATUS
XixFsdCommonCleanUp(
	IN PXIFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS		RC = STATUS_SUCCESS;
	PXIFS_FCB		pFCB = NULL;
	PXIFS_CCB		pCCB = NULL;
	PXIFS_VCB		pVCB = NULL;
	PFILE_OBJECT	pFileObject = NULL;	
	TYPE_OF_OPEN	TypeOfOpen = UnopenedFileObject;

	PIRP					pIrp = NULL;
	PIO_STACK_LOCATION		pIrpSp = NULL;
	KIRQL					SavedIrql;

	PXIFS_LCB	pLCB = NULL;
	PXIFS_FCB	pParentFCB = NULL;

	BOOLEAN					Wait = FALSE;
	BOOLEAN					VCBAcquired = FALSE;
	BOOLEAN					ParentFCBAcquired = FALSE;
	BOOLEAN					CanWait = FALSE;
	BOOLEAN					AttemptTeardown = FALSE;
	BOOLEAN					SendUnlockNotification = FALSE;

	PAGED_CODE();

	DebugTrace((DEBUG_LEVEL_TRACE), (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT), 
		("Enter XifsdCommonCleanUp pIrpContext(%p)\n", pIrpContext));


	ASSERT_IRPCONTEXT(pIrpContext);

	pIrp = pIrpContext->Irp;
	ASSERT(pIrp);

	// check if open request is releated to file system CDO
	{
		PDEVICE_OBJECT	DeviceObject = pIrpContext->TargetDeviceObject;
		ASSERT(DeviceObject);
		
		if (DeviceObject == XiGlobalData.XifsControlDeviceObject) {
			RC = STATUS_SUCCESS;

			DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLEANUP), 
					("CDO Device TargetDevide(%p).\n", DeviceObject));
			XixFsdCompleteRequest(pIrpContext,RC,0);
			return(RC);
		}

	}	



	if(pIrpContext->VCB == NULL){

		DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CLEANUP, 
					("pIrpContext->VCB == NULL.\n"));
		RC = STATUS_SUCCESS;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}


	

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
	ASSERT(pIrpSp);

	pFileObject = pIrpSp->FileObject;
	ASSERT(pFileObject);

	TypeOfOpen = XixFsdDecodeFileObject(pFileObject, &pFCB, &pCCB);

	if(TypeOfOpen <= StreamFileOpen){
		DebugTrace((DEBUG_LEVEL_TRACE|DEBUG_LEVEL_INFO), DEBUG_TARGET_CLEANUP, 
					("TypeOfOpen <= StreamFileOpen.\n"));
		XixFsdCompleteRequest(pIrpContext, STATUS_SUCCESS, 0);
		return STATUS_SUCCESS;
	}


	CanWait = XifsdCheckFlagBoolean(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);

	
	if(CanWait == FALSE){
		DebugTrace((DEBUG_LEVEL_TRACE|DEBUG_LEVEL_INFO), (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_IRPCONTEXT), 
					("PostRequest IrpCxt(%p) Irp(%p)\n", pIrpContext, pIrp));
		RC = XixFsdPostRequest(pIrpContext, pIrp);
		return RC;
	}

	ASSERT_FCB(pFCB);
	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);




	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE|DEBUG_TARGET_VCB), 
				("Acquire exclusive pVCB(%p) VCBResource(%p).\n", pVCB, &pVCB->VCBResource));	

	if((TypeOfOpen == UserVolumeOpen)
		&& XifsdCheckFlagBoolean(pFileObject->Flags, FO_FILE_MODIFIED))
	{
		XifsdAcquireVcbExclusive(CanWait, pVCB, FALSE);
		VCBAcquired = TRUE;		
	}


	XifsdAcquireFcbExclusive(CanWait, pFCB, FALSE);		


	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB), 
					("Acquire exclusive FCB(%p) FCBResource(%p).\n", pFCB, pFCB->FCBResource));

	
	XifsdSetFlag(pFileObject->Flags, FO_CLEANUP_COMPLETE);
	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB), 
					("Set File Object Flags(0x%x)\n", pFileObject->Flags));	



	//IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );

	try{
		switch(TypeOfOpen){
		case UserDirectoryOpen:
			
			if(XifsdCheckFlagBoolean(pCCB->CCBFlags, XIFSD_CCB_FLAG_NOFITY_SET))
			{
				DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("CompletionFilter Notify CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB));

				FsRtlNotifyCleanup(pVCB->NotifyIRPSync, &pVCB->NextNotifyIRP, pCCB);

				//DbgPrint("Notify CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB);

			}


			//DbgPrint("CleanUp (%wZ) pCCB(%p) pCCB->CCBFlags(%x)\n", &pFCB->FCBName, pCCB, pCCB->CCBFlags);


			DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB));


			IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );
			break;
			
		case UserFileOpen:
			//
			//  Coordinate the cleanup operation with the oplock state.
			//  Oplock cleanup operations can always cleanup immediately so no
			//  need to check for STATUS_PENDING.
			//

			FsRtlCheckOplock( &pFCB->FCBOplock,
							  pIrp,
							  pIrpContext,
							  NULL,
							  NULL );

			//
			//  Unlock all outstanding file locks.
			//

			if (pFCB->FCBFileLock != NULL) {

				FsRtlFastUnlockAll( pFCB->FCBFileLock,
									pFileObject,
									IoGetRequestorProcess( pIrp ),
									NULL );
			}



			//
			//  Check the fast io state.
			//

			XifsdLockFcb( pIrpContext, pFCB );
			pFCB->IsFastIoPossible = XixFsdCheckFastIoPossible( pFCB );
			XifsdUnlockFcb( pIrpContext, pFCB );


			/*
			if((pFCB->HasLock != FCB_FILE_LOCK_HAS)
				&& (!XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_OPEN_WRITE))
				&& XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED) 
				&& (pFCB->FCBCleanup == 1)
			){
					if(pFCB->SectionObject.DataSectionObject != NULL) 
					{
						
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

						ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
						ExReleaseResourceLite( pFCB->PagingIoResource );
						
						
						CcPurgeCacheSection( &(pFCB->SectionObject),
														NULL,
														0,
														FALSE 
														);	
														
					}			
			
			}
			*/


			
			if(
				XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED) &&
				(pFCB->FcbNonCachedOpenCount > 1)	&&
				((pFCB->FcbNonCachedOpenCount + 1) ==  pFCB->FCBCleanup)
			)
			{
				if(pFCB->SectionObject.DataSectionObject != NULL) 
				{

					// changed by ILGU HONG for readonly 09052006
					if(!pFCB->PtrVCB->IsVolumeWriteProctected)
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);
					// changed by ILGU HONG for readonly end
					
					//DbgPrint("CcFlush  1 File(%wZ)\n", &pFCB->FCBFullPath);
					ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
					ExReleaseResourceLite( pFCB->PagingIoResource );


					CcPurgeCacheSection( &(pFCB->SectionObject),
														NULL,
														0,
														FALSE 
														);					
					

				}	
			}
			
			/*
			else if(pFCB->FCBCleanup == 1 ){
		
				if(XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED)){
					if(pFCB->SectionObject.DataSectionObject != NULL) 
					{
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

						ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
						ExReleaseResourceLite( pFCB->PagingIoResource );

						CcPurgeCacheSection( &(pFCB->SectionObject),
															NULL,
															0,
															FALSE 
															);					
						

					}
				}

				if(XifsdCheckFlagBoolean(pFCB->FCBFlags,XIFSD_FCB_MODIFIED_FILE)){
					XixFsdUpdateFCB(pFCB);
				}

			}
			*/

			IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );
			//
			//  Cleanup the cache map.
			//
			
			CcUninitializeCacheMap( pFileObject, NULL, NULL );
					
			

			break;
		case UserVolumeOpen:
			break;
		default:
			break;
		}

		


		if((TypeOfOpen == UserDirectoryOpen) || (TypeOfOpen == UserFileOpen)){

			if(pFCB->FCBCleanup == 1 ){
				if(XifsdCheckFlagBoolean(pFCB->FCBFlags,XIFSD_FCB_MODIFIED_FILE)){
					
					// changed by ILGU HONG for readonly 09052006
					if(!pFCB->PtrVCB->IsVolumeWriteProctected){

						XixFsdUpdateFCB(pFCB);

						if(pFCB->WriteStartOffset != -1){

							//DbgPrint("Set Update Information!!!\n");
							XixFsdSendFileChangeRC(
									TRUE,
									pVCB->HostMac, 
									pFCB->LotNumber, 
									pVCB->DiskId, 
									pVCB->PartitionId, 
									pFCB->FileSize.QuadPart, 
									pFCB->RealAllocationSize,
									pFCB->WriteStartOffset
							);
							
							pFCB->WriteStartOffset = -1;
						}
					}
					// changed by ILGU HONG for readonly end

				}


	


			}




			if(XifsdCheckFlagBoolean(pCCB->CCBFlags, XIFSD_CCB_FLAGS_DELETE_ON_CLOSE)){
				
				if(pFCB == pFCB->PtrVCB->RootDirFCB){
					XifsdClearFlag(pCCB->CCBFlags, XIFSD_CCB_FLAGS_DELETE_ON_CLOSE);
					XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
				}else{
					XifsdSetFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
				}
			}

	


			// changed by ILGU HONG for readonly 09082006
			if(XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE) && (!pFCB->PtrVCB->IsVolumeWriteProctected) ){
			// changed by ILGU HONG for readonly end
				if(pFCB->FCBCleanup == 1){
					
					//DbgPrint(" !!!Delete Entry From table (%wZ)  .\n", &pFCB->FCBFullPath);

					ASSERT_CCB(pCCB);
					pLCB = pCCB->PtrLCB;

					ASSERT_LCB(pLCB);

					pParentFCB = pLCB->ParentFcb;
					ASSERT_FCB(pParentFCB);					



  					pFCB->FileSize.QuadPart = 0;
					pFCB->ValidDataLength.QuadPart = 0;

					if(pFCB->FCBType == FCB_TYPE_FILE){
						
						XifsdReleaseFcb(TRUE, pFCB);
						XifsdAcquireFcbExclusive(TRUE, pParentFCB, FALSE);
						ParentFCBAcquired = TRUE;
						XifsdAcquireFcbExclusive(TRUE, pFCB, FALSE);
						RC = DeleteParentChild(pIrpContext, pParentFCB, &pLCB->FileName);
						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							//XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						XifsdClearFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_DELETE_ON_CLOSE);
						XifsdSetFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_LINK_IS_GONE);
						
						XixFsdRemovePrefix(TRUE, pLCB);

						//
						//  Now Decrement the reference counts for the parent and drop the Vcb.
						//
						XifsdLockVcb(pIrpContext,pVCB);
						DebugTrace( DEBUG_LEVEL_INFO, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdDecRefCount( pParentFCB, 1, 1 );

						DebugTrace( DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdUnlockVcb( pIrpContext, pVCB );
						


						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						

					}else {
						
						RC = XixFsReLoadFileFromFcb(pFCB);
						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail XixFsReLoadFileFromFcb (%wZ)\n", &pFCB->FCBName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						if(pFCB->ChildCount != 0){
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}

						XifsdReleaseFcb(TRUE, pFCB);
						XifsdAcquireFcbExclusive(TRUE, pParentFCB, FALSE);
						ParentFCBAcquired = TRUE;
						
						XifsdAcquireFcbExclusive(TRUE, pFCB, FALSE);

						RC = DeleteParentChild(pIrpContext, pParentFCB, &pLCB->FileName);

						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							//ifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						

						XifsdClearFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_DELETE_ON_CLOSE);
						XifsdSetFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_LINK_IS_GONE);
						
						
						XixFsdRemovePrefix(TRUE, pLCB);

						//
						//  Now Decrement the reference counts for the parent and drop the Vcb.
						//
						XifsdLockVcb(pIrpContext,pVCB);
						DebugTrace( DEBUG_LEVEL_INFO, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdDecRefCount( pParentFCB, 1, 1 );

						DebugTrace( DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdUnlockVcb( pIrpContext, pVCB );

						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						

						
					}


			
					//XixFsdDeleteUpdateFCB(pFCB);

					XixFsdSendRenameLinkBC(
						TRUE,
						XIFS_SUBTYPE_FILE_DEL,
						pVCB->HostMac,
						pFCB->LotNumber,
						pVCB->DiskId,
						pVCB->PartitionId,
						pFCB->ParentLotNumber,
						0
					);

				}
			}
			

		}


pass_through:

		XifsdLockVcb(pIrpContext, pVCB);
		
		if(XifsdCheckFlagBoolean(pFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
		{
			ASSERT(pFCB->FcbNonCachedOpenCount > 0);
			pFCB->FcbNonCachedOpenCount --;
		}

		XifsdDecrementClenupCount(pFCB);


		DebugTrace(DEBUG_LEVEL_ALL, DEBUG_TARGET_ALL,
			("Cleanup  Name(%wZ) FCBLotNumber(%I64d) FCBCleanUp(%ld) VCBCleanup(%ld) pCCB(%p) FileObject(%p)\n", 
			&pFCB->FCBName,
			pFCB->LotNumber, 
			pFCB->FCBCleanup, 
			pVCB->VCBCleanup,
			pCCB,
			pFileObject
			));
			
		XifsdUnlockVcb( pIrpContext, pVCB );

		AttemptTeardown = (pVCB->VCBCleanup == 0 && pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_DISMOUNTED );
		
		if(pFileObject == pVCB->LockVolumeFileObject){
			ASSERT(XifsdCheckFlagBoolean(pVCB->VCBFlags, XIFSD_VCB_FLAGS_VOLUME_LOCKED));
			
			IoAcquireVpbSpinLock(&SavedIrql);
			XifsdClearFlag(pVCB->PtrVPB->Flags, VPB_LOCKED);
			IoReleaseVpbSpinLock( SavedIrql );
			
			XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_VOLUME_LOCKED);
			pVCB->LockVolumeFileObject = NULL;
			SendUnlockNotification = TRUE;
			
		}

		

		/*
		if( (pFCB->FCBCleanup == 0) 
				&& (!XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE)) ){

			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT| DEBUG_TARGET_ALL), 
				("CleanUp Release Lot Lock LotNumber(%ld)\n", pFCB->LotNumber));

			XifsdLotUnLock(pVCB, pVCB->TargetDeviceObject, pFCB->LotNumber);
			pFCB->HasLock = FCB_FILE_LOCK_INVALID;
		}
		*/

		//
		//  We must clean up the share access at this time, since we may not
		//  get a Close call for awhile if the file was mapped through this
		//  File Object.
		//

		


	}finally{

		XifsdReleaseFcb(pIrpContext, pFCB);

		if(ParentFCBAcquired) {
			XifsdReleaseFcb(TRUE,pParentFCB);
		}
		

        if (SendUnlockNotification) {

            FsRtlNotifyVolumeEvent( pFileObject, FSRTL_VOLUME_UNLOCK );
        }

  		if (VCBAcquired)  {

			XifsdReleaseVcb( pIrpContext, pVCB);
		}


	}



    if (AttemptTeardown) {
        XifsdAcquireVcbExclusive( CanWait, pVCB, FALSE );

        try {
            
            XixFsdPurgeVolume( pIrpContext, pVCB, FALSE );

        } finally {

            XifsdReleaseVcb( pIrpContext, pVCB );
        }
    }


    //
    //  If this is a normal termination then complete the request
    //

	DebugTrace((DEBUG_LEVEL_TRACE), (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT), 
		("Exit XifsdCommonCleanUp pIrpContext(%p)\n", pIrpContext));

    XixFsdCompleteRequest( pIrpContext, STATUS_SUCCESS, 0 );

    return STATUS_SUCCESS;
}
Beispiel #10
0
NTSTATUS
UdfCompletePcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PPCB Pcb
    )

/*++

Routine Description:

    This routine completes initialization of a Pcb which has been filled
    in with partition descriptors.  Initialization-time data such as the
    physical partition descriptors will be returned to the system.

Arguments:

    Vcb - Vcb of the volume the Pcb describes

    Pcb - Pcb being completed

Return Value:

    NTSTATUS according to whether intialization completion was succesful

--*/

{
    ULONG Reference;

    NTSTATUS Status;

    PAGED_CODE();

    //
    //  Check inputs
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );
    ASSERT_PCB( Pcb );

    DebugTrace(( +1, Dbg, "UdfCompletePcb, Vcb %08x Pcb %08x\n", Vcb, Pcb ));

    //
    //  Complete intialization all physical partitions
    //

    for (Reference = 0;
         Reference < Pcb->Partitions;
         Reference++) {

        DebugTrace(( 0, Dbg, "UdfCompletePcb, Examining Ref %u (type %u)!\n", Reference, Pcb->Partition[Reference].Type));

        switch (Pcb->Partition[Reference].Type) {

            case Physical:

                if (Pcb->Partition[Reference].Physical.PartitionDescriptor == NULL) {

                    DebugTrace(( 0, Dbg,
                                 "UdfCompletePcb, ... but didn't find Partition# %u!\n",
                                 Pcb->Partition[Reference].Physical.PartitionNumber ));

                    DebugTrace(( -1, Dbg, "UdfCompletePcb -> STATUS_DISK_CORRUPT_ERROR\n" ));

                    return STATUS_DISK_CORRUPT_ERROR;
                }

                Pcb->Partition[Reference].Physical.Start =
                    Pcb->Partition[Reference].Physical.PartitionDescriptor->Start;
                Pcb->Partition[Reference].Physical.Length =
                    Pcb->Partition[Reference].Physical.PartitionDescriptor->Length;


                //
                //  Retrieve the sparing information at this point if appropriate.
                //  We have to do this when we can map logical -> physical blocks.
                //

                if (Pcb->Partition[Reference].Physical.SparingMap) {

                    Status = UdfLoadSparingTables( IrpContext,
                                                   Vcb,
                                                   Pcb,
                                                   Reference );

                    if (!NT_SUCCESS( Status )) {

                        DebugTrace(( -1, Dbg,
                                     "UdfCompletePcb -> %08x\n", Status ));
                        return Status;
                    }
                }

                //
                //  We will not need the descriptor or sparing map anymore, so drop them.  
                //

                UdfFreePool( &Pcb->Partition[Reference].Physical.PartitionDescriptor );
                UdfFreePool( &Pcb->Partition[Reference].Physical.SparingMap );
                break;

            case Virtual:
                break;

            default:

                ASSERT(FALSE);
                break;
        }
    }

    DebugTrace(( -1, Dbg, "UdfCompletePcb -> STATUS_SUCCESS\n" ));

    return STATUS_SUCCESS;
}
NTSTATUS
XixFsReadFileInfoFromFcb(
	IN PXIFS_FCB pFCB,
	IN BOOLEAN	Waitable,
	IN uint8 *	Buffer,
	IN uint32	BufferSize
)
{
	NTSTATUS RC = STATUS_SUCCESS;
	uint64			FileId = 0;
	PXIFS_VCB					pVCB = NULL;
	PXIDISK_FILE_HEADER_LOT		pFileHeader = NULL;
	uint32			LotType = LOT_INFO_TYPE_INVALID;
	uint32			Reason = 0;

	PAGED_CODE();

	ASSERT_FCB(pFCB);
	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);

	ASSERT(Waitable == TRUE);
	ASSERT(BufferSize >= XIDISK_FILE_HEADER_LOT_SIZE);


	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter XixFsReadFileInfoFromFcb\n"));

	try{
		RC = XixFsRawReadLotAndFileHeader(
				pVCB->TargetDeviceObject,
				pVCB->LotSize,
				pFCB->LotNumber,
				Buffer,
				XIDISK_FILE_HEADER_LOT_SIZE,
				pVCB->SectorSize
				);
				
		if(!NT_SUCCESS(RC)){
			DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
						("Fail Read File Data(%I64d).\n", pFCB->LotNumber));
			try_return (RC);
		}	
		
		pFileHeader = (PXIDISK_FILE_HEADER_LOT)Buffer;

		// Check Header
		if(pFCB->FCBType ==  FCB_TYPE_DIR){
			LotType = LOT_INFO_TYPE_DIRECTORY;
		}else{
			LotType = LOT_INFO_TYPE_FILE;
		}

		RC = XixFsCheckLotInfo(
				&pFileHeader->LotHeader.LotInfo,
				pVCB->VolumeLotSignature,
				pFCB->LotNumber,
				LotType,
				LOT_FLAG_BEGIN,
				&Reason
				);

		if(!NT_SUCCESS(RC)){
			DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
						("XixFsReadFileInfoFromFcb : XixFsCheckLotInfo (%I64d).\n", pFCB->LotNumber));
			RC = STATUS_FILE_CORRUPT_ERROR;
			try_return(RC);
		}
	}finally{

	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit XixFsReadFileInfoFromFcb Status(0x%x)\n", RC));

	return RC;
}
NTSTATUS
XixFsReadFileInfoFromContext(
	BOOLEAN					Waitable,
	PXIFS_FILE_EMUL_CONTEXT FileContext
)
{
	NTSTATUS RC = STATUS_SUCCESS;
	PXIDISK_FILE_HEADER_LOT pFileHeader = NULL;
	PXIFS_VCB	pVCB = NULL;
	LARGE_INTEGER	Offset;
	uint32	BlockSize;
	uint32	LotType = LOT_INFO_TYPE_INVALID;
	uint32	Reason = 0;

	PAGED_CODE();
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter XixFsReadFileInfoFromContext.\n"));

	ASSERT(Waitable == TRUE);
	ASSERT(FileContext);
	pVCB = FileContext->pVCB;
	ASSERT_VCB(pVCB);


	DebugTrace( DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
					 ("FileContext Searched LotNumber(%I64d) FileType(%ld)\n", 
					 FileContext->LotNumber,
					 FileContext->FileType
					 ));
	
	FileContext->pSearchedFCB = NULL;	


		
	try{
		if(FileContext->Buffer == NULL){
			FileContext->Buffer = 
				ExAllocatePoolWithTag(NonPagedPool,XIDISK_FILE_HEADER_LOT_SIZE, TAG_BUFFER);
		}
	}finally{
		if(AbnormalTermination()){
			RC = STATUS_INSUFFICIENT_RESOURCES;
		}

	}

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


	try{
		RC = XixFsRawReadLotAndFileHeader(
				pVCB->TargetDeviceObject,
				pVCB->LotSize,
				FileContext->LotNumber,
				FileContext->Buffer,
				XIDISK_FILE_HEADER_LOT_SIZE,
				pVCB->SectorSize
				);
				
		if(!NT_SUCCESS(RC)){
			DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
						("Fail Read File Data(%I64d).\n", FileContext->LotNumber));
			try_return (RC);
		}	
		
		pFileHeader = (PXIDISK_FILE_HEADER_LOT)FileContext->Buffer;

		// Check Header
		if(FileContext->FileType ==  FCB_TYPE_DIR){
			LotType = LOT_INFO_TYPE_DIRECTORY;
		}else{
			LotType = LOT_INFO_TYPE_FILE;
		}

		RC = XixFsCheckLotInfo(
				&pFileHeader->LotHeader.LotInfo,
				pVCB->VolumeLotSignature,
				FileContext->LotNumber,
				LotType,
				LOT_FLAG_BEGIN,
				&Reason
				);

		if(!NT_SUCCESS(RC)){
			RC = STATUS_FILE_CORRUPT_ERROR;
			try_return(RC);
		}
		
	}finally{

	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit XixFsReadFileInfoFromContext Status (0x%x).\n", RC));

	return RC;
}
VOID
xixfs_CleanupFlushVCB(
	IN PXIXFS_IRPCONTEXT pIrpContext,
	IN PXIXFS_VCB		pVCB,
	IN BOOLEAN			DisMountVCB
)
{

	

	//PAGED_CODE();

	ASSERT_IRPCONTEXT( pIrpContext );
	ASSERT_VCB( pVCB );

	ASSERT_EXCLUSIVE_XIFS_GDATA;
	ASSERT_EXCLUSIVE_VCB(pVCB);

	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("xixfs_CleanupFlushVCB Status(%ld).\n", pVCB->VCBState));




	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT), 
						 ("11 Current VCB->PtrVPB->ReferenceCount %d \n", pVCB->PtrVPB->ReferenceCount));


	XifsdLockVcb( pIrpContext, pVCB );

	XIXCORE_SET_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);

	if(DisMountVCB){
		if(pVCB->VolumeDasdFCB != NULL){
			pVCB->VolumeDasdFCB->FCBReference -= 1;
			pVCB->VolumeDasdFCB->FCBUserReference -= 1;
		}

		
		if(pVCB->MetaFCB != NULL){
			pVCB->MetaFCB->FCBReference -=1;
			pVCB->MetaFCB->FCBUserReference -= 1;
		}


		if(pVCB->RootDirFCB != NULL){
			pVCB->RootDirFCB->FCBReference -=1;
			pVCB->RootDirFCB->FCBUserReference -= 1;
		}
	}

	XifsdUnlockVcb(pIrpContext, pVCB);

	xixfs_PurgeVolume(pIrpContext, pVCB, DisMountVCB);

	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("22 Current VCB->PtrVPB->ReferenceCount %d \n", pVCB->PtrVPB->ReferenceCount));


	if(DisMountVCB){
		// Added by ILGU HONG
		XifsdReleaseVcb(TRUE, pVCB);
		
		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ),
					 ("VCB %d/%d \n", pVCB->VCBReference, pVCB->VCBUserReference));		


		CcWaitForCurrentLazyWriterActivity();

		XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);
			
		xixfs_RealCloseFCB((PVOID)pVCB);
	}

	XifsdLockVcb( pIrpContext, pVCB );
	XIXCORE_CLEAR_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);
	XifsdUnlockVcb(pIrpContext, pVCB);


	// Added by ILGU HONG END
	if(DisMountVCB){

		// changed by ILGU HONG for readonly 09052006
		if(!pVCB->XixcoreVcb.IsVolumeWriteProtected){

			LARGE_INTEGER	TimeOut;
			
			//
			//	Stop Meta Update process
			//

			KeSetEvent(&pVCB->VCBUmountEvent, 0, FALSE);

			TimeOut.QuadPart = - DEFAULT_XIFS_UMOUNTWAIT;
			KeWaitForSingleObject(&pVCB->VCBStopOkEvent, Executive, KernelMode, FALSE, &TimeOut);		
			


			xixcore_DeregisterHost(&pVCB->XixcoreVcb);
			
			//	Added by ILGU HONG for 08312006
			if(pVCB->NdasVolBacl_Id){
				xixfs_RemoveUserBacl(pVCB->TargetDeviceObject, pVCB->NdasVolBacl_Id);
			}
			
			//	Added by ILGU HONG End	
		}
		// changed by ILGU HONG for readonly end
	}

	return;
}
Beispiel #14
0
VOID
NtfsReleaseVcbCheckDelete (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN UCHAR MajorCode,
    IN PFILE_OBJECT FileObject OPTIONAL
    )

/*++

Routine Description:

    This routine will release the Vcb.  We will also test here whether we should
    teardown the Vcb at this point.  If this is the last open queued to a dismounted
    volume or the last close from a failed mount or the failed mount then we will
    want to test the Vcb for a teardown.

Arguments:

    Vcb - Supplies the Vcb to acquire

    MajorCode - Indicates what type of operation we were called from.

    FileObject - Optionally supplies the file object whose VPB pointer we need to
        zero out

Return Value:

    None.

--*/

{
    ASSERT_IRP_CONTEXT(IrpContext);
    ASSERT_VCB(Vcb);

    if (FlagOn( Vcb->VcbState, VCB_STATE_PERFORMED_DISMOUNT ) &&
        (Vcb->CloseCount == 0)) {

        ULONG ReferenceCount;
        ULONG ResidualCount;

        KIRQL SavedIrql;
        BOOLEAN DeleteVcb = FALSE;

        ASSERT_EXCLUSIVE_RESOURCE( &Vcb->Resource );

        //
        //  The volume has gone through dismount.  Now we need to decide if this
        //  release of the Vcb is the last reference for this volume.  If so we
        //  can tear the volume down.
        //
        //  We compare the reference count in the Vpb with the state of the volume
        //  and the type of operation.  We also need to check if there is a
        //  referenced log file object.
        //

        IoAcquireVpbSpinLock( &SavedIrql );

        ReferenceCount = Vcb->Vpb->ReferenceCount;

        IoReleaseVpbSpinLock( SavedIrql );

        ResidualCount = 0;

        if (Vcb->LogFileObject != NULL) {

            ResidualCount = 1;
        }

        if (MajorCode == IRP_MJ_CREATE) {

            ResidualCount += 1;
        }

        //
        //  If the residual count is the same as the count in the Vpb then we
        //  can delete the Vpb.
        //

        if (ResidualCount == ReferenceCount) {

            SetFlag( Vcb->VcbState, VCB_STATE_DELETE_UNDERWAY );

            ExReleaseResource( &Vcb->Resource );

            //
            //  Never delete the Vcb unless this is the last release of
            //  this Vcb.
            //

            if (!ExIsResourceAcquiredExclusive( &Vcb->Resource ) &&
                (ExIsResourceAcquiredShared( &Vcb->Resource ) == 0)) {

                if (ARGUMENT_PRESENT(FileObject)) { FileObject->Vpb = NULL; }

                //
                //  If this is a create then the IO system will handle the
                //  Vpb.
                //

                if (MajorCode == IRP_MJ_CREATE) {

                    ClearFlag( Vcb->VcbState, VCB_STATE_TEMP_VPB );
                }

                //
                //  Use the global resource to synchronize the DeleteVcb process.
                //

                (VOID) ExAcquireResourceExclusive( &NtfsData.Resource, TRUE );

                RemoveEntryList( &Vcb->VcbLinks );

                ExReleaseResource( &NtfsData.Resource );

                NtfsDeleteVcb( IrpContext, &Vcb );

            } else {

                ClearFlag( Vcb->VcbState, VCB_STATE_DELETE_UNDERWAY );
            }

        } else {

            ExReleaseResource( &Vcb->Resource );
        }

    } else {

        ExReleaseResource( &Vcb->Resource );
    }
}
Beispiel #15
0
ULONG
UdfLookupMetaVsnOfExtent (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN USHORT Reference,
    IN ULONG Lbn,
    IN ULONG Len,
    IN BOOLEAN ExactEnd
    )

/*++

Routine Description:

    This routine maps the input logical block extent on a given partition to
    a starting virtual block in the metadata stream.  If a mapping does not
    exist, one will be created and the metadata stream extended.

Arguments:

    Vcb - Vcb of logical volume

    Reference - Partition reference to use in the mapping

    Lbn - Logical block number

    Len - Length of extent in bytes
    
    ExactEnd - Indicates the extension policy if these blocks are not mapped.

Return Value:

    ULONG virtual sector number

    Raised status if the Lbn extent is split across multiple Vbn extents.

--*/

{
    ULONG Vsn;
    ULONG Psn;
    ULONG SectorCount;

    BOOLEAN Result;

    BOOLEAN UnwindExtension = FALSE;
    LONGLONG UnwindAllocationSize;

    PFCB Fcb = NULL;

    //
    //  Check inputs
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );

    //
    //  The extent must be an integral number of logical blocks in length.
    //

    if (Len == 0 || BlockOffset( Vcb, Len )) {

        UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
    }


    //
    //  Get the physical mapping of the extent.  The Mcb package operates on ULONG/ULONG
    //  keys and values so we must render our 48bit address into 32.  We can do this since
    //  this is a single surface implementation, and it is guaranteed that a surface cannot
    //  contain more than MAXULONG physical sectors.
    //

    Psn = UdfLookupPsnOfExtent( IrpContext,
                                Vcb,
                                Reference,
                                Lbn,
                                Len );

    //
    //  Use try-finally for cleanup
    //

    try {

        //
        //  We must safely establish a mapping and extend the metadata stream so that cached
        //  reads can occur on this new extent.
        //

        Fcb = Vcb->MetadataFcb;
        UdfLockFcb( IrpContext, Fcb );
        
        Result = UdfVmcbLbnToVbn( &Vcb->Vmcb,
                                  Psn,
                                  &Vsn,
                                  &SectorCount );

        if (Result) {

            //
            //  If the mapping covers the extent, we can give this back.
            //

            if (BlocksFromSectors( Vcb, SectorCount ) >= BlocksFromBytes( Vcb, Len )) {

                try_leave( NOTHING );

            }

            //
            //  It is a fatal error if the extent we are mapping is not wholly contained
            //  by an extent of Vsns in the Vmcb.  This will indicate that some structure
            //  is trying to overlap another.
            //

            UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
        }

        //
        //  Add the new mapping.  We know that it is being added to the end of the stream.
        //

        UdfAddVmcbMapping( &Vcb->Vmcb,
                           Psn,
                           SectorsFromBytes( Vcb, Len ),
                           ExactEnd,
                           &Vsn,
                           &SectorCount );

        UnwindAllocationSize = Fcb->AllocationSize.QuadPart;
        UnwindExtension = TRUE;

        Fcb->AllocationSize.QuadPart =
        Fcb->FileSize.QuadPart =
        Fcb->ValidDataLength.QuadPart = LlBytesFromSectors( Vcb, Vsn + SectorCount);

        CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize );
        UnwindExtension = FALSE;

        //
        //  We do not need to purge the cache maps since the Vmcb will always be
        //  page aligned, and thus any reads will have filled it with valid data.
        //

    } finally {

        if (UnwindExtension) {

            ULONG FirstZappedVsn;

            //
            //  Strip off the additional mappings we made.
            //

            Fcb->AllocationSize.QuadPart =
            Fcb->FileSize.QuadPart =
            Fcb->ValidDataLength.QuadPart = UnwindAllocationSize;

            FirstZappedVsn = SectorsFromBytes( Vcb, UnwindAllocationSize );

            UdfRemoveVmcbMapping( &Vcb->Vmcb,
                                  FirstZappedVsn,
                                  Vsn + SectorCount - FirstZappedVsn );

            CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize );
        }

        if (Fcb) { UdfUnlockFcb( IrpContext, Fcb ); }
    }

    return Vsn;
}
NTSTATUS
XixFsInitializeFCBInfo(
	IN PXIFS_FCB pFCB,
	IN BOOLEAN	Waitable
)
{
	NTSTATUS RC = STATUS_UNSUCCESSFUL;
	PXIFS_VCB					pVCB = NULL;
	PXIDISK_FILE_HEADER			pFileHeader = NULL;
	PXIDISK_DIR_HEADER			pDirHeader = NULL;
	LARGE_INTEGER	Offset;
	uint32			LotCount;

	uint32			BufferSize = 0;
	uint8			*Buffer = NULL;
	uint64			FileId = 0;
	uint32			LotType = LOT_INFO_TYPE_INVALID;
	uint8			*NameBuffer = NULL;
	uint8			*ChildBuffer = NULL;
	uint32			Reason;
	uint32			AddLotSize = 0;
	
	PAGED_CODE();
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter XixFsInitializeFCBInfo\n"));

	ASSERT_FCB(pFCB);
	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);

	ASSERT(Waitable == TRUE);

	
	FileId = pFCB->LotNumber;

	BufferSize = XIDISK_FILE_HEADER_LOT_SIZE; 

	Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, TAG_BUFFER );
	
	if(!Buffer){
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	try{
		RC = XixFsReadFileInfoFromFcb(
						pFCB,
						Waitable,
						Buffer,
						BufferSize
						);
		if(!NT_SUCCESS(RC)){
			try_return(RC);
		}

		pFileHeader = (PXIDISK_FILE_HEADER)Buffer;

		if(pFCB->FCBType == FCB_TYPE_DIR){
			pDirHeader = (PXIDISK_DIR_HEADER)Buffer;
			pFCB->LastAccessTime = pDirHeader->DirInfo.Access_time;
			pFCB->LastWriteTime = pDirHeader->DirInfo.Modified_time;
			pFCB->CreationTime = pDirHeader->DirInfo.Create_time;
			
			if(pDirHeader->DirInfo.NameSize != 0){
				uint16 Size = (uint16)pDirHeader->DirInfo.NameSize;
				if(Size > XIFS_MAX_NAME_LEN){
					Size = XIFS_MAX_NAME_LEN;
				}

				if(pFCB->FCBName.Buffer){
					ExFreePool(pFCB->FCBName.Buffer);
					pFCB->FCBName.Buffer = NULL;

				}


				pFCB->FCBName.MaximumLength = SECTORALIGNSIZE_512(Size);
				pFCB->FCBName.Length = Size;
				NameBuffer =ExAllocatePoolWithTag(PagedPool, SECTORALIGNSIZE_512(Size),TAG_FILE_NAME);
				pFCB->FCBName.Buffer = (PWSTR)NameBuffer;
				if(!pFCB->FCBName.Buffer){
					RC = STATUS_INSUFFICIENT_RESOURCES;
					try_return(RC);
				}
				RtlCopyMemory(
					pFCB->FCBName.Buffer, 
					pDirHeader->DirInfo.Name, 
					pFCB->FCBName.Length);		
			}
			pFCB->RealFileSize = pDirHeader->DirInfo.FileSize;
			pFCB->RealAllocationSize = pDirHeader->DirInfo.AllocationSize;
			
			pFCB->ValidDataLength.QuadPart =
			pFCB->FileSize.QuadPart = pDirHeader->DirInfo.FileSize;
			pFCB->AllocationSize.QuadPart = pDirHeader->DirInfo.AllocationSize; 
			
			pFCB->FileAttribute = pDirHeader->DirInfo.FileAttribute;
			
			pFCB->LinkCount = pDirHeader->DirInfo.LinkCount;
			pFCB->Type = pDirHeader->DirInfo.Type;
			if(pVCB->RootDirectoryLotIndex == FileId) {
				XifsdSetFlag(pFCB->Type, (XIFS_FD_TYPE_ROOT_DIRECTORY|XIFS_FD_TYPE_DIRECTORY));
			}
			pFCB->LotNumber = pDirHeader->DirInfo.LotIndex;
			pFCB->FileId = (FCB_TYPE_DIR_INDICATOR|(FCB_ADDRESS_MASK & pFCB->LotNumber));
			pFCB->ParentLotNumber = pDirHeader->DirInfo.ParentDirLotIndex;
			pFCB->AddrLotNumber = pDirHeader->DirInfo.AddressMapIndex;
			
			pFCB->ChildCount= pDirHeader->DirInfo.childCount;		
			pFCB->ChildCount = (uint32)XixFsfindSetBitMapCount(1024, pDirHeader->DirInfo.ChildMap);
			pFCB->AddrStartSecIndex = 0;

		}else{
			pFCB->LastAccessTime = pFileHeader->FileInfo.Access_time;
			
			pFCB->LastWriteTime = pFileHeader->FileInfo.Modified_time;
			pFCB->CreationTime = pFileHeader->FileInfo.Create_time;
			if(pFileHeader->FileInfo.NameSize != 0){
				uint16 Size = (uint16)pFileHeader->FileInfo.NameSize;
				if(Size > XIFS_MAX_NAME_LEN){
					Size = XIFS_MAX_NAME_LEN;
				}

				if(pFCB->FCBName.Buffer){
					ExFreePool(pFCB->FCBName.Buffer);
					pFCB->FCBName.Buffer = NULL;

				}

				pFCB->FCBName.MaximumLength = SECTORALIGNSIZE_512(Size);
				pFCB->FCBName.Length = Size;
				NameBuffer = ExAllocatePool(NonPagedPool, SECTORALIGNSIZE_512(Size));
				pFCB->FCBName.Buffer = (PWSTR)NameBuffer;
				if(!pFCB->FCBName.Buffer){
					RC = STATUS_INSUFFICIENT_RESOURCES;
					try_return(RC);
				}
				RtlCopyMemory(
					pFCB->FCBName.Buffer, 
					pFileHeader->FileInfo.Name, 
					pFCB->FCBName.Length);
			}
			pFCB->RealFileSize = pFileHeader->FileInfo.FileSize;
			pFCB->RealAllocationSize = pFileHeader->FileInfo.AllocationSize;
			
			pFCB->ValidDataLength.QuadPart =
			pFCB->FileSize.QuadPart =  pFileHeader->FileInfo.FileSize;
			pFCB->AllocationSize.QuadPart = pFileHeader->FileInfo.AllocationSize;
			
			pFCB->FileAttribute = pFileHeader->FileInfo.FileAttribute;
			pFCB->LinkCount = pFileHeader->FileInfo.LinkCount;
			pFCB->Type = pFileHeader->FileInfo.Type;
			
			pFCB->LotNumber = pFileHeader->FileInfo.LotIndex;
			pFCB->FileId = (FCB_TYPE_FILE_INDICATOR|(FCB_ADDRESS_MASK & pFCB->LotNumber));
			pFCB->ParentLotNumber = pFileHeader->FileInfo.ParentDirLotIndex;
			pFCB->AddrLotNumber = pFileHeader->FileInfo.AddressMapIndex;
			
			pFCB->AddrStartSecIndex = 0;

			AddLotSize = pVCB->SectorSize;

			

			pFCB->AddrLot = ExAllocatePoolWithTag(NonPagedPool, AddLotSize, TAG_BUFFER);
	
			if(!pFCB->AddrLot){
					RC = STATUS_INSUFFICIENT_RESOURCES;
					try_return(RC);
			}
			
			pFCB->AddrLotSize = AddLotSize;
			
			
			RC = XixFsRawReadAddressOfFile(
						pVCB->TargetDeviceObject,
						pVCB->LotSize,
						pFCB->LotNumber,
						pFCB->AddrLotNumber,
						(uint8 *)pFCB->AddrLot,
						pFCB->AddrLotSize,
						&(pFCB->AddrStartSecIndex),
						0,
						pVCB->SectorSize);
						


			if(!NT_SUCCESS(RC)){
				try_return(RC);
			}
		}


		if(pFCB->LastAccessTime == 0){
			pFCB->LastAccessTime = XixGetSystemTime().QuadPart;
			DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
					("Initialize pFCB->LastAccessTime(%I64d).\n", pFCB->LastAccessTime));
		}
		if(pFCB->LastWriteTime == 0)
		{
			pFCB->LastWriteTime = XixGetSystemTime().QuadPart;
			DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
					("Initialize pFCB->LastWriteTime(%I64d).\n",pFCB->LastWriteTime));
		}
		
		if(pFCB->CreationTime == 0)
		{
			pFCB->CreationTime = XixGetSystemTime().QuadPart;
			DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
					("Initialize pFCB->CreationTime(%I64d).\n", pFCB->CreationTime));
		}


		DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						("Add to FCB File LotNumber(%I64d).\n", FileId));

	}finally{
		if(Buffer) {
			ExFreePool(Buffer);
		}
	}


	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit XixFsInitializeFCBInfo\n"));
	return RC;
}
Beispiel #17
0
NTSTATUS
UdfLoadSparingTables(
    PIRP_CONTEXT IrpContext,
    PVCB Vcb,
    PPCB Pcb,
    ULONG Reference
    )

/*++

Routine Description:

    This routine reads the sparing tables for a partition and fills
    in the sparing Mcb.

Arguments:

    Vcb - the volume hosting the spared partition

    Pcb - the partion block corresponding to the volume

    Reference - the partition reference being pulled in

Return Value:

    NTSTATUS according to whether the sparing tables were loaded

--*/

{
    NTSTATUS Status;

    ULONG SparingTable;
    PULONG SectorBuffer;
    ULONG Psn;

    ULONG RemainingBytes;
    ULONG ByteOffset;
    ULONG TotalBytes;

    BOOLEAN Complete;

    PSPARING_TABLE_HEADER Header;
    PSPARING_TABLE_ENTRY Entry;

    PPARTITION Partition = &Pcb->Partition[Reference];
    PPARTMAP_SPARABLE Map = Partition->Physical.SparingMap;

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );

    ASSERT( Map != NULL );

    DebugTrace(( +1, Dbg, "UdfLoadSparingTables, Vcb %08x, PcbPartition %08x, Map @ %08x\n", Vcb, Partition, Map ));

    DebugTrace(( 0, Dbg, "UdfLoadSparingTables, Map sez: PacketLen %u, NTables %u, TableSize %u\n",
                         Map->PacketLength,
                         Map->NumSparingTables,
                         Map->TableSize));


    //
    //  Check that the sparale map appears sane.  If there are no sparing tables that
    //  is pretty OK, and it'll wind up looking like a regular physical partition.
    //

    if (Map->NumSparingTables == 0) {

        DebugTrace((  0, Dbg, "UdfLoadSparingTables, no sparing tables claimed!\n" ));
        DebugTrace(( -1, Dbg, "UdfLoadSparingTables -> STATUS_SUCCESS\n" ));
        return STATUS_SUCCESS;
    }

    if (Map->NumSparingTables > sizeof(Map->TableLocation)/sizeof(ULONG)) {

        DebugTrace((  0, Dbg, "UdfLoadSparingTables, too many claimed tables to fit! (max %u)\n",
                              sizeof(Map->TableLocation)/sizeof(ULONG)));
        DebugTrace(( -1, Dbg, "UdfLoadSparingTables -> STATUS_DISK_CORRUPT_ERROR\n" ));
        return  STATUS_DISK_CORRUPT_ERROR;
    }

    if (Map->PacketLength != UDF_SPARING_PACKET_LENGTH) {

        DebugTrace((  0, Dbg, "UdfLoadSparingTables, packet size is %u (not %u!\n",
                              Map->PacketLength,
                              UDF_SPARING_PACKET_LENGTH ));
        DebugTrace(( -1, Dbg, "UdfLoadSparingTables -> STATUS_DISK_CORRUPT_ERROR\n" ));
        return  STATUS_DISK_CORRUPT_ERROR;
    }

    if (Map->TableSize < sizeof(SPARING_TABLE_HEADER) ||
        (Map->TableSize - sizeof(SPARING_TABLE_HEADER)) % sizeof(SPARING_TABLE_ENTRY) != 0) {

        DebugTrace((  0, Dbg, "UdfLoadSparingTables, sparing table size is too small or unaligned!\n" ));
        DebugTrace(( -1, Dbg, "UdfLoadSparingTables -> STATUS_DISK_CORRUPT_ERROR\n" ));
        return  STATUS_DISK_CORRUPT_ERROR;
    }

#ifdef UDF_SANITY
    DebugTrace(( 0, Dbg, "UdfLoadSparingTables" ));
    for (SparingTable = 0; SparingTable < Map->NumSparingTables; SparingTable++) {

        DebugTrace(( 0, Dbg, ", Table %u @ %x", SparingTable, Map->TableLocation[SparingTable] ));
    }
    DebugTrace(( 0, Dbg, "\n" ));
#endif

    //
    //  If a sparing mcb doesn't exist, manufacture one.
    //

    if (Pcb->SparingMcb == NULL) {

        Pcb->SparingMcb = FsRtlAllocatePoolWithTag( PagedPool, sizeof(LARGE_MCB), TAG_SPARING_MCB );
        FsRtlInitializeLargeMcb( Pcb->SparingMcb, PagedPool );
    }

    SectorBuffer = FsRtlAllocatePoolWithTag( PagedPool, PAGE_SIZE, TAG_NSR_FSD );

    //
    //  Now loop across the sparing tables and pull the data in.
    //

    try {

        for (Complete = FALSE, SparingTable = 0;

             SparingTable < Map->NumSparingTables;

             SparingTable++) {

            DebugTrace((  0, Dbg, "UdfLoadSparingTables, loading sparing table %u!\n",
                                  SparingTable ));

            ByteOffset = 0;
            TotalBytes = 0;
            RemainingBytes = 0;

            do {

                if (RemainingBytes == 0) {

                    (VOID) UdfReadSectors( IrpContext,
                                           BytesFromSectors( Vcb, Map->TableLocation[SparingTable] ) + ByteOffset,
                                           SectorSize( Vcb ),
                                           FALSE,
                                           SectorBuffer,
                                           Vcb->TargetDeviceObject );

                    //
                    //  Verify the descriptor at the head of the sparing table.  If it is not
                    //  valid, we just break out for a chance at the next table, if any.
                    //

                    if (ByteOffset == 0) {

                        Header = (PSPARING_TABLE_HEADER) SectorBuffer;

                        if (!UdfVerifyDescriptor( IrpContext,
                                                  &Header->Destag,
                                                  0,
                                                  SectorSize( Vcb ),
                                                  Header->Destag.Lbn,
                                                  TRUE )) {

                            DebugTrace((  0, Dbg, "UdfLoadSparingTables, sparing table %u didn't verify destag!\n",
                                                  SparingTable ));
                            break;
                        }

                        if (!UdfUdfIdentifierContained( &Header->RegID,
                                                        &UdfSparingTableIdentifier,
                                                        UDF_VERSION_150,
                                                        UDF_VERSION_RECOGNIZED,
                                                        OSCLASS_INVALID,
                                                        OSIDENTIFIER_INVALID)) {

                            DebugTrace((  0, Dbg, "UdfLoadSparingTables, sparing table %u didn't verify regid!\n",
                                                  SparingTable ));
                            break;
                        }

                        //
                        //  Calculate the total number bytes this map spans and check it against what
                        //  we were told the sparing table sizes are.
                        //

                        DebugTrace(( 0, Dbg, "UdfLoadSparingTables, Sparing table %u has %u entries\n",
                                             SparingTable,
                                             Header->TableEntries ));

                        TotalBytes = sizeof(SPARING_TABLE_HEADER) + Header->TableEntries * sizeof(SPARING_TABLE_ENTRY);

                        if (Map->TableSize < TotalBytes) {

                            DebugTrace((  0, Dbg, "UdfLoadSparingTables, sparing table #ents %u overflows allocation!\n",
                                                  Header->TableEntries ));
                            break;
                        }

                        //
                        //  So far so good, advance past the header.
                        //

                        ByteOffset = sizeof(SPARING_TABLE_HEADER);
                        Entry = Add2Ptr( SectorBuffer, sizeof(SPARING_TABLE_HEADER), PSPARING_TABLE_ENTRY );

                    } else {

                        //
                        //  Pick up in the new sector.
                        //

                        Entry = (PSPARING_TABLE_ENTRY) SectorBuffer;
                    }

                    RemainingBytes = Min( SectorSize( Vcb ), TotalBytes - ByteOffset );
                }

                //
                //  Add the mapping.  Since sparing tables are an Lbn->Psn mapping,
                //  very odd, and I want to simplify things by putting the sparing
                //  in right at IO dispatch, translate this to a Psn->Psn mapping.
                //

                if (Entry->Original != UDF_SPARING_AVALIABLE &&
                    Entry->Original != UDF_SPARING_DEFECTIVE) {

                    Psn = Partition->Physical.Start + SectorsFromBlocks( Vcb, Entry->Original );

                    DebugTrace((  0, Dbg, "UdfLoadSparingTables, mapping from Psn %x (Lbn %x) -> Psn %x\n",
                                          Psn,
                                          Entry->Original,
                                          Entry->Mapped ));

                    FsRtlAddLargeMcbEntry( Pcb->SparingMcb,
                                           Psn,
                                           Entry->Mapped,
                                           UDF_SPARING_PACKET_LENGTH );
                }

                //
                //  Advance to the next, and drop out if we've hit the end.
                //

                ByteOffset += sizeof(SPARING_TABLE_ENTRY);
                RemainingBytes -= sizeof(SPARING_TABLE_ENTRY);
                Entry++;

            } while ( ByteOffset < TotalBytes );
        }

    } finally {

        DebugUnwind( UdfLoadSparingTables );

        UdfFreePool( &SectorBuffer );
    }

    DebugTrace(( -1, Dbg, "UdfLoadSparingTables -> STATUS_SUCCESS\n" ));

    return STATUS_SUCCESS;
}
Beispiel #18
0
NTSTATUS
XixFsdCommonLockControl(
	IN PXIFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS			RC = STATUS_SUCCESS;
	PIRP					pIrp = NULL;
	PIO_STACK_LOCATION	pIrpSp = NULL;
	PFILE_OBJECT		pFileObject = NULL;
	PXIFS_FCB			pFCB = NULL;
	PXIFS_CCB			pCCB = NULL;
	PXIFS_VCB			pVCB = NULL;
	TYPE_OF_OPEN		TypeOfOpen = UnopenedFileObject;

	PAGED_CODE();

	DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!Enter XixFsdCommonLockControl \n"));

	DebugTrace(DEBUG_LEVEL_TRACE,(DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB),
		("Enter XixFsdCommonLockControl\n"));




	ASSERT(pIrpContext);

	pIrp = pIrpContext->Irp;
	ASSERT(pIrp);

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
	ASSERT(pIrpSp);

	pFileObject = pIrpSp->FileObject;
	ASSERT(pFileObject);

	TypeOfOpen = XixFsdDecodeFileObject(pFileObject, &pFCB, &pCCB);

	ASSERT_FCB(pFCB);


	if(TypeOfOpen != UserFileOpen){
		RC = STATUS_INVALID_PARAMETER;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}

	if(pFCB->FCBType != FCB_TYPE_FILE) 
	{
		RC = STATUS_INVALID_PARAMETER;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}

	if(pFCB->HasLock != FCB_FILE_LOCK_HAS){
		RC = STATUS_ACCESS_DENIED;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}

	
	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);

	DebugTrace(DEBUG_LEVEL_TRACE|DEBUG_LEVEL_ALL,(DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB),
		("CALL FsRtlCheckOplock : XixFsdCommonLockControl\n"));

	RC = FsRtlCheckOplock(&pFCB->FCBOplock,
						pIrp,
						pIrpContext,
						XixFsdOplockComplete,
						NULL);

	if(!NT_SUCCESS(RC)){
		DebugTrace(DEBUG_LEVEL_TRACE|DEBUG_LEVEL_ALL,(DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB),
			("return PENDING FsRtlCheckOplock : XixFsdCommonLockControl\n"));
		return RC;
	}

	if(!XixFsdVerifyFcbOperation(pIrpContext, pFCB)){
		RC = STATUS_INVALID_PARAMETER;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}


	try{


		if(pFCB->FCBFileLock == NULL){
			pFCB->FCBFileLock = FsRtlAllocateFileLock(NULL, NULL);

			if(!pFCB->FCBFileLock){
				RC = STATUS_INSUFFICIENT_RESOURCES;
				try_return(RC);
			}
		}


		RC = FsRtlProcessFileLock(pFCB->FCBFileLock, pIrp, NULL);

		XifsdLockFcb(pIrpContext, pFCB);
		pFCB->IsFastIoPossible = XixFsdCheckFastIoPossible(pFCB);
		XifsdUnlockFcb(pIrpContext, pFCB);
	
	}finally{
	}
	
	XixFsdCompleteRequest(pIrpContext, RC, 0);

	DebugTrace(DEBUG_LEVEL_TRACE|DEBUG_LEVEL_ALL,(DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB),
		("Exit XixFsdCommonLockControl\n"));
	
	return RC;
	
}
NTSTATUS
xixfs_CommonQueryVolumeInformation(
	IN PXIXFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS				RC = STATUS_SUCCESS;
	PIRP					pIrp = NULL;
	PIO_STACK_LOCATION		pIrpSp = NULL;
	PXIXFS_VCB				pVCB = NULL;
	PXIXFS_FCB				pFCB = NULL;
	PXIXFS_CCB				pCCB = NULL;
	PFILE_OBJECT				pFileObject = NULL;
	BOOLEAN					Wait = FALSE;
	uint32					BytesToReturn = 0;
	uint32					Length = 0;
	TYPE_OF_OPEN			TypeOfOpen = UnopenedFileObject;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
		("Enter xixfs_CommonQueryVolumeInformation \n"));

	ASSERT(pIrpContext);

	pIrp = pIrpContext->Irp;
	ASSERT(pIrp);

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
	ASSERT(pIrp);

	pFileObject = pIrpSp->FileObject;
	ASSERT(pFileObject);

	TypeOfOpen = xixfs_DecodeFileObject( pFileObject, &pFCB, &pCCB );

    if (TypeOfOpen == UnopenedFileObject) {
		RC = STATUS_INVALID_PARAMETER;
        xixfs_CompleteRequest( pIrpContext, STATUS_INVALID_PARAMETER, 0 );
        return RC;
    }


	DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!VolumeInformation  pCCB(%p)\n", pCCB));

	pVCB = pFCB->PtrVCB;
	ASSERT_VCB(pVCB);


	Wait = XIXCORE_TEST_FLAGS(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);
	




	if(!ExAcquireResourceSharedLite(&(pVCB->VCBResource), Wait)){
		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
					("PostRequest IrpContext(%p) Irp(%p)\n", pIrpContext, pIrp));
		RC = xixfs_PostRequest(pIrpContext, pIrp);
		return RC;
	}

	try{


		Length = pIrpSp->Parameters.QueryVolume.Length ;


		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
					 ("pIrpSp->Parameters.QueryVolume.FsInformationClass (0x%x)\n", 
					 pIrpSp->Parameters.QueryVolume.FsInformationClass));
	

		switch (pIrpSp->Parameters.QueryVolume.FsInformationClass) {

		case FileFsSizeInformation:
		{
	

			RC = xixfs_QueryFsSizeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsVolumeInformation:
		{

			RC = xixfs_QueryFsVolumeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsDeviceInformation:
		{

			RC = xixfs_QueryFsDeviceInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsAttributeInformation:
		{

			RC = xixfs_QueryFsAttributeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}		
		case FileFsFullSizeInformation:
		{
			RC = xixfs_QueryFsFullSizeInfo(pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn);
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		default:
			DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
				("default Not supported Volume Info %ld\n",pIrpSp->Parameters.QueryVolume.FsInformationClass));
			RC = STATUS_INVALID_PARAMETER;
			xixfs_CompleteRequest(pIrpContext, RC, 0);
		break;
		 }

		

	}finally{
		ExReleaseResourceLite(&(pVCB->VCBResource));
	}
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
		("Exit xixfs_CommonQueryVolumeInformation \n"));
	return RC;	
}
Beispiel #20
0
NTSTATUS
XixFsdCommonPNP(
	IN PXIFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS			RC = STATUS_SUCCESS;
	PIRP				pIrp = NULL;
	PIO_STACK_LOCATION	pIrpSp = NULL;
	PXI_VOLUME_DEVICE_OBJECT		pVolumeDeviceObject = NULL;
	PXIFS_VCB						pVCB = NULL;
	uint32							PrevLevel = 0;
	uint32							PrevTarget = 0;


	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Enter XixFsdCommonPNP  \n"));

	ASSERT(pIrpContext);
	pIrp = pIrpContext->Irp;
	ASSERT(pIrp);



	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
	pVolumeDeviceObject = (PXI_VOLUME_DEVICE_OBJECT)pIrpSp->DeviceObject;
	
	if(pVolumeDeviceObject->DeviceObject.Size != sizeof(XI_VOLUME_DEVICE_OBJECT)
		|| (pVolumeDeviceObject->VCB.NodeTypeCode != XIFS_NODE_VCB))
	{
		DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
				 ("XixFsdCommonPNP Invalid Parameter\n"));
		RC = STATUS_INVALID_PARAMETER;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}

	if(!XifsdCheckFlagBoolean(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT)){
		RC = STATUS_PENDING;
		DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
				 ("XifsdPostRequest  IrpContext(%p) Irp(%p)\n", pIrpContext, pIrp ));

		XixFsdPostRequest(pIrpContext, pIrp);
		
		return RC;
	}
	
	PrevLevel = XifsdDebugLevel;
	PrevTarget = XifsdDebugTarget;
	XifsdDebugLevel = DEBUG_LEVEL_ALL;
	XifsdDebugTarget = DEBUG_TARGET_REFCOUNT;


	pVCB = &(pVolumeDeviceObject->VCB);
	ASSERT_VCB(pVCB);


	switch ( pIrpSp->MinorFunction ) 
	{
	case IRP_MN_QUERY_REMOVE_DEVICE:


		
		RC = XixFsdPnpQueryRemove( pIrpContext, pIrp, pVCB );
		
		break;

	case IRP_MN_SURPRISE_REMOVAL:

		
		RC = XixFsdPnpSurpriseRemove( pIrpContext, pIrp, pVCB );
		
		break;

	case IRP_MN_REMOVE_DEVICE:
	
		
		RC = XixFsdPnpRemove( pIrpContext, pIrp, pVCB );
		
		break;

	case IRP_MN_CANCEL_REMOVE_DEVICE:
		
		RC = XixFsdPnpCancelRemove( pIrpContext, pIrp, pVCB );
	
		break;

	default:

		IoSkipCurrentIrpStackLocation( pIrp );

		RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);

		XixFsdReleaseIrpContext(pIrpContext);

		break;
	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Exit XixFsdCommonPNP  \n"));	


	XifsdDebugLevel = PrevLevel;
	XifsdDebugTarget = PrevTarget;

	return RC;
}
Beispiel #21
0
BOOLEAN
CdCheckForDismount (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN BOOLEAN Force
)

/*++

Routine Description:

    This routine is called to check if a volume is ready for dismount.  This
    occurs when only file system references are left on the volume.

    If the dismount is not currently underway and the user reference count
    has gone to zero then we can begin the dismount.

    If the dismount is in progress and there are no references left on the
    volume (we check the Vpb for outstanding references as well to catch
    any create calls dispatched to the file system) then we can delete
    the Vcb.

Arguments:

    Vcb - Vcb for the volume to try to dismount.

    Force - Whether we will force this volume to be dismounted.

Return Value:

    BOOLEAN - True if the Vcb was not gone by the time this function finished,
        False if it was deleted.

    This is only a trustworthy indication to the caller if it had the vcb
    exclusive itself.

--*/

{
    BOOLEAN UnlockVcb = TRUE;
    BOOLEAN VcbPresent = TRUE;
    KIRQL SavedIrql;

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_VCB( Vcb );

    ASSERT_EXCLUSIVE_CDDATA;

    //
    //  Acquire and lock this Vcb to check the dismount state.
    //

    CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );

    //
    //  Lets get rid of any pending closes for this volume.
    //

    CdFspClose( Vcb );

    CdLockVcb( IrpContext, Vcb );

    //
    //  If the dismount is not already underway then check if the
    //  user reference count has gone to zero or we are being forced
    //  to disconnect.  If so start the teardown on the Vcb.
    //

    if (Vcb->VcbCondition != VcbDismountInProgress) {

        if (Vcb->VcbUserReference <= CDFS_RESIDUAL_USER_REFERENCE || Force) {

            CdUnlockVcb( IrpContext, Vcb );
            UnlockVcb = FALSE;
            VcbPresent = CdDismountVcb( IrpContext, Vcb );
        }

        //
        //  If the teardown is underway and there are absolutely no references
        //  remaining then delete the Vcb.  References here include the
        //  references in the Vcb and Vpb.
        //

    } else if (Vcb->VcbReference == 0) {

        IoAcquireVpbSpinLock( &SavedIrql );

        //
        //  If there are no file objects and no reference counts in the
        //  Vpb we can delete the Vcb.  Don't forget that we have the
        //  last reference in the Vpb.
        //

        if (Vcb->Vpb->ReferenceCount == 1) {

            IoReleaseVpbSpinLock( SavedIrql );
            CdUnlockVcb( IrpContext, Vcb );
            UnlockVcb = FALSE;
            CdDeleteVcb( IrpContext, Vcb );
            VcbPresent = FALSE;

        } else {

            IoReleaseVpbSpinLock( SavedIrql );
        }
    }

    //
    //  Unlock the Vcb if still held.
    //

    if (UnlockVcb) {

        CdUnlockVcb( IrpContext, Vcb );
    }

    //
    //  Release any resources still acquired.
    //

    if (VcbPresent) {

        CdReleaseVcb( IrpContext, Vcb );
    }

    return VcbPresent;
}
Beispiel #22
0
NTSTATUS
XixFsdPnpQueryRemove (
    PXIFS_IRPCONTEXT	pIrpContext,
    PIRP				pIrp,
    PXIFS_VCB			pVCB
)
{
	NTSTATUS	RC = STATUS_SUCCESS;
	KEVENT		Event;
	BOOLEAN		IsPresentVCB = FALSE;
	
	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Enter XixFsdPnpQueryRemove  \n"));
	
	
	ASSERT_IRPCONTEXT(pIrpContext);
	ASSERT(pIrp);
	ASSERT_VCB(pVCB);

	

	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("1 VCB->PtrVPB->ReferenceCount %d \n", 
						 pVCB->PtrVPB->ReferenceCount));



	XifsdAcquireGData(pIrpContext);
	XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);

	XifsdLockVcb(pIrpContext, pVCB);
	XifsdSetFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
	XifsdUnlockVcb(pIrpContext, pVCB);


	IsPresentVCB = TRUE;
	RC = XixFsdLockVolumeInternal(pIrpContext, pVCB, NULL);
	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("2 VCB->PtrVPB->ReferenceCount %d \n", 
						 pVCB->PtrVPB->ReferenceCount));
	


	if(NT_SUCCESS(RC)){
		
		//
		//	Release System Resource
		//

		XixFsdCleanupFlushVCB(pIrpContext, pVCB, TRUE);

		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("XixFsdPnpQueryRemove Forward IRP to low stack  .\n"));

		IoCopyCurrentIrpStackLocationToNext( pIrp );
		
		KeInitializeEvent( &Event, NotificationEvent, FALSE );
		IoSetCompletionRoutine( pIrp,
								XixFsdPnpCompletionRoutine,
								&Event,
								TRUE,
								TRUE,
								TRUE );

		//
		//  Send the request and wait.
		//

		RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);

		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("XixFsdPnpQueryRemove Forward IRP's result(0x%x)  .\n", RC));

		if (RC == STATUS_PENDING) {

			KeWaitForSingleObject( &Event,
								   Executive,
								   KernelMode,
								   FALSE,
								   NULL );

			RC = pIrp->IoStatus.Status;
		}

		if(NT_SUCCESS(RC)){

			IsPresentVCB = XixFsdCheckForDismount(pIrpContext, pVCB, TRUE);
			ASSERT(!IsPresentVCB || (pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_DISMOUNT_PROGRESS));
		}
	}

	
	ASSERT( !(NT_SUCCESS(RC) && IsPresentVCB && pVCB->VCBReference != 0) );

	if(IsPresentVCB){
		XifsdLockVcb(pIrpContext, pVCB);
		XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
		XifsdUnlockVcb(pIrpContext, pVCB);

		XifsdReleaseVcb(TRUE, pVCB);
	}

	XifsdReleaseGData(pIrpContext);
	XixFsdCompleteRequest(pIrpContext, RC, 0);

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Exit XifsdPnpQueryRemove  \n"));

	return RC;
}
Beispiel #23
0
NTSTATUS
xixfs_TryClose(
    IN BOOLEAN	CanWait,
    IN BOOLEAN	bUserReference,
    IN PXIXFS_FCB	pFCB
)
{
    PXIXFS_VCB		pVCB = NULL;
    NTSTATUS		RC = STATUS_SUCCESS;
    uint32			UserReference = 0;


    PAGED_CODE();

    ASSERT_FCB(pFCB);
    pVCB = pFCB->PtrVCB;
    ASSERT_VCB(pVCB);

    if(bUserReference) {
        UserReference = 1;
    } else {
        UserReference = 0;
    }



    XifsdDecCloseCount(pFCB);



    if(!CanWait) {
        if(bUserReference) {
            XifsdLockVcb(TRUE, pVCB);

            DebugTrace(DEBUG_LEVEL_CRITICAL|DEBUG_LEVEL_ALL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT),
                       ("XifsdCloseFCB, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                        pVCB->VCBReference,
                        pVCB->VCBUserReference,
                        pFCB->FCBReference,
                        pFCB->FCBUserReference ));


            XifsdDecRefCount(pFCB, 0, 1);
            /*
            DbgPrint("dec CCB user ref Count CCB with  VCB (%d/%d)  (%d/%d)\n",
            		 pVCB->VCBReference,
            		 pVCB->VCBUserReference,
            		 pFCB->FCBReference,
            		 pFCB->FCBUserReference);
            */

            DebugTrace(DEBUG_LEVEL_CRITICAL|DEBUG_LEVEL_ALL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT),
                       ("XifsdCloseFCB, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                        pVCB->VCBReference,
                        pVCB->VCBUserReference,
                        pFCB->FCBReference,
                        pFCB->FCBUserReference ));

            XifsdUnlockVcb(TRUE, pVCB);
        }

        DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                   ("XifsdCloseFCB Fail Insert delete queue FCB Lotnumber(%I64d)\n", pFCB->XixcoreFcb.LotNumber));

        xixfs_InsertCloseQueue(pFCB);

        RC =  STATUS_UNSUCCESSFUL;
    } else {
        if(!xixfs_CloseFCB(CanWait, pVCB, pFCB, UserReference)) {
            if(bUserReference) {
                XifsdLockVcb(TRUE, pVCB);

                DebugTrace(DEBUG_LEVEL_CRITICAL|DEBUG_LEVEL_ALL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT),
                           ("XifsdCloseFCB, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                            pVCB->VCBReference,
                            pVCB->VCBUserReference,
                            pFCB->FCBReference,
                            pFCB->FCBUserReference ));


                XifsdDecRefCount(pFCB, 0, 1);
                /*
                DbgPrint("dec CCB user ref Count CCB with  VCB (%d/%d)  (%d/%d)\n",
                		 pVCB->VCBReference,
                		 pVCB->VCBUserReference,
                		 pFCB->FCBReference,
                		 pFCB->FCBUserReference);
                */

                DebugTrace(DEBUG_LEVEL_CRITICAL|DEBUG_LEVEL_ALL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT),
                           ("XifsdCloseFCB, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                            pVCB->VCBReference,
                            pVCB->VCBUserReference,
                            pFCB->FCBReference,
                            pFCB->FCBUserReference ));

                XifsdUnlockVcb(TRUE, pVCB);
            }

            DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                       ("XifsdCloseFCB Fail Insert delete queue FCB Lotnumber(%I64d)\n", pFCB->XixcoreFcb.LotNumber));

            xixfs_InsertCloseQueue(pFCB);
            RC =  STATUS_UNSUCCESSFUL;
        }

        DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB),
                   ("XifsdCommonFCB, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                    pVCB->VCBReference,
                    pVCB->VCBUserReference,
                    pFCB->FCBReference,
                    pFCB->FCBUserReference ));

    }

    return RC;
}
NTSTATUS
XixFsdCommonDeviceControl(
	IN PXIFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS					RC = STATUS_SUCCESS;
	PIRP						pIrp = NULL;
	PIO_STACK_LOCATION			pIrpSp= NULL;
	PIO_STACK_LOCATION			pNextIrpSp = NULL;
	PFILE_OBJECT				PtrFileObject = NULL;
	PXIFS_FCB					pFCB = NULL;
	PXIFS_CCB					pCCB = NULL;
	PXIFS_VCB					pVCB = NULL;
	BOOLEAN						CompleteIrp = FALSE;
	ULONG						IoControlCode = 0;
	void						*BufferPointer = NULL;
	BOOLEAN						Wait = FALSE;
	BOOLEAN						PostRequest = FALSE;
	TYPE_OF_OPEN				TypeOfOpen = UnopenedFileObject;
	KEVENT						WaitEvent;
	PVOID						CompletionContext = NULL;


	PAGED_CODE();

	DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL, 
		("Enter XixFsdCommonDeviceControl .\n"));

	DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!Enter XixFsdCommonDeviceControl \n"));


	ASSERT(pIrpContext);
	ASSERT(pIrpContext->Irp);
	pIrp = pIrpContext->Irp;
	
	


	try {	
		Wait = XifsdCheckFlagBoolean(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);
		if(!Wait){
			PostRequest = TRUE;
			try_return(RC = STATUS_PENDING);
		}

		// First, get a pointer to the current I/O stack location
		pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
		ASSERT(pIrpSp);

		PtrFileObject = pIrpSp->FileObject;
		ASSERT(PtrFileObject);

		DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL,
			(" Decode File Object\n"));
		
		TypeOfOpen = XixFsdDecodeFileObject( PtrFileObject, &pFCB, &pCCB );


		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DEVCTL|DEBUG_TARGET_IRPCONTEXT),
			("pIrpSp->Parameters.DeviceIoControl.IoControlCode(0x%02x) .\n",
			pIrpSp->Parameters.DeviceIoControl.IoControlCode));

		if (TypeOfOpen == UserVolumeOpen) {
			pVCB = (PXIFS_VCB)(pFCB ->PtrVCB);
			ASSERT_VCB(pVCB);
		} else {
			DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
			("User Volume Open Not supported!!.\n"));

			RC = STATUS_INVALID_PARAMETER;
			XixFsdCompleteRequest(pIrpContext, RC, 0);
			try_return(RC);
		}
		
		
		switch(pIrpSp->Parameters.DeviceIoControl.IoControlCode) {
		case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:

			//DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES\n");

			XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);
			XixFsdFlusVolume(pIrpContext, pVCB);
			

			KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE );
			CompletionContext = &WaitEvent;
			IoCopyCurrentIrpStackLocationToNext(pIrp );
			IoSetCompletionRoutine(pIrp, 
								XixFsdDevFlushAndHoldWriteCompletionRoutine, 
								CompletionContext, 
								TRUE, 
								TRUE, 
								TRUE
								);



			break;
		default:
			 IoSkipCurrentIrpStackLocation( pIrp );
			 /*
			IoCopyCurrentIrpStackLocationToNext(pIrp );
			// Set a completion routine.
			IoSetCompletionRoutine(pIrp, XixFsdDevIoctlCompletion, NULL, TRUE, TRUE, TRUE);
			*/
			break;
		}
		

		// Send the request.
		RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);

		if(RC == STATUS_PENDING && CompletionContext){
			//DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES2\n");
			KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL);
			RC = pIrp->IoStatus.Status;
		}


		if(CompletionContext)
		{
			/*
			DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES RC(0x%x) Status(0x%x) Information(%ld) \n",
				RC, pIrp->IoStatus.Status, pIrp->IoStatus.Information);
			*/
			XifsdReleaseVcb(TRUE, pVCB);
			
			XixFsdCompleteRequest(pIrpContext, RC, (uint32)pIrp->IoStatus.Information);
		}else{
			XixFsdReleaseIrpContext(pIrpContext);
		}

		

	} finally {
		if (!(pIrpContext->IrpContextFlags & XIFSD_IRP_CONTEXT_EXCEPTION)) {
			;
		}

		if(PostRequest ){
			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DEVCTL|DEBUG_TARGET_IRPCONTEXT),
					("PostRequest pIrpCotnext(0x%x) pIrp(0x%x)\n", pIrpContext, pIrp));
			RC = XixFsdPostRequest(pIrpContext, pIrp);
		}		

	}


	DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL, 
		("Exit XixFsdCommonDeviceControl .\n"));
	return(RC);
}